Don't call settings in render loop

This commit is contained in:
Atlante45 2015-01-20 10:56:58 -08:00
parent d7f6add74c
commit 88872825fa
4 changed files with 91 additions and 69 deletions

View file

@ -17,28 +17,15 @@
#include "LODManager.h"
namespace SettingHandles {
const SettingHandle<bool> automaticAvatarLOD("automaticAvatarLOD", true);
const SettingHandle<float> avatarLODDecreaseFPS("avatarLODDecreaseFPS", DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS);
const SettingHandle<float> avatarLODIncreaseFPS("avatarLODIncreaseFPS", ADJUST_LOD_UP_FPS);
const SettingHandle<float> avatarLODDistanceMultiplier("avatarLODDistanceMultiplier",
DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER);
const SettingHandle<int> boundaryLevelAdjust("boundaryLevelAdjust", 0);
const SettingHandle<float> octreeSizeScale("octreeSizeScale", DEFAULT_OCTREE_SIZE_SCALE);
}
float LODManager::getOctreeSizeScale() const {
return SettingHandles::octreeSizeScale.get();
}
void LODManager::setOctreeSizeScale(float sizeScale) {
SettingHandles::octreeSizeScale.set(sizeScale);
_shouldRenderTableNeedsRebuilding = true;
}
int LODManager::getBoundaryLevelAdjust() const {
return SettingHandles::boundaryLevelAdjust.get();
}
void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
SettingHandles::boundaryLevelAdjust.set(boundaryLevelAdjust);
_shouldRenderTableNeedsRebuilding = true;
}
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
@ -54,63 +41,54 @@ void LODManager::autoAdjustLOD(float currentFPS) {
quint64 now = usecTimestampNow();
const quint64 ADJUST_AVATAR_LOD_DOWN_DELAY = 1000 * 1000;
bool automaticAvatarLOD = SettingHandles::automaticAvatarLOD.get();
if (automaticAvatarLOD) {
float avatarLODIncreaseFPS = SettingHandles::avatarLODIncreaseFPS.get();
float avatarLODDecreaseFPS = SettingHandles::avatarLODDecreaseFPS.get();
float avatarLODDistanceMultiplier = SettingHandles::avatarLODDistanceMultiplier.get();
if (_fastFPSAverage.getAverage() < avatarLODDecreaseFPS) {
if (_automaticAvatarLOD) {
if (_fastFPSAverage.getAverage() < _avatarLODDecreaseFPS) {
if (now - _lastAvatarDetailDrop > ADJUST_AVATAR_LOD_DOWN_DELAY) {
// attempt to lower the detail in proportion to the fps difference
float targetFps = (avatarLODDecreaseFPS + avatarLODIncreaseFPS) * 0.5f;
float targetFps = (_avatarLODDecreaseFPS + _avatarLODIncreaseFPS) * 0.5f;
float averageFps = _fastFPSAverage.getAverage();
const float MAXIMUM_MULTIPLIER_SCALE = 2.0f;
avatarLODDistanceMultiplier = qMin(MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER,
avatarLODDistanceMultiplier * (averageFps < EPSILON ?
MAXIMUM_MULTIPLIER_SCALE :
qMin(MAXIMUM_MULTIPLIER_SCALE,
targetFps / averageFps)));
_avatarLODDistanceMultiplier = qMin(MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, _avatarLODDistanceMultiplier *
(averageFps < EPSILON ? MAXIMUM_MULTIPLIER_SCALE :
qMin(MAXIMUM_MULTIPLIER_SCALE, targetFps / averageFps)));
_lastAvatarDetailDrop = now;
}
} else if (_fastFPSAverage.getAverage() > avatarLODIncreaseFPS) {
} else if (_fastFPSAverage.getAverage() > _avatarLODIncreaseFPS) {
// let the detail level creep slowly upwards
const float DISTANCE_DECREASE_RATE = 0.05f;
avatarLODDistanceMultiplier = qMax(MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER,
avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE);
_avatarLODDistanceMultiplier = qMax(MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER,
_avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE);
}
SettingHandles::avatarLODDistanceMultiplier.set(avatarLODDistanceMultiplier);
}
bool changed = false;
quint64 elapsed = now - _lastAdjust;
float octreeSizeScale = getOctreeSizeScale();
if (elapsed > ADJUST_LOD_DOWN_DELAY && _fpsAverage.getAverage() < ADJUST_LOD_DOWN_FPS
&& octreeSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) {
&& _octreeSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) {
octreeSizeScale *= ADJUST_LOD_DOWN_BY;
_octreeSizeScale *= ADJUST_LOD_DOWN_BY;
if (octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) {
octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE;
if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) {
_octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE;
}
changed = true;
_lastAdjust = now;
qDebug() << "adjusting LOD down... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage()
<< "_octreeSizeScale=" << octreeSizeScale;
<< "_octreeSizeScale=" << _octreeSizeScale;
}
if (elapsed > ADJUST_LOD_UP_DELAY && _fpsAverage.getAverage() > ADJUST_LOD_UP_FPS
&& octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) {
octreeSizeScale *= ADJUST_LOD_UP_BY;
if (octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) {
octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE;
&& _octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) {
_octreeSizeScale *= ADJUST_LOD_UP_BY;
if (_octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) {
_octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE;
}
changed = true;
_lastAdjust = now;
qDebug() << "adjusting LOD up... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage()
<< "_octreeSizeScale=" << octreeSizeScale;
<< "_octreeSizeScale=" << _octreeSizeScale;
}
setOctreeSizeScale(octreeSizeScale);
if (changed) {
_shouldRenderTableNeedsRebuilding = true;
@ -200,3 +178,33 @@ bool LODManager::shouldRenderMesh(float largestDimension, float distanceToCamera
return (distanceToCamera <= visibleDistanceAtClosestScale);
}
void LODManager::setOctreeSizeScale(float sizeScale) {
_octreeSizeScale = sizeScale;
_shouldRenderTableNeedsRebuilding = true;
}
void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
_boundaryLevelAdjust = boundaryLevelAdjust;
_shouldRenderTableNeedsRebuilding = true;
}
void LODManager::loadSettings() {
setAutomaticAvatarLOD(SettingHandles::automaticAvatarLOD.get());
setAvatarLODDecreaseFPS(SettingHandles::avatarLODDecreaseFPS.get());
setAvatarLODIncreaseFPS(SettingHandles::avatarLODIncreaseFPS.get());
setAvatarLODDistanceMultiplier(SettingHandles::avatarLODDistanceMultiplier.get());
setBoundaryLevelAdjust(SettingHandles::boundaryLevelAdjust.get());
setOctreeSizeScale(SettingHandles::octreeSizeScale.get());
}
void LODManager::saveSettings() {
SettingHandles::automaticAvatarLOD.set(getAutomaticAvatarLOD());
SettingHandles::avatarLODDecreaseFPS.set(getAvatarLODDecreaseFPS());
SettingHandles::avatarLODIncreaseFPS.set(getAvatarLODIncreaseFPS());
SettingHandles::avatarLODDistanceMultiplier.set(getAvatarLODDistanceMultiplier());
SettingHandles::boundaryLevelAdjust.set(getBoundaryLevelAdjust());
SettingHandles::octreeSizeScale.set(getOctreeSizeScale());
}

View file

@ -38,26 +38,27 @@ const float DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER = 1.0f;
const int ONE_SECOND_OF_FRAMES = 60;
const int FIVE_SECONDS_OF_FRAMES = 5 * ONE_SECOND_OF_FRAMES;
namespace SettingHandles {
const SettingHandle<bool> automaticAvatarLOD("automaticAvatarLOD", true);
const SettingHandle<float> avatarLODDecreaseFPS("avatarLODDecreaseFPS", DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS);
const SettingHandle<float> avatarLODIncreaseFPS("avatarLODIncreaseFPS", ADJUST_LOD_UP_FPS);
const SettingHandle<float> avatarLODDistanceMultiplier("avatarLODDistanceMultiplier",
DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER);
}
class LODManager : public Dependency {
SINGLETON_DEPENDENCY
public:
// TODO: Once the SettingWatcher is implemented, replace them with normal SettingHandles.
float getOctreeSizeScale() const;
void setOctreeSizeScale(float sizeScale);
int getBoundaryLevelAdjust() const;
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
void setAutomaticAvatarLOD(bool automaticAvatarLOD) { _automaticAvatarLOD = automaticAvatarLOD; }
bool getAutomaticAvatarLOD() const { return _automaticAvatarLOD; }
void setAvatarLODDecreaseFPS(float avatarLODDecreaseFPS) { _avatarLODDecreaseFPS = avatarLODDecreaseFPS; }
float getAvatarLODDecreaseFPS() const { return _avatarLODDecreaseFPS; }
void setAvatarLODIncreaseFPS(float avatarLODIncreaseFPS) { _avatarLODIncreaseFPS = avatarLODIncreaseFPS; }
float getAvatarLODIncreaseFPS() const { return _avatarLODIncreaseFPS; }
void setAvatarLODDistanceMultiplier(float multiplier) { _avatarLODDistanceMultiplier = multiplier; }
float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; }
// User Tweakable LOD Items
QString getLODFeedbackText();
void setOctreeSizeScale(float sizeScale);
float getOctreeSizeScale() const { return _octreeSizeScale; }
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
void autoAdjustLOD(float currentFPS);
void resetLODAdjust();
@ -67,6 +68,17 @@ public:
private:
LODManager() {}
void loadSettings();
void saveSettings();
bool _automaticAvatarLOD = true;
float _avatarLODDecreaseFPS = DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS;
float _avatarLODIncreaseFPS = ADJUST_LOD_UP_FPS;
float _avatarLODDistanceMultiplier = DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER;
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
int _boundaryLevelAdjust = 0;
quint64 _lastAdjust = 0;
quint64 _lastAvatarDetailDrop = 0;
SimpleMovingAverage _fpsAverage = FIVE_SECONDS_OF_FRAMES;

View file

@ -115,7 +115,7 @@ glm::quat Avatar::getWorldAlignedOrientation () const {
}
float Avatar::getLODDistance() const {
return SettingHandles::avatarLODDistanceMultiplier.get() *
return DependencyManager::get<LODManager>()->getAvatarLODDistanceMultiplier() *
glm::distance(qApp->getCamera()->getPosition(), _position) / _scale;
}

View file

@ -80,16 +80,16 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
form->addRow("You can see... ", _feedback);
form->addRow("Automatic Avatar LOD Adjustment:", _automaticAvatarLOD = new QCheckBox(this));
_automaticAvatarLOD->setChecked(SettingHandles::automaticAvatarLOD.get());
_automaticAvatarLOD->setChecked(lodManager->getAutomaticAvatarLOD());
connect(_automaticAvatarLOD, SIGNAL(toggled(bool)), SLOT(updateAvatarLODControls()));
form->addRow("Decrease Avatar LOD Below FPS:", _avatarLODDecreaseFPS = new QDoubleSpinBox(this));
_avatarLODDecreaseFPS->setValue(SettingHandles::avatarLODDecreaseFPS.get());
_avatarLODDecreaseFPS->setValue(lodManager->getAvatarLODDecreaseFPS());
_avatarLODDecreaseFPS->setDecimals(0);
connect(_avatarLODDecreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
form->addRow("Increase Avatar LOD Above FPS:", _avatarLODIncreaseFPS = new QDoubleSpinBox(this));
_avatarLODIncreaseFPS->setValue(SettingHandles::avatarLODIncreaseFPS.get());
_avatarLODIncreaseFPS->setValue(lodManager->getAvatarLODIncreaseFPS());
_avatarLODIncreaseFPS->setDecimals(0);
connect(_avatarLODIncreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
@ -97,7 +97,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
_avatarLOD->setDecimals(3);
_avatarLOD->setRange(1.0 / MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, 1.0 / MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER);
_avatarLOD->setSingleStep(0.001);
_avatarLOD->setValue(1.0 / SettingHandles::avatarLODDistanceMultiplier.get());
_avatarLOD->setValue(1.0 / lodManager->getAvatarLODDistanceMultiplier());
connect(_avatarLOD, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
// Add a button to reset
@ -120,7 +120,8 @@ void LodToolsDialog::reloadSliders() {
void LodToolsDialog::updateAvatarLODControls() {
QFormLayout* form = static_cast<QFormLayout*>(layout());
SettingHandles::automaticAvatarLOD.set(_automaticAvatarLOD->isChecked());
auto lodManager = DependencyManager::get<LODManager>();
lodManager->setAutomaticAvatarLOD(_automaticAvatarLOD->isChecked());
_avatarLODDecreaseFPS->setVisible(_automaticAvatarLOD->isChecked());
form->labelForField(_avatarLODDecreaseFPS)->setVisible(_automaticAvatarLOD->isChecked());
@ -132,7 +133,7 @@ void LodToolsDialog::updateAvatarLODControls() {
form->labelForField(_avatarLOD)->setVisible(!_automaticAvatarLOD->isChecked());
if (!_automaticAvatarLOD->isChecked()) {
_avatarLOD->setValue(1.0 / SettingHandles::avatarLODDistanceMultiplier.get());
_avatarLOD->setValue(1.0 / lodManager->getAvatarLODDistanceMultiplier());
}
if (isVisible()) {
@ -141,12 +142,13 @@ void LodToolsDialog::updateAvatarLODControls() {
}
void LodToolsDialog::updateAvatarLODValues() {
auto lodManager = DependencyManager::get<LODManager>();
if (_automaticAvatarLOD->isChecked()) {
SettingHandles::avatarLODDecreaseFPS.set(_avatarLODDecreaseFPS->value());
SettingHandles::avatarLODIncreaseFPS.set(_avatarLODIncreaseFPS->value());
lodManager->setAvatarLODDecreaseFPS(_avatarLODDecreaseFPS->value());
lodManager->setAvatarLODIncreaseFPS(_avatarLODIncreaseFPS->value());
} else {
SettingHandles::avatarLODDistanceMultiplier.set(1.0 / _avatarLOD->value());
lodManager->setAvatarLODDistanceMultiplier(1.0 / _avatarLOD->value());
}
}