From 8b3643dd8b492f7754846e7371686db61bcfef69 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 17 Nov 2014 14:43:27 +0100 Subject: Make opengl context current in context2d's toImage if necessary With the basic render loop the scene graph thread is the render thread and thus we don't get a different opengl context for context2d in immediate/fbo mode. We have to make sure the opengl context is current when we call flush() from functions exposed to JS. Change-Id: Idd91cf1ce9c299a7645cf3b78d4498652376b17e Reviewed-by: Gunnar Sletta --- src/quick/items/context2d/qquickcontext2d.cpp | 30 +++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 0101e0edf4..2d1bb4d933 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -4171,13 +4171,35 @@ QQuickContext2DTexture *QQuickContext2D::texture() const QImage QQuickContext2D::toImage(const QRectF& bounds) { - flush(); - if (m_texture->thread() == QThread::currentThread()) - m_texture->grabImage(bounds); - else if (m_renderStrategy == QQuickCanvasItem::Cooperative) { + if (m_texture->thread() == QThread::currentThread()) { + // if we're either not rendering to an fbo or we have a separate opengl context we can just + // flush. Otherwise we have to make sure the shared opengl context is current before we do + // so. It may or may not be current already, depending on how this method is called. + if (m_renderTarget != QQuickCanvasItem::FramebufferObject || m_glContext) { + flush(); + m_texture->grabImage(bounds); + } else { + QQuickWindow *window = m_canvas->window(); + QOpenGLContext *ctx = window ? window->openglContext() : 0; + if (ctx && ctx->isValid()) { + if (ctx == QOpenGLContext::currentContext()) { + flush(); + } else { + ctx->makeCurrent(window); + flush(); + ctx->doneCurrent(); + } + m_texture->grabImage(bounds); + } else { + qWarning() << "Cannot read pixels from canvas before opengl context is valid"; + return QImage(); + } + } + } else if (m_renderStrategy == QQuickCanvasItem::Cooperative) { qWarning() << "Pixel readback is not supported in Cooperative mode, please try Threaded or Immediate mode"; return QImage(); } else { + flush(); QCoreApplication::postEvent(m_texture, new QEvent(QEvent::Type(QEvent::User + 10))); QMetaObject::invokeMethod(m_texture, "grabImage", -- cgit v1.2.3