mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 01:00:44 +02:00
fix throttled rendering for the 2D display plugin
This commit is contained in:
parent
5a442bdb30
commit
6a7f367e5f
9 changed files with 64 additions and 69 deletions
|
@ -175,8 +175,6 @@ public:
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Starfield information
|
// Starfield information
|
||||||
static uint8_t THROTTLED_IDLE_TIMER_DELAY = 10;
|
|
||||||
|
|
||||||
const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB
|
const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB
|
||||||
|
|
||||||
static QTimer* locationUpdateTimer = NULL;
|
static QTimer* locationUpdateTimer = NULL;
|
||||||
|
@ -737,6 +735,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
_keyboardFocusHighlight->setVisible(false);
|
_keyboardFocusHighlight->setVisible(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(this, &Application::applicationStateChanged, this, &Application::activeChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::aboutToQuit() {
|
void Application::aboutToQuit() {
|
||||||
|
@ -2108,8 +2108,11 @@ void Application::idle() {
|
||||||
// Once rendering is off on another thread we should be able to have Application::idle run at start(0) in
|
// Once rendering is off on another thread we should be able to have Application::idle run at start(0) in
|
||||||
// perpetuity and not expect events to get backed up.
|
// perpetuity and not expect events to get backed up.
|
||||||
|
|
||||||
|
bool isThrottled = getActiveDisplayPlugin()->isThrottled();
|
||||||
|
static const int THROTTLED_IDLE_TIMER_DELAY = MSECS_PER_SECOND / 15;
|
||||||
static const int IDLE_TIMER_DELAY_MS = 2;
|
static const int IDLE_TIMER_DELAY_MS = 2;
|
||||||
int desiredInterval = getActiveDisplayPlugin()->isThrottled() ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS;
|
int desiredInterval = isThrottled ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS;
|
||||||
|
//qDebug() << "isThrottled:" << isThrottled << "desiredInterval:" << desiredInterval;
|
||||||
|
|
||||||
if (idleTimer->interval() != desiredInterval) {
|
if (idleTimer->interval() != desiredInterval) {
|
||||||
idleTimer->start(desiredInterval);
|
idleTimer->start(desiredInterval);
|
||||||
|
@ -4612,6 +4615,24 @@ void Application::checkSkeleton() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Application::isForeground() {
|
||||||
|
return _isForeground && !getWindow()->isMinimized();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::activeChanged(Qt::ApplicationState state) {
|
||||||
|
switch (state) {
|
||||||
|
case Qt::ApplicationActive:
|
||||||
|
_isForeground = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::ApplicationSuspended:
|
||||||
|
case Qt::ApplicationHidden:
|
||||||
|
case Qt::ApplicationInactive:
|
||||||
|
default:
|
||||||
|
_isForeground = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
void Application::showFriendsWindow() {
|
void Application::showFriendsWindow() {
|
||||||
const QString FRIENDS_WINDOW_TITLE = "Add/Remove Friends";
|
const QString FRIENDS_WINDOW_TITLE = "Add/Remove Friends";
|
||||||
const QString FRIENDS_WINDOW_URL = "https://metaverse.highfidelity.com/user/friends";
|
const QString FRIENDS_WINDOW_URL = "https://metaverse.highfidelity.com/user/friends";
|
||||||
|
|
|
@ -291,6 +291,7 @@ public:
|
||||||
virtual void unsetFullscreen(const QScreen* avoid) override;
|
virtual void unsetFullscreen(const QScreen* avoid) override;
|
||||||
virtual void showDisplayPluginsTools() override;
|
virtual void showDisplayPluginsTools() override;
|
||||||
virtual QGLWidget* getPrimarySurface() override;
|
virtual QGLWidget* getPrimarySurface() override;
|
||||||
|
virtual bool isForeground() override;
|
||||||
|
|
||||||
void setActiveDisplayPlugin(const QString& pluginName);
|
void setActiveDisplayPlugin(const QString& pluginName);
|
||||||
|
|
||||||
|
@ -476,6 +477,7 @@ private slots:
|
||||||
void faceTrackerMuteToggled();
|
void faceTrackerMuteToggled();
|
||||||
|
|
||||||
void setCursorVisible(bool visible);
|
void setCursorVisible(bool visible);
|
||||||
|
void activeChanged(Qt::ApplicationState state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resetCameras(Camera& camera, const glm::uvec2& size);
|
void resetCameras(Camera& camera, const glm::uvec2& size);
|
||||||
|
@ -688,6 +690,7 @@ private:
|
||||||
SimpleMovingAverage _simsPerSecond{10};
|
SimpleMovingAverage _simsPerSecond{10};
|
||||||
int _simsPerSecondReport = 0;
|
int _simsPerSecondReport = 0;
|
||||||
quint64 _lastSimsPerSecondUpdate = 0;
|
quint64 _lastSimsPerSecondUpdate = 0;
|
||||||
|
bool _isForeground = true; // starts out assumed to be in foreground
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Application_h
|
#endif // hifi_Application_h
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
|
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
|
|
||||||
const int MSECS_PER_FRAME_WHEN_THROTTLED = 66;
|
|
||||||
|
|
||||||
static QGLFormat& getDesiredGLFormat() {
|
static QGLFormat& getDesiredGLFormat() {
|
||||||
// Specify an OpenGL 3.3 format using the Core profile.
|
// Specify an OpenGL 3.3 format using the Core profile.
|
||||||
// That is, no old-school fixed pipeline functionality
|
// That is, no old-school fixed pipeline functionality
|
||||||
|
@ -35,10 +33,7 @@ static QGLFormat& getDesiredGLFormat() {
|
||||||
return glFormat;
|
return glFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLCanvas::GLCanvas() : QGLWidget(getDesiredGLFormat()),
|
GLCanvas::GLCanvas() : QGLWidget(getDesiredGLFormat()) {
|
||||||
_throttleRendering(false),
|
|
||||||
_idleRenderInterval(MSECS_PER_FRAME_WHEN_THROTTLED)
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
// Cause GLCanvas::eventFilter to be called.
|
// Cause GLCanvas::eventFilter to be called.
|
||||||
// It wouldn't hurt to do this on Mac and PC too; but apparently it's only needed on linux.
|
// It wouldn't hurt to do this on Mac and PC too; but apparently it's only needed on linux.
|
||||||
|
@ -46,15 +41,6 @@ GLCanvas::GLCanvas() : QGLWidget(getDesiredGLFormat()),
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas::stopFrameTimer() {
|
|
||||||
_frameTimer.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GLCanvas::isThrottleRendering() const {
|
|
||||||
return (_throttleRendering
|
|
||||||
|| (Application::getInstance()->getWindow()->isMinimized() && Application::getInstance()->isThrottleFPSEnabled()));
|
|
||||||
}
|
|
||||||
|
|
||||||
int GLCanvas::getDeviceWidth() const {
|
int GLCanvas::getDeviceWidth() const {
|
||||||
return width() * (windowHandle() ? (float)windowHandle()->devicePixelRatio() : 1.0f);
|
return width() * (windowHandle() ? (float)windowHandle()->devicePixelRatio() : 1.0f);
|
||||||
}
|
}
|
||||||
|
@ -66,17 +52,17 @@ int GLCanvas::getDeviceHeight() const {
|
||||||
void GLCanvas::initializeGL() {
|
void GLCanvas::initializeGL() {
|
||||||
setAttribute(Qt::WA_AcceptTouchEvents);
|
setAttribute(Qt::WA_AcceptTouchEvents);
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
connect(Application::getInstance(), SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(activeChanged(Qt::ApplicationState)));
|
|
||||||
connect(&_frameTimer, SIGNAL(timeout()), this, SLOT(throttleRender()));
|
|
||||||
|
|
||||||
// Note, we *DO NOT* want Qt to automatically swap buffers for us. This results in the "ringing" bug mentioned in WL#19514 when we're throttling the framerate.
|
// Note, we *DO NOT* want Qt to automatically swap buffers for us. This results in the "ringing" bug mentioned in WL#19514 when we're throttling the framerate.
|
||||||
setAutoBufferSwap(false);
|
setAutoBufferSwap(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas::paintGL() {
|
void GLCanvas::paintGL() {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
if (!_throttleRendering &&
|
|
||||||
(!Application::getInstance()->getWindow()->isMinimized() || !Application::getInstance()->isThrottleFPSEnabled())) {
|
// FIXME - I'm not sure why this still remains, it appears as if this GLCanvas gets a single paintGL call near
|
||||||
|
// the beginning of the application starting up. I'm not sure if we really need to call Application::paintGL()
|
||||||
|
// in this case, since the display plugins eventually handle all the painting
|
||||||
|
if ((!Application::getInstance()->getWindow()->isMinimized() || !Application::getInstance()->isThrottleFPSEnabled())) {
|
||||||
Application::getInstance()->paintGL();
|
Application::getInstance()->paintGL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,39 +71,6 @@ void GLCanvas::resizeGL(int width, int height) {
|
||||||
Application::getInstance()->resizeGL();
|
Application::getInstance()->resizeGL();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas::activeChanged(Qt::ApplicationState state) {
|
|
||||||
switch (state) {
|
|
||||||
case Qt::ApplicationActive:
|
|
||||||
// If we're active, stop the frame timer and the throttle.
|
|
||||||
_frameTimer.stop();
|
|
||||||
_throttleRendering = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::ApplicationSuspended:
|
|
||||||
case Qt::ApplicationHidden:
|
|
||||||
// If we're hidden or are about to suspend, don't render anything.
|
|
||||||
_throttleRendering = false;
|
|
||||||
_frameTimer.stop();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Otherwise, throttle.
|
|
||||||
if (!_throttleRendering && !Application::getInstance()->isAboutToQuit()
|
|
||||||
&& Application::getInstance()->isThrottleFPSEnabled()) {
|
|
||||||
_frameTimer.start(_idleRenderInterval);
|
|
||||||
_throttleRendering = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLCanvas::throttleRender() {
|
|
||||||
_frameTimer.start(_idleRenderInterval);
|
|
||||||
if (!Application::getInstance()->getWindow()->isMinimized()) {
|
|
||||||
Application::getInstance()->paintGL();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int updateTime = 0;
|
int updateTime = 0;
|
||||||
bool GLCanvas::event(QEvent* event) {
|
bool GLCanvas::event(QEvent* event) {
|
||||||
switch (event->type()) {
|
switch (event->type()) {
|
||||||
|
|
|
@ -23,28 +23,18 @@ class GLCanvas : public QGLWidget {
|
||||||
public:
|
public:
|
||||||
GLCanvas();
|
GLCanvas();
|
||||||
|
|
||||||
void stopFrameTimer();
|
|
||||||
|
|
||||||
bool isThrottleRendering() const;
|
|
||||||
|
|
||||||
int getDeviceWidth() const;
|
int getDeviceWidth() const;
|
||||||
int getDeviceHeight() const;
|
int getDeviceHeight() const;
|
||||||
QSize getDeviceSize() const { return QSize(getDeviceWidth(), getDeviceHeight()); }
|
QSize getDeviceSize() const { return QSize(getDeviceWidth(), getDeviceHeight()); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
QTimer _frameTimer;
|
|
||||||
bool _throttleRendering;
|
|
||||||
int _idleRenderInterval;
|
|
||||||
|
|
||||||
virtual void initializeGL();
|
virtual void initializeGL();
|
||||||
virtual void paintGL();
|
virtual void paintGL();
|
||||||
virtual void resizeGL(int width, int height);
|
virtual void resizeGL(int width, int height);
|
||||||
virtual bool event(QEvent* event);
|
virtual bool event(QEvent* event);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void activeChanged(Qt::ApplicationState state);
|
|
||||||
void throttleRender();
|
|
||||||
bool eventFilter(QObject*, QEvent* event);
|
bool eventFilter(QObject*, QEvent* event);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -283,7 +283,7 @@ namespace MenuOption {
|
||||||
const QString TestPing = "Test Ping";
|
const QString TestPing = "Test Ping";
|
||||||
const QString ThirdPerson = "Third Person";
|
const QString ThirdPerson = "Third Person";
|
||||||
const QString ThreePointCalibration = "3 Point Calibration";
|
const QString ThreePointCalibration = "3 Point Calibration";
|
||||||
const QString ThrottleFPSIfNotFocus = "Throttle FPS If Not Focus";
|
const QString ThrottleFPSIfNotFocus = "Throttle FPS If Not Focus"; // FIXME - this value duplicated in Basic2DWindowOpenGLDisplayPlugin.cpp
|
||||||
const QString ToolWindow = "Tool Window";
|
const QString ToolWindow = "Tool Window";
|
||||||
const QString TransmitterDrive = "Transmitter Drive";
|
const QString TransmitterDrive = "Transmitter Drive";
|
||||||
const QString TurnWithHead = "Turn using Head";
|
const QString TurnWithHead = "Turn using Head";
|
||||||
|
|
|
@ -34,3 +34,24 @@ void Basic2DWindowOpenGLDisplayPlugin::deactivate() {
|
||||||
// container->removeMenu(MENU_PATH);
|
// container->removeMenu(MENU_PATH);
|
||||||
MainWindowOpenGLDisplayPlugin::deactivate();
|
MainWindowOpenGLDisplayPlugin::deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Basic2DWindowOpenGLDisplayPlugin::getDesiredInterval(bool isThrottled) const {
|
||||||
|
static const int THROTTLED_PAINT_TIMER_DELAY = MSECS_PER_SECOND / 15;
|
||||||
|
static const int PAINT_TIMER_DELAY_MS = 1;
|
||||||
|
|
||||||
|
return isThrottled ? THROTTLED_PAINT_TIMER_DELAY : PAINT_TIMER_DELAY_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Basic2DWindowOpenGLDisplayPlugin::isThrottled() const {
|
||||||
|
static const QString ThrottleFPSIfNotFocus = "Throttle FPS If Not Focus"; // FIXME - this value duplicated in Menu.h
|
||||||
|
|
||||||
|
bool shouldThrottle = (!CONTAINER->isForeground() && CONTAINER->isOptionChecked(ThrottleFPSIfNotFocus));
|
||||||
|
|
||||||
|
if (_isThrottled != shouldThrottle) {
|
||||||
|
int desiredInterval = getDesiredInterval(shouldThrottle);
|
||||||
|
_timer.start(desiredInterval);
|
||||||
|
_isThrottled = shouldThrottle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return shouldThrottle;
|
||||||
|
}
|
|
@ -18,6 +18,12 @@ public:
|
||||||
|
|
||||||
virtual const QString & getName() const override;
|
virtual const QString & getName() const override;
|
||||||
|
|
||||||
|
virtual bool isThrottled() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int getDesiredInterval(bool isThrottled) const;
|
||||||
|
mutable bool _isThrottled = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const QString NAME;
|
static const QString NAME;
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,8 +37,8 @@ protected:
|
||||||
virtual void doneCurrent() = 0;
|
virtual void doneCurrent() = 0;
|
||||||
virtual void swapBuffers() = 0;
|
virtual void swapBuffers() = 0;
|
||||||
|
|
||||||
QTimer _timer;
|
mutable QTimer _timer;
|
||||||
ProgramPtr _program;
|
ProgramPtr _program;
|
||||||
ShapeWrapperPtr _plane;
|
ShapeWrapperPtr _plane;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,4 +26,5 @@ public:
|
||||||
virtual void unsetFullscreen(const QScreen* avoidScreen = nullptr) = 0;
|
virtual void unsetFullscreen(const QScreen* avoidScreen = nullptr) = 0;
|
||||||
virtual void showDisplayPluginsTools() = 0;
|
virtual void showDisplayPluginsTools() = 0;
|
||||||
virtual QGLWidget* getPrimarySurface() = 0;
|
virtual QGLWidget* getPrimarySurface() = 0;
|
||||||
|
virtual bool isForeground() = 0;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue