making requested changes

This commit is contained in:
danteruiz 2019-04-25 16:02:12 -07:00
parent 0bdc37859d
commit 9e1671a1bf
9 changed files with 65 additions and 41 deletions

View file

@ -81,7 +81,9 @@ Item {
visible: root.expanded
text: " RefreshRateController:\n " +
"refreshRateTarget:\t " + root.refreshRateTarget + "\n " +
"refreshRateMode:\t " + root.refreshRateMode ;
"refreshRateMode:\t " + root.refreshRateMode + "\n " +
"refreshRateRegime:\t " + root.refreshRateRegime + "\n " +
"uxMode:\t " + root.uxMode;
}
StatText {
visible: root.expanded

View file

@ -84,9 +84,20 @@ void RefreshRateManager::setRefreshRateProfile(RefreshRateManager::RefreshRatePr
}
RefreshRateManager::RefreshRateProfile RefreshRateManager::getRefreshRateProfile() const {
return (RefreshRateManager::RefreshRateProfile) _refreshRateModeLock.resultWithReadLock<int>([&] {
return _refreshRateMode.get();
});
RefreshRateManager::RefreshRateProfile profile = RefreshRateManager::RefreshRateProfile::REALTIME;
if (getUXMode() != RefreshRateManager::UXMode::HMD) {
profile =(RefreshRateManager::RefreshRateProfile) _refreshRateModeLock.resultWithReadLock<int>([&] {
return _refreshRateMode.get();
});
}
return profile;
}
RefreshRateManager::RefreshRateRegime RefreshRateManager::getRefreshRateRegime() const {
return getUXMode() == RefreshRateManager::UXMode::HMD ? RefreshRateManager::RefreshRateRegime::RUNNING :
_refreshRateRegime;
}
void RefreshRateManager::setRefreshRateRegime(RefreshRateManager::RefreshRateRegime refreshRateRegime) {

View file

@ -49,7 +49,7 @@ public:
RefreshRateProfile getRefreshRateProfile() const;
void setRefreshRateRegime(RefreshRateRegime refreshRateRegime);
RefreshRateRegime getRefreshRateRegime() const { return _refreshRateRegime; }
RefreshRateRegime getRefreshRateRegime() const;
void setUXMode(UXMode uxMode);
UXMode getUXMode() const { return _uxMode; }

View file

@ -224,7 +224,11 @@ void Stats::updateStats(bool force) {
if (_expanded || force) {
RefreshRateManager& refreshRateManager = qApp->getRefreshRateManager();
std::string refreshRateMode = RefreshRateManager::refreshRateProfileToString(refreshRateManager.getRefreshRateProfile());
std::string refreshRateRegime = RefreshRateManager::refreshRateRegimeToString(refreshRateManager.getRefreshRateRegime());
std::string uxMode = RefreshRateManager::uxModeToString(refreshRateManager.getUXMode());
STAT_UPDATE(refreshRateMode, QString::fromStdString(refreshRateMode));
STAT_UPDATE(refreshRateRegime, QString::fromStdString(refreshRateRegime));
STAT_UPDATE(uxMode, QString::fromStdString(uxMode));
STAT_UPDATE(refreshRateTarget, refreshRateManager.getActiveRefreshRate());
SharedNodePointer avatarMixer = nodeList->soloNodeOfType(NodeType::AvatarMixer);
if (avatarMixer) {

View file

@ -208,6 +208,8 @@ class Stats : public QQuickItem {
STATS_PROPERTY(int, avatarCount, 0)
STATS_PROPERTY(int, refreshRateTarget, 0)
STATS_PROPERTY(QString, refreshRateMode, QString())
STATS_PROPERTY(QString, refreshRateRegime, QString())
STATS_PROPERTY(QString, uxMode, QString())
STATS_PROPERTY(int, heroAvatarCount, 0)
STATS_PROPERTY(int, physicsObjectCount, 0)
STATS_PROPERTY(int, updatedAvatarCount, 0)
@ -1074,6 +1076,10 @@ signals:
void refreshRateModeChanged();
void refreshRateRegimeChanged();
void uxModeChanged();
// QQuickItem signals.
/**jsdoc

View file

@ -183,18 +183,14 @@ public:
}
// Execute the frame and present it to the display device.
_refreshRateController->clockStartTime();
{
PROFILE_RANGE(render, "PluginPresent")
gl::globalLock();
currentPlugin->present();
currentPlugin->present(_refreshRateController);
gl::globalRelease(false);
CHECK_GL_ERROR();
}
// stop time
_refreshRateController->clockEndTime();
_refreshRateController->sleepThreadIfNeeded(this);
// sleep if needed
_refreshRateController->sleepThreadIfNeeded(this, currentPlugin->isHmd());
}
_context->doneCurrent();
@ -697,7 +693,7 @@ void OpenGLDisplayPlugin::internalPresent() {
_presentRate.increment();
}
void OpenGLDisplayPlugin::present() {
void OpenGLDisplayPlugin::present(const std::shared_ptr<RefreshRateController>& refreshRateController) {
auto frameId = (uint64_t)presentCount();
PROFILE_RANGE_EX(render, __FUNCTION__, 0xffffff00, frameId)
uint64_t startPresent = usecTimestampNow();
@ -708,6 +704,7 @@ void OpenGLDisplayPlugin::present() {
}
incrementPresentCount();
refreshRateController->clockStartTime();
if (_currentFrame) {
auto correction = getViewCorrection();
getGLBackend()->setCameraCorrection(correction, _prevRenderView);
@ -745,6 +742,7 @@ void OpenGLDisplayPlugin::present() {
}
// Take the composite framebuffer and send it to the output device
refreshRateController->clockEndTime();
{
PROFILE_RANGE_EX(render, "internalPresent", 0xff00ffff, frameId)
internalPresent();
@ -752,7 +750,10 @@ void OpenGLDisplayPlugin::present() {
gpu::Backend::freeGPUMemSize.set(gpu::gl::getFreeDedicatedMemory());
} else if (alwaysPresent()) {
refreshRateController->clockEndTime();
internalPresent();
} else {
refreshRateController->clockEndTime();
}
_movingAveragePresent.addSample((float)(usecTimestampNow() - startPresent));
}
@ -772,7 +773,7 @@ float OpenGLDisplayPlugin::presentRate() const {
std::function<void(int)> OpenGLDisplayPlugin::getRefreshRateOperator() {
return [](int targetRefreshRate) {
auto refreshRateController = DependencyManager::get<PresentThread>()->getRefreshRateController();
refreshRateController->setRefreshRateLimit(targetRefreshRate);
refreshRateController->setRefreshRateLimitPeriod(targetRefreshRate);
};
}

View file

@ -128,7 +128,7 @@ protected:
void withOtherThreadContext(std::function<void()> f) const;
void present();
void present(const std::shared_ptr<RefreshRateController>& refreshRateController);
virtual void swapBuffers();
ivec4 eyeViewport(Eye eye) const;

View file

@ -12,31 +12,32 @@
#include "RefreshRateController.h"
#include <QtCore/QThread>
#include <NumericalConstants.h>
int refreshRateConverter(int refreshRate) {
const float ONE_SECOND_IN_MILLISECONDS = 1000.0f;
const float ONE_TIME_UNIT = 1.0f;
float frameInOneTimeUnit = ONE_TIME_UNIT / (float) refreshRate;
float convertedRefreshRate = frameInOneTimeUnit * ONE_SECOND_IN_MILLISECONDS;
return (int) convertedRefreshRate;
long int hzToDurationNanoseconds(int refreshRate) {
return (int64_t) (NSECS_PER_SECOND / (quint64) refreshRate);
}
void RefreshRateController::setRefreshRateLimit(int refreshRateLimit) {
_refreshRateLimit = refreshRateConverter(refreshRateLimit);
int durationNanosecondsToHz(int64_t refreshRateLimitPeriod) {
return (int) (NSECS_PER_SECOND / (quint64) refreshRateLimitPeriod);
}
int RefreshRateController::getRefreshRateLimit() const {
return refreshRateConverter(_refreshRateLimit);
void RefreshRateController::setRefreshRateLimitPeriod(int refreshRateLimit) {
_refreshRateLimitPeriod = hzToDurationNanoseconds(refreshRateLimit);
}
void RefreshRateController::sleepThreadIfNeeded(QThread* thread) {
auto startTimeFromEpoch = _startTime.time_since_epoch();
auto endTimeFromEpoch = _endTime.time_since_epoch();
int RefreshRateController::getRefreshRateLimitPeriod() const {
return durationNanosecondsToHz(_refreshRateLimitPeriod);
}
auto startMs = std::chrono::duration_cast<std::chrono::milliseconds>(startTimeFromEpoch).count();
auto endMs = std::chrono::duration_cast<std::chrono::milliseconds>(endTimeFromEpoch).count();
auto duration = endMs - startMs;
if (duration < _refreshRateLimit) {
thread->msleep(_refreshRateLimit - duration);
void RefreshRateController::sleepThreadIfNeeded(QThread* thread, bool isHmd) {
if (!isHmd) {
static const std::chrono::nanoseconds EPSILON = std::chrono::milliseconds(1);
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(_endTime - _startTime);
auto refreshRateLimitPeriod = std::chrono::nanoseconds(_refreshRateLimitPeriod);
auto sleepDuration = refreshRateLimitPeriod - (duration + EPSILON);
if (sleepDuration.count() > 0) {
thread->msleep(std::chrono::duration_cast<std::chrono::milliseconds>(sleepDuration).count());
}
}
}

View file

@ -24,17 +24,16 @@ public:
RefreshRateController() = default;
~RefreshRateController() = default;
void setRefreshRateLimit(int refreshRateLimiti);
int getRefreshRateLimit() const;
void setRefreshRateLimitPeriod(int refreshRateLimit);
int getRefreshRateLimitPeriod() const;
void clockStartTime() { _startTime = std::chrono::system_clock::now(); }
void clockEndTime() { _endTime = std::chrono::system_clock::now(); }
void sleepThreadIfNeeded(QThread* thread);
void clockStartTime() { _startTime = std::chrono::high_resolution_clock::now(); }
void clockEndTime() { _endTime = std::chrono::high_resolution_clock::now(); }
void sleepThreadIfNeeded(QThread* thread, bool isHmd);
private:
std::chrono::time_point<std::chrono::system_clock> _startTime { std::chrono::system_clock::now() };
std::chrono::time_point<std::chrono::system_clock> _endTime { std::chrono::system_clock::now() };
std::atomic_int _refreshRateLimit { 50 }; // milliseconds
std::chrono::time_point<std::chrono::high_resolution_clock> _startTime { std::chrono::high_resolution_clock::now() };
std::chrono::time_point<std::chrono::high_resolution_clock> _endTime { std::chrono::high_resolution_clock::now() };
std::atomic<int64_t> _refreshRateLimitPeriod { 50 };
};