src/opengl/qgl.cpp
changeset 18 2f34d5167611
parent 3 41300fa6a67c
child 19 fcece45ef507
--- a/src/opengl/qgl.cpp	Tue Feb 02 00:43:10 2010 +0200
+++ b/src/opengl/qgl.cpp	Fri Apr 16 15:50:13 2010 +0300
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
 **
@@ -104,6 +104,10 @@
 QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs;
 #endif
 
+#ifdef Q_WS_X11
+extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
+#endif
+
 struct QGLThreadContext {
     QGLContext *context;
 };
@@ -124,9 +128,6 @@
 };
 Q_GLOBAL_STATIC(QGLDefaultOverlayFormat, defaultOverlayFormatInstance)
 
-QGLExtensions::Extensions QGLExtensions::glExtensions = 0;
-bool QGLExtensions::nvidiaFboNeedsFinish = false;
-
 Q_GLOBAL_STATIC(QGLSignalProxy, theSignalProxy)
 QGLSignalProxy *QGLSignalProxy::instance()
 {
@@ -154,11 +155,9 @@
         // falling back to the GL 1 engine..
         static bool mac_x1600_check_done = false;
         if (!mac_x1600_check_done) {
-            QGLWidget *tmp = 0;
-            if (!QGLContext::currentContext()) {
-                tmp = new QGLWidget();
-                tmp->makeCurrent();
-            }
+            QGLTemporaryContext *tmp = 0;
+            if (!QGLContext::currentContext())
+                tmp = new QGLTemporaryContext();
             if (strstr((char *) glGetString(GL_RENDERER), "X1600"))
                 engineType = QPaintEngine::OpenGL;
             if (tmp)
@@ -178,7 +177,7 @@
             // from an old GL 1.1 server to a GL 2.x client. In that case we can't
             // use GL 2.0.
             if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
-                && (QGLExtensions::glExtensions & QGLExtensions::FragmentShader)
+                && (QGLExtensions::glExtensions() & QGLExtensions::FragmentShader)
                 && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty())
                 engineType = QPaintEngine::OpenGL2;
             else
@@ -1250,7 +1249,7 @@
     static bool cachedDefault = false;
     static OpenGLVersionFlags defaultVersionFlags = OpenGL_Version_None;
     QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext());
-    QGLWidget *dummy = 0;
+    QGLTemporaryContext *tmpContext = 0;
 
     if (currentCtx && currentCtx->d_func()->version_flags_cached)
         return currentCtx->d_func()->version_flags;
@@ -1261,8 +1260,7 @@
         } else {
             if (!hasOpenGL())
                 return defaultVersionFlags;
-            dummy = new QGLWidget;
-            dummy->makeCurrent(); // glGetString() needs a current context
+            tmpContext = new QGLTemporaryContext;
             cachedDefault = true;
         }
     }
@@ -1273,9 +1271,9 @@
         currentCtx->d_func()->version_flags_cached = true;
         currentCtx->d_func()->version_flags = versionFlags;
     }
-    if (dummy) {
+    if (tmpContext) {
         defaultVersionFlags = versionFlags;
-        delete dummy;
+        delete tmpContext;
     }
 
     return versionFlags;
@@ -1436,6 +1434,18 @@
         m_guards = guard->m_next;
 }
 
+const QGLContext *qt_gl_transfer_context(const QGLContext *ctx)
+{
+    if (!ctx)
+        return 0;
+    QList<const QGLContext *> shares
+        (QGLContextPrivate::contextGroup(ctx)->shares());
+    if (shares.size() >= 2)
+        return (ctx == shares.at(0)) ? shares.at(1) : shares.at(0);
+    else
+        return 0;
+}
+
 QGLContextPrivate::~QGLContextPrivate()
 {
     if (!group->m_refs.deref()) {
@@ -1481,9 +1491,13 @@
     max_texture_size = -1;
     version_flags_cached = false;
     version_flags = QGLFormat::OpenGL_Version_None;
+    extension_flags_cached = false;
+    extension_flags = 0;
     current_fbo = 0;
     default_fbo = 0;
     active_engine = 0;
+    for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
+        vertexAttributeArraysEnabledState[i] = false;
 }
 
 QGLContext* QGLContext::currentCtx = 0;
@@ -1541,7 +1555,7 @@
 
 QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha)
 {
-    QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32);
+    QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
     int w = size.width();
     int h = size.height();
 #if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
@@ -1580,22 +1594,18 @@
     Q_ASSERT(qt_gl_texture_cache == 0);
     qt_gl_texture_cache = this;
 
-    QImagePixmapCleanupHooks::instance()->addPixmapModificationHook(cleanupTextures);
-#ifdef Q_WS_X11
-    QImagePixmapCleanupHooks::instance()->addPixmapDestructionHook(cleanupPixmapSurfaces);
-#endif
-    QImagePixmapCleanupHooks::instance()->addImageHook(imageCleanupHook);
+    QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTexturesForPixampData);
+    QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction);
+    QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey);
 }
 
 QGLTextureCache::~QGLTextureCache()
 {
     qt_gl_texture_cache = 0;
 
-    QImagePixmapCleanupHooks::instance()->removePixmapModificationHook(cleanupTextures);
-#ifdef Q_WS_X11
-    QImagePixmapCleanupHooks::instance()->removePixmapDestructionHook(cleanupPixmapSurfaces);
-#endif
-    QImagePixmapCleanupHooks::instance()->removeImageHook(imageCleanupHook);
+    QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData);
+    QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction);
+    QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
 }
 
 void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, int cost)
@@ -1651,41 +1661,33 @@
   a hook that removes textures from the cache when a pixmap/image
   is deref'ed
 */
-void QGLTextureCache::imageCleanupHook(qint64 cacheKey)
-{
-    // ### remove when the GL texture cache becomes thread-safe
-    if (qApp->thread() != QThread::currentThread())
-        return;
-    QGLTexture *texture = instance()->getTexture(cacheKey);
-    if (texture && texture->options & QGLContext::MemoryManagedBindOption)
-        instance()->remove(cacheKey);
-}
-
-
-void QGLTextureCache::cleanupTextures(QPixmap* pixmap)
+void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey)
 {
     // ### remove when the GL texture cache becomes thread-safe
     if (qApp->thread() == QThread::currentThread()) {
-        const qint64 cacheKey = pixmap->cacheKey();
-        QGLTexture *texture = instance()->getTexture(cacheKey);
-        if (texture && texture->options & QGLContext::MemoryManagedBindOption)
-            instance()->remove(cacheKey);
+        instance()->remove(cacheKey);
+        Q_ASSERT(instance()->getTexture(cacheKey) == 0);
     }
 }
 
+
+void QGLTextureCache::cleanupTexturesForPixampData(QPixmapData* pmd)
+{
+    cleanupTexturesForCacheKey(pmd->cacheKey());
+}
+
+void QGLTextureCache::cleanupBeforePixmapDestruction(QPixmapData* pmd)
+{
+    // Remove any bound textures first:
+    cleanupTexturesForPixampData(pmd);
+
 #if defined(Q_WS_X11)
-void QGLTextureCache::cleanupPixmapSurfaces(QPixmap* pixmap)
-{
-    // Remove any bound textures first:
-    cleanupTextures(pixmap);
-
-    QPixmapData *pd = pixmap->data_ptr().data();
-    if (pd->classId() == QPixmapData::X11Class) {
-        Q_ASSERT(pd->ref == 1); // Make sure reference counting isn't broken
-        QGLContextPrivate::destroyGlSurfaceForPixmap(pd);
+    if (pmd->classId() == QPixmapData::X11Class) {
+        Q_ASSERT(pmd->ref == 0); // Make sure reference counting isn't broken
+        QGLContextPrivate::destroyGlSurfaceForPixmap(pmd);
     }
-}
 #endif
+}
 
 void QGLTextureCache::deleteIfEmpty()
 {
@@ -1729,12 +1731,6 @@
 #define GL_GENERATE_MIPMAP_HINT_SGIS  0x8192
 #endif
 
-Q_GLOBAL_STATIC(QGLShareRegister, _qgl_share_reg)
-Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg()
-{
-    return _qgl_share_reg();
-}
-
 /*!
     \class QGLContext
     \brief The QGLContext class encapsulates an OpenGL rendering context.
@@ -1874,6 +1870,35 @@
 {
 }
 
+#define ctx q_ptr
+void QGLContextPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled)
+{
+    Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT);
+    Q_ASSERT(glEnableVertexAttribArray);
+
+    if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled)
+        glDisableVertexAttribArray(arrayIndex);
+
+    if (!vertexAttributeArraysEnabledState[arrayIndex] && enabled)
+        glEnableVertexAttribArray(arrayIndex);
+
+    vertexAttributeArraysEnabledState[arrayIndex] = enabled;
+}
+
+void QGLContextPrivate::syncGlState()
+{
+    Q_ASSERT(glEnableVertexAttribArray);
+    for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) {
+        if (vertexAttributeArraysEnabledState[i])
+            glEnableVertexAttribArray(i);
+        else
+            glDisableVertexAttribArray(i);
+    }
+
+}
+#undef ctx
+
+
 /*!
     \overload
 
@@ -2055,8 +2080,9 @@
     // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null
     Q_ASSERT(texture);
 
-    if (texture->id > 0)
-        QImagePixmapCleanupHooks::enableCleanupHooks(image);
+    // Enable the cleanup hooks for this image so that the texture cache entry is removed when the
+    // image gets deleted:
+    QImagePixmapCleanupHooks::enableCleanupHooks(image);
 
     return texture;
 }
@@ -2110,7 +2136,8 @@
     int tx_h = qt_next_power_of_two(image.height());
 
     QImage img = image;
-    if (!(QGLExtensions::glExtensions & QGLExtensions::NPOTTextures)
+
+    if (!(QGLExtensions::glExtensions() & QGLExtensions::NPOTTextures)
         && !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0)
         && (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height())))
     {
@@ -2132,7 +2159,7 @@
     bool genMipmap = false;
 #endif
     if (glFormat.directRendering()
-        && (QGLExtensions::glExtensions & QGLExtensions::GenerateMipmap)
+        && (QGLExtensions::glExtensions() & QGLExtensions::GenerateMipmap)
         && target == GL_TEXTURE_2D
         && (options & QGLContext::MipmapBindOption))
     {
@@ -2160,9 +2187,12 @@
     bool premul = options & QGLContext::PremultipliedAlphaBindOption;
     GLenum externalFormat;
     GLuint pixel_type;
-    if (QGLExtensions::glExtensions & QGLExtensions::BGRATextureFormat) {
+    if (QGLExtensions::glExtensions() & QGLExtensions::BGRATextureFormat) {
         externalFormat = GL_BGRA;
-        pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+        if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2)
+            pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+        else
+            pixel_type = GL_UNSIGNED_BYTE;
     } else {
         externalFormat = GL_RGBA;
         pixel_type = GL_UNSIGNED_BYTE;
@@ -2241,12 +2271,9 @@
         qgl_byteSwapImage(img, pixel_type);
     }
 #ifdef QT_OPENGL_ES
-    // OpenGL/ES requires that the internal and external formats be identical.
-    // This is typically used to convert GL_RGBA into GL_BGRA.
-    // Also, we need to use GL_UNSIGNED_BYTE when the format is GL_BGRA.
+    // OpenGL/ES requires that the internal and external formats be
+    // identical.
     internalFormat = externalFormat;
-    if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV)
-        pixel_type = GL_UNSIGNED_BYTE;
 #endif
 #ifdef QGL_BIND_TEXTURE_DEBUG
     printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n",
@@ -2278,6 +2305,7 @@
     int cost = img.width()*img.height()*4/1024;
     QGLTexture *texture = new QGLTexture(q, tx_id, target, options);
     QGLTextureCache::instance()->insert(q, key, texture, cost);
+
     return texture;
 }
 
@@ -2322,7 +2350,10 @@
 
 #if defined(Q_WS_X11)
     // Try to use texture_from_pixmap
-    if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType) {
+    const QX11Info *xinfo = qt_x11Info(paintDevice);
+    if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType
+        && xinfo && xinfo->screen() == pixmap.x11Info().screen())
+    {
         texture = bindTextureFromNativePixmap(pd, key, options);
         if (texture) {
             texture->options |= QGLContext::MemoryManagedBindOption;
@@ -2391,7 +2422,7 @@
         return 0;
 
     Q_D(QGLContext);
-    QGLTexture *texture = d->bindTexture(image, target, format, false, DefaultBindOption);
+    QGLTexture *texture = d->bindTexture(image, target, format, DefaultBindOption);
     return texture->id;
 }
 
@@ -2531,11 +2562,13 @@
     for (int i = 0; i < ddsKeys.size(); ++i) {
         GLuint texture = dds_cache->value(ddsKeys.at(i));
         if (id == texture) {
-            glDeleteTextures(1, &texture);
             dds_cache->remove(ddsKeys.at(i));
-            return;
+            break;
         }
     }
+
+    // Finally, actually delete the texture ID
+    glDeleteTextures(1, &id);
 }
 
 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
@@ -2954,7 +2987,7 @@
         wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer();
     }
     if (d->sharing)  // ok, we managed to share
-        qgl_share_reg()->addShare(this, shareContext);
+        QGLContextGroup::addShare(this, shareContext);
     return d->valid;
 }
 
@@ -4360,6 +4393,13 @@
    \note This function temporarily disables depth-testing when the
    text is drawn.
 
+   \note This function can only be used inside a
+   QPainter::beginNativePainting()/QPainter::endNativePainting() block
+   if the default OpenGL paint engine is QPaintEngine::OpenGL. To make
+   QPaintEngine::OpenGL the default GL engine, call
+   QGL::setPreferredPaintEngine(QPaintEngine::OpenGL) before the
+   QApplication constructor.
+
    \l{Overpainting Example}{Overpaint} with QPainter::drawText() instead.
 */
 
@@ -4378,9 +4418,18 @@
     int height = d->glcx->device()->height();
     bool auto_swap = autoBufferSwap();
 
+    QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
+
     QPaintEngine *engine = paintEngine();
-    if (engine->type() == QPaintEngine::OpenGL2)
-        static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(true);
+    if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
+        qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
+                 " active on the same device is not allowed.");
+        return;
+    }
+
+    // this changes what paintEngine() returns
+    qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
+    engine = paintEngine();
     QPainter *p;
     bool reuse_painter = false;
     if (engine->isActive()) {
@@ -4400,11 +4449,6 @@
         setAutoBufferSwap(false);
         // disable glClear() as a result of QPainter::begin()
         d->disable_clear_on_painter_begin = true;
-        if (engine->type() == QPaintEngine::OpenGL2) {
-            qt_save_gl_state();
-            glMatrixMode(GL_MODELVIEW);
-            glLoadIdentity();
-        }
         p = new QPainter(this);
     }
 
@@ -4428,11 +4472,8 @@
         delete p;
         setAutoBufferSwap(auto_swap);
         d->disable_clear_on_painter_begin = false;
-        if (engine->type() == QPaintEngine::OpenGL2)
-            qt_restore_gl_state();
     }
-    if (engine->type() == QPaintEngine::OpenGL2)
-        static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(false);
+    qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
 #else // QT_OPENGL_ES
     Q_UNUSED(x);
     Q_UNUSED(y);
@@ -4480,9 +4521,18 @@
                 &win_x, &win_y, &win_z);
     win_y = height - win_y; // y is inverted
 
+    QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
     QPaintEngine *engine = paintEngine();
-    if (engine->type() == QPaintEngine::OpenGL2)
-        static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(true);
+
+    if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
+        qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
+                 " active on the same device is not allowed.");
+        return;
+    }
+
+    // this changes what paintEngine() returns
+    qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
+    engine = paintEngine();
     QPainter *p;
     bool reuse_painter = false;
     bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
@@ -4496,8 +4546,6 @@
         setAutoBufferSwap(false);
         // disable glClear() as a result of QPainter::begin()
         d->disable_clear_on_painter_begin = true;
-        if (engine->type() == QPaintEngine::OpenGL2)
-            qt_save_gl_state();
         p = new QPainter(this);
     }
 
@@ -4526,13 +4574,10 @@
     } else {
         p->end();
         delete p;
-        if (engine->type() == QPaintEngine::OpenGL2)
-            qt_restore_gl_state();
         setAutoBufferSwap(auto_swap);
         d->disable_clear_on_painter_begin = false;
     }
-    if (engine->type() == QPaintEngine::OpenGL2)
-        static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(false);
+    qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
 #else // QT_OPENGL_ES
     Q_UNUSED(x);
     Q_UNUSED(y);
@@ -4844,9 +4889,13 @@
 
 #endif // QT3_SUPPORT
 
-void QGLExtensions::init_extensions()
+/*
+    Returns the GL extensions for the current context.
+*/
+QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
 {
     QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
+    Extensions glExtensions;
 
     if (extensions.match("GL_ARB_texture_rectangle"))
         glExtensions |= TextureRectangle;
@@ -4907,6 +4956,46 @@
 
     if (extensions.match("GL_EXT_bgra"))
         glExtensions |= BGRATextureFormat;
+
+    return glExtensions;
+}
+
+/*
+    Returns the GL extensions for the current QGLContext. If there is no
+    current QGLContext, a default context will be created and the extensions
+    for that context will be returned instead.
+*/
+QGLExtensions::Extensions QGLExtensions::glExtensions()
+{
+    QGLTemporaryContext *tmpContext = 0;
+    static bool cachedDefault = false;
+    static Extensions defaultExtensions = 0;
+    QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext());
+
+    if (currentCtx && currentCtx->d_func()->extension_flags_cached)
+        return currentCtx->d_func()->extension_flags;
+
+    if (!currentCtx) {
+        if (cachedDefault) {
+            return defaultExtensions;
+        } else {
+            tmpContext = new QGLTemporaryContext;
+            cachedDefault = true;
+        }
+    }
+
+    Extensions extensionFlags = currentContextExtensions();
+    if (currentCtx) {
+        currentCtx->d_func()->extension_flags_cached = true;
+        currentCtx->d_func()->extension_flags = extensionFlags;
+    } else {
+        defaultExtensions = extensionFlags;
+    }
+
+    if (tmpContext)
+        delete tmpContext;
+
+    return extensionFlags;
 }
 
 /*
@@ -4918,7 +5007,6 @@
 
     glDevice.setWidget(q);
 
-    QGLExtensions::init();
     glcx = 0;
     autoSwap = true;
 
@@ -4928,8 +5016,6 @@
 
     if (!glcx)
         glcx = new QGLContext(QGLFormat::defaultFormat(), q);
-
-    q->setAttribute(Qt::WA_NoSystemBackground);
 }
 
 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
@@ -4953,7 +5039,7 @@
 }
 #endif
 
-void QGLShareRegister::addShare(const QGLContext *context, const QGLContext *share) {
+void QGLContextGroup::addShare(const QGLContext *context, const QGLContext *share) {
     Q_ASSERT(context && share);
     if (context->d_ptr->group == share->d_ptr->group)
         return;
@@ -4974,11 +5060,7 @@
     group->m_shares.append(context);
 }
 
-QList<const QGLContext *> QGLShareRegister::shares(const QGLContext *context) {
-    return context->d_ptr->group->m_shares;
-}
-
-void QGLShareRegister::removeShare(const QGLContext *context) {
+void QGLContextGroup::removeShare(const QGLContext *context) {
     // Remove the context from the group.
     QGLContextGroup *group = context->d_ptr->group;
     if (group->m_shares.isEmpty())
@@ -5173,7 +5255,7 @@
     }
 #if !defined(QT_OPENGL_ES)
     if (!glCompressedTexImage2D) {
-        if (!(QGLExtensions::glExtensions & QGLExtensions::TextureCompression)) {
+        if (!(QGLExtensions::glExtensions() & QGLExtensions::TextureCompression)) {
             qWarning("QGLContext::bindTexture(): The GL implementation does "
                      "not support texture compression extensions.");
             return QSize();
@@ -5212,7 +5294,7 @@
         return QSize();
 
     // Bail out if the necessary extension is not present.
-    if (!(QGLExtensions::glExtensions & QGLExtensions::DDSTextureCompression)) {
+    if (!(QGLExtensions::glExtensions() & QGLExtensions::DDSTextureCompression)) {
         qWarning("QGLContext::bindTexture(): DDS texture compression is not supported.");
         return QSize();
     }
@@ -5322,13 +5404,13 @@
 
     // Bail out if the necessary extension is not present.
     if (textureFormat == GL_ETC1_RGB8_OES) {
-        if (!(QGLExtensions::glExtensions &
+        if (!(QGLExtensions::glExtensions() &
                     QGLExtensions::ETC1TextureCompression)) {
             qWarning("QGLContext::bindTexture(): ETC1 texture compression is not supported.");
             return QSize();
         }
     } else {
-        if (!(QGLExtensions::glExtensions &
+        if (!(QGLExtensions::glExtensions() &
                     QGLExtensions::PVRTCTextureCompression)) {
             qWarning("QGLContext::bindTexture(): PVRTC texture compression is not supported.");
             return QSize();