more tweaks to LOD logic

This commit is contained in:
ZappoMan 2015-03-25 12:51:13 -07:00
parent 0e44126106
commit ec2b11640c
2 changed files with 95 additions and 45 deletions

View file

@ -40,26 +40,38 @@ float LODManager::getLODIncreaseFPS() {
void LODManager::autoAdjustLOD(float currentFPS) {
// 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
// our moving average with simulated good data
const int IGNORE_THESE_SAMPLES = 100;
const float ASSUMED_FPS = 60.0f;
if (_fpsAverage.getSampleCount() < IGNORE_THESE_SAMPLES) {
//const float ASSUMED_FPS = 60.0f;
if (_fpsAverageUpWindow.getSampleCount() < IGNORE_THESE_SAMPLES) {
currentFPS = ASSUMED_FPS;
_lastUpShift = _lastDownShift = usecTimestampNow();
}
_fpsAverage.updateAverage(currentFPS);
_fastFPSAverage.updateAverage(currentFPS);
_fpsAverageStartWindow.updateAverage(currentFPS);
_fpsAverageDownWindow.updateAverage(currentFPS);
_fpsAverageUpWindow.updateAverage(currentFPS);
quint64 now = usecTimestampNow();
bool changed = false;
bool octreeChanged = false;
quint64 elapsed = now - _lastAdjust;
quint64 elapsedSinceDownShift = now - _lastDownShift;
quint64 elapsedSinceUpShift = now - _lastUpShift;
if (_automaticLODAdjust) {
// LOD Downward adjustment
if (elapsed > ADJUST_LOD_DOWN_DELAY && _fpsAverage.getAverage() < getLODDecreaseFPS()) {
// LOD Downward adjustment
// If our last adjust was an upshift, then we don't want to consider any downshifts until we've delayed at least
// our START_DELAY_WINDOW_IN_SECS
bool doDownShift = _lastAdjustWasUpShift
? (elapsedSinceUpShift > START_SHIFT_ELPASED && _fpsAverageStartWindow.getAverage() < getLODDecreaseFPS())
: (elapsedSinceDownShift > DOWN_SHIFT_ELPASED && _fpsAverageDownWindow.getAverage() < getLODDecreaseFPS());
if (doDownShift) {
// Octree items... stepwise adjustment
if (_octreeSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) {
@ -70,37 +82,58 @@ void LODManager::autoAdjustLOD(float currentFPS) {
octreeChanged = changed = true;
}
if (changed) {
_lastAdjust = now;
qDebug() << "adjusting LOD down... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage()
<< "_octreeSizeScale=" << _octreeSizeScale;
if (changed) {
if (_lastAdjustWasUpShift) {
qDebug() << "adjusting LOD DOWN after initial delay..."
<< "average fps for last "<< START_DELAY_WINDOW_IN_SECS <<"seconds was "
<< _fpsAverageStartWindow.getAverage()
<< "minimum is:" << getLODDecreaseFPS()
<< "elapsedSinceUpShift:" << elapsedSinceUpShift
<< " NEW _octreeSizeScale=" << _octreeSizeScale;
} else {
qDebug() << "adjusting LOD DOWN..."
<< "average fps for last "<< DOWN_SHIFT_WINDOW_IN_SECS <<"seconds was "
<< _fpsAverageDownWindow.getAverage()
<< "minimum is:" << getLODDecreaseFPS()
<< "elapsedSinceDownShift:" << elapsedSinceDownShift
<< " NEW _octreeSizeScale=" << _octreeSizeScale;
}
_lastDownShift = now;
_lastAdjustWasUpShift = false;
emit LODDecreased();
}
}
} else {
// LOD Upward adjustment
if (elapsed > ADJUST_LOD_UP_DELAY && _fpsAverage.getAverage() > getLODIncreaseFPS()) {
// LOD Upward adjustment
if (elapsedSinceUpShift > UP_SHIFT_ELPASED && _fpsAverageUpWindow.getAverage() > getLODIncreaseFPS()) {
// Octee items... stepwise adjustment
if (_octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) {
if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) {
_octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE;
} else {
_octreeSizeScale *= ADJUST_LOD_UP_BY;
// Octee items... stepwise adjustment
if (_octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) {
if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) {
_octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE;
} else {
_octreeSizeScale *= ADJUST_LOD_UP_BY;
}
if (_octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) {
_octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE;
}
octreeChanged = changed = true;
}
if (_octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) {
_octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE;
}
octreeChanged = changed = true;
}
if (changed) {
_lastAdjust = now;
qDebug() << "adjusting LOD up... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage()
<< "_octreeSizeScale=" << _octreeSizeScale;
if (changed) {
qDebug() << "adjusting LOD UP... average fps for last "<< UP_SHIFT_WINDOW_IN_SECS <<"seconds was "
<< _fpsAverageUpWindow.getAverage()
<< "upshift point is:" << getLODIncreaseFPS()
<< "elapsedSinceUpShift:" << elapsedSinceUpShift
<< " NEW _octreeSizeScale=" << _octreeSizeScale;
emit LODIncreased();
_lastUpShift = now;
_lastAdjustWasUpShift = true;
emit LODIncreased();
}
}
}
@ -116,9 +149,13 @@ void LODManager::autoAdjustLOD(float currentFPS) {
}
void LODManager::resetLODAdjust() {
_fpsAverage.reset();
_fastFPSAverage.reset();
// TODO: Do we need this???
/*
_fpsAverageDownWindow.reset();
_fpsAverageUpWindow.reset();
_lastAdjust = usecTimestampNow();
*/
}
QString LODManager::getLODFeedbackText() {

View file

@ -19,10 +19,22 @@
const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0;
const float DEFAULT_HMD_LOD_DOWN_FPS = 60.0;
const float INCREASE_LOD_GAP = 5.0f;
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 INCREASE_LOD_GAP = 15.0f;
const quint64 ADJUST_LOD_DOWN_DELAY = 1000 * 1000 * 0.5; // Consider adjusting LOD down after half a second
const quint64 ADJUST_LOD_UP_DELAY = ADJUST_LOD_DOWN_DELAY * 2;
const float START_DELAY_WINDOW_IN_SECS = 3.0f; // wait at least this long after steady state/last upshift to consider downshifts
const float DOWN_SHIFT_WINDOW_IN_SECS = 0.5f;
const float UP_SHIFT_WINDOW_IN_SECS = 2.5f;
const int ASSUMED_FPS = 60;
const quint64 START_SHIFT_ELPASED = USECS_PER_SECOND * START_DELAY_WINDOW_IN_SECS;
const quint64 DOWN_SHIFT_ELPASED = USECS_PER_SECOND * DOWN_SHIFT_WINDOW_IN_SECS; // Consider adjusting LOD down after half a second
const quint64 UP_SHIFT_ELPASED = USECS_PER_SECOND * UP_SHIFT_WINDOW_IN_SECS;
const int START_DELAY_SAMPLES_OF_FRAMES = ASSUMED_FPS * START_DELAY_WINDOW_IN_SECS;
const int DOWN_SHIFT_SAMPLES_OF_FRAMES = ASSUMED_FPS * DOWN_SHIFT_WINDOW_IN_SECS;
const int UP_SHIFT_SAMPLES_OF_FRAMES = ASSUMED_FPS * UP_SHIFT_WINDOW_IN_SECS;
const float ADJUST_LOD_DOWN_BY = 0.9f;
const float ADJUST_LOD_UP_BY = 1.1f;
@ -37,9 +49,6 @@ const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE;
// do. But both are still culled using the same angular size logic.
const float AVATAR_TO_ENTITY_RATIO = 2.0f;
const int ONE_SECOND_OF_FRAMES = 60;
const int FIVE_SECONDS_OF_FRAMES = 5 * ONE_SECOND_OF_FRAMES;
class LODManager : public QObject, public Dependency {
Q_OBJECT
@ -51,11 +60,11 @@ public:
Q_INVOKABLE void setDesktopLODDecreaseFPS(float value) { _desktopLODDecreaseFPS = value; }
Q_INVOKABLE float getDesktopLODDecreaseFPS() const { return _desktopLODDecreaseFPS; }
Q_INVOKABLE float getDesktopLODIncreaseFPS() const { return _desktopLODDecreaseFPS + INCREASE_LOD_GAP; }
Q_INVOKABLE float getDesktopLODIncreaseFPS() const { return glm::min(_desktopLODDecreaseFPS + INCREASE_LOD_GAP, MAX_LIKELY_DESKTOP_FPS); }
Q_INVOKABLE void setHMDLODDecreaseFPS(float value) { _hmdLODDecreaseFPS = value; }
Q_INVOKABLE float getHMDLODDecreaseFPS() const { return _hmdLODDecreaseFPS; }
Q_INVOKABLE float getHMDLODIncreaseFPS() const { return _hmdLODDecreaseFPS + INCREASE_LOD_GAP; }
Q_INVOKABLE float getHMDLODIncreaseFPS() const { return glm::min(_hmdLODDecreaseFPS + INCREASE_LOD_GAP, MAX_LIKELY_HMD_FPS); }
Q_INVOKABLE float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; }
@ -68,8 +77,8 @@ public:
Q_INVOKABLE int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
Q_INVOKABLE void resetLODAdjust();
Q_INVOKABLE float getFPSAverage() const { return _fpsAverage.getAverage(); }
Q_INVOKABLE float getFastFPSAverage() const { return _fastFPSAverage.getAverage(); }
//Q_INVOKABLE float getFPSAverage() const { return _fpsAverage.getAverage(); }
//Q_INVOKABLE float getFastFPSAverage() const { return _fastFPSAverage.getAverage(); }
Q_INVOKABLE float getLODDecreaseFPS();
Q_INVOKABLE float getLODIncreaseFPS();
@ -96,9 +105,13 @@ private:
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
int _boundaryLevelAdjust = 0;
quint64 _lastAdjust = 0;
SimpleMovingAverage _fpsAverage = FIVE_SECONDS_OF_FRAMES;
SimpleMovingAverage _fastFPSAverage = ONE_SECOND_OF_FRAMES;
quint64 _lastDownShift = 0;
quint64 _lastUpShift = 0;
bool _lastAdjustWasUpShift = true; // start out as if we've just upshifted
SimpleMovingAverage _fpsAverageStartWindow = START_DELAY_SAMPLES_OF_FRAMES;
SimpleMovingAverage _fpsAverageDownWindow = DOWN_SHIFT_SAMPLES_OF_FRAMES;
SimpleMovingAverage _fpsAverageUpWindow = UP_SHIFT_SAMPLES_OF_FRAMES;
bool _shouldRenderTableNeedsRebuilding = true;
QMap<float, float> _shouldRenderTable;