mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Fix FPS counter
This commit is contained in:
parent
b87e8220c4
commit
df8ad57185
15 changed files with 166 additions and 137 deletions
|
@ -48,12 +48,22 @@ Item {
|
|||
Text {
|
||||
color: root.fontColor;
|
||||
font.pixelSize: root.fontSize
|
||||
text: "Render Rate: " + root.renderrate
|
||||
text: "Render Rate: " + root.renderrate.toFixed(2);
|
||||
}
|
||||
Text {
|
||||
color: root.fontColor;
|
||||
font.pixelSize: root.fontSize
|
||||
text: "Present Rate: " + root.presentrate
|
||||
text: "Present Rate: " + root.presentrate.toFixed(2);
|
||||
}
|
||||
Text {
|
||||
color: root.fontColor;
|
||||
font.pixelSize: root.fontSize
|
||||
text: "Present New Rate: " + root.presentnewrate.toFixed(2);
|
||||
}
|
||||
Text {
|
||||
color: root.fontColor;
|
||||
font.pixelSize: root.fontSize
|
||||
text: "Present Drop Rate: " + root.presentdroprate.toFixed(2);
|
||||
}
|
||||
Text {
|
||||
color: root.fontColor;
|
||||
|
|
|
@ -511,8 +511,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
_sessionRunTimer(startupTimer),
|
||||
_previousSessionCrashed(setupEssentials(argc, argv)),
|
||||
_undoStackScriptingInterface(&_undoStack),
|
||||
_frameCount(0),
|
||||
_fps(60.0f),
|
||||
_physicsEngine(new PhysicsEngine(Vectors::ZERO)),
|
||||
_entityClipboardRenderer(false, this, this),
|
||||
_entityClipboard(new EntityTree()),
|
||||
|
@ -1332,7 +1330,7 @@ void Application::initializeGL() {
|
|||
_idleLoopStdev.reset();
|
||||
|
||||
// update before the first render
|
||||
update(1.0f / _fps);
|
||||
update(0);
|
||||
|
||||
InfoView::show(INFO_HELP_PATH, true);
|
||||
}
|
||||
|
@ -1463,7 +1461,6 @@ void Application::initializeUi() {
|
|||
}
|
||||
|
||||
void Application::paintGL() {
|
||||
|
||||
updateHeartbeat();
|
||||
|
||||
// Some plugins process message events, potentially leading to
|
||||
|
@ -1481,24 +1478,7 @@ void Application::paintGL() {
|
|||
return;
|
||||
}
|
||||
_frameCount++;
|
||||
|
||||
// update fps moving average
|
||||
uint64_t now = usecTimestampNow();
|
||||
static uint64_t lastPaintBegin{ now };
|
||||
uint64_t diff = now - lastPaintBegin;
|
||||
float instantaneousFps = 0.0f;
|
||||
if (diff != 0) {
|
||||
instantaneousFps = (float)USECS_PER_SECOND / (float)diff;
|
||||
_framesPerSecond.updateAverage(_lastInstantaneousFps);
|
||||
}
|
||||
|
||||
lastPaintBegin = now;
|
||||
|
||||
// update fps once a second
|
||||
if (now - _lastFramesPerSecondUpdate > USECS_PER_SECOND) {
|
||||
_fps = _framesPerSecond.getAverage();
|
||||
_lastFramesPerSecondUpdate = now;
|
||||
}
|
||||
_frameCounter.increment();
|
||||
|
||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff0000ff, (uint64_t)_frameCount);
|
||||
PerformanceTimer perfTimer("paintGL");
|
||||
|
@ -1655,7 +1635,7 @@ void Application::paintGL() {
|
|||
}
|
||||
// Update camera position
|
||||
if (!isHMDMode()) {
|
||||
_myCamera.update(1.0f / _fps);
|
||||
_myCamera.update(1.0f / _frameCounter.rate());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1752,8 +1732,6 @@ void Application::paintGL() {
|
|||
batch.resetStages();
|
||||
});
|
||||
}
|
||||
|
||||
_lastInstantaneousFps = instantaneousFps;
|
||||
}
|
||||
|
||||
void Application::runTests() {
|
||||
|
@ -2625,32 +2603,19 @@ bool Application::acceptSnapshot(const QString& urlString) {
|
|||
static uint32_t _renderedFrameIndex { INVALID_FRAME };
|
||||
|
||||
void Application::idle(uint64_t now) {
|
||||
|
||||
// NOTICE NOTICE NOTICE NOTICE
|
||||
// Do not insert new code between here and the PROFILE_RANGE declaration
|
||||
// unless you know exactly what you're doing. This idle function can be
|
||||
// called thousands per second or more, so any additional work that's done
|
||||
// here will have a serious impact on CPU usage. Only add code after all
|
||||
// the thottling logic, i.e. after PROFILE_RANGE
|
||||
// NOTICE NOTICE NOTICE NOTICE
|
||||
updateHeartbeat();
|
||||
|
||||
if (_aboutToQuit || _inPaint) {
|
||||
return; // bail early, nothing to do here.
|
||||
}
|
||||
|
||||
// These tasks need to be done on our first idle, because we don't want the showing of
|
||||
// overlay subwindows to do a showDesktop() until after the first time through
|
||||
static bool firstIdle = true;
|
||||
if (firstIdle) {
|
||||
firstIdle = false;
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
connect(offscreenUi.data(), &OffscreenUi::showDesktop, this, &Application::showDesktop);
|
||||
_overlayConductor.setEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Overlays));
|
||||
}
|
||||
|
||||
// If the offscreen Ui has something active that is NOT the root, then assume it has keyboard focus.
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
if (_keyboardDeviceHasFocus && offscreenUi && offscreenUi->getWindow()->activeFocusItem() != offscreenUi->getRootItem()) {
|
||||
_keyboardMouseDevice->pluginFocusOutEvent();
|
||||
_keyboardDeviceHasFocus = false;
|
||||
} else if (offscreenUi && offscreenUi->getWindow()->activeFocusItem() == offscreenUi->getRootItem()) {
|
||||
_keyboardDeviceHasFocus = true;
|
||||
}
|
||||
|
||||
auto displayPlugin = getActiveDisplayPlugin();
|
||||
// depending on whether we're throttling or not.
|
||||
// Once rendering is off on another thread we should be able to have Application::idle run at start(0) in
|
||||
|
@ -2684,8 +2649,36 @@ void Application::idle(uint64_t now) {
|
|||
return;
|
||||
}
|
||||
|
||||
// NOTICE NOTICE NOTICE NOTICE
|
||||
// do NOT add new code above this line unless you want it to be executed potentially
|
||||
// thousands of times per second
|
||||
// NOTICE NOTICE NOTICE NOTICE
|
||||
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
|
||||
// These tasks need to be done on our first idle, because we don't want the showing of
|
||||
// overlay subwindows to do a showDesktop() until after the first time through
|
||||
static bool firstIdle = true;
|
||||
if (firstIdle) {
|
||||
firstIdle = false;
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
connect(offscreenUi.data(), &OffscreenUi::showDesktop, this, &Application::showDesktop);
|
||||
_overlayConductor.setEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Overlays));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// If the offscreen Ui has something active that is NOT the root, then assume it has keyboard focus.
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
if (_keyboardDeviceHasFocus && offscreenUi && offscreenUi->getWindow()->activeFocusItem() != offscreenUi->getRootItem()) {
|
||||
_keyboardMouseDevice->pluginFocusOutEvent();
|
||||
_keyboardDeviceHasFocus = false;
|
||||
} else if (offscreenUi && offscreenUi->getWindow()->activeFocusItem() == offscreenUi->getRootItem()) {
|
||||
_keyboardDeviceHasFocus = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// We're going to execute idle processing, so restart the last idle timer
|
||||
_lastTimeUpdated.start();
|
||||
|
||||
|
@ -2694,14 +2687,7 @@ void Application::idle(uint64_t now) {
|
|||
Stats::getInstance()->updateStats();
|
||||
AvatarInputs::getInstance()->update();
|
||||
|
||||
{
|
||||
static uint64_t lastIdleStart{ now };
|
||||
uint64_t idleStartToStartDuration = now - lastIdleStart;
|
||||
if (idleStartToStartDuration != 0) {
|
||||
_simsPerSecond.updateAverage((float)USECS_PER_SECOND / (float)idleStartToStartDuration);
|
||||
}
|
||||
lastIdleStart = now;
|
||||
}
|
||||
_simCounter.increment();
|
||||
|
||||
PerformanceTimer perfTimer("idle");
|
||||
// Drop focus from _keyboardFocusedItem if no keyboard messages for 30 seconds
|
||||
|
@ -2757,30 +2743,6 @@ void Application::idle(uint64_t now) {
|
|||
emit checkBackgroundDownloads();
|
||||
}
|
||||
|
||||
float Application::getAverageSimsPerSecond() {
|
||||
uint64_t now = usecTimestampNow();
|
||||
|
||||
if (now - _lastSimsPerSecondUpdate > USECS_PER_SECOND) {
|
||||
_simsPerSecondReport = _simsPerSecond.getAverage();
|
||||
_lastSimsPerSecondUpdate = now;
|
||||
}
|
||||
return _simsPerSecondReport;
|
||||
}
|
||||
|
||||
void Application::setAvatarSimrateSample(float sample) {
|
||||
_avatarSimsPerSecond.updateAverage(sample);
|
||||
}
|
||||
|
||||
float Application::getAvatarSimrate() {
|
||||
uint64_t now = usecTimestampNow();
|
||||
|
||||
if (now - _lastAvatarSimsPerSecondUpdate > USECS_PER_SECOND) {
|
||||
_avatarSimsPerSecondReport = _avatarSimsPerSecond.getAverage();
|
||||
_lastAvatarSimsPerSecondUpdate = now;
|
||||
}
|
||||
return _avatarSimsPerSecondReport;
|
||||
}
|
||||
|
||||
void Application::setLowVelocityFilter(bool lowVelocityFilter) {
|
||||
controller::InputDevice::setLowVelocityFilter(lowVelocityFilter);
|
||||
}
|
||||
|
@ -3051,7 +3013,7 @@ void Application::updateLOD() const {
|
|||
PerformanceTimer perfTimer("LOD");
|
||||
// adjust it unless we were asked to disable this feature, or if we're currently in throttleRendering mode
|
||||
if (!isThrottleRendering()) {
|
||||
DependencyManager::get<LODManager>()->autoAdjustLOD(_fps);
|
||||
DependencyManager::get<LODManager>()->autoAdjustLOD(_frameCounter.rate());
|
||||
} else {
|
||||
DependencyManager::get<LODManager>()->resetLODAdjust();
|
||||
}
|
||||
|
@ -3482,8 +3444,7 @@ void Application::update(float deltaTime) {
|
|||
// AvatarManager update
|
||||
{
|
||||
PerformanceTimer perfTimer("AvatarManger");
|
||||
|
||||
qApp->setAvatarSimrateSample(1.0f / deltaTime);
|
||||
_avatarSimCounter.increment();
|
||||
|
||||
{
|
||||
PROFILE_RANGE_EX("OtherAvatars", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||
|
@ -3805,7 +3766,8 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
bool Application::isHMDMode() const {
|
||||
return getActiveDisplayPlugin()->isHmd();
|
||||
}
|
||||
float Application::getTargetFrameRate() { return getActiveDisplayPlugin()->getTargetFrameRate(); }
|
||||
|
||||
float Application::getTargetFrameRate() const { return getActiveDisplayPlugin()->getTargetFrameRate(); }
|
||||
|
||||
QRect Application::getDesirableApplicationGeometry() const {
|
||||
QRect applicationGeometry = getWindow()->geometry();
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <StDev.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <AbstractUriHandler.h>
|
||||
#include <shared/RateCounter.h>
|
||||
|
||||
#include "avatar/MyAvatar.h"
|
||||
#include "Bookmarks.h"
|
||||
|
@ -155,10 +156,9 @@ public:
|
|||
|
||||
bool isForeground() const { return _isForeground; }
|
||||
|
||||
uint32_t getFrameCount() const { return _frameCount; }
|
||||
float getFps() const { return _fps; }
|
||||
float getTargetFrameRate(); // frames/second
|
||||
float getLastInstanteousFps() const { return _lastInstantaneousFps; }
|
||||
size_t getFrameCount() const { return _frameCount; }
|
||||
float getFps() const { return _frameCounter.rate(); }
|
||||
float getTargetFrameRate() const; // frames/second
|
||||
|
||||
float getFieldOfView() { return _fieldOfView.get(); }
|
||||
void setFieldOfView(float fov);
|
||||
|
@ -216,10 +216,9 @@ public:
|
|||
const QRect& getMirrorViewRect() const { return _mirrorViewRect; }
|
||||
|
||||
void updateMyAvatarLookAtPosition();
|
||||
float getAvatarSimrate();
|
||||
void setAvatarSimrateSample(float sample);
|
||||
|
||||
float getAverageSimsPerSecond();
|
||||
float getAvatarSimrate() const { return _avatarSimCounter.rate(); }
|
||||
float getAverageSimsPerSecond() const { return _simCounter.rate(); }
|
||||
|
||||
signals:
|
||||
void svoImportRequested(const QString& url);
|
||||
|
@ -396,12 +395,15 @@ private:
|
|||
QUndoStack _undoStack;
|
||||
UndoStackScriptingInterface _undoStackScriptingInterface;
|
||||
|
||||
uint32_t _frameCount { 0 };
|
||||
|
||||
// Frame Rate Measurement
|
||||
int _frameCount;
|
||||
float _fps;
|
||||
RateCounter<> _frameCounter;
|
||||
RateCounter<> _avatarSimCounter;
|
||||
RateCounter<> _simCounter;
|
||||
|
||||
QElapsedTimer _timerStart;
|
||||
QElapsedTimer _lastTimeUpdated;
|
||||
float _lastInstantaneousFps { 0.0f };
|
||||
|
||||
ShapeManager _shapeManager;
|
||||
PhysicalEntitySimulation _entitySimulation;
|
||||
|
@ -488,12 +490,6 @@ private:
|
|||
|
||||
EntityItemID _keyboardFocusedItem;
|
||||
quint64 _lastAcceptedKeyPress = 0;
|
||||
|
||||
SimpleMovingAverage _framesPerSecond{10};
|
||||
quint64 _lastFramesPerSecondUpdate = 0;
|
||||
SimpleMovingAverage _simsPerSecond{10};
|
||||
int _simsPerSecondReport = 0;
|
||||
quint64 _lastSimsPerSecondUpdate = 0;
|
||||
bool _isForeground = true; // starts out assumed to be in foreground
|
||||
bool _inPaint = false;
|
||||
bool _isGLInitialized { false };
|
||||
|
|
|
@ -117,11 +117,15 @@ void Stats::updateStats(bool force) {
|
|||
// we need to take one avatar out so we don't include ourselves
|
||||
STAT_UPDATE(avatarCount, avatarManager->size() - 1);
|
||||
STAT_UPDATE(serverCount, (int)nodeList->size());
|
||||
STAT_UPDATE(renderrate, (int)qApp->getFps());
|
||||
STAT_UPDATE(renderrate, qApp->getFps());
|
||||
if (qApp->getActiveDisplayPlugin()) {
|
||||
STAT_UPDATE(presentrate, (int)round(qApp->getActiveDisplayPlugin()->presentRate()));
|
||||
STAT_UPDATE(presentrate, qApp->getActiveDisplayPlugin()->presentRate());
|
||||
STAT_UPDATE(presentnewrate, qApp->getActiveDisplayPlugin()->newFramePresentRate());
|
||||
STAT_UPDATE(presentdroprate, qApp->getActiveDisplayPlugin()->droppedFrameRate());
|
||||
} else {
|
||||
STAT_UPDATE(presentrate, -1);
|
||||
STAT_UPDATE(presentnewrate, -1);
|
||||
STAT_UPDATE(presentdroprate, -1);
|
||||
}
|
||||
STAT_UPDATE(simrate, (int)qApp->getAverageSimsPerSecond());
|
||||
STAT_UPDATE(avatarSimrate, (int)qApp->getAvatarSimrate());
|
||||
|
|
|
@ -32,8 +32,10 @@ class Stats : public QQuickItem {
|
|||
Q_PROPERTY(float audioPacketlossDownstream READ getAudioPacketLossDownstream)
|
||||
|
||||
STATS_PROPERTY(int, serverCount, 0)
|
||||
STATS_PROPERTY(int, renderrate, 0)
|
||||
STATS_PROPERTY(int, presentrate, 0)
|
||||
STATS_PROPERTY(float, renderrate, 0)
|
||||
STATS_PROPERTY(float, presentrate, 0)
|
||||
STATS_PROPERTY(float, presentnewrate, 0)
|
||||
STATS_PROPERTY(float, presentdroprate, 0)
|
||||
STATS_PROPERTY(int, simrate, 0)
|
||||
STATS_PROPERTY(int, avatarSimrate, 0)
|
||||
STATS_PROPERTY(int, avatarCount, 0)
|
||||
|
@ -117,6 +119,8 @@ signals:
|
|||
void serverCountChanged();
|
||||
void renderrateChanged();
|
||||
void presentrateChanged();
|
||||
void presentnewrateChanged();
|
||||
void presentdroprateChanged();
|
||||
void simrateChanged();
|
||||
void avatarSimrateChanged();
|
||||
void avatarCountChanged();
|
||||
|
|
|
@ -30,8 +30,6 @@ bool Basic2DWindowOpenGLDisplayPlugin::internalActivate() {
|
|||
}
|
||||
}, true, false);
|
||||
|
||||
updateFramerate();
|
||||
|
||||
return Parent::internalActivate();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class Basic2DWindowOpenGLDisplayPlugin : public OpenGLDisplayPlugin {
|
|||
public:
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
|
||||
virtual float getTargetFrameRate() override { return _framerateTarget ? (float) _framerateTarget : TARGET_FRAMERATE_Basic2DWindowOpenGL; }
|
||||
virtual float getTargetFrameRate() const override { return _framerateTarget ? (float) _framerateTarget : TARGET_FRAMERATE_Basic2DWindowOpenGL; }
|
||||
|
||||
virtual bool internalActivate() override;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <CursorManager.h>
|
||||
#include "CompositorHelper.h"
|
||||
|
||||
|
||||
#if THREADED_PRESENT
|
||||
|
||||
// FIXME, for display plugins that don't block on something like vsync, just
|
||||
|
@ -415,25 +416,18 @@ void OpenGLDisplayPlugin::updateTextures() {
|
|||
if (_sceneTextureEscrow.fetchAndReleaseWithGpuWait(_currentSceneTexture)) {
|
||||
#endif
|
||||
updateFrameData();
|
||||
}
|
||||
_newFrameRate.increment();
|
||||
}
|
||||
|
||||
_overlayTextureEscrow.fetchSignaledAndRelease(_currentOverlayTexture);
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::updateFrameData() {
|
||||
Lock lock(_mutex);
|
||||
auto previousFrameIndex = _currentRenderFrameIndex;
|
||||
_currentRenderFrameIndex = _sceneTextureToFrameIndexMap[_currentSceneTexture];
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::updateFramerate() {
|
||||
uint64_t now = usecTimestampNow();
|
||||
static uint64_t lastSwapEnd { now };
|
||||
uint64_t diff = now - lastSwapEnd;
|
||||
lastSwapEnd = now;
|
||||
if (diff != 0) {
|
||||
Lock lock(_mutex);
|
||||
_usecsPerFrame.updateAverage(diff);
|
||||
}
|
||||
auto skippedCount = (_currentRenderFrameIndex - previousFrameIndex) - 1;
|
||||
_droppedFrameRate.increment(skippedCount);
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::compositeOverlay() {
|
||||
|
@ -545,19 +539,20 @@ void OpenGLDisplayPlugin::present() {
|
|||
compositeLayers();
|
||||
// Take the composite framebuffer and send it to the output device
|
||||
internalPresent();
|
||||
updateFramerate();
|
||||
_presentRate.increment();
|
||||
}
|
||||
}
|
||||
|
||||
float OpenGLDisplayPlugin::presentRate() {
|
||||
float result { -1.0f };
|
||||
{
|
||||
Lock lock(_mutex);
|
||||
result = _usecsPerFrame.getAverage();
|
||||
}
|
||||
result = 1.0f / result;
|
||||
result *= USECS_PER_SECOND;
|
||||
return result;
|
||||
float OpenGLDisplayPlugin::newFramePresentRate() const {
|
||||
return _newFrameRate.rate();
|
||||
}
|
||||
|
||||
float OpenGLDisplayPlugin::droppedFrameRate() const {
|
||||
return _droppedFrameRate.rate();
|
||||
}
|
||||
|
||||
float OpenGLDisplayPlugin::presentRate() const {
|
||||
return _presentRate.rate();
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::drawUnitQuad() {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "DisplayPlugin.h"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QImage>
|
||||
|
@ -18,6 +19,7 @@
|
|||
#include <SimpleMovingAverage.h>
|
||||
#include <gl/OglplusHelpers.h>
|
||||
#include <gl/GLEscrow.h>
|
||||
#include <shared/RateCounter.h>
|
||||
|
||||
#define THREADED_PRESENT 1
|
||||
|
||||
|
@ -41,7 +43,6 @@ public:
|
|||
|
||||
void submitSceneTexture(uint32_t frameIndex, const gpu::TexturePointer& sceneTexture) override;
|
||||
void submitOverlayTexture(const gpu::TexturePointer& overlayTexture) override;
|
||||
float presentRate() override;
|
||||
|
||||
glm::uvec2 getRecommendedRenderSize() const override {
|
||||
return getSurfacePixels();
|
||||
|
@ -53,6 +54,12 @@ public:
|
|||
|
||||
QImage getScreenshot() const override;
|
||||
|
||||
float presentRate() const override;
|
||||
|
||||
float newFramePresentRate() const override;
|
||||
|
||||
float droppedFrameRate() const override;
|
||||
|
||||
protected:
|
||||
#if THREADED_PRESENT
|
||||
friend class PresentThread;
|
||||
|
@ -88,7 +95,6 @@ protected:
|
|||
|
||||
void present();
|
||||
void updateTextures();
|
||||
void updateFramerate();
|
||||
void drawUnitQuad();
|
||||
void swapBuffers();
|
||||
void eyeViewport(Eye eye) const;
|
||||
|
@ -101,7 +107,9 @@ protected:
|
|||
ShapeWrapperPtr _plane;
|
||||
|
||||
mutable Mutex _mutex;
|
||||
SimpleMovingAverage _usecsPerFrame { 10 };
|
||||
RateCounter<> _droppedFrameRate;
|
||||
RateCounter<> _newFrameRate;
|
||||
RateCounter<> _presentRate;
|
||||
QMap<gpu::TexturePointer, uint32_t> _sceneTextureToFrameIndexMap;
|
||||
uint32_t _currentRenderFrameIndex { 0 };
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ public:
|
|||
/// By default, all HMDs are stereo
|
||||
virtual bool isStereo() const { return isHmd(); }
|
||||
virtual bool isThrottled() const { return false; }
|
||||
virtual float getTargetFrameRate() { return 0.0f; }
|
||||
virtual float getTargetFrameRate() const { return 0.0f; }
|
||||
|
||||
/// Returns a boolean value indicating whether the display is currently visible
|
||||
/// to the user. For monitor displays, false might indicate that a screensaver,
|
||||
|
@ -142,7 +142,12 @@ public:
|
|||
virtual void abandonCalibration() {}
|
||||
virtual void resetSensors() {}
|
||||
virtual float devicePixelRatio() { return 1.0f; }
|
||||
virtual float presentRate() { return -1.0f; }
|
||||
// Rate at which we present to the display device
|
||||
virtual float presentRate() const { return -1.0f; }
|
||||
// Rate at which new frames are being presented to the display device
|
||||
virtual float newFramePresentRate() const { return -1.0f; }
|
||||
// Rate at which rendered frames are being skipped
|
||||
virtual float droppedFrameRate() const { return -1.0f; }
|
||||
uint32_t presentCount() const { return _presentedFrameIndex; }
|
||||
|
||||
virtual void cycleDebugOutput() {}
|
||||
|
|
47
libraries/shared/src/shared/RateCounter.h
Normal file
47
libraries/shared/src/shared/RateCounter.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis 2016/04/10
|
||||
// Copyright 2013-2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef hifi_Shared_RateCounter_h
|
||||
#define hifi_Shared_RateCounter_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <functional>
|
||||
#include <QtCore/QElapsedTimer>
|
||||
|
||||
#include "../SharedUtil.h"
|
||||
#include "../NumericalConstants.h"
|
||||
|
||||
template <uint32_t INTERVAL = MSECS_PER_SECOND, uint8_t PRECISION = 2>
|
||||
class RateCounter {
|
||||
public:
|
||||
void increment(size_t count = 1) {
|
||||
auto now = usecTimestampNow();
|
||||
auto currentIntervalMs = (uint32_t)((now - _start) / USECS_PER_MSEC);
|
||||
if (currentIntervalMs > INTERVAL) {
|
||||
float currentCount = _count;
|
||||
float intervalSeconds = (float)currentIntervalMs / (float)MSECS_PER_SECOND;
|
||||
_rate = roundf(currentCount / intervalSeconds * _scale) / _scale;
|
||||
};
|
||||
_count += count;
|
||||
}
|
||||
|
||||
float rate() const { return _rate; }
|
||||
|
||||
uint8_t precision() const { return PRECISION; }
|
||||
|
||||
uint32_t interval() const { return INTERVAL; }
|
||||
|
||||
private:
|
||||
uint64_t _start { usecTimestampNow() };
|
||||
size_t _count { 0 };
|
||||
float _rate { 0 };
|
||||
const float _scale { powf(10, PRECISION) };
|
||||
};
|
||||
|
||||
#endif
|
|
@ -21,7 +21,7 @@ public:
|
|||
// Stereo specific methods
|
||||
virtual void resetSensors() override final;
|
||||
virtual void beginFrameRender(uint32_t frameIndex) override;
|
||||
float getTargetFrameRate() override { return _hmdDesc.DisplayRefreshRate; }
|
||||
float getTargetFrameRate() const override { return _hmdDesc.DisplayRefreshRate; }
|
||||
|
||||
|
||||
protected:
|
||||
|
|
|
@ -181,7 +181,7 @@ int OculusLegacyDisplayPlugin::getHmdScreen() const {
|
|||
return _hmdScreen;
|
||||
}
|
||||
|
||||
float OculusLegacyDisplayPlugin::getTargetFrameRate() {
|
||||
float OculusLegacyDisplayPlugin::getTargetFrameRate() const {
|
||||
return TARGET_RATE_OculusLegacy;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
virtual void resetSensors() override;
|
||||
virtual void beginFrameRender(uint32_t frameIndex) override;
|
||||
|
||||
virtual float getTargetFrameRate() override;
|
||||
virtual float getTargetFrameRate() const override;
|
||||
|
||||
protected:
|
||||
virtual bool internalActivate() override;
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
virtual bool isSupported() const override;
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
|
||||
virtual float getTargetFrameRate() override { return TARGET_RATE_OpenVr; }
|
||||
virtual float getTargetFrameRate() const override { return TARGET_RATE_OpenVr; }
|
||||
|
||||
virtual void customizeContext() override;
|
||||
|
||||
|
|
Loading…
Reference in a new issue