src/opengl/qgl.cpp
changeset 30 5dc02b23752f
parent 23 89e065397ea6
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    47 #if defined(Q_WS_X11)
    47 #if defined(Q_WS_X11)
    48 #include "private/qt_x11_p.h"
    48 #include "private/qt_x11_p.h"
    49 #include "private/qpixmap_x11_p.h"
    49 #include "private/qpixmap_x11_p.h"
    50 #define INT32 dummy_INT32
    50 #define INT32 dummy_INT32
    51 #define INT8 dummy_INT8
    51 #define INT8 dummy_INT8
    52 #if !defined(QT_OPENGL_ES)
    52 #ifdef QT_NO_EGL
    53 # include <GL/glx.h>
    53 # include <GL/glx.h>
    54 #endif
    54 #endif
    55 #undef INT32
    55 #undef INT32
    56 #undef INT8
    56 #undef INT8
    57 #include "qx11info_x11.h"
    57 #include "qx11info_x11.h"
    65 
    65 
    66 #include "qpixmap.h"
    66 #include "qpixmap.h"
    67 #include "qimage.h"
    67 #include "qimage.h"
    68 #include "qgl_p.h"
    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 #include "gl2paintengineex/qpaintengineex_opengl2_p.h"
    71 #include "gl2paintengineex/qpaintengineex_opengl2_p.h"
    72 #endif
    72 #endif
    73 
    73 
    74 #ifndef QT_OPENGL_ES_2
    74 #ifndef QT_OPENGL_ES_2
    75 #include <private/qpaintengine_opengl_p.h>
    75 #include <private/qpaintengine_opengl_p.h>
    92 #include "qfile.h"
    92 #include "qfile.h"
    93 #include "qlibrary.h"
    93 #include "qlibrary.h"
    94 
    94 
    95 
    95 
    96 QT_BEGIN_NAMESPACE
    96 QT_BEGIN_NAMESPACE
    97 
       
    98 #ifdef QT_OPENGL_ES_1_CL
       
    99 #include "qgl_cl_p.h"
       
   100 #endif
       
   101 
       
   102 
    97 
   103 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
    98 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
   104 QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs;
    99 QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs;
   105 #endif
   100 #endif
   106 
   101 
   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 /*!
   763     if (numSamples < 0) {
   764     if (numSamples < 0) {
   764         qWarning("QGLFormat::setSamples: Cannot have negative number of samples per pixel %d", numSamples);
   765         qWarning("QGLFormat::setSamples: Cannot have negative number of samples per pixel %d", numSamples);
   765         return;
   766         return;
   766     }
   767     }
   767     d->numSamples = numSamples;
   768     d->numSamples = numSamples;
       
   769     setSampleBuffers(numSamples > 0);
   768 }
   770 }
   769 
   771 
   770 /*!
   772 /*!
   771     \since 4.2
   773     \since 4.2
   772 
   774 
   901     if (size < 0) {
   903     if (size < 0) {
   902         qWarning("QGLFormat::setDepthBufferSize: Cannot set negative depth buffer size %d", size);
   904         qWarning("QGLFormat::setDepthBufferSize: Cannot set negative depth buffer size %d", size);
   903         return;
   905         return;
   904     }
   906     }
   905     d->depthSize = size;
   907     d->depthSize = size;
       
   908     setDepth(size > 0);
   906 }
   909 }
   907 
   910 
   908 /*!
   911 /*!
   909     Returns the depth buffer size.
   912     Returns the depth buffer size.
   910 
   913 
  1014     if (size < 0) {
  1017     if (size < 0) {
  1015         qWarning("QGLFormat::setAlphaBufferSize: Cannot set negative alpha buffer size %d", size);
  1018         qWarning("QGLFormat::setAlphaBufferSize: Cannot set negative alpha buffer size %d", size);
  1016         return;
  1019         return;
  1017     }
  1020     }
  1018     d->alphaSize = size;
  1021     d->alphaSize = size;
  1019     setOption(QGL::AlphaChannel);
  1022     setAlpha(size > 0);
  1020 }
  1023 }
  1021 
  1024 
  1022 /*!
  1025 /*!
  1023     Returns the alpha buffer size.
  1026     Returns the alpha buffer size.
  1024 
  1027 
  1041     if (size < 0) {
  1044     if (size < 0) {
  1042         qWarning("QGLFormat::setAccumBufferSize: Cannot set negative accumulate buffer size %d", size);
  1045         qWarning("QGLFormat::setAccumBufferSize: Cannot set negative accumulate buffer size %d", size);
  1043         return;
  1046         return;
  1044     }
  1047     }
  1045     d->accumSize = size;
  1048     d->accumSize = size;
       
  1049     setAccum(size > 0);
  1046 }
  1050 }
  1047 
  1051 
  1048 /*!
  1052 /*!
  1049     Returns the accumulation buffer size.
  1053     Returns the accumulation buffer size.
  1050 
  1054 
  1066     if (size < 0) {
  1070     if (size < 0) {
  1067         qWarning("QGLFormat::setStencilBufferSize: Cannot set negative stencil buffer size %d", size);
  1071         qWarning("QGLFormat::setStencilBufferSize: Cannot set negative stencil buffer size %d", size);
  1068         return;
  1072         return;
  1069     }
  1073     }
  1070     d->stencilSize = size;
  1074     d->stencilSize = size;
       
  1075     setStencil(size > 0);
  1071 }
  1076 }
  1072 
  1077 
  1073 /*!
  1078 /*!
  1074     Returns the stencil buffer size.
  1079     Returns the stencil buffer size.
  1075 
  1080 
  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
  1478 #  ifndef QT_MAC_USE_COCOA
  1593 #  ifndef QT_MAC_USE_COCOA
  1479     update = false;
  1594     update = false;
  1480 #  endif
  1595 #  endif
  1481     vi = 0;
  1596     vi = 0;
  1482 #endif
  1597 #endif
  1483 #if defined(QT_OPENGL_ES)
  1598 #ifndef QT_NO_EGL
       
  1599     ownsEglContext = false;
  1484     eglContext = 0;
  1600     eglContext = 0;
  1485     eglSurface = EGL_NO_SURFACE;
  1601     eglSurface = EGL_NO_SURFACE;
  1486 #endif
  1602 #endif
  1487     fbo = 0;
  1603     fbo = 0;
  1488     crWin = false;
  1604     crWin = false;
  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 {
  1695         QGLContextPrivate::destroyGlSurfaceForPixmap(pmd);
  1802         QGLContextPrivate::destroyGlSurfaceForPixmap(pmd);
  1696     }
  1803     }
  1697 #endif
  1804 #endif
  1698 }
  1805 }
  1699 
  1806 
  1700 void QGLTextureCache::deleteIfEmpty()
  1807 QGLTextureCache *QGLTextureCache::instance()
  1701 {
  1808 {
  1702     if (instance()->size() == 0)
  1809     return qt_gl_texture_cache();
  1703         delete instance();
       
  1704 }
  1810 }
  1705 
  1811 
  1706 // DDS format structure
  1812 // DDS format structure
  1707 struct DDSFormat {
  1813 struct DDSFormat {
  1708     quint32 dwSize;
  1814     quint32 dwSize;
  1864 
  1970 
  1865 QGLContext::~QGLContext()
  1971 QGLContext::~QGLContext()
  1866 {
  1972 {
  1867     // remove any textures cached in this context
  1973     // remove any textures cached in this context
  1868     QGLTextureCache::instance()->removeContextTextures(this);
  1974     QGLTextureCache::instance()->removeContextTextures(this);
  1869     QGLTextureCache::deleteIfEmpty(); // ### thread safety
       
  1870 
  1975 
  1871     d_ptr->group->cleanupResources(this);
  1976     d_ptr->group->cleanupResources(this);
  1872 
  1977 
  1873     QGLSignalProxy::instance()->emitAboutToDestroyContext(this);
  1978     QGLSignalProxy::instance()->emitAboutToDestroyContext(this);
  1874     reset();
  1979     reset();
  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);
  2463 {
  2576 {
  2464     if (image.isNull())
  2577     if (image.isNull())
  2465         return 0;
  2578         return 0;
  2466 
  2579 
  2467     Q_D(QGLContext);
  2580     Q_D(QGLContext);
  2468     QGLTexture *texture = d->bindTexture(image, target, format, false, options);
  2581     QGLTexture *texture = d->bindTexture(image, target, format, options);
  2469     return texture->id;
  2582     return texture->id;
  2470 }
  2583 }
  2471 
  2584 
  2472 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
  2585 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
  2473 /*! \internal */
  2586 /*! \internal */
  2475 {
  2588 {
  2476     if (image.isNull())
  2589     if (image.isNull())
  2477         return 0;
  2590         return 0;
  2478 
  2591 
  2479     Q_D(QGLContext);
  2592     Q_D(QGLContext);
  2480     QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false, DefaultBindOption);
  2593     QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), DefaultBindOption);
  2481     return texture->id;
  2594     return texture->id;
  2482 }
  2595 }
  2483 
  2596 
  2484 /*! \internal */
  2597 /*! \internal */
  2485 GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format,
  2598 GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format,
  2487 {
  2600 {
  2488     if (image.isNull())
  2601     if (image.isNull())
  2489         return 0;
  2602         return 0;
  2490 
  2603 
  2491     Q_D(QGLContext);
  2604     Q_D(QGLContext);
  2492     QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false, options);
  2605     QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), options);
  2493     return texture->id;
  2606     return texture->id;
  2494 }
  2607 }
  2495 #endif
  2608 #endif
  2496 
  2609 
  2497 /*! \overload
  2610 /*! \overload
  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;
  2696 #endif
  2833 #endif
  2697 #else
  2834 #else
  2698     Q_UNUSED(target);
  2835     Q_UNUSED(target);
  2699     Q_UNUSED(textureId);
  2836     Q_UNUSED(textureId);
  2700     Q_UNUSED(textureTarget);
  2837     Q_UNUSED(textureTarget);
  2701     qWarning("drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES/2.0");
  2838     qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine");
  2702 #endif
  2839 #endif
  2703 }
  2840 }
  2704 
  2841 
  2705 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
  2842 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
  2706 /*! \internal */
  2843 /*! \internal */
  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