From e8f91c93de3599309d8fe11fd94318bfdc51d36c Mon Sep 17 00:00:00 2001
From: Kim Motoyoshi Kalland <kim.kalland@nokia.com>
Date: Thu, 12 Feb 2009 15:59:43 +0100
Subject: Merge branch 'gl2text' of ..\qt-main

---
 src/opengl/gl2paintengineex/qglshader.cpp          |  16 ++-
 src/opengl/gl2paintengineex/qglshader_p.h          |   1 +
 .../gl2paintengineex/qpaintengineex_opengl2.cpp    |   6 ++
 src/opengl/opengl.pro                              |  12 +--
 src/opengl/qgl.cpp                                 |  25 ++++-
 src/opengl/qglextensions.cpp                       |  21 +++-
 src/opengl/qglextensions_p.h                       | 111 ++++++++++++++++++++-
 src/opengl/qglframebufferobject.cpp                |   8 +-
 src/opengl/qglpixelbuffer.cpp                      |  10 +-
 src/opengl/qglpixmapfilter.cpp                     |  20 ++--
 src/opengl/qwindowsurface_gl.cpp                   |   8 +-
 11 files changed, 207 insertions(+), 31 deletions(-)

diff --git a/src/opengl/gl2paintengineex/qglshader.cpp b/src/opengl/gl2paintengineex/qglshader.cpp
index 634be84..4ac6e61 100644
--- a/src/opengl/gl2paintengineex/qglshader.cpp
+++ b/src/opengl/gl2paintengineex/qglshader.cpp
@@ -49,7 +49,11 @@
                     return false; \
                 ctx->makeCurrent(); \
 
-
+#if !defined(QT_OPENGL_ES_2)
+static const char *qglslDefines = "#define lowp\n#define mediump\n#define highp\n";
+#else
+static const char *qglslDefines = "";
+#endif
 
 
 class QGLShaderPrivate
@@ -131,9 +135,13 @@ bool QGLShader::compile()
         return false;
 
     const QByteArray src_ba = d->source.toAscii();
-    const char* src = src_ba.constData();
+    const char* src[2];
+    src[0] = qglslDefines;
+    src[1] = src_ba.constData();
+
 
-    glShaderSource(d->shaderId, 1, &src, 0);
+    QGLContext *ctx = d->ctx;
+    glShaderSource(d->shaderId, 2, src, 0);
 
     glCompileShader(d->shaderId);
 
@@ -160,6 +168,7 @@ QString QGLShader::log()
     GLint  logSize;
     GLint  logLength;
 
+    QGLContext *ctx = d->ctx;
     glGetShaderiv(d->shaderId, GL_INFO_LOG_LENGTH, &logSize);
 
     if (!logSize)
@@ -377,6 +386,7 @@ void QGLShaderProgram::use()
     if (!d->valid)
         return;
 
+    QGLContext *ctx = d->ctx;
     glUseProgram(d->programId);
 }
 
diff --git a/src/opengl/gl2paintengineex/qglshader_p.h b/src/opengl/gl2paintengineex/qglshader_p.h
index 1625b84..4cbf3f6 100644
--- a/src/opengl/gl2paintengineex/qglshader_p.h
+++ b/src/opengl/gl2paintengineex/qglshader_p.h
@@ -81,6 +81,7 @@ SAMPLER_2D_SHADOW.
 
 #include <QtOpenGL>
 
+#include <private/qgl_p.h>
 
 typedef struct {
     GLfloat a;
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index a74f044..2948e62 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -845,6 +845,7 @@ void QGL2PaintEngineEx::transformChanged()
 void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src)
 {
     Q_D(QGL2PaintEngineEx);
+    QGLContext *ctx = d->ctx;
     glActiveTexture(QT_BRUSH_TEXTURE_UNIT);
 
     d->ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, true);
@@ -862,6 +863,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const
                         Qt::ImageConversionFlags)
 {
     Q_D(QGL2PaintEngineEx);
+    QGLContext *ctx = d->ctx;
     glActiveTexture(QT_BRUSH_TEXTURE_UNIT);
     d->ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true);
 
@@ -926,6 +928,7 @@ void QGL2PaintEngineEx::drawCachedGlyphs(const QPointF &p, const QTextItemInt &t
     const QImage &image = cache->image();
     int margin = cache->glyphMargin();
 
+    QGLContext *ctx = d->ctx;
     glActiveTexture(QT_BRUSH_TEXTURE_UNIT);
     d->ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true);
 
@@ -1000,6 +1003,9 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
     d->width = widget->width();
     d->height = widget->height();
 
+    qt_resolve_version_1_3_functions(d->ctx);
+    qt_resolve_glsl_extensions(d->ctx);
+
     if (!d->shaderManager)
         d->shaderManager = new QGLPEXShaderManager(d->ctx);
 
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index 48d7caf..af16312 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -34,12 +34,12 @@ SOURCES	+= qgl.cpp \
            qglextensions.cpp \
            qglpixmapfilter.cpp
 
-!contains(QT_CONFIG, opengles2) {
-    HEADERS += qpaintengine_opengl_p.h
-    SOURCES += qpaintengine_opengl.cpp
-}
+#!contains(QT_CONFIG, opengles2) {
+#    HEADERS += qpaintengine_opengl_p.h
+#    SOURCES += qpaintengine_opengl.cpp
+#}
 
-contains(QT_CONFIG, opengles2) {
+#contains(QT_CONFIG, opengles2) {
     SOURCES +=  gl2paintengineex/qglgradientcache.cpp \
                 gl2paintengineex/qglpexshadermanager.cpp \
                 gl2paintengineex/qglshader.cpp \
@@ -51,7 +51,7 @@ contains(QT_CONFIG, opengles2) {
                 gl2paintengineex/qglshader_p.h \
                 gl2paintengineex/qgl2pexvertexarray_p.h \
                 gl2paintengineex/qpaintengineex_opengl2_p.h
-}
+#}
 
 
 x11 {
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 4c152e2..386e9b8 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -65,7 +65,7 @@
 #include "qimage.h"
 #include "qgl_p.h"
 
-#if defined(QT_OPENGL_ES_2)
+#if 1 || defined(QT_OPENGL_ES_2)
 #include "gl2paintengineex/qpaintengineex_opengl2_p.h"
 #else
 #include <private/qpaintengine_opengl_p.h>
@@ -2041,7 +2041,24 @@ void QGLContext::deleteTexture(QMacCompatGLuint id)
 
 // qpaintengine_opengl.cpp
 #if !defined(QT_OPENGL_ES_2)
-extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array);
+//extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array);
+void qt_add_rect_to_array(const QRectF &r, q_vertexType *array)
+{
+    qreal left = r.left();
+    qreal right = r.right();
+    qreal top = r.top();
+    qreal bottom = r.bottom();
+
+    array[0] = f2vt(left);
+    array[1] = f2vt(top);
+    array[2] = f2vt(right);
+    array[3] = f2vt(top);
+    array[4] = f2vt(right);
+    array[5] = f2vt(bottom);
+    array[6] = f2vt(left);
+    array[7] = f2vt(bottom);
+}
+
 #else
 void qt_add_rect_to_array(const QRectF &r, q_vertexType *array) {};
 #endif
@@ -4039,14 +4056,14 @@ void QGLWidget::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QM
 }
 #endif
 
-#if defined(QT_OPENGL_ES_2)
+#if 1 || defined(QT_OPENGL_ES_2)
 Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_engine)
 #else
 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_engine)
 #endif
 
 #ifdef Q_WS_QWS
-Q_OPENGL_EXPORT QOpenGLPaintEngine* qt_qgl_paint_engine()
+Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine()
 {
 #if !defined(QT_OPENGL_ES_2)
     return qt_gl_engine();
diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp
index 8357cf9..b054fe8 100644
--- a/src/opengl/qglextensions.cpp
+++ b/src/opengl/qglextensions.cpp
@@ -176,10 +176,29 @@ bool qt_resolve_glsl_extensions(QGLContext *ctx)
     glUniform1fv = (_glUniform1fv) ctx->getProcAddress(QLatin1String("glUniform1fv"));
     glUniform1i = (_glUniform1i) ctx->getProcAddress(QLatin1String("glUniform1i"));
 
+    glGetActiveAttrib = (_glGetActiveAttrib) ctx->getProcAddress(QLatin1String("glGetActiveAttrib"));
+    glGetAttribLocation = (_glGetAttribLocation) ctx->getProcAddress(QLatin1String("glGetAttribLocation"));
+    glGetActiveUniform = (_glGetActiveUniform) ctx->getProcAddress(QLatin1String("glGetActiveUniform"));
+    glGetProgramInfoLog = (_glGetProgramInfoLog) ctx->getProcAddress(QLatin1String("glGetProgramInfoLog"));
+    glUniform1f = (_glUniform1f) ctx->getProcAddress(QLatin1String("glUniform1f"));
+    glUniform2f = (_glUniform2f) ctx->getProcAddress(QLatin1String("glUniform2f"));
+    glUniform4f = (_glUniform4f) ctx->getProcAddress(QLatin1String("glUniform4f"));
+    glUniformMatrix2fv = (_glUniformMatrix2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2fv"));
+    glUniformMatrix3fv = (_glUniformMatrix3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3fv"));
+    glUniformMatrix4fv = (_glUniformMatrix4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4fv"));
+    glEnableVertexAttribArray = (_glEnableVertexAttribArray) ctx->getProcAddress(QLatin1String("glEnableVertexAttribArray"));
+    glDisableVertexAttribArray = (_glDisableVertexAttribArray) ctx->getProcAddress(QLatin1String("glDisableVertexAttribArray"));
+    glVertexAttribPointer = (_glVertexAttribPointer) ctx->getProcAddress(QLatin1String("glVertexAttribPointer"));
+    glStencilOpSeparate = (_glStencilOpSeparate) ctx->getProcAddress(QLatin1String("glStencilOpSeparate"));
+
     return glCreateShader && glShaderSource && glCompileShader && glDeleteProgram &&
         glCreateProgram && glAttachShader && glDetachShader && glLinkProgram && glUseProgram &&
         glDeleteProgram && glGetShaderInfoLog && glGetShaderiv && glGetProgramiv && glGetUniformLocation &&
-        glUniform1i && glUniform1fv && glUniform2fv && glUniform3fv && glUniform4fv;
+        glUniform1i && glUniform1fv && glUniform2fv && glUniform3fv && glUniform4fv &&
+        glGetActiveAttrib && glGetAttribLocation && glGetActiveUniform && glGetProgramInfoLog &&
+        glUniform1f && glUniform2f && glUniform4f &&
+        glUniformMatrix2fv && glUniformMatrix3fv && glUniformMatrix4fv &&
+        glEnableVertexAttribArray && glDisableVertexAttribArray && glVertexAttribPointer && glStencilOpSeparate;
 }
 
 QT_END_NAMESPACE
diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h
index a0517f5..fdf0bba 100644
--- a/src/opengl/qglextensions_p.h
+++ b/src/opengl/qglextensions_p.h
@@ -74,6 +74,10 @@
 typedef ptrdiff_t GLsizeiptrARB;
 #endif
 
+#ifndef GL_VERSION_2_0
+typedef char GLchar;
+#endif
+
 // ARB_pixel_buffer_object
 typedef void (APIENTRY *_glBindBufferARB) (GLenum, GLuint);
 typedef void (APIENTRY *_glDeleteBuffersARB) (GLsizei, const GLuint *);
@@ -107,10 +111,10 @@ typedef void (APIENTRY *_glGetShaderiv) (GLuint, GLenum, GLint *);
 typedef void (APIENTRY *_glGetProgramiv) (GLuint, GLenum, GLint *);
 
 typedef GLuint (APIENTRY *_glGetUniformLocation) (GLuint, const char*);
-typedef void (APIENTRY *_glUniform4fv) (GLint, GLsizei, GLfloat *);
-typedef void (APIENTRY *_glUniform3fv) (GLint, GLsizei, GLfloat *);
-typedef void (APIENTRY *_glUniform2fv) (GLint, GLsizei, GLfloat *);
-typedef void (APIENTRY *_glUniform1fv) (GLint, GLsizei, GLfloat *);
+typedef void (APIENTRY *_glUniform4fv) (GLint, GLsizei, const GLfloat *);
+typedef void (APIENTRY *_glUniform3fv) (GLint, GLsizei, const GLfloat *);
+typedef void (APIENTRY *_glUniform2fv) (GLint, GLsizei, const GLfloat *);
+typedef void (APIENTRY *_glUniform1fv) (GLint, GLsizei, const GLfloat *);
 typedef void (APIENTRY *_glUniform1i) (GLint, GLint);
 
 typedef void (APIENTRY *_glActiveStencilFaceEXT) (GLenum );
@@ -118,6 +122,22 @@ typedef void (APIENTRY *_glActiveStencilFaceEXT) (GLenum );
 typedef void (APIENTRY *_glMultiTexCoord4f) (GLenum, GLfloat, GLfloat, GLfloat, GLfloat);
 typedef void (APIENTRY *_glActiveTexture) (GLenum);
 
+typedef void (APIENTRY *_glGetActiveAttrib) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+typedef GLint (APIENTRY *_glGetAttribLocation) (GLuint program, const GLchar* name);
+typedef void (APIENTRY *_glGetActiveUniform) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+typedef void (APIENTRY *_glGetProgramInfoLog) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
+typedef void (APIENTRY *_glUniform1f) (GLint location, GLfloat v0);
+typedef void (APIENTRY *_glUniform2f) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRY *_glUniform4f) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRY *_glUniformMatrix2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (APIENTRY *_glUniformMatrix3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (APIENTRY *_glUniformMatrix4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (APIENTRY *_glEnableVertexAttribArray) (GLuint);
+typedef void (APIENTRY *_glDisableVertexAttribArray) (GLuint);
+typedef void (APIENTRY *_glVertexAttribPointer) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer);
+typedef void (APIENTRY *_glStencilOpSeparate) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+
+
 // EXT_GL_framebuffer_object
 typedef GLboolean (APIENTRY *_glIsRenderbufferEXT) (GLuint renderbuffer);
 typedef void (APIENTRY *_glBindRenderbufferEXT) (GLenum target, GLuint renderbuffer);
@@ -207,6 +227,21 @@ struct QGLExtensionFuncs
         qt_glBufferDataARB = 0;
         qt_glMapBufferARB = 0;
         qt_glUnmapBufferARB = 0;
+
+        qt_glGetActiveAttrib = 0;
+        qt_glGetAttribLocation = 0;
+        qt_glGetActiveUniform = 0;
+        qt_glGetProgramInfoLog = 0;
+        qt_glUniform1f = 0;
+        qt_glUniform2f = 0;
+        qt_glUniform4f = 0;
+        qt_glUniformMatrix2fv = 0;
+        qt_glUniformMatrix3fv = 0;
+        qt_glUniformMatrix4fv = 0;
+        qt_glEnableVertexAttribArray = 0;
+        qt_glDisableVertexAttribArray = 0;
+        qt_glVertexAttribPointer = 0;
+        qt_glStencilOpSeparate = 0;
     }
 
     _glProgramStringARB qt_glProgramStringARB;
@@ -270,6 +305,21 @@ struct QGLExtensionFuncs
     _glBufferDataARB qt_glBufferDataARB;
     _glMapBufferARB qt_glMapBufferARB;
     _glUnmapBufferARB qt_glUnmapBufferARB;
+
+    _glGetActiveAttrib qt_glGetActiveAttrib;
+    _glGetAttribLocation qt_glGetAttribLocation;
+    _glGetActiveUniform qt_glGetActiveUniform;
+    _glGetProgramInfoLog qt_glGetProgramInfoLog;
+    _glUniform1f qt_glUniform1f;
+    _glUniform2f qt_glUniform2f;
+    _glUniform4f qt_glUniform4f;
+    _glUniformMatrix2fv qt_glUniformMatrix2fv;
+    _glUniformMatrix3fv qt_glUniformMatrix3fv;
+    _glUniformMatrix4fv qt_glUniformMatrix4fv;
+    _glEnableVertexAttribArray qt_glEnableVertexAttribArray;
+    _glDisableVertexAttribArray qt_glDisableVertexAttribArray;
+    _glVertexAttribPointer qt_glVertexAttribPointer;
+    _glStencilOpSeparate qt_glStencilOpSeparate;
 };
 
 
@@ -416,6 +466,40 @@ struct QGLExtensionFuncs
 #define GL_UNPACK_IMAGE_HEIGHT            0x806E
 #endif
 
+#ifndef GL_VERSION_1_4
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#endif
+
+#ifndef GL_VERSION_2_0
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_LINK_STATUS 0x8B82
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#endif
+
 #define glProgramStringARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glProgramStringARB
 #define glBindProgramARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBindProgramARB
 #define glDeleteProgramsARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDeleteProgramsARB
@@ -502,6 +586,25 @@ struct QGLExtensionFuncs
 #define glUniform1fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform1fv
 #define glUniform1i QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform1i
 
+#define glGetActiveAttrib QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetActiveAttrib
+#define glGetAttribLocation QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetAttribLocation
+#define glGetActiveUniform QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetActiveUniform
+#define glGetProgramInfoLog QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetProgramInfoLog
+#define glUniform1f QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform1f
+#define glUniform2f QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform2f
+#define glUniform4f QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform4f
+#define glUniformMatrix2fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix2fv
+#define glUniformMatrix3fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix3fv
+#define glUniformMatrix4fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix4fv
+#define glEnableVertexAttribArray QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glEnableVertexAttribArray
+#define glDisableVertexAttribArray QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDisableVertexAttribArray
+#define glVertexAttribPointer QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glVertexAttribPointer
+#define glStencilOpSeparate QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glStencilOpSeparate
+
+#if !defined(QT_OPENGL_ES_2)
+#define glClearDepthf(x) glClearDepth(GLdouble(x))
+#endif
+
 extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx);
 bool qt_resolve_buffer_extensions(QGLContext *ctx);
 
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 8524dfa..9134fc6 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -43,7 +43,11 @@
 
 #include <qdebug.h>
 #include <private/qgl_p.h>
+#if 1 || defined(QT_OPENGL_ES_2)
+#include <private/qpaintengineex_opengl2_p.h>
+#else
 #include <private/qpaintengine_opengl_p.h>
+#endif
 #include <qglframebufferobject.h>
 #include <qlibrary.h>
 #include <qimage.h>
@@ -573,7 +577,9 @@ QImage QGLFramebufferObject::toImage() const
     return image;
 }
 
-#if !defined(QT_OPENGL_ES_2)
+#if 1 || defined(QT_OPENGL_ES_2)
+Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_paintengine)
+#else
 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_paintengine)
 #endif
 
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index 5f74f26..6a207c8 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -81,13 +81,15 @@
 #include <private/qglpixelbuffer_p.h>
 #include <qimage.h>
 
-#if !defined(QT_OPENGL_ES_2)
+#if 1 || defined(QT_OPENGL_ES_2)
+#include <private/qpaintengineex_opengl2_p.h>
+#else
 #include <private/qpaintengine_opengl_p.h>
 #endif
 
 QT_BEGIN_NAMESPACE
 
-#if !defined(QT_OPENGL_ES_2)
+#if 0 && !defined(QT_OPENGL_ES_2)
 extern void qgl_cleanup_glyph_cache(QGLContext *);
 #else
 void qgl_cleanup_glyph_cache(QGLContext *) {}
@@ -363,7 +365,9 @@ bool QGLPixelBuffer::isValid() const
     return !d->invalid;
 }
 
-#if !defined(QT_OPENGL_ES_2)
+#if 1 || defined(QT_OPENGL_ES_2)
+Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_paintengine)
+#else
 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_paintengine)
 #endif
 
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
index ff23948..8a64515 100644
--- a/src/opengl/qglpixmapfilter.cpp
+++ b/src/opengl/qglpixmapfilter.cpp
@@ -138,13 +138,6 @@ void QGLSLProgram::disable()
     glUseProgram(0);
 }
 
-typedef GLuint (APIENTRY *_glGetUniformLocation) (GLuint, const char*);
-typedef void (APIENTRY *_glUniform4fv) (GLint, GLsizei, GLfloat *);
-typedef void (APIENTRY *_glUniform3fv) (GLint, GLsizei, GLfloat *);
-typedef void (APIENTRY *_glUniform2fv) (GLint, GLsizei, GLfloat *);
-typedef void (APIENTRY *_glUniform1fv) (GLint, GLsizei, GLfloat *);
-typedef void (APIENTRY *_glUniform1i) (GLint, GLint);
-
 int QGLSLProgram::getUniformLocation(const QString &name)
 {
     return glGetUniformLocation(m_program, name.toAscii().constData());
@@ -244,7 +237,18 @@ QPixmapFilter *QGLContextPrivate::createPixmapFilter(int type) const
 
 #if !defined(QT_OPENGL_ES_2)
 extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array);
-extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array);
+//extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array);
+void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array)
+{
+    array[0] = f2vt(x1);
+    array[1] = f2vt(y1);
+    array[2] = f2vt(x2);
+    array[3] = f2vt(y1);
+    array[4] = f2vt(x2);
+    array[5] = f2vt(y2);
+    array[6] = f2vt(x1);
+    array[7] = f2vt(y2);
+}
 #endif
 
 static void qgl_drawTexture(const QRectF &rect, int tx_width, int tx_height, const QRectF & src)
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index 3dd3064..bb4ffc5 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -69,7 +69,11 @@
 
 #include <private/qglpixelbuffer_p.h>
 #include <private/qgraphicssystem_gl_p.h>
+#if 1 || defined(QT_OPENGL_ES_2)
+#include <private/qpaintengineex_opengl2_p.h>
+#else
 #include <private/qpaintengine_opengl_p.h>
+#endif
 
 #ifndef GLX_ARB_multisample
 #define GLX_SAMPLE_BUFFERS_ARB  100000
@@ -283,7 +287,9 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
     qDebug() << "hijackWindow() context created for" << widget << d_ptr->contexts.size();
 }
 
-#if !defined(QT_OPENGL_ES_2)
+#if 1 || defined(QT_OPENGL_ES_2)
+Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_window_surface_paintengine)
+#else
 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_window_surface_paintengine)
 #endif
 
-- 
cgit v0.12


From afdd536c50ba14ece1db63f5efab0328730f2e26 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Tue, 17 Feb 2009 14:10:06 +0100
Subject: Fixes:    Move QGLDrawable into qgl_p.h so that we can use it in the
 GL 2 paint engine. RevBy:    Tom Details:  Now we can use the GL 2 paint
 engine on non-widget paint devices like pixel buffers,           framebuffer
 objects, and GL window surfaces. Using -graphicssystem opengl works now.

---
 .../gl2paintengineex/qpaintengineex_opengl2.cpp    |  19 +--
 src/opengl/qgl.cpp                                 | 150 ++++++++++++++++++
 src/opengl/qgl_p.h                                 |  33 ++++
 src/opengl/qpaintengine_opengl.cpp                 | 176 ---------------------
 4 files changed, 193 insertions(+), 185 deletions(-)

diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 2948e62..1cc2233 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -133,10 +133,9 @@ public:
     inline QColor premultiplyColor(QColor c, GLfloat opacity);
 
     QGL2PaintEngineEx* q;
-
-    //### Move into QGLDrawable
+    QGLDrawable drawable;
+    QGLContext *ctx;
     int width, height;
-    QGLContext* ctx;
 
     // Dirty flags
     bool matrixDirty; // Implies matrix uniforms are also dirty
@@ -997,11 +996,12 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
 
 //     qDebug("QGL2PaintEngineEx::begin()");
 
-    QGLWidget* widget = static_cast<QGLWidget*>(pdev);
-    d->ctx = const_cast<QGLContext*>(widget->context());
-    d->ctx->makeCurrent();
-    d->width = widget->width();
-    d->height = widget->height();
+    d->drawable.setDevice(pdev);
+    d->drawable.makeCurrent();
+    d->ctx = d->drawable.context();
+    QSize sz = d->drawable.size();
+    d->width = sz.width();
+    d->height = sz.height();
 
     qt_resolve_version_1_3_functions(d->ctx);
     qt_resolve_glsl_extensions(d->ctx);
@@ -1033,7 +1033,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
 bool QGL2PaintEngineEx::end()
 {
     Q_D(QGL2PaintEngineEx);
-    d->ctx->swapBuffers();
+    d->drawable.swapBuffers();
+    d->drawable.doneCurrent();
     return false;
 }
 
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 386e9b8..7c42039 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -71,9 +71,14 @@
 #include <private/qpaintengine_opengl_p.h>
 #endif
 
+#include <qglpixelbuffer.h>
+#include <qglframebufferobject.h>
+
 #include <private/qimage_p.h>
 #include <private/qpixmapdata_p.h>
 #include <private/qpixmapdata_gl_p.h>
+#include <private/qglpixelbuffer_p.h>
+#include <private/qwindowsurface_gl_p.h>
 #include "qcolormap.h"
 #include "qcache.h"
 #include "qfile.h"
@@ -4219,4 +4224,149 @@ Q_OPENGL_EXPORT const QString qt_gl_library_name()
 }
 #endif
 
+void QGLDrawable::setDevice(QPaintDevice *pdev)
+{
+    wasBound = false;
+    widget = 0;
+    buffer = 0;
+    fbo = 0;
+#ifdef Q_WS_QWS
+    wsurf = 0;
+#endif
+    if (pdev->devType() == QInternal::Widget)
+        widget = static_cast<QGLWidget *>(pdev);
+    else if (pdev->devType() == QInternal::Pbuffer)
+        buffer = static_cast<QGLPixelBuffer *>(pdev);
+    else if (pdev->devType() == QInternal::FramebufferObject)
+        fbo = static_cast<QGLFramebufferObject *>(pdev);
+    else if (pdev->devType() == QInternal::UnknownDevice)
+#ifdef Q_WS_QWS
+        wsurf = static_cast<QWSGLPaintDevice*>(pdev)->windowSurface();
+#else
+        wsurf = static_cast<QGLWindowSurface *>(pdev);
+#endif
+}
+
+void QGLDrawable::swapBuffers()
+{
+    if (widget) {
+        if (widget->autoBufferSwap())
+            widget->swapBuffers();
+    } else {
+        glFlush();
+    }
+}
+
+void QGLDrawable::makeCurrent()
+{
+    if (widget)
+        widget->makeCurrent();
+    else if (buffer)
+        buffer->makeCurrent();
+    else if (wsurf)
+        wsurf->context()->makeCurrent();
+    else if (fbo) {
+        wasBound = fbo->isBound();
+        if (!wasBound)
+            fbo->bind();
+    }
+}
+
+void QGLDrawable::doneCurrent()
+{
+    if (fbo && !wasBound)
+        fbo->release();
+}
+
+QSize QGLDrawable::size() const
+{
+    if (widget) {
+        return QSize(widget->d_func()->glcx->device()->width(),
+                     widget->d_func()->glcx->device()->height());
+    } else if (buffer) {
+        return buffer->size();
+    } else if (fbo) {
+        return fbo->size();
+    } else if (wsurf) {
+#ifdef Q_WS_QWS
+        return wsurf->window()->frameSize();
+#else
+        return QSize(wsurf->width(), wsurf->height());
+#endif
+    }
+    return QSize();
+}
+
+QGLFormat QGLDrawable::format() const
+{
+    if (widget)
+        return widget->format();
+    else if (buffer)
+        return buffer->format();
+    else if (wsurf)
+        return wsurf->context()->format();
+    else if (fbo && QGLContext::currentContext()) {
+        QGLFormat fmt = QGLContext::currentContext()->format();
+        fmt.setStencil(fbo->attachment() == QGLFramebufferObject::CombinedDepthStencil);
+        fmt.setDepth(fbo->attachment() != QGLFramebufferObject::NoAttachment);
+        return fmt;
+    }
+
+    return QGLFormat();
+}
+
+GLuint QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format)
+{
+    if (widget)
+        return widget->d_func()->glcx->d_func()->bindTexture(image, target, format, true);
+    else if (buffer)
+        return buffer->d_func()->qctx->d_func()->bindTexture(image, target, format, true);
+    else if (fbo && QGLContext::currentContext())
+        return const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(image, target, format, true);
+    else if (wsurf)
+        return wsurf->context()->d_func()->bindTexture(image, target, format, true);
+    return 0;
+}
+
+GLuint QGLDrawable::bindTexture(const QPixmap &pixmap, GLenum target, GLint format)
+{
+    if (widget)
+        return widget->d_func()->glcx->d_func()->bindTexture(pixmap, target, format, true);
+    else if (buffer)
+        return buffer->d_func()->qctx->d_func()->bindTexture(pixmap, target, format, true);
+    else if (fbo && QGLContext::currentContext())
+        return const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(pixmap, target, format, true);
+    else if (wsurf)
+        return wsurf->context()->d_func()->bindTexture(pixmap, target, format, true);
+    return 0;
+}
+
+QColor QGLDrawable::backgroundColor() const
+{
+    if (widget)
+        return widget->palette().brush(widget->backgroundRole()).color();
+    return QApplication::palette().brush(QPalette::Background).color();
+}
+
+QGLContext *QGLDrawable::context() const
+{
+    if (widget)
+        return widget->d_func()->glcx;
+    else if (buffer)
+        return buffer->d_func()->qctx;
+    else if (fbo)
+        return const_cast<QGLContext *>(QGLContext::currentContext());
+    else if (wsurf)
+        return wsurf->context();
+    return 0;
+}
+
+bool QGLDrawable::autoFillBackground() const
+{
+    if (widget)
+        return widget->autoFillBackground();
+    else
+        return false;
+}
+
 QT_END_NAMESPACE
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index b15eebc..2eccc23 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -282,6 +282,39 @@ Q_SIGNALS:
     void aboutToDestroyContext(const QGLContext *context);
 };
 
+class QGLPixelBuffer;
+class QGLFramebufferObject;
+class QWSGLWindowSurface;
+class QGLWindowSurface;
+class QGLDrawable {
+public:
+    QGLDrawable() : widget(0), buffer(0), fbo(0)
+                  , wsurf(0)
+        {}
+    void setDevice(QPaintDevice *pdev);
+    void swapBuffers();
+    void makeCurrent();
+    void doneCurrent();
+    QSize size() const;
+    QGLFormat format() const;
+    GLuint bindTexture(const QImage &image, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA);
+    GLuint bindTexture(const QPixmap &pixmap, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA);
+    QColor backgroundColor() const;
+    QGLContext *context() const;
+    bool autoFillBackground() const;
+
+private:
+    bool wasBound;
+    QGLWidget *widget;
+    QGLPixelBuffer *buffer;
+    QGLFramebufferObject *fbo;
+#ifdef Q_WS_QWS
+    QWSGLWindowSurface *wsurf;
+#else
+    QGLWindowSurface *wsurf;
+#endif
+};
+
 // GL extension definitions
 class QGLExtensions {
 public:
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index 976a021..998492c 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -57,13 +57,11 @@
 #include "qpen.h"
 #include "qvarlengtharray.h"
 #include <private/qpainter_p.h>
-#include <qglpixelbuffer.h>
 #include <private/qglpixelbuffer_p.h>
 #include <private/qbezier_p.h>
 #include <qglframebufferobject.h>
 
 #include "private/qtessellator_p.h"
-#include "private/qwindowsurface_gl_p.h"
 
 #include "util/fragmentprograms_p.h"
 
@@ -190,180 +188,6 @@ const QGLTrapezoid QGLTrapezoid::translated(const QPointF &delta) const
     return trap;
 }
 
-class QGLDrawable {
-public:
-    QGLDrawable() : widget(0), buffer(0), fbo(0)
-                  , wsurf(0)
-        {}
-    inline void setDevice(QPaintDevice *pdev);
-    inline void swapBuffers();
-    inline void makeCurrent();
-    inline void doneCurrent();
-    inline QSize size() const;
-    inline QGLFormat format() const;
-    inline GLuint bindTexture(const QImage &image, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA);
-    inline GLuint bindTexture(const QPixmap &pixmap, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA);
-    inline QColor backgroundColor() const;
-    inline QGLContext *context() const;
-    inline bool autoFillBackground() const;
-
-private:
-    bool wasBound;
-    QGLWidget *widget;
-    QGLPixelBuffer *buffer;
-    QGLFramebufferObject *fbo;
-#ifdef Q_WS_QWS
-    QWSGLWindowSurface *wsurf;
-#else
-    QGLWindowSurface *wsurf;
-#endif
-};
-
-void QGLDrawable::setDevice(QPaintDevice *pdev)
-{
-    wasBound = false;
-    widget = 0;
-    buffer = 0;
-    fbo = 0;
-#ifdef Q_WS_QWS
-    wsurf = 0;
-#endif
-    if (pdev->devType() == QInternal::Widget)
-        widget = static_cast<QGLWidget *>(pdev);
-    else if (pdev->devType() == QInternal::Pbuffer)
-        buffer = static_cast<QGLPixelBuffer *>(pdev);
-    else if (pdev->devType() == QInternal::FramebufferObject)
-        fbo = static_cast<QGLFramebufferObject *>(pdev);
-    else if (pdev->devType() == QInternal::UnknownDevice)
-#ifdef Q_WS_QWS
-        wsurf = static_cast<QWSGLPaintDevice*>(pdev)->windowSurface();
-#else
-        wsurf = static_cast<QGLWindowSurface *>(pdev);
-#endif
-}
-
-inline void QGLDrawable::swapBuffers()
-{
-    if (widget) {
-        if (widget->autoBufferSwap())
-            widget->swapBuffers();
-    } else {
-        glFlush();
-    }
-}
-
-inline void QGLDrawable::makeCurrent()
-{
-    if (widget)
-        widget->makeCurrent();
-    else if (buffer)
-        buffer->makeCurrent();
-    else if (wsurf)
-        wsurf->context()->makeCurrent();
-    else if (fbo) {
-        wasBound = fbo->isBound();
-        if (!wasBound)
-            fbo->bind();
-    }
-}
-
-inline void QGLDrawable::doneCurrent()
-{
-    if (fbo && !wasBound)
-        fbo->release();
-}
-
-inline QSize QGLDrawable::size() const
-{
-    if (widget) {
-        return QSize(widget->d_func()->glcx->device()->width(),
-                     widget->d_func()->glcx->device()->height());
-    } else if (buffer) {
-        return buffer->size();
-    } else if (fbo) {
-        return fbo->size();
-    } else if (wsurf) {
-#ifdef Q_WS_QWS
-        return wsurf->window()->frameSize();
-#else
-        return QSize(wsurf->width(), wsurf->height());
-#endif
-    }
-    return QSize();
-}
-
-inline QGLFormat QGLDrawable::format() const
-{
-    if (widget)
-        return widget->format();
-    else if (buffer)
-        return buffer->format();
-    else if (wsurf)
-        return wsurf->context()->format();
-    else if (fbo && QGLContext::currentContext()) {
-        QGLFormat fmt = QGLContext::currentContext()->format();
-        fmt.setStencil(fbo->attachment() == QGLFramebufferObject::CombinedDepthStencil);
-        fmt.setDepth(fbo->attachment() != QGLFramebufferObject::NoAttachment);
-        return fmt;
-    }
-
-    return QGLFormat();
-}
-
-inline GLuint QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format)
-{
-    if (widget)
-        return widget->d_func()->glcx->d_func()->bindTexture(image, target, format, true);
-    else if (buffer)
-        return buffer->d_func()->qctx->d_func()->bindTexture(image, target, format, true);
-    else if (fbo && QGLContext::currentContext())
-        return const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(image, target, format, true);
-    else if (wsurf)
-        return wsurf->context()->d_func()->bindTexture(image, target, format, true);
-    return 0;
-}
-
-inline GLuint QGLDrawable::bindTexture(const QPixmap &pixmap, GLenum target, GLint format)
-{
-    if (widget)
-        return widget->d_func()->glcx->d_func()->bindTexture(pixmap, target, format, true);
-    else if (buffer)
-        return buffer->d_func()->qctx->d_func()->bindTexture(pixmap, target, format, true);
-    else if (fbo && QGLContext::currentContext())
-        return const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(pixmap, target, format, true);
-    else if (wsurf)
-        return wsurf->context()->d_func()->bindTexture(pixmap, target, format, true);
-    return 0;
-}
-
-inline QColor QGLDrawable::backgroundColor() const
-{
-    if (widget)
-        return widget->palette().brush(widget->backgroundRole()).color();
-    return QApplication::palette().brush(QPalette::Background).color();
-}
-
-inline QGLContext *QGLDrawable::context() const
-{
-    if (widget)
-        return widget->d_func()->glcx;
-    else if (buffer)
-        return buffer->d_func()->qctx;
-    else if (fbo)
-        return const_cast<QGLContext *>(QGLContext::currentContext());
-    else if (wsurf)
-        return wsurf->context();
-    return 0;
-}
-
-inline bool QGLDrawable::autoFillBackground() const
-{
-    if (widget)
-        return widget->autoFillBackground();
-    else
-        return false;
-}
-
 
 class QOpenGLImmediateModeTessellator;
 class QGLMaskGenerator;
-- 
cgit v0.12


From 842d514edd0ef6fa8d6e863dfe6ba696b95ba790 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Tue, 17 Feb 2009 15:43:05 +0100
Subject: Get rid of warning introduced in the last commit.

---
 src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 1cc2233..e211f10 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -134,8 +134,8 @@ public:
 
     QGL2PaintEngineEx* q;
     QGLDrawable drawable;
-    QGLContext *ctx;
     int width, height;
+    QGLContext *ctx;
 
     // Dirty flags
     bool matrixDirty; // Implies matrix uniforms are also dirty
-- 
cgit v0.12


From a49ec03834b14063b4130c410d59df6e8c4db8ce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Tue, 17 Feb 2009 16:11:41 +0100
Subject: Fixes:    Improve text rendering in GL 2 paint engine. Details: 
 Avoid adding 0.5 to dx() / dy() which caused images / glyphs to           get
 slight antialiasing and edge artifacts.

---
 src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index e211f10..0e41602 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -399,8 +399,8 @@ void QGL2PaintEngineExPrivate::updateMatrix()
     // Use the (3x3) transform for the Model~View matrix:
     const QTransform& transform = q->state()->matrix;
     GLfloat MV[4][4] = {
-        {transform.m11(), transform.m21(), 0.0, transform.dx() + 0.5},
-        {transform.m12(), transform.m22(), 0.0, transform.dy() + 0.5},
+        {transform.m11(), transform.m21(), 0.0, transform.dx()},
+        {transform.m12(), transform.m22(), 0.0, transform.dy()},
         {0.0,             0.0,             1.0, 0.0},
         {transform.m13(), transform.m23(), 0.0, transform.m33()}
     };
-- 
cgit v0.12


From 6513e4b9513dfc591c53744517f05aa3c522ace3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Wed, 18 Feb 2009 09:42:04 +0100
Subject: Fixes:    GL 2 paint engine text rendering optimization. RevBy:   
 Tom Details:  Buffer vertex and texture coordinates so that we get away      
     with just a single glDrawArrays call per text item.           Also move
 drawCachedGlyphs() into the private class.

---
 src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp |   6 ++
 src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h |   1 +
 .../gl2paintengineex/qpaintengineex_opengl2.cpp    | 101 +++++++++------------
 .../gl2paintengineex/qpaintengineex_opengl2_p.h    |   1 -
 4 files changed, 52 insertions(+), 57 deletions(-)

diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp
index 0352d39..f237847 100644
--- a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp
+++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp
@@ -59,6 +59,12 @@ QGLRect QGL2PEXVertexArray::boundingRect() const
         return QGLRect(minX, minY, maxX, maxY);
 }
 
+void QGL2PEXVertexArray::addRect(const QRectF &rect)
+{
+    vertexArray << rect.topLeft() << rect.topRight() << rect.bottomRight()
+                << rect.bottomRight() << rect.bottomLeft() << rect.topLeft();
+}
+
 void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseScale)
 {
     const QPointF* const points = reinterpret_cast<const QPointF*>(path.points());
diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
index c205022..65f6d42 100644
--- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
+++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
@@ -98,6 +98,7 @@ public:
         maxX(-2e10), maxY(-2e10), minX(2e10), minY(2e10),
         boundingRectDirty(true) {}
 
+    void addRect(const QRectF &rect);
     void addPath(const QVectorPath &path, GLfloat curveInverseScale);
     void clear();
 
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 0e41602..ea0d7b1 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -115,6 +115,7 @@ public:
     void setBrush(const QBrush* brush);
 
     void drawTexture(const QGLRect& dest, const QGLRect& src, int txtWidth, int txtHeight);
+    void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti);
 
     void fill(const QVectorPath &path);
     void drawOutline(const QVectorPath& path);
@@ -152,7 +153,8 @@ public:
 
     GLfloat     inverseScale;
 
-    QGL2PEXVertexArray pathVertexArray;
+    QGL2PEXVertexArray vertexCoordinateArray;
+    QGL2PEXVertexArray textureCoordinateArray;
 
     GLfloat pmvMatrix[4][4];
 
@@ -548,17 +550,17 @@ void QGL2PaintEngineExPrivate::drawOutline(const QVectorPath& path)
     if (matrixDirty)
         updateMatrix();
 
-    pathVertexArray.clear();
-    pathVertexArray.addPath(path, inverseScale);
+    vertexCoordinateArray.clear();
+    vertexCoordinateArray.addPath(path, inverseScale);
 
     if (path.hasImplicitClose()) {
         // Close the path's outline
-        pathVertexArray.lineToArray(path.points()[0], path.points()[1]);
-        pathVertexArray.stops().last() += 1;
+        vertexCoordinateArray.lineToArray(path.points()[0], path.points()[1]);
+        vertexCoordinateArray.stops().last() += 1;
     }
 
     prepareForDraw();
-    drawVertexArrays(pathVertexArray, GL_LINE_STRIP);
+    drawVertexArrays(vertexCoordinateArray, GL_LINE_STRIP);
 }
 
 
@@ -578,26 +580,26 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
         composite(rect);
     }
     else if (path.shape() == QVectorPath::EllipseHint) {
-        pathVertexArray.clear();
-        pathVertexArray.addPath(path, inverseScale);
+        vertexCoordinateArray.clear();
+        vertexCoordinateArray.addPath(path, inverseScale);
         prepareForDraw();
-        drawVertexArrays(pathVertexArray, GL_TRIANGLE_FAN);
+        drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN);
     }
     else {
         // The path is too complicated & needs the stencil technique
-        pathVertexArray.clear();
-        pathVertexArray.addPath(path, inverseScale);
+        vertexCoordinateArray.clear();
+        vertexCoordinateArray.addPath(path, inverseScale);
 
-        fillStencilWithVertexArray(pathVertexArray, path.hasWindingFill());
+        fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill());
 
         // Stencil the brush onto the dest buffer
         glStencilFunc(GL_NOTEQUAL, 0, 0xFFFF); // Pass if stencil buff value != 0
         glEnable(GL_STENCIL_TEST);
         prepareForDraw();
-        composite(pathVertexArray.boundingRect());
+        composite(vertexCoordinateArray.boundingRect());
         glDisable(GL_STENCIL_TEST);
 
-        cleanStencilBuffer(pathVertexArray.boundingRect());
+        cleanStencilBuffer(vertexCoordinateArray.boundingRect());
     }
 }
 
@@ -876,6 +878,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const
 
 void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem)
 {
+    Q_D(QGL2PaintEngineEx);
     QOpenGLPaintEngineState *s = state();
 
     const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
@@ -893,17 +896,17 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem
         drawCached = false;
 
     if (drawCached) {
-        drawCachedGlyphs(p, ti);
+        d->drawCachedGlyphs(p, ti);
         return;
     }
 
     QPaintEngineEx::drawTextItem(p, ti);
 }
 
-void QGL2PaintEngineEx::drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti)
+void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti)
 {
-    Q_D(QGL2PaintEngineEx);
-    QOpenGLPaintEngineState *s = state();
+    Q_Q(QGL2PaintEngineEx);
+    QOpenGLPaintEngineState *s = q->state();
 
     QVarLengthArray<QFixedPoint> positions;
     QVarLengthArray<glyph_t> glyphs;
@@ -927,65 +930,51 @@ void QGL2PaintEngineEx::drawCachedGlyphs(const QPointF &p, const QTextItemInt &t
     const QImage &image = cache->image();
     int margin = cache->glyphMargin();
 
-    QGLContext *ctx = d->ctx;
     glActiveTexture(QT_BRUSH_TEXTURE_UNIT);
-    d->ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true);
+    ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true);
 
     glEnable(GL_BLEND);
 
-    d->shaderManager->textShader()->use();
-    d->updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
+    shaderManager->textShader()->use();
+    updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
 
-    if (d->compositionModeDirty)
-        d->updateCompositionMode();
+    if (compositionModeDirty)
+        updateCompositionMode();
 
-    if (d->matrixDirty)
-        d->updateMatrix();
+    if (matrixDirty)
+        updateMatrix();
 
-    if (d->textShaderMatrixUniformDirty) {
-        d->shaderManager->textShader()->uniforms()[QLatin1String("pmvMatrix")] = d->pmvMatrix;
-        d->textShaderMatrixUniformDirty = false;
+    if (textShaderMatrixUniformDirty) {
+        shaderManager->textShader()->uniforms()[QLatin1String("pmvMatrix")] = pmvMatrix;
+        textShaderMatrixUniformDirty = false;
     }
 
-    d->shaderManager->textShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT;
-    QColor col = d->premultiplyColor(state()->pen.color(), (GLfloat)state()->opacity);
-    d->shaderManager->textShader()->uniforms()[QLatin1String("fragmentColor")] = col;
+    shaderManager->textShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT;
+    QColor col = premultiplyColor(s->pen.color(), (GLfloat)s->opacity);
+    shaderManager->textShader()->uniforms()[QLatin1String("fragmentColor")] = col;
 
     GLfloat dx = 1.0 / image.width();
     GLfloat dy = 1.0 / image.height();
 
-    glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
-    glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
+    vertexCoordinateArray.clear();
+    textureCoordinateArray.clear();
+
     for (int i=0; i<glyphs.size(); ++i) {
         const QTextureGlyphCache::Coord &c = cache->coords.value(glyphs[i]);
         int x = positions[i].x.toInt() + c.baseLineX - margin;
         int y = positions[i].y.toInt() - c.baseLineY - margin;
 
-        QGLRect dest = QRectF(x, y, c.w, c.h);
-        QGLRect src = QRectF(c.x, c.y, c.w, c.h);
-
-        GLfloat vertexCoords[] = {
-            dest.left,  dest.top,
-            dest.left,  dest.bottom,
-            dest.right, dest.bottom,
-            dest.right, dest.top
-        };
-
-        glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoords);
-
-        QGLRect srcTextureRect(src.left*dx, 1.0 - src.top*dy, src.right*dx, 1.0 - src.bottom*dy);
+        vertexCoordinateArray.addRect(QRectF(x, y, c.w, c.h));
+        textureCoordinateArray.addRect(QRectF(c.x*dx, 1 - c.y*dy, c.w * dx, -c.h * dy));
+    }
 
-        GLfloat textureCoords[] = {
-            srcTextureRect.left,  srcTextureRect.top,
-            srcTextureRect.left,  srcTextureRect.bottom,
-            srcTextureRect.right, srcTextureRect.bottom,
-            srcTextureRect.right, srcTextureRect.top
-        };
+    glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
+    glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
 
-        glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoords);
+    glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data());
+    glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data());
+    glDrawArrays(GL_TRIANGLES, 0, 6 * glyphs.size());
 
-        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-    }
     glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
     glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
 }
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index ce66e4b..9f84a25 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -100,7 +100,6 @@ public:
     virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
                            Qt::ImageConversionFlags flags = Qt::AutoColor);
     virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
-    void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti);
 
     Type type() const { return OpenGL; }
 
-- 
cgit v0.12


From d903f379470fb9f9159fbf37f2cfc02638cd05f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Wed, 18 Feb 2009 14:54:51 +0100
Subject: Fixes:    Enable use of the GL pixmap backend in the GL 2 paint
 engine.

---
 src/opengl/qgl.cpp            | 10 +++++-----
 src/opengl/qgl_p.h            |  4 ++++
 src/opengl/qpixmapdata_gl.cpp | 13 ++++++++++---
 src/opengl/qpixmapdata_gl_p.h |  1 +
 4 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 7c42039..558897d 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1888,14 +1888,14 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint
 /*! \internal */
 GLuint QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, bool clean)
 {
-#if !defined(QT_OPENGL_ES_2)
-    if (target == qt_gl_preferredTextureTarget() && pixmap.pixmapData()->classId() == QPixmapData::OpenGLClass) {
-        const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pixmap.pixmapData());
+    Q_Q(QGLContext);
+    QPixmapData *pd = pixmap.pixmapData();
+    if (target == qt_gl_preferredTextureTarget() && pd->classId() == QPixmapData::OpenGLClass) {
+        const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pd);
 
-        if (data->isValidContext(QGLContext::currentContext()))
+        if (data->isValidContext(q))
             return data->bind();
     }
-#endif
 
     const qint64 key = pixmap.cacheKey();
     GLuint id;
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 2eccc23..76f3812 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -418,9 +418,13 @@ inline GLenum qt_gl_preferredTextureFormat()
 
 inline GLenum qt_gl_preferredTextureTarget()
 {
+#if 1 || defined(QT_OPENGL_ES_2)
+    return GL_TEXTURE_2D;
+#else
     return (QGLExtensions::glExtensions & QGLExtensions::TextureRectangle)
            ? GL_TEXTURE_RECTANGLE_NV
            : GL_TEXTURE_2D;
+#endif
 }
 
 
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index b079557..ec71fa6 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -57,12 +57,14 @@ class QGLShareContextScope
 public:
     QGLShareContextScope(const QGLContext *ctx)
         : m_oldContext(0)
-        , m_ctx(const_cast<QGLContext *>(ctx))
     {
-        const QGLContext *currentContext = QGLContext::currentContext();
+        QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext());
         if (currentContext != ctx && !qgl_share_reg()->checkSharing(ctx, currentContext)) {
-            m_oldContext = const_cast<QGLContext *>(currentContext);
+            m_oldContext = currentContext;
+            m_ctx = const_cast<QGLContext *>(ctx);
             m_ctx->makeCurrent();
+        } else {
+            m_ctx = currentContext;
         }
     }
 
@@ -127,6 +129,7 @@ QGLPixmapData::QGLPixmapData(PixelType type)
     : QPixmapData(type, OpenGLClass)
     , m_width(0)
     , m_height(0)
+    , m_ctx(0)
     , m_texture(0)
     , m_dirty(false)
 {
@@ -148,6 +151,9 @@ bool QGLPixmapData::isValid() const
 
 bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
 {
+    if (ctx == m_ctx)
+        return true;
+
     const QGLContext *share_ctx = qt_gl_share_widget()->context();
     return ctx == share_ctx || qgl_share_reg()->checkSharing(ctx, share_ctx);
 }
@@ -173,6 +179,7 @@ void QGLPixmapData::ensureCreated() const
     m_dirty = false;
 
     QGLShareContextScope ctx(qt_gl_share_widget()->context());
+    m_ctx = ctx;
 
     const GLenum format = qt_gl_preferredTextureFormat();
     const GLenum target = qt_gl_preferredTextureTarget();
diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h
index e450f01..97f4959 100644
--- a/src/opengl/qpixmapdata_gl_p.h
+++ b/src/opengl/qpixmapdata_gl_p.h
@@ -97,6 +97,7 @@ private:
     int m_width;
     int m_height;
 
+    mutable QGLContext *m_ctx;
     mutable GLuint m_texture;
     mutable bool m_dirty;
     mutable QImage m_source;
-- 
cgit v0.12


From a3c964db2bee664b0e71e9ec1c5d8b2830659ff9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Wed, 18 Feb 2009 14:56:16 +0100
Subject: Fixes:    Introduce mode transfer functions in the GL 2 paint engine.
 RevBy:    Tom Details:  Mode transfer lets us optimize the case where the
 same operation is           done a lot of times in a row, for example image
 or text drawing, by           being able to assume that most of the state has
 already been set up           properly.

---
 src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h |   4 +-
 .../gl2paintengineex/qpaintengineex_opengl2.cpp    | 143 +++++++++++++--------
 2 files changed, 94 insertions(+), 53 deletions(-)

diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
index 65f6d42..a83f13e 100644
--- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
+++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
@@ -62,7 +62,7 @@ public:
     QGLPoint(GLfloat new_x, GLfloat new_y) :
         x(new_x), y(new_y) {};
 
-    QGLPoint(QPointF p) :
+    QGLPoint(const QPointF &p) :
         x(p.x()), y(p.y()) {};
 
     QGLPoint(const QPointF* p) :
@@ -77,7 +77,7 @@ public:
 
 struct QGLRect
 {
-    QGLRect(QRectF r)
+    QGLRect(const QRectF &r)
         :  left(r.left()), top(r.top()), right(r.right()), bottom(r.bottom()) {}
 
     QGLRect(GLfloat l, GLfloat t, GLfloat r, GLfloat b)
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index ea0d7b1..88c33d4 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -86,6 +86,11 @@ extern QImage qt_imageForBrush(int brushStyle, bool invert); //in qbrush.cpp
 
 #include <QDebug>
 
+enum EngineMode {
+    ImageDrawingMode,
+    TextDrawingMode,
+    DefaultMode
+};
 
 static const GLuint QT_VERTEX_COORDS_ATTR  = 0;
 static const GLuint QT_TEXTURE_COORDS_ATTR = 1;
@@ -114,7 +119,9 @@ public:
 
     void setBrush(const QBrush* brush);
 
-    void drawTexture(const QGLRect& dest, const QGLRect& src, int txtWidth, int txtHeight);
+    void transferMode(EngineMode newMode);
+
+    void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize);
     void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti);
 
     void fill(const QVectorPath &path);
@@ -138,6 +145,8 @@ public:
     int width, height;
     QGLContext *ctx;
 
+    EngineMode mode;
+
     // Dirty flags
     bool matrixDirty; // Implies matrix uniforms are also dirty
     bool compositionModeDirty;
@@ -156,6 +165,9 @@ public:
     QGL2PEXVertexArray vertexCoordinateArray;
     QGL2PEXVertexArray textureCoordinateArray;
 
+    GLfloat staticVertexCoordinateArray[8];
+    GLfloat staticTextureCoordinateArray[8];
+
     GLfloat pmvMatrix[4][4];
 
     QGLPEXShaderManager* shaderManager;
@@ -486,14 +498,21 @@ void QGL2PaintEngineExPrivate::updateCompositionMode()
     compositionModeDirty = false;
 }
 
+static inline void setCoords(GLfloat *coords, const QGLRect &rect)
+{
+    coords[0] = rect.left;
+    coords[1] = rect.top;
+    coords[2] = rect.right;
+    coords[3] = rect.top;
+    coords[4] = rect.right;
+    coords[5] = rect.bottom;
+    coords[6] = rect.left;
+    coords[7] = rect.bottom;
+}
 
-void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, int txtWidth, int txtHeight)
+void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize)
 {
 //     qDebug("QGL2PaintEngineExPrivate::drawImage()");
-
-    // We have a shader specifically for drawPixmap/drawImage...
-    shaderManager->imageShader()->use();
-
     updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
 
     if (compositionModeDirty)
@@ -507,45 +526,66 @@ void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& s
         imageShaderMatrixUniformDirty = false;
     }
 
-    shaderManager->imageShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT;
-
-//    if (q->state()->opacity < 0.99f)
+    if (q->state()->opacity < 0.99f)
         shaderManager->imageShader()->uniforms()[QLatin1String("opacity")] = (GLfloat)q->state()->opacity;
 
-    GLfloat vertexCoords[] = {
-        dest.left,  dest.top,
-        dest.left,  dest.bottom,
-        dest.right, dest.bottom,
-        dest.right, dest.top
-    };
+    GLfloat dx = 1.0 / textureSize.width();
+    GLfloat dy = 1.0 / textureSize.height();
 
-    glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
-    glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoords);
+    QGLRect srcTextureRect(src.left*dx, 1.0 - src.top*dy, src.right*dx, 1.0 - src.bottom*dy);
 
-    GLfloat dx = 1.0 / txtWidth;
-    GLfloat dy = 1.0 / txtHeight;
+    setCoords(staticVertexCoordinateArray, dest);
+    setCoords(staticTextureCoordinateArray, srcTextureRect);
 
-    QGLRect srcTextureRect(src.left*dx, 1.0 - src.top*dy, src.right*dx, 1.0 - src.bottom*dy);
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+}
 
-    GLfloat textureCoords[] = {
-        srcTextureRect.left,  srcTextureRect.top,
-        srcTextureRect.left,  srcTextureRect.bottom,
-        srcTextureRect.right, srcTextureRect.bottom,
-        srcTextureRect.right, srcTextureRect.top
-    };
+void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode)
+{
+    if (newMode == mode)
+        return;
 
-    glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
-    glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoords);
+    if (mode == TextDrawingMode || mode == ImageDrawingMode) {
+        glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
+        glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
+    }
 
-    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    if (newMode == TextDrawingMode) {
+        glEnable(GL_BLEND);
+        glActiveTexture(QT_BRUSH_TEXTURE_UNIT);
 
-    glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
-    glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
-}
+        glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
+        glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
 
+        glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data());
+        glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data());
+
+        shaderManager->textShader()->use();
+        shaderManager->textShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT;
+    }
+
+    if (newMode == ImageDrawingMode) {
+        // We have a shader specifically for drawPixmap/drawImage...
+        shaderManager->imageShader()->use();
+        shaderManager->imageShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT;
+        shaderManager->imageShader()->uniforms()[QLatin1String("opacity")] = (GLfloat)1.0;
+
+        glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
+        glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
+
+        glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, staticVertexCoordinateArray);
+        glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, staticTextureCoordinateArray);
+
+        glActiveTexture(QT_BRUSH_TEXTURE_UNIT);
+    }
+
+    mode = newMode;
+}
 
 void QGL2PaintEngineExPrivate::drawOutline(const QVectorPath& path)
 {
+    transferMode(DefaultMode);
+
 //     qDebug("QGL2PaintEngineExPrivate::drawOutline()");
     if (matrixDirty)
         updateMatrix();
@@ -567,6 +607,8 @@ void QGL2PaintEngineExPrivate::drawOutline(const QVectorPath& path)
 // Assumes everything is configured for the brush you want to use
 void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
 {
+    transferMode(DefaultMode);
+
     if (matrixDirty)
         updateMatrix();
 
@@ -846,10 +888,10 @@ void QGL2PaintEngineEx::transformChanged()
 void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src)
 {
     Q_D(QGL2PaintEngineEx);
-    QGLContext *ctx = d->ctx;
-    glActiveTexture(QT_BRUSH_TEXTURE_UNIT);
+    d->transferMode(ImageDrawingMode);
 
-    d->ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, true);
+    QGLContext *ctx = d->ctx;
+    ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, true);
 
     //FIXME: we should use hasAlpha() instead, but that's SLOW at the moment
     if ((state()->opacity < 0.99f) || pixmap.hasAlphaChannel())
@@ -857,23 +899,24 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c
     else
         glDisable(GL_BLEND);
 
-    d->drawTexture(dest, src, pixmap.width(), pixmap.height());
+    d->drawTexture(dest, src, pixmap.size());
 }
 
 void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const QRectF& src,
                         Qt::ImageConversionFlags)
 {
     Q_D(QGL2PaintEngineEx);
+    d->transferMode(ImageDrawingMode);
+
     QGLContext *ctx = d->ctx;
-    glActiveTexture(QT_BRUSH_TEXTURE_UNIT);
-    d->ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true);
+    ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true);
 
     if ((state()->opacity < 0.99f) || image.hasAlphaChannel())
         glEnable(GL_BLEND);
     else
         glDisable(GL_BLEND);
 
-    d->drawTexture(dest, src, image.width(), image.height());
+    d->drawTexture(dest, src, image.size());
 }
 
 void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem)
@@ -908,6 +951,8 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte
     Q_Q(QGL2PaintEngineEx);
     QOpenGLPaintEngineState *s = q->state();
 
+    transferMode(TextDrawingMode);
+
     QVarLengthArray<QFixedPoint> positions;
     QVarLengthArray<glyph_t> glyphs;
     QTransform matrix;
@@ -930,12 +975,8 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte
     const QImage &image = cache->image();
     int margin = cache->glyphMargin();
 
-    glActiveTexture(QT_BRUSH_TEXTURE_UNIT);
     ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true);
 
-    glEnable(GL_BLEND);
-
-    shaderManager->textShader()->use();
     updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
 
     if (compositionModeDirty)
@@ -949,13 +990,15 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte
         textShaderMatrixUniformDirty = false;
     }
 
-    shaderManager->textShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT;
     QColor col = premultiplyColor(s->pen.color(), (GLfloat)s->opacity);
     shaderManager->textShader()->uniforms()[QLatin1String("fragmentColor")] = col;
 
     GLfloat dx = 1.0 / image.width();
     GLfloat dy = 1.0 / image.height();
 
+    QGLPoint *oldVertexCoordinateDataPtr = vertexCoordinateArray.data();
+    QGLPoint *oldTextureCoordinateDataPtr = textureCoordinateArray.data();
+
     vertexCoordinateArray.clear();
     textureCoordinateArray.clear();
 
@@ -968,15 +1011,12 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte
         textureCoordinateArray.addRect(QRectF(c.x*dx, 1 - c.y*dy, c.w * dx, -c.h * dy));
     }
 
-    glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
-    glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
+    if (vertexCoordinateArray.data() != oldVertexCoordinateDataPtr)
+        glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data());
+    if (textureCoordinateArray.data() != oldTextureCoordinateDataPtr)
+        glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data());
 
-    glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data());
-    glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data());
     glDrawArrays(GL_TRIANGLES, 0, 6 * glyphs.size());
-
-    glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
-    glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
 }
 
 bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
@@ -991,6 +1031,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
     QSize sz = d->drawable.size();
     d->width = sz.width();
     d->height = sz.height();
+    d->mode = DefaultMode;
 
     qt_resolve_version_1_3_functions(d->ctx);
     qt_resolve_glsl_extensions(d->ctx);
-- 
cgit v0.12


From 7cee2659388388754d741ba4b46647c57d03c498 Mon Sep 17 00:00:00 2001
From: Gunnar Sletta <gunnar@trolltech.com>
Date: Mon, 23 Feb 2009 13:54:07 +0100
Subject: Fixes:    Make raster engine perform better on 0-opacity drawing
 RevBy:    sroedal Task:     came in from brisbane

---
 src/gui/painting/qdrawhelper_p.h         |  3 ++-
 src/gui/painting/qpaintengine_raster.cpp | 23 +++++++++++++++++------
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index de97683..586ffe3 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -110,6 +110,7 @@ struct QSpanData;
 class QGradient;
 class QRasterBuffer;
 class QClipData;
+class QRasterPaintEngineState;
 
 typedef QT_FT_SpanFunc ProcessSpans;
 typedef void (*BitmapBlitFunc)(QRasterBuffer *rasterBuffer,
@@ -293,7 +294,7 @@ struct QSpanData
     };
 
     void init(QRasterBuffer *rb, const QRasterPaintEngine *pe);
-    void setup(const QBrush &brush, int alpha);
+    void setup(const QBrush &brush, int alpha, const QRasterPaintEngineState *s);
     void setupMatrix(const QTransform &matrix, int bilinear);
     void initTexture(const QImage *image, int alpha, QTextureData::Type = QTextureData::Plain, const QRect &sourceRect = QRect());
     void adjustSpanMethods();
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index ba79b5b..92a196c 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -483,12 +483,12 @@ bool QRasterPaintEngine::begin(QPaintDevice *device)
     d->rasterizer->setClipRect(d->deviceRect);
 
     s->penData.init(d->rasterBuffer, this);
-    s->penData.setup(s->pen.brush(), s->intOpacity);
+    s->penData.setup(s->pen.brush(), s->intOpacity, s);
     s->stroker = &d->basicStroker;
     d->basicStroker.setClipRect(d->deviceRect);
 
     s->brushData.init(d->rasterBuffer, this);
-    s->brushData.setup(s->brush, s->intOpacity);
+    s->brushData.setup(s->brush, s->intOpacity, s);
 
     d->rasterBuffer->compositionMode = QPainter::CompositionMode_SourceOver;
 
@@ -769,7 +769,7 @@ void QRasterPaintEngine::updatePen(const QPen &pen)
     s->strokeFlags = 0;
 
     s->penData.clip = d->clip();
-    s->penData.setup(pen_style == Qt::NoPen ? QBrush() : pen.brush(), s->intOpacity);
+    s->penData.setup(pen_style == Qt::NoPen ? QBrush() : pen.brush(), s->intOpacity, s);
 
     if (s->strokeFlags & QRasterPaintEngine::DirtyTransform
         || pen.brush().transform().type() >= QTransform::TxNone) {
@@ -869,7 +869,7 @@ void QRasterPaintEngine::updateBrush(const QBrush &brush)
     QRasterPaintEngineState *s = state();
     // must set clip prior to setup, as setup uses it...
     s->brushData.clip = d->clip();
-    s->brushData.setup(brush, s->intOpacity);
+    s->brushData.setup(brush, s->intOpacity, s);
     if (s->fillFlags & DirtyTransform
         || brush.transform().type() >= QTransform::TxNone)
         d_func()->updateMatrixData(&s->brushData, brush, d->brushMatrix());
@@ -1024,6 +1024,10 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt,
 {
     if (!clip.isValid())
         return;
+
+    if (alpha ==0)
+        return;
+
     Q_ASSERT(img.depth() >= 8);
 
     int srcBPL = img.bytesPerLine();
@@ -1867,9 +1871,12 @@ void QRasterPaintEngine::fillRect(const QRectF &r, const QColor &color)
     QRasterPaintEngineState *s = state();
 
     d->solid_color_filler.solid.color = PREMUL(ARGB_COMBINE_ALPHA(color.rgba(), s->intOpacity));
+    if ((d->solid_color_filler.solid.color & 0xff000000) == 0
+        && s->composition_mode == QPainter::CompositionMode_SourceOver) {
+        return;
+    }
     d->solid_color_filler.clip = d->clip();
     d->solid_color_filler.adjustSpanMethods();
-
     fillRect(r, &d->solid_color_filler);
 }
 
@@ -4906,7 +4913,7 @@ void QSpanData::init(QRasterBuffer *rb, const QRasterPaintEngine *pe)
 
 extern QImage qt_imageForBrush(int brushStyle, bool invert);
 
-void QSpanData::setup(const QBrush &brush, int alpha)
+void QSpanData::setup(const QBrush &brush, int alpha, const QRasterPaintEngineState *s)
 {
     Qt::BrushStyle brushStyle = qbrush_style(brush);
     switch (brushStyle) {
@@ -4914,6 +4921,10 @@ void QSpanData::setup(const QBrush &brush, int alpha)
         type = Solid;
         QColor c = qbrush_color(brush);
         solid.color = PREMUL(ARGB_COMBINE_ALPHA(c.rgba(), alpha));
+        if ((solid.color & 0xff000000) == 0
+            && s->composition_mode == QPainter::CompositionMode_SourceOver) {
+            type = None;
+        }
         break;
     }
 
-- 
cgit v0.12


From 6ab74831766cdd5cf4e94eee8a60099436e61202 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Mon, 9 Mar 2009 13:07:18 +0100
Subject: Fixes:    Extreme amount of pixel buffers created in embeddeddialogs
 demo. Details:  As a window surface is created even for embedded widgets,
 don't create           the GL resources required by the surface until they
 are actually needed. RevBy:    Tom

---
 src/opengl/qwindowsurface_gl.cpp | 14 +++++++++++---
 src/opengl/qwindowsurface_gl_p.h |  1 +
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index bb4ffc5..08c2aab 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -315,6 +315,8 @@ QGLContext *QGLWindowSurface::context() const
 
 QPaintDevice *QGLWindowSurface::paintDevice()
 {
+    updateGeometry();
+
     if (d_ptr->pb)
         return d_ptr->pb;
 
@@ -330,6 +332,7 @@ static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize,
 
 void QGLWindowSurface::beginPaint(const QRegion &)
 {
+    updateGeometry();
 }
 
 void QGLWindowSurface::endPaint(const QRegion &rgn)
@@ -460,9 +463,9 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
         d_ptr->fbo->bind();
 }
 
-void QGLWindowSurface::setGeometry(const QRect &rect)
+void QGLWindowSurface::updateGeometry()
 {
-    QWindowSurface::setGeometry(rect);
+    QRect rect = QWindowSurface::geometry();
 
     const GLenum target = qt_gl_preferredTextureTarget();
 
@@ -496,7 +499,7 @@ void QGLWindowSurface::setGeometry(const QRect &rect)
                                         qt_gl_share_widget());
 
         if (d_ptr->pb->isValid()) {
-            qDebug() << "PB Sample buffers:" << d_ptr->pb->format().sampleBuffers();
+            qDebug() << "Created Window Surface Pixelbuffer, Sample buffers:" << d_ptr->pb->format().sampleBuffers();
             d_ptr->pb->makeCurrent();
 
             glGenTextures(1, &d_ptr->pb_tex_id);
@@ -561,6 +564,11 @@ void QGLWindowSurface::setGeometry(const QRect &rect)
     d_ptr->ctx->d_ptr->internal_context = true;
 }
 
+void QGLWindowSurface::setGeometry(const QRect &rect)
+{
+    QWindowSurface::setGeometry(rect);
+}
+
 bool QGLWindowSurface::scroll(const QRegion &area, int dx, int dy)
 {
     // this code randomly fails currently for unknown reasons
diff --git a/src/opengl/qwindowsurface_gl_p.h b/src/opengl/qwindowsurface_gl_p.h
index 0194378..d47e3e3 100644
--- a/src/opengl/qwindowsurface_gl_p.h
+++ b/src/opengl/qwindowsurface_gl_p.h
@@ -74,6 +74,7 @@ public:
     QPaintDevice *paintDevice();
     void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
     void setGeometry(const QRect &rect);
+    void updateGeometry();
     bool scroll(const QRegion &area, int dx, int dy);
 
     void beginPaint(const QRegion &region);
-- 
cgit v0.12


From 570ef6dbc4526d39ef8d2b7e29ddedcfa67b061f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Mon, 9 Mar 2009 15:01:48 +0100
Subject: Fixes:    Clipping bug in GL 2 paint engine (embeddeddialogs demo).
 RevBy:    Tom

---
 src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 88c33d4..9eeef1b 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1057,6 +1057,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
 
     glDisable(GL_DEPTH_TEST);
 
+    updateClipRegion(QRegion(), Qt::NoClip);
     return true;
 }
 
-- 
cgit v0.12


From 0f95b04c91e559ca62698234dcd82445c5ee8ceb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Mon, 9 Mar 2009 15:01:16 +0100
Subject: Fixes:    Small optimizations in GL 2 paint engine... RevBy:    Tom

---
 src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 9eeef1b..ce9f976 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -424,7 +424,9 @@ void QGL2PaintEngineExPrivate::updateMatrix()
     for (int row = 0; row < 4; ++row) {
         for (int col = 0; col < 4; ++col) {
             pmvMatrix[col][row] = 0.0;
-            for (int n = 0; n < 4; ++n)
+
+            // P[row][n] is 0.0 for n < row
+            for (int n = row; n < 4; ++n)
                 pmvMatrix[col][row] += P[row][n] * MV[n][col];
         }
     }
@@ -804,8 +806,6 @@ void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush)
 {
     Q_D(QGL2PaintEngineEx);
 
-    QTime startTime = QTime::currentTime();
-
     d->setBrush(&brush);
     d->fill(path);
     d->setBrush(&(state()->brush)); // reset back to the state's brush
-- 
cgit v0.12


From 4feeae36f1dc18795646e648f9987795706d21f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Mon, 9 Mar 2009 13:09:25 +0100
Subject: Fixes:    Get rid of GL 2 paint engine debug message... RevBy:    Tom

---
 src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index ce9f976..6e24bdc 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -794,8 +794,6 @@ void QGL2PaintEngineExPrivate::drawVertexArrays(QGL2PEXVertexArray& vertexArray,
 QGL2PaintEngineEx::QGL2PaintEngineEx()
     : QPaintEngineEx(*(new QGL2PaintEngineExPrivate(this)))
 {
-    qDebug("QGL2PaintEngineEx::QGL2PaintEngineEx()");
-
 }
 
 QGL2PaintEngineEx::~QGL2PaintEngineEx()
-- 
cgit v0.12


From 56fc9b853f8d19999c81ed13a9f2fcd0e95241e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Wed, 11 Mar 2009 09:16:37 +0100
Subject: Fixes:    Respect the SmoothPixmapTransform render hint in the GL2
 paint engine. RevBy:    Tom

---
 src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 6e24bdc..dbf18b1 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -515,7 +515,7 @@ static inline void setCoords(GLfloat *coords, const QGLRect &rect)
 void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize)
 {
 //     qDebug("QGL2PaintEngineExPrivate::drawImage()");
-    updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
+    updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
 
     if (compositionModeDirty)
         updateCompositionMode();
-- 
cgit v0.12


From 4d4580b5f43adb22b6ba95f49698efcd5dbdfeae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Wed, 11 Mar 2009 10:37:13 +0100
Subject: Fixes:    Make FBO window surface work with GL 2 paint engine. RevBy:
    Trond Details:  Need to make sure clipping/scissoring etc is turned off
 and           that we are in a good state.

---
 src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 3 +++
 src/opengl/qwindowsurface_gl.cpp                       | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index dbf18b1..89ed1f7 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1062,6 +1062,9 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
 bool QGL2PaintEngineEx::end()
 {
     Q_D(QGL2PaintEngineEx);
+    QGLContext *ctx = d->ctx;
+    glUseProgram(0);
+    d->transferMode(DefaultMode);
     d->drawable.swapBuffers();
     d->drawable.doneCurrent();
     return false;
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index 08c2aab..5cd4366 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -439,6 +439,9 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
     if (d_ptr->fbo)
         d_ptr->fbo->release();
 
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_SCISSOR_TEST);
+
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
 
@@ -539,6 +542,7 @@ void QGLWindowSurface::updateGeometry()
 
         d_ptr->fbo->bind();
         if (d_ptr->fbo->isValid()) {
+            qDebug() << "Created Window Surface FBO" << rect.size();
             return;
         } else {
             qDebug() << "QGLWindowSurface: Failed to create valid FBO, falling back";
-- 
cgit v0.12


From 1ada6800efbbca276441b3b170b1ccfa0c09c20a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Thu, 12 Mar 2009 09:00:34 +0100
Subject: Fixes:    Add blitting and multisample API to QGLFramebufferObject.
 RevBy:    Trond Details:  Support GL_EXT_framebuffer_multisample and
 GL_EXT_framebuffer_blit           in the QGLFramebufferObject API.

---
 src/opengl/qgl.cpp                  |   2 +
 src/opengl/qgl_p.h                  |   3 +-
 src/opengl/qglextensions.cpp        |   3 +
 src/opengl/qglextensions_p.h        |  37 +++
 src/opengl/qglframebufferobject.cpp | 456 +++++++++++++++++++++++++++++++++---
 src/opengl/qglframebufferobject.h   |  49 ++++
 6 files changed, 520 insertions(+), 30 deletions(-)

diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 558897d..fc11d90 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -4175,6 +4175,8 @@ void QGLExtensions::init_extensions()
     glExtensions |= FramebufferObject;
     glExtensions |= GenerateMipmap;
 #endif
+    if (extensions.contains(QLatin1String("EXT_framebuffer_blit")))
+        glExtensions |= FramebufferBlit;
 
     QGLContext cx(QGLFormat::defaultFormat());
     if (glExtensions & TextureCompression) {
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 76f3812..8ab73d8 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -330,7 +330,8 @@ public:
         StencilWrap             = 0x00000100,
         PackedDepthStencil      = 0x00000200,
         NVFloatBuffer           = 0x00000400,
-        PixelBufferObject       = 0x00000800
+        PixelBufferObject       = 0x00000800,
+        FramebufferBlit         = 0x00001000
     };
     Q_DECLARE_FLAGS(Extensions, Extension)
 
diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp
index b054fe8..e6ac043 100644
--- a/src/opengl/qglextensions.cpp
+++ b/src/opengl/qglextensions.cpp
@@ -74,6 +74,9 @@ bool qt_resolve_framebufferobject_extensions(QGLContext *ctx)
     glGetFramebufferAttachmentParameterivEXT =
         (_glGetFramebufferAttachmentParameterivEXT) ctx->getProcAddress(QLatin1String("glGetFramebufferAttachmentParameterivEXT"));
     glGenerateMipmapEXT = (_glGenerateMipmapEXT) ctx->getProcAddress(QLatin1String("glGenerateMipmapEXT"));
+    glBlitFramebufferEXT = (_glBlitFramebufferEXT) ctx->getProcAddress(QLatin1String("glBlitFramebufferEXT"));
+    glRenderbufferStorageMultisampleEXT =
+        (_glRenderbufferStorageMultisampleEXT) ctx->getProcAddress(QLatin1String("glRenderbufferStorageMultisampleEXT"));
     return glIsRenderbufferEXT;
 #else
     Q_UNUSED(ctx);
diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h
index fdf0bba..cd35eb0 100644
--- a/src/opengl/qglextensions_p.h
+++ b/src/opengl/qglextensions_p.h
@@ -162,6 +162,15 @@ typedef void (APIENTRY *_glGetFramebufferAttachmentParameterivEXT) (GLenum targe
                                                                           GLint *params);
 typedef void (APIENTRY *_glGenerateMipmapEXT) (GLenum target);
 
+// EXT_GL_framebuffer_blit
+typedef void (APIENTRY *_glBlitFramebufferEXT) (int srcX0, int srcY0, int srcX1, int srcY1,
+                                                int dstX0, int dstY0, int dstX1, int dstY1,
+                                                GLbitfield mask, GLenum filter);
+
+// EXT_GL_framebuffer_multisample
+typedef void (APIENTRY *_glRenderbufferStorageMultisampleEXT) (GLenum target, GLsizei samples,
+                                                               GLenum internalformat, GLsizei width, GLsizei height);
+
 QT_BEGIN_NAMESPACE
 
 struct QGLExtensionFuncs
@@ -220,6 +229,8 @@ struct QGLExtensionFuncs
         qt_glGetFramebufferAttachmentParameterivEXT = 0;
         qt_glGenerateMipmapEXT = 0;
 #endif
+        qt_glBlitFramebufferEXT = 0;
+        qt_glRenderbufferStorageMultisampleEXT = 0;
 
         qt_glBindBufferARB = 0;
         qt_glDeleteBuffersARB = 0;
@@ -298,6 +309,8 @@ struct QGLExtensionFuncs
     _glGetFramebufferAttachmentParameterivEXT qt_glGetFramebufferAttachmentParameterivEXT;
     _glGenerateMipmapEXT qt_glGenerateMipmapEXT;
 #endif
+    _glBlitFramebufferEXT qt_glBlitFramebufferEXT;
+    _glRenderbufferStorageMultisampleEXT qt_glRenderbufferStorageMultisampleEXT;
 
     _glBindBufferARB qt_glBindBufferARB;
     _glDeleteBuffersARB qt_glDeleteBuffersARB;
@@ -447,6 +460,28 @@ struct QGLExtensionFuncs
 #define GL_RENDERBUFFER_STENCIL_SIZE_EXT                        0x8D55
 #endif
 
+// GL_EXT_framebuffer_blit
+#ifndef GL_READ_FRAMEBUFFER_EXT
+#define GL_READ_FRAMEBUFFER_EXT                                 0x8CA8
+#endif
+
+// GL_EXT_framebuffer_multisample
+#ifndef GL_RENDERBUFFER_SAMPLES_EXT
+#define GL_RENDERBUFFER_SAMPLES_EXT                             0x8CAB
+#endif
+
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT               0x8D56
+#endif
+
+#ifndef GL_MAX_SAMPLES_EXT
+#define GL_MAX_SAMPLES_EXT                                      0x8D5
+#endif
+
+#ifndef GL_DRAW_FRAMEBUFFER_EXT
+#define GL_DRAW_FRAMEBUFFER_EXT                                 0x8CA9
+#endif
+
 #ifndef GL_EXT_packed_depth_stencil
 #define GL_DEPTH_STENCIL_EXT                                    0x84F9
 #define GL_UNSIGNED_INT_24_8_EXT                                0x84FA
@@ -533,6 +568,8 @@ struct QGLExtensionFuncs
 #define glFramebufferRenderbufferEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glFramebufferRenderbufferEXT
 #define glGetFramebufferAttachmentParameterivEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetFramebufferAttachmentParameterivEXT
 #define glGenerateMipmapEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGenerateMipmapEXT
+#define glBlitFramebufferEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBlitFramebufferEXT
+#define glRenderbufferStorageMultisampleEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glRenderbufferStorageMultisampleEXT
 
 #else // QT_OPENGL_ES_2
 
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 9134fc6..297ef84 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -67,6 +67,216 @@ extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
     }                                                     \
 }
 
+class QGLFramebufferObjectFormatPrivate
+{
+public:
+    int samples;
+    QGLFramebufferObject::Attachment attachment;
+    GLenum target;
+    GLenum internal_format;
+};
+
+/*!
+    \class QGLFramebufferObjectFormat
+    \brief The QGLFramebufferObjectFormat class specifies the format of an OpenGL
+    framebuffer object.
+
+    \since 4.6
+
+    \ingroup multimedia
+
+    A framebuffer object has several characteristics:
+    \list
+    \i \link setSamples() Number of samples per pixels.\endlink
+    \i \link setAttachment() Depth and/or stencil attachments.\endlink
+    \i \link setTextureTarget() Texture target.\endlink
+    \i \link setInternalFormat() Internal format.\endlink
+    \endlist
+
+    Note that the desired attachments or number of samples per pixels might not
+    be supported by the hardware driver. Call QGLFramebufferObject::format()
+    after creating a QGLFramebufferObject to find the exact format that was
+    used to create the frame buffer object.
+
+    \sa QGLFramebufferObject
+*/
+
+/*!
+    \since 4.6
+
+    Creates a QGLFramebufferObjectFormat object with properties specifying
+    the format of an OpenGL framebuffer object.
+
+    A multisample framebuffer object is specified by setting \a samples
+    to a value different from zero. If the desired amount of samples per pixel is
+    not supported by the hardware then the maximum number of samples per pixel
+    will be used. Note that multisample framebuffer objects can not be bound as
+    textures. Also, the \c{GL_EXT_framebuffer_multisample} extension is required
+    to create a framebuffer with more than one sample per pixel.
+
+    For multisample framebuffer objects a color render buffer is created,
+    otherwise a texture with the texture target \a target is created.
+    The color render buffer or texture will have the internal format
+    \a internalFormat, and will be bound to the \c GL_COLOR_ATTACHMENT0
+    attachment in the framebuffer object.
+
+    The \a attachment parameter describes the depth/stencil buffer
+    configuration.
+
+    \sa samples(), attachment(), target(), internalFormat()
+*/
+
+QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(int samples,
+                                                       QGLFramebufferObject::Attachment attachment,
+                                                       GLenum target,
+                                                       GLenum internalFormat)
+{
+    d = new QGLFramebufferObjectFormatPrivate;
+    d->samples = samples;
+    d->attachment = attachment;
+    d->target = target;
+    d->internal_format = internalFormat;
+}
+
+/*!
+    \since 4.6
+
+    Constructs a copy of \a other.
+*/
+
+QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(const QGLFramebufferObjectFormat &other)
+{
+    d = new QGLFramebufferObjectFormatPrivate;
+    *d = *other.d;
+}
+
+/*!
+    \since 4.6
+
+    Assigns \a other to this object.
+*/
+
+QGLFramebufferObjectFormat::QGLFramebufferObjectFormat &
+QGLFramebufferObjectFormat::operator=(const QGLFramebufferObjectFormat &other)
+{
+    *d = *other.d;
+    return *this;
+}
+
+/*!
+    \since 4.6
+
+    Destroys the QGLFramebufferObjectFormat.
+*/
+QGLFramebufferObjectFormat::~QGLFramebufferObjectFormat()
+{
+    delete d;
+}
+
+/*!
+    \since 4.6
+
+    Sets the number of samples per pixel for a multisample framebuffer object
+    to \a samples.
+    A sample count of 0 represents a regular non-multisample framebuffer object.
+
+    \sa samples()
+*/
+void QGLFramebufferObjectFormat::setSamples(int samples)
+{
+    d->samples = samples;
+}
+
+/*!
+    \since 4.6
+
+    Returns the number of samples per pixel if a framebuffer object
+    is a multisample framebuffer object. Otherwise, returns 0.
+
+    \sa setSamples()
+*/
+int QGLFramebufferObjectFormat::samples() const
+{
+    return d->samples;
+}
+
+/*!
+    \since 4.6
+
+    Sets the attachments a framebuffer object should have to \a attachment.
+
+    \sa attachment()
+*/
+void QGLFramebufferObjectFormat::setAttachment(QGLFramebufferObject::Attachment attachment)
+{
+    d->attachment = attachment;
+}
+
+/*!
+    \since 4.6
+
+    Returns the status of the depth and stencil buffers attached to
+    a framebuffer object.
+
+    \sa setAttachment()
+*/
+QGLFramebufferObject::Attachment QGLFramebufferObjectFormat::attachment() const
+{
+    return d->attachment;
+}
+
+/*!
+    \since 4.6
+
+    Sets the texture target of the texture attached to a framebuffer object to
+    \a target. Ignored for multisample framebuffer objects.
+
+    \sa textureTarget(), samples()
+*/
+void QGLFramebufferObjectFormat::setTextureTarget(GLenum target)
+{
+    d->target = target;
+}
+
+/*!
+    \since 4.6
+
+    Returns the texture target of the texture attached to a framebuffer object.
+    Ignored for multisample framebuffer objects.
+
+    \sa setTextureTarget(), samples()
+*/
+GLenum QGLFramebufferObjectFormat::textureTarget() const
+{
+    return d->target;
+}
+
+/*!
+    \since 4.6
+
+    Sets the internal format of a framebuffer object's texture or multisample
+    framebuffer object's color buffer to \a internalFormat.
+
+    \sa internalFormat()
+*/
+void QGLFramebufferObjectFormat::setInternalFormat(GLenum internalFormat)
+{
+    d->internal_format = internalFormat;
+}
+
+/*!
+    \since 4.6
+
+    Returns the internal format of a framebuffer object's texture or
+    multisample framebuffer object's color buffer.
+
+    \sa setInternalFormat()
+*/
+GLenum QGLFramebufferObjectFormat::internalFormat() const
+{
+    return d->internal_format;
+}
+
 class QGLFramebufferObjectPrivate
 {
 public:
@@ -74,13 +284,16 @@ public:
     ~QGLFramebufferObjectPrivate() {}
 
     void init(const QSize& sz, QGLFramebufferObject::Attachment attachment,
-              GLenum internal_format, GLenum texture_target);
+              GLenum internal_format, GLenum texture_target, int samples = 0);
     bool checkFramebufferStatus() const;
     GLuint texture;
     GLuint fbo;
     GLuint depth_stencil_buffer;
+    GLuint color_buffer;
     GLenum target;
     QSize size;
+    QGLFramebufferObjectFormat format;
+    int samples;
     uint valid : 1;
     uint bound : 1;
     QGLFramebufferObject::Attachment fbo_attachment;
@@ -122,6 +335,9 @@ bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
     case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
         qDebug("QGLFramebufferObject: Framebuffer incomplete, missing read buffer.");
         break;
+    case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
+        qDebug("QGLFramebufferObject: Framebuffer incomplete, attachments must have same number of samples per pixel.");
+        break;
     default:
         qDebug() <<"QGLFramebufferObject: An undefined error has occurred: "<< status;
         break;
@@ -130,7 +346,7 @@ bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
 }
 
 void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::Attachment attachment,
-                                       GLenum texture_target, GLenum internal_format)
+                                       GLenum texture_target, GLenum internal_format, int samples)
 {
     ctx = const_cast<QGLContext *>(QGLContext::currentContext());
     bool ext_detected = (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject);
@@ -147,26 +363,56 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At
 
     QT_CHECK_GLERROR();
     // init texture
-    glGenTextures(1, &texture);
-    glBindTexture(target, texture);
-    glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
-                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+    if (samples == 0) {
+        glGenTextures(1, &texture);
+        glBindTexture(target, texture);
+        glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
+                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
 #ifndef QT_OPENGL_ES
-    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 #else
-    glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 #endif
-    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
-                              target, texture, 0);
+        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+                target, texture, 0);
 
-    QT_CHECK_GLERROR();
-    valid = checkFramebufferStatus();
+        QT_CHECK_GLERROR();
+        valid = checkFramebufferStatus();
+
+        color_buffer = 0;
+        samples = 0;
+    } else {
+        GLint maxSamples;
+        glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);
+
+        samples = qBound(1, samples, int(maxSamples));
+
+        glGenRenderbuffersEXT(1, &color_buffer);
+        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, color_buffer);
+        if (glRenderbufferStorageMultisampleEXT) {
+            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
+                internal_format, size.width(), size.height());
+        } else {
+            samples = 0;
+            glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internal_format,
+                size.width(), size.height());
+        }
+
+        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+                                     GL_RENDERBUFFER_EXT, color_buffer);
+
+        QT_CHECK_GLERROR();
+        valid = checkFramebufferStatus();
+
+        if (valid)
+            glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples);
+    }
 
     if (attachment == QGLFramebufferObject::CombinedDepthStencil
         && (QGLExtensions::glExtensions & QGLExtensions::PackedDepthStencil)) {
@@ -175,7 +421,13 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At
         Q_ASSERT(!glIsRenderbufferEXT(depth_stencil_buffer));
         glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_buffer);
         Q_ASSERT(glIsRenderbufferEXT(depth_stencil_buffer));
-        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());
+        if (samples != 0 && glRenderbufferStorageMultisampleEXT)
+            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
+                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());
+        else
+            glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
+                GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());
+
         GLint i = 0;
         glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);
         glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
@@ -183,6 +435,7 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At
         glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                                      GL_RENDERBUFFER_EXT, depth_stencil_buffer);
         fbo_attachment = QGLFramebufferObject::CombinedDepthStencil;
+
         valid = checkFramebufferStatus();
         if (!valid)
             glDeleteRenderbuffersEXT(1, &depth_stencil_buffer);
@@ -193,12 +446,23 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At
         Q_ASSERT(!glIsRenderbufferEXT(depth_stencil_buffer));
         glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_buffer);
         Q_ASSERT(glIsRenderbufferEXT(depth_stencil_buffer));
+        if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
 #ifdef QT_OPENGL_ES
 #define GL_DEPTH_COMPONENT16 0x81A5
-        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height());
+            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
+                GL_DEPTH_COMPONENT16, size.width(), size.height());
 #else
-        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height());
+            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples,
+                GL_DEPTH_COMPONENT, size.width(), size.height());
 #endif
+        } else {
+#ifdef QT_OPENGL_ES
+#define GL_DEPTH_COMPONENT16 0x81A5
+            glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height());
+#else
+            glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height());
+#endif
+        }
         GLint i = 0;
         glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);
         glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
@@ -213,10 +477,18 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At
 
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
     if (!valid) {
-        glDeleteTextures(1, &texture);
+        if (color_buffer)
+            glDeleteRenderbuffersEXT(1, &color_buffer);
+        else
+            glDeleteTextures(1, &texture);
         glDeleteFramebuffersEXT(1, &fbo);
     }
     QT_CHECK_GLERROR();
+
+    format.setTextureTarget(target);
+    format.setSamples(samples);
+    format.setAttachment(fbo_attachment);
+    format.setInternalFormat(internal_format);
 }
 
 /*!
@@ -264,13 +536,18 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At
     framebuffer objects more portable.
     \endlist
 
-    Note that primitives drawn to a QGLFramebufferObject with QPainter
-    will only be antialiased if the QPainter::HighQualityAntialiasing
-    render hint is set. This is because there is currently no support
-    for the \c{GL_EXT_framebuffer_multisample} extension, which is
-    required to do multisample based antialiasing. Also note that the
-    QPainter::HighQualityAntialiasing render hint requires the
-    \c{GL_ARB_fragment_program} extension to work in OpenGL.
+    Note that you need to create a QGLFramebufferObject with more than one
+    sample per pixel for primitives to be antialiased when drawing using a
+    QPainter, unless if the QPainter::HighQualityAntialiasing render hint is
+    set. The QPainter::HighQualityAntialiasing render hint will enable
+    antialiasing as long as the \c{GL_ARB_fragment_program} extension is
+    present. To create a multisample framebuffer object you should use one of
+    the constructors that take a QGLFramebufferObject parameter, and set the
+    QGLFramebufferObject::samples() property to a non-zero value.
+
+    If you want to use a framebuffer object with multisampling enabled
+    as a texture, you first need to copy from it to a regular framebuffer
+    object using QGLContext::blitFramebuffer().
 
     \sa {Framebuffer Object Example}
 */
@@ -358,6 +635,32 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target)
     d->init(QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
 }
 
+/*! \overload
+
+    Constructs an OpenGL framebuffer object of the given \a size based on the
+    supplied \a format.
+*/
+
+QGLFramebufferObject::QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format)
+    : d_ptr(new QGLFramebufferObjectPrivate)
+{
+    Q_D(QGLFramebufferObject);
+    d->init(size, format.attachment(), format.textureTarget(), format.internalFormat(), format.samples());
+}
+
+/*! \overload
+
+    Constructs an OpenGL framebuffer object of the given \a width and \a height
+    based on the supplied \a format.
+*/
+
+QGLFramebufferObject::QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format)
+    : d_ptr(new QGLFramebufferObjectPrivate)
+{
+    Q_D(QGLFramebufferObject);
+    d->init(QSize(width, height), format.attachment(), format.textureTarget(), format.internalFormat(), format.samples());
+}
+
 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
 /*! \internal */
 QGLFramebufferObject::QGLFramebufferObject(int width, int height, QMacCompatGLenum target)
@@ -445,6 +748,8 @@ QGLFramebufferObject::~QGLFramebufferObject()
             || qgl_share_reg()->checkSharing(d->ctx, QGLContext::currentContext())))
     {
         glDeleteTextures(1, &d->texture);
+        if (d->color_buffer)
+            glDeleteRenderbuffersEXT(1, &d->color_buffer);
         if (d->depth_stencil_buffer)
             glDeleteRenderbuffersEXT(1, &d->depth_stencil_buffer);
         glDeleteFramebuffersEXT(1, &d->fbo);
@@ -540,6 +845,9 @@ bool QGLFramebufferObject::release()
     Returns the texture id for the texture attached as the default
     rendering target in this framebuffer object. This texture id can
     be bound as a normal texture in your own GL code.
+
+    If a multisample framebuffer object is used then the value returned
+    from this function will be invalid.
 */
 GLuint QGLFramebufferObject::texture() const
 {
@@ -560,6 +868,15 @@ QSize QGLFramebufferObject::size() const
 }
 
 /*!
+    Returns the format of this framebuffer object.
+*/
+const QGLFramebufferObjectFormat &QGLFramebufferObject::format() const
+{
+    Q_D(const QGLFramebufferObject);
+    return d->format;
+}
+
+/*!
     \fn QImage QGLFramebufferObject::toImage() const
 
     Returns the contents of this framebuffer object as a QImage.
@@ -752,4 +1069,85 @@ bool QGLFramebufferObject::isBound() const
     return d->bound;
 }
 
+/*!
+    \fn bool QGLFramebufferObject::hasOpenGLFramebufferBlit()
+
+    \since 4.6
+
+    Returns true if the OpenGL \c{GL_EXT_framebuffer_blit} extension
+    is present on this system; otherwise returns false.
+*/
+bool QGLFramebufferObject::hasOpenGLFramebufferBlit()
+{
+    QGLWidget dmy; // needed to detect and init the QGLExtensions object
+    return (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit);
+}
+
+/*!
+    \since 4.6
+
+    Blits from the \a sourceRect rectangle in the \a source framebuffer
+    object to the \a targetRect rectangle in the \a target framebuffer object.
+
+    If \a source or \a target is 0, the default framebuffer will be used
+    instead of a framebuffer object as source or target respectively.
+
+    The \a buffers parameter should be a mask consisting of any combination of
+    COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT, and STENCIL_BUFFER_BIT. Any buffer type
+    that is not present both in the source and target buffers is ignored.
+
+    The \a sourceRect and \a targetRect rectangles may have different sizes;
+    in this case \a buffers should not contain DEPTH_BUFFER_BIT or
+    STENCIL_BUFFER_BIT. The \a filter parameter should be set to GL_LINEAR or
+    GL_NEAREST, and specifies whether linear or nearest interpolation should
+    be used when scaling is performed.
+
+    If \a source equals \a target a copy is performed within the same buffer.
+    Results are undefined if the source and target rectangles overlap and
+    have different sizes. The sizes must also be the same if any of the
+    framebuffer objects are multisample framebuffers.
+
+    Note that the scissor test will restrict the blit area if enabled.
+
+    This function will have no effect unless hasOpenGLFramebufferBlit() returns
+    true.
+*/
+void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect,
+                                           QGLFramebufferObject *source, const QRect &sourceRect,
+                                           GLbitfield buffers,
+                                           GLenum filter)
+{
+    if (!(QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit))
+        return;
+
+    const QGLContext *ctx = QGLContext::currentContext();
+    if (!ctx)
+        return;
+
+    const int height = ctx->device()->height();
+
+    const int sh = source ? source->height() : height;
+    const int th = target ? target->height() : height;
+
+    const int sx0 = sourceRect.left();
+    const int sx1 = sourceRect.right();
+    const int sy0 = sh - sourceRect.bottom() - 1;
+    const int sy1 = sh - sourceRect.top() - 1;
+
+    const int tx0 = targetRect.left();
+    const int tx1 = targetRect.right();
+    const int ty0 = th - targetRect.bottom() - 1;
+    const int ty1 = th - targetRect.top() - 1;
+
+    glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source ? source->handle() : 0);
+    glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, target ? target->handle() : 0);
+
+    glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
+                         tx0, ty0, tx1, ty1,
+                         buffers, filter);
+
+    glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
+    glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
+}
+
 QT_END_NAMESPACE
diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h
index a9e1b2f..0a2a9d2 100644
--- a/src/opengl/qglframebufferobject.h
+++ b/src/opengl/qglframebufferobject.h
@@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE
 QT_MODULE(OpenGL)
 
 class QGLFramebufferObjectPrivate;
+class QGLFramebufferObjectFormat;
 
 class Q_OPENGL_EXPORT QGLFramebufferObject : public QPaintDevice
 {
@@ -77,6 +78,9 @@ public:
                          GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
 #endif
 
+    QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format);
+    QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format);
+
 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
     QGLFramebufferObject(const QSize &size, QMacCompatGLenum target = GL_TEXTURE_2D);
     QGLFramebufferObject(int width, int height, QMacCompatGLenum target = GL_TEXTURE_2D);
@@ -89,10 +93,13 @@ public:
 
     virtual ~QGLFramebufferObject();
 
+    const QGLFramebufferObjectFormat &format() const;
+
     bool isValid() const;
     bool isBound() const;
     bool bind();
     bool release();
+
     GLuint texture() const;
     QSize size() const;
     QImage toImage() const;
@@ -110,6 +117,12 @@ public:
     void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
 #endif
 
+    static bool hasOpenGLFramebufferBlit();
+    static void blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect,
+                                QGLFramebufferObject *source, const QRect &sourceRect,
+                                GLbitfield buffers = GL_COLOR_BUFFER_BIT,
+                                GLenum filter = GL_NEAREST);
+
 protected:
     int metric(PaintDeviceMetric metric) const;
     int devType() const { return QInternal::FramebufferObject; }
@@ -120,6 +133,42 @@ private:
     friend class QGLDrawable;
 };
 
+class QGLFramebufferObjectFormatPrivate;
+class Q_OPENGL_EXPORT QGLFramebufferObjectFormat
+{
+public:
+#if !defined(QT_OPENGL_ES) || defined(Q_QDOC)
+    QGLFramebufferObjectFormat(int samples = 0,
+                               QGLFramebufferObject::Attachment attachment = QGLFramebufferObject::NoAttachment,
+                               GLenum target = GL_TEXTURE_2D,
+                               GLenum internalFormat = GL_RGBA8);
+#else
+    QGLFramebufferObjectFormat(int samples = 0,
+                               QGLFramebufferObject::Attachment attachment = QGLFramebufferObject::NoAttachment,
+                               GLenum target = GL_TEXTURE_2D,
+                               GLenum internalFormat = GL_RGBA);
+#endif
+
+    QGLFramebufferObjectFormat(const QGLFramebufferObjectFormat &other);
+    QGLFramebufferObjectFormat &operator=(const QGLFramebufferObjectFormat &other);
+    ~QGLFramebufferObjectFormat();
+
+    void setSamples(int samples);
+    int samples() const;
+
+    void setAttachment(QGLFramebufferObject::Attachment attachment);
+    QGLFramebufferObject::Attachment attachment() const;
+
+    void setTextureTarget(GLenum target);
+    GLenum textureTarget() const;
+
+    void setInternalFormat(GLenum internalFormat);
+    GLenum internalFormat() const;
+
+private:
+    QGLFramebufferObjectFormatPrivate *d;
+};
+
 QT_END_NAMESPACE
 
 QT_END_HEADER
-- 
cgit v0.12


From ee8949183917ae7494cbf0121922d0b68384f90f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Wed, 11 Mar 2009 12:23:51 +0100
Subject: Fixes:    Use the new framebuffer blit/multisample API in the window
 surface. RevBy:    Trond

---
 src/opengl/qwindowsurface_gl.cpp | 49 +++++++++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 18 deletions(-)

diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index 5cd4366..b4a4565 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -436,34 +436,39 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
 #ifdef Q_WS_MAC
     ctx->updatePaintDevice();
 #endif
-    if (d_ptr->fbo)
-        d_ptr->fbo->release();
-
     glDisable(GL_DEPTH_TEST);
     glDisable(GL_SCISSOR_TEST);
 
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
+    if (d_ptr->fbo && QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit) {
+        QGLFramebufferObject::blitFramebuffer(0, rect, d_ptr->fbo, rect);
+        d_ptr->fbo->bind();
+    } else {
+        if (d_ptr->fbo)
+            d_ptr->fbo->release();
 
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
+        glMatrixMode(GL_MODELVIEW);
+        glLoadIdentity();
+
+        glMatrixMode(GL_PROJECTION);
+        glLoadIdentity();
 #ifndef QT_OPENGL_ES
-    glOrtho(0, size.width(), size.height(), 0, -999999, 999999);
+        glOrtho(0, size.width(), size.height(), 0, -999999, 999999);
 #else
-    glOrthof(0, size.width(), size.height(), 0, -999999, 999999);
+        glOrthof(0, size.width(), size.height(), 0, -999999, 999999);
 #endif
-    glViewport(0, 0, size.width(), size.height());
+        glViewport(0, 0, size.width(), size.height());
+
+        glColor4f(1, 1, 1, 1);
+        drawTexture(rect, texture, window()->size(), br);
 
-    glColor4f(1, 1, 1, 1);
-    drawTexture(rect, texture, window()->size(), br);
+        if (d_ptr->fbo)
+            d_ptr->fbo->bind();
+    }
 
     if (ctx->format().doubleBuffer())
         ctx->swapBuffers();
     else
         glFlush();
-
-    if (d_ptr->fbo)
-        d_ptr->fbo->bind();
 }
 
 void QGLWindowSurface::updateGeometry()
@@ -537,12 +542,20 @@ void QGLWindowSurface::updateGeometry()
         ctx->d_ptr->internal_context = true;
         ctx->makeCurrent();
         delete d_ptr->fbo;
-        d_ptr->fbo = new QGLFramebufferObject(rect.size(), QGLFramebufferObject::CombinedDepthStencil,
-                                              GLenum(target), GLenum(GL_RGBA));
 
+        QGLFramebufferObjectFormat format;
+        format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
+        format.setInternalFormat(GL_RGBA);
+        format.setTextureTarget(target);
+
+        if (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit)
+            format.setSamples(8);
+
+        d_ptr->fbo = new QGLFramebufferObject(rect.size(), format);
         d_ptr->fbo->bind();
         if (d_ptr->fbo->isValid()) {
-            qDebug() << "Created Window Surface FBO" << rect.size();
+            qDebug() << "Created Window Surface FBO" << rect.size()
+                     << "with samples" << d_ptr->fbo->format().samples();
             return;
         } else {
             qDebug() << "QGLWindowSurface: Failed to create valid FBO, falling back";
-- 
cgit v0.12


From b469889f6f9b49f2e52948e3419958b0d8bfc994 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Wed, 11 Mar 2009 18:46:13 +0100
Subject: Fixes:    Prevent QGLFramebufferObject from resetting the current
 context. RevBy:    Trond Details:  If there is already an active context we
 don't need a dummy widget.

---
 src/opengl/qglframebufferobject.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 297ef84..45d4788 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -918,7 +918,8 @@ QPaintEngine *QGLFramebufferObject::paintEngine() const
 */
 bool QGLFramebufferObject::hasOpenGLFramebufferObjects()
 {
-    QGLWidget dmy; // needed to detect and init the QGLExtensions object
+    if (!QGLContext::currentContext())
+        QGLWidget dmy; // needed to detect and init the QGLExtensions object
     return (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject);
 }
 
@@ -1079,7 +1080,8 @@ bool QGLFramebufferObject::isBound() const
 */
 bool QGLFramebufferObject::hasOpenGLFramebufferBlit()
 {
-    QGLWidget dmy; // needed to detect and init the QGLExtensions object
+    if (!QGLContext::currentContext())
+        QGLWidget dmy; // needed to detect and init the QGLExtensions object
     return (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit);
 }
 
-- 
cgit v0.12


From 860498a1e63bff2b5a52accda92256c36ba5c23d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <sroedal@trolltech.com>
Date: Wed, 11 Mar 2009 18:47:47 +0100
Subject: Fixes:    Use the blit/multisample FBO API in the framebuffer object
 example. RevBy:    Trond

---
 examples/opengl/framebufferobject/glwidget.cpp | 28 ++++++++++++++++++++++----
 examples/opengl/framebufferobject/glwidget.h   |  3 ++-
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/examples/opengl/framebufferobject/glwidget.cpp b/examples/opengl/framebufferobject/glwidget.cpp
index d3591d6..3cb3929 100644
--- a/examples/opengl/framebufferobject/glwidget.cpp
+++ b/examples/opengl/framebufferobject/glwidget.cpp
@@ -53,7 +53,18 @@ GLWidget::GLWidget(QWidget *parent)
 {
     setWindowTitle(tr("OpenGL framebuffer objects"));
     makeCurrent();
-    fbo = new QGLFramebufferObject(1024, 1024);
+
+    if (QGLFramebufferObject::hasOpenGLFramebufferBlit()) {
+        QGLFramebufferObjectFormat format;
+        format.setSamples(4);
+
+        render_fbo = new QGLFramebufferObject(512, 512, format);
+        texture_fbo = new QGLFramebufferObject(512, 512);
+    } else {
+        render_fbo = new QGLFramebufferObject(1024, 1024);
+        texture_fbo = render_fbo;
+    }
+
     rot_x = rot_y = rot_z = 0.0f;
     scale = 0.1f;
     anim = new QTimeLine(750, this);
@@ -113,7 +124,9 @@ GLWidget::~GLWidget()
 {
     delete[] wave;
     glDeleteLists(tile_list, 1);
-    delete fbo;
+    delete texture_fbo;
+    if (render_fbo != texture_fbo)
+        delete render_fbo;
 }
 
 void GLWidget::paintEvent(QPaintEvent *)
@@ -129,10 +142,16 @@ void GLWidget::draw()
     saveGLState();
 
     // render the 'bubbles.svg' file into our framebuffer object
-    QPainter fbo_painter(fbo);
+    QPainter fbo_painter(render_fbo);
     svg_renderer->render(&fbo_painter);
     fbo_painter.end();
 
+    if (render_fbo != texture_fbo) {
+        QRect rect(0, 0, render_fbo->width(), render_fbo->height());
+        QGLFramebufferObject::blitFramebuffer(texture_fbo, rect,
+                                              render_fbo, rect);
+    }
+
     // draw into the GL widget
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glMatrixMode(GL_PROJECTION);
@@ -145,8 +164,9 @@ void GLWidget::draw()
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-    glBindTexture(GL_TEXTURE_2D, fbo->texture());
+    glBindTexture(GL_TEXTURE_2D, texture_fbo->texture());
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glEnable(GL_TEXTURE_2D);
     glEnable(GL_MULTISAMPLE);
     glEnable(GL_CULL_FACE);
diff --git a/examples/opengl/framebufferobject/glwidget.h b/examples/opengl/framebufferobject/glwidget.h
index b64cfa8..d97ef78 100644
--- a/examples/opengl/framebufferobject/glwidget.h
+++ b/examples/opengl/framebufferobject/glwidget.h
@@ -77,6 +77,7 @@ private:
     QImage logo;
     QTimeLine *anim;
     QSvgRenderer *svg_renderer;
-    QGLFramebufferObject *fbo;
+    QGLFramebufferObject *render_fbo;
+    QGLFramebufferObject *texture_fbo;
 };
 
-- 
cgit v0.12


From 855aa89e0ba99f8a0f75d7b31930bab2cefb93f8 Mon Sep 17 00:00:00 2001
From: Gunnar Sletta <gunnar@trolltech.com>
Date: Wed, 4 Mar 2009 14:43:58 +0100
Subject: Fixes:    make the toNormalizedFillRect function slightly faster
 RevBy:    sroedal

---
 src/gui/painting/qpaintengine_raster.cpp | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 92a196c..3cf618c 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -1706,12 +1706,17 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
 
 static inline QRect toNormalizedFillRect(const QRectF &rect)
 {
-    const int x1 = qRound(rect.x() + aliasedCoordinateDelta);
-    const int y1 = qRound(rect.y() + aliasedCoordinateDelta);
-    const int x2 = qRound(rect.right() + aliasedCoordinateDelta);
-    const int y2 = qRound(rect.bottom() + aliasedCoordinateDelta);
+    int x1 = int(rect.x() + aliasedCoordinateDelta);
+    int y1 = int(rect.y() + aliasedCoordinateDelta);
+    int x2 = int(rect.right() + aliasedCoordinateDelta);
+    int y2 = int(rect.bottom() + aliasedCoordinateDelta);
 
-    return QRect(x1, y1, x2 - x1, y2 - y1).normalized();
+    if (x2 < x1)
+        qSwap(x1, x2);
+    if (y2 < y1)
+        qSwap(y1, y2);
+
+    return QRect(x1, y1, x2 - x1, y2 - y1);
 }
 
 /*!
-- 
cgit v0.12