From 93aa379ae5cf624f024aa9173ce42e90b5c58002 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 9 Oct 2019 11:14:36 +0200 Subject: Make sure right screen is set on QOpenGLContext and QOffscreenSurface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the Qt3D window is on a specific screen, then it needs to ensure that any supporting QOpenGLContexts and QOffscreenSurfaces are set to be using that same screen or it will fail to render the content. Change-Id: Ief4f3e88bf6f71862bc5dace0cb0bddcdf3a98b5 Reviewed-by: Tomi Korpipää Reviewed-by: Paul Lemire --- src/quick3d/imports/scene3d/scene3ditem.cpp | 5 +++++ src/quick3d/quick3dextras/qt3dquickwindow.cpp | 3 +++ src/render/backend/abstractrenderer_p.h | 3 +++ src/render/backend/offscreensurfacehelper.cpp | 1 + src/render/frontend/qrenderaspect.cpp | 1 + src/render/frontend/qrenderaspect_p.h | 2 ++ src/render/renderers/opengl/renderer/commandthread.cpp | 1 + src/render/renderers/opengl/renderer/renderer.cpp | 14 ++++++++++++++ src/render/renderers/opengl/renderer/renderer_p.h | 4 ++++ 9 files changed, 34 insertions(+) diff --git a/src/quick3d/imports/scene3d/scene3ditem.cpp b/src/quick3d/imports/scene3d/scene3ditem.cpp index f5173497b..eb8c6ffd9 100644 --- a/src/quick3d/imports/scene3d/scene3ditem.cpp +++ b/src/quick3d/imports/scene3d/scene3ditem.cpp @@ -66,6 +66,7 @@ #include #include +#include #include #include #include @@ -301,6 +302,7 @@ void Scene3DItem::setWindowSurface(QObject *rootObject) m_dummySurface = new QOffscreenSurface; m_dummySurface->setParent(qGuiApp); // parent to something suitably long-living m_dummySurface->setFormat(rw->format()); + m_dummySurface->setScreen(rw->screen()); m_dummySurface->create(); surfaceSelector->setSurface(m_dummySurface); } else { @@ -388,6 +390,9 @@ QSGNode *Scene3DItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNode // If the render aspect wasn't created yet, do so now if (m_renderAspect == nullptr) { m_renderAspect = new QRenderAspect(QRenderAspect::Synchronous); + auto *rw = QQuickRenderControl::renderWindowFor(window()); + static_cast(Qt3DRender::QRenderAspectPrivate::get(m_renderAspect))->m_screen = + (rw ? rw->screen() : window()->screen()); m_aspectEngine->registerAspect(m_renderAspect); } diff --git a/src/quick3d/quick3dextras/qt3dquickwindow.cpp b/src/quick3d/quick3dextras/qt3dquickwindow.cpp index bc4bb25ee..d67dfdc71 100644 --- a/src/quick3d/quick3dextras/qt3dquickwindow.cpp +++ b/src/quick3d/quick3dextras/qt3dquickwindow.cpp @@ -66,6 +66,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -132,6 +133,8 @@ Qt3DQuickWindow::Qt3DQuickWindow(QWindow *parent) QSurfaceFormat::setDefaultFormat(format); d->m_renderAspect = new Qt3DRender::QRenderAspect; + if (parent && parent->screen()) + static_cast(Qt3DRender::QRenderAspectPrivate::get(d->m_renderAspect))->m_screen = parent->screen(); d->m_inputAspect = new Qt3DInput::QInputAspect; d->m_logicAspect = new Qt3DLogic::QLogicAspect; d->m_engine = new Qt3DCore::Quick::QQmlAspectEngine; diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h index 69e71dece..273ab359a 100644 --- a/src/render/backend/abstractrenderer_p.h +++ b/src/render/backend/abstractrenderer_p.h @@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE class QSurface; class QSize; +class QScreen; namespace Qt3DCore { class QAbstractFrameAdvanceService; @@ -177,6 +178,8 @@ public: // For QtQuick rendering virtual void setOpenGLContext(QOpenGLContext *ctx) = 0; + virtual void setScreen(QScreen *) {} + virtual QScreen *screen() const { return nullptr; } virtual void setOffscreenSurfaceHelper(OffscreenSurfaceHelper *helper) = 0; virtual QSurfaceFormat format() = 0; diff --git a/src/render/backend/offscreensurfacehelper.cpp b/src/render/backend/offscreensurfacehelper.cpp index 89dc6211f..38558d484 100644 --- a/src/render/backend/offscreensurfacehelper.cpp +++ b/src/render/backend/offscreensurfacehelper.cpp @@ -72,6 +72,7 @@ void OffscreenSurfaceHelper::createOffscreenSurface() m_offscreenSurface = new QOffscreenSurface; m_offscreenSurface->setParent(this); m_offscreenSurface->setFormat(m_renderer->format()); + m_offscreenSurface->setScreen(m_renderer->screen()); m_offscreenSurface->create(); } diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 14fbe1754..c60488e16 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -564,6 +564,7 @@ void QRenderAspect::onRegistered() // TO DO: Load proper Renderer class based on Qt configuration preferences d->m_renderer = new Render::Renderer(d->m_renderType); + d->m_renderer->setScreen(d->m_screen); d->m_renderer->setNodeManagers(d->m_nodeManagers); // Create a helper for deferring creation of an offscreen surface used during cleanup diff --git a/src/render/frontend/qrenderaspect_p.h b/src/render/frontend/qrenderaspect_p.h index 4a091e164..28a9b2453 100644 --- a/src/render/frontend/qrenderaspect_p.h +++ b/src/render/frontend/qrenderaspect_p.h @@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE class QSurface; +class QScreen; namespace Qt3DRender { @@ -104,6 +105,7 @@ public: QVector m_renderPlugins; QRenderAspect::RenderType m_renderType; Render::OffscreenSurfaceHelper *m_offscreenHelper; + QScreen *m_screen = nullptr; static QMutex m_pluginLock; static QVector m_pluginConfig; diff --git a/src/render/renderers/opengl/renderer/commandthread.cpp b/src/render/renderers/opengl/renderer/commandthread.cpp index dcaacadcc..70ab964d6 100644 --- a/src/render/renderers/opengl/renderer/commandthread.cpp +++ b/src/render/renderers/opengl/renderer/commandthread.cpp @@ -97,6 +97,7 @@ void CommandThread::initialize(QOpenGLContext *mainContext, OffscreenSurfaceHelp // thread the wglShareLists call is made on) m_localContext.reset(new QOpenGLContext()); m_localContext->setFormat(m_mainContext->format()); + m_localContext->setScreen(m_mainContext->screen()); m_localContext->setShareContext(m_mainContext); if (!m_localContext->create()) qWarning("CommandThread: Failed to create local context"); diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index b4a19c641..d0b1f2a5d 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -357,6 +357,16 @@ void Renderer::setOpenGLContext(QOpenGLContext *context) m_glContext = context; } +void Renderer::setScreen(QScreen *scr) +{ + m_screen = scr; +} + +QScreen *Renderer::screen() const +{ + return m_screen; +} + // Called in RenderThread context by the run method of RenderThread // RenderThread has locked the mutex already and unlocks it when this // method termintates @@ -374,6 +384,8 @@ void Renderer::initialize() // we need to create it if (!m_glContext) { ctx = new QOpenGLContext; + if (m_screen) + ctx->setScreen(m_screen); ctx->setShareContext(qt_gl_global_share_context()); // TO DO: Shouldn't we use the highest context available and trust @@ -403,6 +415,8 @@ void Renderer::initialize() if (!ctx->shareContext()) { m_shareContext = new QOpenGLContext; + if (ctx->screen()) + m_shareContext->setScreen(ctx->screen()); m_shareContext->setFormat(ctx->format()); m_shareContext->setShareContext(ctx); m_shareContext->create(); diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h index 5b5f5c4f4..9376e9eda 100644 --- a/src/render/renderers/opengl/renderer/renderer_p.h +++ b/src/render/renderers/opengl/renderer/renderer_p.h @@ -106,6 +106,7 @@ QT_BEGIN_NAMESPACE class QSurface; class QMouseEvent; +class QScreen; namespace Qt3DCore { class QEntity; @@ -294,6 +295,8 @@ public: ViewSubmissionResultData submitRenderViews(const QVector &renderViews); RendererCache *cache() { return &m_cache; } + void setScreen(QScreen *scr) override; + QScreen *screen() const override; #ifdef QT3D_RENDER_UNIT_TESTS public: @@ -421,6 +424,7 @@ private: QMetaObject::Connection m_contextConnection; RendererCache m_cache; + QScreen *m_screen = nullptr; }; } // namespace Render -- cgit v1.2.3