mirror of
https://github.com/overte-org/overte.git
synced 2025-04-12 09:42:11 +02:00
Refactoring present thread / GL base plugin for saner context management
This commit is contained in:
parent
d8bb9f8d18
commit
7262a10e62
6 changed files with 42 additions and 69 deletions
|
@ -26,17 +26,17 @@ DisplayPluginList getDisplayPlugins() {
|
|||
DisplayPlugin* PLUGIN_POOL[] = {
|
||||
new Basic2DWindowOpenGLDisplayPlugin(),
|
||||
new NullDisplayPlugin(),
|
||||
//#ifdef DEBUG
|
||||
//#endif
|
||||
//
|
||||
// // Stereo modes
|
||||
//
|
||||
// // SBS left/right
|
||||
// new SideBySideStereoDisplayPlugin(),
|
||||
// // Interleaved left/right
|
||||
// new InterleavedStereoDisplayPlugin(),
|
||||
//
|
||||
// // HMDs
|
||||
#ifdef DEBUG
|
||||
#endif
|
||||
|
||||
// Stereo modes
|
||||
|
||||
// SBS left/right
|
||||
new SideBySideStereoDisplayPlugin(),
|
||||
// Interleaved left/right
|
||||
new InterleavedStereoDisplayPlugin(),
|
||||
|
||||
// HMDs
|
||||
//#ifdef Q_OS_WIN
|
||||
// // SteamVR SDK
|
||||
// new OpenVrDisplayPlugin(),
|
||||
|
|
|
@ -28,8 +28,6 @@ class PresentThread : public QThread, public Dependency {
|
|||
using Mutex = std::mutex;
|
||||
using Condition = std::condition_variable;
|
||||
using Lock = std::unique_lock<Mutex>;
|
||||
|
||||
friend class OpenGLDisplayPlugin;
|
||||
public:
|
||||
|
||||
~PresentThread() {
|
||||
|
@ -42,6 +40,14 @@ public:
|
|||
_newPlugin = plugin;
|
||||
}
|
||||
|
||||
void setContext(QGLContext * context) {
|
||||
// Move the OpenGL context to the present thread
|
||||
// Extra code because of the widget 'wrapper' context
|
||||
_context = context;
|
||||
_context->moveToThread(this);
|
||||
_context->contextHandle()->moveToThread(this);
|
||||
}
|
||||
|
||||
virtual void run() override {
|
||||
Q_ASSERT(_context);
|
||||
while (!_shutdown) {
|
||||
|
@ -50,7 +56,7 @@ public:
|
|||
Lock lock(_mutex);
|
||||
// Move the context to the main thread
|
||||
_context->moveToThread(qApp->thread());
|
||||
_widgetContext->moveToThread(qApp->thread());
|
||||
_context->contextHandle()->moveToThread(qApp->thread());
|
||||
_pendingMainThreadOperation = false;
|
||||
// Release the main thread to do it's action
|
||||
_condition.notify_one();
|
||||
|
@ -67,6 +73,7 @@ public:
|
|||
// Check before lock
|
||||
if (_newPlugin != nullptr) {
|
||||
Lock lock(_mutex);
|
||||
_context->makeCurrent();
|
||||
// Check if we have a new plugin to activate
|
||||
if (_newPlugin != nullptr) {
|
||||
// Deactivate the old plugin
|
||||
|
@ -77,8 +84,8 @@ public:
|
|||
_newPlugin->customizeContext();
|
||||
_activePlugin = _newPlugin;
|
||||
_newPlugin = nullptr;
|
||||
_context->doneCurrent();
|
||||
}
|
||||
_context->doneCurrent();
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
|
@ -89,12 +96,14 @@ public:
|
|||
}
|
||||
|
||||
// take the latest texture and present it
|
||||
_context->makeCurrent();
|
||||
_activePlugin->present();
|
||||
|
||||
_context->doneCurrent();
|
||||
}
|
||||
|
||||
_context->doneCurrent();
|
||||
_widgetContext->moveToThread(qApp->thread());
|
||||
_context->moveToThread(qApp->thread());
|
||||
_context->contextHandle()->moveToThread(qApp->thread());
|
||||
}
|
||||
|
||||
void withMainThreadContext(std::function<void()> f) {
|
||||
|
@ -104,14 +113,16 @@ public:
|
|||
_finishedMainThreadOperation = false;
|
||||
_condition.wait(lock, [&] { return !_pendingMainThreadOperation; });
|
||||
|
||||
_widgetContext->makeCurrent();
|
||||
_context->makeCurrent();
|
||||
f();
|
||||
_widgetContext->doneCurrent();
|
||||
_context->doneCurrent();
|
||||
|
||||
// Move the context back to the presentation thread
|
||||
_context->moveToThread(this);
|
||||
_context->contextHandle()->moveToThread(this);
|
||||
|
||||
// restore control of the context to the presentation thread and signal
|
||||
// the end of the operation
|
||||
_widgetContext->moveToThread(this);
|
||||
_context->moveToThread(this);
|
||||
_finishedMainThreadOperation = true;
|
||||
lock.unlock();
|
||||
_condition.notify_one();
|
||||
|
@ -119,6 +130,9 @@ public:
|
|||
|
||||
|
||||
private:
|
||||
void makeCurrent();
|
||||
void doneCurrent();
|
||||
|
||||
bool _shutdown { false };
|
||||
Mutex _mutex;
|
||||
// Used to allow the main thread to perform context operations
|
||||
|
@ -128,8 +142,7 @@ private:
|
|||
QThread* _mainThread { nullptr };
|
||||
OpenGLDisplayPlugin* _newPlugin { nullptr };
|
||||
OpenGLDisplayPlugin* _activePlugin { nullptr };
|
||||
QOpenGLContext* _context { nullptr };
|
||||
QGLContext* _widgetContext { nullptr };
|
||||
QGLContext* _context { nullptr };
|
||||
};
|
||||
|
||||
OpenGLDisplayPlugin::OpenGLDisplayPlugin() {
|
||||
|
@ -165,16 +178,8 @@ void OpenGLDisplayPlugin::activate() {
|
|||
DependencyManager::set<PresentThread>();
|
||||
presentThread = DependencyManager::get<PresentThread>();
|
||||
presentThread->setObjectName("Presentation Thread");
|
||||
|
||||
auto widget = _container->getPrimaryWidget();
|
||||
|
||||
// Move the OpenGL context to the present thread
|
||||
// Extra code because of the widget 'wrapper' context
|
||||
presentThread->_widgetContext = widget->context();
|
||||
presentThread->_widgetContext->moveToThread(presentThread.data());
|
||||
presentThread->_context = presentThread->_widgetContext->contextHandle();
|
||||
presentThread->_context->moveToThread(presentThread.data());
|
||||
|
||||
presentThread->setContext(widget->context());
|
||||
// Start execution
|
||||
presentThread->start();
|
||||
}
|
||||
|
@ -196,9 +201,6 @@ void OpenGLDisplayPlugin::customizeContext() {
|
|||
auto presentThread = DependencyManager::get<PresentThread>();
|
||||
Q_ASSERT(thread() == presentThread->thread());
|
||||
|
||||
bool makeCurrentResult = makeCurrent();
|
||||
Q_ASSERT(makeCurrentResult);
|
||||
|
||||
// TODO: write the proper code for linux
|
||||
#if defined(Q_OS_WIN)
|
||||
_vsyncSupported = wglewGetExtension("WGL_EXT_swap_control");
|
||||
|
@ -213,15 +215,11 @@ void OpenGLDisplayPlugin::customizeContext() {
|
|||
|
||||
_program = loadDefaultShader();
|
||||
_plane = loadPlane(_program);
|
||||
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::uncustomizeContext() {
|
||||
makeCurrent();
|
||||
_program.reset();
|
||||
_plane.reset();
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
// Pressing Alt (and Meta) key alone activates the menubar because its style inherits the
|
||||
|
@ -310,19 +308,11 @@ void OpenGLDisplayPlugin::internalPresent() {
|
|||
}
|
||||
|
||||
void OpenGLDisplayPlugin::present() {
|
||||
auto makeCurrentResult = makeCurrent();
|
||||
Q_ASSERT(makeCurrentResult);
|
||||
if (!makeCurrentResult) {
|
||||
qDebug() << "Failed to make current";
|
||||
return;
|
||||
}
|
||||
|
||||
updateTextures();
|
||||
if (_currentSceneTexture) {
|
||||
internalPresent();
|
||||
updateFramerate();
|
||||
}
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
float OpenGLDisplayPlugin::presentRate() {
|
||||
|
@ -360,18 +350,6 @@ bool OpenGLDisplayPlugin::isVsyncEnabled() {
|
|||
return true;
|
||||
#endif
|
||||
}
|
||||
bool OpenGLDisplayPlugin::makeCurrent() {
|
||||
static auto widget = _container->getPrimaryWidget();
|
||||
widget->makeCurrent();
|
||||
auto result = widget->context()->contextHandle() == QOpenGLContext::currentContext();
|
||||
Q_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::doneCurrent() {
|
||||
static auto widget = _container->getPrimaryWidget();
|
||||
widget->doneCurrent();
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::swapBuffers() {
|
||||
static auto widget = _container->getPrimaryWidget();
|
||||
|
|
|
@ -63,8 +63,6 @@ protected:
|
|||
void updateTextures();
|
||||
void updateFramerate();
|
||||
void drawUnitQuad();
|
||||
bool makeCurrent();
|
||||
void doneCurrent();
|
||||
void swapBuffers();
|
||||
// Plugin specific functionality to composite the scene and overlay and present the result
|
||||
virtual void internalPresent();
|
||||
|
|
|
@ -67,5 +67,9 @@ glm::uvec2 InterleavedStereoDisplayPlugin::getRecommendedRenderSize() const {
|
|||
}
|
||||
|
||||
void InterleavedStereoDisplayPlugin::internalPresent() {
|
||||
// FIXME
|
||||
using namespace oglplus;
|
||||
_program->Bind();
|
||||
auto sceneSize = getRecommendedRenderSize();
|
||||
Uniform<ivec2>(*_program, "textureSize").SetValue(sceneSize);
|
||||
WindowOpenGLDisplayPlugin::internalPresent();
|
||||
}
|
||||
|
|
|
@ -55,11 +55,9 @@ bool OculusBaseDisplayPlugin::isSupported() const {
|
|||
|
||||
// DLL based display plugins MUST initialize GLEW inside the DLL code.
|
||||
void OculusBaseDisplayPlugin::customizeContext() {
|
||||
makeCurrent();
|
||||
glewExperimental = true;
|
||||
GLenum err = glewInit();
|
||||
glGetError();
|
||||
doneCurrent();
|
||||
WindowOpenGLDisplayPlugin::customizeContext();
|
||||
}
|
||||
|
||||
|
|
|
@ -154,8 +154,6 @@ void OculusDisplayPlugin::activate() {
|
|||
|
||||
void OculusDisplayPlugin::customizeContext() {
|
||||
OculusBaseDisplayPlugin::customizeContext();
|
||||
bool makeCurrentResult = makeCurrent();
|
||||
Q_ASSERT(makeCurrentResult);
|
||||
#if (OVR_MAJOR_VERSION >= 6)
|
||||
_sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_hmd));
|
||||
_sceneFbo->Init(getRecommendedRenderSize());
|
||||
|
@ -169,14 +167,11 @@ void OculusDisplayPlugin::customizeContext() {
|
|||
enableVsync(false);
|
||||
// Only enable mirroring if we know vsync is disabled
|
||||
_enablePreview = !isVsyncEnabled();
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
void OculusDisplayPlugin::uncustomizeContext() {
|
||||
#if (OVR_MAJOR_VERSION >= 6)
|
||||
makeCurrent();
|
||||
_sceneFbo.reset();
|
||||
doneCurrent();
|
||||
#endif
|
||||
OculusBaseDisplayPlugin::uncustomizeContext();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue