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