mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 17:58:45 +02:00
Merge pull request #11447 from AndrewMeadows/lod-auto-adjust
LODManager uses batchTime and engineRunTime for automatic LOD adjustment
This commit is contained in:
commit
88097bb39f
4 changed files with 69 additions and 19 deletions
|
@ -4461,11 +4461,13 @@ void Application::init() {
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::updateLOD() const {
|
void Application::updateLOD(float deltaTime) const {
|
||||||
PerformanceTimer perfTimer("LOD");
|
PerformanceTimer perfTimer("LOD");
|
||||||
// adjust it unless we were asked to disable this feature, or if we're currently in throttleRendering mode
|
// adjust it unless we were asked to disable this feature, or if we're currently in throttleRendering mode
|
||||||
if (!isThrottleRendering()) {
|
if (!isThrottleRendering()) {
|
||||||
DependencyManager::get<LODManager>()->autoAdjustLOD(_frameCounter.rate());
|
float batchTime = (float)_gpuContext->getFrameTimerBatchAverage();
|
||||||
|
float engineRunTime = (float)(_renderEngine->getConfiguration().get()->getCPURunTime());
|
||||||
|
DependencyManager::get<LODManager>()->autoAdjustLOD(batchTime, engineRunTime, deltaTime);
|
||||||
} else {
|
} else {
|
||||||
DependencyManager::get<LODManager>()->resetLODAdjust();
|
DependencyManager::get<LODManager>()->resetLODAdjust();
|
||||||
}
|
}
|
||||||
|
@ -4842,7 +4844,7 @@ void Application::update(float deltaTime) {
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "Application::update()");
|
PerformanceWarning warn(showWarnings, "Application::update()");
|
||||||
|
|
||||||
updateLOD();
|
updateLOD(deltaTime);
|
||||||
|
|
||||||
if (!_physicsEnabled) {
|
if (!_physicsEnabled) {
|
||||||
if (!domainLoadingInProgress) {
|
if (!domainLoadingInProgress) {
|
||||||
|
|
|
@ -463,7 +463,7 @@ private:
|
||||||
void update(float deltaTime);
|
void update(float deltaTime);
|
||||||
|
|
||||||
// Various helper functions called during update()
|
// Various helper functions called during update()
|
||||||
void updateLOD() const;
|
void updateLOD(float deltaTime) const;
|
||||||
void updateThreads(float deltaTime);
|
void updateThreads(float deltaTime);
|
||||||
void updateDialogs(float deltaTime) const;
|
void updateDialogs(float deltaTime) const;
|
||||||
|
|
||||||
|
|
|
@ -39,16 +39,29 @@ float LODManager::getLODIncreaseFPS() {
|
||||||
return getDesktopLODIncreaseFPS();
|
return getDesktopLODIncreaseFPS();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LODManager::autoAdjustLOD(float currentFPS) {
|
void LODManager::autoAdjustLOD(float batchTime, float engineRunTime, float deltaTimeSec) {
|
||||||
|
|
||||||
// NOTE: our first ~100 samples at app startup are completely all over the place, and we don't
|
// NOTE: our first ~100 samples at app startup are completely all over the place, and we don't
|
||||||
// really want to count them in our average, so we will ignore the real frame rates and stuff
|
// really want to count them in our average, so we will ignore the real frame rates and stuff
|
||||||
// our moving average with simulated good data
|
// our moving average with simulated good data
|
||||||
const int IGNORE_THESE_SAMPLES = 100;
|
const int IGNORE_THESE_SAMPLES = 100;
|
||||||
if (_fpsAverageUpWindow.getSampleCount() < IGNORE_THESE_SAMPLES) {
|
if (_fpsAverageUpWindow.getSampleCount() < IGNORE_THESE_SAMPLES) {
|
||||||
currentFPS = ASSUMED_FPS;
|
|
||||||
_lastStable = _lastUpShift = _lastDownShift = usecTimestampNow();
|
_lastStable = _lastUpShift = _lastDownShift = usecTimestampNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute time-weighted running average renderTime
|
||||||
|
const float OVERLAY_AND_SWAP_TIME_BUDGET = 2.0f; // msec
|
||||||
|
float renderTime = batchTime + OVERLAY_AND_SWAP_TIME_BUDGET;
|
||||||
|
float maxTime = glm::max(renderTime, engineRunTime);
|
||||||
|
const float BLEND_TIMESCALE = 0.3f; // sec
|
||||||
|
float blend = BLEND_TIMESCALE / deltaTimeSec;
|
||||||
|
if (blend > 1.0f) {
|
||||||
|
blend = 1.0f;
|
||||||
|
}
|
||||||
|
_avgRenderTime = (1.0f - blend) * _avgRenderTime + blend * maxTime; // msec
|
||||||
|
|
||||||
|
// translate into fps for legacy implementation
|
||||||
|
float currentFPS = (float)MSECS_PER_SECOND / _avgRenderTime;
|
||||||
|
|
||||||
_fpsAverageStartWindow.updateAverage(currentFPS);
|
_fpsAverageStartWindow.updateAverage(currentFPS);
|
||||||
_fpsAverageDownWindow.updateAverage(currentFPS);
|
_fpsAverageDownWindow.updateAverage(currentFPS);
|
||||||
|
@ -56,7 +69,6 @@ void LODManager::autoAdjustLOD(float currentFPS) {
|
||||||
|
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
|
|
||||||
bool changed = false;
|
|
||||||
quint64 elapsedSinceDownShift = now - _lastDownShift;
|
quint64 elapsedSinceDownShift = now - _lastDownShift;
|
||||||
quint64 elapsedSinceUpShift = now - _lastUpShift;
|
quint64 elapsedSinceUpShift = now - _lastUpShift;
|
||||||
|
|
||||||
|
@ -64,6 +76,7 @@ void LODManager::autoAdjustLOD(float currentFPS) {
|
||||||
quint64 elapsedSinceStableOrUpShift = now - lastStableOrUpshift;
|
quint64 elapsedSinceStableOrUpShift = now - lastStableOrUpshift;
|
||||||
|
|
||||||
if (_automaticLODAdjust) {
|
if (_automaticLODAdjust) {
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
// LOD Downward adjustment
|
// LOD Downward adjustment
|
||||||
// If we've been downshifting, we watch a shorter downshift window so that we will quickly move toward our
|
// If we've been downshifting, we watch a shorter downshift window so that we will quickly move toward our
|
||||||
|
@ -176,11 +189,44 @@ void LODManager::resetLODAdjust() {
|
||||||
_isDownshifting = false;
|
_isDownshifting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float MIN_DECREASE_FPS = 0.5f;
|
||||||
|
|
||||||
|
void LODManager::setDesktopLODDecreaseFPS(float fps) {
|
||||||
|
if (fps < MIN_DECREASE_FPS) {
|
||||||
|
// avoid divide by zero
|
||||||
|
fps = MIN_DECREASE_FPS;
|
||||||
|
}
|
||||||
|
_desktopMaxRenderTime = (float)MSECS_PER_SECOND / fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
float LODManager::getDesktopLODDecreaseFPS() const {
|
||||||
|
return (float)MSECS_PER_SECOND / _desktopMaxRenderTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
float LODManager::getDesktopLODIncreaseFPS() const {
|
||||||
|
return glm::max(((float)MSECS_PER_SECOND / _desktopMaxRenderTime) + INCREASE_LOD_GAP, MAX_LIKELY_DESKTOP_FPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LODManager::setHMDLODDecreaseFPS(float fps) {
|
||||||
|
if (fps < MIN_DECREASE_FPS) {
|
||||||
|
// avoid divide by zero
|
||||||
|
fps = MIN_DECREASE_FPS;
|
||||||
|
}
|
||||||
|
_hmdMaxRenderTime = (float)MSECS_PER_SECOND / fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
float LODManager::getHMDLODDecreaseFPS() const {
|
||||||
|
return (float)MSECS_PER_SECOND / _hmdMaxRenderTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
float LODManager::getHMDLODIncreaseFPS() const {
|
||||||
|
return glm::max(((float)MSECS_PER_SECOND / _hmdMaxRenderTime) + INCREASE_LOD_GAP, MAX_LIKELY_HMD_FPS);
|
||||||
|
}
|
||||||
|
|
||||||
QString LODManager::getLODFeedbackText() {
|
QString LODManager::getLODFeedbackText() {
|
||||||
// determine granularity feedback
|
// determine granularity feedback
|
||||||
int boundaryLevelAdjust = getBoundaryLevelAdjust();
|
int boundaryLevelAdjust = getBoundaryLevelAdjust();
|
||||||
QString granularityFeedback;
|
QString granularityFeedback;
|
||||||
|
|
||||||
switch (boundaryLevelAdjust) {
|
switch (boundaryLevelAdjust) {
|
||||||
case 0: {
|
case 0: {
|
||||||
granularityFeedback = QString(".");
|
granularityFeedback = QString(".");
|
||||||
|
@ -195,7 +241,6 @@ QString LODManager::getLODFeedbackText() {
|
||||||
granularityFeedback = QString(" at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1);
|
granularityFeedback = QString(" at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// distance feedback
|
// distance feedback
|
||||||
float octreeSizeScale = getOctreeSizeScale();
|
float octreeSizeScale = getOctreeSizeScale();
|
||||||
float relativeToDefault = octreeSizeScale / DEFAULT_OCTREE_SIZE_SCALE;
|
float relativeToDefault = octreeSizeScale / DEFAULT_OCTREE_SIZE_SCALE;
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 20.0;
|
const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 20.0;
|
||||||
const float DEFAULT_HMD_LOD_DOWN_FPS = 20.0;
|
const float DEFAULT_HMD_LOD_DOWN_FPS = 20.0;
|
||||||
|
const float DEFAULT_DESKTOP_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_DESKTOP_LOD_DOWN_FPS; // msec
|
||||||
|
const float DEFAULT_HMD_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_HMD_LOD_DOWN_FPS; // msec
|
||||||
const float MAX_LIKELY_DESKTOP_FPS = 59.0; // this is essentially, V-synch - 1 fps
|
const float MAX_LIKELY_DESKTOP_FPS = 59.0; // this is essentially, V-synch - 1 fps
|
||||||
const float MAX_LIKELY_HMD_FPS = 74.0; // this is essentially, V-synch - 1 fps
|
const float MAX_LIKELY_HMD_FPS = 74.0; // this is essentially, V-synch - 1 fps
|
||||||
const float INCREASE_LOD_GAP = 15.0f;
|
const float INCREASE_LOD_GAP = 15.0f;
|
||||||
|
@ -56,13 +58,13 @@ public:
|
||||||
Q_INVOKABLE void setAutomaticLODAdjust(bool value) { _automaticLODAdjust = value; }
|
Q_INVOKABLE void setAutomaticLODAdjust(bool value) { _automaticLODAdjust = value; }
|
||||||
Q_INVOKABLE bool getAutomaticLODAdjust() const { return _automaticLODAdjust; }
|
Q_INVOKABLE bool getAutomaticLODAdjust() const { return _automaticLODAdjust; }
|
||||||
|
|
||||||
Q_INVOKABLE void setDesktopLODDecreaseFPS(float value) { _desktopLODDecreaseFPS = value; }
|
Q_INVOKABLE void setDesktopLODDecreaseFPS(float value);
|
||||||
Q_INVOKABLE float getDesktopLODDecreaseFPS() const { return _desktopLODDecreaseFPS; }
|
Q_INVOKABLE float getDesktopLODDecreaseFPS() const;
|
||||||
Q_INVOKABLE float getDesktopLODIncreaseFPS() const { return glm::min(_desktopLODDecreaseFPS + INCREASE_LOD_GAP, MAX_LIKELY_DESKTOP_FPS); }
|
Q_INVOKABLE float getDesktopLODIncreaseFPS() const;
|
||||||
|
|
||||||
Q_INVOKABLE void setHMDLODDecreaseFPS(float value) { _hmdLODDecreaseFPS = value; }
|
Q_INVOKABLE void setHMDLODDecreaseFPS(float value);
|
||||||
Q_INVOKABLE float getHMDLODDecreaseFPS() const { return _hmdLODDecreaseFPS; }
|
Q_INVOKABLE float getHMDLODDecreaseFPS() const;
|
||||||
Q_INVOKABLE float getHMDLODIncreaseFPS() const { return glm::min(_hmdLODDecreaseFPS + INCREASE_LOD_GAP, MAX_LIKELY_HMD_FPS); }
|
Q_INVOKABLE float getHMDLODIncreaseFPS() const;
|
||||||
|
|
||||||
// User Tweakable LOD Items
|
// User Tweakable LOD Items
|
||||||
Q_INVOKABLE QString getLODFeedbackText();
|
Q_INVOKABLE QString getLODFeedbackText();
|
||||||
|
@ -76,7 +78,7 @@ public:
|
||||||
Q_INVOKABLE float getLODIncreaseFPS();
|
Q_INVOKABLE float getLODIncreaseFPS();
|
||||||
|
|
||||||
static bool shouldRender(const RenderArgs* args, const AABox& bounds);
|
static bool shouldRender(const RenderArgs* args, const AABox& bounds);
|
||||||
void autoAdjustLOD(float currentFPS);
|
void autoAdjustLOD(float batchTime, float engineRunTime, float deltaTimeSec);
|
||||||
|
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
|
@ -90,8 +92,9 @@ private:
|
||||||
LODManager();
|
LODManager();
|
||||||
|
|
||||||
bool _automaticLODAdjust = true;
|
bool _automaticLODAdjust = true;
|
||||||
float _desktopLODDecreaseFPS = DEFAULT_DESKTOP_LOD_DOWN_FPS;
|
float _avgRenderTime { 0.0 };
|
||||||
float _hmdLODDecreaseFPS = DEFAULT_HMD_LOD_DOWN_FPS;
|
float _desktopMaxRenderTime { DEFAULT_DESKTOP_MAX_RENDER_TIME };
|
||||||
|
float _hmdMaxRenderTime { DEFAULT_HMD_MAX_RENDER_TIME };
|
||||||
|
|
||||||
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
|
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
|
||||||
int _boundaryLevelAdjust = 0;
|
int _boundaryLevelAdjust = 0;
|
||||||
|
|
Loading…
Reference in a new issue