diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 43df311636486946955bb187fcaf99ecf4739ffb..1fa5723d85a835cc2b78e4df5d991a293290bc5b 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -612,6 +612,21 @@ void QGL2PaintEngineExPrivate::resetGLState() #endif } +bool QGL2PaintEngineExPrivate::resetOpenGLContextActiveEngine() +{ + QOpenGLContext *guiGlContext = ctx->contextHandle(); + QOpenGLContextPrivate *guiGlContextPrivate = + guiGlContext ? QOpenGLContextPrivate::get(guiGlContext) : 0; + + if (guiGlContextPrivate && guiGlContextPrivate->active_engine) { + ctx->d_func()->refreshCurrentFbo(); + guiGlContextPrivate->active_engine = 0; + return true; + } + + return false; +} + void QGL2PaintEngineEx::endNativePainting() { Q_D(QGL2PaintEngineEx); @@ -2015,6 +2030,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->ctx = d->device->context(); d->ctx->d_ptr->active_engine = this; + d->resetOpenGLContextActiveEngine(); + const QSize sz = d->device->size(); d->width = sz.width(); d->height = sz.height(); @@ -2080,6 +2097,8 @@ bool QGL2PaintEngineEx::end() ctx->d_ptr->active_engine = 0; + d->resetOpenGLContextActiveEngine(); + d->resetGLState(); delete d->shaderManager; @@ -2105,7 +2124,7 @@ void QGL2PaintEngineEx::ensureActive() Q_D(QGL2PaintEngineEx); QGLContext *ctx = d->ctx; - if (isActive() && ctx->d_ptr->active_engine != this) { + if (isActive() && (ctx->d_ptr->active_engine != this || d->resetOpenGLContextActiveEngine())) { ctx->d_ptr->active_engine = this; d->needsSync = true; } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 528bfdeeb989a4ca9416bfd4510b7bd651aad962..ac1d63df17da3d0c5071a301701e93abfcb2844c 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -191,6 +191,7 @@ public: void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = GLuint(-1)); void resetGLState(); + bool resetOpenGLContextActiveEngine(); // fill, stroke, drawTexture, drawPixmaps & drawCachedGlyphs are the main rendering entry-points, // however writeClip can also be thought of as en entry point as it does similar things. diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp index d8ad3e1470c10bd61e2b08c5079d0b4bf2dcf6ae..56198ceb650d17d5ae0fa4e999974a2523f7af0a 100644 --- a/tests/auto/opengl/qgl/tst_qgl.cpp +++ b/tests/auto/opengl/qgl/tst_qgl.cpp @@ -1200,6 +1200,33 @@ void tst_QGL::currentFboSync() QCOMPARE(fbo1.toImage(), fbo2Image); } + + { + QGLFramebufferObject fbo1(512, 512, QGLFramebufferObject::CombinedDepthStencil); + + QOpenGLFramebufferObjectPaintDevice fbo2(256, 256); + + QImage sourceImage(256, 256, QImage::Format_ARGB32_Premultiplied); + QPainter sourcePainter(&sourceImage); + qt_opengl_draw_test_pattern(&sourcePainter, 256, 256); + + QPainter fbo2Painter(&fbo2); + fbo2Painter.drawImage(0, 0, sourceImage); + QImage fbo2Image1 = fbo2.toImage(); + fbo2Painter.fillRect(0, 0, 256, 256, Qt::white); + + QPainter fbo1Painter(&fbo1); + fbo1Painter.drawImage(0, 0, sourceImage); + fbo1Painter.end(); + + // check that the OpenGL paint engine now knows it needs to sync + fbo2Painter.drawImage(0, 0, sourceImage); + QImage fbo2Image2 = fbo2.toImage(); + + fbo2Painter.end(); + + QCOMPARE(fbo2Image1, fbo2Image2); + } } // Tests multiple QPainters active on different FBOs at the same time, with