aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2014-11-17 14:43:27 +0100
committerUlf Hermann <ulf.hermann@theqtcompany.com>2015-01-12 11:37:53 +0100
commit8b3643dd8b492f7754846e7371686db61bcfef69 (patch)
tree3c4605d2c2f0fb2761c51bf40a9d5f370d3befd7
parente339c279e0241cd132e068f929c303fabde509ee (diff)
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 <gunnar@sletta.org>
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp30
1 files 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",