src/opengl/qgl.cpp
changeset 18 2f34d5167611
parent 3 41300fa6a67c
child 19 fcece45ef507
equal deleted inserted replaced
3:41300fa6a67c 18:2f34d5167611
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtOpenGL module of the Qt Toolkit.
     7 ** This file is part of the QtOpenGL module of the Qt Toolkit.
     8 **
     8 **
   102 
   102 
   103 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
   103 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
   104 QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs;
   104 QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs;
   105 #endif
   105 #endif
   106 
   106 
       
   107 #ifdef Q_WS_X11
       
   108 extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
       
   109 #endif
       
   110 
   107 struct QGLThreadContext {
   111 struct QGLThreadContext {
   108     QGLContext *context;
   112     QGLContext *context;
   109 };
   113 };
   110 
   114 
   111 static QThreadStorage<QGLThreadContext *> qgl_context_storage;
   115 static QThreadStorage<QGLThreadContext *> qgl_context_storage;
   121         setOption(QGL::DirectRendering);
   125         setOption(QGL::DirectRendering);
   122         setPlane(1);
   126         setPlane(1);
   123     }
   127     }
   124 };
   128 };
   125 Q_GLOBAL_STATIC(QGLDefaultOverlayFormat, defaultOverlayFormatInstance)
   129 Q_GLOBAL_STATIC(QGLDefaultOverlayFormat, defaultOverlayFormatInstance)
   126 
       
   127 QGLExtensions::Extensions QGLExtensions::glExtensions = 0;
       
   128 bool QGLExtensions::nvidiaFboNeedsFinish = false;
       
   129 
   130 
   130 Q_GLOBAL_STATIC(QGLSignalProxy, theSignalProxy)
   131 Q_GLOBAL_STATIC(QGLSignalProxy, theSignalProxy)
   131 QGLSignalProxy *QGLSignalProxy::instance()
   132 QGLSignalProxy *QGLSignalProxy::instance()
   132 {
   133 {
   133     return theSignalProxy();
   134     return theSignalProxy();
   152         // values from functions in GLSL. Since working around this in
   153         // values from functions in GLSL. Since working around this in
   153         // the GL2 engine would require a big, ugly rewrite, we're
   154         // the GL2 engine would require a big, ugly rewrite, we're
   154         // falling back to the GL 1 engine..
   155         // falling back to the GL 1 engine..
   155         static bool mac_x1600_check_done = false;
   156         static bool mac_x1600_check_done = false;
   156         if (!mac_x1600_check_done) {
   157         if (!mac_x1600_check_done) {
   157             QGLWidget *tmp = 0;
   158             QGLTemporaryContext *tmp = 0;
   158             if (!QGLContext::currentContext()) {
   159             if (!QGLContext::currentContext())
   159                 tmp = new QGLWidget();
   160                 tmp = new QGLTemporaryContext();
   160                 tmp->makeCurrent();
       
   161             }
       
   162             if (strstr((char *) glGetString(GL_RENDERER), "X1600"))
   161             if (strstr((char *) glGetString(GL_RENDERER), "X1600"))
   163                 engineType = QPaintEngine::OpenGL;
   162                 engineType = QPaintEngine::OpenGL;
   164             if (tmp)
   163             if (tmp)
   165                 delete tmp;
   164                 delete tmp;
   166             mac_x1600_check_done = true;
   165             mac_x1600_check_done = true;
   176             // Also check for the FragmentShader extension in conjunction with
   175             // Also check for the FragmentShader extension in conjunction with
   177             // the 2.0 version flag, to cover the case where we export the display
   176             // the 2.0 version flag, to cover the case where we export the display
   178             // from an old GL 1.1 server to a GL 2.x client. In that case we can't
   177             // from an old GL 1.1 server to a GL 2.x client. In that case we can't
   179             // use GL 2.0.
   178             // use GL 2.0.
   180             if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
   179             if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
   181                 && (QGLExtensions::glExtensions & QGLExtensions::FragmentShader)
   180                 && (QGLExtensions::glExtensions() & QGLExtensions::FragmentShader)
   182                 && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty())
   181                 && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty())
   183                 engineType = QPaintEngine::OpenGL2;
   182                 engineType = QPaintEngine::OpenGL2;
   184             else
   183             else
   185                 engineType = QPaintEngine::OpenGL;
   184                 engineType = QPaintEngine::OpenGL;
   186 #endif
   185 #endif
  1248 QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags()
  1247 QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags()
  1249 {
  1248 {
  1250     static bool cachedDefault = false;
  1249     static bool cachedDefault = false;
  1251     static OpenGLVersionFlags defaultVersionFlags = OpenGL_Version_None;
  1250     static OpenGLVersionFlags defaultVersionFlags = OpenGL_Version_None;
  1252     QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext());
  1251     QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext());
  1253     QGLWidget *dummy = 0;
  1252     QGLTemporaryContext *tmpContext = 0;
  1254 
  1253 
  1255     if (currentCtx && currentCtx->d_func()->version_flags_cached)
  1254     if (currentCtx && currentCtx->d_func()->version_flags_cached)
  1256         return currentCtx->d_func()->version_flags;
  1255         return currentCtx->d_func()->version_flags;
  1257 
  1256 
  1258     if (!currentCtx) {
  1257     if (!currentCtx) {
  1259         if (cachedDefault) {
  1258         if (cachedDefault) {
  1260             return defaultVersionFlags;
  1259             return defaultVersionFlags;
  1261         } else {
  1260         } else {
  1262             if (!hasOpenGL())
  1261             if (!hasOpenGL())
  1263                 return defaultVersionFlags;
  1262                 return defaultVersionFlags;
  1264             dummy = new QGLWidget;
  1263             tmpContext = new QGLTemporaryContext;
  1265             dummy->makeCurrent(); // glGetString() needs a current context
       
  1266             cachedDefault = true;
  1264             cachedDefault = true;
  1267         }
  1265         }
  1268     }
  1266     }
  1269 
  1267 
  1270     QString versionString(QLatin1String(reinterpret_cast<const char*>(glGetString(GL_VERSION))));
  1268     QString versionString(QLatin1String(reinterpret_cast<const char*>(glGetString(GL_VERSION))));
  1271     OpenGLVersionFlags versionFlags = qOpenGLVersionFlagsFromString(versionString);
  1269     OpenGLVersionFlags versionFlags = qOpenGLVersionFlagsFromString(versionString);
  1272     if (currentCtx) {
  1270     if (currentCtx) {
  1273         currentCtx->d_func()->version_flags_cached = true;
  1271         currentCtx->d_func()->version_flags_cached = true;
  1274         currentCtx->d_func()->version_flags = versionFlags;
  1272         currentCtx->d_func()->version_flags = versionFlags;
  1275     }
  1273     }
  1276     if (dummy) {
  1274     if (tmpContext) {
  1277         defaultVersionFlags = versionFlags;
  1275         defaultVersionFlags = versionFlags;
  1278         delete dummy;
  1276         delete tmpContext;
  1279     }
  1277     }
  1280 
  1278 
  1281     return versionFlags;
  1279     return versionFlags;
  1282 }
  1280 }
  1283 
  1281 
  1434         guard->m_prev->m_next = guard->m_next;
  1432         guard->m_prev->m_next = guard->m_next;
  1435     else
  1433     else
  1436         m_guards = guard->m_next;
  1434         m_guards = guard->m_next;
  1437 }
  1435 }
  1438 
  1436 
       
  1437 const QGLContext *qt_gl_transfer_context(const QGLContext *ctx)
       
  1438 {
       
  1439     if (!ctx)
       
  1440         return 0;
       
  1441     QList<const QGLContext *> shares
       
  1442         (QGLContextPrivate::contextGroup(ctx)->shares());
       
  1443     if (shares.size() >= 2)
       
  1444         return (ctx == shares.at(0)) ? shares.at(1) : shares.at(0);
       
  1445     else
       
  1446         return 0;
       
  1447 }
       
  1448 
  1439 QGLContextPrivate::~QGLContextPrivate()
  1449 QGLContextPrivate::~QGLContextPrivate()
  1440 {
  1450 {
  1441     if (!group->m_refs.deref()) {
  1451     if (!group->m_refs.deref()) {
  1442         Q_ASSERT(group->context() == q_ptr);
  1452         Q_ASSERT(group->context() == q_ptr);
  1443         delete group;
  1453         delete group;
  1479     initDone = false;
  1489     initDone = false;
  1480     sharing = false;
  1490     sharing = false;
  1481     max_texture_size = -1;
  1491     max_texture_size = -1;
  1482     version_flags_cached = false;
  1492     version_flags_cached = false;
  1483     version_flags = QGLFormat::OpenGL_Version_None;
  1493     version_flags = QGLFormat::OpenGL_Version_None;
       
  1494     extension_flags_cached = false;
       
  1495     extension_flags = 0;
  1484     current_fbo = 0;
  1496     current_fbo = 0;
  1485     default_fbo = 0;
  1497     default_fbo = 0;
  1486     active_engine = 0;
  1498     active_engine = 0;
       
  1499     for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
       
  1500         vertexAttributeArraysEnabledState[i] = false;
  1487 }
  1501 }
  1488 
  1502 
  1489 QGLContext* QGLContext::currentCtx = 0;
  1503 QGLContext* QGLContext::currentCtx = 0;
  1490 
  1504 
  1491 /*
  1505 /*
  1539     return img;
  1553     return img;
  1540 }
  1554 }
  1541 
  1555 
  1542 QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha)
  1556 QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha)
  1543 {
  1557 {
  1544     QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32);
  1558     QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
  1545     int w = size.width();
  1559     int w = size.width();
  1546     int h = size.height();
  1560     int h = size.height();
  1547 #if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
  1561 #if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
  1548     //### glGetTexImage not in GL ES 2.0, need to do something else here!
  1562     //### glGetTexImage not in GL ES 2.0, need to do something else here!
  1549     glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
  1563     glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
  1578     : m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though
  1592     : m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though
  1579 {
  1593 {
  1580     Q_ASSERT(qt_gl_texture_cache == 0);
  1594     Q_ASSERT(qt_gl_texture_cache == 0);
  1581     qt_gl_texture_cache = this;
  1595     qt_gl_texture_cache = this;
  1582 
  1596 
  1583     QImagePixmapCleanupHooks::instance()->addPixmapModificationHook(cleanupTextures);
  1597     QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTexturesForPixampData);
  1584 #ifdef Q_WS_X11
  1598     QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction);
  1585     QImagePixmapCleanupHooks::instance()->addPixmapDestructionHook(cleanupPixmapSurfaces);
  1599     QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey);
  1586 #endif
       
  1587     QImagePixmapCleanupHooks::instance()->addImageHook(imageCleanupHook);
       
  1588 }
  1600 }
  1589 
  1601 
  1590 QGLTextureCache::~QGLTextureCache()
  1602 QGLTextureCache::~QGLTextureCache()
  1591 {
  1603 {
  1592     qt_gl_texture_cache = 0;
  1604     qt_gl_texture_cache = 0;
  1593 
  1605 
  1594     QImagePixmapCleanupHooks::instance()->removePixmapModificationHook(cleanupTextures);
  1606     QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData);
  1595 #ifdef Q_WS_X11
  1607     QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction);
  1596     QImagePixmapCleanupHooks::instance()->removePixmapDestructionHook(cleanupPixmapSurfaces);
  1608     QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
  1597 #endif
       
  1598     QImagePixmapCleanupHooks::instance()->removeImageHook(imageCleanupHook);
       
  1599 }
  1609 }
  1600 
  1610 
  1601 void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, int cost)
  1611 void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, int cost)
  1602 {
  1612 {
  1603     if (m_cache.totalCost() + cost > m_cache.maxCost()) {
  1613     if (m_cache.totalCost() + cost > m_cache.maxCost()) {
  1649 
  1659 
  1650 /*
  1660 /*
  1651   a hook that removes textures from the cache when a pixmap/image
  1661   a hook that removes textures from the cache when a pixmap/image
  1652   is deref'ed
  1662   is deref'ed
  1653 */
  1663 */
  1654 void QGLTextureCache::imageCleanupHook(qint64 cacheKey)
  1664 void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey)
  1655 {
       
  1656     // ### remove when the GL texture cache becomes thread-safe
       
  1657     if (qApp->thread() != QThread::currentThread())
       
  1658         return;
       
  1659     QGLTexture *texture = instance()->getTexture(cacheKey);
       
  1660     if (texture && texture->options & QGLContext::MemoryManagedBindOption)
       
  1661         instance()->remove(cacheKey);
       
  1662 }
       
  1663 
       
  1664 
       
  1665 void QGLTextureCache::cleanupTextures(QPixmap* pixmap)
       
  1666 {
  1665 {
  1667     // ### remove when the GL texture cache becomes thread-safe
  1666     // ### remove when the GL texture cache becomes thread-safe
  1668     if (qApp->thread() == QThread::currentThread()) {
  1667     if (qApp->thread() == QThread::currentThread()) {
  1669         const qint64 cacheKey = pixmap->cacheKey();
  1668         instance()->remove(cacheKey);
  1670         QGLTexture *texture = instance()->getTexture(cacheKey);
  1669         Q_ASSERT(instance()->getTexture(cacheKey) == 0);
  1671         if (texture && texture->options & QGLContext::MemoryManagedBindOption)
  1670     }
  1672             instance()->remove(cacheKey);
  1671 }
  1673     }
  1672 
  1674 }
  1673 
       
  1674 void QGLTextureCache::cleanupTexturesForPixampData(QPixmapData* pmd)
       
  1675 {
       
  1676     cleanupTexturesForCacheKey(pmd->cacheKey());
       
  1677 }
       
  1678 
       
  1679 void QGLTextureCache::cleanupBeforePixmapDestruction(QPixmapData* pmd)
       
  1680 {
       
  1681     // Remove any bound textures first:
       
  1682     cleanupTexturesForPixampData(pmd);
  1675 
  1683 
  1676 #if defined(Q_WS_X11)
  1684 #if defined(Q_WS_X11)
  1677 void QGLTextureCache::cleanupPixmapSurfaces(QPixmap* pixmap)
  1685     if (pmd->classId() == QPixmapData::X11Class) {
  1678 {
  1686         Q_ASSERT(pmd->ref == 0); // Make sure reference counting isn't broken
  1679     // Remove any bound textures first:
  1687         QGLContextPrivate::destroyGlSurfaceForPixmap(pmd);
  1680     cleanupTextures(pixmap);
  1688     }
  1681 
  1689 #endif
  1682     QPixmapData *pd = pixmap->data_ptr().data();
  1690 }
  1683     if (pd->classId() == QPixmapData::X11Class) {
       
  1684         Q_ASSERT(pd->ref == 1); // Make sure reference counting isn't broken
       
  1685         QGLContextPrivate::destroyGlSurfaceForPixmap(pd);
       
  1686     }
       
  1687 }
       
  1688 #endif
       
  1689 
  1691 
  1690 void QGLTextureCache::deleteIfEmpty()
  1692 void QGLTextureCache::deleteIfEmpty()
  1691 {
  1693 {
  1692     if (instance()->size() == 0)
  1694     if (instance()->size() == 0)
  1693         delete instance();
  1695         delete instance();
  1727 #ifndef GL_GENERATE_MIPMAP_SGIS
  1729 #ifndef GL_GENERATE_MIPMAP_SGIS
  1728 #define GL_GENERATE_MIPMAP_SGIS       0x8191
  1730 #define GL_GENERATE_MIPMAP_SGIS       0x8191
  1729 #define GL_GENERATE_MIPMAP_HINT_SGIS  0x8192
  1731 #define GL_GENERATE_MIPMAP_HINT_SGIS  0x8192
  1730 #endif
  1732 #endif
  1731 
  1733 
  1732 Q_GLOBAL_STATIC(QGLShareRegister, _qgl_share_reg)
       
  1733 Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg()
       
  1734 {
       
  1735     return _qgl_share_reg();
       
  1736 }
       
  1737 
       
  1738 /*!
  1734 /*!
  1739     \class QGLContext
  1735     \class QGLContext
  1740     \brief The QGLContext class encapsulates an OpenGL rendering context.
  1736     \brief The QGLContext class encapsulates an OpenGL rendering context.
  1741 
  1737 
  1742     \ingroup painting-3D
  1738     \ingroup painting-3D
  1871 }
  1867 }
  1872 
  1868 
  1873 void QGLContextPrivate::cleanup()
  1869 void QGLContextPrivate::cleanup()
  1874 {
  1870 {
  1875 }
  1871 }
       
  1872 
       
  1873 #define ctx q_ptr
       
  1874 void QGLContextPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled)
       
  1875 {
       
  1876     Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT);
       
  1877     Q_ASSERT(glEnableVertexAttribArray);
       
  1878 
       
  1879     if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled)
       
  1880         glDisableVertexAttribArray(arrayIndex);
       
  1881 
       
  1882     if (!vertexAttributeArraysEnabledState[arrayIndex] && enabled)
       
  1883         glEnableVertexAttribArray(arrayIndex);
       
  1884 
       
  1885     vertexAttributeArraysEnabledState[arrayIndex] = enabled;
       
  1886 }
       
  1887 
       
  1888 void QGLContextPrivate::syncGlState()
       
  1889 {
       
  1890     Q_ASSERT(glEnableVertexAttribArray);
       
  1891     for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) {
       
  1892         if (vertexAttributeArraysEnabledState[i])
       
  1893             glEnableVertexAttribArray(i);
       
  1894         else
       
  1895             glDisableVertexAttribArray(i);
       
  1896     }
       
  1897 
       
  1898 }
       
  1899 #undef ctx
       
  1900 
  1876 
  1901 
  1877 /*!
  1902 /*!
  1878     \overload
  1903     \overload
  1879 
  1904 
  1880     Reads the compressed texture file \a fileName and generates a 2D GL
  1905     Reads the compressed texture file \a fileName and generates a 2D GL
  2053     if (!texture)
  2078     if (!texture)
  2054         texture = bindTexture(image, target, format, key, options);
  2079         texture = bindTexture(image, target, format, key, options);
  2055     // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null
  2080     // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null
  2056     Q_ASSERT(texture);
  2081     Q_ASSERT(texture);
  2057 
  2082 
  2058     if (texture->id > 0)
  2083     // Enable the cleanup hooks for this image so that the texture cache entry is removed when the
  2059         QImagePixmapCleanupHooks::enableCleanupHooks(image);
  2084     // image gets deleted:
       
  2085     QImagePixmapCleanupHooks::enableCleanupHooks(image);
  2060 
  2086 
  2061     return texture;
  2087     return texture;
  2062 }
  2088 }
  2063 
  2089 
  2064 // #define QGL_BIND_TEXTURE_DEBUG
  2090 // #define QGL_BIND_TEXTURE_DEBUG
  2108     // 2.0 or use the GL_TEXTURE_RECTANGLE texture target
  2134     // 2.0 or use the GL_TEXTURE_RECTANGLE texture target
  2109     int tx_w = qt_next_power_of_two(image.width());
  2135     int tx_w = qt_next_power_of_two(image.width());
  2110     int tx_h = qt_next_power_of_two(image.height());
  2136     int tx_h = qt_next_power_of_two(image.height());
  2111 
  2137 
  2112     QImage img = image;
  2138     QImage img = image;
  2113     if (!(QGLExtensions::glExtensions & QGLExtensions::NPOTTextures)
  2139 
       
  2140     if (!(QGLExtensions::glExtensions() & QGLExtensions::NPOTTextures)
  2114         && !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0)
  2141         && !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0)
  2115         && (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height())))
  2142         && (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height())))
  2116     {
  2143     {
  2117         img = img.scaled(tx_w, tx_h);
  2144         img = img.scaled(tx_w, tx_h);
  2118 #ifdef QGL_BIND_TEXTURE_DEBUG
  2145 #ifdef QGL_BIND_TEXTURE_DEBUG
  2130 
  2157 
  2131 #if defined(QT_OPENGL_ES_2)
  2158 #if defined(QT_OPENGL_ES_2)
  2132     bool genMipmap = false;
  2159     bool genMipmap = false;
  2133 #endif
  2160 #endif
  2134     if (glFormat.directRendering()
  2161     if (glFormat.directRendering()
  2135         && (QGLExtensions::glExtensions & QGLExtensions::GenerateMipmap)
  2162         && (QGLExtensions::glExtensions() & QGLExtensions::GenerateMipmap)
  2136         && target == GL_TEXTURE_2D
  2163         && target == GL_TEXTURE_2D
  2137         && (options & QGLContext::MipmapBindOption))
  2164         && (options & QGLContext::MipmapBindOption))
  2138     {
  2165     {
  2139 #ifdef QGL_BIND_TEXTURE_DEBUG
  2166 #ifdef QGL_BIND_TEXTURE_DEBUG
  2140         printf(" - generating mipmaps (%d ms)\n", time.elapsed());
  2167         printf(" - generating mipmaps (%d ms)\n", time.elapsed());
  2158 
  2185 
  2159     QImage::Format target_format = img.format();
  2186     QImage::Format target_format = img.format();
  2160     bool premul = options & QGLContext::PremultipliedAlphaBindOption;
  2187     bool premul = options & QGLContext::PremultipliedAlphaBindOption;
  2161     GLenum externalFormat;
  2188     GLenum externalFormat;
  2162     GLuint pixel_type;
  2189     GLuint pixel_type;
  2163     if (QGLExtensions::glExtensions & QGLExtensions::BGRATextureFormat) {
  2190     if (QGLExtensions::glExtensions() & QGLExtensions::BGRATextureFormat) {
  2164         externalFormat = GL_BGRA;
  2191         externalFormat = GL_BGRA;
  2165         pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV;
  2192         if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2)
       
  2193             pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV;
       
  2194         else
       
  2195             pixel_type = GL_UNSIGNED_BYTE;
  2166     } else {
  2196     } else {
  2167         externalFormat = GL_RGBA;
  2197         externalFormat = GL_RGBA;
  2168         pixel_type = GL_UNSIGNED_BYTE;
  2198         pixel_type = GL_UNSIGNED_BYTE;
  2169     }
  2199     }
  2170 
  2200 
  2239         // the format to GL_RGB
  2269         // the format to GL_RGB
  2240         Q_ASSERT(img.depth() == 32);
  2270         Q_ASSERT(img.depth() == 32);
  2241         qgl_byteSwapImage(img, pixel_type);
  2271         qgl_byteSwapImage(img, pixel_type);
  2242     }
  2272     }
  2243 #ifdef QT_OPENGL_ES
  2273 #ifdef QT_OPENGL_ES
  2244     // OpenGL/ES requires that the internal and external formats be identical.
  2274     // OpenGL/ES requires that the internal and external formats be
  2245     // This is typically used to convert GL_RGBA into GL_BGRA.
  2275     // identical.
  2246     // Also, we need to use GL_UNSIGNED_BYTE when the format is GL_BGRA.
       
  2247     internalFormat = externalFormat;
  2276     internalFormat = externalFormat;
  2248     if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV)
       
  2249         pixel_type = GL_UNSIGNED_BYTE;
       
  2250 #endif
  2277 #endif
  2251 #ifdef QGL_BIND_TEXTURE_DEBUG
  2278 #ifdef QGL_BIND_TEXTURE_DEBUG
  2252     printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n",
  2279     printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n",
  2253            img.format(), externalFormat, internalFormat, pixel_type);
  2280            img.format(), externalFormat, internalFormat, pixel_type);
  2254 #endif
  2281 #endif
  2276 
  2303 
  2277     // this assumes the size of a texture is always smaller than the max cache size
  2304     // this assumes the size of a texture is always smaller than the max cache size
  2278     int cost = img.width()*img.height()*4/1024;
  2305     int cost = img.width()*img.height()*4/1024;
  2279     QGLTexture *texture = new QGLTexture(q, tx_id, target, options);
  2306     QGLTexture *texture = new QGLTexture(q, tx_id, target, options);
  2280     QGLTextureCache::instance()->insert(q, key, texture, cost);
  2307     QGLTextureCache::instance()->insert(q, key, texture, cost);
       
  2308 
  2281     return texture;
  2309     return texture;
  2282 }
  2310 }
  2283 
  2311 
  2284 QGLTexture *QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum target)
  2312 QGLTexture *QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum target)
  2285 {
  2313 {
  2320         return texture;
  2348         return texture;
  2321     }
  2349     }
  2322 
  2350 
  2323 #if defined(Q_WS_X11)
  2351 #if defined(Q_WS_X11)
  2324     // Try to use texture_from_pixmap
  2352     // Try to use texture_from_pixmap
  2325     if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType) {
  2353     const QX11Info *xinfo = qt_x11Info(paintDevice);
       
  2354     if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType
       
  2355         && xinfo && xinfo->screen() == pixmap.x11Info().screen())
       
  2356     {
  2326         texture = bindTextureFromNativePixmap(pd, key, options);
  2357         texture = bindTextureFromNativePixmap(pd, key, options);
  2327         if (texture) {
  2358         if (texture) {
  2328             texture->options |= QGLContext::MemoryManagedBindOption;
  2359             texture->options |= QGLContext::MemoryManagedBindOption;
  2329             texture->boundPixmap = pd;
  2360             texture->boundPixmap = pd;
  2330             boundPixmaps.insert(pd, QPixmap(pixmap));
  2361             boundPixmaps.insert(pd, QPixmap(pixmap));
  2389 {
  2420 {
  2390     if (image.isNull())
  2421     if (image.isNull())
  2391         return 0;
  2422         return 0;
  2392 
  2423 
  2393     Q_D(QGLContext);
  2424     Q_D(QGLContext);
  2394     QGLTexture *texture = d->bindTexture(image, target, format, false, DefaultBindOption);
  2425     QGLTexture *texture = d->bindTexture(image, target, format, DefaultBindOption);
  2395     return texture->id;
  2426     return texture->id;
  2396 }
  2427 }
  2397 
  2428 
  2398 /*!
  2429 /*!
  2399     \since 4.6
  2430     \since 4.6
  2529     QGLDDSCache *dds_cache = &(d->group->m_dds_cache);
  2560     QGLDDSCache *dds_cache = &(d->group->m_dds_cache);
  2530     QList<QString> ddsKeys = dds_cache->keys();
  2561     QList<QString> ddsKeys = dds_cache->keys();
  2531     for (int i = 0; i < ddsKeys.size(); ++i) {
  2562     for (int i = 0; i < ddsKeys.size(); ++i) {
  2532         GLuint texture = dds_cache->value(ddsKeys.at(i));
  2563         GLuint texture = dds_cache->value(ddsKeys.at(i));
  2533         if (id == texture) {
  2564         if (id == texture) {
  2534             glDeleteTextures(1, &texture);
       
  2535             dds_cache->remove(ddsKeys.at(i));
  2565             dds_cache->remove(ddsKeys.at(i));
  2536             return;
  2566             break;
  2537         }
  2567         }
  2538     }
  2568     }
       
  2569 
       
  2570     // Finally, actually delete the texture ID
       
  2571     glDeleteTextures(1, &id);
  2539 }
  2572 }
  2540 
  2573 
  2541 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
  2574 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
  2542 /*! \internal */
  2575 /*! \internal */
  2543 void QGLContext::deleteTexture(QMacCompatGLuint id)
  2576 void QGLContext::deleteTexture(QMacCompatGLuint id)
  2952     if (d->valid && d->paintDevice->devType() == QInternal::Widget) {
  2985     if (d->valid && d->paintDevice->devType() == QInternal::Widget) {
  2953         QWidgetPrivate *wd = qt_widget_private(static_cast<QWidget *>(d->paintDevice));
  2986         QWidgetPrivate *wd = qt_widget_private(static_cast<QWidget *>(d->paintDevice));
  2954         wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer();
  2987         wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer();
  2955     }
  2988     }
  2956     if (d->sharing)  // ok, we managed to share
  2989     if (d->sharing)  // ok, we managed to share
  2957         qgl_share_reg()->addShare(this, shareContext);
  2990         QGLContextGroup::addShare(this, shareContext);
  2958     return d->valid;
  2991     return d->valid;
  2959 }
  2992 }
  2960 
  2993 
  2961 bool QGLContext::isValid() const
  2994 bool QGLContext::isValid() const
  2962 {
  2995 {
  4358    \note This function is not supported on OpenGL/ES systems.
  4391    \note This function is not supported on OpenGL/ES systems.
  4359 
  4392 
  4360    \note This function temporarily disables depth-testing when the
  4393    \note This function temporarily disables depth-testing when the
  4361    text is drawn.
  4394    text is drawn.
  4362 
  4395 
       
  4396    \note This function can only be used inside a
       
  4397    QPainter::beginNativePainting()/QPainter::endNativePainting() block
       
  4398    if the default OpenGL paint engine is QPaintEngine::OpenGL. To make
       
  4399    QPaintEngine::OpenGL the default GL engine, call
       
  4400    QGL::setPreferredPaintEngine(QPaintEngine::OpenGL) before the
       
  4401    QApplication constructor.
       
  4402 
  4363    \l{Overpainting Example}{Overpaint} with QPainter::drawText() instead.
  4403    \l{Overpainting Example}{Overpaint} with QPainter::drawText() instead.
  4364 */
  4404 */
  4365 
  4405 
  4366 void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, int)
  4406 void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, int)
  4367 {
  4407 {
  4376         glGetIntegerv(GL_VIEWPORT, &view[0]);
  4416         glGetIntegerv(GL_VIEWPORT, &view[0]);
  4377     int width = d->glcx->device()->width();
  4417     int width = d->glcx->device()->width();
  4378     int height = d->glcx->device()->height();
  4418     int height = d->glcx->device()->height();
  4379     bool auto_swap = autoBufferSwap();
  4419     bool auto_swap = autoBufferSwap();
  4380 
  4420 
       
  4421     QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
       
  4422 
  4381     QPaintEngine *engine = paintEngine();
  4423     QPaintEngine *engine = paintEngine();
  4382     if (engine->type() == QPaintEngine::OpenGL2)
  4424     if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
  4383         static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(true);
  4425         qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
       
  4426                  " active on the same device is not allowed.");
       
  4427         return;
       
  4428     }
       
  4429 
       
  4430     // this changes what paintEngine() returns
       
  4431     qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
       
  4432     engine = paintEngine();
  4384     QPainter *p;
  4433     QPainter *p;
  4385     bool reuse_painter = false;
  4434     bool reuse_painter = false;
  4386     if (engine->isActive()) {
  4435     if (engine->isActive()) {
  4387         reuse_painter = true;
  4436         reuse_painter = true;
  4388         p = engine->painter();
  4437         p = engine->painter();
  4398         glLoadIdentity();
  4447         glLoadIdentity();
  4399     } else {
  4448     } else {
  4400         setAutoBufferSwap(false);
  4449         setAutoBufferSwap(false);
  4401         // disable glClear() as a result of QPainter::begin()
  4450         // disable glClear() as a result of QPainter::begin()
  4402         d->disable_clear_on_painter_begin = true;
  4451         d->disable_clear_on_painter_begin = true;
  4403         if (engine->type() == QPaintEngine::OpenGL2) {
       
  4404             qt_save_gl_state();
       
  4405             glMatrixMode(GL_MODELVIEW);
       
  4406             glLoadIdentity();
       
  4407         }
       
  4408         p = new QPainter(this);
  4452         p = new QPainter(this);
  4409     }
  4453     }
  4410 
  4454 
  4411     QRect viewport(view[0], view[1], view[2], view[3]);
  4455     QRect viewport(view[0], view[1], view[2], view[3]);
  4412     if (!use_scissor_testing && viewport != rect()) {
  4456     if (!use_scissor_testing && viewport != rect()) {
  4426     } else {
  4470     } else {
  4427         p->end();
  4471         p->end();
  4428         delete p;
  4472         delete p;
  4429         setAutoBufferSwap(auto_swap);
  4473         setAutoBufferSwap(auto_swap);
  4430         d->disable_clear_on_painter_begin = false;
  4474         d->disable_clear_on_painter_begin = false;
  4431         if (engine->type() == QPaintEngine::OpenGL2)
  4475     }
  4432             qt_restore_gl_state();
  4476     qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
  4433     }
       
  4434     if (engine->type() == QPaintEngine::OpenGL2)
       
  4435         static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(false);
       
  4436 #else // QT_OPENGL_ES
  4477 #else // QT_OPENGL_ES
  4437     Q_UNUSED(x);
  4478     Q_UNUSED(x);
  4438     Q_UNUSED(y);
  4479     Q_UNUSED(y);
  4439     Q_UNUSED(str);
  4480     Q_UNUSED(str);
  4440     Q_UNUSED(font);
  4481     Q_UNUSED(font);
  4478     GLdouble win_x = 0, win_y = 0, win_z = 0;
  4519     GLdouble win_x = 0, win_y = 0, win_z = 0;
  4479     qgluProject(x, y, z, &model[0][0], &proj[0][0], &view[0],
  4520     qgluProject(x, y, z, &model[0][0], &proj[0][0], &view[0],
  4480                 &win_x, &win_y, &win_z);
  4521                 &win_x, &win_y, &win_z);
  4481     win_y = height - win_y; // y is inverted
  4522     win_y = height - win_y; // y is inverted
  4482 
  4523 
       
  4524     QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
  4483     QPaintEngine *engine = paintEngine();
  4525     QPaintEngine *engine = paintEngine();
  4484     if (engine->type() == QPaintEngine::OpenGL2)
  4526 
  4485         static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(true);
  4527     if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
       
  4528         qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
       
  4529                  " active on the same device is not allowed.");
       
  4530         return;
       
  4531     }
       
  4532 
       
  4533     // this changes what paintEngine() returns
       
  4534     qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
       
  4535     engine = paintEngine();
  4486     QPainter *p;
  4536     QPainter *p;
  4487     bool reuse_painter = false;
  4537     bool reuse_painter = false;
  4488     bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
  4538     bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
  4489     bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
  4539     bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
  4490 
  4540 
  4494         qt_save_gl_state();
  4544         qt_save_gl_state();
  4495     } else {
  4545     } else {
  4496         setAutoBufferSwap(false);
  4546         setAutoBufferSwap(false);
  4497         // disable glClear() as a result of QPainter::begin()
  4547         // disable glClear() as a result of QPainter::begin()
  4498         d->disable_clear_on_painter_begin = true;
  4548         d->disable_clear_on_painter_begin = true;
  4499         if (engine->type() == QPaintEngine::OpenGL2)
       
  4500             qt_save_gl_state();
       
  4501         p = new QPainter(this);
  4549         p = new QPainter(this);
  4502     }
  4550     }
  4503 
  4551 
  4504     QRect viewport(view[0], view[1], view[2], view[3]);
  4552     QRect viewport(view[0], view[1], view[2], view[3]);
  4505     if (!use_scissor_testing && viewport != rect()) {
  4553     if (!use_scissor_testing && viewport != rect()) {
  4524     if (reuse_painter) {
  4572     if (reuse_painter) {
  4525         qt_restore_gl_state();
  4573         qt_restore_gl_state();
  4526     } else {
  4574     } else {
  4527         p->end();
  4575         p->end();
  4528         delete p;
  4576         delete p;
  4529         if (engine->type() == QPaintEngine::OpenGL2)
       
  4530             qt_restore_gl_state();
       
  4531         setAutoBufferSwap(auto_swap);
  4577         setAutoBufferSwap(auto_swap);
  4532         d->disable_clear_on_painter_begin = false;
  4578         d->disable_clear_on_painter_begin = false;
  4533     }
  4579     }
  4534     if (engine->type() == QPaintEngine::OpenGL2)
  4580     qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
  4535         static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(false);
       
  4536 #else // QT_OPENGL_ES
  4581 #else // QT_OPENGL_ES
  4537     Q_UNUSED(x);
  4582     Q_UNUSED(x);
  4538     Q_UNUSED(y);
  4583     Q_UNUSED(y);
  4539     Q_UNUSED(z);
  4584     Q_UNUSED(z);
  4540     Q_UNUSED(str);
  4585     Q_UNUSED(str);
  4842     d->init(context, shareWidget);
  4887     d->init(context, shareWidget);
  4843 }
  4888 }
  4844 
  4889 
  4845 #endif // QT3_SUPPORT
  4890 #endif // QT3_SUPPORT
  4846 
  4891 
  4847 void QGLExtensions::init_extensions()
  4892 /*
       
  4893     Returns the GL extensions for the current context.
       
  4894 */
       
  4895 QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
  4848 {
  4896 {
  4849     QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
  4897     QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
       
  4898     Extensions glExtensions;
  4850 
  4899 
  4851     if (extensions.match("GL_ARB_texture_rectangle"))
  4900     if (extensions.match("GL_ARB_texture_rectangle"))
  4852         glExtensions |= TextureRectangle;
  4901         glExtensions |= TextureRectangle;
  4853     if (extensions.match("GL_ARB_multisample"))
  4902     if (extensions.match("GL_ARB_multisample"))
  4854         glExtensions |= SampleBuffers;
  4903         glExtensions |= SampleBuffers;
  4905     if (extensions.match("GL_ARB_texture_non_power_of_two"))
  4954     if (extensions.match("GL_ARB_texture_non_power_of_two"))
  4906         glExtensions |= NPOTTextures;
  4955         glExtensions |= NPOTTextures;
  4907 
  4956 
  4908     if (extensions.match("GL_EXT_bgra"))
  4957     if (extensions.match("GL_EXT_bgra"))
  4909         glExtensions |= BGRATextureFormat;
  4958         glExtensions |= BGRATextureFormat;
       
  4959 
       
  4960     return glExtensions;
       
  4961 }
       
  4962 
       
  4963 /*
       
  4964     Returns the GL extensions for the current QGLContext. If there is no
       
  4965     current QGLContext, a default context will be created and the extensions
       
  4966     for that context will be returned instead.
       
  4967 */
       
  4968 QGLExtensions::Extensions QGLExtensions::glExtensions()
       
  4969 {
       
  4970     QGLTemporaryContext *tmpContext = 0;
       
  4971     static bool cachedDefault = false;
       
  4972     static Extensions defaultExtensions = 0;
       
  4973     QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext());
       
  4974 
       
  4975     if (currentCtx && currentCtx->d_func()->extension_flags_cached)
       
  4976         return currentCtx->d_func()->extension_flags;
       
  4977 
       
  4978     if (!currentCtx) {
       
  4979         if (cachedDefault) {
       
  4980             return defaultExtensions;
       
  4981         } else {
       
  4982             tmpContext = new QGLTemporaryContext;
       
  4983             cachedDefault = true;
       
  4984         }
       
  4985     }
       
  4986 
       
  4987     Extensions extensionFlags = currentContextExtensions();
       
  4988     if (currentCtx) {
       
  4989         currentCtx->d_func()->extension_flags_cached = true;
       
  4990         currentCtx->d_func()->extension_flags = extensionFlags;
       
  4991     } else {
       
  4992         defaultExtensions = extensionFlags;
       
  4993     }
       
  4994 
       
  4995     if (tmpContext)
       
  4996         delete tmpContext;
       
  4997 
       
  4998     return extensionFlags;
  4910 }
  4999 }
  4911 
  5000 
  4912 /*
  5001 /*
  4913   This is the shared initialization for all platforms. Called from QGLWidgetPrivate::init()
  5002   This is the shared initialization for all platforms. Called from QGLWidgetPrivate::init()
  4914 */
  5003 */
  4916 {
  5005 {
  4917     Q_Q(QGLWidget);
  5006     Q_Q(QGLWidget);
  4918 
  5007 
  4919     glDevice.setWidget(q);
  5008     glDevice.setWidget(q);
  4920 
  5009 
  4921     QGLExtensions::init();
       
  4922     glcx = 0;
  5010     glcx = 0;
  4923     autoSwap = true;
  5011     autoSwap = true;
  4924 
  5012 
  4925     if (context && !context->device())
  5013     if (context && !context->device())
  4926         context->setDevice(q);
  5014         context->setDevice(q);
  4927     q->setContext(context, shareWidget ? shareWidget->context() : 0);
  5015     q->setContext(context, shareWidget ? shareWidget->context() : 0);
  4928 
  5016 
  4929     if (!glcx)
  5017     if (!glcx)
  4930         glcx = new QGLContext(QGLFormat::defaultFormat(), q);
  5018         glcx = new QGLContext(QGLFormat::defaultFormat(), q);
  4931 
       
  4932     q->setAttribute(Qt::WA_NoSystemBackground);
       
  4933 }
  5019 }
  4934 
  5020 
  4935 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
  5021 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
  4936 Q_GLOBAL_STATIC(QString, qt_gl_lib_name)
  5022 Q_GLOBAL_STATIC(QString, qt_gl_lib_name)
  4937 
  5023 
  4951     }
  5037     }
  4952     return *qt_gl_lib_name();
  5038     return *qt_gl_lib_name();
  4953 }
  5039 }
  4954 #endif
  5040 #endif
  4955 
  5041 
  4956 void QGLShareRegister::addShare(const QGLContext *context, const QGLContext *share) {
  5042 void QGLContextGroup::addShare(const QGLContext *context, const QGLContext *share) {
  4957     Q_ASSERT(context && share);
  5043     Q_ASSERT(context && share);
  4958     if (context->d_ptr->group == share->d_ptr->group)
  5044     if (context->d_ptr->group == share->d_ptr->group)
  4959         return;
  5045         return;
  4960 
  5046 
  4961     // Make sure 'context' is not already shared with another group of contexts.
  5047     // Make sure 'context' is not already shared with another group of contexts.
  4972     if (group->m_shares.isEmpty())
  5058     if (group->m_shares.isEmpty())
  4973         group->m_shares.append(share);
  5059         group->m_shares.append(share);
  4974     group->m_shares.append(context);
  5060     group->m_shares.append(context);
  4975 }
  5061 }
  4976 
  5062 
  4977 QList<const QGLContext *> QGLShareRegister::shares(const QGLContext *context) {
  5063 void QGLContextGroup::removeShare(const QGLContext *context) {
  4978     return context->d_ptr->group->m_shares;
       
  4979 }
       
  4980 
       
  4981 void QGLShareRegister::removeShare(const QGLContext *context) {
       
  4982     // Remove the context from the group.
  5064     // Remove the context from the group.
  4983     QGLContextGroup *group = context->d_ptr->group;
  5065     QGLContextGroup *group = context->d_ptr->group;
  4984     if (group->m_shares.isEmpty())
  5066     if (group->m_shares.isEmpty())
  4985         return;
  5067         return;
  4986     group->m_shares.removeAll(context);
  5068     group->m_shares.removeAll(context);
  5171         // systems such as x86 and ARM at the moment.
  5253         // systems such as x86 and ARM at the moment.
  5172         return QSize();
  5254         return QSize();
  5173     }
  5255     }
  5174 #if !defined(QT_OPENGL_ES)
  5256 #if !defined(QT_OPENGL_ES)
  5175     if (!glCompressedTexImage2D) {
  5257     if (!glCompressedTexImage2D) {
  5176         if (!(QGLExtensions::glExtensions & QGLExtensions::TextureCompression)) {
  5258         if (!(QGLExtensions::glExtensions() & QGLExtensions::TextureCompression)) {
  5177             qWarning("QGLContext::bindTexture(): The GL implementation does "
  5259             qWarning("QGLContext::bindTexture(): The GL implementation does "
  5178                      "not support texture compression extensions.");
  5260                      "not support texture compression extensions.");
  5179             return QSize();
  5261             return QSize();
  5180         }
  5262         }
  5181         glCompressedTexImage2D = (_glCompressedTexImage2DARB) ctx->getProcAddress(QLatin1String("glCompressedTexImage2DARB"));
  5263         glCompressedTexImage2D = (_glCompressedTexImage2DARB) ctx->getProcAddress(QLatin1String("glCompressedTexImage2DARB"));
  5210     // We only support 2D texture loading at present.
  5292     // We only support 2D texture loading at present.
  5211     if (target != GL_TEXTURE_2D)
  5293     if (target != GL_TEXTURE_2D)
  5212         return QSize();
  5294         return QSize();
  5213 
  5295 
  5214     // Bail out if the necessary extension is not present.
  5296     // Bail out if the necessary extension is not present.
  5215     if (!(QGLExtensions::glExtensions & QGLExtensions::DDSTextureCompression)) {
  5297     if (!(QGLExtensions::glExtensions() & QGLExtensions::DDSTextureCompression)) {
  5216         qWarning("QGLContext::bindTexture(): DDS texture compression is not supported.");
  5298         qWarning("QGLContext::bindTexture(): DDS texture compression is not supported.");
  5217         return QSize();
  5299         return QSize();
  5218     }
  5300     }
  5219 
  5301 
  5220     const DDSFormat *ddsHeader = reinterpret_cast<const DDSFormat *>(buf + 4);
  5302     const DDSFormat *ddsHeader = reinterpret_cast<const DDSFormat *>(buf + 4);
  5320         return QSize();
  5402         return QSize();
  5321     }
  5403     }
  5322 
  5404 
  5323     // Bail out if the necessary extension is not present.
  5405     // Bail out if the necessary extension is not present.
  5324     if (textureFormat == GL_ETC1_RGB8_OES) {
  5406     if (textureFormat == GL_ETC1_RGB8_OES) {
  5325         if (!(QGLExtensions::glExtensions &
  5407         if (!(QGLExtensions::glExtensions() &
  5326                     QGLExtensions::ETC1TextureCompression)) {
  5408                     QGLExtensions::ETC1TextureCompression)) {
  5327             qWarning("QGLContext::bindTexture(): ETC1 texture compression is not supported.");
  5409             qWarning("QGLContext::bindTexture(): ETC1 texture compression is not supported.");
  5328             return QSize();
  5410             return QSize();
  5329         }
  5411         }
  5330     } else {
  5412     } else {
  5331         if (!(QGLExtensions::glExtensions &
  5413         if (!(QGLExtensions::glExtensions() &
  5332                     QGLExtensions::PVRTCTextureCompression)) {
  5414                     QGLExtensions::PVRTCTextureCompression)) {
  5333             qWarning("QGLContext::bindTexture(): PVRTC texture compression is not supported.");
  5415             qWarning("QGLContext::bindTexture(): PVRTC texture compression is not supported.");
  5334             return QSize();
  5416             return QSize();
  5335         }
  5417         }
  5336     }
  5418     }