mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 02:53:43 +02:00
Merge pull request #7044 from jherico/optional_threaded_present
Make threaded present optional
This commit is contained in:
commit
89648f3c2e
2 changed files with 73 additions and 22 deletions
|
@ -21,11 +21,13 @@
|
|||
#include <gl/GLWidget.h>
|
||||
#include <NumericalConstants.h>
|
||||
#include <DependencyManager.h>
|
||||
|
||||
#include <plugins/PluginContainer.h>
|
||||
#include <gl/Config.h>
|
||||
#include <gl/GLEscrow.h>
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
#if THREADED_PRESENT
|
||||
class PresentThread : public QThread, public Dependency {
|
||||
using Mutex = std::mutex;
|
||||
using Condition = std::condition_variable;
|
||||
|
@ -33,16 +35,25 @@ class PresentThread : public QThread, public Dependency {
|
|||
public:
|
||||
|
||||
PresentThread() {
|
||||
connect(qApp, &QCoreApplication::aboutToQuit, [this]{
|
||||
_shutdown = true;
|
||||
connect(qApp, &QCoreApplication::aboutToQuit, [this] {
|
||||
shutdown();
|
||||
});
|
||||
}
|
||||
|
||||
~PresentThread() {
|
||||
_shutdown = true;
|
||||
wait();
|
||||
shutdown();
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
if (isRunning()) {
|
||||
Lock lock(_mutex);
|
||||
_shutdown = true;
|
||||
_condition.wait(lock, [&] { return !_shutdown; });
|
||||
qDebug() << "Present thread shutdown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setNewDisplayPlugin(OpenGLDisplayPlugin* plugin) {
|
||||
Lock lock(_mutex);
|
||||
_newPlugin = plugin;
|
||||
|
@ -120,6 +131,10 @@ public:
|
|||
}
|
||||
_context->doneCurrent();
|
||||
_context->moveToThread(qApp->thread());
|
||||
|
||||
Lock lock(_mutex);
|
||||
_shutdown = false;
|
||||
_condition.notify_one();
|
||||
}
|
||||
|
||||
void withMainThreadContext(std::function<void()> f) {
|
||||
|
@ -159,16 +174,14 @@ private:
|
|||
QGLContext* _context { nullptr };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
OpenGLDisplayPlugin::OpenGLDisplayPlugin() {
|
||||
_sceneTextureEscrow.setRecycler([this](GLuint texture){
|
||||
cleanupForSceneTexture(texture);
|
||||
_container->releaseSceneTexture(texture);
|
||||
});
|
||||
|
||||
_overlayTextureEscrow.setRecycler([this](GLuint texture) {
|
||||
_container->releaseOverlayTexture(texture);
|
||||
});
|
||||
|
||||
connect(&_timer, &QTimer::timeout, this, [&] {
|
||||
#ifdef Q_OS_MAC
|
||||
// On Mac, QT thread timing is such that we can miss one or even two cycles quite often, giving a render rate (including update/simulate)
|
||||
|
@ -191,9 +204,10 @@ void OpenGLDisplayPlugin::cleanupForSceneTexture(uint32_t sceneTexture) {
|
|||
|
||||
|
||||
void OpenGLDisplayPlugin::activate() {
|
||||
_timer.start(1);
|
||||
_vsyncSupported = _container->getPrimaryWidget()->isVsyncSupported();
|
||||
|
||||
#if THREADED_PRESENT
|
||||
_timer.start(1);
|
||||
// Start the present thread if necessary
|
||||
auto presentThread = DependencyManager::get<PresentThread>();
|
||||
if (!presentThread) {
|
||||
|
@ -208,7 +222,15 @@ void OpenGLDisplayPlugin::activate() {
|
|||
presentThread->start();
|
||||
}
|
||||
presentThread->setNewDisplayPlugin(this);
|
||||
#else
|
||||
static auto widget = _container->getPrimaryWidget();
|
||||
widget->makeCurrent();
|
||||
customizeContext();
|
||||
_container->makeRenderingContextCurrent();
|
||||
#endif
|
||||
DisplayPlugin::activate();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::stop() {
|
||||
|
@ -216,19 +238,27 @@ void OpenGLDisplayPlugin::stop() {
|
|||
}
|
||||
|
||||
void OpenGLDisplayPlugin::deactivate() {
|
||||
#if THREADED_PRESENT
|
||||
{
|
||||
Lock lock(_mutex);
|
||||
_deactivateWait.wait(lock, [&]{ return _uncustomized; });
|
||||
}
|
||||
_timer.stop();
|
||||
#else
|
||||
static auto widget = _container->getPrimaryWidget();
|
||||
widget->makeCurrent();
|
||||
uncustomizeContext();
|
||||
_container->makeRenderingContextCurrent();
|
||||
#endif
|
||||
DisplayPlugin::deactivate();
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::customizeContext() {
|
||||
#if THREADED_PRESENT
|
||||
_uncustomized = false;
|
||||
auto presentThread = DependencyManager::get<PresentThread>();
|
||||
Q_ASSERT(thread() == presentThread->thread());
|
||||
|
||||
#endif
|
||||
enableVsync();
|
||||
|
||||
using namespace oglplus;
|
||||
|
@ -297,16 +327,23 @@ void OpenGLDisplayPlugin::submitSceneTexture(uint32_t frameIndex, uint32_t scene
|
|||
|
||||
// Submit it to the presentation thread via escrow
|
||||
_sceneTextureEscrow.submit(sceneTexture);
|
||||
|
||||
#if THREADED_PRESENT
|
||||
#else
|
||||
static auto widget = _container->getPrimaryWidget();
|
||||
widget->makeCurrent();
|
||||
present();
|
||||
_container->makeRenderingContextCurrent();
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::submitOverlayTexture(GLuint sceneTexture, const glm::uvec2& sceneSize) {
|
||||
void OpenGLDisplayPlugin::submitOverlayTexture(GLuint overlayTexture, const glm::uvec2& overlaySize) {
|
||||
// Submit it to the presentation thread via escrow
|
||||
_overlayTextureEscrow.submit(sceneTexture);
|
||||
_currentOverlayTexture = overlayTexture;
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::updateTextures() {
|
||||
_currentSceneTexture = _sceneTextureEscrow.fetchAndRelease(_currentSceneTexture);
|
||||
_currentOverlayTexture = _overlayTextureEscrow.fetchAndRelease(_currentOverlayTexture);
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::updateFramerate() {
|
||||
|
@ -337,6 +374,11 @@ void OpenGLDisplayPlugin::present() {
|
|||
internalPresent();
|
||||
updateFramerate();
|
||||
}
|
||||
|
||||
#if THREADED_PRESENT
|
||||
#else
|
||||
emit requestRender();
|
||||
#endif
|
||||
}
|
||||
|
||||
float OpenGLDisplayPlugin::presentRate() {
|
||||
|
@ -351,12 +393,8 @@ float OpenGLDisplayPlugin::presentRate() {
|
|||
}
|
||||
|
||||
void OpenGLDisplayPlugin::drawUnitQuad() {
|
||||
try {
|
||||
_program->Bind();
|
||||
_plane->Draw();
|
||||
} catch (const oglplus::Error& error) {
|
||||
qWarning() << "The present thread encountered an error writing the scene texture to the output: " << error.what();
|
||||
}
|
||||
_program->Bind();
|
||||
_plane->Draw();
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::enableVsync(bool enable) {
|
||||
|
@ -385,9 +423,16 @@ void OpenGLDisplayPlugin::swapBuffers() {
|
|||
}
|
||||
|
||||
void OpenGLDisplayPlugin::withMainThreadContext(std::function<void()> f) const {
|
||||
#if THREADED_PRESENT
|
||||
static auto presentThread = DependencyManager::get<PresentThread>();
|
||||
presentThread->withMainThreadContext(f);
|
||||
_container->makeRenderingContextCurrent();
|
||||
#else
|
||||
static auto widget = _container->getPrimaryWidget();
|
||||
widget->makeCurrent();
|
||||
f();
|
||||
_container->makeRenderingContextCurrent();
|
||||
#endif
|
||||
}
|
||||
|
||||
QImage OpenGLDisplayPlugin::getScreenshot() const {
|
||||
|
@ -399,8 +444,10 @@ QImage OpenGLDisplayPlugin::getScreenshot() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
#if THREADED_PRESENT
|
||||
void OpenGLDisplayPlugin::enableDeactivate() {
|
||||
Lock lock(_mutex);
|
||||
_uncustomized = true;
|
||||
_deactivateWait.notify_one();
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -18,6 +18,8 @@
|
|||
#include <gl/OglplusHelpers.h>
|
||||
#include <gl/GLEscrow.h>
|
||||
|
||||
#define THREADED_PRESENT 1
|
||||
|
||||
class OpenGLDisplayPlugin : public DisplayPlugin {
|
||||
protected:
|
||||
using Mutex = std::mutex;
|
||||
|
@ -45,8 +47,9 @@ public:
|
|||
virtual QImage getScreenshot() const override;
|
||||
|
||||
protected:
|
||||
#if THREADED_PRESENT
|
||||
friend class PresentThread;
|
||||
|
||||
#endif
|
||||
|
||||
virtual glm::uvec2 getSurfaceSize() const = 0;
|
||||
virtual glm::uvec2 getSurfacePixels() const = 0;
|
||||
|
@ -81,15 +84,16 @@ protected:
|
|||
GLuint _currentSceneTexture { 0 };
|
||||
GLuint _currentOverlayTexture { 0 };
|
||||
|
||||
GLTextureEscrow _overlayTextureEscrow;
|
||||
GLTextureEscrow _sceneTextureEscrow;
|
||||
|
||||
bool _vsyncSupported { false };
|
||||
|
||||
private:
|
||||
#if THREADED_PRESENT
|
||||
void enableDeactivate();
|
||||
Condition _deactivateWait;
|
||||
bool _uncustomized{ false };
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue