summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@nokia.com>2010-05-10 13:12:30 (GMT)
committerPaul Olav Tvete <paul.tvete@nokia.com>2010-05-10 13:12:30 (GMT)
commit395508f4700bb72c120e0f9e8a19ffa69a7c5d88 (patch)
tree92efbecc98b018cfc617aab2c4811f921becd79c /src/opengl
parent6f39ecdabdae9b2132729a2a9940e5febaa420d2 (diff)
parent03f8f1df0d88f5ffe0b3120cffce614cbeefdb70 (diff)
downloadQt-395508f4700bb72c120e0f9e8a19ffa69a7c5d88.zip
Qt-395508f4700bb72c120e0f9e8a19ffa69a7c5d88.tar.gz
Qt-395508f4700bb72c120e0f9e8a19ffa69a7c5d88.tar.bz2
Merge remote branch 'qt/4.7' into lighthouse-4.7
Conflicts: src/gui/egl/egl.pri src/gui/painting/qwindowsurface_p.h
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h16
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp33
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h4
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h2
-rw-r--r--src/opengl/qgl.cpp51
-rw-r--r--src/opengl/qgl.h1
-rw-r--r--src/opengl/qgl_p.h2
-rw-r--r--src/opengl/qgl_x11egl.cpp23
-rw-r--r--src/opengl/qglextensions.cpp11
-rw-r--r--src/opengl/qglpaintdevice.cpp16
-rw-r--r--src/opengl/qglpaintdevice_p.h1
-rw-r--r--src/opengl/qgraphicssystem_gl.cpp22
-rw-r--r--src/opengl/qgraphicssystem_gl_p.h4
-rw-r--r--src/opengl/qpixmapdata_x11gl_egl.cpp247
-rw-r--r--src/opengl/qpixmapdata_x11gl_p.h8
-rw-r--r--src/opengl/qwindowsurface_gl.cpp11
-rw-r--r--src/opengl/qwindowsurface_x11gl.cpp130
-rw-r--r--src/opengl/qwindowsurface_x11gl_p.h1
18 files changed, 358 insertions, 225 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
index 3379296..8dba951 100644
--- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
@@ -282,7 +282,7 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\n\
uniform mediump vec2 halfViewportSize; \n\
uniform highp vec2 invertedTextureSize; \n\
uniform highp mat3 brushTransform; \n\
- varying highp vec2 textureCoords; \n\
+ varying highp vec2 brushTextureCoords; \n\
void setPosition(void) \n\
{ \n\
highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
@@ -292,7 +292,7 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\n\
mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
- textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\
+ brushTextureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\
}\n";
static const char* const qglslAffinePositionWithTextureBrushVertexShader
@@ -303,28 +303,28 @@ static const char* const qglslAffinePositionWithTextureBrushVertexShader
// we emulate GL_REPEAT by only taking the fractional part of the texture coords.
// TODO: Special case POT textures which don't need this emulation
static const char* const qglslTextureBrushSrcFragmentShader = "\n\
- varying highp vec2 textureCoords; \n\
+ varying highp vec2 brushTextureCoords; \n\
uniform lowp sampler2D brushTexture; \n\
lowp vec4 srcPixel() { \n\
- return texture2D(brushTexture, fract(textureCoords)); \n\
+ return texture2D(brushTexture, fract(brushTextureCoords)); \n\
}\n";
#else
static const char* const qglslTextureBrushSrcFragmentShader = "\n\
- varying highp vec2 textureCoords; \n\
+ varying highp vec2 brushTextureCoords; \n\
uniform lowp sampler2D brushTexture; \n\
lowp vec4 srcPixel() \n\
{ \n\
- return texture2D(brushTexture, textureCoords); \n\
+ return texture2D(brushTexture, brushTextureCoords); \n\
}\n";
#endif
static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\
- varying highp vec2 textureCoords; \n\
+ varying highp vec2 brushTextureCoords; \n\
uniform lowp vec4 patternColor; \n\
uniform lowp sampler2D brushTexture; \n\
lowp vec4 srcPixel() \n\
{ \n\
- return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \n\
+ return patternColor * (1.0 - texture2D(brushTexture, brushTextureCoords).r); \n\
}\n";
// Solid Fill Brush
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index c89d34f..4461358 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -573,9 +573,9 @@ void QGL2PaintEngineExPrivate::resetGLState()
glStencilMask(0xff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_ALWAYS, 0, 0xff);
- glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
- glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glDisableVertexAttribArray(QT_OPACITY_ATTR);
+ ctx->d_func()->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false);
+ ctx->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false);
+ ctx->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
#ifndef QT_OPENGL_ES_2
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // color may have been changed by glVertexAttrib()
#endif
@@ -1337,9 +1337,12 @@ void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem)
d->drawCachedGlyphs(glyphType, textItem, true);
}
-void QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src)
+bool QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src)
{
Q_D(QGL2PaintEngineEx);
+ if (!d->shaderManager)
+ return false;
+
ensureActive();
d->transferMode(ImageDrawingMode);
@@ -1354,6 +1357,7 @@ void QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const
d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, textureId);
d->drawTexture(dest, srcRect, size, false);
+ return true;
}
void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem)
@@ -1807,27 +1811,6 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->dirtyStencilRegion = QRect(0, 0, d->width, d->height);
d->stencilClean = true;
- switch (pdev->devType()) {
- case QInternal::Pixmap:
- d->deviceHasAlpha = static_cast<QPixmap *>(pdev)->hasAlphaChannel();
- break;
- case QInternal::FramebufferObject:
- {
- GLenum f = static_cast<QGLFramebufferObject *>(pdev)->format().internalTextureFormat();
-#ifndef QT_OPENGL_ES
- d->deviceHasAlpha = (f != GL_RGB && f != GL_RGB5 && f != GL_RGB8);
-#else
- d->deviceHasAlpha = (f == GL_RGBA);
-#endif
- }
- break;
- default:
- // widget, pbuffer
- d->deviceHasAlpha = d->ctx->d_func()->reqFormat.alpha();
- break;
- }
-
-
// Calling begin paint should make the correct context current. So, any
// code which calls into GL or otherwise needs a current context *must*
// go after beginPaint:
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 2ac2ca4..6ba0c42 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -123,7 +123,6 @@ public:
virtual void renderHintsChanged();
virtual void transformChanged();
- virtual void drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr);
virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
QPainter::PixmapFragmentHints hints);
@@ -136,6 +135,8 @@ public:
virtual void drawStaticTextItem(QStaticTextItem *textItem);
+ bool drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr);
+
Type type() const { return OpenGL2; }
virtual void setState(QPainterState *s);
@@ -290,7 +291,6 @@ public:
bool needsSync;
bool multisamplingAlwaysEnabled;
- bool deviceHasAlpha;
GLfloat depthRange[2];
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
index 04731b1..75c2bb1 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
@@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE
class QGL2PaintEngineExPrivate;
-class QGLTextureGlyphCache : public QObject, public QTextureGlyphCache
+class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QObject, public QTextureGlyphCache
{
Q_OBJECT
public:
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 26eb1e7..634231d 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1259,11 +1259,24 @@ QGLFormat::OpenGLVersionFlags Q_AUTOTEST_EXPORT qOpenGLVersionFlagsFromString(co
versionFlags |= QGLFormat::OpenGL_Version_3_2;
case '1':
versionFlags |= QGLFormat::OpenGL_Version_3_1;
+ case '0':
+ break;
default:
+ versionFlags |= QGLFormat::OpenGL_Version_3_1 |
+ QGLFormat::OpenGL_Version_3_2;
break;
}
} else {
- qWarning("Unrecognised OpenGL version");
+ versionFlags |= QGLFormat::OpenGL_Version_1_1 |
+ QGLFormat::OpenGL_Version_1_2 |
+ QGLFormat::OpenGL_Version_1_3 |
+ QGLFormat::OpenGL_Version_1_4 |
+ QGLFormat::OpenGL_Version_1_5 |
+ QGLFormat::OpenGL_Version_2_0 |
+ QGLFormat::OpenGL_Version_2_1 |
+ QGLFormat::OpenGL_Version_3_0 |
+ QGLFormat::OpenGL_Version_3_1 |
+ QGLFormat::OpenGL_Version_3_2;
}
}
return versionFlags;
@@ -1644,7 +1657,14 @@ static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, boo
uint *q = (uint*)img.scanLine(y);
for (int x=0; x < w; ++x) {
const uint pixel = *q;
- *q = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00);
+ if (alpha_format && include_alpha) {
+ *q = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff)
+ | (pixel & 0xff00ff00);
+ } else {
+ *q = 0xff000000 | ((pixel << 16) & 0xff0000)
+ | ((pixel >> 16) & 0xff) | (pixel & 0x00ff00);
+ }
+
q++;
}
}
@@ -1655,7 +1675,8 @@ static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, boo
QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
{
- QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32);
+ QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32
+ : QImage::Format_RGB32);
int w = size.width();
int h = size.height();
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
@@ -2781,8 +2802,8 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
if (!eng->isNativePaintingActive()) {
QRectF src(0, 0, target.width(), target.height());
QSize size(target.width(), target.height());
- eng->drawTexture(target, textureId, size, src);
- return;
+ if (eng->drawTexture(target, textureId, size, src))
+ return;
}
}
@@ -2857,8 +2878,8 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text
QRectF dest(point, QSizeF(textureWidth, textureHeight));
QRectF src(0, 0, textureWidth, textureHeight);
QSize size(textureWidth, textureHeight);
- eng->drawTexture(dest, textureId, size, src);
- return;
+ if (eng->drawTexture(dest, textureId, size, src))
+ return;
}
}
@@ -3991,7 +4012,7 @@ bool QGLWidget::event(QEvent *e)
if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) {
// The window may have been re-created during re-parent or state change - if so, the EGL
// surface will need to be re-created.
- d->recreateEglSurface(false);
+ d->recreateEglSurface();
}
#endif
#elif defined(Q_WS_WIN)
@@ -5168,11 +5189,17 @@ Q_OPENGL_EXPORT void qt_set_gl_library_name(const QString& name)
Q_OPENGL_EXPORT const QString qt_gl_library_name()
{
if (qt_gl_lib_name()->isNull()) {
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
- return QLatin1String("GL");
-#else // Q_WS_MAC
+#ifdef Q_WS_MAC
return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib");
-#endif
+#else
+# if defined(QT_OPENGL_ES_1)
+ return QLatin1String("GLES_CM");
+# elif defined(QT_OPENGL_ES_2)
+ return QLatin1String("GLESv2");
+# else
+ return QLatin1String("GL");
+# endif
+#endif // defined Q_WS_MAC
}
return *qt_gl_lib_name();
}
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index e389e3f..701aa8e 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -436,6 +436,7 @@ private:
friend class QGLFBOGLPaintDevice;
friend class QGLPaintDevice;
friend class QX11GLPixmapData;
+ friend class QX11GLSharedContexts;
private:
Q_DISABLE_COPY(QGLContext)
};
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index a2445b7..37466d8 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -199,7 +199,7 @@ public:
#elif defined(Q_WS_X11)
QGLOverlayWidget *olw;
#ifndef QT_NO_EGL
- void recreateEglSurface(bool force);
+ void recreateEglSurface();
WId eglSurfaceWindowId;
#endif
#elif defined(Q_WS_MAC)
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp
index d67a3ea..9d28de0 100644
--- a/src/opengl/qgl_x11egl.cpp
+++ b/src/opengl/qgl_x11egl.cpp
@@ -335,24 +335,23 @@ void QGLWidget::setColormap(const QGLColormap &)
{
}
-// Re-creates the EGL surface if the window ID has changed or if force is true
-void QGLWidgetPrivate::recreateEglSurface(bool force)
+// Re-creates the EGL surface if the window ID has changed or if there isn't a surface
+void QGLWidgetPrivate::recreateEglSurface()
{
Q_Q(QGLWidget);
Window currentId = q->winId();
- if ( force || (currentId != eglSurfaceWindowId) ) {
- // The window id has changed so we need to re-create the EGL surface
- QEglContext *ctx = glcx->d_func()->eglContext;
- EGLSurface surface = glcx->d_func()->eglSurface;
- if (surface != EGL_NO_SURFACE)
- ctx->destroySurface(surface); // Will force doneCurrent() if nec.
- surface = ctx->createSurface(q);
- if (surface == EGL_NO_SURFACE)
- qWarning("Error creating EGL window surface: 0x%x", eglGetError());
- glcx->d_func()->eglSurface = surface;
+ // If the window ID has changed since the surface was created, we need to delete the
+ // old surface before re-creating a new one. Note: This should not be the case as the
+ // surface should be deleted before the old window id.
+ if (glcx->d_func()->eglSurface != EGL_NO_SURFACE && (currentId != eglSurfaceWindowId)) {
+ qWarning("EGL surface for deleted window %x was not destroyed", eglSurfaceWindowId);
+ glcx->d_func()->destroyEglSurfaceForDevice();
+ }
+ if (glcx->d_func()->eglSurface == EGL_NO_SURFACE) {
+ glcx->d_func()->eglSurface = glcx->d_func()->eglContext->createSurface(q);
eglSurfaceWindowId = currentId;
}
}
diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp
index ef3c4cd..8e2bbd4 100644
--- a/src/opengl/qglextensions.cpp
+++ b/src/opengl/qglextensions.cpp
@@ -235,11 +235,6 @@ bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx)
bool qt_resolve_glsl_extensions(QGLContext *ctx)
{
- // Geometry shaders are optional...
- glProgramParameteriEXT = (_glProgramParameteriEXT) ctx->getProcAddress(QLatin1String("glProgramParameteriEXT"));
- glFramebufferTextureEXT = (_glFramebufferTextureEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureEXT"));
- glFramebufferTextureLayerEXT = (_glFramebufferTextureLayerEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureLayerEXT"));
- glFramebufferTextureFaceEXT = (_glFramebufferTextureFaceEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureFaceEXT"));
#if defined(QT_OPENGL_ES_2)
// The GLSL shader functions are always present in OpenGL/ES 2.0.
@@ -254,6 +249,12 @@ bool qt_resolve_glsl_extensions(QGLContext *ctx)
if (glCreateShader)
return true;
+ // Geometry shaders are optional...
+ glProgramParameteriEXT = (_glProgramParameteriEXT) ctx->getProcAddress(QLatin1String("glProgramParameteriEXT"));
+ glFramebufferTextureEXT = (_glFramebufferTextureEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureEXT"));
+ glFramebufferTextureLayerEXT = (_glFramebufferTextureLayerEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureLayerEXT"));
+ glFramebufferTextureFaceEXT = (_glFramebufferTextureFaceEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureFaceEXT"));
+
glCreateShader = (_glCreateShader) ctx->getProcAddress(QLatin1String("glCreateShader"));
if (glCreateShader) {
glShaderSource = (_glShaderSource) ctx->getProcAddress(QLatin1String("glShaderSource"));
diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp
index 2d82222..e874e85 100644
--- a/src/opengl/qglpaintdevice.cpp
+++ b/src/opengl/qglpaintdevice.cpp
@@ -63,6 +63,22 @@ QGLPaintDevice::~QGLPaintDevice()
{
}
+int QGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ switch(metric) {
+ case PdmWidth:
+ return size().width();
+ case PdmHeight:
+ return size().height();
+ case PdmDepth: {
+ const QGLFormat f = format();
+ return f.redBufferSize() + f.greenBufferSize() + f.blueBufferSize() + f.alphaBufferSize();
+ }
+ default:
+ qWarning("QGLPaintDevice::metric() - metric %d not known", metric);
+ return 0;
+ }
+}
void QGLPaintDevice::beginPaint()
{
diff --git a/src/opengl/qglpaintdevice_p.h b/src/opengl/qglpaintdevice_p.h
index 3d669da..04f9c3c 100644
--- a/src/opengl/qglpaintdevice_p.h
+++ b/src/opengl/qglpaintdevice_p.h
@@ -81,6 +81,7 @@ public:
static QGLPaintDevice* getDevice(QPaintDevice*);
protected:
+ int metric(QPaintDevice::PaintDeviceMetric metric) const;
GLuint m_previousFBO;
GLuint m_thisFBO;
};
diff --git a/src/opengl/qgraphicssystem_gl.cpp b/src/opengl/qgraphicssystem_gl.cpp
index a282e4c..58cc28a 100644
--- a/src/opengl/qgraphicssystem_gl.cpp
+++ b/src/opengl/qgraphicssystem_gl.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qgraphicssystem_gl_p.h"
+#include <QGraphicsView>
#include "private/qpixmap_raster_p.h"
#include "private/qpixmapdata_gl_p.h"
@@ -47,7 +48,7 @@
#include "private/qgl_p.h"
#include <private/qwindowsurface_raster_p.h>
-#if defined(Q_WS_X11) && defined(QT_OPENGL_ES)
+#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
#include "private/qpixmapdata_x11gl_p.h"
#include "private/qwindowsurface_x11gl_p.h"
#endif
@@ -58,10 +59,6 @@ extern QGLWidget *qt_gl_getShareWidget();
QPixmapData *QGLGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
{
-#if defined(Q_WS_X11) && defined(QT_OPENGL_ES)
- if (type == QPixmapData::PixmapType && QX11GLPixmapData::hasX11GLPixmaps())
- return new QX11GLPixmapData();
-#endif
return new QGLPixmapData(type);
}
@@ -75,9 +72,18 @@ QWindowSurface *QGLGraphicsSystem::createWindowSurface(QWidget *widget) const
return new QRasterWindowSurface(widget);
#endif
-#if defined(Q_WS_X11) && defined(QT_OPENGL_ES)
- if (QX11GLPixmapData::hasX11GLPixmaps())
- return new QX11GLWindowSurface(widget);
+#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
+ if (m_useX11GL && QX11GLPixmapData::hasX11GLPixmaps()) {
+ // If the widget is a QGraphicsView which will be re-drawing the entire
+ // scene each frame anyway, we should use QGLWindowSurface as this may
+ // provide proper buffer flipping, which should be faster than QX11GL's
+ // blitting approach:
+ QGraphicsView* qgv = qobject_cast<QGraphicsView*>(widget);
+ if (qgv && qgv->viewportUpdateMode() == QGraphicsView::FullViewportUpdate)
+ return new QGLWindowSurface(widget);
+ else
+ return new QX11GLWindowSurface(widget);
+ }
#endif
return new QGLWindowSurface(widget);
diff --git a/src/opengl/qgraphicssystem_gl_p.h b/src/opengl/qgraphicssystem_gl_p.h
index ff47854..9d2d506 100644
--- a/src/opengl/qgraphicssystem_gl_p.h
+++ b/src/opengl/qgraphicssystem_gl_p.h
@@ -62,10 +62,12 @@ QT_BEGIN_NAMESPACE
class Q_OPENGL_EXPORT QGLGraphicsSystem : public QGraphicsSystem
{
public:
- QGLGraphicsSystem();
+ QGLGraphicsSystem(bool useX11GL);
QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
QWindowSurface *createWindowSurface(QWidget *widget) const;
+private:
+ bool m_useX11GL;
};
QT_END_NAMESPACE
diff --git a/src/opengl/qpixmapdata_x11gl_egl.cpp b/src/opengl/qpixmapdata_x11gl_egl.cpp
index 3ab385a..2c11a0b 100644
--- a/src/opengl/qpixmapdata_x11gl_egl.cpp
+++ b/src/opengl/qpixmapdata_x11gl_egl.cpp
@@ -62,118 +62,173 @@
QT_BEGIN_NAMESPACE
-// On 16bpp systems, RGB & ARGB pixmaps are different bit-depths and therefore need
-// different contexts:
+class QX11GLSharedContexts
+{
+public:
+ QX11GLSharedContexts()
+ : rgbContext(0)
+ , argbContext(0)
+ , sharedQGLContext(0)
+ , sharePixmap(0)
+ {
+ EGLint rgbConfigId;
+ EGLint argbConfigId;
+
+ do {
+ EGLConfig rgbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL, QEgl::Renderable);
+ EGLConfig argbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL,
+ QEgl::Renderable | QEgl::Translucent);
+
+ eglGetConfigAttrib(QEgl::display(), rgbConfig, EGL_CONFIG_ID, &rgbConfigId);
+ eglGetConfigAttrib(QEgl::display(), argbConfig, EGL_CONFIG_ID, &argbConfigId);
+
+ rgbContext = new QEglContext;
+ rgbContext->setConfig(rgbConfig);
+ rgbContext->createContext();
-Q_GLOBAL_STATIC(QEglContext, qt_x11gl_rgbContext);
-Q_GLOBAL_STATIC(QEglContext, qt_x11gl_argbContext)
+ if (!rgbContext->isValid())
+ break;
-QEglContext* QX11GLPixmapData::rgbContext = 0;
-QEglContext* QX11GLPixmapData::argbContext = 0;
+ // If the RGB & ARGB configs are the same, use the same egl context for both:
+ if (rgbConfig == argbConfig)
+ argbContext = rgbContext;
+
+ // Otherwise, create a seperate context to be used for ARGB pixmaps:
+ if (!argbContext) {
+ argbContext = new QEglContext;
+ argbContext->setConfig(argbConfig);
+ bool success = argbContext->createContext(rgbContext);
+ if (!success) {
+ qWarning("QX11GLPixmapData - RGB & ARGB contexts aren't shared");
+ success = argbContext->createContext();
+ if (!success)
+ argbContext = rgbContext; // Might work, worth a shot at least.
+ }
+ }
+ if (!argbContext->isValid())
+ break;
-bool QX11GLPixmapData::hasX11GLPixmaps()
-{
- static bool checkedForX11Pixmaps = false;
- static bool haveX11Pixmaps = false;
+ // Create the pixmap which will be used to create the egl surface for the share QGLContext
+ QX11PixmapData *rgbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
+ rgbPixmapData->resize(8, 8);
+ rgbPixmapData->fill(Qt::red);
+ sharePixmap = new QPixmap(rgbPixmapData);
+ EGLSurface sharePixmapSurface = QEgl::createSurface(sharePixmap, rgbConfig);
+ rgbPixmapData->gl_surface = (void*)sharePixmapSurface;
+
+ // Create the actual QGLContext which will be used for sharing
+ sharedQGLContext = new QGLContext(QX11GLPixmapData::glFormat());
+ sharedQGLContext->d_func()->eglContext = rgbContext;
+ sharedQGLContext->d_func()->eglSurface = sharePixmapSurface;
+ sharedQGLContext->d_func()->valid = true;
+ qt_glformat_from_eglconfig(sharedQGLContext->d_func()->glFormat, rgbConfig);
+
+
+ valid = rgbContext->makeCurrent(sharePixmapSurface);
+
+ // If the ARGB & RGB configs are different, check ARGB works too:
+ if (argbConfig != rgbConfig) {
+ QX11PixmapData *argbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
+ argbPixmapData->resize(8, 8);
+ argbPixmapData->fill(Qt::transparent); // Force ARGB
+ QPixmap argbPixmap(argbPixmapData); // destroys pixmap data when goes out of scope
+ EGLSurface argbPixmapSurface = QEgl::createSurface(&argbPixmap, argbConfig);
+ valid = argbContext->makeCurrent(argbPixmapSurface);
+ argbContext->doneCurrent();
+ eglDestroySurface(QEgl::display(), argbPixmapSurface);
+ argbPixmapData->gl_surface = 0;
+ }
- if (checkedForX11Pixmaps)
- return haveX11Pixmaps;
+ if (!valid) {
+ qWarning() << "Unable to make pixmap surface current:" << QEgl::errorString();
+ break;
+ }
- checkedForX11Pixmaps = true;
+ // The pixmap surface destruction hooks are installed by QGLTextureCache, so we
+ // must make sure this is instanciated:
+ QGLTextureCache::instance();
+ } while(0);
- EGLint rgbConfigId;
- EGLint argbConfigId;
+ if (!valid)
+ cleanup();
+ else
+ qDebug("Using QX11GLPixmapData with EGL config %d for ARGB and config %d for RGB", argbConfigId, rgbConfigId);
- do {
- if (qgetenv("QT_USE_X11GL_PIXMAPS").isEmpty())
- break;
+ }
- EGLConfig rgbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL, QEgl::Renderable);
- EGLConfig argbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL,
- QEgl::Renderable | QEgl::Translucent);
+ ~QX11GLSharedContexts() {
+ cleanup();
+ }
- eglGetConfigAttrib(QEgl::display(), rgbConfig, EGL_CONFIG_ID, &rgbConfigId);
- eglGetConfigAttrib(QEgl::display(), argbConfig, EGL_CONFIG_ID, &argbConfigId);
+ void cleanup() {
+ if (sharedQGLContext) {
+ delete sharedQGLContext;
+ sharedQGLContext = 0;
+ }
+ if (argbContext && argbContext != rgbContext)
+ delete argbContext;
+ argbContext = 0;
- if (!rgbContext) {
- rgbContext = qt_x11gl_rgbContext();
- rgbContext->setConfig(rgbConfig);
- rgbContext->createContext();
+ if (rgbContext) {
+ delete rgbContext;
+ rgbContext = 0;
}
- if (!rgbContext->isValid())
- break;
+ // Deleting the QPixmap will fire the pixmap destruction cleanup hooks which in turn
+ // will destroy the egl surface:
+ if (sharePixmap) {
+ delete sharePixmap;
+ sharePixmap = 0;
+ }
+ }
- // If the configs are the same, use the same egl contexts:
- if (rgbConfig == argbConfig)
- argbContext = rgbContext;
+ bool isValid() { return valid;}
- if (!argbContext) {
- argbContext = qt_x11gl_argbContext();
- argbContext->setConfig(argbConfig);
- argbContext->createContext();
- }
+ // On 16bpp systems, RGB & ARGB pixmaps are different bit-depths and therefore need
+ // different contexts:
+ QEglContext *rgbContext;
+ QEglContext *argbContext;
- if (!argbContext->isValid())
- break;
-
- {
- QX11PixmapData *argbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
- argbPixmapData->resize(100, 100);
- argbPixmapData->fill(Qt::transparent); // Force ARGB
- QPixmap argbPixmap(argbPixmapData);
- EGLSurface argbPixmapSurface = QEgl::createSurface(&argbPixmap, argbConfig);
- haveX11Pixmaps = argbContext->makeCurrent(argbPixmapSurface);
- argbContext->doneCurrent();
- eglDestroySurface(QEgl::display(), argbPixmapSurface);
- }
+ // The share context wraps the rgbContext and is used as the master of the context share
+ // group. As all other contexts will have the same egl context (or a shared one if rgb != argb)
+ // all QGLContexts will actually be sharing and can be in the same context group.
+ QGLContext *sharedQGLContext;
+private:
+ QPixmap *sharePixmap;
+ bool valid;
+};
- if (!haveX11Pixmaps) {
- qWarning() << "Unable to make pixmap surface current:" << QEgl::errorString();
- break;
- }
+static void qt_cleanup_x11gl_share_contexts();
- // If the ARGB & RGB configs are different, check RGB too:
- if (argbConfig != rgbConfig) {
- QX11PixmapData *rgbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
- rgbPixmapData->resize(100, 100);
- rgbPixmapData->fill(Qt::red);
+Q_GLOBAL_STATIC_WITH_INITIALIZER(QX11GLSharedContexts, qt_x11gl_share_contexts,
+ {
+ qAddPostRoutine(qt_cleanup_x11gl_share_contexts);
+ })
- QPixmap rgbPixmap(rgbPixmapData);
- EGLSurface rgbPixmapSurface = QEgl::createSurface(&rgbPixmap, rgbConfig);
- haveX11Pixmaps = rgbContext->makeCurrent(rgbPixmapSurface);
- rgbContext->doneCurrent();
- eglDestroySurface(QEgl::display(), rgbPixmapSurface);
+static void qt_cleanup_x11gl_share_contexts()
+{
+ qt_x11gl_share_contexts()->cleanup();
+}
- if (!haveX11Pixmaps) {
- qWarning() << "Unable to make pixmap config current:" << QEgl::errorString();
- break;
- }
- }
- // The pixmap surface destruction hooks are installed by QGLTextureCache, so we
- // must make sure this is instanciated:
- QGLTextureCache::instance();
- } while (0);
+QX11GLSharedContexts* QX11GLPixmapData::sharedContexts()
+{
+ return qt_x11gl_share_contexts();
+}
- if (!haveX11Pixmaps) {
- if (argbContext && (argbContext != rgbContext)) {
- delete argbContext;
- argbContext = 0;
- }
- if (rgbContext) {
- delete rgbContext;
- rgbContext = 0;
- }
- }
+bool QX11GLPixmapData::hasX11GLPixmaps()
+{
+ static bool checkedForX11GLPixmaps = false;
+ static bool haveX11GLPixmaps = false;
- if (haveX11Pixmaps)
- qDebug("Using QX11GLPixmapData with EGL config %d for ARGB and config %d for RGB", argbConfigId, rgbConfigId);
- else
- qDebug("QX11GLPixmapData is *NOT* being used");
+ if (checkedForX11GLPixmaps)
+ return haveX11GLPixmaps;
- return haveX11Pixmaps;
+ haveX11GLPixmaps = qt_x11gl_share_contexts()->isValid();
+ checkedForX11GLPixmaps = true;
+
+ return haveX11GLPixmaps;
}
QX11GLPixmapData::QX11GLPixmapData()
@@ -257,7 +312,15 @@ QPaintEngine* QX11GLPixmapData::paintEngine() const
if (!ctx) {
ctx = new QGLContext(glFormat());
Q_ASSERT(ctx->d_func()->eglContext == 0);
- ctx->d_func()->eglContext = hasAlphaChannel() ? argbContext : rgbContext;
+ ctx->d_func()->eglContext = hasAlphaChannel() ? sharedContexts()->argbContext : sharedContexts()->rgbContext;
+
+ // While we use a seperate QGLContext for each pixmap, the underlying QEglContext is
+ // the same. So we must use a "fake" QGLContext and fool the texture cache into thinking
+ // each pixmap's QGLContext is sharing with this central one. The only place this is
+ // going to fail is where we the underlying EGL RGB and ARGB contexts aren't sharing.
+ ctx->d_func()->sharing = true;
+ QGLContextGroup::addShare(ctx, sharedContexts()->sharedQGLContext);
+
// Update the glFormat for the QGLContext:
qt_glformat_from_eglconfig(ctx->d_func()->glFormat, ctx->d_func()->eglContext->config());
}
@@ -321,12 +384,6 @@ void QX11GLPixmapData::beginPaint()
QGLPaintDevice::beginPaint();
}
-void QX11GLPixmapData::endPaint()
-{
- glFinish();
- QGLPaintDevice::endPaint();
-}
-
QGLContext* QX11GLPixmapData::context() const
{
return ctx;
diff --git a/src/opengl/qpixmapdata_x11gl_p.h b/src/opengl/qpixmapdata_x11gl_p.h
index 8681336..2d1336b 100644
--- a/src/opengl/qpixmapdata_x11gl_p.h
+++ b/src/opengl/qpixmapdata_x11gl_p.h
@@ -65,6 +65,8 @@
QT_BEGIN_NAMESPACE
+class QX11GLSharedContexts;
+
class QX11GLPixmapData : public QX11PixmapData, public QGLPaintDevice
{
public:
@@ -79,17 +81,13 @@ public:
// Re-implemented from QGLPaintDevice
QPaintEngine* paintEngine() const; // Also re-implements QX11PixmapData::paintEngine
void beginPaint();
- void endPaint();
QGLContext* context() const;
QSize size() const;
static bool hasX11GLPixmaps();
static QGLFormat glFormat();
+ static QX11GLSharedContexts* sharedContexts();
-#ifndef QT_NO_EGL
- static QEglContext* rgbContext;
- static QEglContext* argbContext;
-#endif
private:
mutable QGLContext* ctx;
};
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index d9417d9..ad7c568 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -82,7 +82,7 @@
#define GLX_SAMPLES_ARB 100001
#endif
-#ifdef QT_OPENGL_ES
+#ifndef QT_NO_EGL
#include <private/qeglcontext_p.h>
#endif
@@ -94,8 +94,8 @@ QT_BEGIN_NAMESPACE
#ifdef Q_WS_WIN
extern Q_GUI_EXPORT bool qt_win_owndc_required;
#endif
-QGLGraphicsSystem::QGLGraphicsSystem()
- : QGraphicsSystem()
+QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL)
+ : QGraphicsSystem(), m_useX11GL(useX11GL)
{
#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)
// only override the system defaults if the user hasn't already
@@ -353,6 +353,11 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
QGLContext *ctx = new QGLContext(surfaceFormat, widget);
ctx->create(qt_gl_share_widget()->context());
+#ifndef QT_NO_EGL
+ if (ctx->d_func()->eglContext->configAttrib(EGL_SWAP_BEHAVIOR) != EGL_BUFFER_PRESERVED)
+ setPartialUpdateSupport(false); // Force full-screen updates
+#endif
+
widgetPrivate->extraData()->glContext = ctx;
union { QGLContext **ctxPtr; void **voidPtr; };
diff --git a/src/opengl/qwindowsurface_x11gl.cpp b/src/opengl/qwindowsurface_x11gl.cpp
index 7befe03..3de6cae 100644
--- a/src/opengl/qwindowsurface_x11gl.cpp
+++ b/src/opengl/qwindowsurface_x11gl.cpp
@@ -72,63 +72,66 @@ extern void *qt_getClipRects(const QRegion &r, int &num); // in qpaintengine_x11
void QX11GLWindowSurface::flush(QWidget *widget, const QRegion &widgetRegion, const QPoint &offset)
{
-// qDebug("QX11GLWindowSurface::flush()");
- QTime startTime = QTime::currentTime();
+ // We don't need to know the widget which initiated the flush. Instead we just use the offset
+ // to translate the widgetRegion:
+ Q_UNUSED(widget);
+
if (m_backBuffer.isNull()) {
- qDebug("QHarmattanWindowSurface::flush() - backBuffer is null, not flushing anything");
+ qDebug("QX11GLWindowSurface::flush() - backBuffer is null, not flushing anything");
return;
}
- QPoint widgetOffset = qt_qwidget_data(widget)->wrect.topLeft();
- QRegion windowRegion(widgetRegion);
- QRect boundingRect = widgetRegion.boundingRect();
- if (!widgetOffset.isNull())
- windowRegion.translate(-widgetOffset);
- QRect windowBoundingRect = windowRegion.boundingRect();
+ Q_ASSERT(window()->size() != m_backBuffer.size());
- int rectCount;
- XRectangle *rects = (XRectangle *)qt_getClipRects(windowRegion, rectCount);
- if (rectCount <= 0)
- return;
-// qDebug() << "XSetClipRectangles";
-// for (int i = 0; i < num; ++i)
-// qDebug() << ' ' << i << rects[i].x << rects[i].x << rects[i].y << rects[i].width << rects[i].height;
+ // Wait for all GL rendering to the back buffer pixmap to complete before trying to
+ // copy it to the window. We do this by making sure the pixmap's context is current
+ // and then call eglWaitClient. The EGL 1.4 spec says eglWaitClient doesn't have to
+ // block, just that "All rendering calls...are guaranteed to be executed before native
+ // rendering calls". This makes it potentially less expensive than glFinish.
+ QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data())->context();
+ if (QGLContext::currentContext() != ctx && ctx && ctx->isValid())
+ ctx->makeCurrent();
+ eglWaitClient();
if (m_windowGC == 0) {
- m_windowGC = XCreateGC(X11->display, m_window->handle(), 0, 0);
- XSetGraphicsExposures(X11->display, m_windowGC, False);
+ XGCValues attribs;
+ attribs.graphics_exposures = False;
+ m_windowGC = XCreateGC(X11->display, m_window->handle(), GCGraphicsExposures, &attribs);
}
+ int rectCount;
+ XRectangle *rects = (XRectangle *)qt_getClipRects(widgetRegion, rectCount);
+ if (rectCount <= 0)
+ return;
+
XSetClipRectangles(X11->display, m_windowGC, 0, 0, rects, rectCount, YXBanded);
+
+ QRect dirtyRect = widgetRegion.boundingRect().translated(-offset);
XCopyArea(X11->display, m_backBuffer.handle(), m_window->handle(), m_windowGC,
- boundingRect.x() + offset.x(), boundingRect.y() + offset.y(),
- boundingRect.width(), boundingRect.height(),
- windowBoundingRect.x(), windowBoundingRect.y());
-
- QX11GLPixmapData* pmd = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data());
- Q_ASSERT(pmd->context());
- pmd->context()->makeCurrent();
- XSync(X11->display, False);
+ dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height(),
+ dirtyRect.x(), dirtyRect.y());
+
+ // Make sure the blit of the update from the back buffer to the window completes
+ // before allowing rendering to start again to the back buffer. Otherwise the GPU
+ // might start rendering to the back buffer again while the blit takes place.
eglWaitNative(EGL_CORE_NATIVE_ENGINE);
}
void QX11GLWindowSurface::setGeometry(const QRect &rect)
{
if (rect.width() > m_backBuffer.size().width() || rect.height() > m_backBuffer.size().height()) {
- QSize newSize = rect.size();
-// QSize newSize(1024,512);
- qDebug() << "QX11GLWindowSurface::setGeometry() - creating a pixmap of size" << newSize;
QX11GLPixmapData *pd = new QX11GLPixmapData;
+ QSize newSize = rect.size();
pd->resize(newSize.width(), newSize.height());
m_backBuffer = QPixmap(pd);
if (window()->testAttribute(Qt::WA_TranslucentBackground))
m_backBuffer.fill(Qt::transparent);
+ if (m_pixmapGC) {
+ XFreeGC(X11->display, m_pixmapGC);
+ m_pixmapGC = 0;
+ }
}
-// if (gc)
-// XFreeGC(X11->display, gc);
-// gc = XCreateGC(X11->display, d_ptr->device.handle(), 0, 0);
-// XSetGraphicsExposures(X11->display, gc, False);
QWindowSurface::setGeometry(rect);
}
@@ -139,10 +142,10 @@ bool QX11GLWindowSurface::scroll(const QRegion &area, int dx, int dy)
Q_ASSERT(m_backBuffer.data_ptr()->classId() == QPixmapData::X11Class);
- QX11GLPixmapData* pmd = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data());
- Q_ASSERT(pmd->context());
- pmd->context()->makeCurrent();
- glFinish();
+ // Make sure all GL rendering is complete before starting the scroll operation:
+ QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data())->context();
+ if (QGLContext::currentContext() != ctx && ctx && ctx->isValid())
+ ctx->makeCurrent();
eglWaitClient();
if (!m_pixmapGC)
@@ -154,24 +157,57 @@ bool QX11GLWindowSurface::scroll(const QRegion &area, int dx, int dy)
rect.x()+dx, rect.y()+dy);
}
- XSync(X11->display, False);
+ // Make sure the scroll operation is complete before allowing GL rendering to resume
eglWaitNative(EGL_CORE_NATIVE_ENGINE);
return true;
}
-/*
-void QX11GLWindowSurface::beginPaint(const QRegion &region)
-{
-}
-void QX11GLWindowSurface::endPaint(const QRegion &region)
+QPixmap QX11GLWindowSurface::grabWidget(const QWidget *widget, const QRect& rect) const
{
-}
+ if (!widget || m_backBuffer.isNull())
+ return QPixmap();
-QImage *QX11GLWindowSurface::buffer(const QWidget *widget)
-{
+ QRect srcRect;
+
+ // make sure the rect is inside the widget & clip to widget's rect
+ if (!rect.isEmpty())
+ srcRect = rect & widget->rect();
+ else
+ srcRect = widget->rect();
+
+ if (srcRect.isEmpty())
+ return QPixmap();
+
+ // If it's a child widget we have to translate the coordinates
+ if (widget != window())
+ srcRect.translate(widget->mapTo(window(), QPoint(0, 0)));
+
+ QPixmap::x11SetDefaultScreen(widget->x11Info().screen());
+
+ QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType);
+ pmd->resize(srcRect.width(), srcRect.height());
+ QPixmap px(pmd);
+
+ GC tmpGc = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0);
+
+ // Make sure all GL rendering is complete before copying the window
+ QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.pixmapData())->context();
+ if (QGLContext::currentContext() != ctx && ctx && ctx->isValid())
+ ctx->makeCurrent();
+ eglWaitClient();
+
+ // Copy srcRect from the backing store to the new pixmap
+ XSetGraphicsExposures(X11->display, tmpGc, False);
+ XCopyArea(X11->display, m_backBuffer.handle(), px.handle(), tmpGc,
+ srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), 0, 0);
+ XFreeGC(X11->display, tmpGc);
+
+ // Wait until the copy has finised before allowing more rendering into the back buffer
+ eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+
+ return px;
}
-*/
QT_END_NAMESPACE
diff --git a/src/opengl/qwindowsurface_x11gl_p.h b/src/opengl/qwindowsurface_x11gl_p.h
index 3a952e8..4d493d0 100644
--- a/src/opengl/qwindowsurface_x11gl_p.h
+++ b/src/opengl/qwindowsurface_x11gl_p.h
@@ -68,6 +68,7 @@ public:
void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
void setGeometry(const QRect &rect);
bool scroll(const QRegion &area, int dx, int dy);
+ QPixmap grabWidget(const QWidget *widget, const QRect& rectangle = QRect()) const;
private:
GC m_windowGC;