diff options
author | Samuel Rødal <srodal@gmail.com> | 2014-10-31 17:02:36 +0100 |
---|---|---|
committer | Samuel Rødal <srodal@gmail.com> | 2014-11-14 11:49:57 +0100 |
commit | c5a9155fa0da2da1918e7419881eb472f408f9dc (patch) | |
tree | 85ff01bcf246442eb83b2a4f608347903ff34735 | |
parent | 7e29781fac7f864ac80ca52be5e61c4f1a500308 (diff) | |
download | qtwebkit-c5a9155fa0da2da1918e7419881eb472f408f9dc.tar.gz |
Avoid using a separate QOpenGLContext for 2D canvas if possible
When using a QGLWidget or QOpenGLWidget as a QGraphicsView viewport, we
can share the context used there. The OpenGL paint engines already keep
track of which engine is currently active on a context, and if necessary
do a state sync to give control to a different paint engine.
The TextureMapperGL does not interfere with the canvas rendering, as
canvas rendering happens entirely separate from the compositing step.
TextureMapperGL's compositing code is also wrapped inside a
QPainter::beginNativePainting() and QPainter::endNativePainting() block,
which means that the paint engine gets a chance to ensure the correct
paint device is the active target, if there have been framebuffer
objects bound for canvas rendering since the last frame.
This can result in significant performance improvements on graphics
drivers where context switching is expensive.
Change-Id: I00ac4e26c026e10549b18bef1fdf4322dd17eeee
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
-rw-r--r-- | Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp | 50 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp | 2 |
2 files changed, 30 insertions, 22 deletions
diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp index dac6f1bc2..4a1651548 100644 --- a/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp +++ b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp @@ -60,16 +60,10 @@ namespace WebCore { class QOpenGLContextThreadStorage { public: - QOpenGLContext *context(QOpenGLContext* sharedContext, const QSurfaceFormat& format) { + QOpenGLContext *context() { QOpenGLContext *&context = storage.localData(); - if (context && context->shareContext() != sharedContext) { - delete context; - context = 0; - } if (!context) { context = new QOpenGLContext; - context->setShareContext(sharedContext); - context->setFormat(format); context->create(); } return context; @@ -86,33 +80,47 @@ Q_GLOBAL_STATIC(QOpenGLContextThreadStorage, imagebuffer_opengl_context) class ImageBufferContext { public: ImageBufferContext(QOpenGLContext* sharedContext) + : m_ownSurface(0) { - // Make a format compatible with the host QOpenGLContext, but only singlebuffered. - QSurfaceFormat format; if (sharedContext) - format = sharedContext->format(); - format.setSwapBehavior(QSurfaceFormat::SingleBuffer); - format.setAlphaBufferSize(8); - m_context = imagebuffer_opengl_context->context(sharedContext, format); - m_surface = new QOffscreenSurface; - m_surface->setFormat(format); - m_surface->create(); + m_format = sharedContext->format(); + + m_context = sharedContext ? sharedContext : imagebuffer_opengl_context->context(); + + m_surface = m_context->surface(); } ~ImageBufferContext() { - if (QOpenGLContext::currentContext() == m_context && m_context->surface() == m_surface) + if (QOpenGLContext::currentContext() == m_context && m_context->surface() == m_ownSurface) m_context->doneCurrent(); - delete m_surface; + delete m_ownSurface; } - void makeCurrentIfNeeded() { - if (QOpenGLContext::currentContext() != m_context || m_context->surface() != m_surface) + void createSurfaceIfNeeded() + { + if (m_surface) + return; + + m_ownSurface = new QOffscreenSurface; + m_ownSurface->setFormat(m_format); + m_ownSurface->create(); + + m_surface = m_ownSurface; + } + void makeCurrentIfNeeded() + { + if (QOpenGLContext::currentContext() != m_context) { + createSurfaceIfNeeded(); + m_context->makeCurrent(m_surface); + } } QOpenGLContext* context() { return m_context; } private: - QOffscreenSurface *m_surface; + QSurface *m_surface; + QOffscreenSurface *m_ownSurface; QOpenGLContext *m_context; + QSurfaceFormat m_format; }; // ---------------------- ImageBufferDataPrivateAccelerated diff --git a/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp b/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp index 9e383b087..569b8cb3f 100644 --- a/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp +++ b/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp @@ -41,7 +41,7 @@ QFramebufferPaintDevice::QFramebufferPaintDevice(const QSize& size, void QFramebufferPaintDevice::ensureActiveTarget() { - if (QOpenGLContext::currentContext() != context() || context()->surface() != m_surface) + if (QOpenGLContext::currentContext() != context()) context()->makeCurrent(m_surface); m_framebufferObject.bind(); |