diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index 7e4335ba635a67b652b00a709d4b007f5a45e111..faee1358ae0833b6061e9415b6b8b1ad7bbda233 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -114,9 +114,13 @@ void QQuickRenderControl::initialize(QOpenGLContext *gl) Q_D(QQuickRenderControl); if (!d->window) return; - bool current = gl->makeCurrent(d->window); - if (current) - QQuickWindowPrivate::get(d->window)->context->initialize(gl); + + // It is the caller's responsiblity to make a context/surface current. + // It cannot be done here since the surface to use may not be the + // surface belonging to window. In fact window may not have a native + // window/surface at all. + + QQuickWindowPrivate::get(d->window)->context->initialize(gl); } void QQuickRenderControl::invalidate() diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 7f62267859d90e28b9f898a7c1621d1824c97489..588120a51aaac7e6228b5df8829a0e00ac5e27b7 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -361,6 +361,9 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size) { QML_MEMORY_SCOPE_STRING("SceneGraph"); Q_Q(QQuickWindow); + if (!renderer) + return; + animationController->advance(); emit q->beforeRendering(); int fboId = 0; diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index ec4ce2f31402d7b52739186843b77b81406f3dd1..e8dec60bc4125d679b2fedadb5807575374c35e6 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -95,7 +95,7 @@ QQuickWidgetPrivate::QQuickWidgetPrivate() renderControl = new QQuickRenderControl; offscreenWindow = new QQuickWindow(renderControl); offscreenWindow->setTitle(QString::fromLatin1("Offscreen")); - offscreenWindow->create(); + // Do not call create() on offscreenWindow. } QQuickWidgetPrivate::~QQuickWidgetPrivate() @@ -155,7 +155,9 @@ void QQuickWidgetPrivate::renderSceneGraph() qWarning("QQuickWidget: render scenegraph with no context"); return; } - context->makeCurrent(offscreenWindow); + + Q_ASSERT(q->window()->windowHandle()->handle()); + context->makeCurrent(q->window()->windowHandle()); renderControl->polishItems(); renderControl->sync(); renderControl->render(); @@ -493,20 +495,25 @@ QSize QQuickWidgetPrivate::rootObjectSize() const void QQuickWidgetPrivate::createContext() { + Q_Q(QQuickWidget); if (context) return; context = new QOpenGLContext(); - context->setFormat(offscreenWindow->requestedFormat()); + context->setFormat(q->window()->windowHandle()->requestedFormat()); if (QSGContext::sharedOpenGLContext()) context->setShareContext(QSGContext::sharedOpenGLContext()); // ??? is this correct if (!context->create()) { - qWarning("QtQuick: failed to create OpenGL context"); + qWarning("QQuickWidget: failed to create OpenGL context"); delete context; context = 0; } - renderControl->initialize(context); + Q_ASSERT(q->window()->windowHandle()->handle()); + if (context->makeCurrent(q->window()->windowHandle())) + renderControl->initialize(context); + else + qWarning("QQuickWidget: failed to make window surface current"); } void QQuickWidget::createFramebufferObject() @@ -518,7 +525,7 @@ void QQuickWidget::createFramebufferObject() QOpenGLContext *context = d->offscreenWindow->openglContext(); if (!context) { - qWarning("createFBO with no context"); + qWarning("QQuickWidget: Attempted to create FBO with no context"); return; } @@ -526,10 +533,17 @@ void QQuickWidget::createFramebufferObject() context->setShareContext(QWidgetPrivate::get(window())->shareContext()); context->create(); } - context->makeCurrent(d->offscreenWindow); + + Q_ASSERT(window()->windowHandle()->handle()); + context->makeCurrent(window()->windowHandle()); d->fbo = new QOpenGLFramebufferObject(size()); d->fbo->setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); d->offscreenWindow->setRenderTarget(d->fbo); + + // Sanity check: The window must not have an underlying platform window. + // Having one would mean create() was called and platforms that only support + // a single native window were in trouble. + Q_ASSERT(!d->offscreenWindow->handle()); } void QQuickWidget::destroyFramebufferObject() @@ -690,7 +704,9 @@ void QQuickWidget::resizeEvent(QResizeEvent *e) qWarning("QQuickWidget::resizeEvent() no OpenGL context"); return; } - context->makeCurrent(d->offscreenWindow); + + Q_ASSERT(window()->windowHandle()->handle()); + context->makeCurrent(window()->windowHandle()); d->renderControl->render(); glFlush(); context->doneCurrent();