src/opengl/qgl.cpp
branchRCL_3
changeset 4 3b1da2848fc7
parent 3 41300fa6a67c
child 5 d3bac044e0f0
equal deleted inserted replaced
3:41300fa6a67c 4:3b1da2848fc7
     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 **
   122         setPlane(1);
   122         setPlane(1);
   123     }
   123     }
   124 };
   124 };
   125 Q_GLOBAL_STATIC(QGLDefaultOverlayFormat, defaultOverlayFormatInstance)
   125 Q_GLOBAL_STATIC(QGLDefaultOverlayFormat, defaultOverlayFormatInstance)
   126 
   126 
   127 QGLExtensions::Extensions QGLExtensions::glExtensions = 0;
       
   128 bool QGLExtensions::nvidiaFboNeedsFinish = false;
       
   129 
       
   130 Q_GLOBAL_STATIC(QGLSignalProxy, theSignalProxy)
   127 Q_GLOBAL_STATIC(QGLSignalProxy, theSignalProxy)
   131 QGLSignalProxy *QGLSignalProxy::instance()
   128 QGLSignalProxy *QGLSignalProxy::instance()
   132 {
   129 {
   133     return theSignalProxy();
   130     return theSignalProxy();
   134 }
   131 }
   152         // values from functions in GLSL. Since working around this in
   149         // values from functions in GLSL. Since working around this in
   153         // the GL2 engine would require a big, ugly rewrite, we're
   150         // the GL2 engine would require a big, ugly rewrite, we're
   154         // falling back to the GL 1 engine..
   151         // falling back to the GL 1 engine..
   155         static bool mac_x1600_check_done = false;
   152         static bool mac_x1600_check_done = false;
   156         if (!mac_x1600_check_done) {
   153         if (!mac_x1600_check_done) {
   157             QGLWidget *tmp = 0;
   154             QGLTemporaryContext *tmp = 0;
   158             if (!QGLContext::currentContext()) {
   155             if (!QGLContext::currentContext())
   159                 tmp = new QGLWidget();
   156                 tmp = new QGLTemporaryContext();
   160                 tmp->makeCurrent();
       
   161             }
       
   162             if (strstr((char *) glGetString(GL_RENDERER), "X1600"))
   157             if (strstr((char *) glGetString(GL_RENDERER), "X1600"))
   163                 engineType = QPaintEngine::OpenGL;
   158                 engineType = QPaintEngine::OpenGL;
   164             if (tmp)
   159             if (tmp)
   165                 delete tmp;
   160                 delete tmp;
   166             mac_x1600_check_done = true;
   161             mac_x1600_check_done = true;
   176             // Also check for the FragmentShader extension in conjunction with
   171             // Also check for the FragmentShader extension in conjunction with
   177             // the 2.0 version flag, to cover the case where we export the display
   172             // 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
   173             // from an old GL 1.1 server to a GL 2.x client. In that case we can't
   179             // use GL 2.0.
   174             // use GL 2.0.
   180             if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
   175             if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
   181                 && (QGLExtensions::glExtensions & QGLExtensions::FragmentShader)
   176                 && (QGLExtensions::glExtensions() & QGLExtensions::FragmentShader)
   182                 && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty())
   177                 && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty())
   183                 engineType = QPaintEngine::OpenGL2;
   178                 engineType = QPaintEngine::OpenGL2;
   184             else
   179             else
   185                 engineType = QPaintEngine::OpenGL;
   180                 engineType = QPaintEngine::OpenGL;
   186 #endif
   181 #endif
  1248 QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags()
  1243 QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags()
  1249 {
  1244 {
  1250     static bool cachedDefault = false;
  1245     static bool cachedDefault = false;
  1251     static OpenGLVersionFlags defaultVersionFlags = OpenGL_Version_None;
  1246     static OpenGLVersionFlags defaultVersionFlags = OpenGL_Version_None;
  1252     QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext());
  1247     QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext());
  1253     QGLWidget *dummy = 0;
  1248     QGLTemporaryContext *tmpContext = 0;
  1254 
  1249 
  1255     if (currentCtx && currentCtx->d_func()->version_flags_cached)
  1250     if (currentCtx && currentCtx->d_func()->version_flags_cached)
  1256         return currentCtx->d_func()->version_flags;
  1251         return currentCtx->d_func()->version_flags;
  1257 
  1252 
  1258     if (!currentCtx) {
  1253     if (!currentCtx) {
  1259         if (cachedDefault) {
  1254         if (cachedDefault) {
  1260             return defaultVersionFlags;
  1255             return defaultVersionFlags;
  1261         } else {
  1256         } else {
  1262             if (!hasOpenGL())
  1257             if (!hasOpenGL())
  1263                 return defaultVersionFlags;
  1258                 return defaultVersionFlags;
  1264             dummy = new QGLWidget;
  1259             tmpContext = new QGLTemporaryContext;
  1265             dummy->makeCurrent(); // glGetString() needs a current context
       
  1266             cachedDefault = true;
  1260             cachedDefault = true;
  1267         }
  1261         }
  1268     }
  1262     }
  1269 
  1263 
  1270     QString versionString(QLatin1String(reinterpret_cast<const char*>(glGetString(GL_VERSION))));
  1264     QString versionString(QLatin1String(reinterpret_cast<const char*>(glGetString(GL_VERSION))));
  1271     OpenGLVersionFlags versionFlags = qOpenGLVersionFlagsFromString(versionString);
  1265     OpenGLVersionFlags versionFlags = qOpenGLVersionFlagsFromString(versionString);
  1272     if (currentCtx) {
  1266     if (currentCtx) {
  1273         currentCtx->d_func()->version_flags_cached = true;
  1267         currentCtx->d_func()->version_flags_cached = true;
  1274         currentCtx->d_func()->version_flags = versionFlags;
  1268         currentCtx->d_func()->version_flags = versionFlags;
  1275     }
  1269     }
  1276     if (dummy) {
  1270     if (tmpContext) {
  1277         defaultVersionFlags = versionFlags;
  1271         defaultVersionFlags = versionFlags;
  1278         delete dummy;
  1272         delete tmpContext;
  1279     }
  1273     }
  1280 
  1274 
  1281     return versionFlags;
  1275     return versionFlags;
  1282 }
  1276 }
  1283 
  1277 
  1434         guard->m_prev->m_next = guard->m_next;
  1428         guard->m_prev->m_next = guard->m_next;
  1435     else
  1429     else
  1436         m_guards = guard->m_next;
  1430         m_guards = guard->m_next;
  1437 }
  1431 }
  1438 
  1432 
       
  1433 const QGLContext *qt_gl_transfer_context(const QGLContext *ctx)
       
  1434 {
       
  1435     if (!ctx)
       
  1436         return 0;
       
  1437     QList<const QGLContext *> shares
       
  1438         (QGLContextPrivate::contextGroup(ctx)->shares());
       
  1439     if (shares.size() >= 2)
       
  1440         return (ctx == shares.at(0)) ? shares.at(1) : shares.at(0);
       
  1441     else
       
  1442         return 0;
       
  1443 }
       
  1444 
  1439 QGLContextPrivate::~QGLContextPrivate()
  1445 QGLContextPrivate::~QGLContextPrivate()
  1440 {
  1446 {
  1441     if (!group->m_refs.deref()) {
  1447     if (!group->m_refs.deref()) {
  1442         Q_ASSERT(group->context() == q_ptr);
  1448         Q_ASSERT(group->context() == q_ptr);
  1443         delete group;
  1449         delete group;
  1479     initDone = false;
  1485     initDone = false;
  1480     sharing = false;
  1486     sharing = false;
  1481     max_texture_size = -1;
  1487     max_texture_size = -1;
  1482     version_flags_cached = false;
  1488     version_flags_cached = false;
  1483     version_flags = QGLFormat::OpenGL_Version_None;
  1489     version_flags = QGLFormat::OpenGL_Version_None;
       
  1490     extension_flags_cached = false;
       
  1491     extension_flags = 0;
  1484     current_fbo = 0;
  1492     current_fbo = 0;
  1485     default_fbo = 0;
  1493     default_fbo = 0;
  1486     active_engine = 0;
  1494     active_engine = 0;
       
  1495     for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
       
  1496         vertexAttributeArraysEnabledState[i] = false;
  1487 }
  1497 }
  1488 
  1498 
  1489 QGLContext* QGLContext::currentCtx = 0;
  1499 QGLContext* QGLContext::currentCtx = 0;
  1490 
  1500 
  1491 /*
  1501 /*
  1539     return img;
  1549     return img;
  1540 }
  1550 }
  1541 
  1551 
  1542 QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha)
  1552 QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha)
  1543 {
  1553 {
  1544     QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32);
  1554     QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
  1545     int w = size.width();
  1555     int w = size.width();
  1546     int h = size.height();
  1556     int h = size.height();
  1547 #if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
  1557 #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!
  1558     //### 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());
  1559     glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
  1727 #ifndef GL_GENERATE_MIPMAP_SGIS
  1737 #ifndef GL_GENERATE_MIPMAP_SGIS
  1728 #define GL_GENERATE_MIPMAP_SGIS       0x8191
  1738 #define GL_GENERATE_MIPMAP_SGIS       0x8191
  1729 #define GL_GENERATE_MIPMAP_HINT_SGIS  0x8192
  1739 #define GL_GENERATE_MIPMAP_HINT_SGIS  0x8192
  1730 #endif
  1740 #endif
  1731 
  1741 
  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 /*!
  1742 /*!
  1739     \class QGLContext
  1743     \class QGLContext
  1740     \brief The QGLContext class encapsulates an OpenGL rendering context.
  1744     \brief The QGLContext class encapsulates an OpenGL rendering context.
  1741 
  1745 
  1742     \ingroup painting-3D
  1746     \ingroup painting-3D
  1871 }
  1875 }
  1872 
  1876 
  1873 void QGLContextPrivate::cleanup()
  1877 void QGLContextPrivate::cleanup()
  1874 {
  1878 {
  1875 }
  1879 }
       
  1880 
       
  1881 #define ctx q_ptr
       
  1882 void QGLContextPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled)
       
  1883 {
       
  1884     Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT);
       
  1885     Q_ASSERT(glEnableVertexAttribArray);
       
  1886 
       
  1887     if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled)
       
  1888         glDisableVertexAttribArray(arrayIndex);
       
  1889 
       
  1890     if (!vertexAttributeArraysEnabledState[arrayIndex] && enabled)
       
  1891         glEnableVertexAttribArray(arrayIndex);
       
  1892 
       
  1893     vertexAttributeArraysEnabledState[arrayIndex] = enabled;
       
  1894 }
       
  1895 
       
  1896 void QGLContextPrivate::syncGlState()
       
  1897 {
       
  1898     Q_ASSERT(glEnableVertexAttribArray);
       
  1899     for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) {
       
  1900         if (vertexAttributeArraysEnabledState[i])
       
  1901             glEnableVertexAttribArray(i);
       
  1902         else
       
  1903             glDisableVertexAttribArray(i);
       
  1904     }
       
  1905 
       
  1906 }
       
  1907 #undef ctx
       
  1908 
  1876 
  1909 
  1877 /*!
  1910 /*!
  1878     \overload
  1911     \overload
  1879 
  1912 
  1880     Reads the compressed texture file \a fileName and generates a 2D GL
  1913     Reads the compressed texture file \a fileName and generates a 2D GL
  2108     // 2.0 or use the GL_TEXTURE_RECTANGLE texture target
  2141     // 2.0 or use the GL_TEXTURE_RECTANGLE texture target
  2109     int tx_w = qt_next_power_of_two(image.width());
  2142     int tx_w = qt_next_power_of_two(image.width());
  2110     int tx_h = qt_next_power_of_two(image.height());
  2143     int tx_h = qt_next_power_of_two(image.height());
  2111 
  2144 
  2112     QImage img = image;
  2145     QImage img = image;
  2113     if (!(QGLExtensions::glExtensions & QGLExtensions::NPOTTextures)
  2146     if (!(QGLExtensions::glExtensions() & QGLExtensions::NPOTTextures)
  2114         && !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0)
  2147         && !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0)
  2115         && (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height())))
  2148         && (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height())))
  2116     {
  2149     {
  2117         img = img.scaled(tx_w, tx_h);
  2150         img = img.scaled(tx_w, tx_h);
  2118 #ifdef QGL_BIND_TEXTURE_DEBUG
  2151 #ifdef QGL_BIND_TEXTURE_DEBUG
  2130 
  2163 
  2131 #if defined(QT_OPENGL_ES_2)
  2164 #if defined(QT_OPENGL_ES_2)
  2132     bool genMipmap = false;
  2165     bool genMipmap = false;
  2133 #endif
  2166 #endif
  2134     if (glFormat.directRendering()
  2167     if (glFormat.directRendering()
  2135         && (QGLExtensions::glExtensions & QGLExtensions::GenerateMipmap)
  2168         && (QGLExtensions::glExtensions() & QGLExtensions::GenerateMipmap)
  2136         && target == GL_TEXTURE_2D
  2169         && target == GL_TEXTURE_2D
  2137         && (options & QGLContext::MipmapBindOption))
  2170         && (options & QGLContext::MipmapBindOption))
  2138     {
  2171     {
  2139 #ifdef QGL_BIND_TEXTURE_DEBUG
  2172 #ifdef QGL_BIND_TEXTURE_DEBUG
  2140         printf(" - generating mipmaps (%d ms)\n", time.elapsed());
  2173         printf(" - generating mipmaps (%d ms)\n", time.elapsed());
  2158 
  2191 
  2159     QImage::Format target_format = img.format();
  2192     QImage::Format target_format = img.format();
  2160     bool premul = options & QGLContext::PremultipliedAlphaBindOption;
  2193     bool premul = options & QGLContext::PremultipliedAlphaBindOption;
  2161     GLenum externalFormat;
  2194     GLenum externalFormat;
  2162     GLuint pixel_type;
  2195     GLuint pixel_type;
  2163     if (QGLExtensions::glExtensions & QGLExtensions::BGRATextureFormat) {
  2196     if (QGLExtensions::glExtensions() & QGLExtensions::BGRATextureFormat) {
  2164         externalFormat = GL_BGRA;
  2197         externalFormat = GL_BGRA;
  2165         pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV;
  2198         if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2)
       
  2199             pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV;
       
  2200         else
       
  2201             pixel_type = GL_UNSIGNED_BYTE;
  2166     } else {
  2202     } else {
  2167         externalFormat = GL_RGBA;
  2203         externalFormat = GL_RGBA;
  2168         pixel_type = GL_UNSIGNED_BYTE;
  2204         pixel_type = GL_UNSIGNED_BYTE;
  2169     }
  2205     }
  2170 
  2206 
  2239         // the format to GL_RGB
  2275         // the format to GL_RGB
  2240         Q_ASSERT(img.depth() == 32);
  2276         Q_ASSERT(img.depth() == 32);
  2241         qgl_byteSwapImage(img, pixel_type);
  2277         qgl_byteSwapImage(img, pixel_type);
  2242     }
  2278     }
  2243 #ifdef QT_OPENGL_ES
  2279 #ifdef QT_OPENGL_ES
  2244     // OpenGL/ES requires that the internal and external formats be identical.
  2280     // OpenGL/ES requires that the internal and external formats be
  2245     // This is typically used to convert GL_RGBA into GL_BGRA.
  2281     // identical.
  2246     // Also, we need to use GL_UNSIGNED_BYTE when the format is GL_BGRA.
       
  2247     internalFormat = externalFormat;
  2282     internalFormat = externalFormat;
  2248     if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV)
       
  2249         pixel_type = GL_UNSIGNED_BYTE;
       
  2250 #endif
  2283 #endif
  2251 #ifdef QGL_BIND_TEXTURE_DEBUG
  2284 #ifdef QGL_BIND_TEXTURE_DEBUG
  2252     printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n",
  2285     printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n",
  2253            img.format(), externalFormat, internalFormat, pixel_type);
  2286            img.format(), externalFormat, internalFormat, pixel_type);
  2254 #endif
  2287 #endif
  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 {
  4376         glGetIntegerv(GL_VIEWPORT, &view[0]);
  4409         glGetIntegerv(GL_VIEWPORT, &view[0]);
  4377     int width = d->glcx->device()->width();
  4410     int width = d->glcx->device()->width();
  4378     int height = d->glcx->device()->height();
  4411     int height = d->glcx->device()->height();
  4379     bool auto_swap = autoBufferSwap();
  4412     bool auto_swap = autoBufferSwap();
  4380 
  4413 
       
  4414     QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
       
  4415     qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
  4381     QPaintEngine *engine = paintEngine();
  4416     QPaintEngine *engine = paintEngine();
  4382     if (engine->type() == QPaintEngine::OpenGL2)
       
  4383         static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(true);
       
  4384     QPainter *p;
  4417     QPainter *p;
  4385     bool reuse_painter = false;
  4418     bool reuse_painter = false;
  4386     if (engine->isActive()) {
  4419     if (engine->isActive()) {
  4387         reuse_painter = true;
  4420         reuse_painter = true;
  4388         p = engine->painter();
  4421         p = engine->painter();
  4398         glLoadIdentity();
  4431         glLoadIdentity();
  4399     } else {
  4432     } else {
  4400         setAutoBufferSwap(false);
  4433         setAutoBufferSwap(false);
  4401         // disable glClear() as a result of QPainter::begin()
  4434         // disable glClear() as a result of QPainter::begin()
  4402         d->disable_clear_on_painter_begin = true;
  4435         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);
  4436         p = new QPainter(this);
  4409     }
  4437     }
  4410 
  4438 
  4411     QRect viewport(view[0], view[1], view[2], view[3]);
  4439     QRect viewport(view[0], view[1], view[2], view[3]);
  4412     if (!use_scissor_testing && viewport != rect()) {
  4440     if (!use_scissor_testing && viewport != rect()) {
  4426     } else {
  4454     } else {
  4427         p->end();
  4455         p->end();
  4428         delete p;
  4456         delete p;
  4429         setAutoBufferSwap(auto_swap);
  4457         setAutoBufferSwap(auto_swap);
  4430         d->disable_clear_on_painter_begin = false;
  4458         d->disable_clear_on_painter_begin = false;
  4431         if (engine->type() == QPaintEngine::OpenGL2)
  4459     }
  4432             qt_restore_gl_state();
  4460     qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
  4433     }
       
  4434     if (engine->type() == QPaintEngine::OpenGL2)
       
  4435         static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(false);
       
  4436 #else // QT_OPENGL_ES
  4461 #else // QT_OPENGL_ES
  4437     Q_UNUSED(x);
  4462     Q_UNUSED(x);
  4438     Q_UNUSED(y);
  4463     Q_UNUSED(y);
  4439     Q_UNUSED(str);
  4464     Q_UNUSED(str);
  4440     Q_UNUSED(font);
  4465     Q_UNUSED(font);
  4478     GLdouble win_x = 0, win_y = 0, win_z = 0;
  4503     GLdouble win_x = 0, win_y = 0, win_z = 0;
  4479     qgluProject(x, y, z, &model[0][0], &proj[0][0], &view[0],
  4504     qgluProject(x, y, z, &model[0][0], &proj[0][0], &view[0],
  4480                 &win_x, &win_y, &win_z);
  4505                 &win_x, &win_y, &win_z);
  4481     win_y = height - win_y; // y is inverted
  4506     win_y = height - win_y; // y is inverted
  4482 
  4507 
       
  4508     QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
       
  4509     qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
  4483     QPaintEngine *engine = paintEngine();
  4510     QPaintEngine *engine = paintEngine();
  4484     if (engine->type() == QPaintEngine::OpenGL2)
       
  4485         static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(true);
       
  4486     QPainter *p;
  4511     QPainter *p;
  4487     bool reuse_painter = false;
  4512     bool reuse_painter = false;
  4488     bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
  4513     bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
  4489     bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
  4514     bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
  4490 
  4515 
  4494         qt_save_gl_state();
  4519         qt_save_gl_state();
  4495     } else {
  4520     } else {
  4496         setAutoBufferSwap(false);
  4521         setAutoBufferSwap(false);
  4497         // disable glClear() as a result of QPainter::begin()
  4522         // disable glClear() as a result of QPainter::begin()
  4498         d->disable_clear_on_painter_begin = true;
  4523         d->disable_clear_on_painter_begin = true;
  4499         if (engine->type() == QPaintEngine::OpenGL2)
       
  4500             qt_save_gl_state();
       
  4501         p = new QPainter(this);
  4524         p = new QPainter(this);
  4502     }
  4525     }
  4503 
  4526 
  4504     QRect viewport(view[0], view[1], view[2], view[3]);
  4527     QRect viewport(view[0], view[1], view[2], view[3]);
  4505     if (!use_scissor_testing && viewport != rect()) {
  4528     if (!use_scissor_testing && viewport != rect()) {
  4524     if (reuse_painter) {
  4547     if (reuse_painter) {
  4525         qt_restore_gl_state();
  4548         qt_restore_gl_state();
  4526     } else {
  4549     } else {
  4527         p->end();
  4550         p->end();
  4528         delete p;
  4551         delete p;
  4529         if (engine->type() == QPaintEngine::OpenGL2)
       
  4530             qt_restore_gl_state();
       
  4531         setAutoBufferSwap(auto_swap);
  4552         setAutoBufferSwap(auto_swap);
  4532         d->disable_clear_on_painter_begin = false;
  4553         d->disable_clear_on_painter_begin = false;
  4533     }
  4554     }
  4534     if (engine->type() == QPaintEngine::OpenGL2)
  4555     qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
  4535         static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(false);
       
  4536 #else // QT_OPENGL_ES
  4556 #else // QT_OPENGL_ES
  4537     Q_UNUSED(x);
  4557     Q_UNUSED(x);
  4538     Q_UNUSED(y);
  4558     Q_UNUSED(y);
  4539     Q_UNUSED(z);
  4559     Q_UNUSED(z);
  4540     Q_UNUSED(str);
  4560     Q_UNUSED(str);
  4842     d->init(context, shareWidget);
  4862     d->init(context, shareWidget);
  4843 }
  4863 }
  4844 
  4864 
  4845 #endif // QT3_SUPPORT
  4865 #endif // QT3_SUPPORT
  4846 
  4866 
  4847 void QGLExtensions::init_extensions()
  4867 /*
       
  4868     Returns the GL extensions for the current context.
       
  4869 */
       
  4870 QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
  4848 {
  4871 {
  4849     QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
  4872     QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
       
  4873     Extensions glExtensions;
  4850 
  4874 
  4851     if (extensions.match("GL_ARB_texture_rectangle"))
  4875     if (extensions.match("GL_ARB_texture_rectangle"))
  4852         glExtensions |= TextureRectangle;
  4876         glExtensions |= TextureRectangle;
  4853     if (extensions.match("GL_ARB_multisample"))
  4877     if (extensions.match("GL_ARB_multisample"))
  4854         glExtensions |= SampleBuffers;
  4878         glExtensions |= SampleBuffers;
  4905     if (extensions.match("GL_ARB_texture_non_power_of_two"))
  4929     if (extensions.match("GL_ARB_texture_non_power_of_two"))
  4906         glExtensions |= NPOTTextures;
  4930         glExtensions |= NPOTTextures;
  4907 
  4931 
  4908     if (extensions.match("GL_EXT_bgra"))
  4932     if (extensions.match("GL_EXT_bgra"))
  4909         glExtensions |= BGRATextureFormat;
  4933         glExtensions |= BGRATextureFormat;
       
  4934 
       
  4935     return glExtensions;
       
  4936 }
       
  4937 
       
  4938 /*
       
  4939     Returns the GL extensions for the current QGLContext. If there is no
       
  4940     current QGLContext, a default context will be created and the extensions
       
  4941     for that context will be returned instead.
       
  4942 */
       
  4943 QGLExtensions::Extensions QGLExtensions::glExtensions()
       
  4944 {
       
  4945     QGLTemporaryContext *tmpContext = 0;
       
  4946     static bool cachedDefault = false;
       
  4947     static Extensions defaultExtensions = 0;
       
  4948     QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext());
       
  4949 
       
  4950     if (currentCtx && currentCtx->d_func()->extension_flags_cached)
       
  4951         return currentCtx->d_func()->extension_flags;
       
  4952 
       
  4953     if (!currentCtx) {
       
  4954         if (cachedDefault) {
       
  4955             return defaultExtensions;
       
  4956         } else {
       
  4957             tmpContext = new QGLTemporaryContext;
       
  4958             cachedDefault = true;
       
  4959         }
       
  4960     }
       
  4961 
       
  4962     Extensions extensionFlags = currentContextExtensions();
       
  4963     if (currentCtx) {
       
  4964         currentCtx->d_func()->extension_flags_cached = true;
       
  4965         currentCtx->d_func()->extension_flags = extensionFlags;
       
  4966     } else {
       
  4967         defaultExtensions = extensionFlags;
       
  4968     }
       
  4969 
       
  4970     if (tmpContext)
       
  4971         delete tmpContext;
       
  4972 
       
  4973     return extensionFlags;
  4910 }
  4974 }
  4911 
  4975 
  4912 /*
  4976 /*
  4913   This is the shared initialization for all platforms. Called from QGLWidgetPrivate::init()
  4977   This is the shared initialization for all platforms. Called from QGLWidgetPrivate::init()
  4914 */
  4978 */
  4916 {
  4980 {
  4917     Q_Q(QGLWidget);
  4981     Q_Q(QGLWidget);
  4918 
  4982 
  4919     glDevice.setWidget(q);
  4983     glDevice.setWidget(q);
  4920 
  4984 
  4921     QGLExtensions::init();
       
  4922     glcx = 0;
  4985     glcx = 0;
  4923     autoSwap = true;
  4986     autoSwap = true;
  4924 
  4987 
  4925     if (context && !context->device())
  4988     if (context && !context->device())
  4926         context->setDevice(q);
  4989         context->setDevice(q);
  4927     q->setContext(context, shareWidget ? shareWidget->context() : 0);
  4990     q->setContext(context, shareWidget ? shareWidget->context() : 0);
  4928 
  4991 
  4929     if (!glcx)
  4992     if (!glcx)
  4930         glcx = new QGLContext(QGLFormat::defaultFormat(), q);
  4993         glcx = new QGLContext(QGLFormat::defaultFormat(), q);
  4931 
       
  4932     q->setAttribute(Qt::WA_NoSystemBackground);
       
  4933 }
  4994 }
  4934 
  4995 
  4935 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
  4996 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
  4936 Q_GLOBAL_STATIC(QString, qt_gl_lib_name)
  4997 Q_GLOBAL_STATIC(QString, qt_gl_lib_name)
  4937 
  4998 
  4951     }
  5012     }
  4952     return *qt_gl_lib_name();
  5013     return *qt_gl_lib_name();
  4953 }
  5014 }
  4954 #endif
  5015 #endif
  4955 
  5016 
  4956 void QGLShareRegister::addShare(const QGLContext *context, const QGLContext *share) {
  5017 void QGLContextGroup::addShare(const QGLContext *context, const QGLContext *share) {
  4957     Q_ASSERT(context && share);
  5018     Q_ASSERT(context && share);
  4958     if (context->d_ptr->group == share->d_ptr->group)
  5019     if (context->d_ptr->group == share->d_ptr->group)
  4959         return;
  5020         return;
  4960 
  5021 
  4961     // Make sure 'context' is not already shared with another group of contexts.
  5022     // Make sure 'context' is not already shared with another group of contexts.
  4972     if (group->m_shares.isEmpty())
  5033     if (group->m_shares.isEmpty())
  4973         group->m_shares.append(share);
  5034         group->m_shares.append(share);
  4974     group->m_shares.append(context);
  5035     group->m_shares.append(context);
  4975 }
  5036 }
  4976 
  5037 
  4977 QList<const QGLContext *> QGLShareRegister::shares(const QGLContext *context) {
  5038 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.
  5039     // Remove the context from the group.
  4983     QGLContextGroup *group = context->d_ptr->group;
  5040     QGLContextGroup *group = context->d_ptr->group;
  4984     if (group->m_shares.isEmpty())
  5041     if (group->m_shares.isEmpty())
  4985         return;
  5042         return;
  4986     group->m_shares.removeAll(context);
  5043     group->m_shares.removeAll(context);
  5171         // systems such as x86 and ARM at the moment.
  5228         // systems such as x86 and ARM at the moment.
  5172         return QSize();
  5229         return QSize();
  5173     }
  5230     }
  5174 #if !defined(QT_OPENGL_ES)
  5231 #if !defined(QT_OPENGL_ES)
  5175     if (!glCompressedTexImage2D) {
  5232     if (!glCompressedTexImage2D) {
  5176         if (!(QGLExtensions::glExtensions & QGLExtensions::TextureCompression)) {
  5233         if (!(QGLExtensions::glExtensions() & QGLExtensions::TextureCompression)) {
  5177             qWarning("QGLContext::bindTexture(): The GL implementation does "
  5234             qWarning("QGLContext::bindTexture(): The GL implementation does "
  5178                      "not support texture compression extensions.");
  5235                      "not support texture compression extensions.");
  5179             return QSize();
  5236             return QSize();
  5180         }
  5237         }
  5181         glCompressedTexImage2D = (_glCompressedTexImage2DARB) ctx->getProcAddress(QLatin1String("glCompressedTexImage2DARB"));
  5238         glCompressedTexImage2D = (_glCompressedTexImage2DARB) ctx->getProcAddress(QLatin1String("glCompressedTexImage2DARB"));
  5210     // We only support 2D texture loading at present.
  5267     // We only support 2D texture loading at present.
  5211     if (target != GL_TEXTURE_2D)
  5268     if (target != GL_TEXTURE_2D)
  5212         return QSize();
  5269         return QSize();
  5213 
  5270 
  5214     // Bail out if the necessary extension is not present.
  5271     // Bail out if the necessary extension is not present.
  5215     if (!(QGLExtensions::glExtensions & QGLExtensions::DDSTextureCompression)) {
  5272     if (!(QGLExtensions::glExtensions() & QGLExtensions::DDSTextureCompression)) {
  5216         qWarning("QGLContext::bindTexture(): DDS texture compression is not supported.");
  5273         qWarning("QGLContext::bindTexture(): DDS texture compression is not supported.");
  5217         return QSize();
  5274         return QSize();
  5218     }
  5275     }
  5219 
  5276 
  5220     const DDSFormat *ddsHeader = reinterpret_cast<const DDSFormat *>(buf + 4);
  5277     const DDSFormat *ddsHeader = reinterpret_cast<const DDSFormat *>(buf + 4);
  5320         return QSize();
  5377         return QSize();
  5321     }
  5378     }
  5322 
  5379 
  5323     // Bail out if the necessary extension is not present.
  5380     // Bail out if the necessary extension is not present.
  5324     if (textureFormat == GL_ETC1_RGB8_OES) {
  5381     if (textureFormat == GL_ETC1_RGB8_OES) {
  5325         if (!(QGLExtensions::glExtensions &
  5382         if (!(QGLExtensions::glExtensions() &
  5326                     QGLExtensions::ETC1TextureCompression)) {
  5383                     QGLExtensions::ETC1TextureCompression)) {
  5327             qWarning("QGLContext::bindTexture(): ETC1 texture compression is not supported.");
  5384             qWarning("QGLContext::bindTexture(): ETC1 texture compression is not supported.");
  5328             return QSize();
  5385             return QSize();
  5329         }
  5386         }
  5330     } else {
  5387     } else {
  5331         if (!(QGLExtensions::glExtensions &
  5388         if (!(QGLExtensions::glExtensions() &
  5332                     QGLExtensions::PVRTCTextureCompression)) {
  5389                     QGLExtensions::PVRTCTextureCompression)) {
  5333             qWarning("QGLContext::bindTexture(): PVRTC texture compression is not supported.");
  5390             qWarning("QGLContext::bindTexture(): PVRTC texture compression is not supported.");
  5334             return QSize();
  5391             return QSize();
  5335         }
  5392         }
  5336     }
  5393     }