mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 01:24:36 +02:00
Fix debug assert in manipulating thread local data to store GL surfaces
This commit is contained in:
parent
748c8cdc58
commit
44816941fc
2 changed files with 40 additions and 7 deletions
|
@ -17,15 +17,18 @@
|
||||||
#include <QtCore/QProcessEnvironment>
|
#include <QtCore/QProcessEnvironment>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QThread>
|
#include <QtCore/QThread>
|
||||||
|
#include <QtCore/QThreadStorage>
|
||||||
|
#include <QtCore/QPointer>
|
||||||
#include <QtGui/QOffscreenSurface>
|
#include <QtGui/QOffscreenSurface>
|
||||||
#include <QtGui/QOpenGLContext>
|
#include <QtGui/QOpenGLContext>
|
||||||
#include <QtGui/QOpenGLDebugLogger>
|
#include <QtGui/QOpenGLDebugLogger>
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
#include "Context.h"
|
#include "Context.h"
|
||||||
#include "GLHelpers.h"
|
#include "GLHelpers.h"
|
||||||
#include "GLLogging.h"
|
#include "GLLogging.h"
|
||||||
|
|
||||||
|
|
||||||
OffscreenGLCanvas::OffscreenGLCanvas() :
|
OffscreenGLCanvas::OffscreenGLCanvas() :
|
||||||
_context(new QOpenGLContext),
|
_context(new QOpenGLContext),
|
||||||
_offscreenSurface(new QOffscreenSurface)
|
_offscreenSurface(new QOffscreenSurface)
|
||||||
|
@ -33,6 +36,8 @@ OffscreenGLCanvas::OffscreenGLCanvas() :
|
||||||
}
|
}
|
||||||
|
|
||||||
OffscreenGLCanvas::~OffscreenGLCanvas() {
|
OffscreenGLCanvas::~OffscreenGLCanvas() {
|
||||||
|
clearThreadContext();
|
||||||
|
|
||||||
// A context with logging enabled needs to be current when it's destroyed
|
// A context with logging enabled needs to be current when it's destroyed
|
||||||
_context->makeCurrent(_offscreenSurface);
|
_context->makeCurrent(_offscreenSurface);
|
||||||
delete _context;
|
delete _context;
|
||||||
|
@ -117,25 +122,51 @@ QObject* OffscreenGLCanvas::getContextObject() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenGLCanvas::moveToThreadWithContext(QThread* thread) {
|
void OffscreenGLCanvas::moveToThreadWithContext(QThread* thread) {
|
||||||
|
clearThreadContext();
|
||||||
moveToThread(thread);
|
moveToThread(thread);
|
||||||
_context->moveToThread(thread);
|
_context->moveToThread(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* THREAD_CONTEXT_PROPERTY = "offscreenGlCanvas";
|
struct ThreadContextStorage : public Dependency {
|
||||||
|
QThreadStorage<QPointer<OffscreenGLCanvas>> threadContext;
|
||||||
|
};
|
||||||
|
|
||||||
void OffscreenGLCanvas::setThreadContext() {
|
void OffscreenGLCanvas::setThreadContext() {
|
||||||
QThread::currentThread()->setProperty(THREAD_CONTEXT_PROPERTY, QVariant::fromValue<QObject*>(this));
|
if (!DependencyManager::isSet<ThreadContextStorage>()) {
|
||||||
|
DependencyManager::set<ThreadContextStorage>();
|
||||||
|
}
|
||||||
|
auto threadContextStorage = DependencyManager::get<ThreadContextStorage>();
|
||||||
|
QPointer<OffscreenGLCanvas> p(this);
|
||||||
|
threadContextStorage->threadContext.setLocalData(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenGLCanvas::clearThreadContext() {
|
||||||
|
if (!DependencyManager::isSet<ThreadContextStorage>()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto threadContextStorage = DependencyManager::get<ThreadContextStorage>();
|
||||||
|
if (!threadContextStorage->threadContext.hasLocalData()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto& threadContext = threadContextStorage->threadContext.localData();
|
||||||
|
if (this != threadContext.operator OffscreenGLCanvas *()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
threadContextStorage->threadContext.setLocalData(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OffscreenGLCanvas::restoreThreadContext() {
|
bool OffscreenGLCanvas::restoreThreadContext() {
|
||||||
// Restore the rendering context for this thread
|
// Restore the rendering context for this thread
|
||||||
auto threadCanvasVariant = QThread::currentThread()->property(THREAD_CONTEXT_PROPERTY);
|
if (!DependencyManager::isSet<ThreadContextStorage>()) {
|
||||||
if (!threadCanvasVariant.isValid()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto threadCanvasObject = qvariant_cast<QObject*>(threadCanvasVariant);
|
auto threadContextStorage = DependencyManager::get<ThreadContextStorage>();
|
||||||
auto threadCanvas = static_cast<OffscreenGLCanvas*>(threadCanvasObject);
|
if (!threadContextStorage->threadContext.hasLocalData()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto threadCanvas = threadContextStorage->threadContext.localData();
|
||||||
if (!threadCanvas) {
|
if (!threadCanvas) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@ private slots:
|
||||||
void onMessageLogged(const QOpenGLDebugMessage &debugMessage);
|
void onMessageLogged(const QOpenGLDebugMessage &debugMessage);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void clearThreadContext();
|
||||||
|
|
||||||
std::once_flag _reportOnce;
|
std::once_flag _reportOnce;
|
||||||
QOpenGLContext* _context{ nullptr };
|
QOpenGLContext* _context{ nullptr };
|
||||||
QOffscreenSurface* _offscreenSurface{ nullptr };
|
QOffscreenSurface* _offscreenSurface{ nullptr };
|
||||||
|
|
Loading…
Reference in a new issue