diff options
author | Laszlo Agocs <laszlo.agocs@digia.com> | 2014-03-04 15:06:36 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-10 15:10:37 +0100 |
commit | 1e8de50674f5b33a50c45224b7e07b3f974f6ab0 (patch) | |
tree | a52d4e421be3c6c2deb4ff07905d5715012b0d9a | |
parent | 11eb9d37dc191b6e71c903e4f7f4d2da579e7df5 (diff) |
Avoid using direct OpenGL calls in gui and widgets
Change-Id: I5d88a2e204ca23e178a4e3044b9cb13392c3e763
Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
-rw-r--r-- | src/gui/kernel/qopenglcontext.cpp | 15 | ||||
-rw-r--r-- | src/gui/opengl/qopengl.cpp | 9 | ||||
-rw-r--r-- | src/gui/opengl/qopengl.h | 20 | ||||
-rw-r--r-- | src/gui/opengl/qopenglbuffer.cpp | 4 | ||||
-rw-r--r-- | src/gui/opengl/qopengldebug.cpp | 21 | ||||
-rw-r--r-- | src/gui/opengl/qopenglframebufferobject.cpp | 43 | ||||
-rw-r--r-- | src/gui/opengl/qopenglfunctions.cpp | 55 | ||||
-rw-r--r-- | src/gui/opengl/qopenglfunctions.h | 38 | ||||
-rw-r--r-- | src/gui/opengl/qopenglgradientcache.cpp | 15 | ||||
-rw-r--r-- | src/gui/opengl/qopenglpaintengine.cpp | 375 | ||||
-rw-r--r-- | src/gui/opengl/qopenglshaderprogram.cpp | 3 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexture.cpp | 6 | ||||
-rw-r--r-- | src/gui/opengl/qopengltextureblitter.cpp | 9 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexturecache.cpp | 15 | ||||
-rw-r--r-- | src/gui/opengl/qopengltextureglyphcache.cpp | 95 | ||||
-rw-r--r-- | src/gui/opengl/qopengltextureglyphcache_p.h | 4 | ||||
-rw-r--r-- | src/gui/painting/qplatformbackingstore.cpp | 45 | ||||
-rw-r--r-- | src/widgets/kernel/qopenglwidget.cpp | 17 |
18 files changed, 448 insertions, 341 deletions
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 74771d6826..d64f996b56 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -334,17 +334,18 @@ int QOpenGLContextPrivate::maxTextureSize() if (max_texture_size != -1) return max_texture_size; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); + Q_Q(QOpenGLContext); + QOpenGLFunctions *funcs = q->functions(); + funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); #ifndef QT_OPENGL_ES - Q_Q(QOpenGLContext); if (!q->isES()) { GLenum proxy = GL_PROXY_TEXTURE_2D; GLint size; GLint next = 64; - glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); + funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); if (size == 0) { return max_texture_size; } @@ -354,8 +355,8 @@ int QOpenGLContextPrivate::maxTextureSize() if (next > max_texture_size) break; - glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); + funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); } while (next > size); max_texture_size = size; @@ -864,7 +865,7 @@ void QOpenGLContext::swapBuffers(QSurface *surface) qWarning() << "QOpenGLContext::swapBuffers() called without corresponding makeCurrent()"; #endif if (surface->format().swapBehavior() == QSurfaceFormat::SingleBuffer) - glFlush(); + functions()->glFlush(); d->platformGLContext->swapBuffers(surfaceHandle); } diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index 94270ba0c4..b452c605e3 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -53,7 +53,9 @@ typedef const GLubyte * (QOPENGLF_APIENTRYP qt_glGetStringi)(GLenum, GLuint); QOpenGLExtensionMatcher::QOpenGLExtensionMatcher() { - const char *extensionStr = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)); + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + QOpenGLFunctions *funcs = ctx->functions(); + const char *extensionStr = reinterpret_cast<const char *>(funcs->glGetString(GL_EXTENSIONS)); if (extensionStr) { QByteArray ba(extensionStr); @@ -64,9 +66,8 @@ QOpenGLExtensionMatcher::QOpenGLExtensionMatcher() #else } else { // clear error state - while (glGetError()) {} + while (funcs->glGetError()) {} - QOpenGLContext *ctx = QOpenGLContext::currentContext(); if (ctx) { qt_glGetStringi glGetStringi = (qt_glGetStringi)ctx->getProcAddress("glGetStringi"); @@ -74,7 +75,7 @@ QOpenGLExtensionMatcher::QOpenGLExtensionMatcher() return; GLint numExtensions; - glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); + funcs->glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); for (int i = 0; i < numExtensions; ++i) { const char *str = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i)); diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h index 6eb656cd09..190c05ba26 100644 --- a/src/gui/opengl/qopengl.h +++ b/src/gui/opengl/qopengl.h @@ -66,7 +66,7 @@ // which the system headers do not. #if defined(QT_OPENGL_ES_2) -# if defined(Q_OS_MAC) +# if defined(Q_OS_MAC) // iOS # include <OpenGLES/ES2/gl.h> # include <OpenGLES/ES2/glext.h> @@ -78,7 +78,7 @@ */ typedef void* GLeglImageOES; -# else // "uncontrolled" platforms +# else // "uncontrolled" ES2 platforms # include <GLES2/gl2.h> /* @@ -90,14 +90,14 @@ typedef void* GLeglImageOES; typedef char GLchar; # include <QtGui/qopengles2ext.h> -# ifndef GL_DOUBLE -# define GL_DOUBLE GL_FLOAT -# endif -# ifndef GLdouble -typedef GLfloat GLdouble; -# endif # endif // Q_OS_MAC -#else +# ifndef GL_DOUBLE +# define GL_DOUBLE GL_FLOAT +# endif +# ifndef GLdouble +typedef GLfloat GLdouble; +# endif +#else // non-ES2 platforms # if defined(Q_OS_MAC) # include <OpenGL/gl.h> # if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 @@ -110,7 +110,7 @@ typedef GLfloat GLdouble; # include <GL/gl.h> # include <QtGui/qopenglext.h> # endif // Q_OS_MAC -#endif +#endif // QT_OPENGL_ES_2 // Desktops, apart from Mac OS X prior to 10.7 can support OpenGL 3 // and desktops apart from Mac can support OpenGL 4 diff --git a/src/gui/opengl/qopenglbuffer.cpp b/src/gui/opengl/qopenglbuffer.cpp index fe121f126f..2e1a4577f6 100644 --- a/src/gui/opengl/qopenglbuffer.cpp +++ b/src/gui/opengl/qopenglbuffer.cpp @@ -337,9 +337,9 @@ bool QOpenGLBuffer::read(int offset, void *data, int count) Q_D(QOpenGLBuffer); if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id()) return false; - while (glGetError() != GL_NO_ERROR) ; // Clear error state. + while (d->funcs->glGetError() != GL_NO_ERROR) ; // Clear error state. d->funcs->glGetBufferSubData(d->type, offset, count, data); - return glGetError() == GL_NO_ERROR; + return d->funcs->glGetError() == GL_NO_ERROR; } #else Q_UNUSED(offset); diff --git a/src/gui/opengl/qopengldebug.cpp b/src/gui/opengl/qopengldebug.cpp index cc6e945954..79b59a8e98 100644 --- a/src/gui/opengl/qopengldebug.cpp +++ b/src/gui/opengl/qopengldebug.cpp @@ -43,6 +43,7 @@ #include <QtCore/qglobal.h> #include <QtCore/qvarlengtharray.h> #include <QtGui/qopengl.h> +#include <QtGui/qopenglfunctions.h> #include "qopengldebug.h" @@ -1380,7 +1381,7 @@ bool QOpenGLDebugLogger::initialize() #undef GET_DEBUG_PROC_ADDRESS - glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, &d->maxMessageLength); + QOpenGLContext::currentContext()->functions()->glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, &d->maxMessageLength); #ifndef QT_NO_DEBUG if (!d->context->format().testOption(QSurfaceFormat::DebugContext)) { @@ -1448,15 +1449,16 @@ void QOpenGLDebugLogger::startLogging(QOpenGLDebugLogger::LoggingMode loggingMod d->glDebugMessageCallback(&qt_opengl_debug_callback, d); - d->debugWasEnabled = glIsEnabled(GL_DEBUG_OUTPUT); - d->syncDebugWasEnabled = glIsEnabled(GL_DEBUG_OUTPUT_SYNCHRONOUS); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + d->debugWasEnabled = funcs->glIsEnabled(GL_DEBUG_OUTPUT); + d->syncDebugWasEnabled = funcs->glIsEnabled(GL_DEBUG_OUTPUT_SYNCHRONOUS); if (d->loggingMode == SynchronousLogging) - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + funcs->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); else - glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + funcs->glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - glEnable(GL_DEBUG_OUTPUT); + funcs->glEnable(GL_DEBUG_OUTPUT); } /*! @@ -1485,13 +1487,14 @@ void QOpenGLDebugLogger::stopLogging() d->glDebugMessageCallback(d->oldDebugCallbackFunction, d->oldDebugCallbackParameter); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); if (!d->debugWasEnabled) - glDisable(GL_DEBUG_OUTPUT); + funcs->glDisable(GL_DEBUG_OUTPUT); if (d->syncDebugWasEnabled) - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + funcs->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); else - glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + funcs->glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS); } /*! diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index db1ea1b1a1..55edaf7baf 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -57,11 +57,11 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_DEBUG #define QT_RESET_GLERROR() \ { \ - while (glGetError() != GL_NO_ERROR) {} \ + while (QOpenGLContext::currentContext()->functions()->glGetError() != GL_NO_ERROR) {} \ } #define QT_CHECK_GLERROR() \ { \ - GLenum err = glGetError(); \ + GLenum err = QOpenGLContext::currentContext()->functions()->glGetError(); \ if (err != GL_NO_ERROR) { \ qDebug("[%s line %d] OpenGL Error: %d", \ __FILE__, __LINE__, (int)err); \ @@ -405,9 +405,9 @@ namespace funcs->glDeleteRenderbuffers(1, &id); } - void freeTextureFunc(QOpenGLFunctions *, GLuint id) + void freeTextureFunc(QOpenGLFunctions *funcs, GLuint id) { - glDeleteTextures(1, &id); + funcs->glDeleteTextures(1, &id); } } @@ -432,7 +432,7 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi #ifndef QT_OPENGL_ES_2 GLint maxSamples; - glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + funcs.glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); samples = qBound(0, int(samples), int(maxSamples)); #endif @@ -497,16 +497,16 @@ void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal QOpenGLContext *ctx = QOpenGLContext::currentContext(); GLuint texture = 0; - glGenTextures(1, &texture); - glBindTexture(target, texture); + funcs.glGenTextures(1, &texture); + funcs.glBindTexture(target, texture); - 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); + funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + funcs.glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); if (mipmap) { int width = size.width(); int height = size.height(); @@ -515,20 +515,20 @@ void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal width = qMax(1, width >> 1); height = qMax(1, height >> 1); ++level; - glTexImage2D(target, level, internal_format, width, height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + funcs.glTexImage2D(target, level, internal_format, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); } } funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, texture, 0); QT_CHECK_GLERROR(); - glBindTexture(target, 0); + funcs.glBindTexture(target, 0); valid = checkFramebufferStatus(ctx); if (valid) texture_guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc); else - glDeleteTextures(1, &texture); + funcs.glDeleteTextures(1, &texture); } void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment) @@ -1084,7 +1084,8 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, int w = size.width(); int h = size.height(); - while (glGetError()); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + while (funcs->glGetError()); #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied @@ -1094,14 +1095,14 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, #else GLint fmt = GL_BGRA; #endif - glReadPixels(0, 0, w, h, fmt, GL_UNSIGNED_BYTE, img.bits()); - if (!glGetError()) + funcs->glReadPixels(0, 0, w, h, fmt, GL_UNSIGNED_BYTE, img.bits()); + if (!funcs->glGetError()) return img.mirrored(); #endif QImage rgbaImage(size, (alpha_format && include_alpha) ? QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGBX8888); - glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rgbaImage.bits()); + funcs->glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rgbaImage.bits()); return rgbaImage.mirrored(); } diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index 5d30020f49..84c70606b1 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -1993,6 +1993,12 @@ void QOpenGLFunctions::initializeOpenGLFunctions() */ /*! + \fn void QOpenGLFunctions::glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) + + \internal +*/ + +/*! \fn bool QOpenGLFunctions::isInitialized(const QOpenGLFunctionsPrivate *d) \internal */ @@ -2394,6 +2400,15 @@ static void QOPENGLF_APIENTRY qopenglfResolveClearColor(GLclampf red, GLclampf g RESOLVE_FUNC_VOID(0, ClearColor)(red, green, blue, alpha); } +static void QOPENGLF_APIENTRY qopenglfResolveClearDepthf(GLclampf depth) +{ + if (QOpenGLContext::currentContext()->isES()) { + RESOLVE_FUNC_VOID(0, ClearDepthf)(depth); + } else { + RESOLVE_FUNC_VOID(0, ClearDepth)((GLdouble) depth); + } +} + static void QOPENGLF_APIENTRY qopenglfResolveClearStencil(GLint s) { RESOLVE_FUNC_VOID(0, ClearStencil)(s); @@ -2434,6 +2449,15 @@ static void QOPENGLF_APIENTRY qopenglfResolveDepthMask(GLboolean flag) RESOLVE_FUNC_VOID(0, DepthMask)(flag); } +static void QOPENGLF_APIENTRY qopenglfResolveDepthRangef(GLclampf zNear, GLclampf zFar) +{ + if (QOpenGLContext::currentContext()->isES()) { + RESOLVE_FUNC_VOID(0, DepthRangef)(zNear, zFar); + } else { + RESOLVE_FUNC_VOID(0, DepthRange)((GLdouble) zNear, (GLdouble) zFar); + } +} + static void QOPENGLF_APIENTRY qopenglfResolveDisable(GLenum cap) { RESOLVE_FUNC_VOID(0, Disable)(cap); @@ -3131,6 +3155,29 @@ static void QOPENGLF_APIENTRY qopenglfResolveGetBufferSubData(GLenum target, qop (target, offset, size, data); } +#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_DYNAMIC) + +// Desktop only + +static void QOPENGLF_APIENTRY qopenglfResolveGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) +{ + RESOLVE_FUNC_VOID(0, GetTexLevelParameteriv)(target, level, pname, params); +} + +// Special translation functions for ES-specific calls on desktop GL + +static void QOPENGLF_APIENTRY qopenglfTranslateClearDepthf(GLclampf depth) +{ + ::glClearDepth(depth); +} + +static void QOPENGLF_APIENTRY qopenglfTranslateDepthRangef(GLclampf zNear, GLclampf zFar) +{ + ::glDepthRange(zNear, zFar); +} + +#endif // !ES2 && !DYNAMIC + QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) { /* Assign a pointer to an above defined static function @@ -3145,6 +3192,7 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) BlendFunc = qopenglfResolveBlendFunc; Clear = qopenglfResolveClear; ClearColor = qopenglfResolveClearColor; + ClearDepthf = qopenglfResolveClearDepthf; ClearStencil = qopenglfResolveClearStencil; ColorMask = qopenglfResolveColorMask; CopyTexImage2D = qopenglfResolveCopyTexImage2D; @@ -3153,6 +3201,7 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) DeleteTextures = qopenglfResolveDeleteTextures; DepthFunc = qopenglfResolveDepthFunc; DepthMask = qopenglfResolveDepthMask; + DepthRangef = qopenglfResolveDepthRangef; Disable = qopenglfResolveDisable; DrawArrays = qopenglfResolveDrawArrays; DrawElements = qopenglfResolveDrawElements; @@ -3186,6 +3235,8 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) TexParameteriv = qopenglfResolveTexParameteriv; TexSubImage2D = qopenglfResolveTexSubImage2D; Viewport = qopenglfResolveViewport; + + GetTexLevelParameteriv = qopenglfResolveGetTexLevelParameteriv; } else { #ifndef QT_OPENGL_DYNAMIC // Use the functions directly. This requires linking QtGui to an OpenGL implementation. @@ -3193,6 +3244,7 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) BlendFunc = ::glBlendFunc; Clear = ::glClear; ClearColor = ::glClearColor; + ClearDepthf = qopenglfTranslateClearDepthf; ClearStencil = ::glClearStencil; ColorMask = ::glColorMask; CopyTexImage2D = ::glCopyTexImage2D; @@ -3201,6 +3253,7 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) DeleteTextures = ::glDeleteTextures; DepthFunc = ::glDepthFunc; DepthMask = ::glDepthMask; + DepthRangef = qopenglfTranslateDepthRangef; Disable = ::glDisable; DrawArrays = ::glDrawArrays; DrawElements = ::glDrawElements; @@ -3234,6 +3287,8 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) TexParameteriv = ::glTexParameteriv; TexSubImage2D = ::glTexSubImage2D; Viewport = ::glViewport; + + GetTexLevelParameteriv = ::glGetTexLevelParameteriv; #else // QT_OPENGL_DYNAMIC // This should not happen. qFatal("QOpenGLFunctions: Dynamic OpenGL builds do not support platforms with insufficient function resolving capabilities"); diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h index ac49037260..03c12200d5 100644 --- a/src/gui/opengl/qopenglfunctions.h +++ b/src/gui/opengl/qopenglfunctions.h @@ -223,6 +223,8 @@ struct QOpenGLFunctionsPrivate; #undef glVertexAttrib4fv #undef glVertexAttribPointer +#undef glTexLevelParameteriv + class Q_GUI_EXPORT QOpenGLFunctions { public: @@ -405,6 +407,9 @@ public: void glVertexAttrib4fv(GLuint indx, const GLfloat* values); void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr); + // OpenGL1, not GLES2 + void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params); + protected: QOpenGLFunctionsPrivate *d_ptr; static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; } @@ -420,6 +425,7 @@ struct QOpenGLFunctionsPrivate void (QOPENGLF_APIENTRYP BlendFunc)(GLenum sfactor, GLenum dfactor); void (QOPENGLF_APIENTRYP Clear)(GLbitfield mask); void (QOPENGLF_APIENTRYP ClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + void (QOPENGLF_APIENTRYP ClearDepthf)(GLclampf depth); void (QOPENGLF_APIENTRYP ClearStencil)(GLint s); void (QOPENGLF_APIENTRYP ColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); void (QOPENGLF_APIENTRYP CopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); @@ -428,6 +434,7 @@ struct QOpenGLFunctionsPrivate void (QOPENGLF_APIENTRYP DeleteTextures)(GLsizei n, const GLuint* textures); void (QOPENGLF_APIENTRYP DepthFunc)(GLenum func); void (QOPENGLF_APIENTRYP DepthMask)(GLboolean flag); + void (QOPENGLF_APIENTRYP DepthRangef)(GLclampf nearVal, GLclampf farVal); void (QOPENGLF_APIENTRYP Disable)(GLenum cap); void (QOPENGLF_APIENTRYP DrawArrays)(GLenum mode, GLint first, GLsizei count); void (QOPENGLF_APIENTRYP DrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices); @@ -557,6 +564,13 @@ struct QOpenGLFunctionsPrivate void (QOPENGLF_APIENTRYP VertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void (QOPENGLF_APIENTRYP VertexAttrib4fv)(GLuint indx, const GLfloat* values); void (QOPENGLF_APIENTRYP VertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr); + + // OpenGL1 only, not GLES2 + void (QOPENGLF_APIENTRYP GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params); + + // Special non-ES OpenGL variants, not to be called directly + void (QOPENGLF_APIENTRYP ClearDepth)(GLdouble depth); + void (QOPENGLF_APIENTRYP DepthRange)(GLdouble zNear, GLdouble zFar); }; // GLES2 + OpenGL1 common subset @@ -1210,7 +1224,8 @@ inline GLenum QOpenGLFunctions::glCheckFramebufferStatus(GLenum target) inline void QOpenGLFunctions::glClearDepthf(GLclampf depth) { #ifndef QT_OPENGL_ES - ::glClearDepth(depth); + Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr)); + d_ptr->ClearDepthf(depth); #else ::glClearDepthf(depth); #endif @@ -1332,7 +1347,8 @@ inline void QOpenGLFunctions::glDeleteShader(GLuint shader) inline void QOpenGLFunctions::glDepthRangef(GLclampf zNear, GLclampf zFar) { #ifndef QT_OPENGL_ES - ::glDepthRange(zNear, zFar); + Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr)); + d_ptr->DepthRangef(zNear, zFar); #else ::glDepthRangef(zNear, zFar); #endif @@ -2138,6 +2154,24 @@ inline void QOpenGLFunctions::glVertexAttribPointer(GLuint indx, GLint size, GLe Q_OPENGL_FUNCTIONS_DEBUG } +// OpenGL1, not GLES2 + +inline void QOpenGLFunctions::glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) +{ +#ifdef QT_OPENGL_ES_2 + Q_UNUSED(target); + Q_UNUSED(level); + Q_UNUSED(pname); + Q_UNUSED(params); + // Cannot get here. + qFatal("QOpenGLFunctions: glGetTexLevelParameteriv not available with OpenGL ES"); +#else + Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr)); + d_ptr->GetTexLevelParameteriv(target, level, pname, params); +#endif + Q_OPENGL_FUNCTIONS_DEBUG +} + QT_END_NAMESPACE #endif // QT_NO_OPENGL diff --git a/src/gui/opengl/qopenglgradientcache.cpp b/src/gui/opengl/qopenglgradientcache.cpp index 9c312808a2..91b4d08474 100644 --- a/src/gui/opengl/qopenglgradientcache.cpp +++ b/src/gui/opengl/qopenglgradientcache.cpp @@ -43,6 +43,7 @@ #include <private/qdrawhelper_p.h> #include <private/qopenglcontext_p.h> #include <QtCore/qmutex.h> +#include <QtGui/qopenglfunctions.h> QT_BEGIN_NAMESPACE @@ -91,9 +92,10 @@ void QOpenGL2GradientCache::cleanCache() { QMutexLocker lock(&m_mutex); QOpenGLGradientColorTableHash::const_iterator it = cache.constBegin(); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); for (; it != cache.constEnd(); ++it) { const CacheInfo &cache_info = it.value(); - glDeleteTextures(1, &cache_info.texId); + funcs->glDeleteTextures(1, &cache_info.texId); } cache.clear(); } @@ -129,6 +131,7 @@ GLuint QOpenGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity GLuint QOpenGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity) { + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); if (cache.size() == maxCacheSize()) { int elem_to_remove = qrand() % maxCacheSize(); quint64 key = cache.keys()[elem_to_remove]; @@ -136,7 +139,7 @@ GLuint QOpenGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient // need to call glDeleteTextures on each removed cache entry: QOpenGLGradientColorTableHash::const_iterator it = cache.constFind(key); do { - glDeleteTextures(1, &it.value().texId); + funcs->glDeleteTextures(1, &it.value().texId); } while (++it != cache.constEnd() && it.key() == key); cache.remove(key); // may remove more than 1, but OK } @@ -144,10 +147,10 @@ GLuint QOpenGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode()); uint buffer[1024]; generateGradientColorTable(gradient, buffer, paletteSize(), opacity); - glGenTextures(1, &cache_entry.texId); - glBindTexture(GL_TEXTURE_2D, cache_entry.texId); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1, - 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + funcs->glGenTextures(1, &cache_entry.texId); + funcs->glBindTexture(GL_TEXTURE_2D, cache_entry.texId); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1, + 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); return cache.insert(hash_val, cache_entry).value().texId; } diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index 7fa80c5343..f160b340e0 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -123,14 +123,14 @@ void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wra lastTextureUsed = id; if (smoothPixmapTransform) { - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } - glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode); - glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode); + funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode); + funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode); } @@ -204,7 +204,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture() GLuint texId = QOpenGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0); funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - glBindTexture(GL_TEXTURE_2D, texId); + funcs.glBindTexture(GL_TEXTURE_2D, texId); if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient) updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); @@ -439,43 +439,43 @@ void QOpenGL2PaintEngineExPrivate::updateCompositionMode() // qDebug() << "QOpenGL2PaintEngineExPrivate::updateCompositionMode() - Setting GL composition mode for " << q->state()->composition_mode; switch(q->state()->composition_mode) { case QPainter::CompositionMode_SourceOver: - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + funcs.glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); break; case QPainter::CompositionMode_DestinationOver: - glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE); + funcs.glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE); break; case QPainter::CompositionMode_Clear: - glBlendFunc(GL_ZERO, GL_ZERO); + funcs.glBlendFunc(GL_ZERO, GL_ZERO); break; case QPainter::CompositionMode_Source: - glBlendFunc(GL_ONE, GL_ZERO); + funcs.glBlendFunc(GL_ONE, GL_ZERO); break; case QPainter::CompositionMode_Destination: - glBlendFunc(GL_ZERO, GL_ONE); + funcs.glBlendFunc(GL_ZERO, GL_ONE); break; case QPainter::CompositionMode_SourceIn: - glBlendFunc(GL_DST_ALPHA, GL_ZERO); + funcs.glBlendFunc(GL_DST_ALPHA, GL_ZERO); break; case QPainter::CompositionMode_DestinationIn: - glBlendFunc(GL_ZERO, GL_SRC_ALPHA); + funcs.glBlendFunc(GL_ZERO, GL_SRC_ALPHA); break; case QPainter::CompositionMode_SourceOut: - glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO); + funcs.glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO); break; case QPainter::CompositionMode_DestinationOut: - glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); + funcs.glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); break; case QPainter::CompositionMode_SourceAtop: - glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + funcs.glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; case QPainter::CompositionMode_DestinationAtop: - glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA); + funcs.glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA); break; case QPainter::CompositionMode_Xor: - glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + funcs.glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; case QPainter::CompositionMode_Plus: - glBlendFunc(GL_ONE, GL_ONE); + funcs.glBlendFunc(GL_ONE, GL_ONE); break; default: qWarning("Unsupported composition mode"); @@ -524,7 +524,7 @@ void QOpenGL2PaintEngineExPrivate::drawTexture(const QOpenGLRect& dest, const QO setCoords(staticVertexCoordinateArray, dest); setCoords(staticTextureCoordinateArray, srcTextureRect); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + funcs.glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } void QOpenGL2PaintEngineEx::beginNativePainting() @@ -541,37 +541,35 @@ void QOpenGL2PaintEngineEx::beginNativePainting() for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) d->funcs.glDisableVertexAttribArray(i); -#ifndef QT_OPENGL_ES_2 - if (!QOpenGLContext::currentContext()->isES()) { - Q_ASSERT(QOpenGLContext::currentContext()); - const QOpenGLContext *ctx = d->ctx; - const QSurfaceFormat &fmt = d->device->context()->format(); - if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1) - || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility"))) - || fmt.profile() == QSurfaceFormat::CompatibilityProfile) - { - // be nice to people who mix OpenGL 1.x code with QPainter commands - // by setting modelview and projection matrices to mirror the GL 1 - // paint engine - const QTransform& mtx = state()->matrix; - - float mv_matrix[4][4] = - { - { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) }, - { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) }, - { 0, 0, 1, 0 }, - { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) } - }; - - const QSize sz = d->device->size(); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999); - - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(&mv_matrix[0][0]); - } +#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_DYNAMIC) + Q_ASSERT(QOpenGLContext::currentContext()); + const QOpenGLContext *ctx = d->ctx; + const QSurfaceFormat &fmt = d->device->context()->format(); + if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1) + || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility"))) + || fmt.profile() == QSurfaceFormat::CompatibilityProfile) + { + // be nice to people who mix OpenGL 1.x code with QPainter commands + // by setting modelview and projection matrices to mirror the GL 1 + // paint engine + const QTransform& mtx = state()->matrix; + + float mv_matrix[4][4] = + { + { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) }, + { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) }, + { 0, 0, 1, 0 }, + { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) } + }; + + const QSize sz = d->device->size(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999); + + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(&mv_matrix[0][0]); } #endif // QT_OPENGL_ES_2 @@ -586,17 +584,17 @@ void QOpenGL2PaintEngineEx::beginNativePainting() void QOpenGL2PaintEngineExPrivate::resetGLState() { - glDisable(GL_BLEND); + funcs.glDisable(GL_BLEND); funcs.glActiveTexture(GL_TEXTURE0); - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDepthMask(true); - glDepthFunc(GL_LESS); + funcs.glDisable(GL_STENCIL_TEST); + funcs.glDisable(GL_DEPTH_TEST); + funcs.glDisable(GL_SCISSOR_TEST); + funcs.glDepthMask(true); + funcs.glDepthFunc(GL_LESS); funcs.glClearDepthf(1); - glStencilMask(0xff); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc(GL_ALWAYS, 0, 0xff); + funcs.glStencilMask(0xff); + funcs.glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + funcs.glStencilFunc(GL_ALWAYS, 0, 0xff); setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false); setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false); setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); @@ -755,9 +753,9 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path) cache->primitiveType = GL_TRIANGLE_FAN; cache->iscale = inverseScale; #ifdef QT_OPENGL_CACHE_AS_VBOS - glGenBuffers(1, &cache->vbo); - glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); - glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW); + funcs.glGenBuffers(1, &cache->vbo); + funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); + funcs.glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW); cache->ibo = 0; #else cache->vertices = (float *) malloc(floatSizeInBytes); @@ -768,12 +766,12 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path) prepareForDraw(currentBrush.isOpaque()); #ifdef QT_OPENGL_CACHE_AS_VBOS - glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); + funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0); #else setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices); #endif - glDrawArrays(cache->primitiveType, 0, cache->vertexCount); + funcs.glDrawArrays(cache->primitiveType, 0, cache->vertexCount); } else { // printf(" - Marking path as cachable...\n"); @@ -833,10 +831,10 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path) cache->iscale = inverseScale; cache->indexType = polys.indices.type(); #ifdef QT_OPENGL_CACHE_AS_VBOS - glGenBuffers(1, &cache->vbo); - glGenBuffers(1, &cache->ibo); - glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo); + funcs.glGenBuffers(1, &cache->vbo); + funcs.glGenBuffers(1, &cache->ibo); + funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); + funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo); if (polys.indices.type() == QVertexIndexVector::UnsignedInt) funcs.glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint32) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW); @@ -863,21 +861,21 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path) prepareForDraw(currentBrush.isOpaque()); #ifdef QT_OPENGL_CACHE_AS_VBOS - glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo); + funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); + funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo); setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0); if (cache->indexType == QVertexIndexVector::UnsignedInt) - glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, 0); + funcs.glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, 0); else - glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); + funcs.glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, 0); + funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + funcs.glBindBuffer(GL_ARRAY_BUFFER, 0); #else setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices); if (cache->indexType == QVertexIndexVector::UnsignedInt) - glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, (qint32 *)cache->indices); + funcs.glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, (qint32 *)cache->indices); else - glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, (qint16 *)cache->indices); + funcs.glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, (qint16 *)cache->indices); #endif } else { @@ -904,9 +902,9 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path) prepareForDraw(currentBrush.isOpaque()); setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertices.constData()); if (funcs.hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint)) - glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.data()); + funcs.glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.data()); else - glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_SHORT, polys.indices.data()); + funcs.glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_SHORT, polys.indices.data()); } else { // We can't handle big, concave painter paths with OpenGL without stencil buffer. qWarning("Painter path exceeds +/-32767 pixels."); @@ -920,24 +918,24 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path) fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill()); - glStencilMask(0xff); - glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); + funcs.glStencilMask(0xff); + funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); if (q->state()->clipTestEnabled) { // Pass when high bit is set, replace stencil value with current clip - glStencilFunc(GL_NOTEQUAL, q->state()->currentClip, GL_STENCIL_HIGH_BIT); + funcs.glStencilFunc(GL_NOTEQUAL, q->state()->currentClip, GL_STENCIL_HIGH_BIT); } else if (path.hasWindingFill()) { // Pass when any bit is set, replace stencil value with 0 - glStencilFunc(GL_NOTEQUAL, 0, 0xff); + funcs.glStencilFunc(GL_NOTEQUAL, 0, 0xff); } else { // Pass when high bit is set, replace stencil value with 0 - glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT); + funcs.glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT); } prepareForDraw(currentBrush.isOpaque()); // Stencil the brush onto the dest buffer composite(vertexCoordinateArray.boundingRect()); - glStencilMask(0); + funcs.glStencilMask(0); updateClipScissorTest(); } } @@ -954,16 +952,16 @@ void QOpenGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, Q_ASSERT(count || stops); // qDebug("QOpenGL2PaintEngineExPrivate::fillStencilWithVertexArray()"); - glStencilMask(0xff); // Enable stencil writes + funcs.glStencilMask(0xff); // Enable stencil writes if (dirtyStencilRegion.intersects(currentScissorBounds)) { QVector<QRect> clearRegion = dirtyStencilRegion.intersected(currentScissorBounds).rects(); - glClearStencil(0); // Clear to zero + funcs.glClearStencil(0); // Clear to zero for (int i = 0; i < clearRegion.size(); ++i) { #ifndef QT_GL_NO_SCISSOR_TEST setScissor(clearRegion.at(i)); #endif - glClear(GL_STENCIL_BUFFER_BIT); + funcs.glClear(GL_STENCIL_BUFFER_BIT); } dirtyStencilRegion -= currentScissorBounds; @@ -973,23 +971,23 @@ void QOpenGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, #endif } - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Disable color writes + funcs.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Disable color writes useSimpleShader(); - glEnable(GL_STENCIL_TEST); // For some reason, this has to happen _after_ the simple shader is use()'d + funcs.glEnable(GL_STENCIL_TEST); // For some reason, this has to happen _after_ the simple shader is use()'d if (mode == WindingFillMode) { Q_ASSERT(stops && !count); if (q->state()->clipTestEnabled) { // Flatten clip values higher than current clip, and set high bit to match current clip - glStencilFunc(GL_LEQUAL, GL_STENCIL_HIGH_BIT | q->state()->currentClip, ~GL_STENCIL_HIGH_BIT); - glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); + funcs.glStencilFunc(GL_LEQUAL, GL_STENCIL_HIGH_BIT | q->state()->currentClip, ~GL_STENCIL_HIGH_BIT); + funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); composite(bounds); - glStencilFunc(GL_EQUAL, GL_STENCIL_HIGH_BIT, GL_STENCIL_HIGH_BIT); + funcs.glStencilFunc(GL_EQUAL, GL_STENCIL_HIGH_BIT, GL_STENCIL_HIGH_BIT); } else if (!stencilClean) { // Clear stencil buffer within bounding rect - glStencilFunc(GL_ALWAYS, 0, 0xff); - glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); + funcs.glStencilFunc(GL_ALWAYS, 0, 0xff); + funcs.glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); composite(bounds); } @@ -997,44 +995,44 @@ void QOpenGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, funcs.glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP); // Dec. for back-facing "holes" funcs.glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP); - glStencilMask(~GL_STENCIL_HIGH_BIT); + funcs.glStencilMask(~GL_STENCIL_HIGH_BIT); drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN); if (q->state()->clipTestEnabled) { // Clear high bit of stencil outside of path - glStencilFunc(GL_EQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT); - glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); - glStencilMask(GL_STENCIL_HIGH_BIT); + funcs.glStencilFunc(GL_EQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT); + funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); + funcs.glStencilMask(GL_STENCIL_HIGH_BIT); composite(bounds); } } else if (mode == OddEvenFillMode) { - glStencilMask(GL_STENCIL_HIGH_BIT); - glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit + funcs.glStencilMask(GL_STENCIL_HIGH_BIT); + funcs.glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN); } else { // TriStripStrokeFillMode Q_ASSERT(count && !stops); // tristrips generated directly, so no vertexArray or stops - glStencilMask(GL_STENCIL_HIGH_BIT); + funcs.glStencilMask(GL_STENCIL_HIGH_BIT); #if 0 - glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit + funcs.glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data); - glDrawArrays(GL_TRIANGLE_STRIP, 0, count); + funcs.glDrawArrays(GL_TRIANGLE_STRIP, 0, count); #else - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + funcs.glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); if (q->state()->clipTestEnabled) { - glStencilFunc(GL_LEQUAL, q->state()->currentClip | GL_STENCIL_HIGH_BIT, - ~GL_STENCIL_HIGH_BIT); + funcs.glStencilFunc(GL_LEQUAL, q->state()->currentClip | GL_STENCIL_HIGH_BIT, + ~GL_STENCIL_HIGH_BIT); } else { - glStencilFunc(GL_ALWAYS, GL_STENCIL_HIGH_BIT, 0xff); + funcs.glStencilFunc(GL_ALWAYS, GL_STENCIL_HIGH_BIT, 0xff); } setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data); - glDrawArrays(GL_TRIANGLE_STRIP, 0, count); + funcs.glDrawArrays(GL_TRIANGLE_STRIP, 0, count); #endif } // Enable color writes & disable stencil writes - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + funcs.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } /* @@ -1050,22 +1048,22 @@ void QOpenGL2PaintEngineExPrivate::resetClipIfNeeded() Q_Q(QOpenGL2PaintEngineEx); useSimpleShader(); - glEnable(GL_STENCIL_TEST); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + funcs.glEnable(GL_STENCIL_TEST); + funcs.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); QRectF bounds = q->state()->matrix.inverted().mapRect(QRectF(0, 0, width, height)); QOpenGLRect rect(bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); // Set high bit on clip region - glStencilFunc(GL_LEQUAL, q->state()->currentClip, 0xff); - glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT); - glStencilMask(GL_STENCIL_HIGH_BIT); + funcs.glStencilFunc(GL_LEQUAL, q->state()->currentClip, 0xff); + funcs.glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT); + funcs.glStencilMask(GL_STENCIL_HIGH_BIT); composite(rect); // Reset clipping to 1 and everything else to zero - glStencilFunc(GL_NOTEQUAL, 0x01, GL_STENCIL_HIGH_BIT); - glStencilOp(GL_ZERO, GL_REPLACE, GL_REPLACE); - glStencilMask(0xff); + funcs.glStencilFunc(GL_NOTEQUAL, 0x01, GL_STENCIL_HIGH_BIT); + funcs.glStencilOp(GL_ZERO, GL_REPLACE, GL_REPLACE); + funcs.glStencilMask(0xff); composite(rect); q->state()->currentClip = 1; @@ -1073,8 +1071,8 @@ void QOpenGL2PaintEngineExPrivate::resetClipIfNeeded() maxClip = 1; - glStencilMask(0x0); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + funcs.glStencilMask(0x0); + funcs.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } bool QOpenGL2PaintEngineExPrivate::prepareForCachedGlyphDraw(const QFontEngineGlyphCache &cache) @@ -1107,9 +1105,9 @@ bool QOpenGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) || (q->state()->composition_mode == QPainter::CompositionMode_SourceOver && srcPixelsAreOpaque && !stateHasOpacity)) { - glDisable(GL_BLEND); + funcs.glDisable(GL_BLEND); } else { - glEnable(GL_BLEND); + funcs.glEnable(GL_BLEND); } QOpenGLEngineShaderManager::OpacityMode opacityMode; @@ -1159,7 +1157,7 @@ void QOpenGL2PaintEngineExPrivate::composite(const QOpenGLRect& boundingRect) { setCoords(staticVertexCoordinateArray, boundingRect); setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, staticVertexCoordinateArray); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + funcs.glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } // Draws the vertex array as a set of <vertexArrayStops.size()> triangle fans. @@ -1177,7 +1175,7 @@ void QOpenGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stop for (int i=previousStop; i<stop; ++i) qDebug(" %02d: [%.2f, %.2f]", i, vertexArray.data()[i].x, vertexArray.data()[i].y); */ - glDrawArrays(primitive, previousStop, stop - previousStop); + funcs.glDrawArrays(primitive, previousStop, stop - previousStop); previousStop = stop; } } @@ -1269,7 +1267,7 @@ void QOpenGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &p if (opaque) { prepareForDraw(opaque); setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, stroker.vertices()); - glDrawArrays(GL_TRIANGLE_STRIP, 0, stroker.vertexCount() / 2); + funcs.glDrawArrays(GL_TRIANGLE_STRIP, 0, stroker.vertexCount() / 2); // QBrush b(Qt::green); // d->setBrush(&b); @@ -1292,16 +1290,16 @@ void QOpenGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &p fillStencilWithVertexArray(stroker.vertices(), stroker.vertexCount() / 2, 0, 0, bounds, QOpenGL2PaintEngineExPrivate::TriStripStrokeFillMode); - glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); + funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); // Pass when any bit is set, replace stencil value with 0 - glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT); + funcs.glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT); prepareForDraw(false); // Stencil the brush onto the dest buffer composite(bounds); - glStencilMask(0); + funcs.glStencilMask(0); updateClipScissorTest(); } @@ -1336,11 +1334,12 @@ void QOpenGL2PaintEngineEx::renderHintsChanged() #ifndef QT_OPENGL_ES_2 if (!QOpenGLContext::currentContext()->isES()) { + Q_D(QOpenGL2PaintEngineEx); if ((state()->renderHints & QPainter::Antialiasing) || (state()->renderHints & QPainter::HighQualityAntialiasing)) - glEnable(GL_MULTISAMPLE); + d->funcs.glEnable(GL_MULTISAMPLE); else - glDisable(GL_MULTISAMPLE); + d->funcs.glDisable(GL_MULTISAMPLE); } #endif // QT_OPENGL_ES_2 @@ -1461,7 +1460,7 @@ bool QOpenGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, co d->transferMode(ImageDrawingMode); d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - glBindTexture(GL_TEXTURE_2D, textureId); + d->funcs.glBindTexture(GL_TEXTURE_2D, textureId); QOpenGLRect srcRect(src.left(), src.bottom(), src.right(), src.top()); @@ -1720,15 +1719,15 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) if (elementIndicesVBOId == 0) - glGenBuffers(1, &elementIndicesVBOId); + funcs.glGenBuffers(1, &elementIndicesVBOId); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementIndices.size() * sizeof(GLushort), - elementIndices.constData(), GL_STATIC_DRAW); + funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId); + funcs.glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementIndices.size() * sizeof(GLushort), + elementIndices.constData(), GL_STATIC_DRAW); #endif } else { #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId); + funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId); #endif } @@ -1774,8 +1773,8 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly opacityUniformDirty = true; } - glEnable(GL_BLEND); - glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR); + funcs.glEnable(GL_BLEND); + funcs.glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR); funcs.glBlendColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); } else { // Other brush styles need two passes. @@ -1790,17 +1789,17 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly compositionModeDirty = false; // I can handle this myself, thank you very much prepareForCachedGlyphDraw(*cache); - glEnable(GL_BLEND); - glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); + funcs.glEnable(GL_BLEND); + funcs.glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); - glBindTexture(GL_TEXTURE_2D, cache->texture()); + funcs.glBindTexture(GL_TEXTURE_2D, cache->texture()); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) - glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0); + funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0); #else - glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); + funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); #endif shaderManager->setMaskType(QOpenGLEngineShaderManager::SubPixelMaskPass2); @@ -1814,8 +1813,8 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly compositionModeDirty = false; prepareForCachedGlyphDraw(*cache); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE); + funcs.glEnable(GL_BLEND); + funcs.glBlendFunc(GL_ONE, GL_ONE); } compositionModeDirty = true; } else if (glyphFormat == QFontEngine::Format_ARGB) { @@ -1839,27 +1838,27 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); if (lastMaskTextureUsed != cache->texture()) { - glBindTexture(GL_TEXTURE_2D, cache->texture()); + funcs.glBindTexture(GL_TEXTURE_2D, cache->texture()); lastMaskTextureUsed = cache->texture(); } if (cache->filterMode() != filterMode) { if (filterMode == QOpenGLTextureGlyphCache::Linear) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + funcs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + funcs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + funcs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } cache->setFilterMode(filterMode); } } #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) - glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0); + funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); #else - glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); + funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); #endif } @@ -1960,7 +1959,7 @@ void QOpenGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFra shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::PatternColor), col); } - glDrawArrays(GL_TRIANGLES, 0, 6 * fragmentCount); + funcs.glDrawArrays(GL_TRIANGLES, 0, 6 * fragmentCount); } bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev) @@ -2005,15 +2004,15 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev) d->shaderManager = new QOpenGLEngineShaderManager(d->ctx); - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); + d->funcs.glDisable(GL_STENCIL_TEST); + d->funcs.glDisable(GL_DEPTH_TEST); + d->funcs.glDisable(GL_SCISSOR_TEST); d->glyphCacheFormat = QFontEngine::Format_A8; #ifndef QT_OPENGL_ES_2 if (!QOpenGLContext::currentContext()->isES()) { - glDisable(GL_MULTISAMPLE); + d->funcs.glDisable(GL_MULTISAMPLE); d->glyphCacheFormat = QFontEngine::Format_A32; d->multisamplingAlwaysEnabled = false; } else @@ -2071,7 +2070,7 @@ void QOpenGL2PaintEngineEx::ensureActive() d->device->ensureActiveTarget(); d->transferMode(BrushDrawingMode); - glViewport(0, 0, d->width, d->height); + d->funcs.glViewport(0, 0, d->width, d->height); d->needsSync = false; d->lastMaskTextureUsed = 0; d->shaderManager->setDirty(); @@ -2086,11 +2085,11 @@ void QOpenGL2PaintEngineExPrivate::updateClipScissorTest() { Q_Q(QOpenGL2PaintEngineEx); if (q->state()->clipTestEnabled) { - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT); + funcs.glEnable(GL_STENCIL_TEST); + funcs.glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT); } else { - glDisable(GL_STENCIL_TEST); - glStencilFunc(GL_ALWAYS, 0, 0xff); + funcs.glDisable(GL_STENCIL_TEST); + funcs.glStencilFunc(GL_ALWAYS, 0, 0xff); } #ifdef QT_GL_NO_SCISSOR_TEST @@ -2112,9 +2111,9 @@ void QOpenGL2PaintEngineExPrivate::updateClipScissorTest() currentScissorBounds = bounds; if (bounds == QRect(0, 0, width, height)) { - glDisable(GL_SCISSOR_TEST); + funcs.glDisable(GL_SCISSOR_TEST); } else { - glEnable(GL_SCISSOR_TEST); + funcs.glEnable(GL_SCISSOR_TEST); setScissor(bounds); } #endif @@ -2130,7 +2129,7 @@ void QOpenGL2PaintEngineExPrivate::setScissor(const QRect &rect) } const int height = rect.height(); - glScissor(left, bottom, width, height); + funcs.glScissor(left, bottom, width, height); } void QOpenGL2PaintEngineEx::clipEnabledChanged() @@ -2149,10 +2148,10 @@ void QOpenGL2PaintEngineExPrivate::clearClip(uint value) { dirtyStencilRegion -= currentScissorBounds; - glStencilMask(0xff); - glClearStencil(value); - glClear(GL_STENCIL_BUFFER_BIT); - glStencilMask(0x0); + funcs.glStencilMask(0xff); + funcs.glClearStencil(value); + funcs.glClear(GL_STENCIL_BUFFER_BIT); + funcs.glStencilMask(0x0); q->state()->needsClipBufferClear = false; } @@ -2180,15 +2179,15 @@ void QOpenGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, uint value clearClip(1); if (path.isEmpty()) { - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT); + funcs.glEnable(GL_STENCIL_TEST); + funcs.glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT); return; } if (q->state()->clipTestEnabled) - glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT); + funcs.glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT); else - glStencilFunc(GL_ALWAYS, 0, 0xff); + funcs.glStencilFunc(GL_ALWAYS, 0, 0xff); vertexCoordinateArray.clear(); vertexCoordinateArray.addPath(path, inverseScale, false); @@ -2196,39 +2195,39 @@ void QOpenGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, uint value if (!singlePass) fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill()); - glColorMask(false, false, false, false); - glEnable(GL_STENCIL_TEST); + funcs.glColorMask(false, false, false, false); + funcs.glEnable(GL_STENCIL_TEST); useSimpleShader(); if (singlePass) { // Under these conditions we can set the new stencil value in a single // pass, by using the current value and the "new value" as the toggles - glStencilFunc(GL_LEQUAL, referenceClipValue, ~GL_STENCIL_HIGH_BIT); - glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT); - glStencilMask(value ^ referenceClipValue); + funcs.glStencilFunc(GL_LEQUAL, referenceClipValue, ~GL_STENCIL_HIGH_BIT); + funcs.glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT); + funcs.glStencilMask(value ^ referenceClipValue); drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN); } else { - glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); - glStencilMask(0xff); + funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); + funcs.glStencilMask(0xff); if (!q->state()->clipTestEnabled && path.hasWindingFill()) { // Pass when any clip bit is set, set high bit - glStencilFunc(GL_NOTEQUAL, GL_STENCIL_HIGH_BIT, ~GL_STENCIL_HIGH_BIT); + funcs.glStencilFunc(GL_NOTEQUAL, GL_STENCIL_HIGH_BIT, ~GL_STENCIL_HIGH_BIT); composite(vertexCoordinateArray.boundingRect()); } // Pass when high bit is set, replace stencil value with new clip value - glStencilFunc(GL_NOTEQUAL, value, GL_STENCIL_HIGH_BIT); + funcs.glStencilFunc(GL_NOTEQUAL, value, GL_STENCIL_HIGH_BIT); composite(vertexCoordinateArray.boundingRect()); } - glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT); - glStencilMask(0); + funcs.glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT); + funcs.glStencilMask(0); - glColorMask(true, true, true, true); + funcs.glColorMask(true, true, true, true); } void QOpenGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) @@ -2384,7 +2383,7 @@ void QOpenGL2PaintEngineEx::setState(QPainterState *new_state) if (old_state == s || old_state->clipChanged) { if (old_state && old_state != s && old_state->canRestoreClip) { d->updateClipScissorTest(); - glDepthFunc(GL_LEQUAL); + d->funcs.glDepthFunc(GL_LEQUAL); } else { d->regenerateClip(); } diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index 08930b558e..d2429cdd23 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -3035,7 +3035,8 @@ int QOpenGLShaderProgram::maxGeometryOutputVertices() const { GLint n = 0; #if defined(QT_OPENGL_3_2) - glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &n); + Q_D(const QOpenGLShaderProgram); + d->glfuncs->glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &n); #endif return n; } diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 901c564a8b..0266656c1b 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -1633,7 +1633,7 @@ GLuint QOpenGLTexture::boundTextureId(BindingTarget target) } GLint textureId = 0; - glGetIntegerv(target, &textureId); + ctx->functions()->glGetIntegerv(target, &textureId); return static_cast<GLuint>(textureId); } @@ -1653,11 +1653,11 @@ GLuint QOpenGLTexture::boundTextureId(uint unit, BindingTarget target) funcs->initializeOpenGLFunctions(); GLint oldTextureUnit = 0; - glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit); + funcs->glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit); funcs->glActiveTexture(unit); GLint textureId = 0; - glGetIntegerv(target, &textureId); + funcs->glGetIntegerv(target, &textureId); funcs->glActiveTexture(oldTextureUnit); return static_cast<GLuint>(textureId); diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp index b776444347..d52517add2 100644 --- a/src/gui/opengl/qopengltextureblitter.cpp +++ b/src/gui/opengl/qopengltextureblitter.cpp @@ -45,6 +45,7 @@ #include <QtGui/QOpenGLShaderProgram> #include <QtGui/QOpenGLVertexArrayObject> #include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLFunctions> QT_BEGIN_NAMESPACE @@ -120,11 +121,11 @@ class TextureBinder public: TextureBinder(GLuint textureId) { - glBindTexture(GL_TEXTURE_2D, textureId); + QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, textureId); } ~TextureBinder() { - glBindTexture(GL_TEXTURE_2D, 0); + QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, 0); } }; @@ -196,7 +197,7 @@ void QOpenGLTextureBlitterPrivate::blit(GLuint texture, program->setUniformValue(textureTransformUniformPos, textureTransform); textureMatrixUniformState = User; - glDrawArrays(GL_TRIANGLES, 0, 6); + QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLES, 0, 6); } void QOpenGLTextureBlitterPrivate::blit(GLuint texture, @@ -219,7 +220,7 @@ void QOpenGLTextureBlitterPrivate::blit(GLuint texture, textureMatrixUniformState = Identity; } - glDrawArrays(GL_TRIANGLES, 0, 6); + QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLES, 0, 6); } QOpenGLTextureBlitter::QOpenGLTextureBlitter() diff --git a/src/gui/opengl/qopengltexturecache.cpp b/src/gui/opengl/qopengltexturecache.cpp index 750264935b..f4aa29ac0f 100644 --- a/src/gui/opengl/qopengltexturecache.cpp +++ b/src/gui/opengl/qopengltexturecache.cpp @@ -117,7 +117,7 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QPixmap & if (!pixmap.paintingActive()) { QOpenGLCachedTexture *entry = m_cache.object(key); if (entry) { - glBindTexture(GL_TEXTURE_2D, entry->id()); + context->functions()->glBindTexture(GL_TEXTURE_2D, entry->id()); return entry->id(); } } @@ -154,7 +154,7 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &i if (!image.paintingActive()) { QOpenGLCachedTexture *entry = m_cache.object(key); if (entry) { - glBindTexture(GL_TEXTURE_2D, entry->id()); + context->functions()->glBindTexture(GL_TEXTURE_2D, entry->id()); return entry->id(); } } @@ -181,12 +181,13 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &i GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, qint64 key, const QImage &image) { GLuint id; - glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_2D, id); + QOpenGLFunctions *funcs = context->functions(); + funcs->glGenTextures(1, &id); + funcs->glBindTexture(GL_TEXTURE_2D, id); QImage tx = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx.width(), tx.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, const_cast<const QImage &>(tx).bits()); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx.width(), tx.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, const_cast<const QImage &>(tx).bits()); int cost = tx.width() * tx.height() * 4 / 1024; m_cache.insert(key, new QOpenGLCachedTexture(id, context), cost); @@ -210,9 +211,9 @@ void QOpenGLTextureCache::freeResource(QOpenGLContext *) Q_ASSERT(false); // the texture cache lives until the context group disappears } -static void freeTexture(QOpenGLFunctions *, GLuint id) +static void freeTexture(QOpenGLFunctions *funcs, GLuint id) { - glDeleteTextures(1, &id); + funcs->glDeleteTextures(1, &id); } QOpenGLCachedTexture::QOpenGLCachedTexture(GLuint id, QOpenGLContext *context) diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp index 92eb9be80c..5844bf639c 100644 --- a/src/gui/opengl/qopengltextureglyphcache.cpp +++ b/src/gui/opengl/qopengltextureglyphcache.cpp @@ -122,8 +122,9 @@ void QOpenGLTextureGlyphCache::createTextureData(int width, int height) if (!m_textureResource) m_textureResource = new QOpenGLGlyphTexture(ctx); - glGenTextures(1, &m_textureResource->m_texture); - glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); + QOpenGLFunctions *funcs = ctx->functions(); + funcs->glGenTextures(1, &m_textureResource->m_texture); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); m_textureResource->m_width = width; m_textureResource->m_height = height; @@ -132,7 +133,7 @@ void QOpenGLTextureGlyphCache::createTextureData(int width, int height) QVarLengthArray<uchar> data(width * height * 4); for (int i = 0; i < data.size(); ++i) data[i] = 0; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); } else { QVarLengthArray<uchar> data(width * height); for (int i = 0; i < data.size(); ++i) @@ -144,13 +145,13 @@ void QOpenGLTextureGlyphCache::createTextureData(int width, int height) const GLint internalFormat = GL_ALPHA; const GLenum format = GL_ALPHA; #endif - glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, &data[0]); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, &data[0]); } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); m_filterMode = Nearest; if (!m_buffer.isCreated()) { @@ -187,8 +188,9 @@ void QOpenGLTextureGlyphCache::resizeTextureData(int width, int height) return; } + QOpenGLFunctions *funcs = ctx->functions(); GLint oldFbo; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFbo); + funcs->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFbo); int oldWidth = m_textureResource->m_width; int oldHeight = m_textureResource->m_height; @@ -205,44 +207,42 @@ void QOpenGLTextureGlyphCache::resizeTextureData(int width, int height) if (ctx->d_func()->workaround_brokenFBOReadBack) { QImageTextureGlyphCache::resizeTextureData(width, height); Q_ASSERT(image().depth() == 8); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); - glDeleteTextures(1, &oldTexture); + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); + funcs->glDeleteTextures(1, &oldTexture); return; } // ### the QTextureGlyphCache API needs to be reworked to allow // ### resizeTextureData to fail - QOpenGLFunctions funcs(ctx); - - funcs.glBindFramebuffer(GL_FRAMEBUFFER, m_textureResource->m_fbo); + funcs->glBindFramebuffer(GL_FRAMEBUFFER, m_textureResource->m_fbo); GLuint tmp_texture; - glGenTextures(1, &tmp_texture); - glBindTexture(GL_TEXTURE_2D, tmp_texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + funcs->glGenTextures(1, &tmp_texture); + funcs->glBindTexture(GL_TEXTURE_2D, tmp_texture); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); m_filterMode = Nearest; - glBindTexture(GL_TEXTURE_2D, 0); - funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, tmp_texture, 0); + funcs->glBindTexture(GL_TEXTURE_2D, 0); + funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, tmp_texture, 0); - funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - glBindTexture(GL_TEXTURE_2D, oldTexture); + funcs->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); + funcs->glBindTexture(GL_TEXTURE_2D, oldTexture); if (pex != 0) pex->transferMode(BrushDrawingMode); - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); + funcs->glDisable(GL_STENCIL_TEST); + funcs->glDisable(GL_DEPTH_TEST); + funcs->glDisable(GL_SCISSOR_TEST); + funcs->glDisable(GL_BLEND); - glViewport(0, 0, oldWidth, oldHeight); + funcs->glViewport(0, 0, oldWidth, oldHeight); QOpenGLShaderProgram *blitProgram = 0; if (pex == 0) { @@ -301,21 +301,21 @@ void QOpenGLTextureGlyphCache::resizeTextureData(int width, int height) blitProgram->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + funcs->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight); + funcs->glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight); - funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_RENDERBUFFER, 0); - glDeleteTextures(1, &tmp_texture); - glDeleteTextures(1, &oldTexture); + funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, 0); + funcs->glDeleteTextures(1, &tmp_texture); + funcs->glDeleteTextures(1, &oldTexture); - funcs.glBindFramebuffer(GL_FRAMEBUFFER, (GLuint)oldFbo); + funcs->glBindFramebuffer(GL_FRAMEBUFFER, (GLuint)oldFbo); if (pex != 0) { - glViewport(0, 0, pex->width, pex->height); + funcs->glViewport(0, 0, pex->width, pex->height); pex->updateClipScissorTest(); } else { if (m_vao.isCreated()) { @@ -335,15 +335,16 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed return; } + QOpenGLFunctions *funcs = ctx->functions(); if (ctx->d_func()->workaround_brokenFBOReadBack) { QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition); - glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); const QImage &texture = image(); const uchar *bits = texture.constBits(); bits += c.y * texture.bytesPerLine() + c.x; for (int i=0; i<c.h; ++i) { - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits); + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits); bits += texture.bytesPerLine(); } return; @@ -404,7 +405,7 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed } } - glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); if (mask.depth() == 32) { #ifdef QT_OPENGL_ES_2 GLenum fmt = GL_RGBA; @@ -415,7 +416,7 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed #if Q_BYTE_ORDER == Q_BIG_ENDIAN fmt = GL_RGBA; #endif - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, fmt, GL_UNSIGNED_BYTE, mask.bits()); + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, fmt, GL_UNSIGNED_BYTE, mask.bits()); } else { // glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is // not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista @@ -438,7 +439,7 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed #if 0 if (ctx->d_func()->workaround_brokenAlphaTexSubImage) { for (int i = 0; i < maskHeight; ++i) - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i)); + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i)); } else { #endif @@ -447,7 +448,7 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed #else const GLenum format = GL_ALPHA; #endif - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, format, GL_UNSIGNED_BYTE, mask.bits()); + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, format, GL_UNSIGNED_BYTE, mask.bits()); #if 0 } diff --git a/src/gui/opengl/qopengltextureglyphcache_p.h b/src/gui/opengl/qopengltextureglyphcache_p.h index 1e2c031018..5a4a4e4c92 100644 --- a/src/gui/opengl/qopengltextureglyphcache_p.h +++ b/src/gui/opengl/qopengltextureglyphcache_p.h @@ -89,9 +89,9 @@ public: qDebug("~QOpenGLGlyphTexture() %p for context %p.", this, ctx); #endif if (!ctx->d_func()->workaround_brokenFBOReadBack) - QOpenGLFunctions(ctx).glDeleteFramebuffers(1, &m_fbo); + ctx->functions()->glDeleteFramebuffers(1, &m_fbo); if (m_width || m_height) - glDeleteTextures(1, &m_texture); + ctx->functions()->glDeleteTextures(1, &m_texture); } void invalidateResource() diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index b4ea8e4842..4843e93858 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -204,7 +204,8 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i Q_UNUSED(offset); context->makeCurrent(window); - glViewport(0, 0, window->width(), window->height()); + QOpenGLFunctions *funcs = context->functions(); + funcs->glViewport(0, 0, window->width(), window->height()); if (!d_ptr->blitter) { d_ptr->blitter = new QOpenGLTextureBlitter; @@ -216,7 +217,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i QRect windowRect(QPoint(), window->size()); for (int i = 0; i < textures->count(); ++i) { GLuint textureId = textures->textureId(i); - glBindTexture(GL_TEXTURE_2D, textureId); + funcs->glBindTexture(GL_TEXTURE_2D, textureId); QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), windowRect); d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft); @@ -226,15 +227,15 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i if (!textureId) return; - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + funcs->glEnable(GL_BLEND); + funcs->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect); d_ptr->blitter->setSwizzleRB(true); d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); d_ptr->blitter->setSwizzleRB(false); - glDisable(GL_BLEND); + funcs->glDisable(GL_BLEND); d_ptr->blitter->release(); context->swapBuffers(window); } @@ -280,27 +281,29 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion) const if (image.format() != QImage::Format_RGB32 && image.format() != QImage::Format_RGBA8888) image = image.convertToFormat(QImage::Format_RGBA8888); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + if (resized) { if (d_ptr->textureId) - glDeleteTextures(1, &d_ptr->textureId); - glGenTextures(1, &d_ptr->textureId); - glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); + funcs->glDeleteTextures(1, &d_ptr->textureId); + funcs->glGenTextures(1, &d_ptr->textureId); + funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); #ifndef QT_OPENGL_ES_2 if (!QOpenGLContext::currentContext()->isES()) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); } #endif - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, - const_cast<uchar*>(image.constBits())); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, + const_cast<uchar*>(image.constBits())); d_ptr->textureSize = imageSize; } else { - glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); + funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); QRect imageRect = image.rect(); QRect rect = dirtyRegion.boundingRect() & imageRect; // if the rect is wide enough it's cheaper to just @@ -314,11 +317,11 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion) const // OpenGL instead of copying, since there's no gap between scanlines if (rect.width() == imageRect.width()) { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, - image.constScanLine(rect.y())); + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + image.constScanLine(rect.y())); } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, - image.copy(rect).constBits()); + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + image.copy(rect).constBits()); } } diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index a5f81a9df8..e05c03d952 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -44,6 +44,7 @@ #include <QtWidgets/private/qwidget_p.h> #include <QOpenGLFramebufferObject> +#include <QOpenGLFunctions> #include <QWindow> #include <qpa/qplatformwindow.h> #include <QDebug> @@ -144,9 +145,10 @@ void QOpenGLWidget::paintGL() void QOpenGLWidget::updateGL() { + Q_D(QOpenGLWidget); makeCurrent(); paintGL(); - glFlush(); + d->context.functions()->glFlush(); doneCurrent(); update(); } @@ -163,15 +165,16 @@ void QOpenGLWidget::resizeEvent(QResizeEvent *) delete d->fbo; // recreate when resized d->fbo = new QOpenGLFramebufferObject(size()); d->fbo->bind(); - glBindTexture(GL_TEXTURE_2D, d->fbo->texture()); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + QOpenGLFunctions *funcs = d->context.functions(); + funcs->glBindTexture(GL_TEXTURE_2D, d->fbo->texture()); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); resizeGL(width(), height()); paintGL(); - glFlush(); + funcs->glFlush(); } void QOpenGLWidget::paintEvent(QPaintEvent *) |