mirror of https://github.com/mgba-emu/mgba.git
Qt: Create OpenGL context on a thread without moving it
This commit is contained in:
parent
7be68ffd1d
commit
74edd964da
|
@ -34,44 +34,15 @@ using namespace QGBA;
|
||||||
|
|
||||||
DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent)
|
DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent)
|
||||||
: Display(parent)
|
: Display(parent)
|
||||||
, m_gl(nullptr)
|
|
||||||
{
|
{
|
||||||
setAttribute(Qt::WA_NativeWindow);
|
setAttribute(Qt::WA_NativeWindow);
|
||||||
windowHandle()->create();
|
windowHandle()->create();
|
||||||
|
|
||||||
// This can spontaneously re-enter into this->resizeEvent before creation is done, so we
|
m_painter = std::make_unique<PainterGL>(windowHandle(), format);
|
||||||
// need to make sure it's initialized to nullptr before we assign the new object to it
|
|
||||||
m_gl = new QOpenGLContext;
|
|
||||||
m_gl->setFormat(format);
|
|
||||||
m_gl->create();
|
|
||||||
|
|
||||||
m_gl->makeCurrent(windowHandle());
|
|
||||||
#if defined(_WIN32) && defined(USE_EPOXY)
|
|
||||||
epoxy_handle_external_wglMakeCurrent();
|
|
||||||
#endif
|
|
||||||
auto version = m_gl->format().version();
|
|
||||||
QStringList extensions = QString(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))).split(' ');
|
|
||||||
|
|
||||||
int forceVersion = 0;
|
|
||||||
if (format.majorVersion() < 2) {
|
|
||||||
forceVersion = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((version == qMakePair(2, 1) && !extensions.contains("GL_ARB_framebuffer_object")) || version == qMakePair(2, 0)) {
|
|
||||||
QSurfaceFormat newFormat(format);
|
|
||||||
newFormat.setVersion(1, 4);
|
|
||||||
forceVersion = 1;
|
|
||||||
m_gl->setFormat(newFormat);
|
|
||||||
m_gl->create();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_painter = new PainterGL(windowHandle(), m_gl, forceVersion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayGL::~DisplayGL() {
|
DisplayGL::~DisplayGL() {
|
||||||
stopDrawing();
|
stopDrawing();
|
||||||
delete m_painter;
|
|
||||||
delete m_gl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DisplayGL::supportsShaders() const {
|
bool DisplayGL::supportsShaders() const {
|
||||||
|
@ -81,7 +52,7 @@ bool DisplayGL::supportsShaders() const {
|
||||||
VideoShader* DisplayGL::shaders() {
|
VideoShader* DisplayGL::shaders() {
|
||||||
VideoShader* shaders = nullptr;
|
VideoShader* shaders = nullptr;
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
QMetaObject::invokeMethod(m_painter, "shaders", Qt::BlockingQueuedConnection, Q_RETURN_ARG(VideoShader*, shaders));
|
QMetaObject::invokeMethod(m_painter.get(), "shaders", Qt::BlockingQueuedConnection, Q_RETURN_ARG(VideoShader*, shaders));
|
||||||
} else {
|
} else {
|
||||||
shaders = m_painter->shaders();
|
shaders = m_painter->shaders();
|
||||||
}
|
}
|
||||||
|
@ -96,16 +67,13 @@ void DisplayGL::startDrawing(std::shared_ptr<CoreController> controller) {
|
||||||
m_painter->setContext(controller);
|
m_painter->setContext(controller);
|
||||||
m_painter->setMessagePainter(messagePainter());
|
m_painter->setMessagePainter(messagePainter());
|
||||||
m_context = controller;
|
m_context = controller;
|
||||||
m_painter->resize(size());
|
|
||||||
m_drawThread = new QThread(this);
|
m_drawThread = new QThread(this);
|
||||||
m_drawThread->setObjectName("Painter Thread");
|
m_drawThread->setObjectName("Painter Thread");
|
||||||
m_gl->doneCurrent();
|
|
||||||
m_gl->moveToThread(m_drawThread);
|
|
||||||
m_painter->moveToThread(m_drawThread);
|
m_painter->moveToThread(m_drawThread);
|
||||||
if (videoProxy()) {
|
if (videoProxy()) {
|
||||||
videoProxy()->moveToThread(m_drawThread);
|
videoProxy()->moveToThread(m_drawThread);
|
||||||
}
|
}
|
||||||
connect(m_drawThread, &QThread::started, m_painter, &PainterGL::start);
|
connect(m_drawThread, &QThread::started, m_painter.get(), &PainterGL::start);
|
||||||
m_drawThread->start();
|
m_drawThread->start();
|
||||||
|
|
||||||
lockAspectRatio(isAspectRatioLocked());
|
lockAspectRatio(isAspectRatioLocked());
|
||||||
|
@ -126,15 +94,10 @@ void DisplayGL::stopDrawing() {
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
m_isDrawing = false;
|
m_isDrawing = false;
|
||||||
CoreController::Interrupter interrupter(m_context);
|
CoreController::Interrupter interrupter(m_context);
|
||||||
QMetaObject::invokeMethod(m_painter, "stop", Qt::BlockingQueuedConnection);
|
QMetaObject::invokeMethod(m_painter.get(), "stop", Qt::BlockingQueuedConnection);
|
||||||
m_drawThread->exit();
|
m_drawThread->exit();
|
||||||
m_drawThread->wait();
|
m_drawThread->wait();
|
||||||
m_drawThread = nullptr;
|
m_drawThread = nullptr;
|
||||||
|
|
||||||
m_gl->makeCurrent(windowHandle());
|
|
||||||
#if defined(_WIN32) && defined(USE_EPOXY)
|
|
||||||
epoxy_handle_external_wglMakeCurrent();
|
|
||||||
#endif
|
|
||||||
setUpdatesEnabled(true);
|
setUpdatesEnabled(true);
|
||||||
}
|
}
|
||||||
m_context.reset();
|
m_context.reset();
|
||||||
|
@ -144,7 +107,7 @@ void DisplayGL::pauseDrawing() {
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
m_isDrawing = false;
|
m_isDrawing = false;
|
||||||
CoreController::Interrupter interrupter(m_context);
|
CoreController::Interrupter interrupter(m_context);
|
||||||
QMetaObject::invokeMethod(m_painter, "pause", Qt::BlockingQueuedConnection);
|
QMetaObject::invokeMethod(m_painter.get(), "pause", Qt::BlockingQueuedConnection);
|
||||||
#ifndef Q_OS_MAC
|
#ifndef Q_OS_MAC
|
||||||
setUpdatesEnabled(true);
|
setUpdatesEnabled(true);
|
||||||
#endif
|
#endif
|
||||||
|
@ -155,7 +118,7 @@ void DisplayGL::unpauseDrawing() {
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
m_isDrawing = true;
|
m_isDrawing = true;
|
||||||
CoreController::Interrupter interrupter(m_context);
|
CoreController::Interrupter interrupter(m_context);
|
||||||
QMetaObject::invokeMethod(m_painter, "unpause", Qt::BlockingQueuedConnection);
|
QMetaObject::invokeMethod(m_painter.get(), "unpause", Qt::BlockingQueuedConnection);
|
||||||
#ifndef Q_OS_MAC
|
#ifndef Q_OS_MAC
|
||||||
setUpdatesEnabled(false);
|
setUpdatesEnabled(false);
|
||||||
#endif
|
#endif
|
||||||
|
@ -164,69 +127,69 @@ void DisplayGL::unpauseDrawing() {
|
||||||
|
|
||||||
void DisplayGL::forceDraw() {
|
void DisplayGL::forceDraw() {
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
QMetaObject::invokeMethod(m_painter, "forceDraw");
|
QMetaObject::invokeMethod(m_painter.get(), "forceDraw");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayGL::lockAspectRatio(bool lock) {
|
void DisplayGL::lockAspectRatio(bool lock) {
|
||||||
Display::lockAspectRatio(lock);
|
Display::lockAspectRatio(lock);
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
QMetaObject::invokeMethod(m_painter, "lockAspectRatio", Q_ARG(bool, lock));
|
QMetaObject::invokeMethod(m_painter.get(), "lockAspectRatio", Q_ARG(bool, lock));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayGL::lockIntegerScaling(bool lock) {
|
void DisplayGL::lockIntegerScaling(bool lock) {
|
||||||
Display::lockIntegerScaling(lock);
|
Display::lockIntegerScaling(lock);
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
QMetaObject::invokeMethod(m_painter, "lockIntegerScaling", Q_ARG(bool, lock));
|
QMetaObject::invokeMethod(m_painter.get(), "lockIntegerScaling", Q_ARG(bool, lock));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayGL::interframeBlending(bool enable) {
|
void DisplayGL::interframeBlending(bool enable) {
|
||||||
Display::interframeBlending(enable);
|
Display::interframeBlending(enable);
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
QMetaObject::invokeMethod(m_painter, "interframeBlending", Q_ARG(bool, enable));
|
QMetaObject::invokeMethod(m_painter.get(), "interframeBlending", Q_ARG(bool, enable));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayGL::showOSDMessages(bool enable) {
|
void DisplayGL::showOSDMessages(bool enable) {
|
||||||
Display::showOSDMessages(enable);
|
Display::showOSDMessages(enable);
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
QMetaObject::invokeMethod(m_painter, "showOSD", Q_ARG(bool, enable));
|
QMetaObject::invokeMethod(m_painter.get(), "showOSD", Q_ARG(bool, enable));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayGL::filter(bool filter) {
|
void DisplayGL::filter(bool filter) {
|
||||||
Display::filter(filter);
|
Display::filter(filter);
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
QMetaObject::invokeMethod(m_painter, "filter", Q_ARG(bool, filter));
|
QMetaObject::invokeMethod(m_painter.get(), "filter", Q_ARG(bool, filter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayGL::framePosted() {
|
void DisplayGL::framePosted() {
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
m_painter->enqueue(m_context->drawContext());
|
m_painter->enqueue(m_context->drawContext());
|
||||||
QMetaObject::invokeMethod(m_painter, "draw");
|
QMetaObject::invokeMethod(m_painter.get(), "draw");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayGL::setShaders(struct VDir* shaders) {
|
void DisplayGL::setShaders(struct VDir* shaders) {
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
QMetaObject::invokeMethod(m_painter, "setShaders", Qt::BlockingQueuedConnection, Q_ARG(struct VDir*, shaders));
|
QMetaObject::invokeMethod(m_painter.get(), "setShaders", Qt::BlockingQueuedConnection, Q_ARG(struct VDir*, shaders));
|
||||||
} else {
|
} else {
|
||||||
m_painter->setShaders(shaders);
|
m_painter->setShaders(shaders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayGL::clearShaders() {
|
void DisplayGL::clearShaders() {
|
||||||
QMetaObject::invokeMethod(m_painter, "clearShaders");
|
QMetaObject::invokeMethod(m_painter.get(), "clearShaders");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayGL::resizeContext() {
|
void DisplayGL::resizeContext() {
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
m_isDrawing = false;
|
m_isDrawing = false;
|
||||||
CoreController::Interrupter interrupter(m_context);
|
CoreController::Interrupter interrupter(m_context);
|
||||||
QMetaObject::invokeMethod(m_painter, "resizeContext", Qt::BlockingQueuedConnection);
|
QMetaObject::invokeMethod(m_painter.get(), "resizeContext", Qt::BlockingQueuedConnection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +198,7 @@ void DisplayGL::setVideoScale(int scale) {
|
||||||
m_isDrawing = false;
|
m_isDrawing = false;
|
||||||
CoreController::Interrupter interrupter(m_context);
|
CoreController::Interrupter interrupter(m_context);
|
||||||
mCoreConfigSetIntValue(&m_context->thread()->core->config, "videoScale", scale);
|
mCoreConfigSetIntValue(&m_context->thread()->core->config, "videoScale", scale);
|
||||||
QMetaObject::invokeMethod(m_painter, "resizeContext", Qt::BlockingQueuedConnection);
|
QMetaObject::invokeMethod(m_painter.get(), "resizeContext", Qt::BlockingQueuedConnection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +209,7 @@ void DisplayGL::resizeEvent(QResizeEvent* event) {
|
||||||
|
|
||||||
void DisplayGL::resizePainter() {
|
void DisplayGL::resizePainter() {
|
||||||
if (m_drawThread) {
|
if (m_drawThread) {
|
||||||
QMetaObject::invokeMethod(m_painter, "resize", Qt::BlockingQueuedConnection, Q_ARG(QSize, size()));
|
QMetaObject::invokeMethod(m_painter.get(), "resize", Qt::BlockingQueuedConnection, Q_ARG(QSize, size()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,10 +225,47 @@ int DisplayGL::framebufferHandle() {
|
||||||
return m_painter->glTex();
|
return m_painter->glTex();
|
||||||
}
|
}
|
||||||
|
|
||||||
PainterGL::PainterGL(QWindow* surface, QOpenGLContext* parent, int forceVersion)
|
PainterGL::PainterGL(QWindow* surface, const QSurfaceFormat& format)
|
||||||
: m_gl(parent)
|
: m_surface(surface)
|
||||||
, m_surface(surface)
|
, m_format(format)
|
||||||
{
|
{
|
||||||
|
for (auto& buf : m_buffers) {
|
||||||
|
m_free.append(&buf.front());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PainterGL::~PainterGL() {
|
||||||
|
if (m_gl) {
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterGL::create() {
|
||||||
|
m_gl = std::make_unique<QOpenGLContext>();
|
||||||
|
m_gl->setFormat(m_format);
|
||||||
|
m_gl->create();
|
||||||
|
|
||||||
|
m_gl->makeCurrent(m_surface);
|
||||||
|
#if defined(_WIN32) && defined(USE_EPOXY)
|
||||||
|
epoxy_handle_external_wglMakeCurrent();
|
||||||
|
#endif
|
||||||
|
auto version = m_gl->format().version();
|
||||||
|
QStringList extensions = QString(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))).split(' ');
|
||||||
|
|
||||||
|
int forceVersion = 0;
|
||||||
|
if (m_format.majorVersion() < 2) {
|
||||||
|
forceVersion = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((version == qMakePair(2, 1) && !extensions.contains("GL_ARB_framebuffer_object")) || version == qMakePair(2, 0)) {
|
||||||
|
QSurfaceFormat newFormat(m_format);
|
||||||
|
newFormat.setVersion(1, 4);
|
||||||
|
forceVersion = 1;
|
||||||
|
m_gl->setFormat(newFormat);
|
||||||
|
m_gl->create();
|
||||||
|
}
|
||||||
|
m_gl->makeCurrent(m_surface);
|
||||||
|
|
||||||
#ifdef BUILD_GL
|
#ifdef BUILD_GL
|
||||||
mGLContext* glBackend;
|
mGLContext* glBackend;
|
||||||
#endif
|
#endif
|
||||||
|
@ -273,24 +273,14 @@ PainterGL::PainterGL(QWindow* surface, QOpenGLContext* parent, int forceVersion)
|
||||||
mGLES2Context* gl2Backend;
|
mGLES2Context* gl2Backend;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_gl->makeCurrent(m_surface);
|
m_window = std::make_unique<QOpenGLPaintDevice>();
|
||||||
m_window = new QOpenGLPaintDevice;
|
|
||||||
{
|
|
||||||
// XXX: Qt creates TLS for OpenGL objects in the local thread
|
|
||||||
// We need to prevent that thread from being the painter thread
|
|
||||||
// Qt also caches the engine object on the device if a different
|
|
||||||
// engine is active, so let's make a temporary one
|
|
||||||
QOpenGLPaintDevice* fakeDevice = new QOpenGLPaintDevice;
|
|
||||||
QPainter fakePainter(fakeDevice);
|
|
||||||
m_window->paintEngine();
|
|
||||||
}
|
|
||||||
#if defined(_WIN32) && defined(USE_EPOXY)
|
#if defined(_WIN32) && defined(USE_EPOXY)
|
||||||
epoxy_handle_external_wglMakeCurrent();
|
epoxy_handle_external_wglMakeCurrent();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BUILD_GLES2
|
#ifdef BUILD_GLES2
|
||||||
auto version = m_gl->format().version();
|
version = m_gl->format().version();
|
||||||
QStringList extensions = QString(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))).split(' ');
|
extensions = QString(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))).split(' ');
|
||||||
if (forceVersion != 1 && ((version == qMakePair(2, 1) && extensions.contains("GL_ARB_framebuffer_object")) || version.first > 2)) {
|
if (forceVersion != 1 && ((version == qMakePair(2, 1) && extensions.contains("GL_ARB_framebuffer_object")) || version.first > 2)) {
|
||||||
gl2Backend = static_cast<mGLES2Context*>(malloc(sizeof(mGLES2Context)));
|
gl2Backend = static_cast<mGLES2Context*>(malloc(sizeof(mGLES2Context)));
|
||||||
mGLES2ContextCreate(gl2Backend);
|
mGLES2ContextCreate(gl2Backend);
|
||||||
|
@ -330,13 +320,12 @@ PainterGL::PainterGL(QWindow* surface, QOpenGLContext* parent, int forceVersion)
|
||||||
m_backend->filter = false;
|
m_backend->filter = false;
|
||||||
m_backend->lockAspectRatio = false;
|
m_backend->lockAspectRatio = false;
|
||||||
m_backend->interframeBlending = false;
|
m_backend->interframeBlending = false;
|
||||||
|
|
||||||
for (auto& buf : m_buffers) {
|
|
||||||
m_free.append(&buf.front());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PainterGL::~PainterGL() {
|
void PainterGL::destroy() {
|
||||||
|
if (!m_gl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_gl->makeCurrent(m_surface);
|
m_gl->makeCurrent(m_surface);
|
||||||
#if defined(_WIN32) && defined(USE_EPOXY)
|
#if defined(_WIN32) && defined(USE_EPOXY)
|
||||||
epoxy_handle_external_wglMakeCurrent();
|
epoxy_handle_external_wglMakeCurrent();
|
||||||
|
@ -357,14 +346,15 @@ PainterGL::~PainterGL() {
|
||||||
#endif
|
#endif
|
||||||
m_backend->deinit(m_backend);
|
m_backend->deinit(m_backend);
|
||||||
m_gl->doneCurrent();
|
m_gl->doneCurrent();
|
||||||
|
m_window.reset();
|
||||||
|
m_gl.reset();
|
||||||
|
|
||||||
free(m_backend);
|
free(m_backend);
|
||||||
m_backend = nullptr;
|
m_backend = nullptr;
|
||||||
delete m_window;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::setContext(std::shared_ptr<CoreController> context) {
|
void PainterGL::setContext(std::shared_ptr<CoreController> context) {
|
||||||
m_context = context;
|
m_context = context;
|
||||||
resizeContext();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::resizeContext() {
|
void PainterGL::resizeContext() {
|
||||||
|
@ -419,6 +409,9 @@ void PainterGL::filter(bool filter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::start() {
|
void PainterGL::start() {
|
||||||
|
if (!m_gl) {
|
||||||
|
create();
|
||||||
|
}
|
||||||
m_gl->makeCurrent(m_surface);
|
m_gl->makeCurrent(m_surface);
|
||||||
#if defined(_WIN32) && defined(USE_EPOXY)
|
#if defined(_WIN32) && defined(USE_EPOXY)
|
||||||
epoxy_handle_external_wglMakeCurrent();
|
epoxy_handle_external_wglMakeCurrent();
|
||||||
|
@ -429,6 +422,7 @@ void PainterGL::start() {
|
||||||
mGLES2ShaderAttach(reinterpret_cast<mGLES2Context*>(m_backend), static_cast<mGLES2Shader*>(m_shader.passes), m_shader.nPasses);
|
mGLES2ShaderAttach(reinterpret_cast<mGLES2Context*>(m_backend), static_cast<mGLES2Shader*>(m_shader.passes), m_shader.nPasses);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
resizeContext();
|
||||||
|
|
||||||
m_buffer = nullptr;
|
m_buffer = nullptr;
|
||||||
m_active = true;
|
m_active = true;
|
||||||
|
@ -456,7 +450,7 @@ void PainterGL::draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::forceDraw() {
|
void PainterGL::forceDraw() {
|
||||||
m_painter.begin(m_window);
|
m_painter.begin(m_window.get());
|
||||||
performDraw();
|
performDraw();
|
||||||
m_painter.end();
|
m_painter.end();
|
||||||
if (!m_context->thread()->impl->sync.audioWait && !m_context->thread()->impl->sync.videoFrameWait) {
|
if (!m_context->thread()->impl->sync.audioWait && !m_context->thread()->impl->sync.videoFrameWait) {
|
||||||
|
@ -477,12 +471,10 @@ void PainterGL::stop() {
|
||||||
if (m_videoProxy) {
|
if (m_videoProxy) {
|
||||||
m_videoProxy->reset();
|
m_videoProxy->reset();
|
||||||
}
|
}
|
||||||
m_gl->doneCurrent();
|
destroy();
|
||||||
m_gl->moveToThread(m_surface->thread());
|
moveToThread(m_surface->thread());
|
||||||
m_context.reset();
|
|
||||||
moveToThread(m_gl->thread());
|
|
||||||
if (m_videoProxy) {
|
if (m_videoProxy) {
|
||||||
m_videoProxy->moveToThread(m_gl->thread());
|
m_videoProxy->moveToThread(m_surface->thread());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,8 +74,7 @@ private:
|
||||||
void resizePainter();
|
void resizePainter();
|
||||||
|
|
||||||
bool m_isDrawing = false;
|
bool m_isDrawing = false;
|
||||||
QOpenGLContext* m_gl;
|
std::unique_ptr<PainterGL> m_painter;
|
||||||
PainterGL* m_painter;
|
|
||||||
QThread* m_drawThread = nullptr;
|
QThread* m_drawThread = nullptr;
|
||||||
std::shared_ptr<CoreController> m_context;
|
std::shared_ptr<CoreController> m_context;
|
||||||
};
|
};
|
||||||
|
@ -84,7 +83,7 @@ class PainterGL : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PainterGL(QWindow* surface, QOpenGLContext* parent, int forceVersion = 0);
|
PainterGL(QWindow* surface, const QSurfaceFormat& format);
|
||||||
~PainterGL();
|
~PainterGL();
|
||||||
|
|
||||||
void setContext(std::shared_ptr<CoreController>);
|
void setContext(std::shared_ptr<CoreController>);
|
||||||
|
@ -120,6 +119,8 @@ private:
|
||||||
void performDraw();
|
void performDraw();
|
||||||
void dequeue();
|
void dequeue();
|
||||||
void dequeueAll();
|
void dequeueAll();
|
||||||
|
void create();
|
||||||
|
void destroy();
|
||||||
|
|
||||||
std::array<std::array<uint32_t, 0x100000>, 3> m_buffers;
|
std::array<std::array<uint32_t, 0x100000>, 3> m_buffers;
|
||||||
QList<uint32_t*> m_free;
|
QList<uint32_t*> m_free;
|
||||||
|
@ -128,8 +129,9 @@ private:
|
||||||
QPainter m_painter;
|
QPainter m_painter;
|
||||||
QMutex m_mutex;
|
QMutex m_mutex;
|
||||||
QWindow* m_surface;
|
QWindow* m_surface;
|
||||||
QOpenGLPaintDevice* m_window;
|
QSurfaceFormat m_format;
|
||||||
QOpenGLContext* m_gl;
|
std::unique_ptr<QOpenGLPaintDevice> m_window;
|
||||||
|
std::unique_ptr<QOpenGLContext> m_gl;
|
||||||
bool m_active = false;
|
bool m_active = false;
|
||||||
bool m_started = false;
|
bool m_started = false;
|
||||||
std::shared_ptr<CoreController> m_context = nullptr;
|
std::shared_ptr<CoreController> m_context = nullptr;
|
||||||
|
|
Loading…
Reference in New Issue