Fixed QtGui's GL paint engine getting out of sync when using QtOpenGL

We need to reset the active_engine belonging to QOpenGLContext whenever
we make the QtOpenGL paint engine active, to give the OpenGL paint
engine in QtGui a chance to sync its state if we've used the QtOpenGL
paint engine inbetween.

Change-Id: I445ce2f99bfbacf55650c881c4fdf07f2ff85069
Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
bb10
Samuel Rødal 2014-11-04 20:24:38 +01:00
parent a4428d480b
commit f79d96b486
3 changed files with 48 additions and 1 deletions

View File

@ -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;
}

View File

@ -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.

View File

@ -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