From 882bf3475c8926abe62ed71e6719458b024caac0 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 13 Jan 2014 15:48:44 +0100 Subject: expand tabs and related whitespace fixes in *.{cpp,h,qdoc} the diff -w for this commit is empty. Started-by: Thiago Macieira Change-Id: I77bb84e71c63ce75e0709e5b94bee18e3ce6ab9e Reviewed-by: Thiago Macieira --- src/opengl/qglframebufferobject.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/opengl') diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index fa3f653aee..ae50366fc7 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -979,7 +979,7 @@ bool QGLFramebufferObject::isValid() const bool QGLFramebufferObject::bind() { if (!isValid()) - return false; + return false; Q_D(QGLFramebufferObject); QGL_FUNC_CONTEXT; if (!ctx) @@ -1011,7 +1011,7 @@ bool QGLFramebufferObject::bind() bool QGLFramebufferObject::release() { if (!isValid()) - return false; + return false; Q_D(QGLFramebufferObject); QGL_FUNC_CONTEXT; if (!ctx) -- cgit v1.2.3 From 8a9bd001c947e6888d37e99fc456339fd2b51b36 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 17 Jan 2014 10:31:27 +0200 Subject: Support multiple native surfaces on Android. Support for multiple native surfaces is needed by applications that need to mix raster windows with GL windows. Rework the raster and opengl implementation, get rid of eglfs and fbconvenience dependencies. Create a single android platform plugin. [ChangeLog][Android] Rework the raster and opengl implementation. [ChangeLog][Android] Create a single android platform plugin. Task-number: QTBUG-34650 Change-Id: I9b1ab51554823329dda8cfbf8fef27c38f917c7b Reviewed-by: Paul Olav Tvete --- src/opengl/opengl.pro | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/opengl') diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index b01ca80829..4d9208d983 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -8,9 +8,6 @@ irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused QMAKE_DOCS = $$PWD/doc/qtopengl.qdocconf -ANDROID_LIB_DEPENDENCY_REPLACEMENTS = \ - "plugins/platforms/android/libqtforandroid.so:plugins/platforms/android/libqtforandroidGL.so" - load(qt_module) contains(QT_CONFIG, opengl):CONFIG += opengl -- cgit v1.2.3 From a7b8ef08415b8056661c3db5950842ee546891b9 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 29 Jan 2014 11:41:31 +0100 Subject: Export optimized premultiply and unpremultiply methods This patch optimizes the unpremultiply method further by using a lookup table to avoid any divisions at all. The opportunity is taken to export both premultiply and unpremultiply since they are commonly used methods relevant to the exported QRgb type that can be both premultiplied and unpremultipled ARGB. [ChangeLog][QtGui][QColor] Exported highly optimized methods for premultiply and unpremultiply of QRgb values. Change-Id: I658bcf57b0bc73c34c1765b64617d43b63ae820b Reviewed-by: Thiago Macieira Reviewed-by: Gunnar Sletta --- src/opengl/gl2paintengineex/qglgradientcache.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/opengl') diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp index e0df4ccdf6..6160554472 100644 --- a/src/opengl/gl2paintengineex/qglgradientcache.cpp +++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp @@ -184,7 +184,7 @@ void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, ui uint current_color = ARGB_COMBINE_ALPHA(colors[0], alpha); qreal incr = 1.0 / qreal(size); qreal fpos = 1.5 * incr; - colorTable[pos++] = qtToGlColor(PREMUL(current_color)); + colorTable[pos++] = qtToGlColor(qPremultiply(current_color)); while (fpos <= s.first().first) { colorTable[pos] = colorTable[pos - 1]; @@ -193,13 +193,13 @@ void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, ui } if (colorInterpolation) - current_color = PREMUL(current_color); + current_color = qPremultiply(current_color); for (int i = 0; i < s.size() - 1; ++i) { qreal delta = 1/(s[i+1].first - s[i].first); uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha); if (colorInterpolation) - next_color = PREMUL(next_color); + next_color = qPremultiply(next_color); while (fpos < s[i+1].first && pos < size) { int dist = int(256 * ((fpos - s[i].first) * delta)); @@ -207,7 +207,7 @@ void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, ui if (colorInterpolation) colorTable[pos] = qtToGlColor(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)); else - colorTable[pos] = qtToGlColor(PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist))); + colorTable[pos] = qtToGlColor(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist))); ++pos; fpos += incr; } @@ -216,7 +216,7 @@ void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, ui Q_ASSERT(s.size() > 0); - uint last_color = qtToGlColor(PREMUL(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha))); + uint last_color = qtToGlColor(qPremultiply(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha))); for (;pos < size; ++pos) colorTable[pos] = last_color; -- cgit v1.2.3 From 97c187da3c1381bc55dd16976bf9fb3c773d0047 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 27 Jan 2014 14:45:11 +0100 Subject: Dynamic GL switch on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The patch introduces a new build configuration on Windows which can be requested by passing -opengl dynamic to configure. Platforms other than Windows (including WinRT) are not affected. The existing Angle and desktop configurations are not affected. These continue to function as before and Angle remains the default. In the future, when all modules have added support for the dynamic path, as described below, the default configuration could be changed to be the dynamic one. This would allow providing a single set of binaries in the official builds instead of the current two. When requesting dynamic GL, Angle is built but QT_OPENGL_ES[_2] are never defined. Instead, the code path that has traditionally been desktop GL only becomes the dynamic path that has to do runtime checks. Qt modules and applications are not linked to opengl32.dll or libegl/glesv2.dll in this case. Instead, QtGui exports all necessary egl/egl/gl functions which will, under the hood, forward all requests to a dynamically loaded EGL/WGL/GL implementation. Porting guide (better said, changes needed to prepare your code to work with dynamic GL builds when the fallback to Angle is utilized): 1. In !QT_OPENGL_ES[_2] code branches use QOpenGLFunctions::isES() to differentiate between desktop and ES where needed. Keep in mind that it is the desktop GL header (plus qopenglext.h) that is included, not the GLES one. QtGui's proxy will handle some differences, for example calling glClearDepth will route to glClearDepthf when needed. The built-in eglGetProcAddress is able to retrieve pointers for standard GLES2 functions too so code resolving OpenGL 2 functions will function in any case. 2. QT_CONFIG will contain "opengl" and "dynamicgl" in dynamic builds, but never "angle" or "opengles2". 3. The preprocessor define QT_OPENGL_DYNAMIC is also available in dynamic builds. The usage of this is strongly discouraged and should not be needed anywhere except for QtGui and the platform plugin. 4. Code in need of the library handle can use QOpenGLFunctions::platformGLHandle(). The decision on which library to load is currently based on a simple test that creates a dummy window/context and tries to resolve an OpenGL 2 function. If this fails, it goes for Angle. This seems to work well on Win7 PCs for example that do not have proper graphics drivers providing OpenGL installed but are D3D9 capable using the default drivers. Setting QT_OPENGL to desktop or angle skips the test and forces usage of the given GL. There are also two new application attributes that could be used for the same purpose. If Angle is requested but the libraries are not present, desktop is tried. If desktop is requested, or if angle is requested but nothing works, the EGL/WGL functions will still be callable but will return 0. This conveniently means that eglInitialize() and such will report a failure. Debug messages can be enabled by setting QT_OPENGLPROXY_DEBUG. This will tell which implementation is chosen. The textures example application is ported to OpenGL 2, the GL 1 code path is removed. [ChangeLog][QtGui] Qt builds on Windows can now be configured for dynamic loading of the OpenGL implementation. This can be requested by passing -opengl dynamic to configure. In this mode no modules will link to opengl32.dll or Angle's libegl/libglesv2. Instead, QtGui will dynamically choose between desktop and Angle during the first GL/EGL/WGL call. This allows deploying applications with a single set of Qt libraries with the ability of transparently falling back to Angle in case the opengl32.dll is not suitable, due to missing graphics drivers for example. Task-number: QTBUG-36483 Change-Id: I716fdebbf60b355b7d9ef57d1e069eef366b4ab9 Reviewed-by: Friedemann Kleint Reviewed-by: Jørgen Lind --- .../gl2paintengineex/qglengineshadermanager.cpp | 5 +- .../gl2paintengineex/qglengineshadersource_p.h | 8 +- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 88 ++-- .../gl2paintengineex/qtextureglyphcache_gl.cpp | 21 +- src/opengl/qgl.cpp | 466 +++++++++++---------- src/opengl/qgl_qpa.cpp | 26 +- src/opengl/qglbuffer.cpp | 16 +- src/opengl/qglframebufferobject.cpp | 83 +++- src/opengl/qglframebufferobject.h | 12 +- src/opengl/qglframebufferobject_p.h | 12 +- src/opengl/qglfunctions.cpp | 174 ++++---- src/opengl/qglfunctions.h | 1 + src/opengl/qglpixelbuffer.cpp | 9 +- src/opengl/qglshaderprogram.cpp | 33 +- 14 files changed, 518 insertions(+), 436 deletions(-) (limited to 'src/opengl') diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index a89d37bc5d..394eb99307 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -163,7 +163,10 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) code[NonPremultipliedImageSrcFragmentShader] = qglslNonPremultipliedImageSrcFragmentShader; code[CustomImageSrcFragmentShader] = qglslCustomSrcFragmentShader; // Calls "customShader", which must be appended code[SolidBrushSrcFragmentShader] = qglslSolidBrushSrcFragmentShader; - code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader; + if (!QOpenGLFunctions::isES()) + code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_desktop; + else + code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_ES; code[TextureBrushSrcWithPatternFragmentShader] = qglslTextureBrushSrcWithPatternFragmentShader; code[PatternBrushSrcFragmentShader] = qglslPatternBrushSrcFragmentShader; code[LinearGradientBrushSrcFragmentShader] = qglslLinearGradientBrushSrcFragmentShader; diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index 05d923ca17..90bd7edf54 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -305,25 +305,23 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\n\ static const char* const qglslAffinePositionWithTextureBrushVertexShader = qglslPositionWithTextureBrushVertexShader; -#if defined(QT_OPENGL_ES_2) // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead, // we emulate GL_REPEAT by only taking the fractional part of the texture coords. // TODO: Special case POT textures which don't need this emulation -static const char* const qglslTextureBrushSrcFragmentShader = "\n\ +static const char* const qglslTextureBrushSrcFragmentShader_ES = "\n\ varying highp vec2 brushTextureCoords; \n\ uniform sampler2D brushTexture; \n\ lowp vec4 srcPixel() { \n\ return texture2D(brushTexture, fract(brushTextureCoords)); \n\ }\n"; -#else -static const char* const qglslTextureBrushSrcFragmentShader = "\n\ + +static const char* const qglslTextureBrushSrcFragmentShader_desktop = "\n\ varying highp vec2 brushTextureCoords; \n\ uniform sampler2D brushTexture; \n\ lowp vec4 srcPixel() \n\ { \n\ return texture2D(brushTexture, brushTextureCoords); \n\ }\n"; -#endif static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\ varying highp vec2 brushTextureCoords; \n\ diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 3b29923586..32dd7be7ba 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -539,33 +539,35 @@ void QGL2PaintEngineEx::beginNativePainting() d->funcs.glDisableVertexAttribArray(i); #ifndef QT_OPENGL_ES_2 - const QGLContext *ctx = d->ctx; - const QGLFormat &fmt = d->device->format(); - if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1) - || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->contextHandle()->hasExtension(QByteArrayLiteral("GL_ARB_compatibility"))) - || fmt.profile() == QGLFormat::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] = + if (!QOpenGLFunctions::isES()) { + const QGLContext *ctx = d->ctx; + const QGLFormat &fmt = d->device->format(); + if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1) + || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->contextHandle()->hasExtension(QByteArrayLiteral("GL_ARB_compatibility"))) + || fmt.profile() == QGLFormat::CompatibilityProfile) { - { 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]); + // 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 @@ -595,9 +597,11 @@ void QGL2PaintEngineExPrivate::resetGLState() ctx->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false); ctx->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); #ifndef QT_OPENGL_ES_2 - // gl_Color, corresponding to vertex attribute 3, may have been changed - float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - funcs.glVertexAttrib4fv(3, color); + if (!QOpenGLFunctions::isES()) { + // gl_Color, corresponding to vertex attribute 3, may have been changed + float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + funcs.glVertexAttrib4fv(3, color); + } #endif } @@ -1352,11 +1356,13 @@ void QGL2PaintEngineEx::renderHintsChanged() state()->renderHintsChanged = true; #if !defined(QT_OPENGL_ES_2) - if ((state()->renderHints & QPainter::Antialiasing) - || (state()->renderHints & QPainter::HighQualityAntialiasing)) - glEnable(GL_MULTISAMPLE); - else - glDisable(GL_MULTISAMPLE); + if (!QOpenGLFunctions::isES()) { + if ((state()->renderHints & QPainter::Antialiasing) + || (state()->renderHints & QPainter::HighQualityAntialiasing)) + glEnable(GL_MULTISAMPLE); + else + glDisable(GL_MULTISAMPLE); + } #endif Q_D(QGL2PaintEngineEx); @@ -2027,21 +2033,23 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) glDisable(GL_SCISSOR_TEST); #if !defined(QT_OPENGL_ES_2) - glDisable(GL_MULTISAMPLE); + if (!QOpenGLFunctions::isES()) + glDisable(GL_MULTISAMPLE); #endif d->glyphCacheType = QFontEngineGlyphCache::Raster_A8; #if !defined(QT_OPENGL_ES_2) + if (!QOpenGLFunctions::isES()) { d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask; -#endif - -#if defined(QT_OPENGL_ES_2) + d->multisamplingAlwaysEnabled = false; + } else { + d->multisamplingAlwaysEnabled = d->device->format().sampleBuffers(); + } +#else // OpenGL ES can't switch MSAA off, so if the gl paint device is // multisampled, it's always multisampled. d->multisamplingAlwaysEnabled = d->device->format().sampleBuffers(); -#else - d->multisamplingAlwaysEnabled = false; #endif return true; diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index d96ab36e2b..d506b7e4b9 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -319,23 +319,24 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub uchar g = src[x] >> 8; uchar b = src[x]; quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding. -#if defined(QT_OPENGL_ES_2) - // swizzle the bits to accommodate for the GL_RGBA upload. - src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16); -#else - src[x] = (src[x] & 0x00ffffff) | (avg << 24); -#endif + if (QOpenGLFunctions::isES()) { + // swizzle the bits to accommodate for the GL_RGBA upload. + src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16); + } else { + src[x] = (src[x] & 0x00ffffff) | (avg << 24); + } } } } glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); if (mask.format() == QImage::Format_RGB32) { -#if defined(QT_OPENGL_ES_2) - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_RGBA, GL_UNSIGNED_BYTE, mask.bits()); -#else - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits()); + GLenum format = GL_RGBA; +#if !defined(QT_OPENGL_ES_2) + if (!QOpenGLFunctions::isES()) + format = GL_BGRA; #endif + glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, format, 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 diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 40a8b1921c..e027de02e0 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1699,10 +1699,12 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp return QImage(); int w = size.width(); int h = size.height(); -#if !defined(QT_OPENGL_ES_2) - //### glGetTexImage not in GL ES 2.0, need to do something else here! - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); -#endif +#ifndef QT_OPENGL_ES + if (!QOpenGLFunctions::isES()) { + //### glGetTexImage not in GL ES 2.0, need to do something else here! + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); + } +#endif // QT_OPENGL_ES convertFromGLImage(img, w, h, alpha_format, include_alpha); return img; } @@ -2282,17 +2284,20 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G glBindTexture(target, tx_id); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filtering); -#if defined(QT_OPENGL_ES_2) - bool genMipmap = false; -#endif + bool genMipmap = !QOpenGLFunctions::isES(); if (glFormat.directRendering() && (qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::GenerateMipmap)) && target == GL_TEXTURE_2D && (options & QGLContext::MipmapBindOption)) { #if !defined(QT_OPENGL_ES_2) - glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); - glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); + if (genMipmap) { + glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); + glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); + } else { + glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); + genMipmap = true; + } #else glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); genMipmap = true; @@ -2421,11 +2426,11 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G printf(" - did byte swapping (%d ms)\n", time.elapsed()); #endif } -#ifdef QT_OPENGL_ES - // OpenGL/ES requires that the internal and external formats be - // identical. - internalFormat = externalFormat; -#endif + if (QOpenGLFunctions::isES()) { + // OpenGL/ES requires that the internal and external formats be + // identical. + internalFormat = externalFormat; + } #ifdef QGL_BIND_TEXTURE_DEBUG printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n", img.format(), externalFormat, internalFormat, pixel_type); @@ -2434,10 +2439,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G const QImage &constRef = img; // to avoid detach in bits()... glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat, pixel_type, constRef.bits()); -#if defined(QT_OPENGL_ES_2) - if (genMipmap) - glGenerateMipmap(target); -#endif + if (genMipmap && QOpenGLFunctions::isES()) + functions->glGenerateMipmap(target); #ifndef QT_NO_DEBUG GLenum error = glGetError(); if (error != GL_NO_ERROR) { @@ -2518,31 +2521,32 @@ int QGLContextPrivate::maxTextureSize() glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); -#if defined(QT_OPENGL_ES) - return max_texture_size; -#else - 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); - if (size == 0) { - return max_texture_size; - } - do { - size = next; - next = size * 2; +#ifndef QT_OPENGL_ES + if (!QOpenGLFunctions::isES()) { + GLenum proxy = GL_PROXY_TEXTURE_2D; - if (next > max_texture_size) - break; + 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, &next); - } while (next > size); + glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); + if (size == 0) { + return max_texture_size; + } + do { + size = next; + next = size * 2; - max_texture_size = size; - return max_texture_size; + 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); + } while (next > size); + + max_texture_size = size; + } #endif + + return max_texture_size; } /*! @@ -2696,7 +2700,7 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex Q_UNUSED(textureHeight); Q_UNUSED(textureTarget); #else - if (textureTarget != GL_TEXTURE_2D) { + if (textureTarget != GL_TEXTURE_2D && !QOpenGLFunctions::isES()) { if (textureWidth == -1 || textureHeight == -1) { glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); @@ -2763,35 +2767,38 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text #endif #ifndef QT_OPENGL_ES_2 + if (!QOpenGLFunctions::isES()) { #ifdef QT_OPENGL_ES - if (textureTarget != GL_TEXTURE_2D) { - qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES"); - return; - } + if (textureTarget != GL_TEXTURE_2D) { + qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES"); + return; + } #else - const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); - GLint oldTexture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); + const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); + GLint oldTexture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); #endif - glEnable(textureTarget); - glBindTexture(textureTarget, textureId); + glEnable(textureTarget); + glBindTexture(textureTarget, textureId); - qDrawTextureRect(target, -1, -1, textureTarget); + qDrawTextureRect(target, -1, -1, textureTarget); #ifdef QT_OPENGL_ES - glDisable(textureTarget); -#else - if (!wasEnabled) glDisable(textureTarget); - glBindTexture(textureTarget, oldTexture); +#else + if (!wasEnabled) + glDisable(textureTarget); + glBindTexture(textureTarget, oldTexture); #endif + return; + } #else Q_UNUSED(target); Q_UNUSED(textureId); Q_UNUSED(textureTarget); - qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine"); #endif + qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine"); } /*! @@ -2821,40 +2828,42 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text Q_UNUSED(point); Q_UNUSED(textureId); Q_UNUSED(textureTarget); - qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead"); #else - - const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); - GLint oldTexture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); - - glEnable(textureTarget); - glBindTexture(textureTarget, textureId); - - GLint textureWidth; - GLint textureHeight; - - glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); - glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); - - if (d_ptr->active_engine && - d_ptr->active_engine->type() == QPaintEngine::OpenGL2) { - QGL2PaintEngineEx *eng = static_cast(d_ptr->active_engine); - if (!eng->isNativePaintingActive()) { - QRectF dest(point, QSizeF(textureWidth, textureHeight)); - QRectF src(0, 0, textureWidth, textureHeight); - QSize size(textureWidth, textureHeight); - if (eng->drawTexture(dest, textureId, size, src)) - return; + if (!QOpenGLFunctions::isES()) { + const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); + GLint oldTexture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); + + glEnable(textureTarget); + glBindTexture(textureTarget, textureId); + + GLint textureWidth; + GLint textureHeight; + + glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); + glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); + + if (d_ptr->active_engine && + d_ptr->active_engine->type() == QPaintEngine::OpenGL2) { + QGL2PaintEngineEx *eng = static_cast(d_ptr->active_engine); + if (!eng->isNativePaintingActive()) { + QRectF dest(point, QSizeF(textureWidth, textureHeight)); + QRectF src(0, 0, textureWidth, textureHeight); + QSize size(textureWidth, textureHeight); + if (eng->drawTexture(dest, textureId, size, src)) + return; + } } - } - qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget); + qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget); - if (!wasEnabled) - glDisable(textureTarget); - glBindTexture(textureTarget, oldTexture); + if (!wasEnabled) + glDisable(textureTarget); + glBindTexture(textureTarget, oldTexture); + return; + } #endif + qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead"); } /*! @@ -4163,7 +4172,7 @@ void QGLWidget::glDraw() return; makeCurrent(); #ifndef QT_OPENGL_ES - if (d->glcx->deviceIsPixmap()) + if (d->glcx->deviceIsPixmap() && !QOpenGLFunctions::isES()) glDrawBuffer(GL_FRONT); #endif QSize readback_target_size = d->glcx->d_ptr->readback_target_size; @@ -4206,18 +4215,20 @@ void QGLWidget::qglColor(const QColor& c) const #ifdef QT_OPENGL_ES glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF()); #else - Q_D(const QGLWidget); - const QGLContext *ctx = QGLContext::currentContext(); - if (ctx) { - if (ctx->format().rgba()) - glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF()); - else if (!d->cmap.isEmpty()) { // QGLColormap in use? - int i = d->cmap.find(c.rgb()); - if (i < 0) - i = d->cmap.findNearest(c.rgb()); - glIndexi(i); - } else - glIndexi(ctx->colorIndex(c)); + if (!QOpenGLFunctions::isES()) { + Q_D(const QGLWidget); + const QGLContext *ctx = QGLContext::currentContext(); + if (ctx) { + if (ctx->format().rgba()) + glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF()); + else if (!d->cmap.isEmpty()) { // QGLColormap in use? + int i = d->cmap.find(c.rgb()); + if (i < 0) + i = d->cmap.findNearest(c.rgb()); + glIndexi(i); + } else + glIndexi(ctx->colorIndex(c)); + } } #endif //QT_OPENGL_ES #else @@ -4238,18 +4249,23 @@ void QGLWidget::qglClearColor(const QColor& c) const #ifdef QT_OPENGL_ES glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); #else - Q_D(const QGLWidget); - const QGLContext *ctx = QGLContext::currentContext(); - if (ctx) { - if (ctx->format().rgba()) - glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); - else if (!d->cmap.isEmpty()) { // QGLColormap in use? - int i = d->cmap.find(c.rgb()); - if (i < 0) - i = d->cmap.findNearest(c.rgb()); - glClearIndex(i); - } else - glClearIndex(ctx->colorIndex(c)); + if (!QOpenGLFunctions::isES()) { + Q_D(const QGLWidget); + const QGLContext *ctx = QGLContext::currentContext(); + if (ctx) { + if (ctx->format().rgba()) + glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); + else if (!d->cmap.isEmpty()) { // QGLColormap in use? + int i = d->cmap.find(c.rgb()); + if (i < 0) + i = d->cmap.findNearest(c.rgb()); + glClearIndex(i); + } else { + glClearIndex(ctx->colorIndex(c)); + } + } + } else { + glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); } #endif } @@ -4411,72 +4427,75 @@ static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str, void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font) { #ifndef QT_OPENGL_ES - Q_D(QGLWidget); - if (str.isEmpty() || !isValid()) - return; - - GLint view[4]; - bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST); - if (!use_scissor_testing) - glGetIntegerv(GL_VIEWPORT, &view[0]); - int width = d->glcx->device()->width(); - int height = d->glcx->device()->height(); - bool auto_swap = autoBufferSwap(); - - QPaintEngine *engine = paintEngine(); - - qt_save_gl_state(); - - QPainter *p; - bool reuse_painter = false; - if (engine->isActive()) { - reuse_painter = true; - p = engine->painter(); + if (!QOpenGLFunctions::isES()) { + Q_D(QGLWidget); + if (str.isEmpty() || !isValid()) + return; + + GLint view[4]; + bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST); + if (!use_scissor_testing) + glGetIntegerv(GL_VIEWPORT, &view[0]); + int width = d->glcx->device()->width(); + int height = d->glcx->device()->height(); + bool auto_swap = autoBufferSwap(); + + QPaintEngine *engine = paintEngine(); + + qt_save_gl_state(); + + QPainter *p; + bool reuse_painter = false; + if (engine->isActive()) { + reuse_painter = true; + p = engine->painter(); + + glDisable(GL_DEPTH_TEST); + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, width, height, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); + + glLoadIdentity(); + } else { + setAutoBufferSwap(false); + // disable glClear() as a result of QPainter::begin() + d->disable_clear_on_painter_begin = true; + p = new QPainter(this); + } - glDisable(GL_DEPTH_TEST); - glViewport(0, 0, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, width, height, 0, 0, 1); - glMatrixMode(GL_MODELVIEW); + QRect viewport(view[0], view[1], view[2], view[3]); + if (!use_scissor_testing && viewport != rect()) { + // if the user hasn't set a scissor box, we set one that + // covers the current viewport + glScissor(view[0], view[1], view[2], view[3]); + glEnable(GL_SCISSOR_TEST); + } else if (use_scissor_testing) { + // use the scissor box set by the user + glEnable(GL_SCISSOR_TEST); + } - glLoadIdentity(); - } else { - setAutoBufferSwap(false); - // disable glClear() as a result of QPainter::begin() - d->disable_clear_on_painter_begin = true; - p = new QPainter(this); - } + qt_gl_draw_text(p, x, y, str, font); - QRect viewport(view[0], view[1], view[2], view[3]); - if (!use_scissor_testing && viewport != rect()) { - // if the user hasn't set a scissor box, we set one that - // covers the current viewport - glScissor(view[0], view[1], view[2], view[3]); - glEnable(GL_SCISSOR_TEST); - } else if (use_scissor_testing) { - // use the scissor box set by the user - glEnable(GL_SCISSOR_TEST); - } + if (!reuse_painter) { + p->end(); + delete p; + setAutoBufferSwap(auto_swap); + d->disable_clear_on_painter_begin = false; + } - qt_gl_draw_text(p, x, y, str, font); + qt_restore_gl_state(); - if (!reuse_painter) { - p->end(); - delete p; - setAutoBufferSwap(auto_swap); - d->disable_clear_on_painter_begin = false; + return; } - - qt_restore_gl_state(); - #else // QT_OPENGL_ES Q_UNUSED(x); Q_UNUSED(y); Q_UNUSED(str); Q_UNUSED(font); - qWarning("QGLWidget::renderText is not supported under OpenGL/ES"); #endif + qWarning("QGLWidget::renderText is not supported under OpenGL/ES"); } /*! \overload @@ -4503,80 +4522,83 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font) void QGLWidget::renderText(double x, double y, double z, const QString &str, const QFont &font) { #ifndef QT_OPENGL_ES - Q_D(QGLWidget); - if (str.isEmpty() || !isValid()) - return; + if (!QOpenGLFunctions::isES()) { + Q_D(QGLWidget); + if (str.isEmpty() || !isValid()) + return; + + bool auto_swap = autoBufferSwap(); + + int width = d->glcx->device()->width(); + int height = d->glcx->device()->height(); + GLdouble model[4 * 4], proj[4 * 4]; + GLint view[4]; + glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]); + glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]); + glGetIntegerv(GL_VIEWPORT, &view[0]); + GLdouble win_x = 0, win_y = 0, win_z = 0; + qgluProject(x, y, z, &model[0], &proj[0], &view[0], + &win_x, &win_y, &win_z); + win_y = height - win_y; // y is inverted - bool auto_swap = autoBufferSwap(); + QPaintEngine *engine = paintEngine(); - int width = d->glcx->device()->width(); - int height = d->glcx->device()->height(); - GLdouble model[4 * 4], proj[4 * 4]; - GLint view[4]; - glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]); - glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]); - glGetIntegerv(GL_VIEWPORT, &view[0]); - GLdouble win_x = 0, win_y = 0, win_z = 0; - qgluProject(x, y, z, &model[0], &proj[0], &view[0], - &win_x, &win_y, &win_z); - win_y = height - win_y; // y is inverted + QPainter *p; + bool reuse_painter = false; + bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST); + bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST); - QPaintEngine *engine = paintEngine(); + qt_save_gl_state(); - QPainter *p; - bool reuse_painter = false; - bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST); - bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST); + if (engine->isActive()) { + reuse_painter = true; + p = engine->painter(); + } else { + setAutoBufferSwap(false); + // disable glClear() as a result of QPainter::begin() + d->disable_clear_on_painter_begin = true; + p = new QPainter(this); + } - qt_save_gl_state(); + QRect viewport(view[0], view[1], view[2], view[3]); + if (!use_scissor_testing && viewport != rect()) { + glScissor(view[0], view[1], view[2], view[3]); + glEnable(GL_SCISSOR_TEST); + } else if (use_scissor_testing) { + glEnable(GL_SCISSOR_TEST); + } + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glViewport(0, 0, width, height); + glOrtho(0, width, height, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glAlphaFunc(GL_GREATER, 0.0); + glEnable(GL_ALPHA_TEST); + if (use_depth_testing) + glEnable(GL_DEPTH_TEST); + glTranslated(0, 0, -win_z); + qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font); + + if (!reuse_painter) { + p->end(); + delete p; + setAutoBufferSwap(auto_swap); + d->disable_clear_on_painter_begin = false; + } - if (engine->isActive()) { - reuse_painter = true; - p = engine->painter(); - } else { - setAutoBufferSwap(false); - // disable glClear() as a result of QPainter::begin() - d->disable_clear_on_painter_begin = true; - p = new QPainter(this); - } + qt_restore_gl_state(); - QRect viewport(view[0], view[1], view[2], view[3]); - if (!use_scissor_testing && viewport != rect()) { - glScissor(view[0], view[1], view[2], view[3]); - glEnable(GL_SCISSOR_TEST); - } else if (use_scissor_testing) { - glEnable(GL_SCISSOR_TEST); - } - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glViewport(0, 0, width, height); - glOrtho(0, width, height, 0, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glAlphaFunc(GL_GREATER, 0.0); - glEnable(GL_ALPHA_TEST); - if (use_depth_testing) - glEnable(GL_DEPTH_TEST); - glTranslated(0, 0, -win_z); - qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font); - - if (!reuse_painter) { - p->end(); - delete p; - setAutoBufferSwap(auto_swap); - d->disable_clear_on_painter_begin = false; + return; } - - qt_restore_gl_state(); - #else // QT_OPENGL_ES Q_UNUSED(x); Q_UNUSED(y); Q_UNUSED(z); Q_UNUSED(str); Q_UNUSED(font); - qWarning("QGLWidget::renderText is not supported under OpenGL/ES"); #endif + qWarning("QGLWidget::renderText is not supported under OpenGL/ES"); } QGLFormat QGLWidget::format() const diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 8b66c891bb..4f4df8d2e4 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -321,21 +321,23 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) d->context = new QOpenGLContext; #if !defined(QT_OPENGL_ES) - // On desktop, request latest released version - QSurfaceFormat format; + if (!QOpenGLFunctions::isES()) { + // On desktop, request latest released version + QSurfaceFormat format; #if defined(Q_OS_MAC) - // OS X is limited to OpenGL 3.2 Core Profile at present - // so set that here. If we use compatibility profile it - // only reports 2.x contexts. - format.setMajorVersion(3); - format.setMinorVersion(2); - format.setProfile(QSurfaceFormat::CoreProfile); + // OS X is limited to OpenGL 3.2 Core Profile at present + // so set that here. If we use compatibility profile it + // only reports 2.x contexts. + format.setMajorVersion(3); + format.setMinorVersion(2); + format.setProfile(QSurfaceFormat::CoreProfile); #else - format.setMajorVersion(4); - format.setMinorVersion(3); -#endif - d->context->setFormat(format); + format.setMajorVersion(4); + format.setMinorVersion(3); #endif + d->context->setFormat(format); + } +#endif // QT_OPENGL_ES d->context->create(); d->context->makeCurrent(d->window); } diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp index 1c9545990f..5491bad628 100644 --- a/src/opengl/qglbuffer.cpp +++ b/src/opengl/qglbuffer.cpp @@ -344,18 +344,20 @@ void QGLBuffer::destroy() bool QGLBuffer::read(int offset, void *data, int count) { #if !defined(QT_OPENGL_ES) - Q_D(QGLBuffer); - if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id()) - return false; - while (glGetError() != GL_NO_ERROR) ; // Clear error state. - d->funcs->glGetBufferSubData(d->type, offset, count, data); - return glGetError() == GL_NO_ERROR; + if (QOpenGLFunctions::platformGLType() != QOpenGLFunctions::GLES1) { + Q_D(QGLBuffer); + if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id()) + return false; + while (glGetError() != GL_NO_ERROR) ; // Clear error state. + d->funcs->glGetBufferSubData(d->type, offset, count, data); + return glGetError() == GL_NO_ERROR; + } #else Q_UNUSED(offset); Q_UNUSED(data); Q_UNUSED(count); - return false; #endif + return false; } /*! diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 66e1aca9bc..b4821ccf61 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -373,8 +373,11 @@ void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f, GLenum format = f->format().internalTextureFormat(); reqAlpha = (format != GL_RGB -#ifndef QT_OPENGL_ES - && format != GL_RGB5 && format != GL_RGB8 +#ifdef GL_RGB5 + && format != GL_RGB5 +#endif +#ifdef GL_RGB8 + && format != GL_RGB8 #endif ); } @@ -592,8 +595,17 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, GL_DEPTH_COMPONENT16, size.width(), size.height()); } #else - funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_DEPTH_COMPONENT, size.width(), size.height()); + if (QOpenGLFunctions::isES()) { + if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) + funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, + GL_DEPTH_COMPONENT24, size.width(), size.height()); + else + funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, + GL_DEPTH_COMPONENT16, size.width(), size.height()); + } else { + funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, + GL_DEPTH_COMPONENT, size.width(), size.height()); + } #endif } else { #ifdef QT_OPENGL_ES @@ -605,7 +617,17 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, size.width(), size.height()); } #else - funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height()); + if (QOpenGLFunctions::isES()) { + if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) { + funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, + size.width(), size.height()); + } else { + funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, + size.width(), size.height()); + } + } else { + funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height()); + } #endif } funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, @@ -621,23 +643,18 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, funcs.glGenRenderbuffers(1, &stencil_buffer); funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer); Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer)); - if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) { -#ifdef QT_OPENGL_ES - funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_STENCIL_INDEX8, size.width(), size.height()); -#else - funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_STENCIL_INDEX, size.width(), size.height()); -#endif - } else { + #ifdef QT_OPENGL_ES - funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, - size.width(), size.height()); + GLenum storage = GL_STENCIL_INDEX8; #else - funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX, - size.width(), size.height()); + GLenum storage = QOpenGLFunctions::isES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX; #endif - } + + if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) + funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height()); + else + funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height()); + funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil_buffer); valid = checkFramebufferStatus(); @@ -830,7 +847,13 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target) : d_ptr(new QGLFramebufferObjectPrivate) { Q_D(QGLFramebufferObject); - d->init(this, size, NoAttachment, target, DEFAULT_FORMAT); + d->init(this, size, NoAttachment, target, +#ifndef QT_OPENGL_ES_2 + QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8 +#else + GL_RGBA +#endif + ); } /*! \overload @@ -844,7 +867,13 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target) : d_ptr(new QGLFramebufferObjectPrivate) { Q_D(QGLFramebufferObject); - d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT); + d->init(this, QSize(width, height), NoAttachment, target, +#ifndef QT_OPENGL_ES_2 + QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8 +#else + GL_RGBA +#endif + ); } /*! \overload @@ -893,6 +922,12 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment att : d_ptr(new QGLFramebufferObjectPrivate) { Q_D(QGLFramebufferObject); + if (!internal_format) +#ifdef QT_OPENGL_ES_2 + internal_format = GL_RGBA; +#else + internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8; +#endif d->init(this, QSize(width, height), attachment, target, internal_format); } @@ -914,6 +949,12 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm : d_ptr(new QGLFramebufferObjectPrivate) { Q_D(QGLFramebufferObject); + if (!internal_format) +#ifdef QT_OPENGL_ES_2 + internal_format = GL_RGBA; +#else + internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8; +#endif d->init(this, size, attachment, target, internal_format); } diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h index 9312a23822..affa47cac7 100644 --- a/src/opengl/qglframebufferobject.h +++ b/src/opengl/qglframebufferobject.h @@ -63,17 +63,11 @@ public: QGLFramebufferObject(const QSize &size, GLenum target = GL_TEXTURE_2D); QGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D); -#if !defined(QT_OPENGL_ES) || defined(Q_QDOC) - QGLFramebufferObject(const QSize &size, Attachment attachment, - GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8); - QGLFramebufferObject(int width, int height, Attachment attachment, - GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8); -#else + QGLFramebufferObject(const QSize &size, Attachment attachment, - GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA); + GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0); QGLFramebufferObject(int width, int height, Attachment attachment, - GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA); -#endif + GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0); QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format); QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format); diff --git a/src/opengl/qglframebufferobject_p.h b/src/opengl/qglframebufferobject_p.h index 0f1128e8f6..3b36c5c2b6 100644 --- a/src/opengl/qglframebufferobject_p.h +++ b/src/opengl/qglframebufferobject_p.h @@ -60,12 +60,6 @@ QT_BEGIN_NAMESPACE -#ifndef QT_OPENGL_ES -#define DEFAULT_FORMAT GL_RGBA8 -#else -#define DEFAULT_FORMAT GL_RGBA -#endif - class QGLFramebufferObjectFormatPrivate { public: @@ -74,9 +68,13 @@ public: samples(0), attachment(QGLFramebufferObject::NoAttachment), target(GL_TEXTURE_2D), - internal_format(DEFAULT_FORMAT), mipmap(false) { +#ifndef QT_OPENGL_ES_2 + internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8; +#else + internal_format = GL_RGBA; +#endif } QGLFramebufferObjectFormatPrivate (const QGLFramebufferObjectFormatPrivate *other) diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp index 2e8caa30f6..e75f9cf915 100644 --- a/src/opengl/qglfunctions.cpp +++ b/src/opengl/qglfunctions.cpp @@ -213,94 +213,94 @@ QGLFunctions::QGLFunctions(const QGLContext *context) static int qt_gl_resolve_features() { -#if defined(QT_OPENGL_ES_2) - int features = QGLFunctions::Multitexture | - QGLFunctions::Shaders | - QGLFunctions::Buffers | - QGLFunctions::Framebuffers | - QGLFunctions::BlendColor | - QGLFunctions::BlendEquation | - QGLFunctions::BlendEquationSeparate | - QGLFunctions::BlendFuncSeparate | - QGLFunctions::BlendSubtract | - QGLFunctions::CompressedTextures | - QGLFunctions::Multisample | - QGLFunctions::StencilSeparate; - QOpenGLExtensionMatcher extensions; - if (extensions.match("GL_OES_texture_npot")) - features |= QGLFunctions::NPOTTextures; - if (extensions.match("GL_IMG_texture_npot")) - features |= QGLFunctions::NPOTTextures; - return features; -#elif defined(QT_OPENGL_ES) - int features = QGLFunctions::Multitexture | - QGLFunctions::Buffers | - QGLFunctions::CompressedTextures | - QGLFunctions::Multisample; - QOpenGLExtensionMatcher extensions; - if (extensions.match("GL_OES_framebuffer_object")) - features |= QGLFunctions::Framebuffers; - if (extensions.match("GL_OES_blend_equation_separate")) - features |= QGLFunctions::BlendEquationSeparate; - if (extensions.match("GL_OES_blend_func_separate")) - features |= QGLFunctions::BlendFuncSeparate; - if (extensions.match("GL_OES_blend_subtract")) - features |= QGLFunctions::BlendSubtract; - if (extensions.match("GL_OES_texture_npot")) - features |= QGLFunctions::NPOTTextures; - if (extensions.match("GL_IMG_texture_npot")) - features |= QGLFunctions::NPOTTextures; - return features; -#else - int features = 0; - QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags(); - QOpenGLExtensionMatcher extensions; - - // Recognize features by extension name. - if (extensions.match("GL_ARB_multitexture")) - features |= QGLFunctions::Multitexture; - if (extensions.match("GL_ARB_shader_objects")) - features |= QGLFunctions::Shaders; - if (extensions.match("GL_EXT_framebuffer_object") || + if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES2) { + int features = QGLFunctions::Multitexture | + QGLFunctions::Shaders | + QGLFunctions::Buffers | + QGLFunctions::Framebuffers | + QGLFunctions::BlendColor | + QGLFunctions::BlendEquation | + QGLFunctions::BlendEquationSeparate | + QGLFunctions::BlendFuncSeparate | + QGLFunctions::BlendSubtract | + QGLFunctions::CompressedTextures | + QGLFunctions::Multisample | + QGLFunctions::StencilSeparate; + QOpenGLExtensionMatcher extensions; + if (extensions.match("GL_OES_texture_npot")) + features |= QGLFunctions::NPOTTextures; + if (extensions.match("GL_IMG_texture_npot")) + features |= QGLFunctions::NPOTTextures; + return features; + } if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES1) { + int features = QGLFunctions::Multitexture | + QGLFunctions::Buffers | + QGLFunctions::CompressedTextures | + QGLFunctions::Multisample; + QOpenGLExtensionMatcher extensions; + if (extensions.match("GL_OES_framebuffer_object")) + features |= QGLFunctions::Framebuffers; + if (extensions.match("GL_OES_blend_equation_separate")) + features |= QGLFunctions::BlendEquationSeparate; + if (extensions.match("GL_OES_blend_func_separate")) + features |= QGLFunctions::BlendFuncSeparate; + if (extensions.match("GL_OES_blend_subtract")) + features |= QGLFunctions::BlendSubtract; + if (extensions.match("GL_OES_texture_npot")) + features |= QGLFunctions::NPOTTextures; + if (extensions.match("GL_IMG_texture_npot")) + features |= QGLFunctions::NPOTTextures; + return features; + } else { + int features = 0; + QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags(); + QOpenGLExtensionMatcher extensions; + + // Recognize features by extension name. + if (extensions.match("GL_ARB_multitexture")) + features |= QGLFunctions::Multitexture; + if (extensions.match("GL_ARB_shader_objects")) + features |= QGLFunctions::Shaders; + if (extensions.match("GL_EXT_framebuffer_object") || extensions.match("GL_ARB_framebuffer_object")) - features |= QGLFunctions::Framebuffers; - if (extensions.match("GL_EXT_blend_color")) - features |= QGLFunctions::BlendColor; - if (extensions.match("GL_EXT_blend_equation_separate")) - features |= QGLFunctions::BlendEquationSeparate; - if (extensions.match("GL_EXT_blend_func_separate")) - features |= QGLFunctions::BlendFuncSeparate; - if (extensions.match("GL_EXT_blend_subtract")) - features |= QGLFunctions::BlendSubtract; - if (extensions.match("GL_ARB_texture_compression")) - features |= QGLFunctions::CompressedTextures; - if (extensions.match("GL_ARB_multisample")) - features |= QGLFunctions::Multisample; - if (extensions.match("GL_ARB_texture_non_power_of_two")) - features |= QGLFunctions::NPOTTextures; - - // Recognize features by minimum OpenGL version. - if (versions & QGLFormat::OpenGL_Version_1_2) { - features |= QGLFunctions::BlendColor | - QGLFunctions::BlendEquation; - } - if (versions & QGLFormat::OpenGL_Version_1_3) { - features |= QGLFunctions::Multitexture | - QGLFunctions::CompressedTextures | - QGLFunctions::Multisample; - } - if (versions & QGLFormat::OpenGL_Version_1_4) - features |= QGLFunctions::BlendFuncSeparate; - if (versions & QGLFormat::OpenGL_Version_1_5) - features |= QGLFunctions::Buffers; - if (versions & QGLFormat::OpenGL_Version_2_0) { - features |= QGLFunctions::Shaders | - QGLFunctions::StencilSeparate | - QGLFunctions::BlendEquationSeparate | - QGLFunctions::NPOTTextures; - } - return features; -#endif + features |= QGLFunctions::Framebuffers; + if (extensions.match("GL_EXT_blend_color")) + features |= QGLFunctions::BlendColor; + if (extensions.match("GL_EXT_blend_equation_separate")) + features |= QGLFunctions::BlendEquationSeparate; + if (extensions.match("GL_EXT_blend_func_separate")) + features |= QGLFunctions::BlendFuncSeparate; + if (extensions.match("GL_EXT_blend_subtract")) + features |= QGLFunctions::BlendSubtract; + if (extensions.match("GL_ARB_texture_compression")) + features |= QGLFunctions::CompressedTextures; + if (extensions.match("GL_ARB_multisample")) + features |= QGLFunctions::Multisample; + if (extensions.match("GL_ARB_texture_non_power_of_two")) + features |= QGLFunctions::NPOTTextures; + + // Recognize features by minimum OpenGL version. + if (versions & QGLFormat::OpenGL_Version_1_2) { + features |= QGLFunctions::BlendColor | + QGLFunctions::BlendEquation; + } + if (versions & QGLFormat::OpenGL_Version_1_3) { + features |= QGLFunctions::Multitexture | + QGLFunctions::CompressedTextures | + QGLFunctions::Multisample; + } + if (versions & QGLFormat::OpenGL_Version_1_4) + features |= QGLFunctions::BlendFuncSeparate; + if (versions & QGLFormat::OpenGL_Version_1_5) + features |= QGLFunctions::Buffers; + if (versions & QGLFormat::OpenGL_Version_2_0) { + features |= QGLFunctions::Shaders | + QGLFunctions::StencilSeparate | + QGLFunctions::BlendEquationSeparate | + QGLFunctions::NPOTTextures; + } + return features; + } } /*! diff --git a/src/opengl/qglfunctions.h b/src/opengl/qglfunctions.h index fd867d7a91..7fc7966a09 100644 --- a/src/opengl/qglfunctions.h +++ b/src/opengl/qglfunctions.h @@ -51,6 +51,7 @@ #include #include +#include QT_BEGIN_NAMESPACE diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index ebc9f296eb..51e7648d72 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -361,7 +361,8 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const glBindTexture(GL_TEXTURE_2D, texture_id); #ifndef QT_OPENGL_ES - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, d->req_size.width(), d->req_size.height(), 0); + GLenum format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8; + glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0); #else glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0); #endif @@ -487,7 +488,8 @@ GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target) { Q_D(QGLPixelBuffer); #ifndef QT_OPENGL_ES - return d->qctx->bindTexture(image, target, GLint(GL_RGBA8)); + GLenum format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8; + return d->qctx->bindTexture(image, target, GLint(format)); #else return d->qctx->bindTexture(image, target, GL_RGBA); #endif @@ -505,7 +507,8 @@ GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target) { Q_D(QGLPixelBuffer); #ifndef QT_OPENGL_ES - return d->qctx->bindTexture(pixmap, target, GLint(GL_RGBA8)); + GLenum format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8; + return d->qctx->bindTexture(pixmap, target, GLint(format)); #else return d->qctx->bindTexture(pixmap, target, GL_RGBA); #endif diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 84e4c26ed1..6b8d38ef42 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -47,6 +47,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -246,7 +247,8 @@ bool QGLShaderPrivate::create() if (shaderType == QGLShader::Vertex) shader = glfuncs->glCreateShader(GL_VERTEX_SHADER); #if !defined(QT_OPENGL_ES_2) - else if (shaderType == QGLShader::Geometry) + else if (shaderType == QGLShader::Geometry + && !QOpenGLFunctions::isES()) shader = glfuncs->glCreateShader(GL_GEOMETRY_SHADER_EXT); #endif else @@ -428,11 +430,14 @@ bool QGLShader::compileSourceCode(const char *source) srclen.append(GLint(headerLen)); } #ifdef QGL_DEFINE_QUALIFIERS - src.append(qualifierDefines); - srclen.append(GLint(sizeof(qualifierDefines) - 1)); + if (!QOpenGLFunctions::isES()) { + src.append(qualifierDefines); + srclen.append(GLint(sizeof(qualifierDefines) - 1)); + } #endif #ifdef QGL_REDEFINE_HIGHP - if (d->shaderType == Fragment) { + if (d->shaderType == Fragment + && QOpenGLFunctions::isES()) { src.append(redefineHighp); srclen.append(GLint(sizeof(redefineHighp) - 1)); } @@ -562,13 +567,15 @@ public: void initializeGeometryShaderFunctions() { - QOpenGLContext *context = QOpenGLContext::currentContext(); - glProgramParameteri = (type_glProgramParameteri) - context->getProcAddress("glProgramParameteri"); - - if (!glProgramParameteri) { + if (!QOpenGLFunctions::isES()) { + QOpenGLContext *context = QOpenGLContext::currentContext(); glProgramParameteri = (type_glProgramParameteri) - context->getProcAddress("glProgramParameteriEXT"); + context->getProcAddress("glProgramParameteri"); + + if (!glProgramParameteri) { + glProgramParameteri = (type_glProgramParameteri) + context->getProcAddress("glProgramParameteriEXT"); + } } } @@ -929,7 +936,8 @@ bool QGLShaderProgram::link() #if !defined(QT_OPENGL_ES_2) // Set up the geometry shader parameters - if (d->glfuncs->glProgramParameteri) { + if (!QOpenGLFunctions::isES() + && d->glfuncs->glProgramParameteri) { foreach (QGLShader *shader, d->shaders) { if (shader->shaderType() & QGLShader::Geometry) { d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_INPUT_TYPE_EXT, @@ -3060,7 +3068,8 @@ int QGLShaderProgram::maxGeometryOutputVertices() const { GLint n = 0; #if !defined(QT_OPENGL_ES_2) - glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n); + if (!QOpenGLFunctions::isES()) + glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n); #endif return n; } -- cgit v1.2.3