util/src/opengl/qgl.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtOpenGL module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qapplication.h"
       
    43 #include "qplatformdefs.h"
       
    44 #include "qgl.h"
       
    45 #include <qdebug.h>
       
    46 
       
    47 #if defined(Q_WS_X11)
       
    48 #include "private/qt_x11_p.h"
       
    49 #include "private/qpixmap_x11_p.h"
       
    50 #define INT32 dummy_INT32
       
    51 #define INT8 dummy_INT8
       
    52 #if !defined(QT_OPENGL_ES)
       
    53 # include <GL/glx.h>
       
    54 #endif
       
    55 #undef INT32
       
    56 #undef INT8
       
    57 #include "qx11info_x11.h"
       
    58 #elif defined(Q_WS_MAC)
       
    59 # include <private/qt_mac_p.h>
       
    60 #endif
       
    61 
       
    62 #include <qdatetime.h>
       
    63 
       
    64 #include <stdlib.h> // malloc
       
    65 
       
    66 #include "qpixmap.h"
       
    67 #include "qimage.h"
       
    68 #include "qgl_p.h"
       
    69 
       
    70 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
       
    71 #include "gl2paintengineex/qpaintengineex_opengl2_p.h"
       
    72 #endif
       
    73 
       
    74 #ifndef QT_OPENGL_ES_2
       
    75 #include <private/qpaintengine_opengl_p.h>
       
    76 #endif
       
    77 
       
    78 #ifdef Q_WS_QWS
       
    79 #include <private/qglwindowsurface_qws_p.h>
       
    80 #endif
       
    81 
       
    82 #include <qglpixelbuffer.h>
       
    83 #include <qglframebufferobject.h>
       
    84 
       
    85 #include <private/qimage_p.h>
       
    86 #include <private/qpixmapdata_p.h>
       
    87 #include <private/qpixmapdata_gl_p.h>
       
    88 #include <private/qglpixelbuffer_p.h>
       
    89 #include <private/qwindowsurface_gl_p.h>
       
    90 #include <private/qimagepixmapcleanuphooks_p.h>
       
    91 #include "qcolormap.h"
       
    92 #include "qfile.h"
       
    93 #include "qlibrary.h"
       
    94 
       
    95 
       
    96 QT_BEGIN_NAMESPACE
       
    97 
       
    98 #ifdef QT_OPENGL_ES_1_CL
       
    99 #include "qgl_cl_p.h"
       
   100 #endif
       
   101 
       
   102 
       
   103 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
       
   104 QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs;
       
   105 #endif
       
   106 
       
   107 #ifdef Q_WS_X11
       
   108 extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
       
   109 #endif
       
   110 
       
   111 struct QGLThreadContext {
       
   112     QGLContext *context;
       
   113 };
       
   114 
       
   115 static QThreadStorage<QGLThreadContext *> qgl_context_storage;
       
   116 
       
   117 Q_GLOBAL_STATIC(QGLFormat, qgl_default_format)
       
   118 
       
   119 class QGLDefaultOverlayFormat: public QGLFormat
       
   120 {
       
   121 public:
       
   122     inline QGLDefaultOverlayFormat()
       
   123     {
       
   124         setOption(QGL::FormatOption(0xffff << 16)); // turn off all options
       
   125         setOption(QGL::DirectRendering);
       
   126         setPlane(1);
       
   127     }
       
   128 };
       
   129 Q_GLOBAL_STATIC(QGLDefaultOverlayFormat, defaultOverlayFormatInstance)
       
   130 
       
   131 Q_GLOBAL_STATIC(QGLSignalProxy, theSignalProxy)
       
   132 QGLSignalProxy *QGLSignalProxy::instance()
       
   133 {
       
   134     return theSignalProxy();
       
   135 }
       
   136 
       
   137 
       
   138 class QGLEngineSelector
       
   139 {
       
   140 public:
       
   141     QGLEngineSelector() : engineType(QPaintEngine::MaxUser)
       
   142     {
       
   143     }
       
   144 
       
   145     void setPreferredPaintEngine(QPaintEngine::Type type) {
       
   146         if (type == QPaintEngine::OpenGL || type == QPaintEngine::OpenGL2)
       
   147             engineType = type;
       
   148     }
       
   149 
       
   150     QPaintEngine::Type preferredPaintEngine() {
       
   151 #ifdef Q_WS_MAC
       
   152         // The ATI X1600 driver for Mac OS X does not support return
       
   153         // values from functions in GLSL. Since working around this in
       
   154         // the GL2 engine would require a big, ugly rewrite, we're
       
   155         // falling back to the GL 1 engine..
       
   156         static bool mac_x1600_check_done = false;
       
   157         if (!mac_x1600_check_done) {
       
   158             QGLTemporaryContext *tmp = 0;
       
   159             if (!QGLContext::currentContext())
       
   160                 tmp = new QGLTemporaryContext();
       
   161             if (strstr((char *) glGetString(GL_RENDERER), "X1600"))
       
   162                 engineType = QPaintEngine::OpenGL;
       
   163             if (tmp)
       
   164                 delete tmp;
       
   165             mac_x1600_check_done = true;
       
   166         }
       
   167 #endif
       
   168         if (engineType == QPaintEngine::MaxUser) {
       
   169             // No user-set engine - use the defaults
       
   170 #if defined(QT_OPENGL_ES_2)
       
   171             engineType = QPaintEngine::OpenGL2;
       
   172 #else
       
   173             // We can't do this in the constructor for this object because it
       
   174             // needs to be called *before* the QApplication constructor.
       
   175             // Also check for the FragmentShader extension in conjunction with
       
   176             // the 2.0 version flag, to cover the case where we export the display
       
   177             // from an old GL 1.1 server to a GL 2.x client. In that case we can't
       
   178             // use GL 2.0.
       
   179             if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
       
   180                 && (QGLExtensions::glExtensions() & QGLExtensions::FragmentShader)
       
   181                 && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty())
       
   182                 engineType = QPaintEngine::OpenGL2;
       
   183             else
       
   184                 engineType = QPaintEngine::OpenGL;
       
   185 #endif
       
   186         }
       
   187         return engineType;
       
   188     }
       
   189 
       
   190 private:
       
   191     QPaintEngine::Type engineType;
       
   192 };
       
   193 
       
   194 Q_GLOBAL_STATIC(QGLEngineSelector, qgl_engine_selector)
       
   195 
       
   196 
       
   197 bool qt_gl_preferGL2Engine()
       
   198 {
       
   199     return qgl_engine_selector()->preferredPaintEngine() == QPaintEngine::OpenGL2;
       
   200 }
       
   201 
       
   202 
       
   203 /*!
       
   204     \namespace QGL
       
   205     \inmodule QtOpenGL
       
   206 
       
   207     \brief The QGL namespace specifies miscellaneous identifiers used
       
   208     in the Qt OpenGL module.
       
   209 
       
   210     \ingroup painting-3D
       
   211 */
       
   212 
       
   213 /*!
       
   214     \enum QGL::FormatOption
       
   215 
       
   216     This enum specifies the format options that can be used to configure an OpenGL
       
   217     context. These are set using QGLFormat::setOption().
       
   218 
       
   219     \value DoubleBuffer      Specifies the use of double buffering.
       
   220     \value DepthBuffer       Enables the use of a depth buffer.
       
   221     \value Rgba              Specifies that the context should use RGBA as its pixel format.
       
   222     \value AlphaChannel      Enables the use of an alpha channel.
       
   223     \value AccumBuffer       Enables the use of an accumulation buffer.
       
   224     \value StencilBuffer     Enables the use of a stencil buffer.
       
   225     \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.
       
   227     \value HasOverlay        Enables the use of an overlay.
       
   228     \value SampleBuffers     Enables the use of sample buffers.
       
   229     \value SingleBuffer      Specifies the use of a single buffer, as opposed to double buffers.
       
   230     \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.
       
   232     \value NoAlphaChannel    Disables the use of an alpha channel.
       
   233     \value NoAccumBuffer     Disables the use of an accumulation buffer.
       
   234     \value NoStencilBuffer   Disables the use of a stencil buffer.
       
   235     \value NoStereoBuffers   Disables the use of stereo buffers.
       
   236     \value IndirectRendering Specifies that the context is used for indirect rendering to a buffer.
       
   237     \value NoOverlay         Disables the use of an overlay.
       
   238     \value NoSampleBuffers   Disables the use of sample buffers.
       
   239 
       
   240     \sa {Sample Buffers Example}
       
   241 */
       
   242 
       
   243 /*!
       
   244    \fn void QGL::setPreferredPaintEngine(QPaintEngine::Type engineType)
       
   245 
       
   246    \since 4.6
       
   247 
       
   248    Sets the preferred OpenGL paint engine that is used to draw onto
       
   249    QGLWidget, QGLPixelBuffer and QGLFramebufferObject targets with QPainter
       
   250    in Qt.
       
   251 
       
   252    The \a engineType parameter specifies which of the GL engines to
       
   253    use. Only \c QPaintEngine::OpenGL and \c QPaintEngine::OpenGL2 are
       
   254    valid parameters to this function. All other values are ignored.
       
   255 
       
   256    By default, the \c QPaintEngine::OpenGL2 engine is used if GL/GLES
       
   257    version 2.0 is available, otherwise \c QPaintEngine::OpenGL is
       
   258    used.
       
   259 
       
   260    \warning This function must be called before the QApplication
       
   261    constructor is called.
       
   262 */
       
   263 void QGL::setPreferredPaintEngine(QPaintEngine::Type engineType)
       
   264 {
       
   265     qgl_engine_selector()->setPreferredPaintEngine(engineType);
       
   266 }
       
   267 
       
   268 
       
   269 /*****************************************************************************
       
   270   QGLFormat implementation
       
   271  *****************************************************************************/
       
   272 
       
   273 
       
   274 /*!
       
   275     \class QGLFormat
       
   276     \brief The QGLFormat class specifies the display format of an OpenGL
       
   277     rendering context.
       
   278 
       
   279     \ingroup painting-3D
       
   280 
       
   281     A display format has several characteristics:
       
   282     \list
       
   283     \i \link setDoubleBuffer() Double or single buffering.\endlink
       
   284     \i \link setDepth() Depth buffer.\endlink
       
   285     \i \link setRgba() RGBA or color index mode.\endlink
       
   286     \i \link setAlpha() Alpha channel.\endlink
       
   287     \i \link setAccum() Accumulation buffer.\endlink
       
   288     \i \link setStencil() Stencil buffer.\endlink
       
   289     \i \link setStereo() Stereo buffers.\endlink
       
   290     \i \link setDirectRendering() Direct rendering.\endlink
       
   291     \i \link setOverlay() Presence of an overlay.\endlink
       
   292     \i \link setPlane() Plane of an overlay.\endlink
       
   293     \i \link setSampleBuffers() Multisample buffers.\endlink
       
   294     \endlist
       
   295 
       
   296     You can also specify preferred bit depths for the color buffer,
       
   297     depth buffer, alpha buffer, accumulation buffer and the stencil
       
   298     buffer with the functions: setRedBufferSize(), setGreenBufferSize(),
       
   299     setBlueBufferSize(), setDepthBufferSize(), setAlphaBufferSize(),
       
   300     setAccumBufferSize() and setStencilBufferSize().
       
   301 
       
   302     Note that even if you specify that you prefer a 32 bit depth
       
   303     buffer (e.g. with setDepthBufferSize(32)), the format that is
       
   304     chosen may not have a 32 bit depth buffer, even if there is a
       
   305     format available with a 32 bit depth buffer. The main reason for
       
   306     this is how the system dependant picking algorithms work on the
       
   307     different platforms, and some format options may have higher
       
   308     precedence than others.
       
   309 
       
   310     You create and tell a QGLFormat object what rendering options you
       
   311     want from an OpenGL rendering context.
       
   312 
       
   313     OpenGL drivers or accelerated hardware may or may not support
       
   314     advanced features such as alpha channel or stereographic viewing.
       
   315     If you request some features that the driver/hardware does not
       
   316     provide when you create a QGLWidget, you will get a rendering
       
   317     context with the nearest subset of features.
       
   318 
       
   319     There are different ways to define the display characteristics of
       
   320     a rendering context. One is to create a QGLFormat and make it the
       
   321     default for the entire application:
       
   322     \snippet doc/src/snippets/code/src_opengl_qgl.cpp 0
       
   323 
       
   324     Or you can specify the desired format when creating an object of
       
   325     your QGLWidget subclass:
       
   326     \snippet doc/src/snippets/code/src_opengl_qgl.cpp 1
       
   327 
       
   328     After the widget has been created, you can find out which of the
       
   329     requested features the system was able to provide:
       
   330     \snippet doc/src/snippets/code/src_opengl_qgl.cpp 2
       
   331 
       
   332     \legalese
       
   333         OpenGL is a trademark of Silicon Graphics, Inc. in the
       
   334         United States and other countries.
       
   335     \endlegalese
       
   336 
       
   337     \sa QGLContext, QGLWidget
       
   338 */
       
   339 
       
   340 #ifndef QT_OPENGL_ES
       
   341 
       
   342 static inline void transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4])
       
   343 {
       
   344 #define M(row,col)  m[col*4+row]
       
   345     out[0] =
       
   346         M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
       
   347     out[1] =
       
   348         M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
       
   349     out[2] =
       
   350         M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
       
   351     out[3] =
       
   352         M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
       
   353 #undef M
       
   354 }
       
   355 
       
   356 static inline GLint qgluProject(GLdouble objx, GLdouble objy, GLdouble objz,
       
   357            const GLdouble model[16], const GLdouble proj[16],
       
   358            const GLint viewport[4],
       
   359            GLdouble * winx, GLdouble * winy, GLdouble * winz)
       
   360 {
       
   361    GLdouble in[4], out[4];
       
   362 
       
   363    in[0] = objx;
       
   364    in[1] = objy;
       
   365    in[2] = objz;
       
   366    in[3] = 1.0;
       
   367    transform_point(out, model, in);
       
   368    transform_point(in, proj, out);
       
   369 
       
   370    if (in[3] == 0.0)
       
   371       return GL_FALSE;
       
   372 
       
   373    in[0] /= in[3];
       
   374    in[1] /= in[3];
       
   375    in[2] /= in[3];
       
   376 
       
   377    *winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
       
   378    *winy = viewport[1] + (1 + in[1]) * viewport[3] / 2;
       
   379 
       
   380    *winz = (1 + in[2]) / 2;
       
   381    return GL_TRUE;
       
   382 }
       
   383 
       
   384 #endif // !QT_OPENGL_ES
       
   385 
       
   386 /*!
       
   387     Constructs a QGLFormat object with the following default settings:
       
   388     \list
       
   389     \i \link setDoubleBuffer() Double buffer:\endlink Enabled.
       
   390     \i \link setDepth() Depth buffer:\endlink Enabled.
       
   391     \i \link setRgba() RGBA:\endlink Enabled (i.e., color index disabled).
       
   392     \i \link setAlpha() Alpha channel:\endlink Disabled.
       
   393     \i \link setAccum() Accumulator buffer:\endlink Disabled.
       
   394     \i \link setStencil() Stencil buffer:\endlink Enabled.
       
   395     \i \link setStereo() Stereo:\endlink Disabled.
       
   396     \i \link setDirectRendering() Direct rendering:\endlink Enabled.
       
   397     \i \link setOverlay() Overlay:\endlink Disabled.
       
   398     \i \link setPlane() Plane:\endlink 0 (i.e., normal plane).
       
   399     \i \link setSampleBuffers() Multisample buffers:\endlink Disabled.
       
   400     \endlist
       
   401 */
       
   402 
       
   403 QGLFormat::QGLFormat()
       
   404 {
       
   405     d = new QGLFormatPrivate;
       
   406 }
       
   407 
       
   408 
       
   409 /*!
       
   410     Creates a QGLFormat object that is a copy of the current
       
   411     defaultFormat().
       
   412 
       
   413     If \a options is not 0, the default format is modified by the
       
   414     specified format options. The \a options parameter should be
       
   415     QGL::FormatOption values OR'ed together.
       
   416 
       
   417     This constructor makes it easy to specify a certain desired format
       
   418     in classes derived from QGLWidget, for example:
       
   419     \snippet doc/src/snippets/code/src_opengl_qgl.cpp 3
       
   420 
       
   421     Note that there are QGL::FormatOption values to turn format settings
       
   422     both on and off, e.g. QGL::DepthBuffer and QGL::NoDepthBuffer,
       
   423     QGL::DirectRendering and QGL::IndirectRendering, etc.
       
   424 
       
   425     The \a plane parameter defaults to 0 and is the plane which this
       
   426     format should be associated with. Not all OpenGL implementations
       
   427     supports overlay/underlay rendering planes.
       
   428 
       
   429     \sa defaultFormat(), setOption(), setPlane()
       
   430 */
       
   431 
       
   432 QGLFormat::QGLFormat(QGL::FormatOptions options, int plane)
       
   433 {
       
   434     d = new QGLFormatPrivate;
       
   435     QGL::FormatOptions newOpts = options;
       
   436     d->opts = defaultFormat().d->opts;
       
   437     d->opts |= (newOpts & 0xffff);
       
   438     d->opts &= ~(newOpts >> 16);
       
   439     d->pln = plane;
       
   440 }
       
   441 
       
   442 /*!
       
   443     \internal
       
   444 */
       
   445 void QGLFormat::detach()
       
   446 {
       
   447     if (d->ref != 1) {
       
   448         QGLFormatPrivate *newd = new QGLFormatPrivate(d);
       
   449         if (!d->ref.deref())
       
   450             delete d;
       
   451         d = newd;
       
   452     }
       
   453 }
       
   454 
       
   455 /*!
       
   456     Constructs a copy of \a other.
       
   457 */
       
   458 
       
   459 QGLFormat::QGLFormat(const QGLFormat &other)
       
   460 {
       
   461     d = other.d;
       
   462     d->ref.ref();
       
   463 }
       
   464 
       
   465 /*!
       
   466     Assigns \a other to this object.
       
   467 */
       
   468 
       
   469 QGLFormat &QGLFormat::operator=(const QGLFormat &other)
       
   470 {
       
   471     if (d != other.d) {
       
   472         other.d->ref.ref();
       
   473         if (!d->ref.deref())
       
   474             delete d;
       
   475         d = other.d;
       
   476     }
       
   477     return *this;
       
   478 }
       
   479 
       
   480 /*!
       
   481     Destroys the QGLFormat.
       
   482 */
       
   483 QGLFormat::~QGLFormat()
       
   484 {
       
   485     if (!d->ref.deref())
       
   486         delete d;
       
   487 }
       
   488 
       
   489 /*!
       
   490     \fn bool QGLFormat::doubleBuffer() const
       
   491 
       
   492     Returns true if double buffering is enabled; otherwise returns
       
   493     false. Double buffering is enabled by default.
       
   494 
       
   495     \sa setDoubleBuffer()
       
   496 */
       
   497 
       
   498 /*!
       
   499     If \a enable is true sets double buffering; otherwise sets single
       
   500     buffering.
       
   501 
       
   502     Double buffering is enabled by default.
       
   503 
       
   504     Double buffering is a technique where graphics are rendered on an
       
   505     off-screen buffer and not directly to the screen. When the drawing
       
   506     has been completed, the program calls a swapBuffers() function to
       
   507     exchange the screen contents with the buffer. The result is
       
   508     flicker-free drawing and often better performance.
       
   509 
       
   510     \sa doubleBuffer(), QGLContext::swapBuffers(),
       
   511     QGLWidget::swapBuffers()
       
   512 */
       
   513 
       
   514 void QGLFormat::setDoubleBuffer(bool enable)
       
   515 {
       
   516     setOption(enable ? QGL::DoubleBuffer : QGL::SingleBuffer);
       
   517 }
       
   518 
       
   519 
       
   520 /*!
       
   521     \fn bool QGLFormat::depth() const
       
   522 
       
   523     Returns true if the depth buffer is enabled; otherwise returns
       
   524     false. The depth buffer is enabled by default.
       
   525 
       
   526     \sa setDepth(), setDepthBufferSize()
       
   527 */
       
   528 
       
   529 /*!
       
   530     If \a enable is true enables the depth buffer; otherwise disables
       
   531     the depth buffer.
       
   532 
       
   533     The depth buffer is enabled by default.
       
   534 
       
   535     The purpose of a depth buffer (or Z-buffering) is to remove hidden
       
   536     surfaces. Pixels are assigned Z values based on the distance to
       
   537     the viewer. A pixel with a high Z value is closer to the viewer
       
   538     than a pixel with a low Z value. This information is used to
       
   539     decide whether to draw a pixel or not.
       
   540 
       
   541     \sa depth(), setDepthBufferSize()
       
   542 */
       
   543 
       
   544 void QGLFormat::setDepth(bool enable)
       
   545 {
       
   546     setOption(enable ? QGL::DepthBuffer : QGL::NoDepthBuffer);
       
   547 }
       
   548 
       
   549 
       
   550 /*!
       
   551     \fn bool QGLFormat::rgba() const
       
   552 
       
   553     Returns true if RGBA color mode is set. Returns false if color
       
   554     index mode is set. The default color mode is RGBA.
       
   555 
       
   556     \sa setRgba()
       
   557 */
       
   558 
       
   559 /*!
       
   560     If \a enable is true sets RGBA mode. If \a enable is false sets
       
   561     color index mode.
       
   562 
       
   563     The default color mode is RGBA.
       
   564 
       
   565     RGBA is the preferred mode for most OpenGL applications. In RGBA
       
   566     color mode you specify colors as red + green + blue + alpha
       
   567     quadruplets.
       
   568 
       
   569     In color index mode you specify an index into a color lookup
       
   570     table.
       
   571 
       
   572     \sa rgba()
       
   573 */
       
   574 
       
   575 void QGLFormat::setRgba(bool enable)
       
   576 {
       
   577     setOption(enable ? QGL::Rgba : QGL::ColorIndex);
       
   578 }
       
   579 
       
   580 
       
   581 /*!
       
   582     \fn bool QGLFormat::alpha() const
       
   583 
       
   584     Returns true if the alpha buffer in the framebuffer is enabled;
       
   585     otherwise returns false. The alpha buffer is disabled by default.
       
   586 
       
   587     \sa setAlpha(), setAlphaBufferSize()
       
   588 */
       
   589 
       
   590 /*!
       
   591     If \a enable is true enables the alpha buffer; otherwise disables
       
   592     the alpha buffer.
       
   593 
       
   594     The alpha buffer is disabled by default.
       
   595 
       
   596     The alpha buffer is typically used for implementing transparency
       
   597     or translucency. The A in RGBA specifies the transparency of a
       
   598     pixel.
       
   599 
       
   600     \sa alpha(), setAlphaBufferSize()
       
   601 */
       
   602 
       
   603 void QGLFormat::setAlpha(bool enable)
       
   604 {
       
   605     setOption(enable ? QGL::AlphaChannel : QGL::NoAlphaChannel);
       
   606 }
       
   607 
       
   608 
       
   609 /*!
       
   610     \fn bool QGLFormat::accum() const
       
   611 
       
   612     Returns true if the accumulation buffer is enabled; otherwise
       
   613     returns false. The accumulation buffer is disabled by default.
       
   614 
       
   615     \sa setAccum(), setAccumBufferSize()
       
   616 */
       
   617 
       
   618 /*!
       
   619     If \a enable is true enables the accumulation buffer; otherwise
       
   620     disables the accumulation buffer.
       
   621 
       
   622     The accumulation buffer is disabled by default.
       
   623 
       
   624     The accumulation buffer is used to create blur effects and
       
   625     multiple exposures.
       
   626 
       
   627     \sa accum(), setAccumBufferSize()
       
   628 */
       
   629 
       
   630 void QGLFormat::setAccum(bool enable)
       
   631 {
       
   632     setOption(enable ? QGL::AccumBuffer : QGL::NoAccumBuffer);
       
   633 }
       
   634 
       
   635 
       
   636 /*!
       
   637     \fn bool QGLFormat::stencil() const
       
   638 
       
   639     Returns true if the stencil buffer is enabled; otherwise returns
       
   640     false. The stencil buffer is enabled by default.
       
   641 
       
   642     \sa setStencil(), setStencilBufferSize()
       
   643 */
       
   644 
       
   645 /*!
       
   646     If \a enable is true enables the stencil buffer; otherwise
       
   647     disables the stencil buffer.
       
   648 
       
   649     The stencil buffer is enabled by default.
       
   650 
       
   651     The stencil buffer masks certain parts of the drawing area so that
       
   652     masked parts are not drawn on.
       
   653 
       
   654     \sa stencil(), setStencilBufferSize()
       
   655 */
       
   656 
       
   657 void QGLFormat::setStencil(bool enable)
       
   658 {
       
   659     setOption(enable ? QGL::StencilBuffer: QGL::NoStencilBuffer);
       
   660 }
       
   661 
       
   662 
       
   663 /*!
       
   664     \fn bool QGLFormat::stereo() const
       
   665 
       
   666     Returns true if stereo buffering is enabled; otherwise returns
       
   667     false. Stereo buffering is disabled by default.
       
   668 
       
   669     \sa setStereo()
       
   670 */
       
   671 
       
   672 /*!
       
   673     If \a enable is true enables stereo buffering; otherwise disables
       
   674     stereo buffering.
       
   675 
       
   676     Stereo buffering is disabled by default.
       
   677 
       
   678     Stereo buffering provides extra color buffers to generate left-eye
       
   679     and right-eye images.
       
   680 
       
   681     \sa stereo()
       
   682 */
       
   683 
       
   684 void QGLFormat::setStereo(bool enable)
       
   685 {
       
   686     setOption(enable ? QGL::StereoBuffers : QGL::NoStereoBuffers);
       
   687 }
       
   688 
       
   689 
       
   690 /*!
       
   691     \fn bool QGLFormat::directRendering() const
       
   692 
       
   693     Returns true if direct rendering is enabled; otherwise returns
       
   694     false.
       
   695 
       
   696     Direct rendering is enabled by default.
       
   697 
       
   698     \sa setDirectRendering()
       
   699 */
       
   700 
       
   701 /*!
       
   702     If \a enable is true enables direct rendering; otherwise disables
       
   703     direct rendering.
       
   704 
       
   705     Direct rendering is enabled by default.
       
   706 
       
   707     Enabling this option will make OpenGL bypass the underlying window
       
   708     system and render directly from hardware to the screen, if this is
       
   709     supported by the system.
       
   710 
       
   711     \sa directRendering()
       
   712 */
       
   713 
       
   714 void QGLFormat::setDirectRendering(bool enable)
       
   715 {
       
   716     setOption(enable ? QGL::DirectRendering : QGL::IndirectRendering);
       
   717 }
       
   718 
       
   719 /*!
       
   720     \fn bool QGLFormat::sampleBuffers() const
       
   721 
       
   722     Returns true if multisample buffer support is enabled; otherwise
       
   723     returns false.
       
   724 
       
   725     The multisample buffer is disabled by default.
       
   726 
       
   727     \sa setSampleBuffers()
       
   728 */
       
   729 
       
   730 /*!
       
   731     If \a enable is true, a GL context with multisample buffer support
       
   732     is picked; otherwise ignored.
       
   733 
       
   734     \sa sampleBuffers(), setSamples(), samples()
       
   735 */
       
   736 void QGLFormat::setSampleBuffers(bool enable)
       
   737 {
       
   738     setOption(enable ? QGL::SampleBuffers : QGL::NoSampleBuffers);
       
   739 }
       
   740 
       
   741 /*!
       
   742     Returns the number of samples per pixel when multisampling is
       
   743     enabled. By default, the highest number of samples that is
       
   744     available is used.
       
   745 
       
   746     \sa setSampleBuffers(), sampleBuffers(), setSamples()
       
   747 */
       
   748 int QGLFormat::samples() const
       
   749 {
       
   750    return d->numSamples;
       
   751 }
       
   752 
       
   753 /*!
       
   754     Set the preferred number of samples per pixel when multisampling
       
   755     is enabled to \a numSamples. By default, the highest number of
       
   756     samples available is used.
       
   757 
       
   758     \sa setSampleBuffers(), sampleBuffers(), samples()
       
   759 */
       
   760 void QGLFormat::setSamples(int numSamples)
       
   761 {
       
   762     detach();
       
   763     if (numSamples < 0) {
       
   764         qWarning("QGLFormat::setSamples: Cannot have negative number of samples per pixel %d", numSamples);
       
   765         return;
       
   766     }
       
   767     d->numSamples = numSamples;
       
   768 }
       
   769 
       
   770 /*!
       
   771     \since 4.2
       
   772 
       
   773     Set the preferred swap interval. This can be used to sync the GL
       
   774     drawing into a system window to the vertical refresh of the screen.
       
   775     Setting an \a interval value of 0 will turn the vertical refresh syncing
       
   776     off, any value higher than 0 will turn the vertical syncing on.
       
   777 
       
   778     Under Windows and under X11, where the \c{WGL_EXT_swap_control}
       
   779     and \c{GLX_SGI_video_sync} extensions are used, the \a interval
       
   780     parameter can be used to set the minimum number of video frames
       
   781     that are displayed before a buffer swap will occur. In effect,
       
   782     setting the \a interval to 10, means there will be 10 vertical
       
   783     retraces between every buffer swap.
       
   784 
       
   785     Under Windows the \c{WGL_EXT_swap_control} extension has to be present,
       
   786     and under X11 the \c{GLX_SGI_video_sync} extension has to be present.
       
   787 */
       
   788 void QGLFormat::setSwapInterval(int interval)
       
   789 {
       
   790     detach();
       
   791     d->swapInterval = interval;
       
   792 }
       
   793 
       
   794 /*!
       
   795     \since 4.2
       
   796 
       
   797     Returns the currently set swap interval. -1 is returned if setting
       
   798     the swap interval isn't supported in the system GL implementation.
       
   799 */
       
   800 int QGLFormat::swapInterval() const
       
   801 {
       
   802     return d->swapInterval;
       
   803 }
       
   804 
       
   805 /*!
       
   806     \fn bool QGLFormat::hasOverlay() const
       
   807 
       
   808     Returns true if overlay plane is enabled; otherwise returns false.
       
   809 
       
   810     Overlay is disabled by default.
       
   811 
       
   812     \sa setOverlay()
       
   813 */
       
   814 
       
   815 /*!
       
   816     If \a enable is true enables an overlay plane; otherwise disables
       
   817     the overlay plane.
       
   818 
       
   819     Enabling the overlay plane will cause QGLWidget to create an
       
   820     additional context in an overlay plane. See the QGLWidget
       
   821     documentation for further information.
       
   822 
       
   823     \sa hasOverlay()
       
   824 */
       
   825 
       
   826 void QGLFormat::setOverlay(bool enable)
       
   827 {
       
   828     setOption(enable ? QGL::HasOverlay : QGL::NoOverlay);
       
   829 }
       
   830 
       
   831 /*!
       
   832     Returns the plane of this format. The default for normal formats
       
   833     is 0, which means the normal plane. The default for overlay
       
   834     formats is 1, which is the first overlay plane.
       
   835 
       
   836     \sa setPlane(), defaultOverlayFormat()
       
   837 */
       
   838 int QGLFormat::plane() const
       
   839 {
       
   840     return d->pln;
       
   841 }
       
   842 
       
   843 /*!
       
   844     Sets the requested plane to \a plane. 0 is the normal plane, 1 is
       
   845     the first overlay plane, 2 is the second overlay plane, etc.; -1,
       
   846     -2, etc. are underlay planes.
       
   847 
       
   848     Note that in contrast to other format specifications, the plane
       
   849     specifications will be matched exactly. This means that if you
       
   850     specify a plane that the underlying OpenGL system cannot provide,
       
   851     an \link QGLWidget::isValid() invalid\endlink QGLWidget will be
       
   852     created.
       
   853 
       
   854     \sa plane()
       
   855 */
       
   856 void QGLFormat::setPlane(int plane)
       
   857 {
       
   858     detach();
       
   859     d->pln = plane;
       
   860 }
       
   861 
       
   862 /*!
       
   863     Sets the format option to \a opt.
       
   864 
       
   865     \sa testOption()
       
   866 */
       
   867 
       
   868 void QGLFormat::setOption(QGL::FormatOptions opt)
       
   869 {
       
   870     detach();
       
   871     if (opt & 0xffff)
       
   872         d->opts |= opt;
       
   873     else
       
   874        d->opts &= ~(opt >> 16);
       
   875 }
       
   876 
       
   877 
       
   878 
       
   879 /*!
       
   880     Returns true if format option \a opt is set; otherwise returns false.
       
   881 
       
   882     \sa setOption()
       
   883 */
       
   884 
       
   885 bool QGLFormat::testOption(QGL::FormatOptions opt) const
       
   886 {
       
   887     if (opt & 0xffff)
       
   888        return (d->opts & opt) != 0;
       
   889     else
       
   890        return (d->opts & (opt >> 16)) == 0;
       
   891 }
       
   892 
       
   893 /*!
       
   894     Set the minimum depth buffer size to \a size.
       
   895 
       
   896     \sa depthBufferSize(), setDepth(), depth()
       
   897 */
       
   898 void QGLFormat::setDepthBufferSize(int size)
       
   899 {
       
   900     detach();
       
   901     if (size < 0) {
       
   902         qWarning("QGLFormat::setDepthBufferSize: Cannot set negative depth buffer size %d", size);
       
   903         return;
       
   904     }
       
   905     d->depthSize = size;
       
   906 }
       
   907 
       
   908 /*!
       
   909     Returns the depth buffer size.
       
   910 
       
   911     \sa depth(), setDepth(), setDepthBufferSize()
       
   912 */
       
   913 int QGLFormat::depthBufferSize() const
       
   914 {
       
   915    return d->depthSize;
       
   916 }
       
   917 
       
   918 /*!
       
   919     \since 4.2
       
   920 
       
   921     Set the preferred red buffer size to \a size.
       
   922 
       
   923     \sa setGreenBufferSize(), setBlueBufferSize(), setAlphaBufferSize()
       
   924 */
       
   925 void QGLFormat::setRedBufferSize(int size)
       
   926 {
       
   927     detach();
       
   928     if (size < 0) {
       
   929         qWarning("QGLFormat::setRedBufferSize: Cannot set negative red buffer size %d", size);
       
   930         return;
       
   931     }
       
   932     d->redSize = size;
       
   933 }
       
   934 
       
   935 /*!
       
   936     \since 4.2
       
   937 
       
   938     Returns the red buffer size.
       
   939 
       
   940     \sa setRedBufferSize()
       
   941 */
       
   942 int QGLFormat::redBufferSize() const
       
   943 {
       
   944    return d->redSize;
       
   945 }
       
   946 
       
   947 /*!
       
   948     \since 4.2
       
   949 
       
   950     Set the preferred green buffer size to \a size.
       
   951 
       
   952     \sa setRedBufferSize(), setBlueBufferSize(), setAlphaBufferSize()
       
   953 */
       
   954 void QGLFormat::setGreenBufferSize(int size)
       
   955 {
       
   956     detach();
       
   957     if (size < 0) {
       
   958         qWarning("QGLFormat::setGreenBufferSize: Cannot set negative green buffer size %d", size);
       
   959         return;
       
   960     }
       
   961     d->greenSize = size;
       
   962 }
       
   963 
       
   964 /*!
       
   965     \since 4.2
       
   966 
       
   967     Returns the green buffer size.
       
   968 
       
   969     \sa setGreenBufferSize()
       
   970 */
       
   971 int QGLFormat::greenBufferSize() const
       
   972 {
       
   973    return d->greenSize;
       
   974 }
       
   975 
       
   976 /*!
       
   977     \since 4.2
       
   978 
       
   979     Set the preferred blue buffer size to \a size.
       
   980 
       
   981     \sa setRedBufferSize(), setGreenBufferSize(), setAlphaBufferSize()
       
   982 */
       
   983 void QGLFormat::setBlueBufferSize(int size)
       
   984 {
       
   985     detach();
       
   986     if (size < 0) {
       
   987         qWarning("QGLFormat::setBlueBufferSize: Cannot set negative blue buffer size %d", size);
       
   988         return;
       
   989     }
       
   990     d->blueSize = size;
       
   991 }
       
   992 
       
   993 /*!
       
   994     \since 4.2
       
   995 
       
   996     Returns the blue buffer size.
       
   997 
       
   998     \sa setBlueBufferSize()
       
   999 */
       
  1000 int QGLFormat::blueBufferSize() const
       
  1001 {
       
  1002    return d->blueSize;
       
  1003 }
       
  1004 
       
  1005 /*!
       
  1006     Set the preferred alpha buffer size to \a size.
       
  1007     This function implicitly enables the alpha channel.
       
  1008 
       
  1009     \sa setRedBufferSize(), setGreenBufferSize(), alphaBufferSize()
       
  1010 */
       
  1011 void QGLFormat::setAlphaBufferSize(int size)
       
  1012 {
       
  1013     detach();
       
  1014     if (size < 0) {
       
  1015         qWarning("QGLFormat::setAlphaBufferSize: Cannot set negative alpha buffer size %d", size);
       
  1016         return;
       
  1017     }
       
  1018     d->alphaSize = size;
       
  1019     setOption(QGL::AlphaChannel);
       
  1020 }
       
  1021 
       
  1022 /*!
       
  1023     Returns the alpha buffer size.
       
  1024 
       
  1025     \sa alpha(), setAlpha(), setAlphaBufferSize()
       
  1026 */
       
  1027 int QGLFormat::alphaBufferSize() const
       
  1028 {
       
  1029    return d->alphaSize;
       
  1030 }
       
  1031 
       
  1032 /*!
       
  1033     Set the preferred accumulation buffer size, where \a size is the
       
  1034     bit depth for each RGBA component.
       
  1035 
       
  1036     \sa accum(), setAccum(), accumBufferSize()
       
  1037 */
       
  1038 void QGLFormat::setAccumBufferSize(int size)
       
  1039 {
       
  1040     detach();
       
  1041     if (size < 0) {
       
  1042         qWarning("QGLFormat::setAccumBufferSize: Cannot set negative accumulate buffer size %d", size);
       
  1043         return;
       
  1044     }
       
  1045     d->accumSize = size;
       
  1046 }
       
  1047 
       
  1048 /*!
       
  1049     Returns the accumulation buffer size.
       
  1050 
       
  1051     \sa setAccumBufferSize(), accum(), setAccum()
       
  1052 */
       
  1053 int QGLFormat::accumBufferSize() const
       
  1054 {
       
  1055    return d->accumSize;
       
  1056 }
       
  1057 
       
  1058 /*!
       
  1059     Set the preferred stencil buffer size to \a size.
       
  1060 
       
  1061     \sa stencilBufferSize(), setStencil(), stencil()
       
  1062 */
       
  1063 void QGLFormat::setStencilBufferSize(int size)
       
  1064 {
       
  1065     detach();
       
  1066     if (size < 0) {
       
  1067         qWarning("QGLFormat::setStencilBufferSize: Cannot set negative stencil buffer size %d", size);
       
  1068         return;
       
  1069     }
       
  1070     d->stencilSize = size;
       
  1071 }
       
  1072 
       
  1073 /*!
       
  1074     Returns the stencil buffer size.
       
  1075 
       
  1076     \sa stencil(), setStencil(), setStencilBufferSize()
       
  1077 */
       
  1078 int QGLFormat::stencilBufferSize() const
       
  1079 {
       
  1080    return d->stencilSize;
       
  1081 }
       
  1082 
       
  1083 /*!
       
  1084     \fn bool QGLFormat::hasOpenGL()
       
  1085 
       
  1086     Returns true if the window system has any OpenGL support;
       
  1087     otherwise returns false.
       
  1088 
       
  1089     \warning This function must not be called until the QApplication
       
  1090     object has been created.
       
  1091 */
       
  1092 
       
  1093 
       
  1094 
       
  1095 /*!
       
  1096     \fn bool QGLFormat::hasOpenGLOverlays()
       
  1097 
       
  1098     Returns true if the window system supports OpenGL overlays;
       
  1099     otherwise returns false.
       
  1100 
       
  1101     \warning This function must not be called until the QApplication
       
  1102     object has been created.
       
  1103 */
       
  1104 
       
  1105 QGLFormat::OpenGLVersionFlags Q_AUTOTEST_EXPORT qOpenGLVersionFlagsFromString(const QString &versionString)
       
  1106 {
       
  1107     QGLFormat::OpenGLVersionFlags versionFlags = QGLFormat::OpenGL_Version_None;
       
  1108 
       
  1109     if (versionString.startsWith(QLatin1String("OpenGL ES"))) {
       
  1110         QStringList parts = versionString.split(QLatin1Char(' '));
       
  1111         if (parts.size() >= 3) {
       
  1112             if (parts[2].startsWith(QLatin1String("1."))) {
       
  1113                 if (parts[1].endsWith(QLatin1String("-CM"))) {
       
  1114                     versionFlags |= QGLFormat::OpenGL_ES_Common_Version_1_0 |
       
  1115                                     QGLFormat::OpenGL_ES_CommonLite_Version_1_0;
       
  1116                     if (parts[2].startsWith(QLatin1String("1.1")))
       
  1117                         versionFlags |= QGLFormat::OpenGL_ES_Common_Version_1_1 |
       
  1118                                         QGLFormat::OpenGL_ES_CommonLite_Version_1_1;
       
  1119                 }
       
  1120                 else {
       
  1121                     // Not -CM, must be CL, CommonLite
       
  1122                     versionFlags |= QGLFormat::OpenGL_ES_CommonLite_Version_1_0;
       
  1123                     if (parts[2].startsWith(QLatin1String("1.1")))
       
  1124                         versionFlags |= QGLFormat::OpenGL_ES_CommonLite_Version_1_1;
       
  1125                 }
       
  1126             }
       
  1127             else {
       
  1128                 // OpenGL ES version 2.0 or higher
       
  1129                 versionFlags |= QGLFormat::OpenGL_ES_Version_2_0;
       
  1130             }
       
  1131         }
       
  1132         else {
       
  1133             // if < 3 parts to the name, it is an unrecognised OpenGL ES
       
  1134             qWarning("Unrecognised OpenGL ES version");
       
  1135         }
       
  1136     }
       
  1137     else {
       
  1138         // not ES, regular OpenGL, the version numbers are first in the string
       
  1139         if (versionString.startsWith(QLatin1String("1."))) {
       
  1140             switch (versionString[2].toAscii()) {
       
  1141             case '5':
       
  1142                 versionFlags |= QGLFormat::OpenGL_Version_1_5;
       
  1143             case '4':
       
  1144                 versionFlags |= QGLFormat::OpenGL_Version_1_4;
       
  1145             case '3':
       
  1146                 versionFlags |= QGLFormat::OpenGL_Version_1_3;
       
  1147             case '2':
       
  1148                 versionFlags |= QGLFormat::OpenGL_Version_1_2;
       
  1149             case '1':
       
  1150                 versionFlags |= QGLFormat::OpenGL_Version_1_1;
       
  1151             default:
       
  1152                 break;
       
  1153             }
       
  1154         }
       
  1155         else if (versionString.startsWith(QLatin1String("2."))) {
       
  1156             versionFlags |= QGLFormat::OpenGL_Version_1_1 |
       
  1157                             QGLFormat::OpenGL_Version_1_2 |
       
  1158                             QGLFormat::OpenGL_Version_1_3 |
       
  1159                             QGLFormat::OpenGL_Version_1_4 |
       
  1160                             QGLFormat::OpenGL_Version_1_5 |
       
  1161                             QGLFormat::OpenGL_Version_2_0;
       
  1162             QString minorVersion = versionString.section(QLatin1Char(' '), 0, 0).section(QLatin1Char('.'), 1, 1);
       
  1163             if (minorVersion == QChar(QLatin1Char('1')))
       
  1164                 versionFlags |= QGLFormat::OpenGL_Version_2_1;
       
  1165         }
       
  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     }
       
  1179     return versionFlags;
       
  1180 }
       
  1181 
       
  1182 /*!
       
  1183     \enum QGLFormat::OpenGLVersionFlag
       
  1184     \since 4.2
       
  1185 
       
  1186     This enum describes the various OpenGL versions that are
       
  1187     recognized by Qt. Use the QGLFormat::openGLVersionFlags() function
       
  1188     to identify which versions that are supported at runtime.
       
  1189 
       
  1190     \value OpenGL_Version_None  If no OpenGL is present or if no OpenGL context is current.
       
  1191 
       
  1192     \value OpenGL_Version_1_1  OpenGL version 1.1 or higher is present.
       
  1193 
       
  1194     \value OpenGL_Version_1_2  OpenGL version 1.2 or higher is present.
       
  1195 
       
  1196     \value OpenGL_Version_1_3  OpenGL version 1.3 or higher is present.
       
  1197 
       
  1198     \value OpenGL_Version_1_4  OpenGL version 1.4 or higher is present.
       
  1199 
       
  1200     \value OpenGL_Version_1_5  OpenGL version 1.5 or higher is present.
       
  1201 
       
  1202     \value OpenGL_Version_2_0  OpenGL version 2.0 or higher is present.
       
  1203     Note that version 2.0 supports all the functionality of version 1.5.
       
  1204 
       
  1205     \value OpenGL_Version_2_1  OpenGL version 2.1 or higher is present.
       
  1206 
       
  1207     \value OpenGL_Version_3_0  OpenGL version 3.0 or higher is present.
       
  1208 
       
  1209     \value OpenGL_ES_CommonLite_Version_1_0  OpenGL ES version 1.0 Common Lite or higher is present.
       
  1210 
       
  1211     \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.
       
  1213 
       
  1214     \value OpenGL_ES_CommonLite_Version_1_1  OpenGL ES version 1.1 Common Lite or higher is present.
       
  1215 
       
  1216     \value OpenGL_ES_Common_Version_1_1  OpenGL ES version 1.1 Common or higher is present.
       
  1217     The Common profile supports all the features of Common Lite.
       
  1218 
       
  1219     \value OpenGL_ES_Version_2_0  OpenGL ES version 2.0 or higher is present.
       
  1220     Note that OpenGL ES version 2.0 does not support all the features of OpenGL ES 1.x.
       
  1221     So if OpenGL_ES_Version_2_0 is returned, none of the ES 1.x flags are returned.
       
  1222 
       
  1223     See also \l{http://www.opengl.org} for more information about the different
       
  1224     revisions of OpenGL.
       
  1225 
       
  1226     \sa openGLVersionFlags()
       
  1227 */
       
  1228 
       
  1229 /*!
       
  1230     \since 4.2
       
  1231 
       
  1232     Identifies, at runtime, which OpenGL versions that are supported
       
  1233     by the current platform.
       
  1234 
       
  1235     Note that if OpenGL version 1.5 is supported, its predecessors
       
  1236     (i.e., version 1.4 and lower) are also supported. To identify the
       
  1237     support of a particular feature, like multi texturing, test for
       
  1238     the version in which the feature was first introduced (i.e.,
       
  1239     version 1.3 in the case of multi texturing) to adapt to the largest
       
  1240     possible group of runtime platforms.
       
  1241 
       
  1242     This function needs a valid current OpenGL context to work;
       
  1243     otherwise it will return OpenGL_Version_None.
       
  1244 
       
  1245     \sa hasOpenGL(), hasOpenGLOverlays()
       
  1246 */
       
  1247 QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags()
       
  1248 {
       
  1249     static bool cachedDefault = false;
       
  1250     static OpenGLVersionFlags defaultVersionFlags = OpenGL_Version_None;
       
  1251     QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext());
       
  1252     QGLTemporaryContext *tmpContext = 0;
       
  1253 
       
  1254     if (currentCtx && currentCtx->d_func()->version_flags_cached)
       
  1255         return currentCtx->d_func()->version_flags;
       
  1256 
       
  1257     if (!currentCtx) {
       
  1258         if (cachedDefault) {
       
  1259             return defaultVersionFlags;
       
  1260         } else {
       
  1261             if (!hasOpenGL())
       
  1262                 return defaultVersionFlags;
       
  1263             tmpContext = new QGLTemporaryContext;
       
  1264             cachedDefault = true;
       
  1265         }
       
  1266     }
       
  1267 
       
  1268     QString versionString(QLatin1String(reinterpret_cast<const char*>(glGetString(GL_VERSION))));
       
  1269     OpenGLVersionFlags versionFlags = qOpenGLVersionFlagsFromString(versionString);
       
  1270     if (currentCtx) {
       
  1271         currentCtx->d_func()->version_flags_cached = true;
       
  1272         currentCtx->d_func()->version_flags = versionFlags;
       
  1273     }
       
  1274     if (tmpContext) {
       
  1275         defaultVersionFlags = versionFlags;
       
  1276         delete tmpContext;
       
  1277     }
       
  1278 
       
  1279     return versionFlags;
       
  1280 }
       
  1281 
       
  1282 
       
  1283 /*!
       
  1284     Returns the default QGLFormat for the application. All QGLWidget
       
  1285     objects that are created use this format unless another format is
       
  1286     specified, e.g. when they are constructed.
       
  1287 
       
  1288     If no special default format has been set using
       
  1289     setDefaultFormat(), the default format is the same as that created
       
  1290     with QGLFormat().
       
  1291 
       
  1292     \sa setDefaultFormat()
       
  1293 */
       
  1294 
       
  1295 QGLFormat QGLFormat::defaultFormat()
       
  1296 {
       
  1297     return *qgl_default_format();
       
  1298 }
       
  1299 
       
  1300 /*!
       
  1301     Sets a new default QGLFormat for the application to \a f. For
       
  1302     example, to set single buffering as the default instead of double
       
  1303     buffering, your main() might contain code like this:
       
  1304     \snippet doc/src/snippets/code/src_opengl_qgl.cpp 4
       
  1305 
       
  1306     \sa defaultFormat()
       
  1307 */
       
  1308 
       
  1309 void QGLFormat::setDefaultFormat(const QGLFormat &f)
       
  1310 {
       
  1311     *qgl_default_format() = f;
       
  1312 }
       
  1313 
       
  1314 
       
  1315 /*!
       
  1316     Returns the default QGLFormat for overlay contexts.
       
  1317 
       
  1318     The default overlay format is:
       
  1319     \list
       
  1320     \i \link setDoubleBuffer() Double buffer:\endlink Disabled.
       
  1321     \i \link setDepth() Depth buffer:\endlink Disabled.
       
  1322     \i \link setRgba() RGBA:\endlink Disabled (i.e., color index enabled).
       
  1323     \i \link setAlpha() Alpha channel:\endlink Disabled.
       
  1324     \i \link setAccum() Accumulator buffer:\endlink Disabled.
       
  1325     \i \link setStencil() Stencil buffer:\endlink Disabled.
       
  1326     \i \link setStereo() Stereo:\endlink Disabled.
       
  1327     \i \link setDirectRendering() Direct rendering:\endlink Enabled.
       
  1328     \i \link setOverlay() Overlay:\endlink Disabled.
       
  1329     \i \link setSampleBuffers() Multisample buffers:\endlink Disabled.
       
  1330     \i \link setPlane() Plane:\endlink 1 (i.e., first overlay plane).
       
  1331     \endlist
       
  1332 
       
  1333     \sa setDefaultFormat()
       
  1334 */
       
  1335 
       
  1336 QGLFormat QGLFormat::defaultOverlayFormat()
       
  1337 {
       
  1338     return *defaultOverlayFormatInstance();
       
  1339 }
       
  1340 
       
  1341 /*!
       
  1342     Sets a new default QGLFormat for overlay contexts to \a f. This
       
  1343     format is used whenever a QGLWidget is created with a format that
       
  1344     hasOverlay() enabled.
       
  1345 
       
  1346     For example, to get a double buffered overlay context (if
       
  1347     available), use code like this:
       
  1348 
       
  1349     \snippet doc/src/snippets/code/src_opengl_qgl.cpp 5
       
  1350 
       
  1351     As usual, you can find out after widget creation whether the
       
  1352     underlying OpenGL system was able to provide the requested
       
  1353     specification:
       
  1354 
       
  1355     \snippet doc/src/snippets/code/src_opengl_qgl.cpp 6
       
  1356 
       
  1357     \sa defaultOverlayFormat()
       
  1358 */
       
  1359 
       
  1360 void QGLFormat::setDefaultOverlayFormat(const QGLFormat &f)
       
  1361 {
       
  1362     QGLFormat *defaultFormat = defaultOverlayFormatInstance();
       
  1363     *defaultFormat = f;
       
  1364     // Make sure the user doesn't request that the overlays themselves
       
  1365     // have overlays, since it is unlikely that the system supports
       
  1366     // infinitely many planes...
       
  1367     defaultFormat->setOverlay(false);
       
  1368 }
       
  1369 
       
  1370 
       
  1371 /*!
       
  1372     Returns true if all the options of the two QGLFormat objects
       
  1373     \a a and \a b are equal; otherwise returns false.
       
  1374 
       
  1375     \relates QGLFormat
       
  1376 */
       
  1377 
       
  1378 bool operator==(const QGLFormat& a, const QGLFormat& b)
       
  1379 {
       
  1380     return (int) a.d->opts == (int) b.d->opts && a.d->pln == b.d->pln && a.d->alphaSize == b.d->alphaSize
       
  1381         && a.d->accumSize == b.d->accumSize && a.d->stencilSize == b.d->stencilSize
       
  1382         && a.d->depthSize == b.d->depthSize
       
  1383         && a.d->redSize == b.d->redSize
       
  1384         && a.d->greenSize == b.d->greenSize
       
  1385         && a.d->blueSize == b.d->blueSize
       
  1386         && a.d->numSamples == b.d->numSamples
       
  1387         && a.d->swapInterval == b.d->swapInterval;
       
  1388 }
       
  1389 
       
  1390 
       
  1391 /*!
       
  1392     Returns false if all the options of the two QGLFormat objects
       
  1393     \a a and \a b are equal; otherwise returns true.
       
  1394 
       
  1395     \relates QGLFormat
       
  1396 */
       
  1397 
       
  1398 bool operator!=(const QGLFormat& a, const QGLFormat& b)
       
  1399 {
       
  1400     return !(a == b);
       
  1401 }
       
  1402 
       
  1403 /*****************************************************************************
       
  1404   QGLContext implementation
       
  1405  *****************************************************************************/
       
  1406 
       
  1407 QGLContextGroup::~QGLContextGroup()
       
  1408 {
       
  1409     // Clear any remaining QGLSharedResourceGuard objects on the group.
       
  1410     QGLSharedResourceGuard *guard = m_guards;
       
  1411     while (guard != 0) {
       
  1412         guard->m_group = 0;
       
  1413         guard->m_id = 0;
       
  1414         guard = guard->m_next;
       
  1415     }
       
  1416 }
       
  1417 
       
  1418 void QGLContextGroup::addGuard(QGLSharedResourceGuard *guard)
       
  1419 {
       
  1420     if (m_guards)
       
  1421         m_guards->m_prev = guard;
       
  1422     guard->m_next = m_guards;
       
  1423     guard->m_prev = 0;
       
  1424     m_guards = guard;
       
  1425 }
       
  1426 
       
  1427 void QGLContextGroup::removeGuard(QGLSharedResourceGuard *guard)
       
  1428 {
       
  1429     if (guard->m_next)
       
  1430         guard->m_next->m_prev = guard->m_prev;
       
  1431     if (guard->m_prev)
       
  1432         guard->m_prev->m_next = guard->m_next;
       
  1433     else
       
  1434         m_guards = guard->m_next;
       
  1435 }
       
  1436 
       
  1437 const QGLContext *qt_gl_transfer_context(const QGLContext *ctx)
       
  1438 {
       
  1439     if (!ctx)
       
  1440         return 0;
       
  1441     QList<const QGLContext *> shares
       
  1442         (QGLContextPrivate::contextGroup(ctx)->shares());
       
  1443     if (shares.size() >= 2)
       
  1444         return (ctx == shares.at(0)) ? shares.at(1) : shares.at(0);
       
  1445     else
       
  1446         return 0;
       
  1447 }
       
  1448 
       
  1449 QGLContextPrivate::~QGLContextPrivate()
       
  1450 {
       
  1451     if (!group->m_refs.deref()) {
       
  1452         Q_ASSERT(group->context() == q_ptr);
       
  1453         delete group;
       
  1454     }
       
  1455 }
       
  1456 
       
  1457 void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
       
  1458 {
       
  1459     Q_Q(QGLContext);
       
  1460     glFormat = reqFormat = format;
       
  1461     valid = false;
       
  1462     q->setDevice(dev);
       
  1463 #if defined(Q_WS_X11)
       
  1464     pbuf = 0;
       
  1465     gpm = 0;
       
  1466     vi = 0;
       
  1467     screen = QX11Info::appScreen();
       
  1468 #endif
       
  1469 #if defined(Q_WS_WIN)
       
  1470     dc = 0;
       
  1471     win = 0;
       
  1472     pixelFormatId = 0;
       
  1473     cmap = 0;
       
  1474     hbitmap = 0;
       
  1475     hbitmap_hdc = 0;
       
  1476 #endif
       
  1477 #if defined(Q_WS_MAC)
       
  1478 #  ifndef QT_MAC_USE_COCOA
       
  1479     update = false;
       
  1480 #  endif
       
  1481     vi = 0;
       
  1482 #endif
       
  1483 #if defined(QT_OPENGL_ES)
       
  1484     eglContext = 0;
       
  1485     eglSurface = EGL_NO_SURFACE;
       
  1486 #endif
       
  1487     fbo = 0;
       
  1488     crWin = false;
       
  1489     initDone = false;
       
  1490     sharing = false;
       
  1491     max_texture_size = -1;
       
  1492     version_flags_cached = false;
       
  1493     version_flags = QGLFormat::OpenGL_Version_None;
       
  1494     extension_flags_cached = false;
       
  1495     extension_flags = 0;
       
  1496     current_fbo = 0;
       
  1497     default_fbo = 0;
       
  1498     active_engine = 0;
       
  1499     for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
       
  1500         vertexAttributeArraysEnabledState[i] = false;
       
  1501 }
       
  1502 
       
  1503 QGLContext* QGLContext::currentCtx = 0;
       
  1504 
       
  1505 /*
       
  1506    Read back the contents of the currently bound framebuffer, used in
       
  1507    QGLWidget::grabFrameBuffer(), QGLPixelbuffer::toImage() and
       
  1508    QGLFramebufferObject::toImage()
       
  1509 */
       
  1510 
       
  1511 static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, bool include_alpha)
       
  1512 {
       
  1513     if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
       
  1514         // OpenGL gives RGBA; Qt wants ARGB
       
  1515         uint *p = (uint*)img.bits();
       
  1516         uint *end = p + w*h;
       
  1517         if (alpha_format && include_alpha) {
       
  1518             while (p < end) {
       
  1519                 uint a = *p << 24;
       
  1520                 *p = (*p >> 8) | a;
       
  1521                 p++;
       
  1522             }
       
  1523         } else {
       
  1524             // This is an old legacy fix for PowerPC based Macs, which
       
  1525             // we shouldn't remove
       
  1526             while (p < end) {
       
  1527                 *p = 0xff000000 | (*p>>8);
       
  1528                 ++p;
       
  1529             }
       
  1530         }
       
  1531     } else {
       
  1532         // OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB
       
  1533         for (int y = 0; y < h; y++) {
       
  1534             uint *q = (uint*)img.scanLine(y);
       
  1535             for (int x=0; x < w; ++x) {
       
  1536                 const uint pixel = *q;
       
  1537                 *q = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00);
       
  1538                 q++;
       
  1539             }
       
  1540         }
       
  1541 
       
  1542     }
       
  1543     img = img.mirrored();
       
  1544 }
       
  1545 
       
  1546 QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
       
  1547 {
       
  1548     QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32);
       
  1549     int w = size.width();
       
  1550     int h = size.height();
       
  1551     glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
       
  1552     convertFromGLImage(img, w, h, alpha_format, include_alpha);
       
  1553     return img;
       
  1554 }
       
  1555 
       
  1556 QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha)
       
  1557 {
       
  1558     QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
       
  1559     int w = size.width();
       
  1560     int h = size.height();
       
  1561 #if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
       
  1562     //### glGetTexImage not in GL ES 2.0, need to do something else here!
       
  1563     glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
       
  1564 #endif
       
  1565     convertFromGLImage(img, w, h, alpha_format, include_alpha);
       
  1566     return img;
       
  1567 }
       
  1568 
       
  1569 // returns the highest number closest to v, which is a power of 2
       
  1570 // NB! assumes 32 bit ints
       
  1571 int qt_next_power_of_two(int v)
       
  1572 {
       
  1573     v--;
       
  1574     v |= v >> 1;
       
  1575     v |= v >> 2;
       
  1576     v |= v >> 4;
       
  1577     v |= v >> 8;
       
  1578     v |= v >> 16;
       
  1579     ++v;
       
  1580     return v;
       
  1581 }
       
  1582 
       
  1583 typedef void (*_qt_pixmap_cleanup_hook_64)(qint64);
       
  1584 typedef void (*_qt_image_cleanup_hook_64)(qint64);
       
  1585 
       
  1586 extern Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64;
       
  1587 extern Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64;
       
  1588 
       
  1589 static QGLTextureCache *qt_gl_texture_cache = 0;
       
  1590 
       
  1591 QGLTextureCache::QGLTextureCache()
       
  1592     : m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though
       
  1593 {
       
  1594     Q_ASSERT(qt_gl_texture_cache == 0);
       
  1595     qt_gl_texture_cache = this;
       
  1596 
       
  1597     QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTexturesForPixampData);
       
  1598     QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction);
       
  1599     QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey);
       
  1600 }
       
  1601 
       
  1602 QGLTextureCache::~QGLTextureCache()
       
  1603 {
       
  1604     qt_gl_texture_cache = 0;
       
  1605 
       
  1606     QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData);
       
  1607     QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction);
       
  1608     QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
       
  1609 }
       
  1610 
       
  1611 void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, int cost)
       
  1612 {
       
  1613     if (m_cache.totalCost() + cost > m_cache.maxCost()) {
       
  1614         // the cache is full - make an attempt to remove something
       
  1615         const QList<qint64> keys = m_cache.keys();
       
  1616         int i = 0;
       
  1617         while (i < m_cache.count()
       
  1618                && (m_cache.totalCost() + cost > m_cache.maxCost())) {
       
  1619             QGLTexture *tex = m_cache.object(keys.at(i));
       
  1620             if (tex->context == ctx)
       
  1621                 m_cache.remove(keys.at(i));
       
  1622             ++i;
       
  1623         }
       
  1624     }
       
  1625     m_cache.insert(key, texture, cost);
       
  1626 }
       
  1627 
       
  1628 bool QGLTextureCache::remove(QGLContext* ctx, GLuint textureId)
       
  1629 {
       
  1630     QList<qint64> keys = m_cache.keys();
       
  1631     for (int i = 0; i < keys.size(); ++i) {
       
  1632         QGLTexture *tex = m_cache.object(keys.at(i));
       
  1633         if (tex->id == textureId && tex->context == ctx) {
       
  1634             tex->options |= QGLContext::MemoryManagedBindOption; // forces a glDeleteTextures() call
       
  1635             m_cache.remove(keys.at(i));
       
  1636             return true;
       
  1637         }
       
  1638     }
       
  1639     return false;
       
  1640 }
       
  1641 
       
  1642 void QGLTextureCache::removeContextTextures(QGLContext* ctx)
       
  1643 {
       
  1644     QList<qint64> keys = m_cache.keys();
       
  1645     for (int i = 0; i < keys.size(); ++i) {
       
  1646         const qint64 &key = keys.at(i);
       
  1647         if (m_cache.object(key)->context == ctx)
       
  1648             m_cache.remove(key);
       
  1649     }
       
  1650 }
       
  1651 
       
  1652 QGLTextureCache* QGLTextureCache::instance()
       
  1653 {
       
  1654     if (!qt_gl_texture_cache)
       
  1655         qt_gl_texture_cache = new QGLTextureCache;
       
  1656 
       
  1657     return qt_gl_texture_cache;
       
  1658 }
       
  1659 
       
  1660 /*
       
  1661   a hook that removes textures from the cache when a pixmap/image
       
  1662   is deref'ed
       
  1663 */
       
  1664 void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey)
       
  1665 {
       
  1666     // ### remove when the GL texture cache becomes thread-safe
       
  1667     if (qApp->thread() == QThread::currentThread()) {
       
  1668         instance()->remove(cacheKey);
       
  1669         Q_ASSERT(instance()->getTexture(cacheKey) == 0);
       
  1670     }
       
  1671 }
       
  1672 
       
  1673 
       
  1674 void QGLTextureCache::cleanupTexturesForPixampData(QPixmapData* pmd)
       
  1675 {
       
  1676     cleanupTexturesForCacheKey(pmd->cacheKey());
       
  1677 }
       
  1678 
       
  1679 void QGLTextureCache::cleanupBeforePixmapDestruction(QPixmapData* pmd)
       
  1680 {
       
  1681     // Remove any bound textures first:
       
  1682     cleanupTexturesForPixampData(pmd);
       
  1683 
       
  1684 #if defined(Q_WS_X11)
       
  1685     if (pmd->classId() == QPixmapData::X11Class) {
       
  1686         Q_ASSERT(pmd->ref == 0); // Make sure reference counting isn't broken
       
  1687         QGLContextPrivate::destroyGlSurfaceForPixmap(pmd);
       
  1688     }
       
  1689 #endif
       
  1690 }
       
  1691 
       
  1692 void QGLTextureCache::deleteIfEmpty()
       
  1693 {
       
  1694     if (instance()->size() == 0)
       
  1695         delete instance();
       
  1696 }
       
  1697 
       
  1698 // DDS format structure
       
  1699 struct DDSFormat {
       
  1700     quint32 dwSize;
       
  1701     quint32 dwFlags;
       
  1702     quint32 dwHeight;
       
  1703     quint32 dwWidth;
       
  1704     quint32 dwLinearSize;
       
  1705     quint32 dummy1;
       
  1706     quint32 dwMipMapCount;
       
  1707     quint32 dummy2[11];
       
  1708     struct {
       
  1709         quint32 dummy3[2];
       
  1710         quint32 dwFourCC;
       
  1711         quint32 dummy4[5];
       
  1712     } ddsPixelFormat;
       
  1713 };
       
  1714 
       
  1715 // compressed texture pixel formats
       
  1716 #define FOURCC_DXT1  0x31545844
       
  1717 #define FOURCC_DXT2  0x32545844
       
  1718 #define FOURCC_DXT3  0x33545844
       
  1719 #define FOURCC_DXT4  0x34545844
       
  1720 #define FOURCC_DXT5  0x35545844
       
  1721 
       
  1722 #ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
       
  1723 #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT   0x83F0
       
  1724 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT  0x83F1
       
  1725 #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT  0x83F2
       
  1726 #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT  0x83F3
       
  1727 #endif
       
  1728 
       
  1729 #ifndef GL_GENERATE_MIPMAP_SGIS
       
  1730 #define GL_GENERATE_MIPMAP_SGIS       0x8191
       
  1731 #define GL_GENERATE_MIPMAP_HINT_SGIS  0x8192
       
  1732 #endif
       
  1733 
       
  1734 /*!
       
  1735     \class QGLContext
       
  1736     \brief The QGLContext class encapsulates an OpenGL rendering context.
       
  1737 
       
  1738     \ingroup painting-3D
       
  1739 
       
  1740     An OpenGL rendering context is a complete set of OpenGL state
       
  1741     variables. The rendering context's \l {QGL::FormatOption} {format}
       
  1742     is set in the constructor, but it can also be set later with
       
  1743     setFormat(). The format options that are actually set are returned
       
  1744     by format(); the options you asked for are returned by
       
  1745     requestedFormat(). Note that after a QGLContext object has been
       
  1746     constructed, the actual OpenGL context must be created by
       
  1747     explicitly calling the \link create() create()\endlink
       
  1748     function. The makeCurrent() function makes this context the
       
  1749     current rendering context. You can make \e no context current
       
  1750     using doneCurrent(). The reset() function will reset the context
       
  1751     and make it invalid.
       
  1752 
       
  1753     You can examine properties of the context with, e.g. isValid(),
       
  1754     isSharing(), initialized(), windowCreated() and
       
  1755     overlayTransparentColor().
       
  1756 
       
  1757     If you're using double buffering you can swap the screen contents
       
  1758     with the off-screen buffer using swapBuffers().
       
  1759 
       
  1760     Please note that QGLContext is not thread safe.
       
  1761 */
       
  1762 
       
  1763 /*!
       
  1764     \enum QGLContext::BindOption
       
  1765     \since 4.6
       
  1766 
       
  1767     A set of options to decide how to bind a texture using bindTexture().
       
  1768 
       
  1769     \value NoBindOption Don't do anything, pass the texture straight
       
  1770     through.
       
  1771 
       
  1772     \value InvertedYBindOption Specifies that the texture should be flipped
       
  1773     over the X axis so that the texture coordinate 0,0 corresponds to
       
  1774     the top left corner. Inverting the texture implies a deep copy
       
  1775     prior to upload.
       
  1776 
       
  1777     \value MipmapBindOption Specifies that bindTexture() should try
       
  1778     to generate mipmaps.  If the GL implementation supports the \c
       
  1779     GL_SGIS_generate_mipmap extension, mipmaps will be automatically
       
  1780     generated for the texture. Mipmap generation is only supported for
       
  1781     the \c GL_TEXTURE_2D target.
       
  1782 
       
  1783     \value PremultipliedAlphaBindOption Specifies that the image should be
       
  1784     uploaded with premultiplied alpha and does a conversion accordingly.
       
  1785 
       
  1786     \value LinearFilteringBindOption Specifies that the texture filtering
       
  1787     should be set to GL_LINEAR. Default is GL_NEAREST. If mipmap is
       
  1788     also enabled, filtering will be set to GL_LINEAR_MIPMAP_LINEAR.
       
  1789 
       
  1790     \value DefaultBindOption In Qt 4.5 and earlier, bindTexture()
       
  1791     would mirror the image and automatically generate mipmaps. This
       
  1792     option helps preserve this default behavior.
       
  1793 
       
  1794     \omitvalue CanFlipNativePixmapBindOption Used by x11 from pixmap to choose
       
  1795     wether or not it can bind the pixmap upside down or not.
       
  1796 
       
  1797     \omitvalue MemoryManagedBindOption Used by paint engines to
       
  1798     indicate that the pixmap should be memory managed along side with
       
  1799     the pixmap/image that it stems from, e.g. installing destruction
       
  1800     hooks in them.
       
  1801 
       
  1802     \omitvalue InternalBindOption
       
  1803 */
       
  1804 
       
  1805 /*!
       
  1806     \obsolete
       
  1807 
       
  1808     Constructs an OpenGL context for the given paint \a device, which
       
  1809     can be a widget or a pixmap. The \a format specifies several
       
  1810     display options for the context.
       
  1811 
       
  1812     If the underlying OpenGL/Window system cannot satisfy all the
       
  1813     features requested in \a format, the nearest subset of features
       
  1814     will be used. After creation, the format() method will return the
       
  1815     actual format obtained.
       
  1816 
       
  1817     Note that after a QGLContext object has been constructed, \l
       
  1818     create() must be called explicitly to create the actual OpenGL
       
  1819     context. The context will be \l {isValid()}{invalid} if it was not
       
  1820     possible to obtain a GL context at all.
       
  1821 */
       
  1822 
       
  1823 QGLContext::QGLContext(const QGLFormat &format, QPaintDevice *device)
       
  1824     : d_ptr(new QGLContextPrivate(this))
       
  1825 {
       
  1826     Q_D(QGLContext);
       
  1827     d->init(device, format);
       
  1828 }
       
  1829 
       
  1830 /*!
       
  1831     Constructs an OpenGL context with the given \a format which
       
  1832     specifies several display options for the context.
       
  1833 
       
  1834     If the underlying OpenGL/Window system cannot satisfy all the
       
  1835     features requested in \a format, the nearest subset of features
       
  1836     will be used. After creation, the format() method will return the
       
  1837     actual format obtained.
       
  1838 
       
  1839     Note that after a QGLContext object has been constructed, \l
       
  1840     create() must be called explicitly to create the actual OpenGL
       
  1841     context. The context will be \l {isValid()}{invalid} if it was not
       
  1842     possible to obtain a GL context at all.
       
  1843 
       
  1844     \sa format(), isValid()
       
  1845 */
       
  1846 QGLContext::QGLContext(const QGLFormat &format)
       
  1847     : d_ptr(new QGLContextPrivate(this))
       
  1848 {
       
  1849     Q_D(QGLContext);
       
  1850     d->init(0, format);
       
  1851 }
       
  1852 
       
  1853 /*!
       
  1854     Destroys the OpenGL context and frees its resources.
       
  1855 */
       
  1856 
       
  1857 QGLContext::~QGLContext()
       
  1858 {
       
  1859     // remove any textures cached in this context
       
  1860     QGLTextureCache::instance()->removeContextTextures(this);
       
  1861     QGLTextureCache::deleteIfEmpty(); // ### thread safety
       
  1862 
       
  1863     d_ptr->group->cleanupResources(this);
       
  1864 
       
  1865     QGLSignalProxy::instance()->emitAboutToDestroyContext(this);
       
  1866     reset();
       
  1867 }
       
  1868 
       
  1869 void QGLContextPrivate::cleanup()
       
  1870 {
       
  1871 }
       
  1872 
       
  1873 #define ctx q_ptr
       
  1874 void QGLContextPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled)
       
  1875 {
       
  1876     Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT);
       
  1877     Q_ASSERT(glEnableVertexAttribArray);
       
  1878 
       
  1879     if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled)
       
  1880         glDisableVertexAttribArray(arrayIndex);
       
  1881 
       
  1882     if (!vertexAttributeArraysEnabledState[arrayIndex] && enabled)
       
  1883         glEnableVertexAttribArray(arrayIndex);
       
  1884 
       
  1885     vertexAttributeArraysEnabledState[arrayIndex] = enabled;
       
  1886 }
       
  1887 
       
  1888 void QGLContextPrivate::syncGlState()
       
  1889 {
       
  1890     Q_ASSERT(glEnableVertexAttribArray);
       
  1891     for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) {
       
  1892         if (vertexAttributeArraysEnabledState[i])
       
  1893             glEnableVertexAttribArray(i);
       
  1894         else
       
  1895             glDisableVertexAttribArray(i);
       
  1896     }
       
  1897 
       
  1898 }
       
  1899 #undef ctx
       
  1900 
       
  1901 
       
  1902 /*!
       
  1903     \overload
       
  1904 
       
  1905     Reads the compressed texture file \a fileName and generates a 2D GL
       
  1906     texture from it.
       
  1907 
       
  1908     This function can load DirectDrawSurface (DDS) textures in the
       
  1909     DXT1, DXT3 and DXT5 DDS formats if the \c GL_ARB_texture_compression
       
  1910     and \c GL_EXT_texture_compression_s3tc extensions are supported.
       
  1911 
       
  1912     Since 4.6.1, textures in the ETC1 format can be loaded if the
       
  1913     \c GL_OES_compressed_ETC1_RGB8_texture extension is supported
       
  1914     and the ETC1 texture has been encapsulated in the PVR container format.
       
  1915     Also, textures in the PVRTC2 and PVRTC4 formats can be loaded
       
  1916     if the \c GL_IMG_texture_compression_pvrtc extension is supported.
       
  1917 
       
  1918     \sa deleteTexture()
       
  1919 */
       
  1920 
       
  1921 GLuint QGLContext::bindTexture(const QString &fileName)
       
  1922 {
       
  1923     Q_D(QGLContext);
       
  1924     QGLDDSCache *dds_cache = &(d->group->m_dds_cache);
       
  1925     QGLDDSCache::const_iterator it = dds_cache->constFind(fileName);
       
  1926     if (it != dds_cache->constEnd()) {
       
  1927         glBindTexture(GL_TEXTURE_2D, it.value());
       
  1928         return it.value();
       
  1929     }
       
  1930 
       
  1931     QGLTexture texture(this);
       
  1932     QSize size = texture.bindCompressedTexture(fileName);
       
  1933     if (!size.isValid())
       
  1934         return 0;
       
  1935 
       
  1936     dds_cache->insert(fileName, texture.id);
       
  1937     return texture.id;
       
  1938 }
       
  1939 
       
  1940 static inline QRgb qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture_format)
       
  1941 {
       
  1942     if (texture_format == GL_BGRA) {
       
  1943         if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
       
  1944             return ((src_pixel << 24) & 0xff000000)
       
  1945                    | ((src_pixel >> 24) & 0x000000ff)
       
  1946                    | ((src_pixel << 8) & 0x00ff0000)
       
  1947                    | ((src_pixel >> 8) & 0x0000ff00);
       
  1948         } else {
       
  1949             return src_pixel;
       
  1950         }
       
  1951     } else {  // GL_RGBA
       
  1952         if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
       
  1953             return (src_pixel << 8) | ((src_pixel >> 24) & 0xff);
       
  1954         } else {
       
  1955             return ((src_pixel << 16) & 0xff0000)
       
  1956                    | ((src_pixel >> 16) & 0xff)
       
  1957                    | (src_pixel & 0xff00ff00);
       
  1958         }
       
  1959     }
       
  1960 }
       
  1961 
       
  1962 QRgb qt_gl_convertToGLFormat(QRgb src_pixel, GLenum texture_format)
       
  1963 {
       
  1964     return qt_gl_convertToGLFormatHelper(src_pixel, texture_format);
       
  1965 }
       
  1966 
       
  1967 static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum texture_format)
       
  1968 {
       
  1969     Q_ASSERT(dst.depth() == 32);
       
  1970     Q_ASSERT(img.depth() == 32);
       
  1971 
       
  1972     if (dst.size() != img.size()) {
       
  1973         int target_width = dst.width();
       
  1974         int target_height = dst.height();
       
  1975         qreal sx = target_width / qreal(img.width());
       
  1976         qreal sy = target_height / qreal(img.height());
       
  1977 
       
  1978         quint32 *dest = (quint32 *) dst.scanLine(0); // NB! avoid detach here
       
  1979         uchar *srcPixels = (uchar *) img.scanLine(img.height() - 1);
       
  1980         int sbpl = img.bytesPerLine();
       
  1981         int dbpl = dst.bytesPerLine();
       
  1982 
       
  1983         int ix = int(0x00010000 / sx);
       
  1984         int iy = int(0x00010000 / sy);
       
  1985 
       
  1986         quint32 basex = int(0.5 * ix);
       
  1987         quint32 srcy = int(0.5 * iy);
       
  1988 
       
  1989         // scale, swizzle and mirror in one loop
       
  1990         while (target_height--) {
       
  1991             const uint *src = (const quint32 *) (srcPixels - (srcy >> 16) * sbpl);
       
  1992             int srcx = basex;
       
  1993             for (int x=0; x<target_width; ++x) {
       
  1994                 dest[x] = qt_gl_convertToGLFormatHelper(src[srcx >> 16], texture_format);
       
  1995                 srcx += ix;
       
  1996             }
       
  1997             dest = (quint32 *)(((uchar *) dest) + dbpl);
       
  1998             srcy += iy;
       
  1999         }
       
  2000     } else {
       
  2001         const int width = img.width();
       
  2002         const int height = img.height();
       
  2003         const uint *p = (const uint*) img.scanLine(img.height() - 1);
       
  2004         uint *q = (uint*) dst.scanLine(0);
       
  2005 
       
  2006         if (texture_format == GL_BGRA) {
       
  2007             if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
       
  2008                 // mirror + swizzle
       
  2009                 for (int i=0; i < height; ++i) {
       
  2010                     const uint *end = p + width;
       
  2011                     while (p < end) {
       
  2012                         *q = ((*p << 24) & 0xff000000)
       
  2013                              | ((*p >> 24) & 0x000000ff)
       
  2014                              | ((*p << 8) & 0x00ff0000)
       
  2015                              | ((*p >> 8) & 0x0000ff00);
       
  2016                         p++;
       
  2017                         q++;
       
  2018                     }
       
  2019                     p -= 2 * width;
       
  2020                 }
       
  2021             } else {
       
  2022                 const uint bytesPerLine = img.bytesPerLine();
       
  2023                 for (int i=0; i < height; ++i) {
       
  2024                     memcpy(q, p, bytesPerLine);
       
  2025                     q += width;
       
  2026                     p -= width;
       
  2027                 }
       
  2028             }
       
  2029         } else {
       
  2030             if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
       
  2031                 for (int i=0; i < height; ++i) {
       
  2032                     const uint *end = p + width;
       
  2033                     while (p < end) {
       
  2034                         *q = (*p << 8) | ((*p >> 24) & 0xff);
       
  2035                         p++;
       
  2036                         q++;
       
  2037                     }
       
  2038                     p -= 2 * width;
       
  2039                 }
       
  2040             } else {
       
  2041                 for (int i=0; i < height; ++i) {
       
  2042                     const uint *end = p + width;
       
  2043                     while (p < end) {
       
  2044                         *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
       
  2045                         p++;
       
  2046                         q++;
       
  2047                     }
       
  2048                     p -= 2 * width;
       
  2049                 }
       
  2050             }
       
  2051         }
       
  2052     }
       
  2053 }
       
  2054 
       
  2055 QImage QGLContextPrivate::convertToGLFormat(const QImage &image, bool force_premul,
       
  2056                                             GLenum texture_format)
       
  2057 {
       
  2058     QImage::Format target_format = image.format();
       
  2059     if (force_premul || image.format() != QImage::Format_ARGB32)
       
  2060         target_format = QImage::Format_ARGB32_Premultiplied;
       
  2061 
       
  2062     QImage result(image.width(), image.height(), target_format);
       
  2063     convertToGLFormatHelper(result, image.convertToFormat(target_format), texture_format);
       
  2064     return result;
       
  2065 }
       
  2066 
       
  2067 /*! \internal */
       
  2068 QGLTexture *QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format,
       
  2069                                            QGLContext::BindOptions options)
       
  2070 {
       
  2071     const qint64 key = image.cacheKey();
       
  2072     QGLTexture *texture = textureCacheLookup(key, target);
       
  2073     if (texture) {
       
  2074         glBindTexture(target, texture->id);
       
  2075         return texture;
       
  2076     }
       
  2077 
       
  2078     if (!texture)
       
  2079         texture = bindTexture(image, target, format, key, options);
       
  2080     // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null
       
  2081     Q_ASSERT(texture);
       
  2082 
       
  2083     // Enable the cleanup hooks for this image so that the texture cache entry is removed when the
       
  2084     // image gets deleted:
       
  2085     QImagePixmapCleanupHooks::enableCleanupHooks(image);
       
  2086 
       
  2087     return texture;
       
  2088 }
       
  2089 
       
  2090 // #define QGL_BIND_TEXTURE_DEBUG
       
  2091 
       
  2092 // map from Qt's ARGB endianness-dependent format to GL's big-endian RGBA layout
       
  2093 static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
       
  2094 {
       
  2095     const int width = img.width();
       
  2096     const int height = img.height();
       
  2097 
       
  2098     if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV
       
  2099         || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian))
       
  2100     {
       
  2101         for (int i = 0; i < height; ++i) {
       
  2102             uint *p = (uint *) img.scanLine(i);
       
  2103             for (int x = 0; x < width; ++x)
       
  2104                 p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
       
  2105         }
       
  2106     } else {
       
  2107         for (int i = 0; i < height; ++i) {
       
  2108             uint *p = (uint *) img.scanLine(i);
       
  2109             for (int x = 0; x < width; ++x)
       
  2110                 p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff);
       
  2111         }
       
  2112     }
       
  2113 }
       
  2114 
       
  2115 QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint internalFormat,
       
  2116                                            const qint64 key, QGLContext::BindOptions options)
       
  2117 {
       
  2118     Q_Q(QGLContext);
       
  2119 
       
  2120 #ifdef QGL_BIND_TEXTURE_DEBUG
       
  2121     printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x\n",
       
  2122            image.width(), image.height(), internalFormat, int(options));
       
  2123     QTime time;
       
  2124     time.start();
       
  2125 #endif
       
  2126 
       
  2127 #ifndef QT_NO_DEBUG
       
  2128     // Reset the gl error stack...git
       
  2129     while (glGetError() != GL_NO_ERROR) ;
       
  2130 #endif
       
  2131 
       
  2132     // Scale the pixmap if needed. GL textures needs to have the
       
  2133     // dimensions 2^n+2(border) x 2^m+2(border), unless we're using GL
       
  2134     // 2.0 or use the GL_TEXTURE_RECTANGLE texture target
       
  2135     int tx_w = qt_next_power_of_two(image.width());
       
  2136     int tx_h = qt_next_power_of_two(image.height());
       
  2137 
       
  2138     QImage img = image;
       
  2139 
       
  2140     if (!(QGLExtensions::glExtensions() & QGLExtensions::NPOTTextures)
       
  2141         && !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0)
       
  2142         && (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height())))
       
  2143     {
       
  2144         img = img.scaled(tx_w, tx_h);
       
  2145 #ifdef QGL_BIND_TEXTURE_DEBUG
       
  2146         printf(" - upscaled to %dx%d (%d ms)\n", tx_w, tx_h, time.elapsed());
       
  2147 
       
  2148 #endif
       
  2149     }
       
  2150 
       
  2151     GLuint filtering = options & QGLContext::LinearFilteringBindOption ? GL_LINEAR : GL_NEAREST;
       
  2152 
       
  2153     GLuint tx_id;
       
  2154     glGenTextures(1, &tx_id);
       
  2155     glBindTexture(target, tx_id);
       
  2156     glTexParameterf(target, GL_TEXTURE_MAG_FILTER, filtering);
       
  2157 
       
  2158 #if defined(QT_OPENGL_ES_2)
       
  2159     bool genMipmap = false;
       
  2160 #endif
       
  2161     if (glFormat.directRendering()
       
  2162         && (QGLExtensions::glExtensions() & QGLExtensions::GenerateMipmap)
       
  2163         && target == GL_TEXTURE_2D
       
  2164         && (options & QGLContext::MipmapBindOption))
       
  2165     {
       
  2166 #ifdef QGL_BIND_TEXTURE_DEBUG
       
  2167         printf(" - generating mipmaps (%d ms)\n", time.elapsed());
       
  2168 #endif
       
  2169 #if !defined(QT_OPENGL_ES_2)
       
  2170         glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
       
  2171 #ifndef QT_OPENGL_ES
       
  2172         glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
       
  2173 #else
       
  2174         glTexParameterf(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
       
  2175 #endif
       
  2176 #else
       
  2177         glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
       
  2178         genMipmap = true;
       
  2179 #endif
       
  2180         glTexParameterf(target, GL_TEXTURE_MIN_FILTER, options & QGLContext::LinearFilteringBindOption
       
  2181                         ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST);
       
  2182     } else {
       
  2183         glTexParameterf(target, GL_TEXTURE_MIN_FILTER, filtering);
       
  2184     }
       
  2185 
       
  2186     QImage::Format target_format = img.format();
       
  2187     bool premul = options & QGLContext::PremultipliedAlphaBindOption;
       
  2188     GLenum externalFormat;
       
  2189     GLuint pixel_type;
       
  2190     if (QGLExtensions::glExtensions() & QGLExtensions::BGRATextureFormat) {
       
  2191         externalFormat = GL_BGRA;
       
  2192         if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2)
       
  2193             pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV;
       
  2194         else
       
  2195             pixel_type = GL_UNSIGNED_BYTE;
       
  2196     } else {
       
  2197         externalFormat = GL_RGBA;
       
  2198         pixel_type = GL_UNSIGNED_BYTE;
       
  2199     }
       
  2200 
       
  2201     switch (target_format) {
       
  2202     case QImage::Format_ARGB32:
       
  2203         if (premul) {
       
  2204             img = img.convertToFormat(target_format = QImage::Format_ARGB32_Premultiplied);
       
  2205 #ifdef QGL_BIND_TEXTURE_DEBUG
       
  2206             printf(" - converting ARGB32 -> ARGB32_Premultiplied (%d ms) \n", time.elapsed());
       
  2207 #endif
       
  2208         }
       
  2209         break;
       
  2210     case QImage::Format_ARGB32_Premultiplied:
       
  2211         if (!premul) {
       
  2212             img = img.convertToFormat(target_format = QImage::Format_ARGB32);
       
  2213 #ifdef QGL_BIND_TEXTURE_DEBUG
       
  2214             printf(" - converting ARGB32_Premultiplied -> ARGB32 (%d ms)\n", time.elapsed());
       
  2215 #endif
       
  2216         }
       
  2217         break;
       
  2218     case QImage::Format_RGB16:
       
  2219         pixel_type = GL_UNSIGNED_SHORT_5_6_5;
       
  2220         externalFormat = GL_RGB;
       
  2221         internalFormat = GL_RGB;
       
  2222         break;
       
  2223     case QImage::Format_RGB32:
       
  2224         break;
       
  2225     default:
       
  2226         if (img.hasAlphaChannel()) {
       
  2227             img = img.convertToFormat(premul
       
  2228                                       ? QImage::Format_ARGB32_Premultiplied
       
  2229                                       : QImage::Format_ARGB32);
       
  2230 #ifdef QGL_BIND_TEXTURE_DEBUG
       
  2231             printf(" - converting to 32-bit alpha format (%d ms)\n", time.elapsed());
       
  2232 #endif
       
  2233         } else {
       
  2234             img = img.convertToFormat(QImage::Format_RGB32);
       
  2235 #ifdef QGL_BIND_TEXTURE_DEBUG
       
  2236             printf(" - converting to 32-bit (%d ms)\n", time.elapsed());
       
  2237 #endif
       
  2238         }
       
  2239     }
       
  2240 
       
  2241     if (options & QGLContext::InvertedYBindOption) {
       
  2242 #ifdef QGL_BIND_TEXTURE_DEBUG
       
  2243             printf(" - flipping bits over y (%d ms)\n", time.elapsed());
       
  2244 #endif
       
  2245         if (img.isDetached()) {
       
  2246             int ipl = img.bytesPerLine() / 4;
       
  2247             int h = img.height();
       
  2248             for (int y=0; y<h/2; ++y) {
       
  2249                 int *a = (int *) img.scanLine(y);
       
  2250                 int *b = (int *) img.scanLine(h - y - 1);
       
  2251                 for (int x=0; x<ipl; ++x)
       
  2252                     qSwap(a[x], b[x]);
       
  2253             }
       
  2254         } else {
       
  2255             // Create a new image and copy across.  If we use the
       
  2256             // above in-place code then a full copy of the image is
       
  2257             // made before the lines are swapped, which processes the
       
  2258             // data twice.  This version should only do it once.
       
  2259             img = img.mirrored();
       
  2260         }
       
  2261     }
       
  2262 
       
  2263     if (externalFormat == GL_RGBA) {
       
  2264 #ifdef QGL_BIND_TEXTURE_DEBUG
       
  2265             printf(" - doing byte swapping (%d ms)\n", time.elapsed());
       
  2266 #endif
       
  2267         // The only case where we end up with a depth different from
       
  2268         // 32 in the switch above is for the RGB16 case, where we set
       
  2269         // the format to GL_RGB
       
  2270         Q_ASSERT(img.depth() == 32);
       
  2271         qgl_byteSwapImage(img, pixel_type);
       
  2272     }
       
  2273 #ifdef QT_OPENGL_ES
       
  2274     // OpenGL/ES requires that the internal and external formats be
       
  2275     // identical.
       
  2276     internalFormat = externalFormat;
       
  2277 #endif
       
  2278 #ifdef QGL_BIND_TEXTURE_DEBUG
       
  2279     printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n",
       
  2280            img.format(), externalFormat, internalFormat, pixel_type);
       
  2281 #endif
       
  2282 
       
  2283     const QImage &constRef = img; // to avoid detach in bits()...
       
  2284     glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
       
  2285                  pixel_type, constRef.bits());
       
  2286 #if defined(QT_OPENGL_ES_2)
       
  2287     if (genMipmap)
       
  2288         glGenerateMipmap(target);
       
  2289 #endif
       
  2290 #ifndef QT_NO_DEBUG
       
  2291     GLenum error = glGetError();
       
  2292     if (error != GL_NO_ERROR) {
       
  2293         qWarning(" - texture upload failed, error code 0x%x\n", error);
       
  2294     }
       
  2295 #endif
       
  2296 
       
  2297 #ifdef QGL_BIND_TEXTURE_DEBUG
       
  2298     static int totalUploadTime = 0;
       
  2299     totalUploadTime += time.elapsed();
       
  2300     printf(" - upload done in (%d ms) time=%d\n", time.elapsed(), totalUploadTime);
       
  2301 #endif
       
  2302 
       
  2303 
       
  2304     // this assumes the size of a texture is always smaller than the max cache size
       
  2305     int cost = img.width()*img.height()*4/1024;
       
  2306     QGLTexture *texture = new QGLTexture(q, tx_id, target, options);
       
  2307     QGLTextureCache::instance()->insert(q, key, texture, cost);
       
  2308 
       
  2309     return texture;
       
  2310 }
       
  2311 
       
  2312 QGLTexture *QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum target)
       
  2313 {
       
  2314     Q_Q(QGLContext);
       
  2315     QGLTexture *texture = QGLTextureCache::instance()->getTexture(key);
       
  2316     if (texture && texture->target == target
       
  2317         && (texture->context == q || QGLContext::areSharing(q, texture->context)))
       
  2318     {
       
  2319         return texture;
       
  2320     }
       
  2321     return 0;
       
  2322 }
       
  2323 
       
  2324 
       
  2325 /*! \internal */
       
  2326 QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, QGLContext::BindOptions options)
       
  2327 {
       
  2328     Q_Q(QGLContext);
       
  2329     QPixmapData *pd = pixmap.pixmapData();
       
  2330 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
       
  2331     if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) {
       
  2332         const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pd);
       
  2333 
       
  2334         if (data->isValidContext(q)) {
       
  2335             data->bind();
       
  2336             return data->texture();
       
  2337         }
       
  2338     }
       
  2339 #else
       
  2340     Q_UNUSED(pd);
       
  2341     Q_UNUSED(q);
       
  2342 #endif
       
  2343 
       
  2344     const qint64 key = pixmap.cacheKey();
       
  2345     QGLTexture *texture = textureCacheLookup(key, target);
       
  2346     if (texture) {
       
  2347         glBindTexture(target, texture->id);
       
  2348         return texture;
       
  2349     }
       
  2350 
       
  2351 #if defined(Q_WS_X11)
       
  2352     // Try to use texture_from_pixmap
       
  2353     const QX11Info *xinfo = qt_x11Info(paintDevice);
       
  2354     if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType
       
  2355         && xinfo && xinfo->screen() == pixmap.x11Info().screen())
       
  2356     {
       
  2357         texture = bindTextureFromNativePixmap(pd, key, options);
       
  2358         if (texture) {
       
  2359             texture->options |= QGLContext::MemoryManagedBindOption;
       
  2360             texture->boundPixmap = pd;
       
  2361             boundPixmaps.insert(pd, QPixmap(pixmap));
       
  2362         }
       
  2363     }
       
  2364 #endif
       
  2365 
       
  2366     if (!texture)
       
  2367         texture = bindTexture(pixmap.toImage(), target, format, key, options);
       
  2368     // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null
       
  2369     Q_ASSERT(texture);
       
  2370 
       
  2371     if (texture->id > 0)
       
  2372         QImagePixmapCleanupHooks::enableCleanupHooks(pixmap);
       
  2373 
       
  2374     return texture;
       
  2375 }
       
  2376 
       
  2377 /*! \internal */
       
  2378 int QGLContextPrivate::maxTextureSize()
       
  2379 {
       
  2380     if (max_texture_size != -1)
       
  2381         return max_texture_size;
       
  2382 
       
  2383     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
       
  2384 
       
  2385 #if defined(QT_OPENGL_ES)
       
  2386     return max_texture_size;
       
  2387 #else
       
  2388     GLenum proxy = GL_PROXY_TEXTURE_2D;
       
  2389 
       
  2390     GLint size;
       
  2391     GLint next = 64;
       
  2392     glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
       
  2393     glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
       
  2394     if (size == 0) {
       
  2395         return max_texture_size;
       
  2396     }
       
  2397     do {
       
  2398         size = next;
       
  2399         next = size * 2;
       
  2400 
       
  2401         if (next > max_texture_size)
       
  2402             break;
       
  2403         glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
       
  2404         glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
       
  2405     } while (next > size);
       
  2406 
       
  2407     max_texture_size = size;
       
  2408     return max_texture_size;
       
  2409 #endif
       
  2410 }
       
  2411 
       
  2412 /*!
       
  2413   Generates and binds a 2D GL texture to the current context, based
       
  2414   on \a image. The generated texture id is returned and can be used in
       
  2415   later \c glBindTexture() calls.
       
  2416 
       
  2417   \overload
       
  2418 */
       
  2419 GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format)
       
  2420 {
       
  2421     if (image.isNull())
       
  2422         return 0;
       
  2423 
       
  2424     Q_D(QGLContext);
       
  2425     QGLTexture *texture = d->bindTexture(image, target, format, DefaultBindOption);
       
  2426     return texture->id;
       
  2427 }
       
  2428 
       
  2429 /*!
       
  2430     \since 4.6
       
  2431 
       
  2432     Generates and binds a 2D GL texture to the current context, based
       
  2433     on \a image. The generated texture id is returned and can be used
       
  2434     in later \c glBindTexture() calls.
       
  2435 
       
  2436     The \a target parameter specifies the texture target. The default
       
  2437     target is \c GL_TEXTURE_2D.
       
  2438 
       
  2439     The \a format parameter sets the internal format for the
       
  2440     texture. The default format is \c GL_RGBA.
       
  2441 
       
  2442     The binding \a options are a set of options used to decide how to
       
  2443     bind the texture to the context.
       
  2444 
       
  2445     The texture that is generated is cached, so multiple calls to
       
  2446     bindTexture() with the same QImage will return the same texture
       
  2447     id.
       
  2448 
       
  2449     Note that we assume default values for the glPixelStore() and
       
  2450     glPixelTransfer() parameters.
       
  2451 
       
  2452     \sa deleteTexture()
       
  2453 */
       
  2454 GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format, BindOptions options)
       
  2455 {
       
  2456     if (image.isNull())
       
  2457         return 0;
       
  2458 
       
  2459     Q_D(QGLContext);
       
  2460     QGLTexture *texture = d->bindTexture(image, target, format, false, options);
       
  2461     return texture->id;
       
  2462 }
       
  2463 
       
  2464 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
       
  2465 /*! \internal */
       
  2466 GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format)
       
  2467 {
       
  2468     if (image.isNull())
       
  2469         return 0;
       
  2470 
       
  2471     Q_D(QGLContext);
       
  2472     QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false, DefaultBindOption);
       
  2473     return texture->id;
       
  2474 }
       
  2475 
       
  2476 /*! \internal */
       
  2477 GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format,
       
  2478                                BindOptions options)
       
  2479 {
       
  2480     if (image.isNull())
       
  2481         return 0;
       
  2482 
       
  2483     Q_D(QGLContext);
       
  2484     QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false, options);
       
  2485     return texture->id;
       
  2486 }
       
  2487 #endif
       
  2488 
       
  2489 /*! \overload
       
  2490 
       
  2491     Generates and binds a 2D GL texture based on \a pixmap.
       
  2492 */
       
  2493 GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint format)
       
  2494 {
       
  2495     if (pixmap.isNull())
       
  2496         return 0;
       
  2497 
       
  2498     Q_D(QGLContext);
       
  2499     QGLTexture *texture = d->bindTexture(pixmap, target, format, DefaultBindOption);
       
  2500     return texture->id;
       
  2501 }
       
  2502 
       
  2503 /*!
       
  2504   \overload
       
  2505   \since 4.6
       
  2506 
       
  2507   Generates and binds a 2D GL texture to the current context, based
       
  2508   on \a pixmap.
       
  2509 */
       
  2510 GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, BindOptions options)
       
  2511 {
       
  2512     if (pixmap.isNull())
       
  2513         return 0;
       
  2514 
       
  2515     Q_D(QGLContext);
       
  2516     QGLTexture *texture = d->bindTexture(pixmap, target, format, options);
       
  2517     return texture->id;
       
  2518 }
       
  2519 
       
  2520 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
       
  2521 /*! \internal */
       
  2522 GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format)
       
  2523 {
       
  2524     if (pixmap.isNull())
       
  2525         return 0;
       
  2526 
       
  2527     Q_D(QGLContext);
       
  2528     QGLTexture *texture = d->bindTexture(pixmap, GLenum(target), GLint(format), DefaultBindOption);
       
  2529     return texture->id;
       
  2530 }
       
  2531 /*! \internal */
       
  2532 GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format,
       
  2533                                BindOptions options)
       
  2534 {
       
  2535     if (pixmap.isNull())
       
  2536         return 0;
       
  2537 
       
  2538     Q_D(QGLContext);
       
  2539     QGLTexture *texture = d->bindTexture(pixmap, GLenum(target), GLint(format), options);
       
  2540     return texture->id;
       
  2541 }
       
  2542 #endif
       
  2543 
       
  2544 /*!
       
  2545     Removes the texture identified by \a id from the texture cache,
       
  2546     and calls glDeleteTextures() to delete the texture from the
       
  2547     context.
       
  2548 
       
  2549     \sa bindTexture()
       
  2550 */
       
  2551 void QGLContext::deleteTexture(GLuint id)
       
  2552 {
       
  2553     Q_D(QGLContext);
       
  2554 
       
  2555     if (QGLTextureCache::instance()->remove(this, id))
       
  2556         return;
       
  2557 
       
  2558     // check the DDS cache if the texture wasn't found in the pixmap/image
       
  2559     // cache
       
  2560     QGLDDSCache *dds_cache = &(d->group->m_dds_cache);
       
  2561     QList<QString> ddsKeys = dds_cache->keys();
       
  2562     for (int i = 0; i < ddsKeys.size(); ++i) {
       
  2563         GLuint texture = dds_cache->value(ddsKeys.at(i));
       
  2564         if (id == texture) {
       
  2565             dds_cache->remove(ddsKeys.at(i));
       
  2566             break;
       
  2567         }
       
  2568     }
       
  2569 
       
  2570     // Finally, actually delete the texture ID
       
  2571     glDeleteTextures(1, &id);
       
  2572 }
       
  2573 
       
  2574 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
       
  2575 /*! \internal */
       
  2576 void QGLContext::deleteTexture(QMacCompatGLuint id)
       
  2577 {
       
  2578     return deleteTexture(GLuint(id));
       
  2579 }
       
  2580 #endif
       
  2581 
       
  2582 void qt_add_rect_to_array(const QRectF &r, q_vertexType *array)
       
  2583 {
       
  2584     qreal left = r.left();
       
  2585     qreal right = r.right();
       
  2586     qreal top = r.top();
       
  2587     qreal bottom = r.bottom();
       
  2588 
       
  2589     array[0] = f2vt(left);
       
  2590     array[1] = f2vt(top);
       
  2591     array[2] = f2vt(right);
       
  2592     array[3] = f2vt(top);
       
  2593     array[4] = f2vt(right);
       
  2594     array[5] = f2vt(bottom);
       
  2595     array[6] = f2vt(left);
       
  2596     array[7] = f2vt(bottom);
       
  2597 }
       
  2598 
       
  2599 void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array)
       
  2600 {
       
  2601     array[0] = f2vt(x1);
       
  2602     array[1] = f2vt(y1);
       
  2603     array[2] = f2vt(x2);
       
  2604     array[3] = f2vt(y1);
       
  2605     array[4] = f2vt(x2);
       
  2606     array[5] = f2vt(y2);
       
  2607     array[6] = f2vt(x1);
       
  2608     array[7] = f2vt(y2);
       
  2609 }
       
  2610 
       
  2611 #if !defined(QT_OPENGL_ES_2)
       
  2612 
       
  2613 static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint textureHeight, GLenum textureTarget)
       
  2614 {
       
  2615     q_vertexType tx = f2vt(1);
       
  2616     q_vertexType ty = f2vt(1);
       
  2617 
       
  2618 #ifdef QT_OPENGL_ES
       
  2619     Q_UNUSED(textureWidth);
       
  2620     Q_UNUSED(textureHeight);
       
  2621     Q_UNUSED(textureTarget);
       
  2622 #else
       
  2623     if (textureTarget != GL_TEXTURE_2D) {
       
  2624         if (textureWidth == -1 || textureHeight == -1) {
       
  2625             glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
       
  2626             glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
       
  2627         }
       
  2628 
       
  2629         tx = f2vt(textureWidth);
       
  2630         ty = f2vt(textureHeight);
       
  2631     }
       
  2632 #endif
       
  2633 
       
  2634     q_vertexType texCoordArray[4*2] = {
       
  2635         0, ty, tx, ty, tx, 0, 0, 0
       
  2636     };
       
  2637 
       
  2638     q_vertexType vertexArray[4*2];
       
  2639     qt_add_rect_to_array(target, vertexArray);
       
  2640 
       
  2641     glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);
       
  2642     glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray);
       
  2643 
       
  2644     glEnableClientState(GL_VERTEX_ARRAY);
       
  2645     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
       
  2646     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
       
  2647 
       
  2648     glDisableClientState(GL_VERTEX_ARRAY);
       
  2649     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
       
  2650 }
       
  2651 
       
  2652 #endif // !QT_OPENGL_ES_2
       
  2653 
       
  2654 /*!
       
  2655     \since 4.4
       
  2656 
       
  2657     Draws the given texture, \a textureId, to the given target rectangle,
       
  2658     \a target, in OpenGL model space. The \a textureTarget should be a 2D
       
  2659     texture target.
       
  2660 
       
  2661     \note This function is not supported under OpenGL/ES 2.0.
       
  2662 */
       
  2663 void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget)
       
  2664 {
       
  2665 #ifndef QT_OPENGL_ES_2
       
  2666 #ifdef QT_OPENGL_ES
       
  2667     if (textureTarget != GL_TEXTURE_2D) {
       
  2668         qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES");
       
  2669         return;
       
  2670     }
       
  2671 #else
       
  2672     const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
       
  2673     GLint oldTexture;
       
  2674     glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
       
  2675 #endif
       
  2676 
       
  2677     glEnable(textureTarget);
       
  2678     glBindTexture(textureTarget, textureId);
       
  2679 
       
  2680     qDrawTextureRect(target, -1, -1, textureTarget);
       
  2681 
       
  2682 #ifdef QT_OPENGL_ES
       
  2683     glDisable(textureTarget);
       
  2684 #else
       
  2685     if (!wasEnabled)
       
  2686         glDisable(textureTarget);
       
  2687     glBindTexture(textureTarget, oldTexture);
       
  2688 #endif
       
  2689 #else
       
  2690     Q_UNUSED(target);
       
  2691     Q_UNUSED(textureId);
       
  2692     Q_UNUSED(textureTarget);
       
  2693     qWarning("drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES/2.0");
       
  2694 #endif
       
  2695 }
       
  2696 
       
  2697 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
       
  2698 /*! \internal */
       
  2699 void QGLContext::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
       
  2700 {
       
  2701     drawTexture(target, GLuint(textureId), GLenum(textureTarget));
       
  2702 }
       
  2703 #endif
       
  2704 
       
  2705 /*!
       
  2706     \since 4.4
       
  2707 
       
  2708     Draws the given texture at the given \a point in OpenGL model
       
  2709     space. The \a textureTarget should be a 2D texture target.
       
  2710 
       
  2711     \note This function is not supported under OpenGL/ES.
       
  2712 */
       
  2713 void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget)
       
  2714 {
       
  2715     // this would be ok on OpenGL ES 2.0, but currently we don't have a define for that
       
  2716 #ifdef QT_OPENGL_ES
       
  2717     Q_UNUSED(point);
       
  2718     Q_UNUSED(textureId);
       
  2719     Q_UNUSED(textureTarget);
       
  2720     qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead");
       
  2721 #else
       
  2722     const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
       
  2723     GLint oldTexture;
       
  2724     glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
       
  2725 
       
  2726     glEnable(textureTarget);
       
  2727     glBindTexture(textureTarget, textureId);
       
  2728 
       
  2729     GLint textureWidth;
       
  2730     GLint textureHeight;
       
  2731 
       
  2732     glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
       
  2733     glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
       
  2734 
       
  2735     qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget);
       
  2736 
       
  2737     if (!wasEnabled)
       
  2738         glDisable(textureTarget);
       
  2739     glBindTexture(textureTarget, oldTexture);
       
  2740 #endif
       
  2741 }
       
  2742 
       
  2743 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
       
  2744 /*! \internal */
       
  2745 void QGLContext::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
       
  2746 {
       
  2747     drawTexture(point, GLuint(textureId), GLenum(textureTarget));
       
  2748 }
       
  2749 #endif
       
  2750 
       
  2751 
       
  2752 /*!
       
  2753     This function sets the limit for the texture cache to \a size,
       
  2754     expressed in kilobytes.
       
  2755 
       
  2756     By default, the cache limit is approximately 64 MB.
       
  2757 
       
  2758     \sa textureCacheLimit()
       
  2759 */
       
  2760 void QGLContext::setTextureCacheLimit(int size)
       
  2761 {
       
  2762     QGLTextureCache::instance()->setMaxCost(size);
       
  2763 }
       
  2764 
       
  2765 /*!
       
  2766     Returns the current texture cache limit in kilobytes.
       
  2767 
       
  2768     \sa setTextureCacheLimit()
       
  2769 */
       
  2770 int QGLContext::textureCacheLimit()
       
  2771 {
       
  2772     return QGLTextureCache::instance()->maxCost();
       
  2773 }
       
  2774 
       
  2775 
       
  2776 /*!
       
  2777     \fn QGLFormat QGLContext::format() const
       
  2778 
       
  2779     Returns the frame buffer format that was obtained (this may be a
       
  2780     subset of what was requested).
       
  2781 
       
  2782     \sa requestedFormat()
       
  2783 */
       
  2784 
       
  2785 /*!
       
  2786     \fn QGLFormat QGLContext::requestedFormat() const
       
  2787 
       
  2788     Returns the frame buffer format that was originally requested in
       
  2789     the constructor or setFormat().
       
  2790 
       
  2791     \sa format()
       
  2792 */
       
  2793 
       
  2794 /*!
       
  2795     Sets a \a format for this context. The context is \link reset()
       
  2796     reset\endlink.
       
  2797 
       
  2798     Call create() to create a new GL context that tries to match the
       
  2799     new format.
       
  2800 
       
  2801     \snippet doc/src/snippets/code/src_opengl_qgl.cpp 7
       
  2802 
       
  2803     \sa format(), reset(), create()
       
  2804 */
       
  2805 
       
  2806 void QGLContext::setFormat(const QGLFormat &format)
       
  2807 {
       
  2808     Q_D(QGLContext);
       
  2809     reset();
       
  2810     d->glFormat = d->reqFormat = format;
       
  2811 }
       
  2812 
       
  2813 /*!
       
  2814     \internal
       
  2815 */
       
  2816 void QGLContext::setDevice(QPaintDevice *pDev)
       
  2817 {
       
  2818     Q_D(QGLContext);
       
  2819     if (isValid())
       
  2820         reset();
       
  2821     d->paintDevice = pDev;
       
  2822     if (d->paintDevice && (d->paintDevice->devType() != QInternal::Widget
       
  2823                            && d->paintDevice->devType() != QInternal::Pixmap
       
  2824                            && d->paintDevice->devType() != QInternal::Pbuffer)) {
       
  2825         qWarning("QGLContext: Unsupported paint device type");
       
  2826     }
       
  2827 }
       
  2828 
       
  2829 /*!
       
  2830     \fn bool QGLContext::isValid() const
       
  2831 
       
  2832     Returns true if a GL rendering context has been successfully
       
  2833     created; otherwise returns false.
       
  2834 */
       
  2835 
       
  2836 /*!
       
  2837     \fn void QGLContext::setValid(bool valid)
       
  2838     \internal
       
  2839 
       
  2840     Forces the GL rendering context to be valid.
       
  2841 */
       
  2842 
       
  2843 /*!
       
  2844     \fn bool QGLContext::isSharing() const
       
  2845 
       
  2846     Returns true if this context is sharing its GL context with
       
  2847     another QGLContext, otherwise false is returned. Note that context
       
  2848     sharing might not be supported between contexts with different
       
  2849     formats.
       
  2850 */
       
  2851 
       
  2852 /*!
       
  2853     Returns true if \a context1 and \a context2 are sharing their
       
  2854     GL resources such as textures, shader programs, etc;
       
  2855     otherwise returns false.
       
  2856 
       
  2857     \since 4.6
       
  2858 */
       
  2859 bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *context2)
       
  2860 {
       
  2861     if (!context1 || !context2)
       
  2862         return false;
       
  2863     return context1->d_ptr->group == context2->d_ptr->group;
       
  2864 }
       
  2865 
       
  2866 /*!
       
  2867     \fn bool QGLContext::deviceIsPixmap() const
       
  2868 
       
  2869     Returns true if the paint device of this context is a pixmap;
       
  2870     otherwise returns false.
       
  2871 */
       
  2872 
       
  2873 /*!
       
  2874     \fn bool QGLContext::windowCreated() const
       
  2875 
       
  2876     Returns true if a window has been created for this context;
       
  2877     otherwise returns false.
       
  2878 
       
  2879     \sa setWindowCreated()
       
  2880 */
       
  2881 
       
  2882 /*!
       
  2883     \fn void QGLContext::setWindowCreated(bool on)
       
  2884 
       
  2885     If \a on is true the context has had a window created for it. If
       
  2886     \a on is false no window has been created for the context.
       
  2887 
       
  2888     \sa windowCreated()
       
  2889 */
       
  2890 
       
  2891 /*!
       
  2892     \fn uint QGLContext::colorIndex(const QColor& c) const
       
  2893 
       
  2894     \internal
       
  2895 
       
  2896     Returns a colormap index for the color c, in ColorIndex mode. Used
       
  2897     by qglColor() and qglClearColor().
       
  2898 */
       
  2899 
       
  2900 
       
  2901 /*!
       
  2902     \fn bool QGLContext::initialized() const
       
  2903 
       
  2904     Returns true if this context has been initialized, i.e. if
       
  2905     QGLWidget::initializeGL() has been performed on it; otherwise
       
  2906     returns false.
       
  2907 
       
  2908     \sa setInitialized()
       
  2909 */
       
  2910 
       
  2911 /*!
       
  2912     \fn void QGLContext::setInitialized(bool on)
       
  2913 
       
  2914     If \a on is true the context has been initialized, i.e.
       
  2915     QGLContext::setInitialized() has been called on it. If \a on is
       
  2916     false the context has not been initialized.
       
  2917 
       
  2918     \sa initialized()
       
  2919 */
       
  2920 
       
  2921 /*!
       
  2922     \fn const QGLContext* QGLContext::currentContext()
       
  2923 
       
  2924     Returns the current context, i.e. the context to which any OpenGL
       
  2925     commands will currently be directed. Returns 0 if no context is
       
  2926     current.
       
  2927 
       
  2928     \sa makeCurrent()
       
  2929 */
       
  2930 
       
  2931 /*!
       
  2932     \fn QColor QGLContext::overlayTransparentColor() const
       
  2933 
       
  2934     If this context is a valid context in an overlay plane, returns
       
  2935     the plane's transparent color. Otherwise returns an \link
       
  2936     QColor::isValid() invalid \endlink color.
       
  2937 
       
  2938     The returned color's \link QColor::pixel() pixel \endlink value is
       
  2939     the index of the transparent color in the colormap of the overlay
       
  2940     plane. (Naturally, the color's RGB values are meaningless.)
       
  2941 
       
  2942     The returned QColor object will generally work as expected only
       
  2943     when passed as the argument to QGLWidget::qglColor() or
       
  2944     QGLWidget::qglClearColor(). Under certain circumstances it can
       
  2945     also be used to draw transparent graphics with a QPainter. See the
       
  2946     examples/opengl/overlay_x11 example for details.
       
  2947 */
       
  2948 
       
  2949 
       
  2950 /*!
       
  2951     Creates the GL context. Returns true if it was successful in
       
  2952     creating a valid GL rendering context on the paint device
       
  2953     specified in the constructor; otherwise returns false (i.e. the
       
  2954     context is invalid).
       
  2955 
       
  2956     After successful creation, format() returns the set of features of
       
  2957     the created GL rendering context.
       
  2958 
       
  2959     If \a shareContext points to a valid QGLContext, this method will
       
  2960     try to establish OpenGL display list and texture object sharing
       
  2961     between this context and the \a shareContext. Note that this may
       
  2962     fail if the two contexts have different \l {format()} {formats}.
       
  2963     Use isSharing() to see if sharing is in effect.
       
  2964 
       
  2965     \warning Implementation note: initialization of C++ class
       
  2966     members usually takes place in the class constructor. QGLContext
       
  2967     is an exception because it must be simple to customize. The
       
  2968     virtual functions chooseContext() (and chooseVisual() for X11) can
       
  2969     be reimplemented in a subclass to select a particular context. The
       
  2970     problem is that virtual functions are not properly called during
       
  2971     construction (even though this is correct C++) because C++
       
  2972     constructs class hierarchies from the bottom up. For this reason
       
  2973     we need a create() function.
       
  2974 
       
  2975     \sa chooseContext(), format(), isValid()
       
  2976 */
       
  2977 
       
  2978 bool QGLContext::create(const QGLContext* shareContext)
       
  2979 {
       
  2980     Q_D(QGLContext);
       
  2981     if (!d->paintDevice)
       
  2982         return false;
       
  2983     reset();
       
  2984     d->valid = chooseContext(shareContext);
       
  2985     if (d->valid && d->paintDevice->devType() == QInternal::Widget) {
       
  2986         QWidgetPrivate *wd = qt_widget_private(static_cast<QWidget *>(d->paintDevice));
       
  2987         wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer();
       
  2988     }
       
  2989     if (d->sharing)  // ok, we managed to share
       
  2990         QGLContextGroup::addShare(this, shareContext);
       
  2991     return d->valid;
       
  2992 }
       
  2993 
       
  2994 bool QGLContext::isValid() const
       
  2995 {
       
  2996     Q_D(const QGLContext);
       
  2997     return d->valid;
       
  2998 }
       
  2999 
       
  3000 void QGLContext::setValid(bool valid)
       
  3001 {
       
  3002     Q_D(QGLContext);
       
  3003     d->valid = valid;
       
  3004 }
       
  3005 
       
  3006 bool QGLContext::isSharing() const
       
  3007 {
       
  3008     Q_D(const QGLContext);
       
  3009     return d->group->isSharing();
       
  3010 }
       
  3011 
       
  3012 QGLFormat QGLContext::format() const
       
  3013 {
       
  3014     Q_D(const QGLContext);
       
  3015     return d->glFormat;
       
  3016 }
       
  3017 
       
  3018 QGLFormat QGLContext::requestedFormat() const
       
  3019 {
       
  3020     Q_D(const QGLContext);
       
  3021     return d->reqFormat;
       
  3022 }
       
  3023 
       
  3024  QPaintDevice* QGLContext::device() const
       
  3025 {
       
  3026     Q_D(const QGLContext);
       
  3027     return d->paintDevice;
       
  3028 }
       
  3029 
       
  3030 bool QGLContext::deviceIsPixmap() const
       
  3031 {
       
  3032     Q_D(const QGLContext);
       
  3033     return d->paintDevice->devType() == QInternal::Pixmap;
       
  3034 }
       
  3035 
       
  3036 
       
  3037 bool QGLContext::windowCreated() const
       
  3038 {
       
  3039     Q_D(const QGLContext);
       
  3040     return d->crWin;
       
  3041 }
       
  3042 
       
  3043 
       
  3044 void QGLContext::setWindowCreated(bool on)
       
  3045 {
       
  3046     Q_D(QGLContext);
       
  3047     d->crWin = on;
       
  3048 }
       
  3049 
       
  3050 bool QGLContext::initialized() const
       
  3051 {
       
  3052     Q_D(const QGLContext);
       
  3053     return d->initDone;
       
  3054 }
       
  3055 
       
  3056 void QGLContext::setInitialized(bool on)
       
  3057 {
       
  3058     Q_D(QGLContext);
       
  3059     d->initDone = on;
       
  3060 }
       
  3061 
       
  3062 const QGLContext* QGLContext::currentContext()
       
  3063 {
       
  3064     QGLThreadContext *threadContext = qgl_context_storage.localData();
       
  3065     if (threadContext)
       
  3066         return threadContext->context;
       
  3067     return 0;
       
  3068 }
       
  3069 
       
  3070 void QGLContextPrivate::setCurrentContext(QGLContext *context)
       
  3071 {
       
  3072     QGLThreadContext *threadContext = qgl_context_storage.localData();
       
  3073     if (!threadContext) {
       
  3074         if (!QThread::currentThread()) {
       
  3075             // We don't have a current QThread, so just set the static.
       
  3076             QGLContext::currentCtx = context;
       
  3077             return;
       
  3078         }
       
  3079         threadContext = new QGLThreadContext;
       
  3080         qgl_context_storage.setLocalData(threadContext);
       
  3081     }
       
  3082     threadContext->context = context;
       
  3083     QGLContext::currentCtx = context; // XXX: backwards-compat, not thread-safe
       
  3084 }
       
  3085 
       
  3086 /*!
       
  3087     \fn bool QGLContext::chooseContext(const QGLContext* shareContext = 0)
       
  3088 
       
  3089     This semi-internal function is called by create(). It creates a
       
  3090     system-dependent OpenGL handle that matches the format() of \a
       
  3091     shareContext as closely as possible, returning true if successful
       
  3092     or false if a suitable handle could not be found.
       
  3093 
       
  3094     On Windows, it calls the virtual function choosePixelFormat(),
       
  3095     which finds a matching pixel format identifier. On X11, it calls
       
  3096     the virtual function chooseVisual() which finds an appropriate X
       
  3097     visual. On other platforms it may work differently.
       
  3098 */
       
  3099 
       
  3100 /*! \fn int QGLContext::choosePixelFormat(void* dummyPfd, HDC pdc)
       
  3101 
       
  3102     \bold{Win32 only:} This virtual function chooses a pixel format
       
  3103     that matches the OpenGL \link setFormat() format\endlink.
       
  3104     Reimplement this function in a subclass if you need a custom
       
  3105     context.
       
  3106 
       
  3107     \warning The \a dummyPfd pointer and \a pdc are used as a \c
       
  3108     PIXELFORMATDESCRIPTOR*. We use \c void to avoid using
       
  3109     Windows-specific types in our header files.
       
  3110 
       
  3111     \sa chooseContext()
       
  3112 */
       
  3113 
       
  3114 /*! \fn void *QGLContext::chooseVisual()
       
  3115 
       
  3116   \bold{X11 only:} This virtual function tries to find a visual that
       
  3117   matches the format, reducing the demands if the original request
       
  3118   cannot be met.
       
  3119 
       
  3120   The algorithm for reducing the demands of the format is quite
       
  3121   simple-minded, so override this method in your subclass if your
       
  3122   application has spcific requirements on visual selection.
       
  3123 
       
  3124   \sa chooseContext()
       
  3125 */
       
  3126 
       
  3127 /*! \fn void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth)
       
  3128   \internal
       
  3129 
       
  3130   \bold{X11 only:} This virtual function chooses a visual that matches
       
  3131   the OpenGL \link format() format\endlink. Reimplement this function
       
  3132   in a subclass if you need a custom visual.
       
  3133 
       
  3134   \sa chooseContext()
       
  3135 */
       
  3136 
       
  3137 /*!
       
  3138     \fn void QGLContext::reset()
       
  3139 
       
  3140     Resets the context and makes it invalid.
       
  3141 
       
  3142     \sa create(), isValid()
       
  3143 */
       
  3144 
       
  3145 
       
  3146 /*!
       
  3147     \fn void QGLContext::makeCurrent()
       
  3148 
       
  3149     Makes this context the current OpenGL rendering context. All GL
       
  3150     functions you call operate on this context until another context
       
  3151     is made current.
       
  3152 
       
  3153     In some very rare cases the underlying call may fail. If this
       
  3154     occurs an error message is output to stderr.
       
  3155 */
       
  3156 
       
  3157 
       
  3158 /*!
       
  3159     \fn void QGLContext::swapBuffers() const
       
  3160 
       
  3161     Swaps the screen contents with an off-screen buffer. Only works if
       
  3162     the context is in double buffer mode.
       
  3163 
       
  3164     \sa QGLFormat::setDoubleBuffer()
       
  3165 */
       
  3166 
       
  3167 
       
  3168 /*!
       
  3169     \fn void QGLContext::doneCurrent()
       
  3170 
       
  3171     Makes no GL context the current context. Normally, you do not need
       
  3172     to call this function; QGLContext calls it as necessary.
       
  3173 */
       
  3174 
       
  3175 
       
  3176 /*!
       
  3177     \fn QPaintDevice* QGLContext::device() const
       
  3178 
       
  3179     Returns the paint device set for this context.
       
  3180 
       
  3181     \sa QGLContext::QGLContext()
       
  3182 */
       
  3183 
       
  3184 /*!
       
  3185     \obsolete
       
  3186     \fn void QGLContext::generateFontDisplayLists(const QFont& font, int listBase)
       
  3187 
       
  3188     Generates a set of 256 display lists for the 256 first characters
       
  3189     in the font \a font. The first list will start at index \a listBase.
       
  3190 
       
  3191     \sa QGLWidget::renderText()
       
  3192 */
       
  3193 
       
  3194 
       
  3195 /*****************************************************************************
       
  3196   QGLWidget implementation
       
  3197  *****************************************************************************/
       
  3198 
       
  3199 
       
  3200 /*!
       
  3201     \class QGLWidget
       
  3202     \brief The QGLWidget class is a widget for rendering OpenGL graphics.
       
  3203 
       
  3204     \ingroup painting-3D
       
  3205 
       
  3206 
       
  3207     QGLWidget provides functionality for displaying OpenGL graphics
       
  3208     integrated into a Qt application. It is very simple to use. You
       
  3209     inherit from it and use the subclass like any other QWidget,
       
  3210     except that you have the choice between using QPainter and
       
  3211     standard OpenGL rendering commands.
       
  3212 
       
  3213     QGLWidget provides three convenient virtual functions that you can
       
  3214     reimplement in your subclass to perform the typical OpenGL tasks:
       
  3215 
       
  3216     \list
       
  3217     \i paintGL() - Renders the OpenGL scene. Gets called whenever the widget
       
  3218     needs to be updated.
       
  3219     \i resizeGL() - Sets up the OpenGL viewport, projection, etc. Gets
       
  3220     called whenever the widget has been resized (and also when it
       
  3221     is shown for the first time because all newly created widgets get a
       
  3222     resize event automatically).
       
  3223     \i initializeGL() - Sets up the OpenGL rendering context, defines display
       
  3224     lists, etc. Gets called once before the first time resizeGL() or
       
  3225     paintGL() is called.
       
  3226     \endlist
       
  3227 
       
  3228     Here is a rough outline of how a QGLWidget subclass might look:
       
  3229 
       
  3230     \snippet doc/src/snippets/code/src_opengl_qgl.cpp 8
       
  3231 
       
  3232     If you need to trigger a repaint from places other than paintGL()
       
  3233     (a typical example is when using \link QTimer timers\endlink to
       
  3234     animate scenes), you should call the widget's updateGL() function.
       
  3235 
       
  3236     Your widget's OpenGL rendering context is made current when
       
  3237     paintGL(), resizeGL(), or initializeGL() is called. If you need to
       
  3238     call the standard OpenGL API functions from other places (e.g. in
       
  3239     your widget's constructor or in your own paint functions), you
       
  3240     must call makeCurrent() first.
       
  3241 
       
  3242     QGLWidget provides functions for requesting a new display \link
       
  3243     QGLFormat format\endlink and you can also create widgets with
       
  3244     customized rendering \link QGLContext contexts\endlink.
       
  3245 
       
  3246     You can also share OpenGL display lists between QGLWidget objects (see
       
  3247     the documentation of the QGLWidget constructors for details).
       
  3248 
       
  3249     Note that under Windows, the QGLContext belonging to a QGLWidget
       
  3250     has to be recreated when the QGLWidget is reparented. This is
       
  3251     necessary due to limitations on the Windows platform. This will
       
  3252     most likely cause problems for users that have subclassed and
       
  3253     installed their own QGLContext on a QGLWidget. It is possible to
       
  3254     work around this issue by putting the QGLWidget inside a dummy
       
  3255     widget and then reparenting the dummy widget, instead of the
       
  3256     QGLWidget. This will side-step the issue altogether, and is what
       
  3257     we recommend for users that need this kind of functionality.
       
  3258 
       
  3259     On Mac OS X, when Qt is built with Cocoa support, a QGLWidget
       
  3260     can't have any sibling widgets placed ontop of itself. This is due
       
  3261     to limitations in the Cocoa API and is not supported by Apple.
       
  3262 
       
  3263     \section1 Overlays
       
  3264 
       
  3265     The QGLWidget creates a GL overlay context in addition to the
       
  3266     normal context if overlays are supported by the underlying system.
       
  3267 
       
  3268     If you want to use overlays, you specify it in the \link QGLFormat
       
  3269     format\endlink. (Note: Overlay must be requested in the format
       
  3270     passed to the QGLWidget constructor.) Your GL widget should also
       
  3271     implement some or all of these virtual methods:
       
  3272 
       
  3273     \list
       
  3274     \i paintOverlayGL()
       
  3275     \i resizeOverlayGL()
       
  3276     \i initializeOverlayGL()
       
  3277     \endlist
       
  3278 
       
  3279     These methods work in the same way as the normal paintGL() etc.
       
  3280     functions, except that they will be called when the overlay
       
  3281     context is made current. You can explicitly make the overlay
       
  3282     context current by using makeOverlayCurrent(), and you can access
       
  3283     the overlay context directly (e.g. to ask for its transparent
       
  3284     color) by calling overlayContext().
       
  3285 
       
  3286     On X servers in which the default visual is in an overlay plane,
       
  3287     non-GL Qt windows can also be used for overlays.
       
  3288 
       
  3289     \section1 Painting Techniques
       
  3290 
       
  3291     As described above, subclass QGLWidget to render pure 3D content in the
       
  3292     following way:
       
  3293 
       
  3294     \list
       
  3295     \o Reimplement the QGLWidget::initializeGL() and QGLWidget::resizeGL() to
       
  3296        set up the OpenGL state and provide a perspective transformation.
       
  3297     \o Reimplement QGLWidget::paintGL() to paint the 3D scene, calling only
       
  3298        OpenGL functions to draw on the widget.
       
  3299     \endlist
       
  3300 
       
  3301     It is also possible to draw 2D graphics onto a QGLWidget subclass, it is necessary
       
  3302     to reimplement QGLWidget::paintEvent() and do the following:
       
  3303 
       
  3304     \list
       
  3305     \o Construct a QPainter object.
       
  3306     \o Initialize it for use on the widget with the QPainter::begin() function.
       
  3307     \o Draw primitives using QPainter's member functions.
       
  3308     \o Call QPainter::end() to finish painting.
       
  3309     \endlist
       
  3310 
       
  3311     Overpainting 2D content on top of 3D content takes a little more effort.
       
  3312     One approach to doing this is shown in the
       
  3313     \l{Overpainting Example}{Overpainting} example.
       
  3314 
       
  3315     \e{OpenGL is a trademark of Silicon Graphics, Inc. in the United States and other
       
  3316     countries.}
       
  3317 
       
  3318     \sa QGLPixelBuffer, {Hello GL Example}, {2D Painting Example}, {Overpainting Example},
       
  3319         {Grabber Example}
       
  3320 */
       
  3321 
       
  3322 /*!
       
  3323     Constructs an OpenGL widget with a \a parent widget.
       
  3324 
       
  3325     The \link QGLFormat::defaultFormat() default format\endlink is
       
  3326     used. The widget will be \link isValid() invalid\endlink if the
       
  3327     system has no \link QGLFormat::hasOpenGL() OpenGL support\endlink.
       
  3328 
       
  3329     The \a parent and widget flag, \a f, arguments are passed
       
  3330     to the QWidget constructor.
       
  3331 
       
  3332     If \a shareWidget is a valid QGLWidget, this widget will share
       
  3333     OpenGL display lists and texture objects with \a shareWidget. But
       
  3334     if \a shareWidget and this widget have different \l {format()}
       
  3335     {formats}, sharing might not be possible. You can check whether
       
  3336     sharing is in effect by calling isSharing().
       
  3337 
       
  3338     The initialization of OpenGL rendering state, etc. should be done
       
  3339     by overriding the initializeGL() function, rather than in the
       
  3340     constructor of your QGLWidget subclass.
       
  3341 
       
  3342     \sa QGLFormat::defaultFormat(), {Textures Example}
       
  3343 */
       
  3344 
       
  3345 QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFlags f)
       
  3346     : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
       
  3347 {
       
  3348     Q_D(QGLWidget);
       
  3349     setAttribute(Qt::WA_PaintOnScreen);
       
  3350     setAttribute(Qt::WA_NoSystemBackground);
       
  3351     setAutoFillBackground(true); // for compatibility
       
  3352     d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget);
       
  3353 }
       
  3354 
       
  3355 
       
  3356 /*!
       
  3357     Constructs an OpenGL widget with parent \a parent.
       
  3358 
       
  3359     The \a format argument specifies the desired \link QGLFormat
       
  3360     rendering options \endlink. If the underlying OpenGL/Window system
       
  3361     cannot satisfy all the features requested in \a format, the
       
  3362     nearest subset of features will be used. After creation, the
       
  3363     format() method will return the actual format obtained.
       
  3364 
       
  3365     The widget will be \link isValid() invalid\endlink if the system
       
  3366     has no \link QGLFormat::hasOpenGL() OpenGL support\endlink.
       
  3367 
       
  3368     The \a parent and widget flag, \a f, arguments are passed
       
  3369     to the QWidget constructor.
       
  3370 
       
  3371     If \a shareWidget is a valid QGLWidget, this widget will share
       
  3372     OpenGL display lists and texture objects with \a shareWidget. But
       
  3373     if \a shareWidget and this widget have different \l {format()}
       
  3374     {formats}, sharing might not be possible. You can check whether
       
  3375     sharing is in effect by calling isSharing().
       
  3376 
       
  3377     The initialization of OpenGL rendering state, etc. should be done
       
  3378     by overriding the initializeGL() function, rather than in the
       
  3379     constructor of your QGLWidget subclass.
       
  3380 
       
  3381     \sa QGLFormat::defaultFormat(), isValid()
       
  3382 */
       
  3383 
       
  3384 QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget* shareWidget,
       
  3385                      Qt::WindowFlags f)
       
  3386     : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
       
  3387 {
       
  3388     Q_D(QGLWidget);
       
  3389     setAttribute(Qt::WA_PaintOnScreen);
       
  3390     setAttribute(Qt::WA_NoSystemBackground);
       
  3391     setAutoFillBackground(true); // for compatibility
       
  3392     d->init(new QGLContext(format, this), shareWidget);
       
  3393 }
       
  3394 
       
  3395 /*!
       
  3396     Constructs an OpenGL widget with parent \a parent.
       
  3397 
       
  3398     The \a context argument is a pointer to the QGLContext that
       
  3399     you wish to be bound to this widget. This allows you to pass in
       
  3400     your own QGLContext sub-classes.
       
  3401 
       
  3402     The widget will be \link isValid() invalid\endlink if the system
       
  3403     has no \link QGLFormat::hasOpenGL() OpenGL support\endlink.
       
  3404 
       
  3405     The \a parent and widget flag, \a f, arguments are passed
       
  3406     to the QWidget constructor.
       
  3407 
       
  3408     If \a shareWidget is a valid QGLWidget, this widget will share
       
  3409     OpenGL display lists and texture objects with \a shareWidget. But
       
  3410     if \a shareWidget and this widget have different \l {format()}
       
  3411     {formats}, sharing might not be possible. You can check whether
       
  3412     sharing is in effect by calling isSharing().
       
  3413 
       
  3414     The initialization of OpenGL rendering state, etc. should be done
       
  3415     by overriding the initializeGL() function, rather than in the
       
  3416     constructor of your QGLWidget subclass.
       
  3417 
       
  3418     \sa QGLFormat::defaultFormat(), isValid()
       
  3419 */
       
  3420 QGLWidget::QGLWidget(QGLContext *context, QWidget *parent, const QGLWidget *shareWidget,
       
  3421                      Qt::WindowFlags f)
       
  3422     : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
       
  3423 {
       
  3424     Q_D(QGLWidget);
       
  3425     setAttribute(Qt::WA_PaintOnScreen);
       
  3426     setAttribute(Qt::WA_NoSystemBackground);
       
  3427     setAutoFillBackground(true); // for compatibility
       
  3428     d->init(context, shareWidget);
       
  3429 }
       
  3430 
       
  3431 /*!
       
  3432     Destroys the widget.
       
  3433 */
       
  3434 
       
  3435 QGLWidget::~QGLWidget()
       
  3436 {
       
  3437     Q_D(QGLWidget);
       
  3438 #if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
       
  3439     bool doRelease = (glcx && glcx->windowCreated());
       
  3440 #endif
       
  3441     delete d->glcx;
       
  3442 #if defined(Q_WGL)
       
  3443     delete d->olcx;
       
  3444 #endif
       
  3445 #if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
       
  3446     if (doRelease)
       
  3447         glXReleaseBuffersMESA(x11Display(), winId());
       
  3448 #endif
       
  3449     d->cleanupColormaps();
       
  3450 
       
  3451 #ifdef Q_WS_MAC
       
  3452     QWidget *current = parentWidget();
       
  3453     while (current) {
       
  3454         qt_widget_private(current)->glWidgets.removeAll(QWidgetPrivate::GlWidgetInfo(this));
       
  3455         if (current->isWindow())
       
  3456             break;
       
  3457         current = current->parentWidget();
       
  3458     };
       
  3459 #endif
       
  3460 }
       
  3461 
       
  3462 /*!
       
  3463     \fn QGLFormat QGLWidget::format() const
       
  3464 
       
  3465     Returns the format of the contained GL rendering context.
       
  3466 */
       
  3467 
       
  3468 /*!
       
  3469     \fn bool QGLWidget::doubleBuffer() const
       
  3470 
       
  3471     Returns true if the contained GL rendering context has double
       
  3472     buffering; otherwise returns false.
       
  3473 
       
  3474     \sa QGLFormat::doubleBuffer()
       
  3475 */
       
  3476 
       
  3477 /*!
       
  3478     \fn void QGLWidget::setAutoBufferSwap(bool on)
       
  3479 
       
  3480     If \a on is true automatic GL buffer swapping is switched on;
       
  3481     otherwise it is switched off.
       
  3482 
       
  3483     If \a on is true and the widget is using a double-buffered format,
       
  3484     the background and foreground GL buffers will automatically be
       
  3485     swapped after each paintGL() call.
       
  3486 
       
  3487     The buffer auto-swapping is on by default.
       
  3488 
       
  3489     \sa autoBufferSwap(), doubleBuffer(), swapBuffers()
       
  3490 */
       
  3491 
       
  3492 /*!
       
  3493     \fn bool QGLWidget::autoBufferSwap() const
       
  3494 
       
  3495     Returns true if the widget is doing automatic GL buffer swapping;
       
  3496     otherwise returns false.
       
  3497 
       
  3498     \sa setAutoBufferSwap()
       
  3499 */
       
  3500 
       
  3501 /*!
       
  3502     \fn void *QGLContext::getProcAddress(const QString &proc) const
       
  3503 
       
  3504     Returns a function pointer to the GL extension function passed in
       
  3505     \a proc. 0 is returned if a pointer to the function could not be
       
  3506     obtained.
       
  3507 */
       
  3508 
       
  3509 /*!
       
  3510     \fn bool QGLWidget::isValid() const
       
  3511 
       
  3512     Returns true if the widget has a valid GL rendering context;
       
  3513     otherwise returns false. A widget will be invalid if the system
       
  3514     has no \link QGLFormat::hasOpenGL() OpenGL support\endlink.
       
  3515 */
       
  3516 
       
  3517 bool QGLWidget::isValid() const
       
  3518 {
       
  3519     Q_D(const QGLWidget);
       
  3520     return d->glcx && d->glcx->isValid();
       
  3521 }
       
  3522 
       
  3523 /*!
       
  3524     \fn bool QGLWidget::isSharing() const
       
  3525 
       
  3526     Returns true if this widget's GL context is shared with another GL
       
  3527     context, otherwise false is returned. Context sharing might not be
       
  3528     possible if the widgets use different formats.
       
  3529 
       
  3530     \sa format()
       
  3531 */
       
  3532 
       
  3533 bool QGLWidget::isSharing() const
       
  3534 {
       
  3535     Q_D(const QGLWidget);
       
  3536     return d->glcx->isSharing();
       
  3537 }
       
  3538 
       
  3539 /*!
       
  3540     \fn void QGLWidget::makeCurrent()
       
  3541 
       
  3542     Makes this widget the current widget for OpenGL operations, i.e.
       
  3543     makes the widget's rendering context the current OpenGL rendering
       
  3544     context.
       
  3545 */
       
  3546 
       
  3547 void QGLWidget::makeCurrent()
       
  3548 {
       
  3549     Q_D(QGLWidget);
       
  3550     d->glcx->makeCurrent();
       
  3551 }
       
  3552 
       
  3553 /*!
       
  3554     \fn void QGLWidget::doneCurrent()
       
  3555 
       
  3556     Makes no GL context the current context. Normally, you do not need
       
  3557     to call this function; QGLContext calls it as necessary. However,
       
  3558     it may be useful in multithreaded environments.
       
  3559 */
       
  3560 
       
  3561 void QGLWidget::doneCurrent()
       
  3562 {
       
  3563     Q_D(QGLWidget);
       
  3564     d->glcx->doneCurrent();
       
  3565 }
       
  3566 
       
  3567 /*!
       
  3568     \fn void QGLWidget::swapBuffers()
       
  3569 
       
  3570     Swaps the screen contents with an off-screen buffer. This only
       
  3571     works if the widget's format specifies double buffer mode.
       
  3572 
       
  3573     Normally, there is no need to explicitly call this function
       
  3574     because it is done automatically after each widget repaint, i.e.
       
  3575     each time after paintGL() has been executed.
       
  3576 
       
  3577     \sa doubleBuffer(), setAutoBufferSwap(), QGLFormat::setDoubleBuffer()
       
  3578 */
       
  3579 
       
  3580 void QGLWidget::swapBuffers()
       
  3581 {
       
  3582     Q_D(QGLWidget);
       
  3583     d->glcx->swapBuffers();
       
  3584 }
       
  3585 
       
  3586 
       
  3587 /*!
       
  3588     \fn const QGLContext* QGLWidget::overlayContext() const
       
  3589 
       
  3590     Returns the overlay context of this widget, or 0 if this widget
       
  3591     has no overlay.
       
  3592 
       
  3593     \sa context()
       
  3594 */
       
  3595 
       
  3596 
       
  3597 
       
  3598 /*!
       
  3599     \fn void QGLWidget::makeOverlayCurrent()
       
  3600 
       
  3601     Makes the overlay context of this widget current. Use this if you
       
  3602     need to issue OpenGL commands to the overlay context outside of
       
  3603     initializeOverlayGL(), resizeOverlayGL(), and paintOverlayGL().
       
  3604 
       
  3605     Does nothing if this widget has no overlay.
       
  3606 
       
  3607     \sa makeCurrent()
       
  3608 */
       
  3609 
       
  3610 
       
  3611 /*!
       
  3612   \obsolete
       
  3613 
       
  3614   Sets a new format for this widget.
       
  3615 
       
  3616   If the underlying OpenGL/Window system cannot satisfy all the
       
  3617   features requested in \a format, the nearest subset of features will
       
  3618   be used. After creation, the format() method will return the actual
       
  3619   rendering context format obtained.
       
  3620 
       
  3621   The widget will be assigned a new QGLContext, and the initializeGL()
       
  3622   function will be executed for this new context before the first
       
  3623   resizeGL() or paintGL().
       
  3624 
       
  3625   This method will try to keep display list and texture object sharing
       
  3626   in effect with other QGLWidget objects, but changing the format might make
       
  3627   sharing impossible. Use isSharing() to see if sharing is still in
       
  3628   effect.
       
  3629 
       
  3630   \sa format(), isSharing(), isValid()
       
  3631 */
       
  3632 
       
  3633 void QGLWidget::setFormat(const QGLFormat &format)
       
  3634 {
       
  3635     setContext(new QGLContext(format,this));
       
  3636 }
       
  3637 
       
  3638 
       
  3639 
       
  3640 
       
  3641 /*!
       
  3642     \fn const QGLContext *QGLWidget::context() const
       
  3643 
       
  3644     Returns the context of this widget.
       
  3645 
       
  3646     It is possible that the context is not valid (see isValid()), for
       
  3647     example, if the underlying hardware does not support the format
       
  3648     attributes that were requested.
       
  3649 */
       
  3650 
       
  3651 /*
       
  3652   \fn void QGLWidget::setContext(QGLContext *context,
       
  3653                                  const QGLContext* shareContext,
       
  3654                                  bool deleteOldContext)
       
  3655   \obsolete
       
  3656 
       
  3657   Sets a new context for this widget. The QGLContext \a context must
       
  3658   be created using \e new. QGLWidget will delete \a context when
       
  3659   another context is set or when the widget is destroyed.
       
  3660 
       
  3661   If \a context is invalid, QGLContext::create() is performed on
       
  3662   it. The initializeGL() function will then be executed for the new
       
  3663   context before the first resizeGL() or paintGL().
       
  3664 
       
  3665   If \a context is invalid, this method will try to keep display list
       
  3666   and texture object sharing in effect, or (if \a shareContext points
       
  3667   to a valid context) start display list and texture object sharing
       
  3668   with that context, but sharing might be impossible if the two
       
  3669   contexts have different \l {format()} {formats}. Use isSharing() to
       
  3670   see whether sharing is in effect.
       
  3671 
       
  3672   If \a deleteOldContext is true (the default), the existing context
       
  3673   will be deleted. You may use false here if you have kept a pointer
       
  3674   to the old context (as returned by context()), and want to restore
       
  3675   that context later.
       
  3676 
       
  3677   \sa context(), isSharing()
       
  3678 */
       
  3679 
       
  3680 
       
  3681 
       
  3682 /*!
       
  3683     \fn void QGLWidget::updateGL()
       
  3684 
       
  3685     Updates the widget by calling glDraw().
       
  3686 */
       
  3687 
       
  3688 void QGLWidget::updateGL()
       
  3689 {
       
  3690     if (updatesEnabled())
       
  3691         glDraw();
       
  3692 }
       
  3693 
       
  3694 
       
  3695 /*!
       
  3696     \fn void QGLWidget::updateOverlayGL()
       
  3697 
       
  3698     Updates the widget's overlay (if any). Will cause the virtual
       
  3699     function paintOverlayGL() to be executed.
       
  3700 
       
  3701     The widget's rendering context will become the current context and
       
  3702     initializeGL() will be called if it hasn't already been called.
       
  3703 */
       
  3704 
       
  3705 
       
  3706 /*!
       
  3707     This virtual function is called once before the first call to
       
  3708     paintGL() or resizeGL(), and then once whenever the widget has
       
  3709     been assigned a new QGLContext. Reimplement it in a subclass.
       
  3710 
       
  3711     This function should set up any required OpenGL context rendering
       
  3712     flags, defining display lists, etc.
       
  3713 
       
  3714     There is no need to call makeCurrent() because this has already
       
  3715     been done when this function is called.
       
  3716 */
       
  3717 
       
  3718 void QGLWidget::initializeGL()
       
  3719 {
       
  3720 }
       
  3721 
       
  3722 
       
  3723 /*!
       
  3724     This virtual function is called whenever the widget needs to be
       
  3725     painted. Reimplement it in a subclass.
       
  3726 
       
  3727     There is no need to call makeCurrent() because this has already
       
  3728     been done when this function is called.
       
  3729 */
       
  3730 
       
  3731 void QGLWidget::paintGL()
       
  3732 {
       
  3733 }
       
  3734 
       
  3735 
       
  3736 /*!
       
  3737     \fn void QGLWidget::resizeGL(int width , int height)
       
  3738 
       
  3739     This virtual function is called whenever the widget has been
       
  3740     resized. The new size is passed in \a width and \a height.
       
  3741     Reimplement it in a subclass.
       
  3742 
       
  3743     There is no need to call makeCurrent() because this has already
       
  3744     been done when this function is called.
       
  3745 */
       
  3746 
       
  3747 void QGLWidget::resizeGL(int, int)
       
  3748 {
       
  3749 }
       
  3750 
       
  3751 
       
  3752 
       
  3753 /*!
       
  3754     This virtual function is used in the same manner as initializeGL()
       
  3755     except that it operates on the widget's overlay context instead of
       
  3756     the widget's main context. This means that initializeOverlayGL()
       
  3757     is called once before the first call to paintOverlayGL() or
       
  3758     resizeOverlayGL(). Reimplement it in a subclass.
       
  3759 
       
  3760     This function should set up any required OpenGL context rendering
       
  3761     flags, defining display lists, etc. for the overlay context.
       
  3762 
       
  3763     There is no need to call makeOverlayCurrent() because this has
       
  3764     already been done when this function is called.
       
  3765 */
       
  3766 
       
  3767 void QGLWidget::initializeOverlayGL()
       
  3768 {
       
  3769 }
       
  3770 
       
  3771 
       
  3772 /*!
       
  3773     This virtual function is used in the same manner as paintGL()
       
  3774     except that it operates on the widget's overlay context instead of
       
  3775     the widget's main context. This means that paintOverlayGL() is
       
  3776     called whenever the widget's overlay needs to be painted.
       
  3777     Reimplement it in a subclass.
       
  3778 
       
  3779     There is no need to call makeOverlayCurrent() because this has
       
  3780     already been done when this function is called.
       
  3781 */
       
  3782 
       
  3783 void QGLWidget::paintOverlayGL()
       
  3784 {
       
  3785 }
       
  3786 
       
  3787 
       
  3788 /*!
       
  3789     \fn void QGLWidget::resizeOverlayGL(int width , int height)
       
  3790 
       
  3791     This virtual function is used in the same manner as paintGL()
       
  3792     except that it operates on the widget's overlay context instead of
       
  3793     the widget's main context. This means that resizeOverlayGL() is
       
  3794     called whenever the widget has been resized. The new size is
       
  3795     passed in \a width and \a height. Reimplement it in a subclass.
       
  3796 
       
  3797     There is no need to call makeOverlayCurrent() because this has
       
  3798     already been done when this function is called.
       
  3799 */
       
  3800 
       
  3801 void QGLWidget::resizeOverlayGL(int, int)
       
  3802 {
       
  3803 }
       
  3804 
       
  3805 /*! \fn bool QGLWidget::event(QEvent *e)
       
  3806   \reimp
       
  3807 */
       
  3808 #if !defined(Q_OS_WINCE) && !defined(Q_WS_QWS)
       
  3809 bool QGLWidget::event(QEvent *e)
       
  3810 {
       
  3811     Q_D(QGLWidget);
       
  3812 
       
  3813     if (e->type() == QEvent::Paint) {
       
  3814         QPoint offset;
       
  3815         QPaintDevice *redirectedDevice = d->redirected(&offset);
       
  3816         if (redirectedDevice && redirectedDevice->devType() == QInternal::Pixmap) {
       
  3817             d->restoreRedirected();
       
  3818             QPixmap pixmap = renderPixmap();
       
  3819             d->setRedirected(redirectedDevice, offset);
       
  3820             QPainter p(redirectedDevice);
       
  3821             p.drawPixmap(-offset, pixmap);
       
  3822             return true;
       
  3823         }
       
  3824     }
       
  3825 
       
  3826 #if defined(Q_WS_X11)
       
  3827     // prevents X errors on some systems, where we get a flush to a
       
  3828     // hidden widget
       
  3829     if (e->type() == QEvent::Hide) {
       
  3830         makeCurrent();
       
  3831         glFinish();
       
  3832         doneCurrent();
       
  3833     } else if (e->type() == QEvent::ParentChange) {
       
  3834         // if we've reparented a window that has the current context
       
  3835         // bound, we need to rebind that context to the new window id
       
  3836         if (d->glcx == QGLContext::currentContext())
       
  3837             makeCurrent();
       
  3838 
       
  3839         if (d->glcx->d_func()->screen != d->xinfo.screen() || testAttribute(Qt::WA_TranslucentBackground)) {
       
  3840             setContext(new QGLContext(d->glcx->requestedFormat(), this));
       
  3841             // ### recreating the overlay isn't supported atm
       
  3842         }
       
  3843     }
       
  3844 
       
  3845 #if defined(QT_OPENGL_ES)
       
  3846     // A re-parent is likely to destroy the X11 window and re-create it. It is important
       
  3847     // that we free the EGL surface _before_ the winID changes - otherwise we can leak.
       
  3848     if (e->type() == QEvent::ParentAboutToChange)
       
  3849         d->glcx->d_func()->destroyEglSurfaceForDevice();
       
  3850 
       
  3851     if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) {
       
  3852         // The window may have been re-created during re-parent or state change - if so, the EGL
       
  3853         // surface will need to be re-created.
       
  3854         d->recreateEglSurface(false);
       
  3855     }
       
  3856 #endif
       
  3857 #elif defined(Q_WS_WIN)
       
  3858     if (e->type() == QEvent::ParentChange) {
       
  3859         QGLContext *newContext = new QGLContext(d->glcx->requestedFormat(), this);
       
  3860         setContext(newContext, d->glcx);
       
  3861 
       
  3862         // the overlay needs to be recreated as well
       
  3863         delete d->olcx;
       
  3864         if (isValid() && context()->format().hasOverlay()) {
       
  3865             d->olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), this);
       
  3866             if (!d->olcx->create(isSharing() ? d->glcx : 0)) {
       
  3867                 delete d->olcx;
       
  3868                 d->olcx = 0;
       
  3869                 d->glcx->d_func()->glFormat.setOverlay(false);
       
  3870             }
       
  3871         } else {
       
  3872             d->olcx = 0;
       
  3873         }
       
  3874     } else if (e->type() == QEvent::Show) {
       
  3875         if (!format().rgba())
       
  3876             d->updateColormap();
       
  3877     }
       
  3878 #elif defined(Q_WS_MAC)
       
  3879     if (e->type() == QEvent::MacGLWindowChange
       
  3880 #if 0 //(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
       
  3881         && ((QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 && isWindow())
       
  3882             || QSysInfo::MacintoshVersion <= QSysInfo::MV_10_4)
       
  3883 #endif
       
  3884         ) {
       
  3885         if (d->needWindowChange) {
       
  3886             d->needWindowChange = false;
       
  3887             d->glcx->updatePaintDevice();
       
  3888             update();
       
  3889         }
       
  3890         return true;
       
  3891 #  if defined(QT_MAC_USE_COCOA)
       
  3892     } else if (e->type() == QEvent::MacGLClearDrawable) {
       
  3893         d->glcx->d_ptr->clearDrawable();
       
  3894 #  endif
       
  3895     }
       
  3896 #endif
       
  3897 
       
  3898     return QWidget::event(e);
       
  3899 }
       
  3900 #endif
       
  3901 
       
  3902 /*!
       
  3903     \fn void QGLWidget::paintEvent(QPaintEvent *event)
       
  3904 
       
  3905     Handles paint events passed in the \a event parameter. Will cause
       
  3906     the virtual paintGL() function to be called.
       
  3907 
       
  3908     The widget's rendering context will become the current context and
       
  3909     initializeGL() will be called if it hasn't already been called.
       
  3910 */
       
  3911 
       
  3912 void QGLWidget::paintEvent(QPaintEvent *)
       
  3913 {
       
  3914     if (updatesEnabled()) {
       
  3915         glDraw();
       
  3916         updateOverlayGL();
       
  3917     }
       
  3918 }
       
  3919 
       
  3920 
       
  3921 /*!
       
  3922     \fn void QGLWidget::resizeEvent(QResizeEvent *event)
       
  3923 
       
  3924     Handles resize events that are passed in the \a event parameter.
       
  3925     Calls the virtual function resizeGL().
       
  3926 */
       
  3927 
       
  3928 
       
  3929 /*!
       
  3930     \fn void QGLWidget::setMouseTracking(bool enable)
       
  3931 
       
  3932     If \a enable is true then mouse tracking is enabled; otherwise it
       
  3933     is disabled.
       
  3934 */
       
  3935 
       
  3936 
       
  3937 /*!
       
  3938     Renders the current scene on a pixmap and returns the pixmap.
       
  3939 
       
  3940     You can use this method on both visible and invisible QGLWidget objects.
       
  3941 
       
  3942     This method will create a pixmap and a temporary QGLContext to
       
  3943     render on the pixmap. It will then call initializeGL(),
       
  3944     resizeGL(), and paintGL() on this context. Finally, the widget's
       
  3945     original GL context is restored.
       
  3946 
       
  3947     The size of the pixmap will be \a w pixels wide and \a h pixels
       
  3948     high unless one of these parameters is 0 (the default), in which
       
  3949     case the pixmap will have the same size as the widget.
       
  3950 
       
  3951     If \a useContext is true, this method will try to be more
       
  3952     efficient by using the existing GL context to render the pixmap.
       
  3953     The default is false. Only use true if you understand the risks.
       
  3954     Note that under Windows a temporary context has to be created
       
  3955     and usage of the \e useContext parameter is not supported.
       
  3956 
       
  3957     Overlays are not rendered onto the pixmap.
       
  3958 
       
  3959     If the GL rendering context and the desktop have different bit
       
  3960     depths, the result will most likely look surprising.
       
  3961 
       
  3962     Note that the creation of display lists, modifications of the view
       
  3963     frustum etc. should be done from within initializeGL(). If this is
       
  3964     not done, the temporary QGLContext will not be initialized
       
  3965     properly, and the rendered pixmap may be incomplete/corrupted.
       
  3966 */
       
  3967 
       
  3968 QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
       
  3969 {
       
  3970     Q_D(QGLWidget);
       
  3971     QSize sz = size();
       
  3972     if ((w > 0) && (h > 0))
       
  3973         sz = QSize(w, h);
       
  3974 
       
  3975 #if defined(Q_WS_X11)
       
  3976     extern int qt_x11_preferred_pixmap_depth;
       
  3977     int old_depth = qt_x11_preferred_pixmap_depth;
       
  3978     qt_x11_preferred_pixmap_depth = x11Info().depth();
       
  3979 
       
  3980     QPixmapData *data = new QX11PixmapData(QPixmapData::PixmapType);
       
  3981     data->resize(sz.width(), sz.height());
       
  3982     QPixmap pm(data);
       
  3983     qt_x11_preferred_pixmap_depth = old_depth;
       
  3984     QX11Info xinfo = x11Info();
       
  3985 
       
  3986     // make sure we use a pixmap with the same depth/visual as the widget
       
  3987     if (xinfo.visual() != QX11Info::appVisual()) {
       
  3988         QX11InfoData* xd = pm.x11Info().getX11Data(true);
       
  3989         xd->depth = xinfo.depth();
       
  3990         xd->visual = static_cast<Visual *>(xinfo.visual());
       
  3991         const_cast<QX11Info &>(pm.x11Info()).setX11Data(xd);
       
  3992     }
       
  3993 
       
  3994 #else
       
  3995     QPixmap pm(sz);
       
  3996 #endif
       
  3997 
       
  3998     d->glcx->doneCurrent();
       
  3999 
       
  4000     bool success = true;
       
  4001 
       
  4002     if (useContext && isValid() && d->renderCxPm(&pm))
       
  4003         return pm;
       
  4004 
       
  4005     QGLFormat fmt = d->glcx->requestedFormat();
       
  4006     fmt.setDirectRendering(false);                // Direct is unlikely to work
       
  4007     fmt.setDoubleBuffer(false);                // We don't need dbl buf
       
  4008 #ifdef Q_WS_MAC // crash prevention on the Mac - it's unlikely to work anyway
       
  4009     fmt.setSampleBuffers(false);
       
  4010 #endif
       
  4011 
       
  4012     QGLContext* ocx = d->glcx;
       
  4013     ocx->doneCurrent();
       
  4014     d->glcx = new QGLContext(fmt, &pm);
       
  4015     d->glcx->create();
       
  4016 
       
  4017     if (d->glcx->isValid())
       
  4018         updateGL();
       
  4019     else
       
  4020         success = false;
       
  4021 
       
  4022     delete d->glcx;
       
  4023     d->glcx = ocx;
       
  4024 
       
  4025     ocx->makeCurrent();
       
  4026 
       
  4027     if (success) {
       
  4028 #if defined(Q_WS_X11)
       
  4029         if (xinfo.visual() != QX11Info::appVisual()) {
       
  4030             QImage image = pm.toImage();
       
  4031             QPixmap p = QPixmap::fromImage(image);
       
  4032             return p;
       
  4033         }
       
  4034 #endif
       
  4035         return pm;
       
  4036     }
       
  4037     return QPixmap();
       
  4038 }
       
  4039 
       
  4040 /*!
       
  4041     Returns an image of the frame buffer. If \a withAlpha is true the
       
  4042     alpha channel is included.
       
  4043 
       
  4044     Depending on your hardware, you can explicitly select which color
       
  4045     buffer to grab with a glReadBuffer() call before calling this
       
  4046     function.
       
  4047 */
       
  4048 QImage QGLWidget::grabFrameBuffer(bool withAlpha)
       
  4049 {
       
  4050     makeCurrent();
       
  4051     QImage res;
       
  4052     int w = width();
       
  4053     int h = height();
       
  4054     if (format().rgba()) {
       
  4055         res = qt_gl_read_framebuffer(QSize(w, h), format().alpha(), withAlpha);
       
  4056     } else {
       
  4057 #if defined (Q_WS_WIN) && !defined(QT_OPENGL_ES)
       
  4058         res = QImage(w, h, QImage::Format_Indexed8);
       
  4059         glReadPixels(0, 0, w, h, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, res.bits());
       
  4060         const QVector<QColor> pal = QColormap::instance().colormap();
       
  4061         if (pal.size()) {
       
  4062             res.setColorCount(pal.size());
       
  4063             for (int i = 0; i < pal.size(); i++)
       
  4064                 res.setColor(i, pal.at(i).rgb());
       
  4065         }
       
  4066         res = res.mirrored();
       
  4067 #endif
       
  4068     }
       
  4069 
       
  4070     return res;
       
  4071 }
       
  4072 
       
  4073 
       
  4074 
       
  4075 /*!
       
  4076     Initializes OpenGL for this widget's context. Calls the virtual
       
  4077     function initializeGL().
       
  4078 */
       
  4079 
       
  4080 void QGLWidget::glInit()
       
  4081 {
       
  4082     Q_D(QGLWidget);
       
  4083     if (!isValid())
       
  4084         return;
       
  4085     makeCurrent();
       
  4086     initializeGL();
       
  4087     d->glcx->setInitialized(true);
       
  4088 }
       
  4089 
       
  4090 
       
  4091 /*!
       
  4092     Executes the virtual function paintGL().
       
  4093 
       
  4094     The widget's rendering context will become the current context and
       
  4095     initializeGL() will be called if it hasn't already been called.
       
  4096 */
       
  4097 
       
  4098 void QGLWidget::glDraw()
       
  4099 {
       
  4100     Q_D(QGLWidget);
       
  4101     if (!isValid())
       
  4102         return;
       
  4103     makeCurrent();
       
  4104 #ifndef QT_OPENGL_ES
       
  4105     if (d->glcx->deviceIsPixmap())
       
  4106         glDrawBuffer(GL_FRONT);
       
  4107 #endif
       
  4108     if (!d->glcx->initialized()) {
       
  4109         glInit();
       
  4110         resizeGL(d->glcx->device()->width(), d->glcx->device()->height()); // New context needs this "resize"
       
  4111     }
       
  4112     paintGL();
       
  4113     if (doubleBuffer()) {
       
  4114         if (d->autoSwap)
       
  4115             swapBuffers();
       
  4116     } else {
       
  4117         glFlush();
       
  4118     }
       
  4119 }
       
  4120 
       
  4121 /*!
       
  4122     Convenience function for specifying a drawing color to OpenGL.
       
  4123     Calls glColor4 (in RGBA mode) or glIndex (in color-index mode)
       
  4124     with the color \a c. Applies to this widgets GL context.
       
  4125 
       
  4126     \note This function is not supported on OpenGL/ES 2.0 systems.
       
  4127 
       
  4128     \sa qglClearColor(), QGLContext::currentContext(), QColor
       
  4129 */
       
  4130 
       
  4131 void QGLWidget::qglColor(const QColor& c) const
       
  4132 {
       
  4133 #if !defined(QT_OPENGL_ES_2)
       
  4134 #ifdef QT_OPENGL_ES
       
  4135     glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
       
  4136 #else
       
  4137     Q_D(const QGLWidget);
       
  4138     const QGLContext *ctx = QGLContext::currentContext();
       
  4139     if (ctx) {
       
  4140         if (ctx->format().rgba())
       
  4141             glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
       
  4142         else if (!d->cmap.isEmpty()) { // QGLColormap in use?
       
  4143             int i = d->cmap.find(c.rgb());
       
  4144             if (i < 0)
       
  4145                 i = d->cmap.findNearest(c.rgb());
       
  4146             glIndexi(i);
       
  4147         } else
       
  4148             glIndexi(ctx->colorIndex(c));
       
  4149     }
       
  4150 #endif //QT_OPENGL_ES
       
  4151 #else
       
  4152     Q_UNUSED(c);
       
  4153 #endif //QT_OPENGL_ES_2
       
  4154 }
       
  4155 
       
  4156 /*!
       
  4157     Convenience function for specifying the clearing color to OpenGL.
       
  4158     Calls glClearColor (in RGBA mode) or glClearIndex (in color-index
       
  4159     mode) with the color \a c. Applies to this widgets GL context.
       
  4160 
       
  4161     \sa qglColor(), QGLContext::currentContext(), QColor
       
  4162 */
       
  4163 
       
  4164 void QGLWidget::qglClearColor(const QColor& c) const
       
  4165 {
       
  4166 #ifdef QT_OPENGL_ES
       
  4167     glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
       
  4168 #else
       
  4169     Q_D(const QGLWidget);
       
  4170     const QGLContext *ctx = QGLContext::currentContext();
       
  4171     if (ctx) {
       
  4172         if (ctx->format().rgba())
       
  4173             glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
       
  4174         else if (!d->cmap.isEmpty()) { // QGLColormap in use?
       
  4175             int i = d->cmap.find(c.rgb());
       
  4176             if (i < 0)
       
  4177                 i = d->cmap.findNearest(c.rgb());
       
  4178             glClearIndex(i);
       
  4179         } else
       
  4180             glClearIndex(ctx->colorIndex(c));
       
  4181     }
       
  4182 #endif
       
  4183 }
       
  4184 
       
  4185 
       
  4186 /*!
       
  4187     Converts the image \a img into the unnamed format expected by
       
  4188     OpenGL functions such as glTexImage2D(). The returned image is not
       
  4189     usable as a QImage, but QImage::width(), QImage::height() and
       
  4190     QImage::bits() may be used with OpenGL. The GL format used is
       
  4191     \c GL_RGBA.
       
  4192 
       
  4193     \omit ###
       
  4194 
       
  4195     \l opengl/texture example
       
  4196     The following few lines are from the texture example. Most of the
       
  4197     code is irrelevant, so we just quote the relevant bits:
       
  4198 
       
  4199     \quotefromfile opengl/texture/gltexobj.cpp
       
  4200     \skipto tex1
       
  4201     \printline tex1
       
  4202     \printline gllogo.bmp
       
  4203 
       
  4204     We create \e tex1 (and another variable) for OpenGL, and load a real
       
  4205     image into \e buf.
       
  4206 
       
  4207     \skipto convertToGLFormat
       
  4208     \printline convertToGLFormat
       
  4209 
       
  4210     A few lines later, we convert \e buf into OpenGL format and store it
       
  4211     in \e tex1.
       
  4212 
       
  4213     \skipto glTexImage2D
       
  4214     \printline glTexImage2D
       
  4215     \printline tex1.bits
       
  4216 
       
  4217     Note the dimension restrictions for texture images as described in
       
  4218     the glTexImage2D() documentation. The width must be 2^m + 2*border
       
  4219     and the height 2^n + 2*border where m and n are integers and
       
  4220     border is either 0 or 1.
       
  4221 
       
  4222     Another function in the same example uses \e tex1 with OpenGL.
       
  4223 
       
  4224     \endomit
       
  4225 */
       
  4226 
       
  4227 QImage QGLWidget::convertToGLFormat(const QImage& img)
       
  4228 {
       
  4229     QImage res(img.size(), QImage::Format_ARGB32);
       
  4230     convertToGLFormatHelper(res, img.convertToFormat(QImage::Format_ARGB32), GL_RGBA);
       
  4231     return res;
       
  4232 }
       
  4233 
       
  4234 
       
  4235 /*!
       
  4236     \fn QGLColormap & QGLWidget::colormap() const
       
  4237 
       
  4238     Returns the colormap for this widget.
       
  4239 
       
  4240     Usually it is only top-level widgets that can have different
       
  4241     colormaps installed. Asking for the colormap of a child widget
       
  4242     will return the colormap for the child's top-level widget.
       
  4243 
       
  4244     If no colormap has been set for this widget, the QGLColormap
       
  4245     returned will be empty.
       
  4246 
       
  4247     \sa setColormap(), QGLColormap::isEmpty()
       
  4248 */
       
  4249 
       
  4250 /*!
       
  4251     \fn void QGLWidget::setColormap(const QGLColormap & cmap)
       
  4252 
       
  4253     Set the colormap for this widget to \a cmap. Usually it is only
       
  4254     top-level widgets that can have colormaps installed.
       
  4255 
       
  4256     \sa colormap()
       
  4257 */
       
  4258 
       
  4259 
       
  4260 /*!
       
  4261     \obsolete
       
  4262 
       
  4263     Returns the value of the first display list that is generated for
       
  4264     the characters in the given \a font. \a listBase indicates the base
       
  4265     value used when generating the display lists for the font. The
       
  4266     default value is 2000.
       
  4267 
       
  4268     \note This function is not supported on OpenGL/ES systems.
       
  4269 */
       
  4270 int QGLWidget::fontDisplayListBase(const QFont & font, int listBase)
       
  4271 {
       
  4272 #ifndef QT_OPENGL_ES
       
  4273     Q_D(QGLWidget);
       
  4274     int base;
       
  4275 
       
  4276     if (!d->glcx) { // this can't happen unless we run out of mem
       
  4277         return 0;
       
  4278     }
       
  4279 
       
  4280     // always regenerate font disp. lists for pixmaps - hw accelerated
       
  4281     // contexts can't handle this otherwise
       
  4282     bool regenerate = d->glcx->deviceIsPixmap();
       
  4283 #ifndef QT_NO_FONTCONFIG
       
  4284     // font color needs to be part of the font cache key when using
       
  4285     // antialiased fonts since one set of glyphs needs to be generated
       
  4286     // for each font color
       
  4287     QString color_key;
       
  4288     if (font.styleStrategy() != QFont::NoAntialias) {
       
  4289         GLfloat color[4];
       
  4290         glGetFloatv(GL_CURRENT_COLOR, color);
       
  4291         color_key.sprintf("%f_%f_%f",color[0], color[1], color[2]);
       
  4292     }
       
  4293     QString key = font.key() + color_key + QString::number((int) regenerate);
       
  4294 #else
       
  4295     QString key = font.key() + QString::number((int) regenerate);
       
  4296 #endif
       
  4297     if (!regenerate && (d->displayListCache.find(key) != d->displayListCache.end())) {
       
  4298         base = d->displayListCache[key];
       
  4299     } else {
       
  4300         int maxBase = listBase - 256;
       
  4301         QMap<QString,int>::ConstIterator it;
       
  4302         for (it = d->displayListCache.constBegin(); it != d->displayListCache.constEnd(); ++it) {
       
  4303             if (maxBase < it.value()) {
       
  4304                 maxBase = it.value();
       
  4305             }
       
  4306         }
       
  4307         maxBase += 256;
       
  4308         d->glcx->generateFontDisplayLists(font, maxBase);
       
  4309         d->displayListCache[key] = maxBase;
       
  4310         base = maxBase;
       
  4311     }
       
  4312     return base;
       
  4313 #else // QT_OPENGL_ES
       
  4314     Q_UNUSED(font);
       
  4315     Q_UNUSED(listBase);
       
  4316     return 0;
       
  4317 #endif
       
  4318 }
       
  4319 
       
  4320 #ifndef QT_OPENGL_ES
       
  4321 
       
  4322 static void qt_save_gl_state()
       
  4323 {
       
  4324     glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
       
  4325     glPushAttrib(GL_ALL_ATTRIB_BITS);
       
  4326     glMatrixMode(GL_TEXTURE);
       
  4327     glPushMatrix();
       
  4328     glLoadIdentity();
       
  4329     glMatrixMode(GL_PROJECTION);
       
  4330     glPushMatrix();
       
  4331     glMatrixMode(GL_MODELVIEW);
       
  4332     glPushMatrix();
       
  4333 
       
  4334     glShadeModel(GL_FLAT);
       
  4335     glDisable(GL_CULL_FACE);
       
  4336     glDisable(GL_LIGHTING);
       
  4337     glDisable(GL_STENCIL_TEST);
       
  4338     glDisable(GL_DEPTH_TEST);
       
  4339     glEnable(GL_BLEND);
       
  4340     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
       
  4341 }
       
  4342 
       
  4343 static void qt_restore_gl_state()
       
  4344 {
       
  4345     glMatrixMode(GL_TEXTURE);
       
  4346     glPopMatrix();
       
  4347     glMatrixMode(GL_PROJECTION);
       
  4348     glPopMatrix();
       
  4349     glMatrixMode(GL_MODELVIEW);
       
  4350     glPopMatrix();
       
  4351     glPopAttrib();
       
  4352     glPopClientAttrib();
       
  4353 }
       
  4354 
       
  4355 static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str,
       
  4356                             const QFont &font)
       
  4357 {
       
  4358     GLfloat color[4];
       
  4359     glGetFloatv(GL_CURRENT_COLOR, &color[0]);
       
  4360 
       
  4361     QColor col;
       
  4362     col.setRgbF(color[0], color[1], color[2],color[3]);
       
  4363     QPen old_pen = p->pen();
       
  4364     QFont old_font = p->font();
       
  4365 
       
  4366     p->setPen(col);
       
  4367     p->setFont(font);
       
  4368     p->drawText(x, y, str);
       
  4369 
       
  4370     p->setPen(old_pen);
       
  4371     p->setFont(old_font);
       
  4372 }
       
  4373 
       
  4374 #endif // !QT_OPENGL_ES
       
  4375 
       
  4376 /*!
       
  4377    Renders the string \a str into the GL context of this widget.
       
  4378 
       
  4379    \a x and \a y are specified in window coordinates, with the origin
       
  4380    in the upper left-hand corner of the window. If \a font is not
       
  4381    specified, the currently set application font will be used to
       
  4382    render the string. To change the color of the rendered text you can
       
  4383    use the glColor() call (or the qglColor() convenience function),
       
  4384    just before the renderText() call.
       
  4385 
       
  4386    The \a listBase parameter is obsolete and will be removed in a
       
  4387    future version of Qt.
       
  4388 
       
  4389    \note This function clears the stencil buffer.
       
  4390 
       
  4391    \note This function is not supported on OpenGL/ES systems.
       
  4392 
       
  4393    \note This function temporarily disables depth-testing when the
       
  4394    text is drawn.
       
  4395 
       
  4396    \note This function can only be used inside a
       
  4397    QPainter::beginNativePainting()/QPainter::endNativePainting() block
       
  4398    if the default OpenGL paint engine is QPaintEngine::OpenGL. To make
       
  4399    QPaintEngine::OpenGL the default GL engine, call
       
  4400    QGL::setPreferredPaintEngine(QPaintEngine::OpenGL) before the
       
  4401    QApplication constructor.
       
  4402 
       
  4403    \l{Overpainting Example}{Overpaint} with QPainter::drawText() instead.
       
  4404 */
       
  4405 
       
  4406 void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, int)
       
  4407 {
       
  4408 #ifndef QT_OPENGL_ES
       
  4409     Q_D(QGLWidget);
       
  4410     if (str.isEmpty() || !isValid())
       
  4411         return;
       
  4412 
       
  4413     GLint view[4];
       
  4414     bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
       
  4415     if (!use_scissor_testing)
       
  4416         glGetIntegerv(GL_VIEWPORT, &view[0]);
       
  4417     int width = d->glcx->device()->width();
       
  4418     int height = d->glcx->device()->height();
       
  4419     bool auto_swap = autoBufferSwap();
       
  4420 
       
  4421     QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
       
  4422 
       
  4423     QPaintEngine *engine = paintEngine();
       
  4424     if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
       
  4425         qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
       
  4426                  " active on the same device is not allowed.");
       
  4427         return;
       
  4428     }
       
  4429 
       
  4430     // this changes what paintEngine() returns
       
  4431     qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
       
  4432     engine = paintEngine();
       
  4433     QPainter *p;
       
  4434     bool reuse_painter = false;
       
  4435     if (engine->isActive()) {
       
  4436         reuse_painter = true;
       
  4437         p = engine->painter();
       
  4438         qt_save_gl_state();
       
  4439 
       
  4440         glDisable(GL_DEPTH_TEST);
       
  4441         glViewport(0, 0, width, height);
       
  4442         glMatrixMode(GL_PROJECTION);
       
  4443         glLoadIdentity();
       
  4444         glOrtho(0, width, height, 0, 0, 1);
       
  4445         glMatrixMode(GL_MODELVIEW);
       
  4446 
       
  4447         glLoadIdentity();
       
  4448     } else {
       
  4449         setAutoBufferSwap(false);
       
  4450         // disable glClear() as a result of QPainter::begin()
       
  4451         d->disable_clear_on_painter_begin = true;
       
  4452         p = new QPainter(this);
       
  4453     }
       
  4454 
       
  4455     QRect viewport(view[0], view[1], view[2], view[3]);
       
  4456     if (!use_scissor_testing && viewport != rect()) {
       
  4457         // if the user hasn't set a scissor box, we set one that
       
  4458         // covers the current viewport
       
  4459         glScissor(view[0], view[1], view[2], view[3]);
       
  4460         glEnable(GL_SCISSOR_TEST);
       
  4461     } else if (use_scissor_testing) {
       
  4462         // use the scissor box set by the user
       
  4463         glEnable(GL_SCISSOR_TEST);
       
  4464     }
       
  4465 
       
  4466     qt_gl_draw_text(p, x, y, str, font);
       
  4467 
       
  4468     if (reuse_painter) {
       
  4469         qt_restore_gl_state();
       
  4470     } else {
       
  4471         p->end();
       
  4472         delete p;
       
  4473         setAutoBufferSwap(auto_swap);
       
  4474         d->disable_clear_on_painter_begin = false;
       
  4475     }
       
  4476     qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
       
  4477 #else // QT_OPENGL_ES
       
  4478     Q_UNUSED(x);
       
  4479     Q_UNUSED(y);
       
  4480     Q_UNUSED(str);
       
  4481     Q_UNUSED(font);
       
  4482     qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
       
  4483 #endif
       
  4484 }
       
  4485 
       
  4486 /*! \overload
       
  4487 
       
  4488     \a x, \a y and \a z are specified in scene or object coordinates
       
  4489     relative to the currently set projection and model matrices. This
       
  4490     can be useful if you want to annotate models with text labels and
       
  4491     have the labels move with the model as it is rotated etc.
       
  4492 
       
  4493     \note This function is not supported on OpenGL/ES systems.
       
  4494 
       
  4495     \note If depth testing is enabled before this function is called,
       
  4496     then the drawn text will be depth-tested against the models that
       
  4497     have already been drawn in the scene.  Use \c{glDisable(GL_DEPTH_TEST)}
       
  4498     before calling this function to annotate the models without
       
  4499     depth-testing the text.
       
  4500 
       
  4501     \l{Overpainting Example}{Overpaint} with QPainter::drawText() instead.
       
  4502 */
       
  4503 void QGLWidget::renderText(double x, double y, double z, const QString &str, const QFont &font, int)
       
  4504 {
       
  4505 #ifndef QT_OPENGL_ES
       
  4506     Q_D(QGLWidget);
       
  4507     if (str.isEmpty() || !isValid())
       
  4508         return;
       
  4509 
       
  4510     bool auto_swap = autoBufferSwap();
       
  4511 
       
  4512     int width = d->glcx->device()->width();
       
  4513     int height = d->glcx->device()->height();
       
  4514     GLdouble model[4][4], proj[4][4];
       
  4515     GLint view[4];
       
  4516     glGetDoublev(GL_MODELVIEW_MATRIX, &model[0][0]);
       
  4517     glGetDoublev(GL_PROJECTION_MATRIX, &proj[0][0]);
       
  4518     glGetIntegerv(GL_VIEWPORT, &view[0]);
       
  4519     GLdouble win_x = 0, win_y = 0, win_z = 0;
       
  4520     qgluProject(x, y, z, &model[0][0], &proj[0][0], &view[0],
       
  4521                 &win_x, &win_y, &win_z);
       
  4522     win_y = height - win_y; // y is inverted
       
  4523 
       
  4524     QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
       
  4525     QPaintEngine *engine = paintEngine();
       
  4526 
       
  4527     if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
       
  4528         qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
       
  4529                  " active on the same device is not allowed.");
       
  4530         return;
       
  4531     }
       
  4532 
       
  4533     // this changes what paintEngine() returns
       
  4534     qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
       
  4535     engine = paintEngine();
       
  4536     QPainter *p;
       
  4537     bool reuse_painter = false;
       
  4538     bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
       
  4539     bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
       
  4540 
       
  4541     if (engine->isActive()) {
       
  4542         reuse_painter = true;
       
  4543         p = engine->painter();
       
  4544         qt_save_gl_state();
       
  4545     } else {
       
  4546         setAutoBufferSwap(false);
       
  4547         // disable glClear() as a result of QPainter::begin()
       
  4548         d->disable_clear_on_painter_begin = true;
       
  4549         p = new QPainter(this);
       
  4550     }
       
  4551 
       
  4552     QRect viewport(view[0], view[1], view[2], view[3]);
       
  4553     if (!use_scissor_testing && viewport != rect()) {
       
  4554         glScissor(view[0], view[1], view[2], view[3]);
       
  4555         glEnable(GL_SCISSOR_TEST);
       
  4556     } else if (use_scissor_testing) {
       
  4557         glEnable(GL_SCISSOR_TEST);
       
  4558     }
       
  4559     glMatrixMode(GL_PROJECTION);
       
  4560     glLoadIdentity();
       
  4561     glViewport(0, 0, width, height);
       
  4562     glOrtho(0, width, height, 0, 0, 1);
       
  4563     glMatrixMode(GL_MODELVIEW);
       
  4564     glLoadIdentity();
       
  4565     glAlphaFunc(GL_GREATER, 0.0);
       
  4566     glEnable(GL_ALPHA_TEST);
       
  4567     if (use_depth_testing)
       
  4568         glEnable(GL_DEPTH_TEST);
       
  4569     glTranslated(0, 0, -win_z);
       
  4570     qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font);
       
  4571 
       
  4572     if (reuse_painter) {
       
  4573         qt_restore_gl_state();
       
  4574     } else {
       
  4575         p->end();
       
  4576         delete p;
       
  4577         setAutoBufferSwap(auto_swap);
       
  4578         d->disable_clear_on_painter_begin = false;
       
  4579     }
       
  4580     qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
       
  4581 #else // QT_OPENGL_ES
       
  4582     Q_UNUSED(x);
       
  4583     Q_UNUSED(y);
       
  4584     Q_UNUSED(z);
       
  4585     Q_UNUSED(str);
       
  4586     Q_UNUSED(font);
       
  4587     qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
       
  4588 #endif
       
  4589 }
       
  4590 
       
  4591 QGLFormat QGLWidget::format() const
       
  4592 {
       
  4593     Q_D(const QGLWidget);
       
  4594     return d->glcx->format();
       
  4595 }
       
  4596 
       
  4597 const QGLContext *QGLWidget::context() const
       
  4598 {
       
  4599     Q_D(const QGLWidget);
       
  4600     return d->glcx;
       
  4601 }
       
  4602 
       
  4603 bool QGLWidget::doubleBuffer() const
       
  4604 {
       
  4605     Q_D(const QGLWidget);
       
  4606     return d->glcx->d_ptr->glFormat.testOption(QGL::DoubleBuffer);
       
  4607 }
       
  4608 
       
  4609 void QGLWidget::setAutoBufferSwap(bool on)
       
  4610 {
       
  4611     Q_D(QGLWidget);
       
  4612     d->autoSwap = on;
       
  4613 }
       
  4614 
       
  4615 bool QGLWidget::autoBufferSwap() const
       
  4616 {
       
  4617     Q_D(const QGLWidget);
       
  4618     return d->autoSwap;
       
  4619 }
       
  4620 
       
  4621 /*!
       
  4622     Calls QGLContext:::bindTexture(\a image, \a target, \a format) on the currently
       
  4623     set context.
       
  4624 
       
  4625     \sa deleteTexture()
       
  4626 */
       
  4627 GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format)
       
  4628 {
       
  4629     if (image.isNull())
       
  4630         return 0;
       
  4631 
       
  4632     Q_D(QGLWidget);
       
  4633     return d->glcx->bindTexture(image, target, format, QGLContext::DefaultBindOption);
       
  4634 }
       
  4635 
       
  4636 /*!
       
  4637   \overload
       
  4638   \since 4.6
       
  4639 
       
  4640   The binding \a options are a set of options used to decide how to
       
  4641   bind the texture to the context.
       
  4642  */
       
  4643 GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format, QGLContext::BindOptions options)
       
  4644 {
       
  4645     if (image.isNull())
       
  4646         return 0;
       
  4647 
       
  4648     Q_D(QGLWidget);
       
  4649     return d->glcx->bindTexture(image, target, format, options);
       
  4650 }
       
  4651 
       
  4652 
       
  4653 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
       
  4654 /*! \internal */
       
  4655 GLuint QGLWidget::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format)
       
  4656 {
       
  4657     if (image.isNull())
       
  4658         return 0;
       
  4659 
       
  4660    Q_D(QGLWidget);
       
  4661    return d->glcx->bindTexture(image, GLenum(target), GLint(format), QGLContext::DefaultBindOption);
       
  4662 }
       
  4663 
       
  4664 GLuint QGLWidget::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format,
       
  4665                               QGLContext::BindOptions options)
       
  4666 {
       
  4667     if (image.isNull())
       
  4668         return 0;
       
  4669 
       
  4670    Q_D(QGLWidget);
       
  4671    return d->glcx->bindTexture(image, GLenum(target), GLint(format), options);
       
  4672 }
       
  4673 #endif
       
  4674 
       
  4675 /*!
       
  4676     Calls QGLContext:::bindTexture(\a pixmap, \a target, \a format) on the currently
       
  4677     set context.
       
  4678 
       
  4679     \sa deleteTexture()
       
  4680 */
       
  4681 GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format)
       
  4682 {
       
  4683     if (pixmap.isNull())
       
  4684         return 0;
       
  4685 
       
  4686     Q_D(QGLWidget);
       
  4687     return d->glcx->bindTexture(pixmap, target, format, QGLContext::DefaultBindOption);
       
  4688 }
       
  4689 
       
  4690 /*!
       
  4691   \overload
       
  4692   \since 4.6
       
  4693 
       
  4694   Generates and binds a 2D GL texture to the current context, based
       
  4695   on \a pixmap. The generated texture id is returned and can be used in
       
  4696 
       
  4697   The binding \a options are a set of options used to decide how to
       
  4698   bind the texture to the context.
       
  4699  */
       
  4700 GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format,
       
  4701                               QGLContext::BindOptions options)
       
  4702 {
       
  4703     Q_D(QGLWidget);
       
  4704     return d->glcx->bindTexture(pixmap, target, format, options);
       
  4705 }
       
  4706 
       
  4707 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
       
  4708 /*! \internal */
       
  4709 GLuint QGLWidget::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format)
       
  4710 {
       
  4711     Q_D(QGLWidget);
       
  4712     return d->glcx->bindTexture(pixmap, target, format, QGLContext::DefaultBindOption);
       
  4713 }
       
  4714 
       
  4715 GLuint QGLWidget::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format,
       
  4716                               QGLContext::BindOptions options)
       
  4717 {
       
  4718     Q_D(QGLWidget);
       
  4719     return d->glcx->bindTexture(pixmap, target, format, options);
       
  4720 }
       
  4721 #endif
       
  4722 
       
  4723 
       
  4724 /*! \overload
       
  4725 
       
  4726     Calls QGLContext::bindTexture(\a fileName) on the currently set context.
       
  4727 
       
  4728     \sa deleteTexture()
       
  4729 */
       
  4730 GLuint QGLWidget::bindTexture(const QString &fileName)
       
  4731 {
       
  4732     Q_D(QGLWidget);
       
  4733     return d->glcx->bindTexture(fileName);
       
  4734 }
       
  4735 
       
  4736 /*!
       
  4737     Calls QGLContext::deleteTexture(\a id) on the currently set
       
  4738     context.
       
  4739 
       
  4740     \sa bindTexture()
       
  4741 */
       
  4742 void QGLWidget::deleteTexture(GLuint id)
       
  4743 {
       
  4744     Q_D(QGLWidget);
       
  4745     d->glcx->deleteTexture(id);
       
  4746 }
       
  4747 
       
  4748 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
       
  4749 /*! \internal */
       
  4750 void QGLWidget::deleteTexture(QMacCompatGLuint id)
       
  4751 {
       
  4752     Q_D(QGLWidget);
       
  4753     d->glcx->deleteTexture(GLuint(id));
       
  4754 }
       
  4755 #endif
       
  4756 
       
  4757 /*!
       
  4758     \since 4.4
       
  4759 
       
  4760     Draws the given texture, \a textureId to the given target rectangle,
       
  4761     \a target, in OpenGL model space. The \a textureTarget should be a 2D
       
  4762     texture target.
       
  4763 
       
  4764     Equivalent to the corresponding QGLContext::drawTexture().
       
  4765 */
       
  4766 void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget)
       
  4767 {
       
  4768     Q_D(QGLWidget);
       
  4769     d->glcx->drawTexture(target, textureId, textureTarget);
       
  4770 }
       
  4771 
       
  4772 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
       
  4773 /*! \internal */
       
  4774 void QGLWidget::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
       
  4775 {
       
  4776     Q_D(QGLWidget);
       
  4777     d->glcx->drawTexture(target, GLint(textureId), GLenum(textureTarget));
       
  4778 }
       
  4779 #endif
       
  4780 
       
  4781 /*!
       
  4782     \since 4.4
       
  4783 
       
  4784     Draws the given texture, \a textureId, at the given \a point in OpenGL
       
  4785     model space. The \a textureTarget should be a 2D texture target.
       
  4786 
       
  4787     Equivalent to the corresponding QGLContext::drawTexture().
       
  4788 */
       
  4789 void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget)
       
  4790 {
       
  4791     Q_D(QGLWidget);
       
  4792     d->glcx->drawTexture(point, textureId, textureTarget);
       
  4793 }
       
  4794 
       
  4795 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
       
  4796 /*! \internal */
       
  4797 void QGLWidget::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
       
  4798 {
       
  4799     Q_D(QGLWidget);
       
  4800     d->glcx->drawTexture(point, GLuint(textureId), GLenum(textureTarget));
       
  4801 }
       
  4802 #endif
       
  4803 
       
  4804 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
       
  4805 Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_2_engine)
       
  4806 #endif
       
  4807 
       
  4808 #ifndef QT_OPENGL_ES_2
       
  4809 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_engine)
       
  4810 #endif
       
  4811 
       
  4812 Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine()
       
  4813 {
       
  4814 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)
       
  4815     return qt_gl_engine();
       
  4816 #elif defined(QT_OPENGL_ES_2)
       
  4817     return qt_gl_2_engine();
       
  4818 #else
       
  4819     if (qt_gl_preferGL2Engine())
       
  4820         return qt_gl_2_engine();
       
  4821     else
       
  4822         return qt_gl_engine();
       
  4823 #endif
       
  4824 }
       
  4825 
       
  4826 /*!
       
  4827     \internal
       
  4828 
       
  4829     Returns the GL widget's paint engine. This is normally a
       
  4830     QOpenGLPaintEngine.
       
  4831 */
       
  4832 QPaintEngine *QGLWidget::paintEngine() const
       
  4833 {
       
  4834     return qt_qgl_paint_engine();
       
  4835 }
       
  4836 
       
  4837 #ifdef QT3_SUPPORT
       
  4838 /*!
       
  4839     \overload
       
  4840     \obsolete
       
  4841  */
       
  4842 QGLWidget::QGLWidget(QWidget *parent, const char *name,
       
  4843                       const QGLWidget* shareWidget, Qt::WindowFlags f)
       
  4844     : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
       
  4845 {
       
  4846     Q_D(QGLWidget);
       
  4847     if (name)
       
  4848         setObjectName(QString::fromAscii(name));
       
  4849     setAttribute(Qt::WA_PaintOnScreen);
       
  4850     setAttribute(Qt::WA_NoSystemBackground);
       
  4851     setAutoFillBackground(true); // for compatibility
       
  4852     d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget);
       
  4853 }
       
  4854 
       
  4855 /*!
       
  4856     \overload
       
  4857     \obsolete
       
  4858  */
       
  4859 QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent,
       
  4860                       const char *name, const QGLWidget* shareWidget,
       
  4861                       Qt::WindowFlags f)
       
  4862     : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
       
  4863 {
       
  4864     Q_D(QGLWidget);
       
  4865     if (name)
       
  4866         setObjectName(QString::fromAscii(name));
       
  4867     setAttribute(Qt::WA_PaintOnScreen);
       
  4868     setAttribute(Qt::WA_NoSystemBackground);
       
  4869     setAutoFillBackground(true); // for compatibility
       
  4870     d->init(new QGLContext(format, this), shareWidget);
       
  4871 }
       
  4872 
       
  4873 /*!
       
  4874     \overload
       
  4875     \obsolete
       
  4876  */
       
  4877 QGLWidget::QGLWidget(QGLContext *context, QWidget *parent,
       
  4878                       const char *name, const QGLWidget *shareWidget, Qt::WindowFlags f)
       
  4879     : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
       
  4880 {
       
  4881     Q_D(QGLWidget);
       
  4882     if (name)
       
  4883         setObjectName(QString::fromAscii(name));
       
  4884     setAttribute(Qt::WA_PaintOnScreen);
       
  4885     setAttribute(Qt::WA_NoSystemBackground);
       
  4886     setAutoFillBackground(true); // for compatibility
       
  4887     d->init(context, shareWidget);
       
  4888 }
       
  4889 
       
  4890 #endif // QT3_SUPPORT
       
  4891 
       
  4892 /*
       
  4893     Returns the GL extensions for the current context.
       
  4894 */
       
  4895 QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
       
  4896 {
       
  4897     QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
       
  4898     Extensions glExtensions;
       
  4899 
       
  4900     if (extensions.match("GL_ARB_texture_rectangle"))
       
  4901         glExtensions |= TextureRectangle;
       
  4902     if (extensions.match("GL_ARB_multisample"))
       
  4903         glExtensions |= SampleBuffers;
       
  4904     if (extensions.match("GL_SGIS_generate_mipmap"))
       
  4905         glExtensions |= GenerateMipmap;
       
  4906     if (extensions.match("GL_ARB_texture_compression"))
       
  4907         glExtensions |= TextureCompression;
       
  4908     if (extensions.match("GL_EXT_texture_compression_s3tc"))
       
  4909         glExtensions |= DDSTextureCompression;
       
  4910     if (extensions.match("GL_OES_compressed_ETC1_RGB8_texture"))
       
  4911         glExtensions |= ETC1TextureCompression;
       
  4912     if (extensions.match("GL_IMG_texture_compression_pvrtc"))
       
  4913         glExtensions |= PVRTCTextureCompression;
       
  4914     if (extensions.match("GL_ARB_fragment_program"))
       
  4915         glExtensions |= FragmentProgram;
       
  4916     if (extensions.match("GL_ARB_fragment_shader"))
       
  4917         glExtensions |= FragmentShader;
       
  4918     if (extensions.match("GL_ARB_texture_mirrored_repeat"))
       
  4919         glExtensions |= MirroredRepeat;
       
  4920     if (extensions.match("GL_EXT_framebuffer_object"))
       
  4921         glExtensions |= FramebufferObject;
       
  4922     if (extensions.match("GL_EXT_stencil_two_side"))
       
  4923         glExtensions |= StencilTwoSide;
       
  4924     if (extensions.match("GL_EXT_stencil_wrap"))
       
  4925         glExtensions |= StencilWrap;
       
  4926     if (extensions.match("GL_EXT_packed_depth_stencil"))
       
  4927         glExtensions |= PackedDepthStencil;
       
  4928     if (extensions.match("GL_NV_float_buffer"))
       
  4929         glExtensions |= NVFloatBuffer;
       
  4930     if (extensions.match("GL_ARB_pixel_buffer_object"))
       
  4931         glExtensions |= PixelBufferObject;
       
  4932 #if defined(QT_OPENGL_ES_2)
       
  4933     glExtensions |= FramebufferObject;
       
  4934     glExtensions |= GenerateMipmap;
       
  4935     glExtensions |= FragmentShader;
       
  4936 #endif
       
  4937 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)
       
  4938     if (extensions.match("GL_OES_framebuffer_object"))
       
  4939         glExtensions |= FramebufferObject;
       
  4940 #endif
       
  4941 #if defined(QT_OPENGL_ES)
       
  4942     if (extensions.match("GL_OES_packed_depth_stencil"))
       
  4943         glExtensions |= PackedDepthStencil;
       
  4944 #endif
       
  4945     if (extensions.match("GL_ARB_framebuffer_object")) {
       
  4946         // ARB_framebuffer_object also includes EXT_framebuffer_blit.
       
  4947         glExtensions |= FramebufferObject;
       
  4948         glExtensions |= FramebufferBlit;
       
  4949     }
       
  4950 
       
  4951     if (extensions.match("GL_EXT_framebuffer_blit"))
       
  4952         glExtensions |= FramebufferBlit;
       
  4953 
       
  4954     if (extensions.match("GL_ARB_texture_non_power_of_two"))
       
  4955         glExtensions |= NPOTTextures;
       
  4956 
       
  4957     if (extensions.match("GL_EXT_bgra"))
       
  4958         glExtensions |= BGRATextureFormat;
       
  4959 
       
  4960     return glExtensions;
       
  4961 }
       
  4962 
       
  4963 /*
       
  4964     Returns the GL extensions for the current QGLContext. If there is no
       
  4965     current QGLContext, a default context will be created and the extensions
       
  4966     for that context will be returned instead.
       
  4967 */
       
  4968 QGLExtensions::Extensions QGLExtensions::glExtensions()
       
  4969 {
       
  4970     QGLTemporaryContext *tmpContext = 0;
       
  4971     static bool cachedDefault = false;
       
  4972     static Extensions defaultExtensions = 0;
       
  4973     QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext());
       
  4974 
       
  4975     if (currentCtx && currentCtx->d_func()->extension_flags_cached)
       
  4976         return currentCtx->d_func()->extension_flags;
       
  4977 
       
  4978     if (!currentCtx) {
       
  4979         if (cachedDefault) {
       
  4980             return defaultExtensions;
       
  4981         } else {
       
  4982             tmpContext = new QGLTemporaryContext;
       
  4983             cachedDefault = true;
       
  4984         }
       
  4985     }
       
  4986 
       
  4987     Extensions extensionFlags = currentContextExtensions();
       
  4988     if (currentCtx) {
       
  4989         currentCtx->d_func()->extension_flags_cached = true;
       
  4990         currentCtx->d_func()->extension_flags = extensionFlags;
       
  4991     } else {
       
  4992         defaultExtensions = extensionFlags;
       
  4993     }
       
  4994 
       
  4995     if (tmpContext)
       
  4996         delete tmpContext;
       
  4997 
       
  4998     return extensionFlags;
       
  4999 }
       
  5000 
       
  5001 /*
       
  5002   This is the shared initialization for all platforms. Called from QGLWidgetPrivate::init()
       
  5003 */
       
  5004 void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWidget)
       
  5005 {
       
  5006     Q_Q(QGLWidget);
       
  5007 
       
  5008     glDevice.setWidget(q);
       
  5009 
       
  5010     glcx = 0;
       
  5011     autoSwap = true;
       
  5012 
       
  5013     if (context && !context->device())
       
  5014         context->setDevice(q);
       
  5015     q->setContext(context, shareWidget ? shareWidget->context() : 0);
       
  5016 
       
  5017     if (!glcx)
       
  5018         glcx = new QGLContext(QGLFormat::defaultFormat(), q);
       
  5019 }
       
  5020 
       
  5021 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
       
  5022 Q_GLOBAL_STATIC(QString, qt_gl_lib_name)
       
  5023 
       
  5024 Q_OPENGL_EXPORT void qt_set_gl_library_name(const QString& name)
       
  5025 {
       
  5026     qt_gl_lib_name()->operator=(name);
       
  5027 }
       
  5028 
       
  5029 Q_OPENGL_EXPORT const QString qt_gl_library_name()
       
  5030 {
       
  5031     if (qt_gl_lib_name()->isNull()) {
       
  5032 #if defined(Q_WS_X11) || defined(Q_WS_QWS)
       
  5033         return QLatin1String("GL");
       
  5034 #else // Q_WS_MAC
       
  5035         return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib");
       
  5036 #endif
       
  5037     }
       
  5038     return *qt_gl_lib_name();
       
  5039 }
       
  5040 #endif
       
  5041 
       
  5042 void QGLContextGroup::addShare(const QGLContext *context, const QGLContext *share) {
       
  5043     Q_ASSERT(context && share);
       
  5044     if (context->d_ptr->group == share->d_ptr->group)
       
  5045         return;
       
  5046 
       
  5047     // Make sure 'context' is not already shared with another group of contexts.
       
  5048     Q_ASSERT(context->d_ptr->group->m_refs == 1);
       
  5049 
       
  5050     // Free 'context' group resources and make it use the same resources as 'share'.
       
  5051     QGLContextGroup *group = share->d_ptr->group;
       
  5052     delete context->d_ptr->group;
       
  5053     context->d_ptr->group = group;
       
  5054     group->m_refs.ref();
       
  5055 
       
  5056     // Maintain a list of all the contexts in each group of sharing contexts.
       
  5057     // The list is empty if the "share" context wasn't sharing already.
       
  5058     if (group->m_shares.isEmpty())
       
  5059         group->m_shares.append(share);
       
  5060     group->m_shares.append(context);
       
  5061 }
       
  5062 
       
  5063 void QGLContextGroup::removeShare(const QGLContext *context) {
       
  5064     // Remove the context from the group.
       
  5065     QGLContextGroup *group = context->d_ptr->group;
       
  5066     if (group->m_shares.isEmpty())
       
  5067         return;
       
  5068     group->m_shares.removeAll(context);
       
  5069 
       
  5070     // Update context group representative.
       
  5071     Q_ASSERT(group->m_shares.size() != 0);
       
  5072     if (group->m_context == context)
       
  5073         group->m_context = group->m_shares[0];
       
  5074 
       
  5075     // If there is only one context left, then make the list empty.
       
  5076     if (group->m_shares.size() == 1)
       
  5077         group->m_shares.clear();
       
  5078 }
       
  5079 
       
  5080 QGLContextResource::QGLContextResource(FreeFunc f)
       
  5081     : free(f), active(0)
       
  5082 {
       
  5083 }
       
  5084 
       
  5085 QGLContextResource::~QGLContextResource()
       
  5086 {
       
  5087 #ifndef QT_NO_DEBUG
       
  5088     if (active != 0) {
       
  5089         qWarning("QtOpenGL: Resources are still available at program shutdown.\n"
       
  5090                  "          This is possibly caused by a leaked QGLWidget, \n"
       
  5091                  "          QGLFramebufferObject or QGLPixelBuffer.");
       
  5092     }
       
  5093 #endif
       
  5094 }
       
  5095 
       
  5096 void QGLContextResource::insert(const QGLContext *key, void *value)
       
  5097 {
       
  5098     QGLContextGroup *group = QGLContextPrivate::contextGroup(key);
       
  5099     Q_ASSERT(!group->m_resources.contains(this));
       
  5100     group->m_resources.insert(this, value);
       
  5101     active.ref();
       
  5102 }
       
  5103 
       
  5104 void *QGLContextResource::value(const QGLContext *key)
       
  5105 {
       
  5106     QGLContextGroup *group = QGLContextPrivate::contextGroup(key);
       
  5107     return group->m_resources.value(this, 0);
       
  5108 }
       
  5109 
       
  5110 void QGLContextResource::cleanup(const QGLContext *ctx, void *value)
       
  5111 {
       
  5112     QGLShareContextScope scope(ctx);
       
  5113     free(value);
       
  5114     active.deref();
       
  5115 }
       
  5116 
       
  5117 void QGLContextGroup::cleanupResources(const QGLContext *ctx)
       
  5118 {
       
  5119     // If there are still shares, then no cleanup to be done yet.
       
  5120     if (m_shares.size() > 1)
       
  5121         return;
       
  5122 
       
  5123     // Iterate over all resources and free each in turn.
       
  5124     QHash<QGLContextResource *, void *>::ConstIterator it;
       
  5125     for (it = m_resources.begin(); it != m_resources.end(); ++it)
       
  5126         it.key()->cleanup(ctx, it.value());
       
  5127 }
       
  5128 
       
  5129 QGLSharedResourceGuard::~QGLSharedResourceGuard()
       
  5130 {
       
  5131     if (m_group)
       
  5132         m_group->removeGuard(this);
       
  5133 }
       
  5134 
       
  5135 void QGLSharedResourceGuard::setContext(const QGLContext *context)
       
  5136 {
       
  5137     if (m_group)
       
  5138         m_group->removeGuard(this);
       
  5139     if (context) {
       
  5140         m_group = QGLContextPrivate::contextGroup(context);
       
  5141         m_group->addGuard(this);
       
  5142     } else {
       
  5143         m_group = 0;
       
  5144     }
       
  5145 }
       
  5146 
       
  5147 QSize QGLTexture::bindCompressedTexture
       
  5148     (const QString& fileName, const char *format)
       
  5149 {
       
  5150     QFile file(fileName);
       
  5151     if (!file.open(QIODevice::ReadOnly))
       
  5152         return QSize();
       
  5153     QByteArray contents = file.readAll();
       
  5154     file.close();
       
  5155     return bindCompressedTexture
       
  5156         (contents.constData(), contents.size(), format);
       
  5157 }
       
  5158 
       
  5159 // PVR header format for container files that store textures compressed
       
  5160 // with the ETC1, PVRTC2, and PVRTC4 encodings.  Format information from the
       
  5161 // PowerVR SDK at http://www.imgtec.com/powervr/insider/powervr-sdk.asp
       
  5162 // "PVRTexTool Reference Manual, version 1.11f".
       
  5163 struct PvrHeader
       
  5164 {
       
  5165     quint32 headerSize;
       
  5166     quint32 height;
       
  5167     quint32 width;
       
  5168     quint32 mipMapCount;
       
  5169     quint32 flags;
       
  5170     quint32 dataSize;
       
  5171     quint32 bitsPerPixel;
       
  5172     quint32 redMask;
       
  5173     quint32 greenMask;
       
  5174     quint32 blueMask;
       
  5175     quint32 alphaMask;
       
  5176     quint32 magic;
       
  5177     quint32 surfaceCount;
       
  5178 };
       
  5179 
       
  5180 #define PVR_MAGIC               0x21525650      // "PVR!" in little-endian
       
  5181 
       
  5182 #define PVR_FORMAT_MASK         0x000000FF
       
  5183 #define PVR_FORMAT_PVRTC2       0x00000018
       
  5184 #define PVR_FORMAT_PVRTC4       0x00000019
       
  5185 #define PVR_FORMAT_ETC1         0x00000036
       
  5186 
       
  5187 #define PVR_HAS_MIPMAPS         0x00000100
       
  5188 #define PVR_TWIDDLED            0x00000200
       
  5189 #define PVR_NORMAL_MAP          0x00000400
       
  5190 #define PVR_BORDER_ADDED        0x00000800
       
  5191 #define PVR_CUBE_MAP            0x00001000
       
  5192 #define PVR_FALSE_COLOR_MIPMAPS 0x00002000
       
  5193 #define PVR_VOLUME_TEXTURE      0x00004000
       
  5194 #define PVR_ALPHA_IN_TEXTURE    0x00008000
       
  5195 #define PVR_VERTICAL_FLIP       0x00010000
       
  5196 
       
  5197 #ifndef GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG
       
  5198 #define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG      0x8C00
       
  5199 #define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG      0x8C01
       
  5200 #define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG     0x8C02
       
  5201 #define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG     0x8C03
       
  5202 #endif
       
  5203 
       
  5204 #ifndef GL_ETC1_RGB8_OES
       
  5205 #define GL_ETC1_RGB8_OES                        0x8D64
       
  5206 #endif
       
  5207 
       
  5208 bool QGLTexture::canBindCompressedTexture
       
  5209     (const char *buf, int len, const char *format, bool *hasAlpha)
       
  5210 {
       
  5211     if (QSysInfo::ByteOrder != QSysInfo::LittleEndian) {
       
  5212         // Compressed texture loading only supported on little-endian
       
  5213         // systems such as x86 and ARM at the moment.
       
  5214         return false;
       
  5215     }
       
  5216     if (!format) {
       
  5217         // Auto-detect the format from the header.
       
  5218         if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) {
       
  5219             *hasAlpha = true;
       
  5220             return true;
       
  5221         } else if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) {
       
  5222             const PvrHeader *pvrHeader =
       
  5223                 reinterpret_cast<const PvrHeader *>(buf);
       
  5224             *hasAlpha = (pvrHeader->alphaMask != 0);
       
  5225             return true;
       
  5226         }
       
  5227     } else {
       
  5228         // Validate the format against the header.
       
  5229         if (!qstricmp(format, "DDS")) {
       
  5230             if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) {
       
  5231                 *hasAlpha = true;
       
  5232                 return true;
       
  5233             }
       
  5234         } else if (!qstricmp(format, "PVR") || !qstricmp(format, "ETC1")) {
       
  5235             if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) {
       
  5236                 const PvrHeader *pvrHeader =
       
  5237                     reinterpret_cast<const PvrHeader *>(buf);
       
  5238                 *hasAlpha = (pvrHeader->alphaMask != 0);
       
  5239                 return true;
       
  5240             }
       
  5241         }
       
  5242     }
       
  5243     return false;
       
  5244 }
       
  5245 
       
  5246 #define ctx QGLContext::currentContext()
       
  5247 
       
  5248 QSize QGLTexture::bindCompressedTexture
       
  5249     (const char *buf, int len, const char *format)
       
  5250 {
       
  5251     if (QSysInfo::ByteOrder != QSysInfo::LittleEndian) {
       
  5252         // Compressed texture loading only supported on little-endian
       
  5253         // systems such as x86 and ARM at the moment.
       
  5254         return QSize();
       
  5255     }
       
  5256 #if !defined(QT_OPENGL_ES)
       
  5257     if (!glCompressedTexImage2D) {
       
  5258         if (!(QGLExtensions::glExtensions() & QGLExtensions::TextureCompression)) {
       
  5259             qWarning("QGLContext::bindTexture(): The GL implementation does "
       
  5260                      "not support texture compression extensions.");
       
  5261             return QSize();
       
  5262         }
       
  5263         glCompressedTexImage2D = (_glCompressedTexImage2DARB) ctx->getProcAddress(QLatin1String("glCompressedTexImage2DARB"));
       
  5264         if (!glCompressedTexImage2D) {
       
  5265             qWarning("QGLContext::bindTexture(): could not resolve "
       
  5266                      "glCompressedTexImage2DARB.");
       
  5267             return QSize();
       
  5268         }
       
  5269     }
       
  5270 #endif
       
  5271     if (!format) {
       
  5272         // Auto-detect the format from the header.
       
  5273         if (len >= 4 && !qstrncmp(buf, "DDS ", 4))
       
  5274             return bindCompressedTextureDDS(buf, len);
       
  5275         else if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4))
       
  5276             return bindCompressedTexturePVR(buf, len);
       
  5277     } else {
       
  5278         // Validate the format against the header.
       
  5279         if (!qstricmp(format, "DDS")) {
       
  5280             if (len >= 4 && !qstrncmp(buf, "DDS ", 4))
       
  5281                 return bindCompressedTextureDDS(buf, len);
       
  5282         } else if (!qstricmp(format, "PVR") || !qstricmp(format, "ETC1")) {
       
  5283             if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4))
       
  5284                 return bindCompressedTexturePVR(buf, len);
       
  5285         }
       
  5286     }
       
  5287     return QSize();
       
  5288 }
       
  5289 
       
  5290 QSize QGLTexture::bindCompressedTextureDDS(const char *buf, int len)
       
  5291 {
       
  5292     // We only support 2D texture loading at present.
       
  5293     if (target != GL_TEXTURE_2D)
       
  5294         return QSize();
       
  5295 
       
  5296     // Bail out if the necessary extension is not present.
       
  5297     if (!(QGLExtensions::glExtensions() & QGLExtensions::DDSTextureCompression)) {
       
  5298         qWarning("QGLContext::bindTexture(): DDS texture compression is not supported.");
       
  5299         return QSize();
       
  5300     }
       
  5301 
       
  5302     const DDSFormat *ddsHeader = reinterpret_cast<const DDSFormat *>(buf + 4);
       
  5303     if (!ddsHeader->dwLinearSize) {
       
  5304         qWarning("QGLContext::bindTexture(): DDS image size is not valid.");
       
  5305         return QSize();
       
  5306     }
       
  5307 
       
  5308     int blockSize = 16;
       
  5309     GLenum format;
       
  5310 
       
  5311     switch(ddsHeader->ddsPixelFormat.dwFourCC) {
       
  5312     case FOURCC_DXT1:
       
  5313         format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
       
  5314         blockSize = 8;
       
  5315         break;
       
  5316     case FOURCC_DXT3:
       
  5317         format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
       
  5318         break;
       
  5319     case FOURCC_DXT5:
       
  5320         format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
       
  5321         break;
       
  5322     default:
       
  5323         qWarning("QGLContext::bindTexture(): DDS image format not supported.");
       
  5324         return QSize();
       
  5325     }
       
  5326 
       
  5327     const GLubyte *pixels =
       
  5328         reinterpret_cast<const GLubyte *>(buf + ddsHeader->dwSize + 4);
       
  5329 
       
  5330     glGenTextures(1, &id);
       
  5331     glBindTexture(GL_TEXTURE_2D, id);
       
  5332     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       
  5333     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       
  5334 
       
  5335     int size;
       
  5336     int offset = 0;
       
  5337     int available = len - int(ddsHeader->dwSize + 4);
       
  5338     int w = ddsHeader->dwWidth;
       
  5339     int h = ddsHeader->dwHeight;
       
  5340 
       
  5341     // load mip-maps
       
  5342     for(int i = 0; i < (int) ddsHeader->dwMipMapCount; ++i) {
       
  5343         if (w == 0) w = 1;
       
  5344         if (h == 0) h = 1;
       
  5345 
       
  5346         size = ((w+3)/4) * ((h+3)/4) * blockSize;
       
  5347         if (size > available)
       
  5348             break;
       
  5349         glCompressedTexImage2D(GL_TEXTURE_2D, i, format, w, h, 0,
       
  5350                                size, pixels + offset);
       
  5351         offset += size;
       
  5352         available -= size;
       
  5353 
       
  5354         // half size for each mip-map level
       
  5355         w = w/2;
       
  5356         h = h/2;
       
  5357     }
       
  5358 
       
  5359     // DDS images are not inverted.
       
  5360     options &= ~QGLContext::InvertedYBindOption;
       
  5361 
       
  5362     return QSize(ddsHeader->dwWidth, ddsHeader->dwHeight);
       
  5363 }
       
  5364 
       
  5365 QSize QGLTexture::bindCompressedTexturePVR(const char *buf, int len)
       
  5366 {
       
  5367     // We only support 2D texture loading at present.  Cube maps later.
       
  5368     if (target != GL_TEXTURE_2D)
       
  5369         return QSize();
       
  5370 
       
  5371     // Determine which texture format we will be loading.
       
  5372     const PvrHeader *pvrHeader = reinterpret_cast<const PvrHeader *>(buf);
       
  5373     GLenum textureFormat;
       
  5374     quint32 minWidth, minHeight;
       
  5375     switch (pvrHeader->flags & PVR_FORMAT_MASK) {
       
  5376     case PVR_FORMAT_PVRTC2:
       
  5377         if (pvrHeader->alphaMask)
       
  5378             textureFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
       
  5379         else
       
  5380             textureFormat = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
       
  5381         minWidth = 16;
       
  5382         minHeight = 8;
       
  5383         break;
       
  5384 
       
  5385     case PVR_FORMAT_PVRTC4:
       
  5386         if (pvrHeader->alphaMask)
       
  5387             textureFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
       
  5388         else
       
  5389             textureFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
       
  5390         minWidth = 8;
       
  5391         minHeight = 8;
       
  5392         break;
       
  5393 
       
  5394     case PVR_FORMAT_ETC1:
       
  5395         textureFormat = GL_ETC1_RGB8_OES;
       
  5396         minWidth = 4;
       
  5397         minHeight = 4;
       
  5398         break;
       
  5399 
       
  5400     default:
       
  5401         qWarning("QGLContext::bindTexture(): PVR image format 0x%x not supported.", int(pvrHeader->flags & PVR_FORMAT_MASK));
       
  5402         return QSize();
       
  5403     }
       
  5404 
       
  5405     // Bail out if the necessary extension is not present.
       
  5406     if (textureFormat == GL_ETC1_RGB8_OES) {
       
  5407         if (!(QGLExtensions::glExtensions() &
       
  5408                     QGLExtensions::ETC1TextureCompression)) {
       
  5409             qWarning("QGLContext::bindTexture(): ETC1 texture compression is not supported.");
       
  5410             return QSize();
       
  5411         }
       
  5412     } else {
       
  5413         if (!(QGLExtensions::glExtensions() &
       
  5414                     QGLExtensions::PVRTCTextureCompression)) {
       
  5415             qWarning("QGLContext::bindTexture(): PVRTC texture compression is not supported.");
       
  5416             return QSize();
       
  5417         }
       
  5418     }
       
  5419 
       
  5420     // Boundary check on the buffer size.
       
  5421     quint32 bufferSize = pvrHeader->headerSize + pvrHeader->dataSize;
       
  5422     if (bufferSize > quint32(len)) {
       
  5423         qWarning("QGLContext::bindTexture(): PVR image size is not valid.");
       
  5424         return QSize();
       
  5425     }
       
  5426 
       
  5427     // Create the texture.
       
  5428     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
       
  5429     glGenTextures(1, &id);
       
  5430     glBindTexture(GL_TEXTURE_2D, id);
       
  5431     if (pvrHeader->mipMapCount) {
       
  5432         if ((options & QGLContext::LinearFilteringBindOption) != 0) {
       
  5433             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       
  5434             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
       
  5435         } else {
       
  5436             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
       
  5437             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
       
  5438         }
       
  5439     } else if ((options & QGLContext::LinearFilteringBindOption) != 0) {
       
  5440         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       
  5441         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       
  5442     } else {
       
  5443         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
       
  5444         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
       
  5445     }
       
  5446 
       
  5447     // Load the compressed mipmap levels.
       
  5448     const GLubyte *buffer =
       
  5449         reinterpret_cast<const GLubyte *>(buf + pvrHeader->headerSize);
       
  5450     bufferSize = pvrHeader->dataSize;
       
  5451     quint32 level = 0;
       
  5452     quint32 width = pvrHeader->width;
       
  5453     quint32 height = pvrHeader->height;
       
  5454     while (bufferSize > 0 && level <= pvrHeader->mipMapCount) {
       
  5455         quint32 size =
       
  5456             (qMax(width, minWidth) * qMax(height, minHeight) *
       
  5457              pvrHeader->bitsPerPixel) / 8;
       
  5458         if (size > bufferSize)
       
  5459             break;
       
  5460         glCompressedTexImage2D(GL_TEXTURE_2D, GLint(level), textureFormat,
       
  5461                                GLsizei(width), GLsizei(height), 0,
       
  5462                                GLsizei(size), buffer);
       
  5463         width /= 2;
       
  5464         height /= 2;
       
  5465         buffer += size;
       
  5466         ++level;
       
  5467     }
       
  5468 
       
  5469     // Restore the default pixel alignment for later texture uploads.
       
  5470     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
       
  5471 
       
  5472     // Set the invert flag for the texture.  The "vertical flip"
       
  5473     // flag in PVR is the opposite sense to our sense of inversion.
       
  5474     if ((pvrHeader->flags & PVR_VERTICAL_FLIP) != 0)
       
  5475         options &= ~QGLContext::InvertedYBindOption;
       
  5476     else
       
  5477         options |= QGLContext::InvertedYBindOption;
       
  5478 
       
  5479     return QSize(pvrHeader->width, pvrHeader->height);
       
  5480 }
       
  5481 
       
  5482 #undef ctx
       
  5483 
       
  5484 QT_END_NAMESPACE