summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Rødal <srodal@gmail.com>2014-10-29 14:03:44 +0100
committerSamuel Rødal <srodal@gmail.com>2014-11-04 15:17:55 +0100
commitcab992ea0898676ba83ca5eb95d346bfa185421e (patch)
treee8fe9a8c678b33fb8c62d1fa35906f59d19766e5
parentb4f2205830a4dc199452bc26fb8cab6741a3d4e7 (diff)
downloadqtwebkit-cab992ea0898676ba83ca5eb95d346bfa185421e.tar.gz
Fixed self-drawing of 2D canvas with accelerated 2D canvas enabled.
The canvas 2D API allows drawing the canvas onto itself, however with accelerated 2D canvas enabled the canvas is implemented in terms of rendering to a texture using framebuffer objects. OpenGL does not allow having the same texture be both a source and a destination in the same rendering operation, so the results are undefined. Instead, we need to blit the texture into a temporary framebuffer object, before using that as the source of the final drawing operation. Task-number: QTBUG-42275 Change-Id: I8114814dab2c8c6ca90b8d35a37b383b79923cb3 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp22
-rw-r--r--Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp15
-rw-r--r--Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.h4
3 files changed, 34 insertions, 7 deletions
diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp
index ca404869a..a7e60d090 100644
--- a/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp
@@ -200,7 +200,27 @@ void ImageBufferDataPrivateAccelerated::draw(GraphicsContext* destContext, Color
// If accelerated compositing is disabled, this may be the painter of the QGLWidget, which is a QGL2PaintEngineEx.
QOpenGL2PaintEngineEx* acceleratedPaintEngine = dynamic_cast<QOpenGL2PaintEngineEx*>(destContext->platformContext()->paintEngine());
if (acceleratedPaintEngine) {
- acceleratedPaintEngine->drawTexture(destRect, m_paintDevice->texture(), m_paintDevice->size(), srcRect);
+ QPaintDevice* targetPaintDevice = acceleratedPaintEngine->paintDevice();
+
+ QRect rect(QPoint(), m_paintDevice->size());
+
+ // Using the same texture as source and target of a rendering operation is undefined in OpenGL,
+ // so if that's the case we need to use a temporary intermediate buffer.
+ if (m_paintDevice == targetPaintDevice) {
+ m_context->makeCurrentIfNeeded();
+
+ QFramebufferPaintDevice device(rect.size(), QOpenGLFramebufferObject::NoAttachment, false);
+
+ QPainter painter(&device);
+ QOpenGL2PaintEngineEx* pe = static_cast<QOpenGL2PaintEngineEx*>(painter.paintEngine());
+ pe->drawTexture(rect, m_paintDevice->texture(), rect.size(), rect);
+ painter.end();
+
+ acceleratedPaintEngine->drawTexture(destRect, device.texture(), rect.size(), srcRect);
+ } else {
+ acceleratedPaintEngine->drawTexture(destRect, m_paintDevice->texture(), rect.size(), srcRect);
+ }
+
return;
}
}
diff --git a/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp b/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp
index 6d5936956..9e383b087 100644
--- a/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp
+++ b/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp
@@ -21,17 +21,22 @@
#include "QFramebufferPaintDevice.h"
#include <QOpenGLFunctions>
-QFramebufferPaintDevice::QFramebufferPaintDevice(const QSize& size)
+QFramebufferPaintDevice::QFramebufferPaintDevice(const QSize& size,
+ QOpenGLFramebufferObject::Attachment attachment,
+ bool clearOnInit)
: QOpenGLPaintDevice(size)
- , m_framebufferObject(size, QOpenGLFramebufferObject::CombinedDepthStencil)
+ , m_framebufferObject(size, attachment)
{
m_surface = QOpenGLContext::currentContext()->surface();
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
setPaintFlipped(true);
#endif
- m_framebufferObject.bind();
- context()->functions()->glClearColor(0, 0, 0, 0);
- context()->functions()->glClear(GL_COLOR_BUFFER_BIT);
+ if (clearOnInit) {
+ m_framebufferObject.bind();
+
+ context()->functions()->glClearColor(0, 0, 0, 0);
+ context()->functions()->glClear(GL_COLOR_BUFFER_BIT);
+ }
}
void QFramebufferPaintDevice::ensureActiveTarget()
diff --git a/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.h b/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.h
index 795a55568..757c417f9 100644
--- a/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.h
+++ b/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.h
@@ -27,7 +27,9 @@
class QFramebufferPaintDevice : public QOpenGLPaintDevice {
public:
- QFramebufferPaintDevice(const QSize& size);
+ QFramebufferPaintDevice(const QSize& size,
+ QOpenGLFramebufferObject::Attachment attachment = QOpenGLFramebufferObject::CombinedDepthStencil,
+ bool clearOnInit = true);
// QOpenGLPaintDevice:
virtual void ensureActiveTarget() Q_DECL_OVERRIDE;