Changeset 846 for trunk/src/opengl/qgl.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/opengl/qgl.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 201 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation ([email protected]) … … 50 50 #define INT32 dummy_INT32 51 51 #define INT8 dummy_INT8 52 #if !defined(QT_OPENGL_ES)52 #if 53 53 # include <GL/glx.h> 54 54 #endif … … 68 68 #include "qgl_p.h" 69 69 70 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)70 #if !defined(QT_OPENGL_ES_1) 71 71 #include "gl2paintengineex/qpaintengineex_opengl2_p.h" 72 72 #endif … … 92 92 #include "qfile.h" 93 93 #include "qlibrary.h" 94 94 95 95 96 96 97 QT_BEGIN_NAMESPACE 97 98 98 #ifdef QT_OPENGL_ES_1_CL 99 #include "qgl_cl_p.h" 100 #endif 101 102 103 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) 99 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) 104 100 QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs; 105 101 #endif … … 132 128 QGLSignalProxy *QGLSignalProxy::instance() 133 129 { 134 return theSignalProxy(); 130 QGLSignalProxy *proxy = theSignalProxy(); 131 if (proxy && proxy->thread() != qApp->thread()) { 132 if (proxy->thread() == QThread::currentThread()) 133 proxy->moveToThread(qApp->thread()); 134 } 135 return proxy; 135 136 } 136 137 … … 227 228 \value HasOverlay Enables the use of an overlay. 228 229 \value SampleBuffers Enables the use of sample buffers. 230 231 232 229 233 \value SingleBuffer Specifies the use of a single buffer, as opposed to double buffers. 230 234 \value NoDepthBuffer Disables the use of a depth buffer. … … 237 241 \value NoOverlay Disables the use of an overlay. 238 242 \value NoSampleBuffers Disables the use of sample buffers. 243 244 245 239 246 240 247 \sa {Sample Buffers Example} … … 508 515 flicker-free drawing and often better performance. 509 516 517 518 519 510 520 \sa doubleBuffer(), QGLContext::swapBuffers(), 511 521 QGLWidget::swapBuffers() … … 766 776 } 767 777 d->numSamples = numSamples; 778 768 779 } 769 780 … … 904 915 } 905 916 d->depthSize = size; 917 906 918 } 907 919 … … 1017 1029 } 1018 1030 d->alphaSize = size; 1019 set Option(QGL::AlphaChannel);1031 set); 1020 1032 } 1021 1033 … … 1044 1056 } 1045 1057 d->accumSize = size; 1058 1046 1059 } 1047 1060 … … 1069 1082 } 1070 1083 d->stencilSize = size; 1084 1071 1085 } 1072 1086 … … 1080 1094 return d->stencilSize; 1081 1095 } 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1082 1180 1083 1181 /*! … … 1117 1215 versionFlags |= QGLFormat::OpenGL_ES_Common_Version_1_1 | 1118 1216 QGLFormat::OpenGL_ES_CommonLite_Version_1_1; 1119 } 1120 else { 1217 } else { 1121 1218 // Not -CM, must be CL, CommonLite 1122 1219 versionFlags |= QGLFormat::OpenGL_ES_CommonLite_Version_1_0; … … 1124 1221 versionFlags |= QGLFormat::OpenGL_ES_CommonLite_Version_1_1; 1125 1222 } 1126 } 1127 else { 1223 } else { 1128 1224 // OpenGL ES version 2.0 or higher 1129 1225 versionFlags |= QGLFormat::OpenGL_ES_Version_2_0; 1130 1226 } 1131 } 1132 else { 1227 } else { 1133 1228 // if < 3 parts to the name, it is an unrecognised OpenGL ES 1134 1229 qWarning("Unrecognised OpenGL ES version"); 1135 1230 } 1136 } 1137 else { 1231 } else { 1138 1232 // not ES, regular OpenGL, the version numbers are first in the string 1139 1233 if (versionString.startsWith(QLatin1String("1."))) { … … 1152 1246 break; 1153 1247 } 1154 } 1155 else if (versionString.startsWith(QLatin1String("2."))) { 1248 } else if (versionString.startsWith(QLatin1String("2."))) { 1156 1249 versionFlags |= QGLFormat::OpenGL_Version_1_1 | 1157 1250 QGLFormat::OpenGL_Version_1_2 | … … 1160 1253 QGLFormat::OpenGL_Version_1_5 | 1161 1254 QGLFormat::OpenGL_Version_2_0; 1162 QString minorVersion = versionString.section(QLatin1Char(' '), 0, 0).section(QLatin1Char('.'), 1, 1); 1163 if (minorVersion == QChar(QLatin1Char('1'))) 1255 if (versionString[2].toAscii() == '1') 1164 1256 versionFlags |= QGLFormat::OpenGL_Version_2_1; 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1165 1307 } 1166 else if (versionString.startsWith(QLatin1String("3."))) {1167 versionFlags |= QGLFormat::OpenGL_Version_1_1 |1168 QGLFormat::OpenGL_Version_1_2 |1169 QGLFormat::OpenGL_Version_1_3 |1170 QGLFormat::OpenGL_Version_1_4 |1171 QGLFormat::OpenGL_Version_1_5 |1172 QGLFormat::OpenGL_Version_2_0 |1173 QGLFormat::OpenGL_Version_2_1 |1174 QGLFormat::OpenGL_Version_3_0;1175 }1176 else1177 qWarning("Unrecognised OpenGL version");1178 1308 } 1179 1309 return versionFlags; … … 1206 1336 1207 1337 \value OpenGL_Version_3_0 OpenGL version 3.0 or higher is present. 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1208 1348 1209 1349 \value OpenGL_ES_CommonLite_Version_1_0 OpenGL ES version 1.0 Common Lite or higher is present. … … 1378 1518 bool operator==(const QGLFormat& a, const QGLFormat& b) 1379 1519 { 1380 return (int) a.d->opts == (int) b.d->opts && a.d->pln == b.d->pln && a.d->alphaSize == b.d->alphaSize 1381 && a.d->accumSize == b.d->accumSize && a.d->stencilSize == b.d->stencilSize 1520 return (a.d == b.d) || ((int) a.d->opts == (int) b.d->opts 1521 && a.d->pln == b.d->pln 1522 && a.d->alphaSize == b.d->alphaSize 1523 && a.d->accumSize == b.d->accumSize 1524 && a.d->stencilSize == b.d->stencilSize 1382 1525 && a.d->depthSize == b.d->depthSize 1383 1526 && a.d->redSize == b.d->redSize … … 1385 1528 && a.d->blueSize == b.d->blueSize 1386 1529 && a.d->numSamples == b.d->numSamples 1387 && a.d->swapInterval == b.d->swapInterval; 1388 } 1530 && a.d->swapInterval == b.d->swapInterval 1531 && a.d->majorVersion == b.d->majorVersion 1532 && a.d->minorVersion == b.d->minorVersion 1533 && a.d->profile == b.d->profile); 1534 } 1535 1536 #ifndef QT_NO_DEBUG_STREAM 1537 QDebug operator<<(QDebug dbg, const QGLFormat &f) 1538 { 1539 const QGLFormatPrivate * const d = f.d; 1540 1541 dbg.nospace() << "QGLFormat(" 1542 << "options " << d->opts 1543 << ", plane " << d->pln 1544 << ", depthBufferSize " << d->depthSize 1545 << ", accumBufferSize " << d->accumSize 1546 << ", stencilBufferSize " << d->stencilSize 1547 << ", redBufferSize " << d->redSize 1548 << ", greenBufferSize " << d->greenSize 1549 << ", blueBufferSize " << d->blueSize 1550 << ", alphaBufferSize " << d->alphaSize 1551 << ", samples " << d->numSamples 1552 << ", swapInterval " << d->swapInterval 1553 << ", majorVersion " << d->majorVersion 1554 << ", minorVersion " << d->minorVersion 1555 << ", profile " << d->profile 1556 << ')'; 1557 1558 return dbg.space(); 1559 } 1560 #endif 1389 1561 1390 1562 … … 1400 1572 return !(a == b); 1401 1573 } 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1402 1591 1403 1592 /***************************************************************************** 1404 1593 QGLContext implementation 1405 1594 *****************************************************************************/ 1595 1596 1597 1598 1599 1600 1406 1601 1407 1602 QGLContextGroup::~QGLContextGroup() … … 1414 1609 guard = guard->m_next; 1415 1610 } 1611 1416 1612 } 1417 1613 … … 1447 1643 } 1448 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1449 1654 QGLContextPrivate::~QGLContextPrivate() 1450 1655 { … … 1453 1658 delete group; 1454 1659 } 1660 1661 1455 1662 } 1456 1663 … … 1481 1688 vi = 0; 1482 1689 #endif 1483 #if defined(QT_OPENGL_ES) 1690 #ifndef QT_NO_EGL 1691 ownsEglContext = false; 1484 1692 eglContext = 0; 1485 1693 eglSurface = EGL_NO_SURFACE; … … 1497 1705 default_fbo = 0; 1498 1706 active_engine = 0; 1707 1708 1709 1710 1711 1712 1713 1714 1499 1715 for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) 1500 1716 vertexAttributeArraysEnabledState[i] = false; … … 1567 1783 int w = size.width(); 1568 1784 int h = size.height(); 1569 #if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)1785 #if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) 1570 1786 //### glGetTexImage not in GL ES 2.0, need to do something else here! 1571 1787 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); … … 1595 1811 extern Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64; 1596 1812 1597 static QGLTextureCache *qt_gl_texture_cache = 0; 1813 1814 Q_GLOBAL_STATIC(QGLTextureCache, qt_gl_texture_cache) 1598 1815 1599 1816 QGLTextureCache::QGLTextureCache() 1600 1817 : m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though 1601 1818 { 1602 Q_ASSERT(qt_gl_texture_cache == 0);1603 qt_gl_texture_cache = this;1604 1605 1819 QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTexturesForPixampData); 1606 1820 QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction); … … 1610 1824 QGLTextureCache::~QGLTextureCache() 1611 1825 { 1612 qt_gl_texture_cache = 0;1613 1614 1826 QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData); 1615 1827 QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction); … … 1619 1831 void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, int cost) 1620 1832 { 1833 1621 1834 if (m_cache.totalCost() + cost > m_cache.maxCost()) { 1622 1835 // the cache is full - make an attempt to remove something 1623 const QList< qint64> keys = m_cache.keys();1836 const QList<> keys = m_cache.keys(); 1624 1837 int i = 0; 1625 1838 while (i < m_cache.count() … … 1631 1844 } 1632 1845 } 1633 m_cache.insert(key, texture, cost); 1846 const QGLTextureCacheKey cacheKey = {key, QGLContextPrivate::contextGroup(ctx)}; 1847 m_cache.insert(cacheKey, texture, cost); 1848 } 1849 1850 void QGLTextureCache::remove(qint64 key) 1851 { 1852 QWriteLocker locker(&m_lock); 1853 QMutexLocker groupLocker(&qt_context_groups()->m_mutex); 1854 QList<QGLContextGroup *>::const_iterator it = qt_context_groups()->m_list.constBegin(); 1855 while (it != qt_context_groups()->m_list.constEnd()) { 1856 const QGLTextureCacheKey cacheKey = {key, *it}; 1857 m_cache.remove(cacheKey); 1858 ++it; 1859 } 1634 1860 } 1635 1861 1636 1862 bool QGLTextureCache::remove(QGLContext* ctx, GLuint textureId) 1637 1863 { 1638 QList<qint64> keys = m_cache.keys(); 1864 QWriteLocker locker(&m_lock); 1865 QList<QGLTextureCacheKey> keys = m_cache.keys(); 1639 1866 for (int i = 0; i < keys.size(); ++i) { 1640 1867 QGLTexture *tex = m_cache.object(keys.at(i)); … … 1650 1877 void QGLTextureCache::removeContextTextures(QGLContext* ctx) 1651 1878 { 1652 QList<qint64> keys = m_cache.keys(); 1879 QWriteLocker locker(&m_lock); 1880 QList<QGLTextureCacheKey> keys = m_cache.keys(); 1653 1881 for (int i = 0; i < keys.size(); ++i) { 1654 const qint64&key = keys.at(i);1882 const &key = keys.at(i); 1655 1883 if (m_cache.object(key)->context == ctx) 1656 1884 m_cache.remove(key); 1657 1885 } 1658 }1659 1660 QGLTextureCache* QGLTextureCache::instance()1661 {1662 if (!qt_gl_texture_cache)1663 qt_gl_texture_cache = new QGLTextureCache;1664 1665 return qt_gl_texture_cache;1666 1886 } 1667 1887 … … 1672 1892 void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey) 1673 1893 { 1674 // ### remove when the GL texture cache becomes thread-safe 1675 if (qApp->thread() == QThread::currentThread()) { 1676 instance()->remove(cacheKey); 1677 Q_ASSERT(instance()->getTexture(cacheKey) == 0); 1678 } 1894 qt_gl_texture_cache()->remove(cacheKey); 1679 1895 } 1680 1896 … … 1698 1914 } 1699 1915 1700 void QGLTextureCache::deleteIfEmpty() 1701 { 1702 if (instance()->size() == 0) 1703 delete instance(); 1916 QGLTextureCache *QGLTextureCache::instance() 1917 { 1918 return qt_gl_texture_cache(); 1704 1919 } 1705 1920 … … 1801 2016 1802 2017 \omitvalue CanFlipNativePixmapBindOption Used by x11 from pixmap to choose 1803 w ether or not it can bind the pixmap upside down or not.2018 wether or not it can bind the pixmap upside down or not. 1804 2019 1805 2020 \omitvalue MemoryManagedBindOption Used by paint engines to … … 1867 2082 // remove any textures cached in this context 1868 2083 QGLTextureCache::instance()->removeContextTextures(this); 1869 QGLTextureCache::deleteIfEmpty(); // ### thread safety1870 2084 1871 2085 d_ptr->group->cleanupResources(this); … … 1883 2097 { 1884 2098 Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT); 2099 1885 2100 Q_ASSERT(glEnableVertexAttribArray); 2101 1886 2102 1887 2103 if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled) … … 1896 2112 void QGLContextPrivate::syncGlState() 1897 2113 { 2114 1898 2115 Q_ASSERT(glEnableVertexAttribArray); 2116 1899 2117 for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) { 1900 2118 if (vertexAttributeArraysEnabledState[i]) … … 1907 2125 #undef ctx 1908 2126 2127 2128 2129 2130 2131 2132 2133 1909 2134 1910 2135 /*! … … 2061 2286 } 2062 2287 2288 2289 2290 2291 2292 2293 2294 2063 2295 QImage QGLContextPrivate::convertToGLFormat(const QImage &image, bool force_premul, 2064 2296 GLenum texture_format) … … 2077 2309 QGLContext::BindOptions options) 2078 2310 { 2311 2312 2079 2313 const qint64 key = image.cacheKey(); 2080 2314 QGLTexture *texture = textureCacheLookup(key, target); 2081 2315 if (texture) { 2082 glBindTexture(target, texture->id); 2083 return texture; 2316 if (image.paintingActive()) { 2317 // A QPainter is active on the image - take the safe route and replace the texture. 2318 q->deleteTexture(texture->id); 2319 texture = 0; 2320 } else { 2321 glBindTexture(target, texture->id); 2322 return texture; 2323 } 2084 2324 } 2085 2325 … … 2127 2367 2128 2368 #ifdef QGL_BIND_TEXTURE_DEBUG 2129 printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x \n",2130 image.width(), image.height(), internalFormat, int(options) );2369 printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x\n", 2370 image.width(), image.height(), internalFormat, int(options)); 2131 2371 QTime time; 2132 2372 time.start(); … … 2172 2412 && (options & QGLContext::MipmapBindOption)) 2173 2413 { 2174 #ifdef QGL_BIND_TEXTURE_DEBUG2175 printf(" - generating mipmaps (%d ms)\n", time.elapsed());2176 #endif2177 2414 #if !defined(QT_OPENGL_ES_2) 2178 2415 glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); … … 2188 2425 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, options & QGLContext::LinearFilteringBindOption 2189 2426 ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST); 2427 2428 2429 2190 2430 } else { 2191 2431 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, filtering); … … 2212 2452 img = img.convertToFormat(target_format = QImage::Format_ARGB32_Premultiplied); 2213 2453 #ifdef QGL_BIND_TEXTURE_DEBUG 2214 printf(" - convert ingARGB32 -> ARGB32_Premultiplied (%d ms) \n", time.elapsed());2454 printf(" - convert ARGB32 -> ARGB32_Premultiplied (%d ms) \n", time.elapsed()); 2215 2455 #endif 2216 2456 } … … 2220 2460 img = img.convertToFormat(target_format = QImage::Format_ARGB32); 2221 2461 #ifdef QGL_BIND_TEXTURE_DEBUG 2222 printf(" - convert ingARGB32_Premultiplied -> ARGB32 (%d ms)\n", time.elapsed());2462 printf(" - convert ARGB32_Premultiplied -> ARGB32 (%d ms)\n", time.elapsed()); 2223 2463 #endif 2224 2464 } … … 2237 2477 : QImage::Format_ARGB32); 2238 2478 #ifdef QGL_BIND_TEXTURE_DEBUG 2239 printf(" - convert ingto 32-bit alpha format (%d ms)\n", time.elapsed());2479 printf(" - convert to 32-bit alpha format (%d ms)\n", time.elapsed()); 2240 2480 #endif 2241 2481 } else { 2242 2482 img = img.convertToFormat(QImage::Format_RGB32); 2243 2483 #ifdef QGL_BIND_TEXTURE_DEBUG 2244 printf(" - convert ingto 32-bit (%d ms)\n", time.elapsed());2484 printf(" - convert to 32-bit (%d ms)\n", time.elapsed()); 2245 2485 #endif 2246 2486 } … … 2248 2488 2249 2489 if (options & QGLContext::InvertedYBindOption) { 2250 #ifdef QGL_BIND_TEXTURE_DEBUG2251 printf(" - flipping bits over y (%d ms)\n", time.elapsed());2252 #endif2253 2490 if (img.isDetached()) { 2254 2491 int ipl = img.bytesPerLine() / 4; … … 2267 2504 img = img.mirrored(); 2268 2505 } 2506 2507 2508 2269 2509 } 2270 2510 2271 2511 if (externalFormat == GL_RGBA) { 2272 #ifdef QGL_BIND_TEXTURE_DEBUG2273 printf(" - doing byte swapping (%d ms)\n", time.elapsed());2274 #endif2275 2512 // The only case where we end up with a depth different from 2276 2513 // 32 in the switch above is for the RGB16 case, where we set … … 2278 2515 Q_ASSERT(img.depth() == 32); 2279 2516 qgl_byteSwapImage(img, pixel_type); 2517 2518 2519 2280 2520 } 2281 2521 #ifdef QT_OPENGL_ES … … 2299 2539 GLenum error = glGetError(); 2300 2540 if (error != GL_NO_ERROR) { 2301 qWarning(" - texture upload failed, error code 0x%x \n", error);2541 qWarning(" - texture upload failed, error code 0x%x); 2302 2542 } 2303 2543 #endif … … 2306 2546 static int totalUploadTime = 0; 2307 2547 totalUploadTime += time.elapsed(); 2308 printf(" - upload done in (%d ms) time=%d\n", time.elapsed(), totalUploadTime);2548 printf(" - upload done in \n", time.elapsed(), totalUploadTime); 2309 2549 #endif 2310 2550 … … 2321 2561 { 2322 2562 Q_Q(QGLContext); 2323 QGLTexture *texture = QGLTextureCache::instance()->getTexture( key);2563 QGLTexture *texture = QGLTextureCache::instance()->getTexture(key); 2324 2564 if (texture && texture->target == target 2325 2565 && (texture->context == q || QGLContext::areSharing(q, texture->context))) … … 2336 2576 Q_Q(QGLContext); 2337 2577 QPixmapData *pd = pixmap.pixmapData(); 2338 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)2578 #if !defined(QT_OPENGL_ES_1) 2339 2579 if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) { 2340 2580 const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pd); … … 2347 2587 #else 2348 2588 Q_UNUSED(pd); 2349 Q_UNUSED(q);2350 2589 #endif 2351 2590 … … 2353 2592 QGLTexture *texture = textureCacheLookup(key, target); 2354 2593 if (texture) { 2355 glBindTexture(target, texture->id); 2356 return texture; 2594 if (pixmap.paintingActive()) { 2595 // A QPainter is active on the pixmap - take the safe route and replace the texture. 2596 q->deleteTexture(texture->id); 2597 texture = 0; 2598 } else { 2599 glBindTexture(target, texture->id); 2600 return texture; 2601 } 2357 2602 } 2358 2603 … … 2361 2606 const QX11Info *xinfo = qt_x11Info(paintDevice); 2362 2607 if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType 2363 && xinfo && xinfo->screen() == pixmap.x11Info().screen()) 2608 && xinfo && xinfo->screen() == pixmap.x11Info().screen() 2609 && target == GL_TEXTURE_2D) 2364 2610 { 2365 texture = bindTextureFromNativePixmap(pd, key, options); 2366 if (texture) { 2367 texture->options |= QGLContext::MemoryManagedBindOption; 2368 texture->boundPixmap = pd; 2369 boundPixmaps.insert(pd, QPixmap(pixmap)); 2611 if (!workaround_brokenTextureFromPixmap_init) { 2612 workaround_brokenTextureFromPixmap_init = true; 2613 2614 const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION))); 2615 const int pos = versionString.indexOf("NVIDIA "); 2616 2617 if (pos >= 0) { 2618 const QByteArray nvidiaVersionString = versionString.mid(pos + strlen("NVIDIA ")); 2619 2620 if (nvidiaVersionString.startsWith("195") || nvidiaVersionString.startsWith("256")) 2621 workaround_brokenTextureFromPixmap = true; 2622 } 2370 2623 } 2371 } 2372 #endif 2373 2374 if (!texture) 2375 texture = bindTexture(pixmap.toImage(), target, format, key, options); 2624 2625 if (!workaround_brokenTextureFromPixmap) { 2626 texture = bindTextureFromNativePixmap(const_cast<QPixmap*>(&pixmap), key, options); 2627 if (texture) { 2628 texture->options |= QGLContext::MemoryManagedBindOption; 2629 texture->boundPixmap = pd; 2630 boundPixmaps.insert(pd, QPixmap(pixmap)); 2631 } 2632 } 2633 } 2634 #endif 2635 2636 if (!texture) { 2637 QImage image = pixmap.toImage(); 2638 // If the system depth is 16 and the pixmap doesn't have an alpha channel 2639 // then we convert it to RGB16 in the hope that it gets uploaded as a 16 2640 // bit texture which is much faster to access than a 32-bit one. 2641 if (pixmap.depth() == 16 && !image.hasAlphaChannel() ) 2642 image = image.convertToFormat(QImage::Format_RGB16); 2643 texture = bindTexture(image, target, format, key, options); 2644 } 2376 2645 // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null 2377 2646 Q_ASSERT(texture); … … 2466 2735 2467 2736 Q_D(QGLContext); 2468 QGLTexture *texture = d->bindTexture(image, target, format, false,options);2737 QGLTexture *texture = d->bindTexture(image, target, format, options); 2469 2738 return texture->id; 2470 2739 } … … 2478 2747 2479 2748 Q_D(QGLContext); 2480 QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false,DefaultBindOption);2749 QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), DefaultBindOption); 2481 2750 return texture->id; 2482 2751 } … … 2490 2759 2491 2760 Q_D(QGLContext); 2492 QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false,options);2761 QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), options); 2493 2762 return texture->id; 2494 2763 } … … 2588 2857 #endif 2589 2858 2590 void qt_add_rect_to_array(const QRectF &r, q_vertexType*array)2859 void qt_add_rect_to_array(const QRectF &r, *array) 2591 2860 { 2592 2861 qreal left = r.left(); … … 2595 2864 qreal bottom = r.bottom(); 2596 2865 2597 array[0] = f2vt(left);2598 array[1] = f2vt(top);2599 array[2] = f2vt(right);2600 array[3] = f2vt(top);2601 array[4] = f2vt(right);2602 array[5] = f2vt(bottom);2603 array[6] = f2vt(left);2604 array[7] = f2vt(bottom);2605 } 2606 2607 void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType*array)2608 { 2609 array[0] = f2vt(x1);2610 array[1] = f2vt(y1);2611 array[2] = f2vt(x2);2612 array[3] = f2vt(y1);2613 array[4] = f2vt(x2);2614 array[5] = f2vt(y2);2615 array[6] = f2vt(x1);2616 array[7] = f2vt(y2);2866 array[0] = ; 2867 array[1] = ; 2868 array[2] = ; 2869 array[3] = ; 2870 array[4] = ; 2871 array[5] = ; 2872 array[6] = ; 2873 array[7] = ; 2874 } 2875 2876 void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, *array) 2877 { 2878 array[0] = ; 2879 array[1] = ; 2880 array[2] = ; 2881 array[3] = ; 2882 array[4] = ; 2883 array[5] = ; 2884 array[6] = ; 2885 array[7] = ; 2617 2886 } 2618 2887 … … 2621 2890 static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint textureHeight, GLenum textureTarget) 2622 2891 { 2623 q_vertexType tx = f2vt(1);2624 q_vertexType ty = f2vt(1);2892 ; 2893 ; 2625 2894 2626 2895 #ifdef QT_OPENGL_ES … … 2635 2904 } 2636 2905 2637 tx = f2vt(textureWidth);2638 ty = f2vt(textureHeight);2639 } 2640 #endif 2641 2642 q_vertexTypetexCoordArray[4*2] = {2906 tx = t(textureWidth); 2907 ty = t(textureHeight); 2908 } 2909 #endif 2910 2911 texCoordArray[4*2] = { 2643 2912 0, ty, tx, ty, tx, 0, 0, 0 2644 2913 }; 2645 2914 2646 q_vertexTypevertexArray[4*2];2915 vertexArray[4*2]; 2647 2916 qt_add_rect_to_array(target, vertexArray); 2648 2917 2649 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);2650 glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray);2918 glVertexPointer(2, , 0, vertexArray); 2919 glTexCoordPointer(2, , 0, texCoordArray); 2651 2920 2652 2921 glEnableClientState(GL_VERTEX_ARRAY); … … 2663 2932 \since 4.4 2664 2933 2665 Draws the given texture, \a textureId, to the given target rectangle, 2666 \a target, in OpenGL model space. The \a textureTarget should be a 2D 2667 texture target. 2668 2669 \note This function is not supported under OpenGL/ES 2.0. 2934 This function supports the following use cases: 2935 2936 \list 2937 \i On OpenGL and OpenGL ES 1.x it draws the given texture, \a textureId, 2938 to the given target rectangle, \a target, in OpenGL model space. The 2939 \a textureTarget should be a 2D texture target. 2940 \i On OpenGL and OpenGL ES 2.x, if a painter is active, not inside a 2941 beginNativePainting / endNativePainting block, and uses the 2942 engine with type QPaintEngine::OpenGL2, the function will draw the given 2943 texture, \a textureId, to the given target rectangle, \a target, 2944 respecting the current painter state. This will let you draw a texture 2945 with the clip, transform, render hints, and composition mode set by the 2946 painter. Note that the texture target needs to be GL_TEXTURE_2D for this 2947 use case, and that this is the only supported use case under OpenGL ES 2.x. 2948 \endlist 2949 2670 2950 */ 2671 2951 void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) 2672 2952 { 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2673 2966 #ifndef QT_OPENGL_ES_2 2674 2967 #ifdef QT_OPENGL_ES … … 2699 2992 Q_UNUSED(textureId); 2700 2993 Q_UNUSED(textureTarget); 2701 qWarning("drawTexture( const QRectF &target, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES/2.0");2994 qWarning("drawTexture("); 2702 2995 #endif 2703 2996 } … … 2714 3007 \since 4.4 2715 3008 2716 Draws the given texture at the given \a point in OpenGL model 2717 space. The \a textureTarget should be a 2D texture target. 2718 2719 \note This function is not supported under OpenGL/ES. 3009 This function supports the following use cases: 3010 3011 \list 3012 \i By default it draws the given texture, \a textureId, 3013 at the given \a point in OpenGL model space. The 3014 \a textureTarget should be a 2D texture target. 3015 \i If a painter is active, not inside a 3016 beginNativePainting / endNativePainting block, and uses the 3017 engine with type QPaintEngine::OpenGL2, the function will draw the given 3018 texture, \a textureId, at the given \a point, 3019 respecting the current painter state. This will let you draw a texture 3020 with the clip, transform, render hints, and composition mode set by the 3021 painter. Note that the texture target needs to be GL_TEXTURE_2D for this 3022 use case. 3023 \endlist 3024 3025 \note This function is not supported under any version of OpenGL ES. 2720 3026 */ 2721 3027 void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) 2722 3028 { 2723 // this would be ok on OpenGL ES 2.0, but currently we don't have a define for that2724 3029 #ifdef QT_OPENGL_ES 2725 3030 Q_UNUSED(point); … … 2728 3033 qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead"); 2729 3034 #else 3035 2730 3036 const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); 2731 3037 GLint oldTexture; … … 2740 3046 glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); 2741 3047 glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 2742 3060 2743 3061 qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget); … … 3199 3517 \sa QGLWidget::renderText() 3200 3518 */ 3519 3201 3520 3202 3521 … … 3321 3640 \l{Overpainting Example}{Overpainting} example. 3322 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3323 3651 \e{OpenGL is a trademark of Silicon Graphics, Inc. in the United States and other 3324 3652 countries.} … … 3448 3776 #endif 3449 3777 delete d->glcx; 3450 #if defined(Q_WGL) 3778 d->glcx = 0; 3779 #if defined(Q_WS_WIN) 3451 3780 delete d->olcx; 3781 3452 3782 #endif 3453 3783 #if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT) … … 3851 4181 } 3852 4182 3853 #if defined(QT_OPENGL_ES)4183 #if 3854 4184 // A re-parent is likely to destroy the X11 window and re-create it. It is important 3855 4185 // that we free the EGL surface _before_ the winID changes - otherwise we can leak. … … 3860 4190 // The window may have been re-created during re-parent or state change - if so, the EGL 3861 4191 // surface will need to be re-created. 3862 d->recreateEglSurface( false);4192 d->recreateEglSurface(); 3863 4193 } 3864 4194 #endif … … 3902 4232 # endif 3903 4233 } 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 3904 4262 #endif 3905 4263 … … 4109 4467 if (!isValid()) 4110 4468 return; 4469 4470 4471 4472 4473 4111 4474 makeCurrent(); 4112 4475 #ifndef QT_OPENGL_ES … … 4766 5129 \since 4.4 4767 5130 4768 Draws the given texture, \a textureId to the given target rectangle, 4769 \a target, in OpenGL model space. The \a textureTarget should be a 2D 4770 texture target. 4771 4772 Equivalent to the corresponding QGLContext::drawTexture(). 5131 Calls the corresponding QGLContext::drawTexture() with 5132 \a target, \a textureId, and \a textureTarget for this 5133 widget's context. 4773 5134 */ 4774 5135 void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) … … 4790 5151 \since 4.4 4791 5152 4792 Draws the given texture, \a textureId, at the given \a point in OpenGL 4793 model space. The \a textureTarget should be a 2D texture target. 4794 4795 Equivalent to the corresponding QGLContext::drawTexture(). 5153 Calls the corresponding QGLContext::drawTexture() with 5154 \a point, \a textureId, and \a textureTarget for this 5155 widget's context. 4796 5156 */ 4797 5157 void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) … … 4810 5170 #endif 4811 5171 4812 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)5172 #if 4813 5173 Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_2_engine) 4814 5174 #endif … … 4820 5180 Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine() 4821 5181 { 4822 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)5182 #if defined(QT_OPENGL_ES_1) 4823 5183 return qt_gl_engine(); 4824 5184 #elif defined(QT_OPENGL_ES_2) … … 4924 5284 if (extensions.match("GL_ARB_fragment_shader")) 4925 5285 glExtensions |= FragmentShader; 5286 5287 4926 5288 if (extensions.match("GL_ARB_texture_mirrored_repeat")) 4927 5289 glExtensions |= MirroredRepeat; … … 4938 5300 if (extensions.match("GL_ARB_pixel_buffer_object")) 4939 5301 glExtensions |= PixelBufferObject; 5302 5303 4940 5304 #if defined(QT_OPENGL_ES_2) 4941 5305 glExtensions |= FramebufferObject; … … 4943 5307 glExtensions |= FragmentShader; 4944 5308 #endif 4945 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)5309 #if defined(QT_OPENGL_ES_1) 4946 5310 if (extensions.match("GL_OES_framebuffer_object")) 4947 5311 glExtensions |= FramebufferObject; … … 4950 5314 if (extensions.match("GL_OES_packed_depth_stencil")) 4951 5315 glExtensions |= PackedDepthStencil; 5316 5317 5318 5319 5320 5321 4952 5322 #endif 4953 5323 if (extensions.match("GL_ARB_framebuffer_object")) { … … 4969 5339 } 4970 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 4971 5355 /* 4972 5356 Returns the GL extensions for the current QGLContext. If there is no … … 4976 5360 QGLExtensions::Extensions QGLExtensions::glExtensions() 4977 5361 { 4978 QGLTemporaryContext *tmpContext = 0; 4979 static bool cachedDefault = false; 4980 static Extensions defaultExtensions = 0; 5362 Extensions extensionFlags = 0; 4981 5363 QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext()); 4982 5364 … … 4985 5367 4986 5368 if (!currentCtx) { 4987 if (cachedDefault) { 4988 return defaultExtensions; 4989 } else { 4990 tmpContext = new QGLTemporaryContext; 4991 cachedDefault = true; 4992 } 4993 } 4994 4995 Extensions extensionFlags = currentContextExtensions(); 4996 if (currentCtx) { 5369 extensionFlags = qtDefaultExtensions()->extensions; 5370 } else { 5371 extensionFlags = currentContextExtensions(); 4997 5372 currentCtx->d_func()->extension_flags_cached = true; 4998 5373 currentCtx->d_func()->extension_flags = extensionFlags; 4999 } else { 5000 defaultExtensions = extensionFlags; 5001 } 5002 5003 if (tmpContext) 5004 delete tmpContext; 5005 5374 } 5006 5375 return extensionFlags; 5007 5376 } … … 5038 5407 { 5039 5408 if (qt_gl_lib_name()->isNull()) { 5040 #if defined(Q_WS_X11) || defined(Q_WS_QWS) 5409 #ifdef Q_WS_MAC 5410 return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"); 5411 #else 5412 # if defined(QT_OPENGL_ES_1) 5413 return QLatin1String("GLES_CM"); 5414 # elif defined(QT_OPENGL_ES_2) 5415 return QLatin1String("GLESv2"); 5416 # else 5041 5417 return QLatin1String("GL"); 5042 #else // Q_WS_MAC 5043 return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"); 5044 #endif 5418 # endif 5419 #endif // defined Q_WS_MAC 5045 5420 } 5046 5421 return *qt_gl_lib_name();
Note:
See TracChangeset
for help on using the changeset viewer.