Merge pull request #7145 from howard-stearns/lod-pid-removal

Lod pid removal
This commit is contained in:
Brad Hefta-Gaub 2016-02-20 10:29:42 -08:00
commit 9066fb0622
8 changed files with 4 additions and 148 deletions

View file

@ -267,15 +267,9 @@ Item {
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.showAcuity
visible: root.expanded
text: "LOD: " + root.lodStatus;
}
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded && !root.showAcuity
text: root.lodStatsRenderText;
}
}
}
}

View file

@ -1635,13 +1635,7 @@ void Application::paintGL() {
});
}
// Some LOD-like controls need to know a smoothly varying "potential" frame rate that doesn't
// include time waiting for sync, and which can report a number above target if we've got the headroom.
// In my tests, the following is mostly less than 0.5ms, and never more than 3ms. I don't think its worth measuring during runtime.
const float paintWaitAndQTTimerAllowance = 0.001f; // seconds
// Store both values now for use by next cycle.
_lastInstantaneousFps = instantaneousFps;
_lastUnsynchronizedFps = 1.0f / (((usecTimestampNow() - now) / (float)USECS_PER_SECOND) + paintWaitAndQTTimerAllowance);
_pendingPaint = false;
}
@ -3083,11 +3077,7 @@ void Application::update(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::update()");
if (DependencyManager::get<LODManager>()->getUseAcuity()) {
updateLOD();
} else {
DependencyManager::get<LODManager>()->updatePIDRenderDistance(getTargetFrameRate(), getLastInstanteousFps(), deltaTime, isThrottleRendering());
}
updateLOD();
{
PerformanceTimer perfTimer("devices");

View file

@ -157,7 +157,6 @@ public:
float getFps() const { return _fps; }
float getTargetFrameRate(); // frames/second
float getLastInstanteousFps() const { return _lastInstantaneousFps; }
float getLastUnsynchronizedFps() const { return _lastUnsynchronizedFps; }
float getFieldOfView() { return _fieldOfView.get(); }
void setFieldOfView(float fov);
@ -402,7 +401,6 @@ private:
QElapsedTimer _timerStart;
QElapsedTimer _lastTimeUpdated;
float _lastInstantaneousFps { 0.0f };
float _lastUnsynchronizedFps { 0.0f };
ShapeManager _shapeManager;
PhysicalEntitySimulation _entitySimulation;

View file

@ -20,29 +20,8 @@
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 adjusted by a PID such that frame rate targets are met.
// acuity: a pseudo-acuity target is held, or adjusted to match minimum frame rates (and a PID controlls avatar rendering distance)
// If unspecified, acuity is used only if user has specified non-default minumum frame rates.
Setting::Handle<int> lodPreference("lodPreference", (int)LODManager::LODPreference::acuity);
const float SMALLEST_REASONABLE_HORIZON = 50.0f; // meters
Setting::Handle<float> renderDistanceInverseHighLimit("renderDistanceInverseHighLimit", 1.0f / SMALLEST_REASONABLE_HORIZON);
void LODManager::setRenderDistanceInverseHighLimit(float newValue) {
renderDistanceInverseHighLimit.set(newValue); // persist it, and tell all the controllers that use it
_renderDistanceController.setControlledValueHighLimit(newValue);
}
LODManager::LODManager() {
setRenderDistanceInverseHighLimit(renderDistanceInverseHighLimit.get());
setRenderDistanceInverseLowLimit(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 LODManager.setRenderDistanceControllerHistory("render pid", 240))
//setRenderDistanceControllerHistory("render pid", 60 * 4);
// Note that extra logging/hysteresis is turned off in Avatar.cpp when the above logging is on.
setRenderDistanceKP(0.000012f); // Usually about 0.6 of largest that doesn't oscillate when other parameters 0.
setRenderDistanceKI(0.00002f); // Big enough to bring us to target with the above KP.
}
float LODManager::getLODDecreaseFPS() {
@ -234,53 +213,7 @@ 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;
}
QString LODManager::getLODStatsRenderText() {
const QString label = "Rendered objects: ";
return label + QString::number(getRenderedCount()) + " w/in " + QString::number((int)getRenderDistance()) + "m";
}
// compare autoAdjustLOD()
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) {
// NOTE: this branch of code is the alternate form of LOD that uses PID controllers.
if (!getUseAcuity()) {
float distanceToCamera = glm::length(bounds.calcCenter() - args->_viewFrustum->getPosition());
float largestDimension = bounds.getLargestDimension();
const float scenerySize = 300; // meters
bool isRendered = (largestDimension > scenerySize) || // render scenery regardless of distance
(distanceToCamera < renderDistance + largestDimension);
renderedCount += isRendered ? 1 : 0;
return isRendered;
}
// FIXME - eventually we want to use the render accuracy as an indicator for the level of detail
// to use in rendering.
float renderAccuracy = args->_viewFrustum->calculateRenderAccuracy(bounds, args->_sizeScale, args->_boundaryLevelAdjust);
@ -299,12 +232,6 @@ 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());
Menu::getInstance()->getSubMenuFromName(MenuOption::RenderResolution, Menu::getInstance()->getSubMenuFromName("Render", Menu::getInstance()->getMenu("Developer")))->setEnabled(getUseAcuity());
}
void LODManager::saveSettings() {

View file

@ -18,8 +18,8 @@
#include <PIDController.h>
#include <SimpleMovingAverage.h>
const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 15.0;
const float DEFAULT_HMD_LOD_DOWN_FPS = 30.0;
const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0;
const float DEFAULT_HMD_LOD_DOWN_FPS = 45.0;
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;
@ -76,27 +76,6 @@ 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 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 bool getRenderDistanceControllerIsLogging() { return _renderDistanceController.getIsLogging(); }
Q_INVOKABLE void setRenderDistanceControllerHistory(QString label, int size) { return _renderDistanceController.setHistorySize(label, size); }
Q_INVOKABLE float getRenderDistanceInverseLowLimit() { return _renderDistanceController.getControlledValueLowLimit(); }
Q_INVOKABLE void setRenderDistanceInverseLowLimit(float newValue) { _renderDistanceController.setControlledValueLowLimit(newValue); }
Q_INVOKABLE float getRenderDistanceInverseHighLimit() { return _renderDistanceController.getControlledValueHighLimit(); }
Q_INVOKABLE void setRenderDistanceInverseHighLimit(float newValue);
void updatePIDRenderDistance(float targetFps, float measuredFps, float deltaTime, bool isThrottled);
float getRenderDistance();
int getRenderedCount();
QString getLODStatsRenderText();
static bool shouldRender(const RenderArgs* args, const AABox& bounds);
void autoAdjustLOD(float currentFPS);
@ -126,9 +105,6 @@ private:
SimpleMovingAverage _fpsAverageStartWindow = START_DELAY_SAMPLES_OF_FRAMES;
SimpleMovingAverage _fpsAverageDownWindow = DOWN_SHIFT_SAMPLES_OF_FRAMES;
SimpleMovingAverage _fpsAverageUpWindow = UP_SHIFT_SAMPLES_OF_FRAMES;
PIDController _renderDistanceController{};
SimpleMovingAverage _renderDistanceAverage{ 10 };
};
#endif // hifi_LODManager_h

View file

@ -87,13 +87,6 @@ void setupPreferences() {
}
static const QString LOD_TUNING("Level of Detail Tuning");
CheckPreference* acuityToggle;
{
auto getter = []()->bool { return DependencyManager::get<LODManager>()->getUseAcuity(); };
auto setter = [](bool value) { DependencyManager::get<LODManager>()->setUseAcuity(value); };
preferences->addPreference(acuityToggle = new CheckPreference(LOD_TUNING, "Render based on visual acuity", getter, setter));
}
{
auto getter = []()->float { return DependencyManager::get<LODManager>()->getDesktopLODDecreaseFPS(); };
auto setter = [](float value) { DependencyManager::get<LODManager>()->setDesktopLODDecreaseFPS(value); };
@ -101,7 +94,6 @@ void setupPreferences() {
preference->setMin(0);
preference->setMax(120);
preference->setStep(1);
preference->setEnabler(acuityToggle);
preferences->addPreference(preference);
}
@ -112,18 +104,6 @@ void setupPreferences() {
preference->setMin(0);
preference->setMax(120);
preference->setStep(1);
preference->setEnabler(acuityToggle);
preferences->addPreference(preference);
}
{
auto getter = []()->float { return 1.0f / DependencyManager::get<LODManager>()->getRenderDistanceInverseHighLimit(); };
auto setter = [](float value) { DependencyManager::get<LODManager>()->setRenderDistanceInverseHighLimit(1.0f / value); };
auto preference = new SpinnerPreference(LOD_TUNING, "Minimum Display Distance", getter, setter);
preference->setMin(5);
preference->setMax(32768);
preference->setStep(1);
preference->setEnabler(acuityToggle, true);
preferences->addPreference(preference);
}

View file

@ -283,9 +283,7 @@ void Stats::updateStats(bool force) {
STAT_UPDATE(localLeaves, (int)OctreeElement::getLeafNodeCount());
// LOD Details
STAT_UPDATE(lodStatus, "You can see " + DependencyManager::get<LODManager>()->getLODFeedbackText());
STAT_UPDATE(lodStatsRenderText, DependencyManager::get<LODManager>()->getLODStatsRenderText());
}
STAT_UPDATE(showAcuity, (_expanded || force) && DependencyManager::get<LODManager>()->getUseAcuity());
bool performanceTimerIsActive = PerformanceTimer::isActive();
bool displayPerf = _expanded && Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails);

View file

@ -30,7 +30,6 @@ class Stats : public QQuickItem {
Q_PROPERTY(QString monospaceFont READ monospaceFont CONSTANT)
Q_PROPERTY(float audioPacketlossUpstream READ getAudioPacketLossUpstream)
Q_PROPERTY(float audioPacketlossDownstream READ getAudioPacketLossDownstream)
Q_PROPERTY(bool showAcuity READ getShowAcuity WRITE setShowAcuity NOTIFY showAcuityChanged)
STATS_PROPERTY(int, serverCount, 0)
STATS_PROPERTY(int, renderrate, 0)
@ -80,7 +79,6 @@ class Stats : public QQuickItem {
STATS_PROPERTY(QString, packetStats, QString())
STATS_PROPERTY(QString, lodStatus, QString())
STATS_PROPERTY(QString, timingStats, QString())
STATS_PROPERTY(QString, lodStatsRenderText, QString())
STATS_PROPERTY(int, serverElements, 0)
STATS_PROPERTY(int, serverInternal, 0)
STATS_PROPERTY(int, serverLeaves, 0)
@ -112,15 +110,12 @@ public:
emit expandedChanged();
}
}
bool getShowAcuity() { return _showAcuity; }
void setShowAcuity(bool newValue) { _showAcuity = newValue; }
public slots:
void forceUpdateStats() { updateStats(true); }
signals:
void expandedChanged();
void showAcuityChanged();
void timingExpandedChanged();
void serverCountChanged();
void renderrateChanged();
@ -128,7 +123,6 @@ signals:
void simrateChanged();
void avatarSimrateChanged();
void avatarCountChanged();
void lodStatsRenderTextChanged();
void packetInCountChanged();
void packetOutCountChanged();
void mbpsInChanged();
@ -182,7 +176,6 @@ private:
int _recentMaxPackets{ 0 } ; // recent max incoming voxel packets to process
bool _resetRecentMaxPacketsSoon{ true };
bool _expanded{ false };
bool _showAcuity{ false };
bool _timingExpanded{ false };
QString _monospaceFont;
const AudioIOStats* _audioStats;