224 \value StencilBuffer Enables the use of a stencil buffer. |
219 \value StencilBuffer Enables the use of a stencil buffer. |
225 \value StereoBuffers Enables the use of a stereo buffers for use with visualization hardware. |
220 \value StereoBuffers Enables the use of a stereo buffers for use with visualization hardware. |
226 \value DirectRendering Specifies that the context is used for direct rendering to a display. |
221 \value DirectRendering Specifies that the context is used for direct rendering to a display. |
227 \value HasOverlay Enables the use of an overlay. |
222 \value HasOverlay Enables the use of an overlay. |
228 \value SampleBuffers Enables the use of sample buffers. |
223 \value SampleBuffers Enables the use of sample buffers. |
|
224 \value DeprecatedFunctions Enables the use of deprecated functionality for OpenGL 3.x |
|
225 contexts. A context with deprecated functionality enabled is |
|
226 called a full context in the OpenGL specification. |
229 \value SingleBuffer Specifies the use of a single buffer, as opposed to double buffers. |
227 \value SingleBuffer Specifies the use of a single buffer, as opposed to double buffers. |
230 \value NoDepthBuffer Disables the use of a depth buffer. |
228 \value NoDepthBuffer Disables the use of a depth buffer. |
231 \value ColorIndex Specifies that the context should use a color index as its pixel format. |
229 \value ColorIndex Specifies that the context should use a color index as its pixel format. |
232 \value NoAlphaChannel Disables the use of an alpha channel. |
230 \value NoAlphaChannel Disables the use of an alpha channel. |
233 \value NoAccumBuffer Disables the use of an accumulation buffer. |
231 \value NoAccumBuffer Disables the use of an accumulation buffer. |
234 \value NoStencilBuffer Disables the use of a stencil buffer. |
232 \value NoStencilBuffer Disables the use of a stencil buffer. |
235 \value NoStereoBuffers Disables the use of stereo buffers. |
233 \value NoStereoBuffers Disables the use of stereo buffers. |
236 \value IndirectRendering Specifies that the context is used for indirect rendering to a buffer. |
234 \value IndirectRendering Specifies that the context is used for indirect rendering to a buffer. |
237 \value NoOverlay Disables the use of an overlay. |
235 \value NoOverlay Disables the use of an overlay. |
238 \value NoSampleBuffers Disables the use of sample buffers. |
236 \value NoSampleBuffers Disables the use of sample buffers. |
|
237 \value NoDeprecatedFunctions Disables the use of deprecated functionality for OpenGL 3.x |
|
238 contexts. A context with deprecated functionality disabled is |
|
239 called a forward compatible context in the OpenGL specification. |
239 |
240 |
240 \sa {Sample Buffers Example} |
241 \sa {Sample Buffers Example} |
241 */ |
242 */ |
242 |
243 |
243 /*! |
244 /*! |
1077 */ |
1082 */ |
1078 int QGLFormat::stencilBufferSize() const |
1083 int QGLFormat::stencilBufferSize() const |
1079 { |
1084 { |
1080 return d->stencilSize; |
1085 return d->stencilSize; |
1081 } |
1086 } |
|
1087 |
|
1088 /*! |
|
1089 \since 4.7 |
|
1090 |
|
1091 Set the OpenGL version to the \a major and \a minor numbers. If a |
|
1092 context compatible with the requested OpenGL version cannot be |
|
1093 created, a context compatible with version 1.x is created instead. |
|
1094 |
|
1095 \sa majorVersion(), minorVersion() |
|
1096 */ |
|
1097 void QGLFormat::setVersion(int major, int minor) |
|
1098 { |
|
1099 if (major < 1 || minor < 0) { |
|
1100 qWarning("QGLFormat::setVersion: Cannot set zero or negative version number %d.%d", major, minor); |
|
1101 return; |
|
1102 } |
|
1103 detach(); |
|
1104 d->majorVersion = major; |
|
1105 d->minorVersion = minor; |
|
1106 } |
|
1107 |
|
1108 /*! |
|
1109 \since 4.7 |
|
1110 |
|
1111 Returns the OpenGL major version. |
|
1112 |
|
1113 \sa setVersion(), minorVersion() |
|
1114 */ |
|
1115 int QGLFormat::majorVersion() const |
|
1116 { |
|
1117 return d->majorVersion; |
|
1118 } |
|
1119 |
|
1120 /*! |
|
1121 \since 4.7 |
|
1122 |
|
1123 Returns the OpenGL minor version. |
|
1124 |
|
1125 \sa setVersion(), majorVersion() |
|
1126 */ |
|
1127 int QGLFormat::minorVersion() const |
|
1128 { |
|
1129 return d->minorVersion; |
|
1130 } |
|
1131 |
|
1132 /*! |
|
1133 \enum QGLFormat::OpenGLContextProfile |
|
1134 \since 4.7 |
|
1135 |
|
1136 This enum describes the OpenGL context profiles that can be |
|
1137 specified for contexts implementing OpenGL version 3.2 or |
|
1138 higher. These profiles are different from OpenGL ES profiles. |
|
1139 |
|
1140 \value NoProfile OpenGL version is lower than 3.2. |
|
1141 \value CoreProfile Functionality deprecated in OpenGL version 3.0 is not available. |
|
1142 \value CompatibilityProfile Functionality from earlier OpenGL versions is available. |
|
1143 */ |
|
1144 |
|
1145 /*! |
|
1146 \since 4.7 |
|
1147 |
|
1148 Set the OpenGL context profile to \a profile. The \a profile is |
|
1149 ignored if the requested OpenGL version is less than 3.2. |
|
1150 |
|
1151 \sa profile() |
|
1152 */ |
|
1153 void QGLFormat::setProfile(OpenGLContextProfile profile) |
|
1154 { |
|
1155 detach(); |
|
1156 d->profile = profile; |
|
1157 } |
|
1158 |
|
1159 /*! |
|
1160 \since 4.7 |
|
1161 |
|
1162 Returns the OpenGL context profile. |
|
1163 |
|
1164 \sa setProfile() |
|
1165 */ |
|
1166 QGLFormat::OpenGLContextProfile QGLFormat::profile() const |
|
1167 { |
|
1168 return d->profile; |
|
1169 } |
|
1170 |
1082 |
1171 |
1083 /*! |
1172 /*! |
1084 \fn bool QGLFormat::hasOpenGL() |
1173 \fn bool QGLFormat::hasOpenGL() |
1085 |
1174 |
1086 Returns true if the window system has any OpenGL support; |
1175 Returns true if the window system has any OpenGL support; |
1114 versionFlags |= QGLFormat::OpenGL_ES_Common_Version_1_0 | |
1203 versionFlags |= QGLFormat::OpenGL_ES_Common_Version_1_0 | |
1115 QGLFormat::OpenGL_ES_CommonLite_Version_1_0; |
1204 QGLFormat::OpenGL_ES_CommonLite_Version_1_0; |
1116 if (parts[2].startsWith(QLatin1String("1.1"))) |
1205 if (parts[2].startsWith(QLatin1String("1.1"))) |
1117 versionFlags |= QGLFormat::OpenGL_ES_Common_Version_1_1 | |
1206 versionFlags |= QGLFormat::OpenGL_ES_Common_Version_1_1 | |
1118 QGLFormat::OpenGL_ES_CommonLite_Version_1_1; |
1207 QGLFormat::OpenGL_ES_CommonLite_Version_1_1; |
1119 } |
1208 } else { |
1120 else { |
|
1121 // Not -CM, must be CL, CommonLite |
1209 // Not -CM, must be CL, CommonLite |
1122 versionFlags |= QGLFormat::OpenGL_ES_CommonLite_Version_1_0; |
1210 versionFlags |= QGLFormat::OpenGL_ES_CommonLite_Version_1_0; |
1123 if (parts[2].startsWith(QLatin1String("1.1"))) |
1211 if (parts[2].startsWith(QLatin1String("1.1"))) |
1124 versionFlags |= QGLFormat::OpenGL_ES_CommonLite_Version_1_1; |
1212 versionFlags |= QGLFormat::OpenGL_ES_CommonLite_Version_1_1; |
1125 } |
1213 } |
1126 } |
1214 } else { |
1127 else { |
|
1128 // OpenGL ES version 2.0 or higher |
1215 // OpenGL ES version 2.0 or higher |
1129 versionFlags |= QGLFormat::OpenGL_ES_Version_2_0; |
1216 versionFlags |= QGLFormat::OpenGL_ES_Version_2_0; |
1130 } |
1217 } |
1131 } |
1218 } else { |
1132 else { |
|
1133 // if < 3 parts to the name, it is an unrecognised OpenGL ES |
1219 // if < 3 parts to the name, it is an unrecognised OpenGL ES |
1134 qWarning("Unrecognised OpenGL ES version"); |
1220 qWarning("Unrecognised OpenGL ES version"); |
1135 } |
1221 } |
1136 } |
1222 } else { |
1137 else { |
|
1138 // not ES, regular OpenGL, the version numbers are first in the string |
1223 // not ES, regular OpenGL, the version numbers are first in the string |
1139 if (versionString.startsWith(QLatin1String("1."))) { |
1224 if (versionString.startsWith(QLatin1String("1."))) { |
1140 switch (versionString[2].toAscii()) { |
1225 switch (versionString[2].toAscii()) { |
1141 case '5': |
1226 case '5': |
1142 versionFlags |= QGLFormat::OpenGL_Version_1_5; |
1227 versionFlags |= QGLFormat::OpenGL_Version_1_5; |
1149 case '1': |
1234 case '1': |
1150 versionFlags |= QGLFormat::OpenGL_Version_1_1; |
1235 versionFlags |= QGLFormat::OpenGL_Version_1_1; |
1151 default: |
1236 default: |
1152 break; |
1237 break; |
1153 } |
1238 } |
1154 } |
1239 } else if (versionString.startsWith(QLatin1String("2."))) { |
1155 else if (versionString.startsWith(QLatin1String("2."))) { |
|
1156 versionFlags |= QGLFormat::OpenGL_Version_1_1 | |
1240 versionFlags |= QGLFormat::OpenGL_Version_1_1 | |
1157 QGLFormat::OpenGL_Version_1_2 | |
1241 QGLFormat::OpenGL_Version_1_2 | |
1158 QGLFormat::OpenGL_Version_1_3 | |
1242 QGLFormat::OpenGL_Version_1_3 | |
1159 QGLFormat::OpenGL_Version_1_4 | |
1243 QGLFormat::OpenGL_Version_1_4 | |
1160 QGLFormat::OpenGL_Version_1_5 | |
1244 QGLFormat::OpenGL_Version_1_5 | |
1161 QGLFormat::OpenGL_Version_2_0; |
1245 QGLFormat::OpenGL_Version_2_0; |
1162 QString minorVersion = versionString.section(QLatin1Char(' '), 0, 0).section(QLatin1Char('.'), 1, 1); |
1246 if (versionString[2].toAscii() == '1') |
1163 if (minorVersion == QChar(QLatin1Char('1'))) |
|
1164 versionFlags |= QGLFormat::OpenGL_Version_2_1; |
1247 versionFlags |= QGLFormat::OpenGL_Version_2_1; |
|
1248 } else if (versionString.startsWith(QLatin1String("3."))) { |
|
1249 versionFlags |= QGLFormat::OpenGL_Version_1_1 | |
|
1250 QGLFormat::OpenGL_Version_1_2 | |
|
1251 QGLFormat::OpenGL_Version_1_3 | |
|
1252 QGLFormat::OpenGL_Version_1_4 | |
|
1253 QGLFormat::OpenGL_Version_1_5 | |
|
1254 QGLFormat::OpenGL_Version_2_0 | |
|
1255 QGLFormat::OpenGL_Version_2_1 | |
|
1256 QGLFormat::OpenGL_Version_3_0; |
|
1257 switch (versionString[2].toAscii()) { |
|
1258 case '2': |
|
1259 versionFlags |= QGLFormat::OpenGL_Version_3_2; |
|
1260 case '1': |
|
1261 versionFlags |= QGLFormat::OpenGL_Version_3_1; |
|
1262 case '0': |
|
1263 break; |
|
1264 default: |
|
1265 versionFlags |= QGLFormat::OpenGL_Version_3_1 | |
|
1266 QGLFormat::OpenGL_Version_3_2; |
|
1267 break; |
|
1268 } |
|
1269 } else { |
|
1270 versionFlags |= QGLFormat::OpenGL_Version_1_1 | |
|
1271 QGLFormat::OpenGL_Version_1_2 | |
|
1272 QGLFormat::OpenGL_Version_1_3 | |
|
1273 QGLFormat::OpenGL_Version_1_4 | |
|
1274 QGLFormat::OpenGL_Version_1_5 | |
|
1275 QGLFormat::OpenGL_Version_2_0 | |
|
1276 QGLFormat::OpenGL_Version_2_1 | |
|
1277 QGLFormat::OpenGL_Version_3_0 | |
|
1278 QGLFormat::OpenGL_Version_3_1 | |
|
1279 QGLFormat::OpenGL_Version_3_2; |
1165 } |
1280 } |
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 else |
|
1177 qWarning("Unrecognised OpenGL version"); |
|
1178 } |
1281 } |
1179 return versionFlags; |
1282 return versionFlags; |
1180 } |
1283 } |
1181 |
1284 |
1182 /*! |
1285 /*! |
1203 Note that version 2.0 supports all the functionality of version 1.5. |
1306 Note that version 2.0 supports all the functionality of version 1.5. |
1204 |
1307 |
1205 \value OpenGL_Version_2_1 OpenGL version 2.1 or higher is present. |
1308 \value OpenGL_Version_2_1 OpenGL version 2.1 or higher is present. |
1206 |
1309 |
1207 \value OpenGL_Version_3_0 OpenGL version 3.0 or higher is present. |
1310 \value OpenGL_Version_3_0 OpenGL version 3.0 or higher is present. |
|
1311 |
|
1312 \value OpenGL_Version_3_1 OpenGL version 3.1 or higher is present. |
|
1313 Note that OpenGL version 3.1 or higher does not necessarily support all the features of |
|
1314 version 3.0 and lower. |
|
1315 |
|
1316 \value OpenGL_Version_3_2 OpenGL version 3.2 or higher is present. |
1208 |
1317 |
1209 \value OpenGL_ES_CommonLite_Version_1_0 OpenGL ES version 1.0 Common Lite or higher is present. |
1318 \value OpenGL_ES_CommonLite_Version_1_0 OpenGL ES version 1.0 Common Lite or higher is present. |
1210 |
1319 |
1211 \value OpenGL_ES_Common_Version_1_0 OpenGL ES version 1.0 Common or higher is present. |
1320 \value OpenGL_ES_Common_Version_1_0 OpenGL ES version 1.0 Common or higher is present. |
1212 The Common profile supports all the features of Common Lite. |
1321 The Common profile supports all the features of Common Lite. |
1375 \relates QGLFormat |
1484 \relates QGLFormat |
1376 */ |
1485 */ |
1377 |
1486 |
1378 bool operator==(const QGLFormat& a, const QGLFormat& b) |
1487 bool operator==(const QGLFormat& a, const QGLFormat& b) |
1379 { |
1488 { |
1380 return (int) a.d->opts == (int) b.d->opts && a.d->pln == b.d->pln && a.d->alphaSize == b.d->alphaSize |
1489 return (a.d == b.d) || ((int) a.d->opts == (int) b.d->opts |
1381 && a.d->accumSize == b.d->accumSize && a.d->stencilSize == b.d->stencilSize |
1490 && a.d->pln == b.d->pln |
|
1491 && a.d->alphaSize == b.d->alphaSize |
|
1492 && a.d->accumSize == b.d->accumSize |
|
1493 && a.d->stencilSize == b.d->stencilSize |
1382 && a.d->depthSize == b.d->depthSize |
1494 && a.d->depthSize == b.d->depthSize |
1383 && a.d->redSize == b.d->redSize |
1495 && a.d->redSize == b.d->redSize |
1384 && a.d->greenSize == b.d->greenSize |
1496 && a.d->greenSize == b.d->greenSize |
1385 && a.d->blueSize == b.d->blueSize |
1497 && a.d->blueSize == b.d->blueSize |
1386 && a.d->numSamples == b.d->numSamples |
1498 && a.d->numSamples == b.d->numSamples |
1387 && a.d->swapInterval == b.d->swapInterval; |
1499 && a.d->swapInterval == b.d->swapInterval |
|
1500 && a.d->majorVersion == b.d->majorVersion |
|
1501 && a.d->minorVersion == b.d->minorVersion |
|
1502 && a.d->profile == b.d->profile); |
1388 } |
1503 } |
1389 |
1504 |
1390 |
1505 |
1391 /*! |
1506 /*! |
1392 Returns false if all the options of the two QGLFormat objects |
1507 Returns false if all the options of the two QGLFormat objects |
1494 extension_flags_cached = false; |
1610 extension_flags_cached = false; |
1495 extension_flags = 0; |
1611 extension_flags = 0; |
1496 current_fbo = 0; |
1612 current_fbo = 0; |
1497 default_fbo = 0; |
1613 default_fbo = 0; |
1498 active_engine = 0; |
1614 active_engine = 0; |
|
1615 workaround_needsFullClearOnEveryFrame = false; |
|
1616 workaround_brokenFBOReadBack = false; |
|
1617 workaroundsCached = false; |
1499 for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) |
1618 for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) |
1500 vertexAttributeArraysEnabledState[i] = false; |
1619 vertexAttributeArraysEnabledState[i] = false; |
1501 } |
1620 } |
1502 |
1621 |
1503 QGLContext* QGLContext::currentCtx = 0; |
1622 QGLContext* QGLContext::currentCtx = 0; |
1564 QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha) |
1683 QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha) |
1565 { |
1684 { |
1566 QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); |
1685 QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); |
1567 int w = size.width(); |
1686 int w = size.width(); |
1568 int h = size.height(); |
1687 int h = size.height(); |
1569 #if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) |
1688 #if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) |
1570 //### glGetTexImage not in GL ES 2.0, need to do something else here! |
1689 //### glGetTexImage not in GL ES 2.0, need to do something else here! |
1571 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); |
1690 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); |
1572 #endif |
1691 #endif |
1573 convertFromGLImage(img, w, h, alpha_format, include_alpha); |
1692 convertFromGLImage(img, w, h, alpha_format, include_alpha); |
1574 return img; |
1693 return img; |
1592 typedef void (*_qt_image_cleanup_hook_64)(qint64); |
1711 typedef void (*_qt_image_cleanup_hook_64)(qint64); |
1593 |
1712 |
1594 extern Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64; |
1713 extern Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64; |
1595 extern Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64; |
1714 extern Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64; |
1596 |
1715 |
1597 static QGLTextureCache *qt_gl_texture_cache = 0; |
1716 |
|
1717 Q_GLOBAL_STATIC(QGLTextureCache, qt_gl_texture_cache) |
1598 |
1718 |
1599 QGLTextureCache::QGLTextureCache() |
1719 QGLTextureCache::QGLTextureCache() |
1600 : m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though |
1720 : m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though |
1601 { |
1721 { |
1602 Q_ASSERT(qt_gl_texture_cache == 0); |
|
1603 qt_gl_texture_cache = this; |
|
1604 |
|
1605 QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTexturesForPixampData); |
1722 QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTexturesForPixampData); |
1606 QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction); |
1723 QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction); |
1607 QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey); |
1724 QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey); |
1608 } |
1725 } |
1609 |
1726 |
1610 QGLTextureCache::~QGLTextureCache() |
1727 QGLTextureCache::~QGLTextureCache() |
1611 { |
1728 { |
1612 qt_gl_texture_cache = 0; |
|
1613 |
|
1614 QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData); |
1729 QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData); |
1615 QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction); |
1730 QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction); |
1616 QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey); |
1731 QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey); |
1617 } |
1732 } |
1618 |
1733 |
1619 void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, int cost) |
1734 void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, int cost) |
1620 { |
1735 { |
|
1736 QWriteLocker locker(&m_lock); |
1621 if (m_cache.totalCost() + cost > m_cache.maxCost()) { |
1737 if (m_cache.totalCost() + cost > m_cache.maxCost()) { |
1622 // the cache is full - make an attempt to remove something |
1738 // the cache is full - make an attempt to remove something |
1623 const QList<qint64> keys = m_cache.keys(); |
1739 const QList<qint64> keys = m_cache.keys(); |
1624 int i = 0; |
1740 int i = 0; |
1625 while (i < m_cache.count() |
1741 while (i < m_cache.count() |
1633 m_cache.insert(key, texture, cost); |
1749 m_cache.insert(key, texture, cost); |
1634 } |
1750 } |
1635 |
1751 |
1636 bool QGLTextureCache::remove(QGLContext* ctx, GLuint textureId) |
1752 bool QGLTextureCache::remove(QGLContext* ctx, GLuint textureId) |
1637 { |
1753 { |
|
1754 QWriteLocker locker(&m_lock); |
1638 QList<qint64> keys = m_cache.keys(); |
1755 QList<qint64> keys = m_cache.keys(); |
1639 for (int i = 0; i < keys.size(); ++i) { |
1756 for (int i = 0; i < keys.size(); ++i) { |
1640 QGLTexture *tex = m_cache.object(keys.at(i)); |
1757 QGLTexture *tex = m_cache.object(keys.at(i)); |
1641 if (tex->id == textureId && tex->context == ctx) { |
1758 if (tex->id == textureId && tex->context == ctx) { |
1642 tex->options |= QGLContext::MemoryManagedBindOption; // forces a glDeleteTextures() call |
1759 tex->options |= QGLContext::MemoryManagedBindOption; // forces a glDeleteTextures() call |
1647 return false; |
1764 return false; |
1648 } |
1765 } |
1649 |
1766 |
1650 void QGLTextureCache::removeContextTextures(QGLContext* ctx) |
1767 void QGLTextureCache::removeContextTextures(QGLContext* ctx) |
1651 { |
1768 { |
|
1769 QWriteLocker locker(&m_lock); |
1652 QList<qint64> keys = m_cache.keys(); |
1770 QList<qint64> keys = m_cache.keys(); |
1653 for (int i = 0; i < keys.size(); ++i) { |
1771 for (int i = 0; i < keys.size(); ++i) { |
1654 const qint64 &key = keys.at(i); |
1772 const qint64 &key = keys.at(i); |
1655 if (m_cache.object(key)->context == ctx) |
1773 if (m_cache.object(key)->context == ctx) |
1656 m_cache.remove(key); |
1774 m_cache.remove(key); |
1657 } |
1775 } |
1658 } |
1776 } |
1659 |
1777 |
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 } |
|
1667 |
|
1668 /* |
1778 /* |
1669 a hook that removes textures from the cache when a pixmap/image |
1779 a hook that removes textures from the cache when a pixmap/image |
1670 is deref'ed |
1780 is deref'ed |
1671 */ |
1781 */ |
1672 void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey) |
1782 void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey) |
1673 { |
1783 { |
1674 // ### remove when the GL texture cache becomes thread-safe |
1784 qt_gl_texture_cache()->remove(cacheKey); |
1675 if (qApp->thread() == QThread::currentThread()) { |
1785 Q_ASSERT(qt_gl_texture_cache()->getTexture(cacheKey) == 0); |
1676 instance()->remove(cacheKey); |
|
1677 Q_ASSERT(instance()->getTexture(cacheKey) == 0); |
|
1678 } |
|
1679 } |
1786 } |
1680 |
1787 |
1681 |
1788 |
1682 void QGLTextureCache::cleanupTexturesForPixampData(QPixmapData* pmd) |
1789 void QGLTextureCache::cleanupTexturesForPixampData(QPixmapData* pmd) |
1683 { |
1790 { |
2124 const qint64 key, QGLContext::BindOptions options) |
2229 const qint64 key, QGLContext::BindOptions options) |
2125 { |
2230 { |
2126 Q_Q(QGLContext); |
2231 Q_Q(QGLContext); |
2127 |
2232 |
2128 #ifdef QGL_BIND_TEXTURE_DEBUG |
2233 #ifdef QGL_BIND_TEXTURE_DEBUG |
2129 printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x\n", |
2234 printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x, key=%llx\n", |
2130 image.width(), image.height(), internalFormat, int(options)); |
2235 image.width(), image.height(), internalFormat, int(options), key); |
2131 QTime time; |
2236 QTime time; |
2132 time.start(); |
2237 time.start(); |
2133 #endif |
2238 #endif |
2134 |
2239 |
2135 #ifndef QT_NO_DEBUG |
2240 #ifndef QT_NO_DEBUG |
2296 glGenerateMipmap(target); |
2401 glGenerateMipmap(target); |
2297 #endif |
2402 #endif |
2298 #ifndef QT_NO_DEBUG |
2403 #ifndef QT_NO_DEBUG |
2299 GLenum error = glGetError(); |
2404 GLenum error = glGetError(); |
2300 if (error != GL_NO_ERROR) { |
2405 if (error != GL_NO_ERROR) { |
2301 qWarning(" - texture upload failed, error code 0x%x\n", error); |
2406 qWarning(" - texture upload failed, error code 0x%x, enum: %d (%x)\n", error, target, target); |
2302 } |
2407 } |
2303 #endif |
2408 #endif |
2304 |
2409 |
2305 #ifdef QGL_BIND_TEXTURE_DEBUG |
2410 #ifdef QGL_BIND_TEXTURE_DEBUG |
2306 static int totalUploadTime = 0; |
2411 static int totalUploadTime = 0; |
2333 /*! \internal */ |
2438 /*! \internal */ |
2334 QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, QGLContext::BindOptions options) |
2439 QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, QGLContext::BindOptions options) |
2335 { |
2440 { |
2336 Q_Q(QGLContext); |
2441 Q_Q(QGLContext); |
2337 QPixmapData *pd = pixmap.pixmapData(); |
2442 QPixmapData *pd = pixmap.pixmapData(); |
2338 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) |
2443 #if !defined(QT_OPENGL_ES_1) |
2339 if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) { |
2444 if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) { |
2340 const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pd); |
2445 const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pd); |
2341 |
2446 |
2342 if (data->isValidContext(q)) { |
2447 if (data->isValidContext(q)) { |
2343 data->bind(); |
2448 data->bind(); |
2358 |
2463 |
2359 #if defined(Q_WS_X11) |
2464 #if defined(Q_WS_X11) |
2360 // Try to use texture_from_pixmap |
2465 // Try to use texture_from_pixmap |
2361 const QX11Info *xinfo = qt_x11Info(paintDevice); |
2466 const QX11Info *xinfo = qt_x11Info(paintDevice); |
2362 if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType |
2467 if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType |
2363 && xinfo && xinfo->screen() == pixmap.x11Info().screen()) |
2468 && xinfo && xinfo->screen() == pixmap.x11Info().screen() |
|
2469 && target == GL_TEXTURE_2D) |
2364 { |
2470 { |
2365 texture = bindTextureFromNativePixmap(pd, key, options); |
2471 texture = bindTextureFromNativePixmap(const_cast<QPixmap*>(&pixmap), key, options); |
2366 if (texture) { |
2472 if (texture) { |
2367 texture->options |= QGLContext::MemoryManagedBindOption; |
2473 texture->options |= QGLContext::MemoryManagedBindOption; |
2368 texture->boundPixmap = pd; |
2474 texture->boundPixmap = pd; |
2369 boundPixmaps.insert(pd, QPixmap(pixmap)); |
2475 boundPixmaps.insert(pd, QPixmap(pixmap)); |
2370 } |
2476 } |
2371 } |
2477 } |
2372 #endif |
2478 #endif |
2373 |
2479 |
2374 if (!texture) |
2480 if (!texture) { |
2375 texture = bindTexture(pixmap.toImage(), target, format, key, options); |
2481 QImage image = pixmap.toImage(); |
|
2482 // If the system depth is 16 and the pixmap doesn't have an alpha channel |
|
2483 // then we convert it to RGB16 in the hope that it gets uploaded as a 16 |
|
2484 // bit texture which is much faster to access than a 32-bit one. |
|
2485 if (pixmap.depth() == 16 && !image.hasAlphaChannel() ) |
|
2486 image = image.convertToFormat(QImage::Format_RGB16); |
|
2487 texture = bindTexture(image, target, format, key, options); |
|
2488 } |
2376 // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null |
2489 // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null |
2377 Q_ASSERT(texture); |
2490 Q_ASSERT(texture); |
2378 |
2491 |
2379 if (texture->id > 0) |
2492 if (texture->id > 0) |
2380 QImagePixmapCleanupHooks::enableCleanupHooks(pixmap); |
2493 QImagePixmapCleanupHooks::enableCleanupHooks(pixmap); |
2585 { |
2698 { |
2586 return deleteTexture(GLuint(id)); |
2699 return deleteTexture(GLuint(id)); |
2587 } |
2700 } |
2588 #endif |
2701 #endif |
2589 |
2702 |
2590 void qt_add_rect_to_array(const QRectF &r, q_vertexType *array) |
2703 void qt_add_rect_to_array(const QRectF &r, GLfloat *array) |
2591 { |
2704 { |
2592 qreal left = r.left(); |
2705 qreal left = r.left(); |
2593 qreal right = r.right(); |
2706 qreal right = r.right(); |
2594 qreal top = r.top(); |
2707 qreal top = r.top(); |
2595 qreal bottom = r.bottom(); |
2708 qreal bottom = r.bottom(); |
2596 |
2709 |
2597 array[0] = f2vt(left); |
2710 array[0] = left; |
2598 array[1] = f2vt(top); |
2711 array[1] = top; |
2599 array[2] = f2vt(right); |
2712 array[2] = right; |
2600 array[3] = f2vt(top); |
2713 array[3] = top; |
2601 array[4] = f2vt(right); |
2714 array[4] = right; |
2602 array[5] = f2vt(bottom); |
2715 array[5] = bottom; |
2603 array[6] = f2vt(left); |
2716 array[6] = left; |
2604 array[7] = f2vt(bottom); |
2717 array[7] = bottom; |
2605 } |
2718 } |
2606 |
2719 |
2607 void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array) |
2720 void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, GLfloat *array) |
2608 { |
2721 { |
2609 array[0] = f2vt(x1); |
2722 array[0] = x1; |
2610 array[1] = f2vt(y1); |
2723 array[1] = y1; |
2611 array[2] = f2vt(x2); |
2724 array[2] = x2; |
2612 array[3] = f2vt(y1); |
2725 array[3] = y1; |
2613 array[4] = f2vt(x2); |
2726 array[4] = x2; |
2614 array[5] = f2vt(y2); |
2727 array[5] = y2; |
2615 array[6] = f2vt(x1); |
2728 array[6] = x1; |
2616 array[7] = f2vt(y2); |
2729 array[7] = y2; |
2617 } |
2730 } |
2618 |
2731 |
2619 #if !defined(QT_OPENGL_ES_2) |
2732 #if !defined(QT_OPENGL_ES_2) |
2620 |
2733 |
2621 static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint textureHeight, GLenum textureTarget) |
2734 static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint textureHeight, GLenum textureTarget) |
2622 { |
2735 { |
2623 q_vertexType tx = f2vt(1); |
2736 GLfloat tx = 1.0f; |
2624 q_vertexType ty = f2vt(1); |
2737 GLfloat ty = 1.0f; |
2625 |
2738 |
2626 #ifdef QT_OPENGL_ES |
2739 #ifdef QT_OPENGL_ES |
2627 Q_UNUSED(textureWidth); |
2740 Q_UNUSED(textureWidth); |
2628 Q_UNUSED(textureHeight); |
2741 Q_UNUSED(textureHeight); |
2629 Q_UNUSED(textureTarget); |
2742 Q_UNUSED(textureTarget); |
2632 if (textureWidth == -1 || textureHeight == -1) { |
2745 if (textureWidth == -1 || textureHeight == -1) { |
2633 glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); |
2746 glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); |
2634 glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); |
2747 glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); |
2635 } |
2748 } |
2636 |
2749 |
2637 tx = f2vt(textureWidth); |
2750 tx = GLfloat(textureWidth); |
2638 ty = f2vt(textureHeight); |
2751 ty = GLfloat(textureHeight); |
2639 } |
2752 } |
2640 #endif |
2753 #endif |
2641 |
2754 |
2642 q_vertexType texCoordArray[4*2] = { |
2755 GLfloat texCoordArray[4*2] = { |
2643 0, ty, tx, ty, tx, 0, 0, 0 |
2756 0, ty, tx, ty, tx, 0, 0, 0 |
2644 }; |
2757 }; |
2645 |
2758 |
2646 q_vertexType vertexArray[4*2]; |
2759 GLfloat vertexArray[4*2]; |
2647 qt_add_rect_to_array(target, vertexArray); |
2760 qt_add_rect_to_array(target, vertexArray); |
2648 |
2761 |
2649 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); |
2762 glVertexPointer(2, GL_FLOAT, 0, vertexArray); |
2650 glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray); |
2763 glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); |
2651 |
2764 |
2652 glEnableClientState(GL_VERTEX_ARRAY); |
2765 glEnableClientState(GL_VERTEX_ARRAY); |
2653 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
2766 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
2654 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
2767 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
2655 |
2768 |
2660 #endif // !QT_OPENGL_ES_2 |
2773 #endif // !QT_OPENGL_ES_2 |
2661 |
2774 |
2662 /*! |
2775 /*! |
2663 \since 4.4 |
2776 \since 4.4 |
2664 |
2777 |
2665 Draws the given texture, \a textureId, to the given target rectangle, |
2778 This function supports the following use cases: |
2666 \a target, in OpenGL model space. The \a textureTarget should be a 2D |
2779 |
2667 texture target. |
2780 \list |
2668 |
2781 \i On OpenGL and OpenGL ES 1.x it draws the given texture, \a textureId, |
2669 \note This function is not supported under OpenGL/ES 2.0. |
2782 to the given target rectangle, \a target, in OpenGL model space. The |
|
2783 \a textureTarget should be a 2D texture target. |
|
2784 \i On OpenGL and OpenGL ES 2.x, if a painter is active, not inside a |
|
2785 beginNativePainting / endNativePainting block, and uses the |
|
2786 engine with type QPaintEngine::OpenGL2, the function will draw the given |
|
2787 texture, \a textureId, to the given target rectangle, \a target, |
|
2788 respecting the current painter state. This will let you draw a texture |
|
2789 with the clip, transform, render hints, and composition mode set by the |
|
2790 painter. Note that the texture target needs to be GL_TEXTURE_2D for this |
|
2791 use case, and that this is the only supported use case under OpenGL ES 2.x. |
|
2792 \endlist |
|
2793 |
2670 */ |
2794 */ |
2671 void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) |
2795 void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) |
2672 { |
2796 { |
|
2797 #if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) |
|
2798 if (d_ptr->active_engine && |
|
2799 d_ptr->active_engine->type() == QPaintEngine::OpenGL2) { |
|
2800 QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine); |
|
2801 if (!eng->isNativePaintingActive()) { |
|
2802 QRectF src(0, 0, target.width(), target.height()); |
|
2803 QSize size(target.width(), target.height()); |
|
2804 if (eng->drawTexture(target, textureId, size, src)) |
|
2805 return; |
|
2806 } |
|
2807 } |
|
2808 #endif |
|
2809 |
2673 #ifndef QT_OPENGL_ES_2 |
2810 #ifndef QT_OPENGL_ES_2 |
2674 #ifdef QT_OPENGL_ES |
2811 #ifdef QT_OPENGL_ES |
2675 if (textureTarget != GL_TEXTURE_2D) { |
2812 if (textureTarget != GL_TEXTURE_2D) { |
2676 qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES"); |
2813 qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES"); |
2677 return; |
2814 return; |
2711 #endif |
2848 #endif |
2712 |
2849 |
2713 /*! |
2850 /*! |
2714 \since 4.4 |
2851 \since 4.4 |
2715 |
2852 |
2716 Draws the given texture at the given \a point in OpenGL model |
2853 This function supports the following use cases: |
2717 space. The \a textureTarget should be a 2D texture target. |
2854 |
2718 |
2855 \list |
2719 \note This function is not supported under OpenGL/ES. |
2856 \i By default it draws the given texture, \a textureId, |
|
2857 at the given \a point in OpenGL model space. The |
|
2858 \a textureTarget should be a 2D texture target. |
|
2859 \i If a painter is active, not inside a |
|
2860 beginNativePainting / endNativePainting block, and uses the |
|
2861 engine with type QPaintEngine::OpenGL2, the function will draw the given |
|
2862 texture, \a textureId, at the given \a point, |
|
2863 respecting the current painter state. This will let you draw a texture |
|
2864 with the clip, transform, render hints, and composition mode set by the |
|
2865 painter. Note that the texture target needs to be GL_TEXTURE_2D for this |
|
2866 use case. |
|
2867 \endlist |
|
2868 |
|
2869 \note This function is not supported under any version of OpenGL ES. |
2720 */ |
2870 */ |
2721 void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) |
2871 void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) |
2722 { |
2872 { |
2723 // this would be ok on OpenGL ES 2.0, but currently we don't have a define for that |
|
2724 #ifdef QT_OPENGL_ES |
2873 #ifdef QT_OPENGL_ES |
2725 Q_UNUSED(point); |
2874 Q_UNUSED(point); |
2726 Q_UNUSED(textureId); |
2875 Q_UNUSED(textureId); |
2727 Q_UNUSED(textureTarget); |
2876 Q_UNUSED(textureTarget); |
2728 qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead"); |
2877 qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead"); |
2729 #else |
2878 #else |
|
2879 |
2730 const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); |
2880 const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); |
2731 GLint oldTexture; |
2881 GLint oldTexture; |
2732 glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); |
2882 glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); |
2733 |
2883 |
2734 glEnable(textureTarget); |
2884 glEnable(textureTarget); |
2737 GLint textureWidth; |
2887 GLint textureWidth; |
2738 GLint textureHeight; |
2888 GLint textureHeight; |
2739 |
2889 |
2740 glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); |
2890 glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); |
2741 glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); |
2891 glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); |
|
2892 |
|
2893 if (d_ptr->active_engine && |
|
2894 d_ptr->active_engine->type() == QPaintEngine::OpenGL2) { |
|
2895 QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine); |
|
2896 if (!eng->isNativePaintingActive()) { |
|
2897 QRectF dest(point, QSizeF(textureWidth, textureHeight)); |
|
2898 QRectF src(0, 0, textureWidth, textureHeight); |
|
2899 QSize size(textureWidth, textureHeight); |
|
2900 if (eng->drawTexture(dest, textureId, size, src)) |
|
2901 return; |
|
2902 } |
|
2903 } |
2742 |
2904 |
2743 qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget); |
2905 qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget); |
2744 |
2906 |
2745 if (!wasEnabled) |
2907 if (!wasEnabled) |
2746 glDisable(textureTarget); |
2908 glDisable(textureTarget); |
3196 Generates a set of 256 display lists for the 256 first characters |
3358 Generates a set of 256 display lists for the 256 first characters |
3197 in the font \a font. The first list will start at index \a listBase. |
3359 in the font \a font. The first list will start at index \a listBase. |
3198 |
3360 |
3199 \sa QGLWidget::renderText() |
3361 \sa QGLWidget::renderText() |
3200 */ |
3362 */ |
|
3363 |
3201 |
3364 |
3202 |
3365 |
3203 /***************************************************************************** |
3366 /***************************************************************************** |
3204 QGLWidget implementation |
3367 QGLWidget implementation |
3205 *****************************************************************************/ |
3368 *****************************************************************************/ |
3317 \endlist |
3480 \endlist |
3318 |
3481 |
3319 Overpainting 2D content on top of 3D content takes a little more effort. |
3482 Overpainting 2D content on top of 3D content takes a little more effort. |
3320 One approach to doing this is shown in the |
3483 One approach to doing this is shown in the |
3321 \l{Overpainting Example}{Overpainting} example. |
3484 \l{Overpainting Example}{Overpainting} example. |
|
3485 |
|
3486 \section1 Threading |
|
3487 |
|
3488 It is possible to render into a QGLWidget from another thread, but it |
|
3489 requires that all access to the GL context is safe guarded. The Qt GUI |
|
3490 thread will try to use the context in resizeEvent and paintEvent, so in |
|
3491 order for threaded rendering using a GL widget to work, these functions |
|
3492 need to be intercepted in the GUI thread and handled accordingly in the |
|
3493 application. |
3322 |
3494 |
3323 \e{OpenGL is a trademark of Silicon Graphics, Inc. in the United States and other |
3495 \e{OpenGL is a trademark of Silicon Graphics, Inc. in the United States and other |
3324 countries.} |
3496 countries.} |
3325 |
3497 |
3326 \sa QGLPixelBuffer, {Hello GL Example}, {2D Painting Example}, {Overpainting Example}, |
3498 \sa QGLPixelBuffer, {Hello GL Example}, {2D Painting Example}, {Overpainting Example}, |
3848 setContext(new QGLContext(d->glcx->requestedFormat(), this)); |
4020 setContext(new QGLContext(d->glcx->requestedFormat(), this)); |
3849 // ### recreating the overlay isn't supported atm |
4021 // ### recreating the overlay isn't supported atm |
3850 } |
4022 } |
3851 } |
4023 } |
3852 |
4024 |
3853 #if defined(QT_OPENGL_ES) |
4025 #ifndef QT_NO_EGL |
3854 // A re-parent is likely to destroy the X11 window and re-create it. It is important |
4026 // A re-parent is likely to destroy the X11 window and re-create it. It is important |
3855 // that we free the EGL surface _before_ the winID changes - otherwise we can leak. |
4027 // that we free the EGL surface _before_ the winID changes - otherwise we can leak. |
3856 if (e->type() == QEvent::ParentAboutToChange) |
4028 if (e->type() == QEvent::ParentAboutToChange) |
3857 d->glcx->d_func()->destroyEglSurfaceForDevice(); |
4029 d->glcx->d_func()->destroyEglSurfaceForDevice(); |
3858 |
4030 |
3859 if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) { |
4031 if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) { |
3860 // The window may have been re-created during re-parent or state change - if so, the EGL |
4032 // The window may have been re-created during re-parent or state change - if so, the EGL |
3861 // surface will need to be re-created. |
4033 // surface will need to be re-created. |
3862 d->recreateEglSurface(false); |
4034 d->recreateEglSurface(); |
3863 } |
4035 } |
3864 #endif |
4036 #endif |
3865 #elif defined(Q_WS_WIN) |
4037 #elif defined(Q_WS_WIN) |
3866 if (e->type() == QEvent::ParentChange) { |
4038 if (e->type() == QEvent::ParentChange) { |
3867 QGLContext *newContext = new QGLContext(d->glcx->requestedFormat(), this); |
4039 QGLContext *newContext = new QGLContext(d->glcx->requestedFormat(), this); |
4763 #endif |
4935 #endif |
4764 |
4936 |
4765 /*! |
4937 /*! |
4766 \since 4.4 |
4938 \since 4.4 |
4767 |
4939 |
4768 Draws the given texture, \a textureId to the given target rectangle, |
4940 Calls the corresponding QGLContext::drawTexture() on |
4769 \a target, in OpenGL model space. The \a textureTarget should be a 2D |
4941 this widget's context. |
4770 texture target. |
|
4771 |
|
4772 Equivalent to the corresponding QGLContext::drawTexture(). |
|
4773 */ |
4942 */ |
4774 void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) |
4943 void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) |
4775 { |
4944 { |
4776 Q_D(QGLWidget); |
4945 Q_D(QGLWidget); |
4777 d->glcx->drawTexture(target, textureId, textureTarget); |
4946 d->glcx->drawTexture(target, textureId, textureTarget); |
4787 #endif |
4956 #endif |
4788 |
4957 |
4789 /*! |
4958 /*! |
4790 \since 4.4 |
4959 \since 4.4 |
4791 |
4960 |
4792 Draws the given texture, \a textureId, at the given \a point in OpenGL |
4961 Calls the corresponding QGLContext::drawTexture() on |
4793 model space. The \a textureTarget should be a 2D texture target. |
4962 this widget's context. |
4794 |
|
4795 Equivalent to the corresponding QGLContext::drawTexture(). |
|
4796 */ |
4963 */ |
4797 void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) |
4964 void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) |
4798 { |
4965 { |
4799 Q_D(QGLWidget); |
4966 Q_D(QGLWidget); |
4800 d->glcx->drawTexture(point, textureId, textureTarget); |
4967 d->glcx->drawTexture(point, textureId, textureTarget); |
4807 Q_D(QGLWidget); |
4974 Q_D(QGLWidget); |
4808 d->glcx->drawTexture(point, GLuint(textureId), GLenum(textureTarget)); |
4975 d->glcx->drawTexture(point, GLuint(textureId), GLenum(textureTarget)); |
4809 } |
4976 } |
4810 #endif |
4977 #endif |
4811 |
4978 |
4812 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) |
4979 #ifndef QT_OPENGL_ES_1 |
4813 Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_2_engine) |
4980 Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_2_engine) |
4814 #endif |
4981 #endif |
4815 |
4982 |
4816 #ifndef QT_OPENGL_ES_2 |
4983 #ifndef QT_OPENGL_ES_2 |
4817 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_engine) |
4984 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_engine) |
4818 #endif |
4985 #endif |
4819 |
4986 |
4820 Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine() |
4987 Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine() |
4821 { |
4988 { |
4822 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL) |
4989 #if defined(QT_OPENGL_ES_1) |
4823 return qt_gl_engine(); |
4990 return qt_gl_engine(); |
4824 #elif defined(QT_OPENGL_ES_2) |
4991 #elif defined(QT_OPENGL_ES_2) |
4825 return qt_gl_2_engine(); |
4992 return qt_gl_2_engine(); |
4826 #else |
4993 #else |
4827 if (qt_gl_preferGL2Engine()) |
4994 if (qt_gl_preferGL2Engine()) |
4940 #if defined(QT_OPENGL_ES_2) |
5107 #if defined(QT_OPENGL_ES_2) |
4941 glExtensions |= FramebufferObject; |
5108 glExtensions |= FramebufferObject; |
4942 glExtensions |= GenerateMipmap; |
5109 glExtensions |= GenerateMipmap; |
4943 glExtensions |= FragmentShader; |
5110 glExtensions |= FragmentShader; |
4944 #endif |
5111 #endif |
4945 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL) |
5112 #if defined(QT_OPENGL_ES_1) |
4946 if (extensions.match("GL_OES_framebuffer_object")) |
5113 if (extensions.match("GL_OES_framebuffer_object")) |
4947 glExtensions |= FramebufferObject; |
5114 glExtensions |= FramebufferObject; |
4948 #endif |
5115 #endif |
4949 #if defined(QT_OPENGL_ES) |
5116 #if defined(QT_OPENGL_ES) |
4950 if (extensions.match("GL_OES_packed_depth_stencil")) |
5117 if (extensions.match("GL_OES_packed_depth_stencil")) |
4966 glExtensions |= BGRATextureFormat; |
5133 glExtensions |= BGRATextureFormat; |
4967 |
5134 |
4968 return glExtensions; |
5135 return glExtensions; |
4969 } |
5136 } |
4970 |
5137 |
|
5138 |
|
5139 class QGLDefaultExtensions |
|
5140 { |
|
5141 public: |
|
5142 QGLDefaultExtensions() { |
|
5143 QGLTemporaryContext tempContext; |
|
5144 extensions = QGLExtensions::currentContextExtensions(); |
|
5145 } |
|
5146 |
|
5147 QGLExtensions::Extensions extensions; |
|
5148 }; |
|
5149 |
|
5150 Q_GLOBAL_STATIC(QGLDefaultExtensions, qtDefaultExtensions) |
|
5151 |
4971 /* |
5152 /* |
4972 Returns the GL extensions for the current QGLContext. If there is no |
5153 Returns the GL extensions for the current QGLContext. If there is no |
4973 current QGLContext, a default context will be created and the extensions |
5154 current QGLContext, a default context will be created and the extensions |
4974 for that context will be returned instead. |
5155 for that context will be returned instead. |
4975 */ |
5156 */ |
4976 QGLExtensions::Extensions QGLExtensions::glExtensions() |
5157 QGLExtensions::Extensions QGLExtensions::glExtensions() |
4977 { |
5158 { |
4978 QGLTemporaryContext *tmpContext = 0; |
5159 Extensions extensionFlags = 0; |
4979 static bool cachedDefault = false; |
|
4980 static Extensions defaultExtensions = 0; |
|
4981 QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext()); |
5160 QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext()); |
4982 |
5161 |
4983 if (currentCtx && currentCtx->d_func()->extension_flags_cached) |
5162 if (currentCtx && currentCtx->d_func()->extension_flags_cached) |
4984 return currentCtx->d_func()->extension_flags; |
5163 return currentCtx->d_func()->extension_flags; |
4985 |
5164 |
4986 if (!currentCtx) { |
5165 if (!currentCtx) { |
4987 if (cachedDefault) { |
5166 extensionFlags = qtDefaultExtensions()->extensions; |
4988 return defaultExtensions; |
5167 } else { |
4989 } else { |
5168 extensionFlags = currentContextExtensions(); |
4990 tmpContext = new QGLTemporaryContext; |
|
4991 cachedDefault = true; |
|
4992 } |
|
4993 } |
|
4994 |
|
4995 Extensions extensionFlags = currentContextExtensions(); |
|
4996 if (currentCtx) { |
|
4997 currentCtx->d_func()->extension_flags_cached = true; |
5169 currentCtx->d_func()->extension_flags_cached = true; |
4998 currentCtx->d_func()->extension_flags = extensionFlags; |
5170 currentCtx->d_func()->extension_flags = extensionFlags; |
4999 } else { |
5171 } |
5000 defaultExtensions = extensionFlags; |
|
5001 } |
|
5002 |
|
5003 if (tmpContext) |
|
5004 delete tmpContext; |
|
5005 |
|
5006 return extensionFlags; |
5172 return extensionFlags; |
5007 } |
5173 } |
5008 |
5174 |
5009 /* |
5175 /* |
5010 This is the shared initialization for all platforms. Called from QGLWidgetPrivate::init() |
5176 This is the shared initialization for all platforms. Called from QGLWidgetPrivate::init() |
5035 } |
5201 } |
5036 |
5202 |
5037 Q_OPENGL_EXPORT const QString qt_gl_library_name() |
5203 Q_OPENGL_EXPORT const QString qt_gl_library_name() |
5038 { |
5204 { |
5039 if (qt_gl_lib_name()->isNull()) { |
5205 if (qt_gl_lib_name()->isNull()) { |
5040 #if defined(Q_WS_X11) || defined(Q_WS_QWS) |
5206 #ifdef Q_WS_MAC |
|
5207 return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"); |
|
5208 #else |
|
5209 # if defined(QT_OPENGL_ES_1) |
|
5210 return QLatin1String("GLES_CM"); |
|
5211 # elif defined(QT_OPENGL_ES_2) |
|
5212 return QLatin1String("GLESv2"); |
|
5213 # else |
5041 return QLatin1String("GL"); |
5214 return QLatin1String("GL"); |
5042 #else // Q_WS_MAC |
5215 # endif |
5043 return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"); |
5216 #endif // defined Q_WS_MAC |
5044 #endif |
|
5045 } |
5217 } |
5046 return *qt_gl_lib_name(); |
5218 return *qt_gl_lib_name(); |
5047 } |
5219 } |
5048 #endif |
5220 #endif |
5049 |
5221 |