diff options
author | Samuel Rødal <srodal@gmail.com> | 2014-10-29 14:03:44 +0100 |
---|---|---|
committer | Samuel Rødal <srodal@gmail.com> | 2014-11-04 15:17:55 +0100 |
commit | cab992ea0898676ba83ca5eb95d346bfa185421e (patch) | |
tree | e8fe9a8c678b33fb8c62d1fa35906f59d19766e5 | |
parent | b4f2205830a4dc199452bc26fb8cab6741a3d4e7 (diff) | |
download | qtwebkit-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>
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; |