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