From fd3d228b044dee8071afe8f7407dc6d2ac0092d6 Mon Sep 17 00:00:00 2001
From: Miikka Heikkinen <miikka.heikkinen@theqtcompany.com>
Date: Tue, 21 Apr 2015 12:08:43 +0300
Subject: [PATCH] Fix readPixels for antialiased buffers.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When calling readPixels from javascript, we need to blit the
antialiased fbo into the render fbo before we can read the pixel.

Change-Id: I342342f396c42f3d5320105552838cd7c99d1c4b
Task-number: QTBUG-45373
Reviewed-by: Tomi Korpipää <tomi.korpipaa@theqtcompany.com>
Reviewed-by: Pasi Keränen <pasi.keranen@digia.com>
---
 src/imports/qtcanvas3d/canvas3d.cpp  | 27 +++++++++++++++++++--------
 src/imports/qtcanvas3d/canvas3d_p.h  |  1 +
 src/imports/qtcanvas3d/context3d.cpp | 11 +++++++++++
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/src/imports/qtcanvas3d/canvas3d.cpp b/src/imports/qtcanvas3d/canvas3d.cpp
index 159e24d..f1f6213 100644
--- a/src/imports/qtcanvas3d/canvas3d.cpp
+++ b/src/imports/qtcanvas3d/canvas3d.cpp
@@ -582,6 +582,23 @@ void Canvas::updateWindowParameters()
     }
 }
 
+/*!
+ * \internal
+ *
+ * Blits the antialias fbo into the final render fbo.
+ * Returns the final render fbo handle.
+ */
+GLuint Canvas::resolveMSAAFbo()
+{
+    qCDebug(canvas3drendering).nospace() << "Canvas3D::" << __FUNCTION__
+                                         << " Resolving MSAA from FBO:"
+                                         << m_antialiasFbo->handle()
+                                         << " to FBO:" << m_renderFbo->handle();
+    QOpenGLFramebufferObject::blitFramebuffer(m_renderFbo, m_antialiasFbo);
+
+    return m_renderFbo->handle();
+}
+
 /*!
  * \internal
  */
@@ -791,14 +808,8 @@ void Canvas::renderNext()
                                          << " Emit paintGL() signal";
     emit paintGL();
 
-    // Resolve MSAA
-    if (m_contextAttribs.antialias()) {
-        qCDebug(canvas3drendering).nospace() << "Canvas3D::" << __FUNCTION__
-                                             << " Resolving MSAA from FBO:"
-                                             << m_antialiasFbo->handle()
-                                             << " to FBO:" << m_renderFbo->handle();
-        QOpenGLFramebufferObject::blitFramebuffer(m_renderFbo, m_antialiasFbo);
-    }
+    if (m_contextAttribs.antialias())
+        resolveMSAAFbo();
 
     // We need to flush the contents to the FBO before posting
     // the texture to the other thread, otherwise, we might
diff --git a/src/imports/qtcanvas3d/canvas3d_p.h b/src/imports/qtcanvas3d/canvas3d_p.h
index fe7f0d5..08be21a 100644
--- a/src/imports/qtcanvas3d/canvas3d_p.h
+++ b/src/imports/qtcanvas3d/canvas3d_p.h
@@ -93,6 +93,7 @@ public:
     void createFBOs();
 
     void bindCurrentRenderTarget();
+    GLuint resolveMSAAFbo();
 
     uint fps();
 
diff --git a/src/imports/qtcanvas3d/context3d.cpp b/src/imports/qtcanvas3d/context3d.cpp
index 234765a..38e0487 100644
--- a/src/imports/qtcanvas3d/context3d.cpp
+++ b/src/imports/qtcanvas3d/context3d.cpp
@@ -5214,7 +5214,18 @@ void CanvasContext::readPixels(int x, int y, long width, long height, glEnums fo
         return;
     }
 
+    // Check if the buffer is antialiased. If it is, we need to blit to the final buffer before
+    // reading the value.
+    if (m_contextAttributes.antialias()) {
+        GLuint readFbo = m_canvas->resolveMSAAFbo();
+        glBindFramebuffer(GL_FRAMEBUFFER, readFbo);
+    }
+
     glReadPixels(x, y, width, height, format, type, bufferPtr);
+
+    if (m_contextAttributes.antialias())
+        m_canvas->bindCurrentRenderTarget();
+
     logAllGLErrors(__FUNCTION__);
 }
 
-- 
GitLab