mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 17:10:45 +02:00
making requested changes
This commit is contained in:
parent
0bdc37859d
commit
9e1671a1bf
9 changed files with 65 additions and 41 deletions
|
@ -81,7 +81,9 @@ Item {
|
||||||
visible: root.expanded
|
visible: root.expanded
|
||||||
text: " RefreshRateController:\n " +
|
text: " RefreshRateController:\n " +
|
||||||
"refreshRateTarget:\t " + root.refreshRateTarget + "\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 {
|
StatText {
|
||||||
visible: root.expanded
|
visible: root.expanded
|
||||||
|
|
|
@ -84,9 +84,20 @@ void RefreshRateManager::setRefreshRateProfile(RefreshRateManager::RefreshRatePr
|
||||||
}
|
}
|
||||||
|
|
||||||
RefreshRateManager::RefreshRateProfile RefreshRateManager::getRefreshRateProfile() const {
|
RefreshRateManager::RefreshRateProfile RefreshRateManager::getRefreshRateProfile() const {
|
||||||
return (RefreshRateManager::RefreshRateProfile) _refreshRateModeLock.resultWithReadLock<int>([&] {
|
RefreshRateManager::RefreshRateProfile profile = RefreshRateManager::RefreshRateProfile::REALTIME;
|
||||||
|
|
||||||
|
if (getUXMode() != RefreshRateManager::UXMode::HMD) {
|
||||||
|
profile =(RefreshRateManager::RefreshRateProfile) _refreshRateModeLock.resultWithReadLock<int>([&] {
|
||||||
return _refreshRateMode.get();
|
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) {
|
void RefreshRateManager::setRefreshRateRegime(RefreshRateManager::RefreshRateRegime refreshRateRegime) {
|
||||||
|
|
|
@ -49,7 +49,7 @@ public:
|
||||||
RefreshRateProfile getRefreshRateProfile() const;
|
RefreshRateProfile getRefreshRateProfile() const;
|
||||||
|
|
||||||
void setRefreshRateRegime(RefreshRateRegime refreshRateRegime);
|
void setRefreshRateRegime(RefreshRateRegime refreshRateRegime);
|
||||||
RefreshRateRegime getRefreshRateRegime() const { return _refreshRateRegime; }
|
RefreshRateRegime getRefreshRateRegime() const;
|
||||||
|
|
||||||
void setUXMode(UXMode uxMode);
|
void setUXMode(UXMode uxMode);
|
||||||
UXMode getUXMode() const { return _uxMode; }
|
UXMode getUXMode() const { return _uxMode; }
|
||||||
|
|
|
@ -224,7 +224,11 @@ void Stats::updateStats(bool force) {
|
||||||
if (_expanded || force) {
|
if (_expanded || force) {
|
||||||
RefreshRateManager& refreshRateManager = qApp->getRefreshRateManager();
|
RefreshRateManager& refreshRateManager = qApp->getRefreshRateManager();
|
||||||
std::string refreshRateMode = RefreshRateManager::refreshRateProfileToString(refreshRateManager.getRefreshRateProfile());
|
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(refreshRateMode, QString::fromStdString(refreshRateMode));
|
||||||
|
STAT_UPDATE(refreshRateRegime, QString::fromStdString(refreshRateRegime));
|
||||||
|
STAT_UPDATE(uxMode, QString::fromStdString(uxMode));
|
||||||
STAT_UPDATE(refreshRateTarget, refreshRateManager.getActiveRefreshRate());
|
STAT_UPDATE(refreshRateTarget, refreshRateManager.getActiveRefreshRate());
|
||||||
SharedNodePointer avatarMixer = nodeList->soloNodeOfType(NodeType::AvatarMixer);
|
SharedNodePointer avatarMixer = nodeList->soloNodeOfType(NodeType::AvatarMixer);
|
||||||
if (avatarMixer) {
|
if (avatarMixer) {
|
||||||
|
|
|
@ -208,6 +208,8 @@ class Stats : public QQuickItem {
|
||||||
STATS_PROPERTY(int, avatarCount, 0)
|
STATS_PROPERTY(int, avatarCount, 0)
|
||||||
STATS_PROPERTY(int, refreshRateTarget, 0)
|
STATS_PROPERTY(int, refreshRateTarget, 0)
|
||||||
STATS_PROPERTY(QString, refreshRateMode, QString())
|
STATS_PROPERTY(QString, refreshRateMode, QString())
|
||||||
|
STATS_PROPERTY(QString, refreshRateRegime, QString())
|
||||||
|
STATS_PROPERTY(QString, uxMode, QString())
|
||||||
STATS_PROPERTY(int, heroAvatarCount, 0)
|
STATS_PROPERTY(int, heroAvatarCount, 0)
|
||||||
STATS_PROPERTY(int, physicsObjectCount, 0)
|
STATS_PROPERTY(int, physicsObjectCount, 0)
|
||||||
STATS_PROPERTY(int, updatedAvatarCount, 0)
|
STATS_PROPERTY(int, updatedAvatarCount, 0)
|
||||||
|
@ -1074,6 +1076,10 @@ signals:
|
||||||
|
|
||||||
void refreshRateModeChanged();
|
void refreshRateModeChanged();
|
||||||
|
|
||||||
|
void refreshRateRegimeChanged();
|
||||||
|
|
||||||
|
void uxModeChanged();
|
||||||
|
|
||||||
// QQuickItem signals.
|
// QQuickItem signals.
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
|
|
@ -183,18 +183,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the frame and present it to the display device.
|
// Execute the frame and present it to the display device.
|
||||||
_refreshRateController->clockStartTime();
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE(render, "PluginPresent")
|
PROFILE_RANGE(render, "PluginPresent")
|
||||||
gl::globalLock();
|
gl::globalLock();
|
||||||
currentPlugin->present();
|
currentPlugin->present(_refreshRateController);
|
||||||
gl::globalRelease(false);
|
gl::globalRelease(false);
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
// stop time
|
_refreshRateController->sleepThreadIfNeeded(this, currentPlugin->isHmd());
|
||||||
_refreshRateController->clockEndTime();
|
|
||||||
_refreshRateController->sleepThreadIfNeeded(this);
|
|
||||||
// sleep if needed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_context->doneCurrent();
|
_context->doneCurrent();
|
||||||
|
@ -697,7 +693,7 @@ void OpenGLDisplayPlugin::internalPresent() {
|
||||||
_presentRate.increment();
|
_presentRate.increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::present() {
|
void OpenGLDisplayPlugin::present(const std::shared_ptr<RefreshRateController>& refreshRateController) {
|
||||||
auto frameId = (uint64_t)presentCount();
|
auto frameId = (uint64_t)presentCount();
|
||||||
PROFILE_RANGE_EX(render, __FUNCTION__, 0xffffff00, frameId)
|
PROFILE_RANGE_EX(render, __FUNCTION__, 0xffffff00, frameId)
|
||||||
uint64_t startPresent = usecTimestampNow();
|
uint64_t startPresent = usecTimestampNow();
|
||||||
|
@ -708,6 +704,7 @@ void OpenGLDisplayPlugin::present() {
|
||||||
}
|
}
|
||||||
incrementPresentCount();
|
incrementPresentCount();
|
||||||
|
|
||||||
|
refreshRateController->clockStartTime();
|
||||||
if (_currentFrame) {
|
if (_currentFrame) {
|
||||||
auto correction = getViewCorrection();
|
auto correction = getViewCorrection();
|
||||||
getGLBackend()->setCameraCorrection(correction, _prevRenderView);
|
getGLBackend()->setCameraCorrection(correction, _prevRenderView);
|
||||||
|
@ -745,6 +742,7 @@ void OpenGLDisplayPlugin::present() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take the composite framebuffer and send it to the output device
|
// Take the composite framebuffer and send it to the output device
|
||||||
|
refreshRateController->clockEndTime();
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX(render, "internalPresent", 0xff00ffff, frameId)
|
PROFILE_RANGE_EX(render, "internalPresent", 0xff00ffff, frameId)
|
||||||
internalPresent();
|
internalPresent();
|
||||||
|
@ -752,7 +750,10 @@ void OpenGLDisplayPlugin::present() {
|
||||||
|
|
||||||
gpu::Backend::freeGPUMemSize.set(gpu::gl::getFreeDedicatedMemory());
|
gpu::Backend::freeGPUMemSize.set(gpu::gl::getFreeDedicatedMemory());
|
||||||
} else if (alwaysPresent()) {
|
} else if (alwaysPresent()) {
|
||||||
|
refreshRateController->clockEndTime();
|
||||||
internalPresent();
|
internalPresent();
|
||||||
|
} else {
|
||||||
|
refreshRateController->clockEndTime();
|
||||||
}
|
}
|
||||||
_movingAveragePresent.addSample((float)(usecTimestampNow() - startPresent));
|
_movingAveragePresent.addSample((float)(usecTimestampNow() - startPresent));
|
||||||
}
|
}
|
||||||
|
@ -772,7 +773,7 @@ float OpenGLDisplayPlugin::presentRate() const {
|
||||||
std::function<void(int)> OpenGLDisplayPlugin::getRefreshRateOperator() {
|
std::function<void(int)> OpenGLDisplayPlugin::getRefreshRateOperator() {
|
||||||
return [](int targetRefreshRate) {
|
return [](int targetRefreshRate) {
|
||||||
auto refreshRateController = DependencyManager::get<PresentThread>()->getRefreshRateController();
|
auto refreshRateController = DependencyManager::get<PresentThread>()->getRefreshRateController();
|
||||||
refreshRateController->setRefreshRateLimit(targetRefreshRate);
|
refreshRateController->setRefreshRateLimitPeriod(targetRefreshRate);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ protected:
|
||||||
|
|
||||||
void withOtherThreadContext(std::function<void()> f) const;
|
void withOtherThreadContext(std::function<void()> f) const;
|
||||||
|
|
||||||
void present();
|
void present(const std::shared_ptr<RefreshRateController>& refreshRateController);
|
||||||
virtual void swapBuffers();
|
virtual void swapBuffers();
|
||||||
ivec4 eyeViewport(Eye eye) const;
|
ivec4 eyeViewport(Eye eye) const;
|
||||||
|
|
||||||
|
|
|
@ -12,31 +12,32 @@
|
||||||
#include "RefreshRateController.h"
|
#include "RefreshRateController.h"
|
||||||
|
|
||||||
#include <QtCore/QThread>
|
#include <QtCore/QThread>
|
||||||
|
#include <NumericalConstants.h>
|
||||||
|
|
||||||
int refreshRateConverter(int refreshRate) {
|
long int hzToDurationNanoseconds(int refreshRate) {
|
||||||
const float ONE_SECOND_IN_MILLISECONDS = 1000.0f;
|
return (int64_t) (NSECS_PER_SECOND / (quint64) refreshRate);
|
||||||
const float ONE_TIME_UNIT = 1.0f;
|
|
||||||
float frameInOneTimeUnit = ONE_TIME_UNIT / (float) refreshRate;
|
|
||||||
float convertedRefreshRate = frameInOneTimeUnit * ONE_SECOND_IN_MILLISECONDS;
|
|
||||||
return (int) convertedRefreshRate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RefreshRateController::setRefreshRateLimit(int refreshRateLimit) {
|
int durationNanosecondsToHz(int64_t refreshRateLimitPeriod) {
|
||||||
_refreshRateLimit = refreshRateConverter(refreshRateLimit);
|
return (int) (NSECS_PER_SECOND / (quint64) refreshRateLimitPeriod);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RefreshRateController::getRefreshRateLimit() const {
|
void RefreshRateController::setRefreshRateLimitPeriod(int refreshRateLimit) {
|
||||||
return refreshRateConverter(_refreshRateLimit);
|
_refreshRateLimitPeriod = hzToDurationNanoseconds(refreshRateLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RefreshRateController::sleepThreadIfNeeded(QThread* thread) {
|
int RefreshRateController::getRefreshRateLimitPeriod() const {
|
||||||
auto startTimeFromEpoch = _startTime.time_since_epoch();
|
return durationNanosecondsToHz(_refreshRateLimitPeriod);
|
||||||
auto endTimeFromEpoch = _endTime.time_since_epoch();
|
}
|
||||||
|
|
||||||
auto startMs = std::chrono::duration_cast<std::chrono::milliseconds>(startTimeFromEpoch).count();
|
void RefreshRateController::sleepThreadIfNeeded(QThread* thread, bool isHmd) {
|
||||||
auto endMs = std::chrono::duration_cast<std::chrono::milliseconds>(endTimeFromEpoch).count();
|
if (!isHmd) {
|
||||||
auto duration = endMs - startMs;
|
static const std::chrono::nanoseconds EPSILON = std::chrono::milliseconds(1);
|
||||||
if (duration < _refreshRateLimit) {
|
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(_endTime - _startTime);
|
||||||
thread->msleep(_refreshRateLimit - duration);
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,17 +24,16 @@ public:
|
||||||
RefreshRateController() = default;
|
RefreshRateController() = default;
|
||||||
~RefreshRateController() = default;
|
~RefreshRateController() = default;
|
||||||
|
|
||||||
void setRefreshRateLimit(int refreshRateLimiti);
|
void setRefreshRateLimitPeriod(int refreshRateLimit);
|
||||||
int getRefreshRateLimit() const;
|
int getRefreshRateLimitPeriod() const;
|
||||||
|
|
||||||
void clockStartTime() { _startTime = std::chrono::system_clock::now(); }
|
void clockStartTime() { _startTime = std::chrono::high_resolution_clock::now(); }
|
||||||
void clockEndTime() { _endTime = std::chrono::system_clock::now(); }
|
void clockEndTime() { _endTime = std::chrono::high_resolution_clock::now(); }
|
||||||
void sleepThreadIfNeeded(QThread* thread);
|
void sleepThreadIfNeeded(QThread* thread, bool isHmd);
|
||||||
private:
|
private:
|
||||||
|
std::chrono::time_point<std::chrono::high_resolution_clock> _startTime { std::chrono::high_resolution_clock::now() };
|
||||||
std::chrono::time_point<std::chrono::system_clock> _startTime { std::chrono::system_clock::now() };
|
std::chrono::time_point<std::chrono::high_resolution_clock> _endTime { std::chrono::high_resolution_clock::now() };
|
||||||
std::chrono::time_point<std::chrono::system_clock> _endTime { std::chrono::system_clock::now() };
|
std::atomic<int64_t> _refreshRateLimitPeriod { 50 };
|
||||||
std::atomic_int _refreshRateLimit { 50 }; // milliseconds
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue