summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Rødal <srodal@gmail.com>2014-10-31 17:02:36 +0100
committerSamuel Rødal <srodal@gmail.com>2014-11-14 11:49:57 +0100
commitc5a9155fa0da2da1918e7419881eb472f408f9dc (patch)
tree85ff01bcf246442eb83b2a4f608347903ff34735
parent7e29781fac7f864ac80ca52be5e61c4f1a500308 (diff)
downloadqtwebkit-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.cpp50
-rw-r--r--Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp2
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();