checkpoint

This commit is contained in:
howard-stearns 2015-12-15 16:07:37 -08:00
parent 205bc1b790
commit 069199554c
7 changed files with 148 additions and 13 deletions

View file

@ -2801,7 +2801,11 @@ void Application::update(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::update()");
updateLOD();
if (DependencyManager::get<LODManager>()->getUseAcuity()) {
updateLOD();
} else {
DependencyManager::get<LODManager>()->updatePIDRenderDistance(getTargetFrameRate(), getLastInstanteousFps(), deltaTime, isThrottleRendering());
}
{
PerformanceTimer perfTimer("devices");

View file

@ -20,9 +20,25 @@
Setting::Handle<float> desktopLODDecreaseFPS("desktopLODDecreaseFPS", DEFAULT_DESKTOP_LOD_DOWN_FPS);
Setting::Handle<float> hmdLODDecreaseFPS("hmdLODDecreaseFPS", DEFAULT_HMD_LOD_DOWN_FPS);
// There are two different systems in use, based on lodPreference:
// pid: renderDistance is automatically adjusted such that frame rate targets are met.
// acuity: a pseudo-acuity target is held, or adjusted to match minimum frame rates.
// If unspecified, acuity is used only if user has specified non-default minumum frame rates.
Setting::Handle<int> lodPreference("lodPreference", (int)LODManager::LODPreference::unspecified);
LODManager::LODManager() {
calculateAvatarLODDistanceMultiplier();
_renderDistanceController.setControlledValueHighLimit(20.0f);
_renderDistanceController.setControlledValueLowLimit(1.0f / (float)TREE_SCALE);
// Advice for tuning parameters:
// See PIDController.h. There's a section on tuning in the reference.
// Turn on logging with the following (or from js with AvatarList.setRenderDistanceControllerHistory("avatar render", 300))
//_renderDistanceController.setHistorySize("avatar render", target_fps * 4);
// Note that extra logging/hysteresis is turned off in Avatar.cpp when the above logging is on.
_renderDistanceController.setKP(0.000012f); // Usually about 0.6 of largest that doesn't oscillate when other parameters 0.
_renderDistanceController.setKI(0.00002f); // Big enough to bring us to target with the above KP.
_renderDistanceController.setHistorySize("FIXME", 240);
}
float LODManager::getLODDecreaseFPS() {
@ -39,7 +55,6 @@ float LODManager::getLODIncreaseFPS() {
return getDesktopLODIncreaseFPS();
}
void LODManager::autoAdjustLOD(float currentFPS) {
// NOTE: our first ~100 samples at app startup are completely all over the place, and we don't
@ -217,15 +232,53 @@ QString LODManager::getLODFeedbackText() {
return result;
}
static float renderDistance = (float)TREE_SCALE;
static int renderedCount = 0;
static int lastRenderedCount = 0;
bool LODManager::getUseAcuity() { return lodPreference.get() == (int)LODManager::LODPreference::acuity; }
void LODManager::setUseAcuity(bool newValue) { lodPreference.set(newValue ? (int)LODManager::LODPreference::acuity : (int)LODManager::LODPreference::pid); }
float LODManager::getRenderDistance() {
return renderDistance;
}
int LODManager::getRenderedCount() {
return lastRenderedCount;
}
// compare audoAdjustLOD()
void LODManager::updatePIDRenderDistance(float targetFps, float measuredFps, float deltaTime, bool isThrottled) {
float distance;
if (!isThrottled) {
_renderDistanceController.setMeasuredValueSetpoint(targetFps); // No problem updating in flight.
// The PID controller raises the controlled value when the measured value goes up.
// The measured value is frame rate. When the controlled value (1 / render cutoff distance)
// goes up, the render cutoff distance gets closer, the number of rendered avatars is less, and frame rate
// goes up.
distance = 1.0f / _renderDistanceController.update(measuredFps, deltaTime);
}
else {
// Here we choose to just use the maximum render cutoff distance if throttled.
distance = 1.0f / _renderDistanceController.getControlledValueLowLimit();
}
_renderDistanceAverage.updateAverage(distance);
renderDistance = _renderDistanceAverage.getAverage(); // average only once per cycle
lastRenderedCount = renderedCount;
renderedCount = 0;
}
bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) {
float distanceToCamera = glm::length(bounds.calcCenter() - args->_viewFrustum->getPosition());
float largestDimension = bounds.getLargestDimension();
if (!getUseAcuity()) {
bool isRendered = fabsf(distanceToCamera - largestDimension) < renderDistance;
renderedCount += isRendered ? 1 : 0;
return isRendered;
}
const float maxScale = (float)TREE_SCALE;
const float octreeToMeshRatio = 4.0f; // must be this many times closer to a mesh than a voxel to see it.
float octreeSizeScale = args->_sizeScale;
int boundaryLevelAdjust = args->_boundaryLevelAdjust;
float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / octreeToMeshRatio;
float distanceToCamera = glm::length(bounds.calcCenter() - args->_viewFrustum->getPosition());
float largestDimension = bounds.getLargestDimension();
static bool shouldRenderTableNeedsBuilding = true;
static QMap<float, float> shouldRenderTable;
if (shouldRenderTableNeedsBuilding) {
@ -315,6 +368,11 @@ void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) {
void LODManager::loadSettings() {
setDesktopLODDecreaseFPS(desktopLODDecreaseFPS.get());
setHMDLODDecreaseFPS(hmdLODDecreaseFPS.get());
if (lodPreference.get() == (int)LODManager::LODPreference::unspecified) {
setUseAcuity((getDesktopLODDecreaseFPS() != DEFAULT_DESKTOP_LOD_DOWN_FPS) || (getHMDLODDecreaseFPS() != DEFAULT_HMD_LOD_DOWN_FPS));
}
Menu::getInstance()->getActionForOption(MenuOption::LodTools)->setEnabled(getUseAcuity());
}
void LODManager::saveSettings() {

View file

@ -15,6 +15,7 @@
#include <DependencyManager.h>
#include <NumericalConstants.h>
#include <OctreeConstants.h>
#include <PIDController.h>
#include <SimpleMovingAverage.h>
const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 15.0;
@ -81,6 +82,24 @@ public:
Q_INVOKABLE float getLODDecreaseFPS();
Q_INVOKABLE float getLODIncreaseFPS();
enum class LODPreference {
pid = 0,
acuity,
unspecified
};
static bool getUseAcuity();
static void setUseAcuity(bool newValue);
Q_INVOKABLE bool getRenderDistanceControllerIsLogging() { return _renderDistanceController.getIsLogging(); }
Q_INVOKABLE void setRenderDistanceControllerHistory(QString label, int size) { return _renderDistanceController.setHistorySize(label, size); }
Q_INVOKABLE void setRenderDistanceKP(float newValue) { _renderDistanceController.setKP(newValue); }
Q_INVOKABLE void setRenderDistanceKI(float newValue) { _renderDistanceController.setKI(newValue); }
Q_INVOKABLE void setRenderDistanceKD(float newValue) { _renderDistanceController.setKD(newValue); }
Q_INVOKABLE void setRenderDistanceInverseLowLimit(float newValue) { _renderDistanceController.setControlledValueLowLimit(newValue); }
Q_INVOKABLE void setRenderDistanceInverseHighLimit(float newValue) { _renderDistanceController.setControlledValueHighLimit(newValue); }
void updatePIDRenderDistance(float targetFps, float measuredFps, float deltaTime, bool isThrottled);
float getRenderDistance();
int getRenderedCount();
static bool shouldRender(const RenderArgs* args, const AABox& bounds);
bool shouldRenderMesh(float largestDimension, float distanceToCamera);
void autoAdjustLOD(float currentFPS);
@ -116,6 +135,9 @@ private:
bool _shouldRenderTableNeedsRebuilding = true;
QMap<float, float> _shouldRenderTable;
PIDController _renderDistanceController{};
SimpleMovingAverage _renderDistanceAverage{ 10 };
};
#endif // hifi_LODManager_h

View file

@ -48,6 +48,7 @@ PreferencesDialog::PreferencesDialog(QWidget* parent) :
connect(ui.buttonChangeAppearance, &QPushButton::clicked, this, &PreferencesDialog::openFullAvatarModelBrowser);
connect(ui.appearanceDescription, &QLineEdit::editingFinished, this, &PreferencesDialog::changeFullAvatarURL);
connect(ui.useAcuityCheckBox, &QCheckBox::clicked, this, &PreferencesDialog::changeUseAcuity);
connect(qApp, &Application::fullAvatarURLChanged, this, &PreferencesDialog::fullAvatarURLChanged);
@ -58,6 +59,15 @@ PreferencesDialog::PreferencesDialog(QWidget* parent) :
UIUtil::scaleWidgetFontSizes(this);
}
void PreferencesDialog::changeUseAcuity() {
bool useAcuity = ui.useAcuityCheckBox->isChecked();
ui.label_desktopMinimumFPSSpin->setEnabled(useAcuity);
ui.desktopMinimumFPSSpin->setEnabled(useAcuity);
ui.label_hmdMinimumFPSSpin->setEnabled(useAcuity);
ui.hmdMinimumFPSSpin->setEnabled(useAcuity);
ui.label_smallestReasonableRenderHorizon->setText(useAcuity ? "Minimum Avatar Display Distance (@half speed)" : "Minimum Display Distance (@half speed)");
Menu::getInstance()->getActionForOption(MenuOption::LodTools)->setEnabled(useAcuity);
}
void PreferencesDialog::changeFullAvatarURL() {
DependencyManager::get<AvatarManager>()->getMyAvatar()->useFullAvatarURL(ui.appearanceDescription->text(), "");
this->fullAvatarURLChanged(ui.appearanceDescription->text(), "");
@ -212,9 +222,11 @@ void PreferencesDialog::loadPreferences() {
// LOD items
auto lodManager = DependencyManager::get<LODManager>();
ui.useAcuityCheckBox->setChecked(lodManager->getUseAcuity());
ui.desktopMinimumFPSSpin->setValue(lodManager->getDesktopLODDecreaseFPS());
ui.hmdMinimumFPSSpin->setValue(lodManager->getHMDLODDecreaseFPS());
ui.avatarRenderSmallestReasonableHorizon->setValue(1.0f / DependencyManager::get<AvatarManager>()->getRenderDistanceInverseHighLimit());
ui.smallestReasonableRenderHorizon->setValue(1.0f / DependencyManager::get<AvatarManager>()->getRenderDistanceInverseHighLimit());
changeUseAcuity();
}
void PreferencesDialog::savePreferences() {
@ -303,7 +315,8 @@ void PreferencesDialog::savePreferences() {
// LOD items
auto lodManager = DependencyManager::get<LODManager>();
lodManager->setUseAcuity(ui.useAcuityCheckBox->isChecked());
lodManager->setDesktopLODDecreaseFPS(ui.desktopMinimumFPSSpin->value());
lodManager->setHMDLODDecreaseFPS(ui.hmdMinimumFPSSpin->value());
DependencyManager::get<AvatarManager>()->setRenderDistanceInverseHighLimit(1.0f / ui.avatarRenderSmallestReasonableHorizon->value());
DependencyManager::get<AvatarManager>()->setRenderDistanceInverseHighLimit(1.0f / ui.smallestReasonableRenderHorizon->value());
}

View file

@ -51,6 +51,7 @@ private slots:
void openScriptsLocationBrowser();
void changeFullAvatarURL();
void fullAvatarURLChanged(const QString& newValue, const QString& modelName);
void changeUseAcuity();
};
#endif // hifi_PreferencesDialog_h

View file

@ -116,8 +116,8 @@ void Stats::updateStats(bool force) {
auto avatarManager = DependencyManager::get<AvatarManager>();
// we need to take one avatar out so we don't include ourselves
STAT_UPDATE(avatarCount, avatarManager->size() - 1);
STAT_UPDATE(avatarRenderableCount, avatarManager->getNumberInRenderRange());
STAT_UPDATE(avatarRenderDistance, (int) round(avatarManager->getRenderDistance())); // deliberately truncating
STAT_UPDATE(avatarRenderableCount, DependencyManager::get<LODManager>()->getRenderedCount()); //FIXME avatarManager->getNumberInRenderRange());
STAT_UPDATE(avatarRenderDistance, (int)round(DependencyManager::get<LODManager>()->getRenderDistance())); // FIXME avatarManager->getRenderDistance())); // deliberately truncating
STAT_UPDATE(serverCount, (int)nodeList->size());
STAT_UPDATE(renderrate, (int)qApp->getFps());
if (qApp->getActiveDisplayPlugin()) {

View file

@ -742,6 +742,43 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="useAcuityCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>28</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<family>Arial</family>
</font>
</property>
<property name="text">
<string>Render based on visual acuity</string>
</property>
<property name="iconSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_111x">
<property name="spacing">
@ -757,7 +794,7 @@
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_9x">
<widget class="QLabel" name="label_desktopMinimumFPSSpin">
<property name="font">
<font>
<family>Arial</family>
@ -842,7 +879,7 @@
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_9y">
<widget class="QLabel" name="label_hmdMinimumFPSSpin">
<property name="font">
<font>
<family>Arial</family>
@ -927,7 +964,7 @@
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_9yz">
<widget class="QLabel" name="label_smallestReasonableRenderHorizon">
<property name="font">
<font>
<family>Arial</family>
@ -963,7 +1000,7 @@
</spacer>
</item>
<item>
<widget class="QSpinBox" name="avatarRenderSmallestReasonableHorizon">
<widget class="QSpinBox" name="smallestReasonableRenderHorizon">
<property name="minimumSize">
<size>
<width>100</width>