Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/opengl/qgl.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information ([email protected])
     4** All rights reserved.
     5** Contact: Nokia Corporation ([email protected])
    56**
    67** This file is part of the QtOpenGL module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you
     37** @nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6060#endif
    6161
     62
     63
    6264#include <stdlib.h> // malloc
    6365
     
    6668#include "qgl_p.h"
    6769
    68 #if defined(QT_OPENGL_ES_2)
     70#if )
    6971#include "gl2paintengineex/qpaintengineex_opengl2_p.h"
    70 #else
     72#endif
     73
     74#ifndef QT_OPENGL_ES_2
    7175#include <private/qpaintengine_opengl_p.h>
    7276#endif
     77
     78
     79
     80
     81
     82
     83
    7384
    7485#include <private/qimage_p.h>
    7586#include <private/qpixmapdata_p.h>
    7687#include <private/qpixmapdata_gl_p.h>
     88
     89
     90
    7791#include "qcolormap.h"
    78 #include "qcache.h"
    7992#include "qfile.h"
    8093#include "qlibrary.h"
     
    92105#endif
    93106
    94 QThreadStorage<QGLThreadContext *> qgl_context_storage;
     107struct QGLThreadContext {
     108    QGLContext *context;
     109};
     110
     111static QThreadStorage<QGLThreadContext *> qgl_context_storage;
    95112
    96113Q_GLOBAL_STATIC(QGLFormat, qgl_default_format)
     
    111128bool QGLExtensions::nvidiaFboNeedsFinish = false;
    112129
    113 #ifndef APIENTRY
    114 # define APIENTRY
    115 #endif
    116 typedef void (APIENTRY *pfn_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei,
    117                                                         GLsizei, GLint, GLsizei, const GLvoid *);
    118 static pfn_glCompressedTexImage2DARB qt_glCompressedTexImage2DARB = 0;
    119 
    120 
    121 #ifndef APIENTRY
    122 #define APIENTRY
    123 #endif
    124 
    125130Q_GLOBAL_STATIC(QGLSignalProxy, theSignalProxy)
    126131QGLSignalProxy *QGLSignalProxy::instance()
     
    129134}
    130135
     136
     137
     138
     139
     140
     141
     142
     143
     144
     145
     146
     147
     148
     149
     150
     151
     152
     153
     154
     155
     156
     157
     158
     159
     160
     161
     162
     163
     164
     165
     166
     167
     168
     169
     170
     171
     172
     173
     174
     175
     176
     177
     178
     179
     180
     181
     182
     183
     184
     185
     186
     187
     188
     189
     190
     191
     192
     193
     194
     195
     196
     197
     198
     199
     200
     201
     202
     203
    131204/*!
    132205    \namespace QGL
     206
    133207
    134208    \brief The QGL namespace specifies miscellaneous identifiers used
    135209    in the Qt OpenGL module.
    136210
    137     \ingroup multimedia
     211    \ingroup
    138212*/
    139213
     
    168242*/
    169243
     244
     245
     246
     247
     248
     249
     250
     251
     252
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
    170270/*****************************************************************************
    171271  QGLFormat implementation
     
    178278    rendering context.
    179279
    180     \ingroup multimedia
     280    \ingroup
    181281
    182282    A display format has several characteristics:
     
    191291    \i \link setDirectRendering() Direct rendering.\endlink
    192292    \i \link setOverlay() Presence of an overlay.\endlink
    193     \i \link setPlane() The plane of an overlay format.\endlink
     293    \i \link setPlane() .\endlink
    194294    \i \link setSampleBuffers() Multisample buffers.\endlink
    195295    \endlist
    196296
    197     You can also specify preferred bit depths for the depth buffer,
    198     alpha buffer, accumulation buffer and the stencil buffer with the
    199     functions: setDepthBufferSize(), setAlphaBufferSize(),
     297    You can also specify preferred bit depths for the color buffer,
     298    depth buffer, alpha buffer, accumulation buffer and the stencil
     299    buffer with the functions: setRedBufferSize(), setGreenBufferSize(),
     300    setBlueBufferSize(), setDepthBufferSize(), setAlphaBufferSize(),
    200301    setAccumBufferSize() and setStencilBufferSize().
    201302
     
    237338    \sa QGLContext, QGLWidget
    238339*/
     340
     341
    239342
    240343static inline void transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4])
     
    280383}
    281384
    282 /*!
    283     Constructs a QGLFormat object with the factory default settings:
     385#endif // !QT_OPENGL_ES
     386
     387/*!
     388    Constructs a QGLFormat object with the following default settings:
    284389    \list
    285390    \i \link setDoubleBuffer() Double buffer:\endlink Enabled.
     
    288393    \i \link setAlpha() Alpha channel:\endlink Disabled.
    289394    \i \link setAccum() Accumulator buffer:\endlink Disabled.
    290     \i \link setStencil() Stencil buffer:\endlink Disabled.
     395    \i \link setStencil() Stencil buffer:\endlink abled.
    291396    \i \link setStereo() Stereo:\endlink Disabled.
    292397    \i \link setDirectRendering() Direct rendering:\endlink Enabled.
     
    304409
    305410/*!
    306     Creates a QGLFormat object that is a copy of the current \link
    307     defaultFormat() application default format\endlink.
    308 
    309     If \a options is not 0, this copy is modified by these format
    310     options. The \a options parameter should be \c FormatOption values
    311     OR'ed together.
     411    Creates a QGLFormat object that is a copy of the current
     412    defaultFormat().
     413
     414    If \a options is not 0, th
     415   
     416    OR'ed together.
    312417
    313418    This constructor makes it easy to specify a certain desired format
     
    315420    \snippet doc/src/snippets/code/src_opengl_qgl.cpp 3
    316421
    317     Note that there are \c FormatOption values to turn format settings
    318     both on and off, e.g. \c DepthBuffer and \c NoDepthBuffer,
    319     \c DirectRendering and \c IndirectRendering, etc.
     422    Note that there are FormatOption values to turn format settings
     423    both on and off, e.g. NoDepthBuffer,
     424    IndirectRendering, etc.
    320425
    321426    The \a plane parameter defaults to 0 and is the plane which this
     
    323428    supports overlay/underlay rendering planes.
    324429
    325     \sa defaultFormat(), setOption()
     430    \sa defaultFormat(), setOption()
    326431*/
    327432
     
    337442
    338443/*!
     444
     445
     446
     447
     448
     449
     450
     451
     452
     453
     454
     455
     456
    339457    Constructs a copy of \a other.
    340458*/
     
    342460QGLFormat::QGLFormat(const QGLFormat &other)
    343461{
    344     d = new QGLFormatPrivate;
    345     *d = *other.d;
     462    d = ;
     463    ;
    346464}
    347465
     
    352470QGLFormat &QGLFormat::operator=(const QGLFormat &other)
    353471{
    354     *d = *other.d;
     472    if (d != other.d) {
     473        other.d->ref.ref();
     474        if (!d->ref.deref())
     475            delete d;
     476        d = other.d;
     477    }
    355478    return *this;
    356479}
     
    361484QGLFormat::~QGLFormat()
    362485{
    363     delete d;
     486    if (!d->ref.deref())
     487        delete d;
    364488}
    365489
     
    515639
    516640    Returns true if the stencil buffer is enabled; otherwise returns
    517     false. The stencil buffer is disabled by default.
     641    false. The stencil buffer is abled by default.
    518642
    519643    \sa setStencil(), setStencilBufferSize()
     
    524648    disables the stencil buffer.
    525649
    526     The stencil buffer is disabled by default.
     650    The stencil buffer is abled by default.
    527651
    528652    The stencil buffer masks certain parts of the drawing area so that
     
    637761void QGLFormat::setSamples(int numSamples)
    638762{
     763
    639764    if (numSamples < 0) {
    640765        qWarning("QGLFormat::setSamples: Cannot have negative number of samples per pixel %d", numSamples);
     
    664789void QGLFormat::setSwapInterval(int interval)
    665790{
     791
    666792    d->swapInterval = interval;
    667793}
     
    709835    formats is 1, which is the first overlay plane.
    710836
    711     \sa setPlane()
     837    \sa setPlane()
    712838*/
    713839int QGLFormat::plane() const
     
    731857void QGLFormat::setPlane(int plane)
    732858{
     859
    733860    d->pln = plane;
    734861}
     
    742869void QGLFormat::setOption(QGL::FormatOptions opt)
    743870{
     871
    744872    if (opt & 0xffff)
    745873        d->opts |= opt;
     
    771899void QGLFormat::setDepthBufferSize(int size)
    772900{
     901
    773902    if (size < 0) {
    774903        qWarning("QGLFormat::setDepthBufferSize: Cannot set negative depth buffer size %d", size);
     
    797926void QGLFormat::setRedBufferSize(int size)
    798927{
     928
    799929    if (size < 0) {
    800930        qWarning("QGLFormat::setRedBufferSize: Cannot set negative red buffer size %d", size);
     
    825955void QGLFormat::setGreenBufferSize(int size)
    826956{
     957
    827958    if (size < 0) {
    828959        qWarning("QGLFormat::setGreenBufferSize: Cannot set negative green buffer size %d", size);
     
    853984void QGLFormat::setBlueBufferSize(int size)
    854985{
     986
    855987    if (size < 0) {
    856988        qWarning("QGLFormat::setBlueBufferSize: Cannot set negative blue buffer size %d", size);
     
    8801012void QGLFormat::setAlphaBufferSize(int size)
    8811013{
     1014
    8821015    if (size < 0) {
    8831016        qWarning("QGLFormat::setAlphaBufferSize: Cannot set negative alpha buffer size %d", size);
     
    9061039void QGLFormat::setAccumBufferSize(int size)
    9071040{
     1041
    9081042    if (size < 0) {
    9091043        qWarning("QGLFormat::setAccumBufferSize: Cannot set negative accumulate buffer size %d", size);
     
    9301064void QGLFormat::setStencilBufferSize(int size)
    9311065{
     1066
    9321067    if (size < 0) {
    9331068        qWarning("QGLFormat::setStencilBufferSize: Cannot set negative stencil buffer size %d", size);
     
    11251260            return defaultVersionFlags;
    11261261        } else {
    1127             cachedDefault = true;
    11281262            if (!hasOpenGL())
    11291263                return defaultVersionFlags;
    11301264            dummy = new QGLWidget;
    11311265            dummy->makeCurrent(); // glGetString() needs a current context
     1266
    11321267        }
    11331268    }
     
    11491284
    11501285/*!
    1151     Returns the default QGLFormat for the application. All QGLWidgets
    1152     that are created use this format unless another format is
     1286    Returns the default QGLFormat for the application. All QGLWidget
     1287    that are created use this format unless another format is
    11531288    specified, e.g. when they are constructed.
    11541289
     
    11831318    Returns the default QGLFormat for overlay contexts.
    11841319
    1185     The factory default overlay format is:
     1320    The default overlay format is:
    11861321    \list
    11871322    \i \link setDoubleBuffer() Double buffer:\endlink Disabled.
     
    11941329    \i \link setDirectRendering() Direct rendering:\endlink Enabled.
    11951330    \i \link setOverlay() Overlay:\endlink Disabled.
     1331
    11961332    \i \link setPlane() Plane:\endlink 1 (i.e., first overlay plane).
    11971333    \endlist
     
    12361372
    12371373/*!
    1238     Returns true if all the options of the two QGLFormats are equal;
    1239     otherwise returns false.
     1374    Returns true if all the options of the two QGLFormat objects
     1375    \a a and \a b are equal; otherwise returns false.
     1376
     1377    \relates QGLFormat
    12401378*/
    12411379
     
    12441382    return (int) a.d->opts == (int) b.d->opts && a.d->pln == b.d->pln && a.d->alphaSize == b.d->alphaSize
    12451383        && a.d->accumSize == b.d->accumSize && a.d->stencilSize == b.d->stencilSize
    1246         && a.d->depthSize == b.d->depthSize;
    1247 }
    1248 
    1249 
    1250 /*!
    1251     Returns false if all the options of the two QGLFormats are equal;
    1252     otherwise returns true.
     1384        && a.d->depthSize == b.d->depthSize
     1385        && a.d->redSize == b.d->redSize
     1386        && a.d->greenSize == b.d->greenSize
     1387        && a.d->blueSize == b.d->blueSize
     1388        && a.d->numSamples == b.d->numSamples
     1389        && a.d->swapInterval == b.d->swapInterval;
     1390}
     1391
     1392
     1393/*!
     1394    Returns false if all the options of the two QGLFormat objects
     1395    \a a and \a b are equal; otherwise returns true.
     1396
     1397    \relates QGLFormat
    12531398*/
    12541399
     
    12611406  QGLContext implementation
    12621407 *****************************************************************************/
     1408
     1409
     1410
     1411
     1412
     1413
     1414
     1415
     1416
     1417
     1418
     1419
     1420
     1421
     1422
     1423
     1424
     1425
     1426
     1427
     1428
     1429
     1430
     1431
     1432
     1433
     1434
     1435
     1436
     1437
     1438
     1439
     1440
     1441
     1442
     1443
     1444
     1445
     1446
    12631447void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
    12641448{
     
    12891473#if defined(QT_OPENGL_ES)
    12901474    eglContext = 0;
    1291 #endif
    1292     pbo = 0;
     1475    eglSurface = EGL_NO_SURFACE;
     1476#endif
     1477    fbo = 0;
    12931478    crWin = false;
    12941479    initDone = false;
    12951480    sharing = false;
    1296     clear_on_painter_begin = true;
    12971481    max_texture_size = -1;
    12981482    version_flags_cached = false;
    12991483    version_flags = QGLFormat::OpenGL_Version_None;
     1484
     1485
     1486
    13001487}
    13011488
     
    13081495*/
    13091496
    1310 QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
    1311 {
    1312     QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32);
    1313     int w = size.width();
    1314     int h = size.height();
    1315     glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
     1497static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, bool include_alpha)
     1498{
    13161499    if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
    13171500        // OpenGL gives RGBA; Qt wants ARGB
     
    13281511            // we shouldn't remove
    13291512            while (p < end) {
    1330                 *p = 0xFF000000 | (*p>>8);
     1513                *p = 0x000000 | (*p>>8);
    13311514                ++p;
    13321515            }
     
    13341517    } else {
    13351518        // OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB
    1336         img = img.rgbSwapped();
    1337     }
    1338     return img.mirrored();
     1519        for (int y = 0; y < h; y++) {
     1520            uint *q = (uint*)img.scanLine(y);
     1521            for (int x=0; x < w; ++x) {
     1522                const uint pixel = *q;
     1523                *q = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00);
     1524                q++;
     1525            }
     1526        }
     1527
     1528    }
     1529    img = img.mirrored();
     1530}
     1531
     1532QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
     1533{
     1534    QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32);
     1535    int w = size.width();
     1536    int h = size.height();
     1537    glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
     1538    convertFromGLImage(img, w, h, alpha_format, include_alpha);
     1539    return img;
     1540}
     1541
     1542QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha)
     1543{
     1544    QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32);
     1545    int w = size.width();
     1546    int h = size.height();
     1547#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
     1548    //### glGetTexImage not in GL ES 2.0, need to do something else here!
     1549    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
     1550#endif
     1551    convertFromGLImage(img, w, h, alpha_format, include_alpha);
     1552    return img;
    13391553}
    13401554
     
    13531567}
    13541568
    1355 class QGLTexture {
    1356 public:
    1357     QGLTexture(const QGLContext *ctx, GLuint tx_id, GLenum tx_target, bool _clean = false)
    1358         : context(ctx), id(tx_id), target(tx_target), clean(_clean) {}
    1359     ~QGLTexture() {
    1360         if (clean) {
    1361             QGLContext *current = const_cast<QGLContext *>(QGLContext::currentContext());
    1362             QGLContext *ctx = const_cast<QGLContext *>(context);
    1363             bool switch_context = current && current != ctx && !qgl_share_reg()->checkSharing(current, ctx);
    1364             if (switch_context)
    1365                 ctx->makeCurrent();
    1366             glDeleteTextures(1, &id);
    1367             if (switch_context)
    1368                 current->makeCurrent();
    1369         }
    1370      }
    1371 
    1372     const QGLContext *context;
    1373     GLuint id;
    1374     GLenum target;
    1375     bool clean;
    1376 };
    1377 
    1378 typedef QCache<qint64, QGLTexture> QGLTextureCache;
    1379 static int qt_tex_cache_limit = 64*1024; // cache ~64 MB worth of textures - this is not accurate though
    1380 static QGLTextureCache *qt_tex_cache = 0;
    1381 
    13821569typedef void (*_qt_pixmap_cleanup_hook_64)(qint64);
    13831570typedef void (*_qt_image_cleanup_hook_64)(qint64);
     
    13851572extern Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64;
    13861573extern Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64;
     1574
     1575
     1576
     1577
     1578
     1579
     1580
     1581
     1582
     1583
     1584
     1585
     1586
     1587
     1588
     1589
     1590
     1591
     1592
     1593
     1594
     1595
     1596
     1597
     1598
     1599
     1600
     1601
     1602
     1603
     1604
     1605
     1606
     1607
     1608
     1609
     1610
     1611
     1612
     1613
     1614
     1615
     1616
     1617
     1618
     1619
     1620
     1621
     1622
     1623
     1624
     1625
     1626
     1627
     1628
     1629
     1630
     1631
     1632
     1633
     1634
     1635
     1636
     1637
     1638
     1639
     1640
     1641
     1642
     1643
     1644
     1645
     1646
     1647
     1648
     1649
     1650
     1651
     1652
     1653
     1654
     1655
     1656
     1657
     1658
     1659
     1660
     1661
     1662
     1663
     1664
     1665
     1666
     1667
     1668
     1669
     1670
     1671
     1672
     1673
     1674
     1675
     1676
     1677
     1678
     1679
     1680
     1681
     1682
     1683
     1684
     1685
     1686
     1687
     1688
     1689
     1690
     1691
     1692
     1693
     1694
    13871695
    13881696// DDS format structure
     
    14221730#endif
    14231731
    1424 Q_GLOBAL_STATIC(QGLShareRegister, _qgl_share_reg);
     1732Q_GLOBAL_STATIC(QGLShareRegister, _qgl_share_reg)
    14251733Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg()
    14261734{
     
    14321740    \brief The QGLContext class encapsulates an OpenGL rendering context.
    14331741
    1434     \ingroup multimedia
     1742    \ingroup
    14351743
    14361744    An OpenGL rendering context is a complete set of OpenGL state
     
    14571765*/
    14581766
     1767
     1768
     1769
     1770
     1771
     1772
     1773
     1774
     1775
     1776
     1777
     1778
     1779
     1780
     1781
     1782
     1783
     1784
     1785
     1786
     1787
     1788
     1789
     1790
     1791
     1792
     1793
     1794
     1795
     1796
     1797
     1798
     1799
     1800
     1801
     1802
     1803
     1804
     1805
     1806
     1807
    14591808
    14601809/*!
     
    14771826
    14781827QGLContext::QGLContext(const QGLFormat &format, QPaintDevice *device)
    1479 {
    1480     d_ptr = new QGLContextPrivate(this);
     1828    : d_ptr(new QGLContextPrivate(this))
     1829{
    14811830    Q_D(QGLContext);
    14821831    d->init(device, format);
     
    15001849*/
    15011850QGLContext::QGLContext(const QGLFormat &format)
    1502 {
    1503     d_ptr = new QGLContextPrivate(this);
     1851    : d_ptr(new QGLContextPrivate(this))
     1852{
    15041853    Q_D(QGLContext);
    15051854    d->init(0, format);
     
    15121861QGLContext::~QGLContext()
    15131862{
    1514     Q_D(QGLContext);
    15151863    // remove any textures cached in this context
    1516     if (qt_tex_cache) {
    1517         QList<qint64> keys = qt_tex_cache->keys();
    1518         for (int i = 0; i < keys.size(); ++i) {
    1519             const qint64 &key = keys.at(i);
    1520             if (qt_tex_cache->object(key)->context == this)
    1521                 qt_tex_cache->remove(key);
    1522         }
    1523         // ### thread safety
    1524         if (qt_tex_cache->size() == 0) {
    1525             qt_pixmap_cleanup_hook_64 = 0;
    1526             qt_image_cleanup_hook_64 = 0;
    1527             delete qt_tex_cache;
    1528             qt_tex_cache = 0;
    1529         }
    1530     }
     1864    QGLTextureCache::instance()->removeContextTextures(this);
     1865    QGLTextureCache::deleteIfEmpty(); // ### thread safety
     1866
     1867    d_ptr->group->cleanupResources(this);
    15311868
    15321869    QGLSignalProxy::instance()->emitAboutToDestroyContext(this);
    15331870    reset();
    1534     delete d;
    15351871}
    15361872
    15371873void QGLContextPrivate::cleanup()
    15381874{
    1539     Q_Q(QGLContext);
    1540     if (pbo) {
    1541         QGLContext *ctx = q;
    1542         glDeleteBuffersARB(1, &pbo);
    1543         pbo = 0;
    1544     }
    1545 }
    1546 
    1547 typedef QHash<QString, GLuint> QGLDDSCache;
    1548 Q_GLOBAL_STATIC(QGLDDSCache, qgl_dds_cache)
     1875}
    15491876
    15501877/*!
    15511878    \overload
    15521879
    1553     Reads the DirectDrawSurface (DDS) compressed file \a fileName and
    1554     generates a 2D GL texture from it.
    1555 
    1556     Only the DXT1, DXT3 and DXT5 DDS formats are supported.
    1557 
    1558     Note that this will only work if the implementation supports the
    1559     \c GL_ARB_texture_compression and \c GL_EXT_texture_compression_s3tc
    1560     extensions.
     1880    Reads the compressed texture file \a fileName and generates a 2D GL
     1881    texture from it.
     1882
     1883    This function can load DirectDrawSurface (DDS) textures in the
     1884    DXT1, DXT3 and DXT5 DDS formats if the \c GL_ARB_texture_compression
     1885    and \c GL_EXT_texture_compression_s3tc extensions are supported.
     1886
     1887    Since 4.6.1, textures in the ETC1 format can be loaded if the
     1888    \c GL_OES_compressed_ETC1_RGB8_texture extension is supported
     1889    and the ETC1 texture has been encapsulated in the PVR container format.
     1890    Also, textures in the PVRTC2 and PVRTC4 formats can be loaded
     1891    if the \c GL_IMG_texture_compression_pvrtc extension is supported.
    15611892
    15621893    \sa deleteTexture()
     
    15651896GLuint QGLContext::bindTexture(const QString &fileName)
    15661897{
    1567     if (!qt_glCompressedTexImage2DARB) {
    1568         qWarning("QGLContext::bindTexture(): The GL implementation does not support texture"
    1569                  "compression extensions.");
    1570         return 0;
    1571     }
    1572 
    1573     QGLDDSCache::const_iterator it = qgl_dds_cache()->constFind(fileName);
    1574     if (it != qgl_dds_cache()->constEnd()) {
     1898    Q_D(QGLContext);
     1899    QGLDDSCache *dds_cache = &(d->group->m_dds_cache);
     1900    QGLDDSCache::const_iterator it = dds_cache->constFind(fileName);
     1901    if (it != dds_cache->constEnd()) {
    15751902        glBindTexture(GL_TEXTURE_2D, it.value());
    15761903        return it.value();
    15771904    }
    15781905
    1579     QFile f(fileName);
    1580     f.open(QIODevice::ReadOnly);
    1581 
    1582     char tag[4];
    1583     f.read(&tag[0], 4);
    1584     if (strncmp(tag,"DDS ", 4) != 0) {
    1585         qWarning("QGLContext::bindTexture(): not a DDS image file.");
     1906    QGLTexture texture(this);
     1907    QSize size = texture.bindCompressedTexture(fileName);
     1908    if (!size.isValid())
    15861909        return 0;
    1587     }
    1588 
    1589     DDSFormat ddsHeader;
    1590     f.read((char *) &ddsHeader, sizeof(DDSFormat));
    1591 
    1592     if (!ddsHeader.dwLinearSize) {
    1593         qWarning("QGLContext::bindTexture() DDS image size is not valid.");
    1594         return 0;
    1595     }
    1596 
    1597     int factor = 4;
    1598     int bufferSize = 0;
    1599     int blockSize = 16;
    1600     GLenum format;
    1601 
    1602     switch(ddsHeader.ddsPixelFormat.dwFourCC) {
    1603     case FOURCC_DXT1:
    1604         format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
    1605         factor = 2;
    1606         blockSize = 8;
    1607         break;
    1608     case FOURCC_DXT3:
    1609         format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
    1610         break;
    1611     case FOURCC_DXT5:
    1612         format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
    1613         break;
    1614     default:
    1615         qWarning("QGLContext::bindTexture() DDS image format not supported.");
    1616         return 0;
    1617     }
    1618 
    1619     if (ddsHeader.dwMipMapCount > 1)
    1620         bufferSize = ddsHeader.dwLinearSize * factor;
    1621     else
    1622         bufferSize = ddsHeader.dwLinearSize;
    1623 
    1624     GLubyte *pixels = (GLubyte *) malloc(bufferSize*sizeof(GLubyte));
    1625     f.seek(ddsHeader.dwSize + 4);
    1626     f.read((char *) pixels, bufferSize);
    1627     f.close();
    1628 
    1629     GLuint tx_id;
    1630     glGenTextures(1, &tx_id);
    1631     glBindTexture(GL_TEXTURE_2D, tx_id);
    1632     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    1633     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    1634 
    1635     int size;
    1636     int offset = 0;
    1637     int w = ddsHeader.dwWidth;
    1638     int h = ddsHeader.dwHeight;
    1639 
    1640     // load mip-maps
    1641     for(int i = 0; i < (int) ddsHeader.dwMipMapCount; ++i) {
    1642         if (w == 0) w = 1;
    1643         if (h == 0) h = 1;
    1644 
    1645         size = ((w+3)/4) * ((h+3)/4) * blockSize;
    1646         qt_glCompressedTexImage2DARB(GL_TEXTURE_2D, i, format, w, h, 0,
    1647                                      size, pixels + offset);
    1648         offset += size;
    1649 
    1650         // half size for each mip-map level
    1651         w = w/2;
    1652         h = h/2;
    1653     }
    1654 
    1655     free(pixels);
    1656 
    1657     qgl_dds_cache()->insert(fileName, tx_id);
    1658     return tx_id;
    1659 }
    1660 
    1661 /*
    1662   a hook that removes textures from the cache when a pixmap/image
    1663   is deref'ed
    1664 */
    1665 static void qt_gl_clean_cache(qint64 cacheKey)
    1666 {
    1667     // ### remove when the GL texture cache becomes thread-safe
    1668     if (qApp->thread() != QThread::currentThread())
    1669         return;
    1670     if (qt_tex_cache) {
    1671         QGLTexture *texture = qt_tex_cache->object(cacheKey);
    1672         if (texture && texture->clean)
    1673             qt_tex_cache->remove(cacheKey);
    1674     }
     1910
     1911    dds_cache->insert(fileName, texture.id);
     1912    return texture.id;
     1913}
     1914
     1915static inline QRgb qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture_format)
     1916{
     1917    if (texture_format == GL_BGRA) {
     1918        if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
     1919            return ((src_pixel << 24) & 0xff000000)
     1920                   | ((src_pixel >> 24) & 0x000000ff)
     1921                   | ((src_pixel << 8) & 0x00ff0000)
     1922                   | ((src_pixel >> 8) & 0x0000ff00);
     1923        } else {
     1924            return src_pixel;
     1925        }
     1926    } else {  // GL_RGBA
     1927        if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
     1928            return (src_pixel << 8) | ((src_pixel >> 24) & 0xff);
     1929        } else {
     1930            return ((src_pixel << 16) & 0xff0000)
     1931                   | ((src_pixel >> 16) & 0xff)
     1932                   | (src_pixel & 0xff00ff00);
     1933        }
     1934    }
     1935}
     1936
     1937QRgb qt_gl_convertToGLFormat(QRgb src_pixel, GLenum texture_format)
     1938{
     1939    return qt_gl_convertToGLFormatHelper(src_pixel, texture_format);
    16751940}
    16761941
    16771942static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum texture_format)
    16781943{
    1679     Q_ASSERT(dst.size() == img.size());
    16801944    Q_ASSERT(dst.depth() == 32);
    16811945    Q_ASSERT(img.depth() == 32);
    16821946
    1683     const int width = img.width();
    1684     const int height = img.height();
    1685     const uint *p = (const uint*) img.scanLine(img.height() - 1);
    1686     uint *q = (uint*) dst.scanLine(0);
    1687 
    1688     if (texture_format == GL_BGRA) {
    1689         if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
    1690             // mirror + swizzle
    1691             for (int i=0; i < height; ++i) {
    1692                 const uint *end = p + width;
    1693                 while (p < end) {
    1694                     *q = ((*p << 24) & 0xff000000)
    1695                          | ((*p >> 24) & 0x000000ff)
    1696                          | ((*p << 8) & 0x00ff0000)
    1697                          | ((*p >> 8) & 0x0000ff00);
    1698                     p++;
    1699                     q++;
     1947    if (dst.size() != img.size()) {
     1948        int target_width = dst.width();
     1949        int target_height = dst.height();
     1950        qreal sx = target_width / qreal(img.width());
     1951        qreal sy = target_height / qreal(img.height());
     1952
     1953        quint32 *dest = (quint32 *) dst.scanLine(0); // NB! avoid detach here
     1954        uchar *srcPixels = (uchar *) img.scanLine(img.height() - 1);
     1955        int sbpl = img.bytesPerLine();
     1956        int dbpl = dst.bytesPerLine();
     1957
     1958        int ix = int(0x00010000 / sx);
     1959        int iy = int(0x00010000 / sy);
     1960
     1961        quint32 basex = int(0.5 * ix);
     1962        quint32 srcy = int(0.5 * iy);
     1963
     1964        // scale, swizzle and mirror in one loop
     1965        while (target_height--) {
     1966            const uint *src = (const quint32 *) (srcPixels - (srcy >> 16) * sbpl);
     1967            int srcx = basex;
     1968            for (int x=0; x<target_width; ++x) {
     1969                dest[x] = qt_gl_convertToGLFormatHelper(src[srcx >> 16], texture_format);
     1970                srcx += ix;
     1971            }
     1972            dest = (quint32 *)(((uchar *) dest) + dbpl);
     1973            srcy += iy;
     1974        }
     1975    } else {
     1976        const int width = img.width();
     1977        const int height = img.height();
     1978        const uint *p = (const uint*) img.scanLine(img.height() - 1);
     1979        uint *q = (uint*) dst.scanLine(0);
     1980
     1981        if (texture_format == GL_BGRA) {
     1982            if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
     1983                // mirror + swizzle
     1984                for (int i=0; i < height; ++i) {
     1985                    const uint *end = p + width;
     1986                    while (p < end) {
     1987                        *q = ((*p << 24) & 0xff000000)
     1988                             | ((*p >> 24) & 0x000000ff)
     1989                             | ((*p << 8) & 0x00ff0000)
     1990                             | ((*p >> 8) & 0x0000ff00);
     1991                        p++;
     1992                        q++;
     1993                    }
     1994                    p -= 2 * width;
    17001995                }
    1701                 p -= 2 * width;
     1996            } else {
     1997                const uint bytesPerLine = img.bytesPerLine();
     1998                for (int i=0; i < height; ++i) {
     1999                    memcpy(q, p, bytesPerLine);
     2000                    q += width;
     2001                    p -= width;
     2002                }
    17022003            }
    17032004        } else {
    1704             const uint bytesPerLine = img.bytesPerLine();
    1705             for (int i=0; i < height; ++i) {
    1706                 memcpy(q, p, bytesPerLine);
    1707                 q += width;
    1708                 p -= width;
    1709             }
    1710         }
    1711     } else {
    1712         if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
    1713             for (int i=0; i < height; ++i) {
    1714                 const uint *end = p + width;
    1715                 while (p < end) {
    1716                     *q = (*p << 8) | ((*p >> 24) & 0xFF);
    1717                     p++;
    1718                     q++;
     2005            if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
     2006                for (int i=0; i < height; ++i) {
     2007                    const uint *end = p + width;
     2008                    while (p < end) {
     2009                        *q = (*p << 8) | ((*p >> 24) & 0xff);
     2010                        p++;
     2011                        q++;
     2012                    }
     2013                    p -= 2 * width;
    17192014                }
    1720                 p -= 2 * width;
    1721             }
    1722         } else {
    1723             for (int i=0; i < height; ++i) {
    1724                 const uint *end = p + width;
    1725                 while (p < end) {
    1726                     *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
    1727                     p++;
    1728                     q++;
     2015           
     2016           
     2017       
     2018            ) {
     2019                ;
     2020               
     2021                    ;
     2022                   
     2023                    ;
    17292024                }
    1730                 p -= 2 * width;
    17312025            }
    17322026        }
     
    17462040}
    17472041
    1748 GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format,
    1749                                       const qint64 key, bool clean)
     2042/*! \internal */
     2043QGLTexture *QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format,
     2044                                           QGLContext::BindOptions options)
     2045{
     2046    const qint64 key = image.cacheKey();
     2047    QGLTexture *texture = textureCacheLookup(key, target);
     2048    if (texture) {
     2049        glBindTexture(target, texture->id);
     2050        return texture;
     2051    }
     2052
     2053    if (!texture)
     2054        texture = bindTexture(image, target, format, key, options);
     2055    // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null
     2056    Q_ASSERT(texture);
     2057
     2058    if (texture->id > 0)
     2059        QImagePixmapCleanupHooks::enableCleanupHooks(image);
     2060
     2061    return texture;
     2062}
     2063
     2064// #define QGL_BIND_TEXTURE_DEBUG
     2065
     2066// map from Qt's ARGB endianness-dependent format to GL's big-endian RGBA layout
     2067static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
     2068{
     2069    const int width = img.width();
     2070    const int height = img.height();
     2071
     2072    if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV
     2073        || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian))
     2074    {
     2075        for (int i = 0; i < height; ++i) {
     2076            uint *p = (uint *) img.scanLine(i);
     2077            for (int x = 0; x < width; ++x)
     2078                p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
     2079        }
     2080    } else {
     2081        for (int i = 0; i < height; ++i) {
     2082            uint *p = (uint *) img.scanLine(i);
     2083            for (int x = 0; x < width; ++x)
     2084                p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff);
     2085        }
     2086    }
     2087}
     2088
     2089QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint internalFormat,
     2090                                           const qint64 key, QGLContext::BindOptions options)
    17502091{
    17512092    Q_Q(QGLContext);
    17522093
    1753     QGLContext *ctx = q;
    1754 
    1755     bool use_pbo = false;
    1756     if (QGLExtensions::glExtensions & QGLExtensions::PixelBufferObject) {
    1757 
    1758         use_pbo = qt_resolve_buffer_extensions(ctx);
    1759         if (use_pbo && pbo == 0)
    1760             glGenBuffersARB(1, &pbo);
    1761     }
    1762 
    1763     // the GL_BGRA format is only present in GL version >= 1.2
    1764     GLenum texture_format = (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2)
    1765                             ? GL_BGRA : GL_RGBA;
    1766     if (!qt_tex_cache) {
    1767         qt_tex_cache = new QGLTextureCache(qt_tex_cache_limit);
    1768         qt_pixmap_cleanup_hook_64 = qt_gl_clean_cache;
    1769         qt_image_cleanup_hook_64 = qt_gl_clean_cache;
    1770     }
     2094#ifdef QGL_BIND_TEXTURE_DEBUG
     2095    printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x\n",
     2096           image.width(), image.height(), internalFormat, int(options));
     2097    QTime time;
     2098    time.start();
     2099#endif
     2100
     2101#ifndef QT_NO_DEBUG
     2102    // Reset the gl error stack...git
     2103    while (glGetError() != GL_NO_ERROR) ;
     2104#endif
    17712105
    17722106    // Scale the pixmap if needed. GL textures needs to have the
    1773     // dimensions 2^n+2(border) x 2^m+2(border).
     2107    // dimensions 2^n+2(border) x 2^m+2(border), unless we're using GL
     2108    // 2.0 or use the GL_TEXTURE_RECTANGLE texture target
    17742109    int tx_w = qt_next_power_of_two(image.width());
    17752110    int tx_h = qt_next_power_of_two(image.height());
    17762111
    1777     // Note: the clean param is only true when a texture is bound
    1778     // from the QOpenGLPaintEngine - in that case we have to force
    1779     // a premultiplied texture format
    17802112    QImage img = image;
    1781     if (( !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) &&
    1782           !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0) )
     2113    if (
     2114        )
    17832115        && (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height())))
    17842116    {
    1785         img = image.scaled(tx_w, tx_h);
    1786     }
     2117        img = img.scaled(tx_w, tx_h);
     2118#ifdef QGL_BIND_TEXTURE_DEBUG
     2119        printf(" - upscaled to %dx%d (%d ms)\n", tx_w, tx_h, time.elapsed());
     2120
     2121#endif
     2122    }
     2123
     2124    GLuint filtering = options & QGLContext::LinearFilteringBindOption ? GL_LINEAR : GL_NEAREST;
    17872125
    17882126    GLuint tx_id;
    17892127    glGenTextures(1, &tx_id);
    17902128    glBindTexture(target, tx_id);
    1791     glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     2129    glTexParameterf(target, GL_TEXTURE_MAG_FILTER, filtering);
     2130
     2131#if defined(QT_OPENGL_ES_2)
     2132    bool genMipmap = false;
     2133#endif
    17922134    if (glFormat.directRendering()
    1793         && QGLExtensions::glExtensions & QGLExtensions::GenerateMipmap
    1794         && target == GL_TEXTURE_2D && !clean)
     2135        && (QGLExtensions::glExtensions & QGLExtensions::GenerateMipmap)
     2136        && target == GL_TEXTURE_2D
     2137        && (options & QGLContext::MipmapBindOption))
    17952138    {
     2139
     2140
     2141
     2142
    17962143        glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
    17972144#ifndef QT_OPENGL_ES
     
    18002147        glTexParameterf(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
    18012148#endif
    1802         glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    1803 
    1804         // Mipmap generation causes huge slowdown with PBO's for some reason
    1805         use_pbo = false;
     2149#else
     2150        glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
     2151        genMipmap = true;
     2152#endif
     2153        glTexParameterf(target, GL_TEXTURE_MIN_FILTER, options & QGLContext::LinearFilteringBindOption
     2154                        ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST);
    18062155    } else {
    1807         glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    1808     }
    1809 
    1810     uchar *ptr = 0;
    1811     if (use_pbo) {
    1812         glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
    1813         glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, img.width() * img.height() * 4, 0, GL_STREAM_DRAW_ARB);
    1814         ptr = reinterpret_cast<uchar *>(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB));
    1815     }
    1816 
    1817     if (ptr) {
    1818         QImage::Format target_format = img.format();
    1819         if (clean || img.format() != QImage::Format_ARGB32)
    1820             target_format = QImage::Format_ARGB32_Premultiplied;
    1821 
    1822         QImage buffer(ptr, img.width(), img.height(), target_format);
    1823         convertToGLFormatHelper(buffer, img.convertToFormat(target_format), texture_format);
    1824         glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
    1825         glTexImage2D(target, 0, format, img.width(), img.height(), 0, texture_format, GL_UNSIGNED_BYTE, 0);
     2156        glTexParameterf(target, GL_TEXTURE_MIN_FILTER, filtering);
     2157    }
     2158
     2159    QImage::Format target_format = img.format();
     2160    bool premul = options & QGLContext::PremultipliedAlphaBindOption;
     2161    GLenum externalFormat;
     2162    GLuint pixel_type;
     2163    if (QGLExtensions::glExtensions & QGLExtensions::BGRATextureFormat) {
     2164        externalFormat = GL_BGRA;
     2165        pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV;
    18262166    } else {
    1827         QImage tx = convertToGLFormat(img, clean, texture_format);
    1828         glTexImage2D(target, 0, format, tx.width(), tx.height(), 0, texture_format,
    1829                      GL_UNSIGNED_BYTE, tx.bits());
    1830     }
    1831 
    1832     if (use_pbo)
    1833         glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
     2167        externalFormat = GL_RGBA;
     2168        pixel_type = GL_UNSIGNED_BYTE;
     2169    }
     2170
     2171    switch (target_format) {
     2172    case QImage::Format_ARGB32:
     2173        if (premul) {
     2174            img = img.convertToFormat(target_format = QImage::Format_ARGB32_Premultiplied);
     2175#ifdef QGL_BIND_TEXTURE_DEBUG
     2176            printf(" - converting ARGB32 -> ARGB32_Premultiplied (%d ms) \n", time.elapsed());
     2177#endif
     2178        }
     2179        break;
     2180    case QImage::Format_ARGB32_Premultiplied:
     2181        if (!premul) {
     2182            img = img.convertToFormat(target_format = QImage::Format_ARGB32);
     2183#ifdef QGL_BIND_TEXTURE_DEBUG
     2184            printf(" - converting ARGB32_Premultiplied -> ARGB32 (%d ms)\n", time.elapsed());
     2185#endif
     2186        }
     2187        break;
     2188    case QImage::Format_RGB16:
     2189        pixel_type = GL_UNSIGNED_SHORT_5_6_5;
     2190        externalFormat = GL_RGB;
     2191        internalFormat = GL_RGB;
     2192        break;
     2193    case QImage::Format_RGB32:
     2194        break;
     2195    default:
     2196        if (img.hasAlphaChannel()) {
     2197            img = img.convertToFormat(premul
     2198                                      ? QImage::Format_ARGB32_Premultiplied
     2199                                      : QImage::Format_ARGB32);
     2200#ifdef QGL_BIND_TEXTURE_DEBUG
     2201            printf(" - converting to 32-bit alpha format (%d ms)\n", time.elapsed());
     2202#endif
     2203        } else {
     2204            img = img.convertToFormat(QImage::Format_RGB32);
     2205#ifdef QGL_BIND_TEXTURE_DEBUG
     2206            printf(" - converting to 32-bit (%d ms)\n", time.elapsed());
     2207#endif
     2208        }
     2209    }
     2210
     2211    if (options & QGLContext::InvertedYBindOption) {
     2212#ifdef QGL_BIND_TEXTURE_DEBUG
     2213            printf(" - flipping bits over y (%d ms)\n", time.elapsed());
     2214#endif
     2215        if (img.isDetached()) {
     2216            int ipl = img.bytesPerLine() / 4;
     2217            int h = img.height();
     2218            for (int y=0; y<h/2; ++y) {
     2219                int *a = (int *) img.scanLine(y);
     2220                int *b = (int *) img.scanLine(h - y - 1);
     2221                for (int x=0; x<ipl; ++x)
     2222                    qSwap(a[x], b[x]);
     2223            }
     2224        } else {
     2225            // Create a new image and copy across.  If we use the
     2226            // above in-place code then a full copy of the image is
     2227            // made before the lines are swapped, which processes the
     2228            // data twice.  This version should only do it once.
     2229            img = img.mirrored();
     2230        }
     2231    }
     2232
     2233    if (externalFormat == GL_RGBA) {
     2234#ifdef QGL_BIND_TEXTURE_DEBUG
     2235            printf(" - doing byte swapping (%d ms)\n", time.elapsed());
     2236#endif
     2237        // The only case where we end up with a depth different from
     2238        // 32 in the switch above is for the RGB16 case, where we set
     2239        // the format to GL_RGB
     2240        Q_ASSERT(img.depth() == 32);
     2241        qgl_byteSwapImage(img, pixel_type);
     2242    }
     2243#ifdef QT_OPENGL_ES
     2244    // OpenGL/ES requires that the internal and external formats be identical.
     2245    // This is typically used to convert GL_RGBA into GL_BGRA.
     2246    // Also, we need to use GL_UNSIGNED_BYTE when the format is GL_BGRA.
     2247    internalFormat = externalFormat;
     2248    if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV)
     2249        pixel_type = GL_UNSIGNED_BYTE;
     2250#endif
     2251#ifdef QGL_BIND_TEXTURE_DEBUG
     2252    printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n",
     2253           img.format(), externalFormat, internalFormat, pixel_type);
     2254#endif
     2255
     2256    const QImage &constRef = img; // to avoid detach in bits()...
     2257    glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
     2258                 pixel_type, constRef.bits());
     2259#if defined(QT_OPENGL_ES_2)
     2260    if (genMipmap)
     2261        glGenerateMipmap(target);
     2262#endif
     2263#ifndef QT_NO_DEBUG
     2264    GLenum error = glGetError();
     2265    if (error != GL_NO_ERROR) {
     2266        qWarning(" - texture upload failed, error code 0x%x\n", error);
     2267    }
     2268#endif
     2269
     2270#ifdef QGL_BIND_TEXTURE_DEBUG
     2271    static int totalUploadTime = 0;
     2272    totalUploadTime += time.elapsed();
     2273    printf(" - upload done in (%d ms) time=%d\n", time.elapsed(), totalUploadTime);
     2274#endif
     2275
    18342276
    18352277    // this assumes the size of a texture is always smaller than the max cache size
    18362278    int cost = img.width()*img.height()*4/1024;
    1837     if (qt_tex_cache->totalCost() + cost > qt_tex_cache->maxCost()) {
    1838         // the cache is full - make an attempt to remove something
    1839         const QList<qint64> keys = qt_tex_cache->keys();
    1840         int i = 0;
    1841         while (i < qt_tex_cache->count()
    1842                && (qt_tex_cache->totalCost() + cost > qt_tex_cache->maxCost())) {
    1843             QGLTexture *tex = qt_tex_cache->object(keys.at(i));
    1844             if (tex->context == q)
    1845                 qt_tex_cache->remove(keys.at(i));
    1846             ++i;
     2279    QGLTexture *texture = new QGLTexture(q, tx_id, target, options);
     2280    QGLTextureCache::instance()->insert(q, key, texture, cost);
     2281    return texture;
     2282}
     2283
     2284QGLTexture *QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum target)
     2285{
     2286    Q_Q(QGLContext);
     2287    QGLTexture *texture = QGLTextureCache::instance()->getTexture(key);
     2288    if (texture && texture->target == target
     2289        && (texture->context == q || QGLContext::areSharing(q, texture->context)))
     2290    {
     2291        return texture;
     2292    }
     2293    return 0;
     2294}
     2295
     2296
     2297/*! \internal */
     2298QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, QGLContext::BindOptions options)
     2299{
     2300    Q_Q(QGLContext);
     2301    QPixmapData *pd = pixmap.pixmapData();
     2302#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
     2303    if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) {
     2304        const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pd);
     2305
     2306        if (data->isValidContext(q)) {
     2307            data->bind();
     2308            return data->texture();
    18472309        }
    18482310    }
    1849     qt_tex_cache->insert(key, new QGLTexture(q, tx_id, target, clean), cost);
    1850     return tx_id;
    1851 }
    1852 
    1853 bool QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum target, GLuint *id)
    1854 {
    1855     Q_Q(QGLContext);
    1856     if (qt_tex_cache) {
    1857         QGLTexture *texture = qt_tex_cache->object(key);
    1858         if (texture && texture->target == target
    1859             && (texture->context == q || qgl_share_reg()->checkSharing(q, texture->context)))
    1860         {
    1861             *id = texture->id;
    1862             return true;
     2311#else
     2312    Q_UNUSED(pd);
     2313    Q_UNUSED(q);
     2314#endif
     2315
     2316    const qint64 key = pixmap.cacheKey();
     2317    QGLTexture *texture = textureCacheLookup(key, target);
     2318    if (texture) {
     2319        glBindTexture(target, texture->id);
     2320        return texture;
     2321    }
     2322
     2323#if defined(Q_WS_X11)
     2324    // Try to use texture_from_pixmap
     2325    if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType) {
     2326        texture = bindTextureFromNativePixmap(pd, key, options);
     2327        if (texture) {
     2328            texture->options |= QGLContext::MemoryManagedBindOption;
     2329            texture->boundPixmap = pd;
     2330            boundPixmaps.insert(pd, QPixmap(pixmap));
    18632331        }
    18642332    }
    1865     return false;
    1866 }
    1867 
    1868 /*! \internal */
    1869 GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format, bool clean)
    1870 {
    1871     const qint64 key = image.cacheKey();
    1872     GLuint id;
    1873     if (textureCacheLookup(key, target, &id)) {
    1874         glBindTexture(target, id);
    1875         return id;
    1876     }
    1877     GLuint cached = bindTexture(image, target, format, key, clean);
    1878     const_cast<QImage &>(image).data_ptr()->is_cached = (cached > 0);
    1879     return cached;
    1880 }
    1881 
    1882 /*! \internal */
    1883 GLuint QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, bool clean)
    1884 {
    1885 #if !defined(QT_OPENGL_ES_2)
    1886     if (target == qt_gl_preferredTextureTarget() && pixmap.pixmapData()->classId() == QPixmapData::OpenGLClass) {
    1887         const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pixmap.pixmapData());
    1888 
    1889         if (data->isValidContext(QGLContext::currentContext()))
    1890             return data->bind();
    1891     }
    1892 #endif
    1893 
    1894     const qint64 key = pixmap.cacheKey();
    1895     GLuint id;
    1896     if (textureCacheLookup(key, target, &id)) {
    1897         glBindTexture(target, id);
    1898         return id;
    1899     }
    1900     GLuint cached = bindTexture(pixmap.toImage(), target, format, key, clean);
    1901     const_cast<QPixmap &>(pixmap).data_ptr()->is_cached = (cached > 0);
    1902     return cached;
     2333#endif
     2334
     2335    if (!texture)
     2336        texture = bindTexture(pixmap.toImage(), target, format, key, options);
     2337    // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null
     2338    Q_ASSERT(texture);
     2339
     2340    if (texture->id > 0)
     2341        QImagePixmapCleanupHooks::enableCleanupHooks(pixmap);
     2342
     2343    return texture;
    19032344}
    19042345
     
    19392380
    19402381/*!
     2382
     2383
     2384
     2385
     2386
     2387
     2388
     2389
     2390
     2391
     2392
     2393
     2394
     2395
     2396
     2397
     2398
     2399
     2400
    19412401    Generates and binds a 2D GL texture to the current context, based
    19422402    on \a image. The generated texture id is returned and can be used
     
    19472407
    19482408    The \a format parameter sets the internal format for the
    1949     texture. The default format is \c GL_RGBA8.
    1950 
    1951     If the GL implementation supports the \c GL_SGIS_generate_mipmap
    1952     extension, mipmaps will be automatically generated for the
    1953     texture. Mipmap generation is only supported for the \c
    1954     GL_TEXTURE_2D target.
     2409    texture. The default format is \c GL_RGBA.
     2410
     2411    The binding \a options are a set of options used to decide how to
     2412    bind the texture to the context.
    19552413
    19562414    The texture that is generated is cached, so multiple calls to
     
    19632421    \sa deleteTexture()
    19642422*/
    1965 GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format)
    1966 {
     2423GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format, BindOptions options)
     2424{
     2425    if (image.isNull())
     2426        return 0;
     2427
    19672428    Q_D(QGLContext);
    1968     return d->bindTexture(image, target, format, false);
     2429    QGLTexture *texture = d->bindTexture(image, target, format, false, options);
     2430    return texture->id;
    19692431}
    19702432
     
    19732435GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format)
    19742436{
     2437
     2438
     2439
    19752440    Q_D(QGLContext);
    1976     return d->bindTexture(image, GLenum(target), GLint(format), false);
     2441    QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false, DefaultBindOption);
     2442    return texture->id;
     2443}
     2444
     2445/*! \internal */
     2446GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format,
     2447                               BindOptions options)
     2448{
     2449    if (image.isNull())
     2450        return 0;
     2451
     2452    Q_D(QGLContext);
     2453    QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false, options);
     2454    return texture->id;
    19772455}
    19782456#endif
     
    19842462GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint format)
    19852463{
     2464
     2465
     2466
    19862467    Q_D(QGLContext);
    1987     return d->bindTexture(pixmap, target, format, false);
     2468    QGLTexture *texture = d->bindTexture(pixmap, target, format, DefaultBindOption);
     2469    return texture->id;
     2470}
     2471
     2472/*!
     2473  \overload
     2474  \since 4.6
     2475
     2476  Generates and binds a 2D GL texture to the current context, based
     2477  on \a pixmap.
     2478*/
     2479GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, BindOptions options)
     2480{
     2481    if (pixmap.isNull())
     2482        return 0;
     2483
     2484    Q_D(QGLContext);
     2485    QGLTexture *texture = d->bindTexture(pixmap, target, format, options);
     2486    return texture->id;
    19882487}
    19892488
     
    19922491GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format)
    19932492{
     2493
     2494
     2495
    19942496    Q_D(QGLContext);
    1995     return d->bindTexture(pixmap, GLenum(target), GLint(format), false);
     2497    QGLTexture *texture = d->bindTexture(pixmap, GLenum(target), GLint(format), DefaultBindOption);
     2498    return texture->id;
     2499}
     2500/*! \internal */
     2501GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format,
     2502                               BindOptions options)
     2503{
     2504    if (pixmap.isNull())
     2505        return 0;
     2506
     2507    Q_D(QGLContext);
     2508    QGLTexture *texture = d->bindTexture(pixmap, GLenum(target), GLint(format), options);
     2509    return texture->id;
    19962510}
    19972511#endif
     
    20062520void QGLContext::deleteTexture(GLuint id)
    20072521{
    2008     if (qt_tex_cache) {
    2009         QList<qint64> keys = qt_tex_cache->keys();
    2010         for (int i = 0; i < keys.size(); ++i) {
    2011             QGLTexture *tex = qt_tex_cache->object(keys.at(i));
    2012             if (tex->id == id && tex->context == this) {
    2013                 tex->clean = true; // forces a glDeleteTextures() call
    2014                 qt_tex_cache->remove(keys.at(i));
    2015                 return;
    2016             }
    2017         }
    2018     }
     2522    Q_D(QGLContext);
     2523
     2524    if (QGLTextureCache::instance()->remove(this, id))
     2525        return;
    20192526
    20202527    // check the DDS cache if the texture wasn't found in the pixmap/image
    20212528    // cache
    2022     QList<QString> ddsKeys = qgl_dds_cache()->keys();
     2529    QGLDDSCache *dds_cache = &(d->group->m_dds_cache);
     2530    QList<QString> ddsKeys = dds_cache->keys();
    20232531    for (int i = 0; i < ddsKeys.size(); ++i) {
    2024         GLuint texture = qgl_dds_cache()->value(ddsKeys.at(i));
     2532        GLuint texture = ->value(ddsKeys.at(i));
    20252533        if (id == texture) {
    20262534            glDeleteTextures(1, &texture);
    2027             qgl_dds_cache()->remove(ddsKeys.at(i));
     2535            ->remove(ddsKeys.at(i));
    20282536            return;
    20292537        }
     
    20392547#endif
    20402548
    2041 // qpaintengine_opengl.cpp
     2549void qt_add_rect_to_array(const QRectF &r, q_vertexType *array)
     2550{
     2551    qreal left = r.left();
     2552    qreal right = r.right();
     2553    qreal top = r.top();
     2554    qreal bottom = r.bottom();
     2555
     2556    array[0] = f2vt(left);
     2557    array[1] = f2vt(top);
     2558    array[2] = f2vt(right);
     2559    array[3] = f2vt(top);
     2560    array[4] = f2vt(right);
     2561    array[5] = f2vt(bottom);
     2562    array[6] = f2vt(left);
     2563    array[7] = f2vt(bottom);
     2564}
     2565
     2566void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array)
     2567{
     2568    array[0] = f2vt(x1);
     2569    array[1] = f2vt(y1);
     2570    array[2] = f2vt(x2);
     2571    array[3] = f2vt(y1);
     2572    array[4] = f2vt(x2);
     2573    array[5] = f2vt(y2);
     2574    array[6] = f2vt(x1);
     2575    array[7] = f2vt(y2);
     2576}
     2577
    20422578#if !defined(QT_OPENGL_ES_2)
    2043 extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array);
    2044 #else
    2045 void qt_add_rect_to_array(const QRectF &r, q_vertexType *array) {};
    2046 #endif
    20472579
    20482580static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint textureHeight, GLenum textureTarget)
     
    20742606    qt_add_rect_to_array(target, vertexArray);
    20752607
    2076 #if !defined(QT_OPENGL_ES_2)
    20772608    glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);
    20782609    glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray);
     
    20842615    glDisableClientState(GL_VERTEX_ARRAY);
    20852616    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    2086 #endif
    2087 }
     2617}
     2618
     2619#endif // !QT_OPENGL_ES_2
    20882620
    20892621/*!
     
    20942626    texture target.
    20952627
    2096     Equivalent to the corresponding QGLContext::drawTexture().
     2628    .
    20972629*/
    20982630void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget)
    20992631{
     2632
    21002633#ifdef QT_OPENGL_ES
    21012634    if (textureTarget != GL_TEXTURE_2D) {
     
    21212654    glBindTexture(textureTarget, oldTexture);
    21222655#endif
     2656
     2657
     2658
     2659
     2660
     2661
    21232662}
    21242663
     
    21372676    space. The \a textureTarget should be a 2D texture target.
    21382677
    2139     Equivalent to the corresponding QGLContext::drawTexture().
     2678    .
    21402679*/
    21412680void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget)
     
    21882727void QGLContext::setTextureCacheLimit(int size)
    21892728{
    2190     qt_tex_cache_limit = size;
    2191     if (qt_tex_cache)
    2192         qt_tex_cache->setMaxCost(qt_tex_cache_limit);
     2729    QGLTextureCache::instance()->setMaxCost(size);
    21932730}
    21942731
     
    22002737int QGLContext::textureCacheLimit()
    22012738{
    2202     return qt_tex_cache_limit;
     2739    return ;
    22032740}
    22042741
     
    22792816    formats.
    22802817*/
     2818
     2819
     2820
     2821
     2822
     2823
     2824
     2825
     2826
     2827
     2828
     2829
     2830
     2831
    22812832
    22822833/*!
     
    23992950    reset();
    24002951    d->valid = chooseContext(shareContext);
     2952
     2953
     2954
     2955
    24012956    if (d->sharing)  // ok, we managed to share
    24022957        qgl_share_reg()->addShare(this, shareContext);
     
    24192974{
    24202975    Q_D(const QGLContext);
    2421     return d->sharing;
     2976    return d->;
    24222977}
    24232978
     
    24743029const QGLContext* QGLContext::currentContext()
    24753030{
    2476     if (qgl_context_storage.hasLocalData())
    2477         return qgl_context_storage.localData()->context;
     3031    QGLThreadContext *threadContext = qgl_context_storage.localData();
     3032    if (threadContext)
     3033        return threadContext->context;
    24783034    return 0;
     3035
     3036
     3037
     3038
     3039
     3040
     3041
     3042
     3043
     3044
     3045
     3046
     3047
     3048
     3049
     3050
    24793051}
    24803052
     
    24933065*/
    24943066
     3067
     3068
     3069
     3070
     3071
     3072
     3073
     3074
     3075
     3076
     3077
     3078
     3079
     3080
     3081
     3082
     3083
     3084
     3085
     3086
     3087
     3088
     3089
     3090
     3091
     3092
     3093
     3094
     3095
     3096
     3097
     3098
     3099
     3100
     3101
     3102
    24953103
    24963104/*!
     
    25613169    \brief The QGLWidget class is a widget for rendering OpenGL graphics.
    25623170
    2563     \ingroup multimedia
    2564     \mainclass
     3171    \ingroup
     3172
    25653173
    25663174    QGLWidget provides functionality for displaying OpenGL graphics
     
    25773185    needs to be updated.
    25783186    \i resizeGL() - Sets up the OpenGL viewport, projection, etc. Gets
    2579     called whenever the the widget has been resized (and also when it
     3187    called whenever the widget has been resized (and also when it
    25803188    is shown for the first time because all newly created widgets get a
    25813189    resize event automatically).
     
    26033211    customized rendering \link QGLContext contexts\endlink.
    26043212
    2605     You can also share OpenGL display lists between QGLWidgets (see
     3213    You can also share OpenGL display lists between QGLWidgets (see
    26063214    the documentation of the QGLWidget constructors for details).
    26073215
     
    28853493    Returns true if this widget's GL context is shared with another GL
    28863494    context, otherwise false is returned. Context sharing might not be
    2887     possible if the QGLWidgets use different formats.
     3495    possible if the idgets use different formats.
    28883496
    28893497    \sa format()
     
    29833591
    29843592  This method will try to keep display list and texture object sharing
    2985   in effect with other QGLWidgets, but changing the format might make
     3593  in effect with other QGLWidgets, but changing the format might make
    29863594  sharing impossible. Use isSharing() to see if sharing is still in
    29873595  effect.
     
    30093617
    30103618/*
     3619
     3620
     3621
    30113622  \obsolete
    3012 
    3013   \fn void QGLWidget::setContext(QGLContext *context,
    3014                                   const QGLContext* shareContext,
    3015                                   bool deleteOldContext)
    30163623
    30173624  Sets a new context for this widget. The QGLContext \a context must
     
    31633770}
    31643771
    3165 
     3772/*! \fn bool QGLWidget::event(QEvent *e)
     3773  \reimp
     3774*/
    31663775#if !defined(Q_OS_WINCE) && !defined(Q_WS_QWS)
    3167 /*! \reimp */
    31683776bool QGLWidget::event(QEvent *e)
    31693777{
     
    31913799        doneCurrent();
    31923800    } else if (e->type() == QEvent::ParentChange) {
    3193         if (d->glcx->d_func()->screen != d->xinfo.screen()) {
     3801        // if we've reparented a window that has the current context
     3802        // bound, we need to rebind that context to the new window id
     3803        if (d->glcx == QGLContext::currentContext())
     3804            makeCurrent();
     3805
     3806        if (d->glcx->d_func()->screen != d->xinfo.screen() || testAttribute(Qt::WA_TranslucentBackground)) {
    31943807            setContext(new QGLContext(d->glcx->requestedFormat(), this));
    31953808            // ### recreating the overlay isn't supported atm
    31963809        }
     3810
     3811
    31973812#if defined(QT_OPENGL_ES)
    3198         // The window may have been re-created during re-parent - if so, the EGL
     3813    // A re-parent is likely to destroy the X11 window and re-create it. It is important
     3814    // that we free the EGL surface _before_ the winID changes - otherwise we can leak.
     3815    if (e->type() == QEvent::ParentAboutToChange)
     3816        d->glcx->d_func()->destroyEglSurfaceForDevice();
     3817
     3818    if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) {
     3819        // The window may have been re-created during re-parent or state change - if so, the EGL
    31993820        // surface will need to be re-created.
    32003821        d->recreateEglSurface(false);
    3201 #endif
    3202     }
     3822    }
     3823#endif
    32033824#elif defined(Q_WS_WIN)
    32043825    if (e->type() == QEvent::ParentChange) {
    32053826        QGLContext *newContext = new QGLContext(d->glcx->requestedFormat(), this);
    3206         qgl_share_reg()->replaceShare(d->glcx, newContext);
    3207         setContext(newContext);
     3827        );
     3828
    32083829        // the overlay needs to be recreated as well
    32093830        delete d->olcx;
     
    32843905    Renders the current scene on a pixmap and returns the pixmap.
    32853906
    3286     You can use this method on both visible and invisible QGLWidgets.
     3907    You can use this method on both visible and invisible QGLWidgets.
    32873908
    32883909    This method will create a pixmap and a temporary QGLContext to
     
    34064027        const QVector<QColor> pal = QColormap::instance().colormap();
    34074028        if (pal.size()) {
    3408             res.setNumColors(pal.size());
     4029            res.set(pal.size());
    34094030            for (int i = 0; i < pal.size(); i++)
    34104031                res.setColor(i, pal.at(i).rgb());
     
    34704091    with the color \a c. Applies to this widgets GL context.
    34714092
     4093
     4094
    34724095    \sa qglClearColor(), QGLContext::currentContext(), QColor
    34734096*/
     
    34774100#if !defined(QT_OPENGL_ES_2)
    34784101#ifdef QT_OPENGL_ES
    3479     glColor4f(c.red()/255.0, c.green()/255.0, c.blue()/255.0, c.alpha()/255.0);
     4102    glColor4f(c.red);
    34804103#else
    34814104    Q_D(const QGLWidget);
     
    34834106    if (ctx) {
    34844107        if (ctx->format().rgba())
    3485             glColor4ub(c.red(), c.green(), c.blue(), c.alpha());
     4108            glColor4());
    34864109        else if (!d->cmap.isEmpty()) { // QGLColormap in use?
    34874110            int i = d->cmap.find(c.rgb());
     
    34934116    }
    34944117#endif //QT_OPENGL_ES
     4118
     4119
    34954120#endif //QT_OPENGL_ES_2
    34964121}
     
    35074132{
    35084133#ifdef QT_OPENGL_ES
    3509     glClearColor((GLfloat)c.red() / 255.0, (GLfloat)c.green() / 255.0,
    3510                  (GLfloat)c.blue() / 255.0, (GLfloat) c.alpha() / 255.0);
     4134    glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
    35114135#else
    35124136    Q_D(const QGLWidget);
     
    35144138    if (ctx) {
    35154139        if (ctx->format().rgba())
    3516             glClearColor((GLfloat)c.red() / 255.0, (GLfloat)c.green() / 255.0,
    3517                           (GLfloat)c.blue() / 255.0, (GLfloat) c.alpha() / 255.0);
     4140            glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
    35184141        else if (!d->cmap.isEmpty()) { // QGLColormap in use?
    35194142            int i = d->cmap.find(c.rgb());
     
    35864209    will return the colormap for the child's top-level widget.
    35874210
    3588     If no colormap has been set for this widget, the QColormap
     4211    If no colormap has been set for this widget, the QColormap
    35894212    returned will be empty.
    35904213
    3591     \sa setColormap()
     4214    \sa setColormap()
    35924215*/
    35934216
     
    36094232    value used when generating the display lists for the font. The
    36104233    default value is 2000.
     4234
     4235
    36114236*/
    36124237int QGLWidget::fontDisplayListBase(const QFont & font, int listBase)
    36134238{
     4239
    36144240    Q_D(QGLWidget);
    36154241    int base;
     
    36294255    if (font.styleStrategy() != QFont::NoAntialias) {
    36304256        GLfloat color[4];
    3631 #ifndef QT_OPENGL_ES
    36324257        glGetFloatv(GL_CURRENT_COLOR, color);
    3633 #endif
    36344258        color_key.sprintf("%f_%f_%f",color[0], color[1], color[2]);
    36354259    }
     
    36544278    }
    36554279    return base;
    3656 }
     4280#else // QT_OPENGL_ES
     4281    Q_UNUSED(font);
     4282    Q_UNUSED(listBase);
     4283    return 0;
     4284#endif
     4285}
     4286
     4287#ifndef QT_OPENGL_ES
    36574288
    36584289static void qt_save_gl_state()
    36594290{
    3660 #ifndef QT_OPENGL_ES
    36614291    glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
    36624292    glPushAttrib(GL_ALL_ATTRIB_BITS);
    3663 #endif
    3664 #if !defined(QT_OPENGL_ES_2)
    36654293    glMatrixMode(GL_TEXTURE);
    36664294    glPushMatrix();
     
    36754303    glDisable(GL_LIGHTING);
    36764304    glDisable(GL_STENCIL_TEST);
     4305
    36774306    glEnable(GL_BLEND);
    36784307    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    3679 #endif // !defined(QT_OPENGL_ES_2)
    36804308}
    36814309
    36824310static void qt_restore_gl_state()
    36834311{
    3684 #if !defined(QT_OPENGL_ES_2)
    36854312    glMatrixMode(GL_TEXTURE);
    36864313    glPopMatrix();
     
    36894316    glMatrixMode(GL_MODELVIEW);
    36904317    glPopMatrix();
    3691 #endif // !defined(QT_OPENGL_ES_2)
    3692 #ifndef QT_OPENGL_ES
    36934318    glPopAttrib();
    36944319    glPopClientAttrib();
    3695 #endif
    36964320}
    36974321
     
    37004324{
    37014325    GLfloat color[4];
    3702 #ifndef QT_OPENGL_ES
    37034326    glGetFloatv(GL_CURRENT_COLOR, &color[0]);
    3704 #endif
    37054327
    37064328    QColor col;
     
    37164338    p->setFont(old_font);
    37174339}
     4340
     4341
    37184342
    37194343/*!
     
    37314355
    37324356   \note This function clears the stencil buffer.
     4357
     4358
     4359
     4360
     4361
     4362
     4363
    37334364*/
    37344365
    37354366void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, int)
    37364367{
     4368
    37374369    Q_D(QGLWidget);
    37384370    if (str.isEmpty() || !isValid())
     
    37404372
    37414373    GLint view[4];
    3742 #ifndef QT_OPENGL_ES
    37434374    bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
    37444375    if (!use_scissor_testing)
    37454376        glGetIntegerv(GL_VIEWPORT, &view[0]);
    3746 #else
    3747     bool use_scissor_testing = false;
    3748 #endif
    37494377    int width = d->glcx->device()->width();
    37504378    int height = d->glcx->device()->height();
    37514379    bool auto_swap = autoBufferSwap();
    37524380
     4381
     4382
    37534383    QPaintEngine *engine = paintEngine();
    37544384    QPainter *p;
     
    37594389        qt_save_gl_state();
    37604390
    3761 #if !defined(QT_OPENGL_ES_2)
    37624391        glDisable(GL_DEPTH_TEST);
    37634392        glViewport(0, 0, width, height);
    37644393        glMatrixMode(GL_PROJECTION);
    37654394        glLoadIdentity();
    3766 #ifndef QT_OPENGL_ES
    37674395        glOrtho(0, width, height, 0, 0, 1);
    3768 #else
    3769         glOrthof(0, width, height, 0, 0, 1);
    3770 #endif
    37714396        glMatrixMode(GL_MODELVIEW);
    37724397
    37734398        glLoadIdentity();
    3774 #endif // !defined(QT_OPENGL_ES_2)
    37754399    } else {
    37764400        setAutoBufferSwap(false);
    37774401        // disable glClear() as a result of QPainter::begin()
    3778         d->glcx->d_func()->clear_on_painter_begin = false;
     4402        d->e;
    37794403        p = new QPainter(this);
    37804404    }
     
    37994423        delete p;
    38004424        setAutoBufferSwap(auto_swap);
    3801         d->glcx->d_func()->clear_on_painter_begin = true;
    3802     }
     4425        d->disable_clear_on_painter_begin = false;
     4426    }
     4427    qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
     4428#else // QT_OPENGL_ES
     4429    Q_UNUSED(x);
     4430    Q_UNUSED(y);
     4431    Q_UNUSED(str);
     4432    Q_UNUSED(font);
     4433    qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
     4434#endif
    38034435}
    38044436
     
    38094441    can be useful if you want to annotate models with text labels and
    38104442    have the labels move with the model as it is rotated etc.
     4443
     4444
     4445
     4446
     4447
     4448
     4449
     4450
     4451
     4452
    38114453*/
    38124454void QGLWidget::renderText(double x, double y, double z, const QString &str, const QFont &font, int)
    38134455{
     4456
    38144457    Q_D(QGLWidget);
    38154458    if (str.isEmpty() || !isValid())
     
    38224465    GLdouble model[4][4], proj[4][4];
    38234466    GLint view[4];
    3824 #ifndef QT_OPENGL_ES
    38254467    glGetDoublev(GL_MODELVIEW_MATRIX, &model[0][0]);
    38264468    glGetDoublev(GL_PROJECTION_MATRIX, &proj[0][0]);
    38274469    glGetIntegerv(GL_VIEWPORT, &view[0]);
    3828 #endif
    38294470    GLdouble win_x = 0, win_y = 0, win_z = 0;
    38304471    qgluProject(x, y, z, &model[0][0], &proj[0][0], &view[0],
     
    38324473    win_y = height - win_y; // y is inverted
    38334474
     4475
     4476
    38344477    QPaintEngine *engine = paintEngine();
    38354478    QPainter *p;
    38364479    bool reuse_painter = false;
    3837 #ifndef QT_OPENGL_ES
    38384480    bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
    38394481    bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
    3840 #else
    3841     bool use_depth_testing = false;
    3842     bool use_scissor_testing = false;
    3843 #endif
    38444482
    38454483    if (engine->isActive()) {
     
    38504488        setAutoBufferSwap(false);
    38514489        // disable glClear() as a result of QPainter::begin()
    3852         d->glcx->d_func()->clear_on_painter_begin = false;
     4490        d->e;
    38534491        p = new QPainter(this);
    38544492    }
     
    38614499        glEnable(GL_SCISSOR_TEST);
    38624500    }
    3863 #if !defined(QT_OPENGL_ES_2)
    38644501    glMatrixMode(GL_PROJECTION);
    38654502    glLoadIdentity();
    38664503    glViewport(0, 0, width, height);
    3867 #ifndef QT_OPENGL_ES
    38684504    glOrtho(0, width, height, 0, 0, 1);
    3869 #else
    3870     glOrthof(0, width, height, 0, 0, 1);
    3871 #endif
    38724505    glMatrixMode(GL_MODELVIEW);
    38734506    glLoadIdentity();
     
    38764509    if (use_depth_testing)
    38774510        glEnable(GL_DEPTH_TEST);
    3878 #ifndef QT_OPENGL_ES
    38794511    glTranslated(0, 0, -win_z);
    3880 #else
    3881     glTranslatef(0, 0, -win_z);
    3882 #endif
    3883 #endif // !defined(QT_OPENGL_ES_2)
    38844512    qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font);
    38854513
     
    38904518        delete p;
    38914519        setAutoBufferSwap(auto_swap);
    3892         d->glcx->d_func()->clear_on_painter_begin = true;
    3893     }
     4520        d->disable_clear_on_painter_begin = false;
     4521    }
     4522    qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
     4523#else // QT_OPENGL_ES
     4524    Q_UNUSED(x);
     4525    Q_UNUSED(y);
     4526    Q_UNUSED(z);
     4527    Q_UNUSED(str);
     4528    Q_UNUSED(font);
     4529    qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
     4530#endif
    38944531}
    38954532
     
    39324569GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format)
    39334570{
     4571
     4572
     4573
    39344574    Q_D(QGLWidget);
    3935     return d->glcx->bindTexture(image, target, format);
    3936 }
     4575    return d->glcx->bindTexture(image, target, format, QGLContext::DefaultBindOption);
     4576}
     4577
     4578/*!
     4579  \overload
     4580  \since 4.6
     4581
     4582  The binding \a options are a set of options used to decide how to
     4583  bind the texture to the context.
     4584 */
     4585GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format, QGLContext::BindOptions options)
     4586{
     4587    if (image.isNull())
     4588        return 0;
     4589
     4590    Q_D(QGLWidget);
     4591    return d->glcx->bindTexture(image, target, format, options);
     4592}
     4593
    39374594
    39384595#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
     
    39404597GLuint QGLWidget::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format)
    39414598{
     4599
     4600
     4601
    39424602   Q_D(QGLWidget);
    3943    return d->glcx->bindTexture(image, GLenum(target), GLint(format));
     4603   return d->glcx->bindTexture(image, GLenum(target), GLint(format), QGLContext::DefaultBindOption);
     4604}
     4605
     4606GLuint QGLWidget::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format,
     4607                              QGLContext::BindOptions options)
     4608{
     4609    if (image.isNull())
     4610        return 0;
     4611
     4612   Q_D(QGLWidget);
     4613   return d->glcx->bindTexture(image, GLenum(target), GLint(format), options);
    39444614}
    39454615#endif
     
    39534623GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format)
    39544624{
     4625
     4626
     4627
    39554628    Q_D(QGLWidget);
    3956     return d->glcx->bindTexture(pixmap, target, format);
     4629    return d->glcx->bindTexture(pixmap, target, format, QGLContext::DefaultBindOption);
     4630}
     4631
     4632/*!
     4633  \overload
     4634  \since 4.6
     4635
     4636  Generates and binds a 2D GL texture to the current context, based
     4637  on \a pixmap. The generated texture id is returned and can be used in
     4638
     4639  The binding \a options are a set of options used to decide how to
     4640  bind the texture to the context.
     4641 */
     4642GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format,
     4643                              QGLContext::BindOptions options)
     4644{
     4645    Q_D(QGLWidget);
     4646    return d->glcx->bindTexture(pixmap, target, format, options);
    39574647}
    39584648
     
    39624652{
    39634653    Q_D(QGLWidget);
    3964     return d->glcx->bindTexture(pixmap, target, format);
     4654    return d->glcx->bindTexture(pixmap, target, format, QGLContext::DefaultBindOption);
     4655}
     4656
     4657GLuint QGLWidget::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format,
     4658                              QGLContext::BindOptions options)
     4659{
     4660    Q_D(QGLWidget);
     4661    return d->glcx->bindTexture(pixmap, target, format, options);
    39654662}
    39664663#endif
     
    40474744#endif
    40484745
    4049 #if defined(QT_OPENGL_ES_2)
    4050 Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_engine)
     4746#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
     4747Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_2_engine)
     4748#endif
     4749
     4750#ifndef QT_OPENGL_ES_2
     4751Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_engine)
     4752#endif
     4753
     4754Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine()
     4755{
     4756#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)
     4757    return qt_gl_engine();
     4758#elif defined(QT_OPENGL_ES_2)
     4759    return qt_gl_2_engine();
    40514760#else
    4052 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_engine)
    4053 #endif
    4054 
    4055 #ifdef Q_WS_QWS
    4056 Q_OPENGL_EXPORT QOpenGLPaintEngine* qt_qgl_paint_engine()
    4057 {
    4058 #if !defined(QT_OPENGL_ES_2)
    4059     return qt_gl_engine();
    4060 #else
    4061     return 0; // XXX
    4062 #endif
    4063 }
    4064 #endif
     4761    if (qt_gl_preferGL2Engine())
     4762        return qt_gl_2_engine();
     4763    else
     4764        return qt_gl_engine();
     4765#endif
     4766}
    40654767
    40664768/*!
     
    40724774QPaintEngine *QGLWidget::paintEngine() const
    40734775{
    4074     return qt_gl_engine();
     4776    return qt__engine();
    40754777}
    40764778
     
    41324834void QGLExtensions::init_extensions()
    41334835{
    4134     QString extensions = QLatin1String(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
    4135     if (extensions.contains(QLatin1String("texture_rectangle")))
     4836    QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
     4837
     4838    if (extensions.match("GL_ARB_texture_rectangle"))
    41364839        glExtensions |= TextureRectangle;
    4137     if (extensions.contains(QLatin1String("multisample")))
     4840    if (extensions.))
    41384841        glExtensions |= SampleBuffers;
    4139     if (extensions.contains(QLatin1String("generate_mipmap")))
     4842    if (extensions.))
    41404843        glExtensions |= GenerateMipmap;
    4141     if (extensions.contains(QLatin1String("texture_compression_s3tc")))
     4844    if (extensions.))
    41424845        glExtensions |= TextureCompression;
    4143     if (extensions.contains(QLatin1String("ARB_fragment_program")))
     4846    if (extensions.match("GL_EXT_texture_compression_s3tc"))
     4847        glExtensions |= DDSTextureCompression;
     4848    if (extensions.match("GL_OES_compressed_ETC1_RGB8_texture"))
     4849        glExtensions |= ETC1TextureCompression;
     4850    if (extensions.match("GL_IMG_texture_compression_pvrtc"))
     4851        glExtensions |= PVRTCTextureCompression;
     4852    if (extensions.match("GL_ARB_fragment_program"))
    41444853        glExtensions |= FragmentProgram;
    4145     if (extensions.contains(QLatin1String("mirrored_repeat")))
     4854    if (extensions.match("GL_ARB_fragment_shader"))
     4855        glExtensions |= FragmentShader;
     4856    if (extensions.match("GL_ARB_texture_mirrored_repeat"))
    41464857        glExtensions |= MirroredRepeat;
    4147     if (extensions.contains(QLatin1String("EXT_framebuffer_object")))
     4858    if (extensions.))
    41484859        glExtensions |= FramebufferObject;
    4149     if (extensions.contains(QLatin1String("EXT_stencil_two_side")))
     4860    if (extensions.))
    41504861        glExtensions |= StencilTwoSide;
    4151     if (extensions.contains(QLatin1String("EXT_stencil_wrap")))
     4862    if (extensions.))
    41524863        glExtensions |= StencilWrap;
    4153     if (extensions.contains(QLatin1String("EXT_packed_depth_stencil")))
     4864    if (extensions.))
    41544865        glExtensions |= PackedDepthStencil;
    4155     if (extensions.contains(QLatin1String("GL_NV_float_buffer")))
     4866    if (extensions.))
    41564867        glExtensions |= NVFloatBuffer;
    4157     if (extensions.contains(QLatin1String("ARB_pixel_buffer_object")))
     4868    if (extensions.))
    41584869        glExtensions |= PixelBufferObject;
    41594870#if defined(QT_OPENGL_ES_2)
    41604871    glExtensions |= FramebufferObject;
    41614872    glExtensions |= GenerateMipmap;
    4162 #endif
    4163 
    4164     QGLContext cx(QGLFormat::defaultFormat());
    4165     if (glExtensions & TextureCompression) {
    4166         qt_glCompressedTexImage2DARB = (pfn_glCompressedTexImage2DARB) cx.getProcAddress(QLatin1String("glCompressedTexImage2DARB"));
    4167     }
     4873    glExtensions |= FragmentShader;
     4874#endif
     4875#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)
     4876    if (extensions.match("GL_OES_framebuffer_object"))
     4877        glExtensions |= FramebufferObject;
     4878#endif
     4879#if defined(QT_OPENGL_ES)
     4880    if (extensions.match("GL_OES_packed_depth_stencil"))
     4881        glExtensions |= PackedDepthStencil;
     4882#endif
     4883    if (extensions.match("GL_ARB_framebuffer_object")) {
     4884        // ARB_framebuffer_object also includes EXT_framebuffer_blit.
     4885        glExtensions |= FramebufferObject;
     4886        glExtensions |= FramebufferBlit;
     4887    }
     4888
     4889    if (extensions.match("GL_EXT_framebuffer_blit"))
     4890        glExtensions |= FramebufferBlit;
     4891
     4892    if (extensions.match("GL_ARB_texture_non_power_of_two"))
     4893        glExtensions |= NPOTTextures;
     4894
     4895    if (extensions.match("GL_EXT_bgra"))
     4896        glExtensions |= BGRATextureFormat;
    41684897}
    41694898
     
    41744903{
    41754904    Q_Q(QGLWidget);
     4905
     4906
    41764907
    41774908    QGLExtensions::init();
     
    41904921
    41914922#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
    4192 Q_GLOBAL_STATIC(QString, qt_gl_lib_name);
     4923Q_GLOBAL_STATIC(QString, qt_gl_lib_name)
    41934924
    41944925Q_OPENGL_EXPORT void qt_set_gl_library_name(const QString& name)
     
    42014932    if (qt_gl_lib_name()->isNull()) {
    42024933#if defined(Q_WS_X11) || defined(Q_WS_QWS)
    4203         return QString(QLatin1String("GL"));
     4934        return Q);
    42044935#else // Q_WS_MAC
    42054936        return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib");
     
    42104941#endif
    42114942
     4943
     4944
     4945
     4946
     4947
     4948
     4949
     4950
     4951
     4952
     4953
     4954
     4955
     4956
     4957
     4958
     4959
     4960
     4961
     4962
     4963
     4964
     4965
     4966
     4967
     4968
     4969
     4970
     4971
     4972
     4973
     4974
     4975
     4976
     4977
     4978
     4979
     4980
     4981
     4982
     4983
     4984
     4985
     4986
     4987
     4988
     4989
     4990
     4991
     4992
     4993
     4994
     4995
     4996
     4997
     4998
     4999
     5000
     5001
     5002
     5003
     5004
     5005
     5006
     5007
     5008
     5009
     5010
     5011
     5012
     5013
     5014
     5015
     5016
     5017
     5018
     5019
     5020
     5021
     5022
     5023
     5024
     5025
     5026
     5027
     5028
     5029
     5030
     5031
     5032
     5033
     5034
     5035
     5036
     5037
     5038
     5039
     5040
     5041
     5042
     5043
     5044
     5045
     5046
     5047
     5048
     5049
     5050
     5051
     5052
     5053
     5054
     5055
     5056
     5057
     5058
     5059
     5060
     5061
     5062
     5063
     5064
     5065
     5066
     5067
     5068
     5069
     5070
     5071
     5072
     5073
     5074
     5075
     5076
     5077
     5078
     5079
     5080
     5081
     5082
     5083
     5084
     5085
     5086
     5087
     5088
     5089
     5090
     5091
     5092
     5093
     5094
     5095
     5096
     5097
     5098
     5099
     5100
     5101
     5102
     5103
     5104
     5105
     5106
     5107
     5108
     5109
     5110
     5111
     5112
     5113
     5114
     5115
     5116
     5117
     5118
     5119
     5120
     5121
     5122
     5123
     5124
     5125
     5126
     5127
     5128
     5129
     5130
     5131
     5132
     5133
     5134
     5135
     5136
     5137
     5138
     5139
     5140
     5141
     5142
     5143
     5144
     5145
     5146
     5147
     5148
     5149
     5150
     5151
     5152
     5153
     5154
     5155
     5156
     5157
     5158
     5159
     5160
     5161
     5162
     5163
     5164
     5165
     5166
     5167
     5168
     5169
     5170
     5171
     5172
     5173
     5174
     5175
     5176
     5177
     5178
     5179
     5180
     5181
     5182
     5183
     5184
     5185
     5186
     5187
     5188
     5189
     5190
     5191
     5192
     5193
     5194
     5195
     5196
     5197
     5198
     5199
     5200
     5201
     5202
     5203
     5204
     5205
     5206
     5207
     5208
     5209
     5210
     5211
     5212
     5213
     5214
     5215
     5216
     5217
     5218
     5219
     5220
     5221
     5222
     5223
     5224
     5225
     5226
     5227
     5228
     5229
     5230
     5231
     5232
     5233
     5234
     5235
     5236
     5237
     5238
     5239
     5240
     5241
     5242
     5243
     5244
     5245
     5246
     5247
     5248
     5249
     5250
     5251
     5252
     5253
     5254
     5255
     5256
     5257
     5258
     5259
     5260
     5261
     5262
     5263
     5264
     5265
     5266
     5267
     5268
     5269
     5270
     5271
     5272
     5273
     5274
     5275
     5276
     5277
     5278
     5279
     5280
     5281
     5282
     5283
     5284
     5285
     5286
     5287
     5288
     5289
     5290
     5291
     5292
     5293
     5294
     5295
     5296
     5297
     5298
     5299
     5300
     5301
     5302
     5303
     5304
     5305
     5306
     5307
     5308
     5309
     5310
     5311
     5312
     5313
     5314
     5315
     5316
     5317
     5318
     5319
     5320
     5321
     5322
     5323
     5324
     5325
     5326
     5327
     5328
     5329
     5330
     5331
     5332
     5333
     5334
     5335
     5336
     5337
     5338
     5339
     5340
     5341
     5342
     5343
     5344
     5345
     5346
     5347
     5348
     5349
     5350
     5351
     5352
     5353
     5354
     5355
     5356
     5357
     5358
     5359
     5360
     5361
     5362
     5363
     5364
     5365
     5366
     5367
     5368
     5369
     5370
     5371
     5372
     5373
     5374
     5375
     5376
     5377
     5378
     5379
     5380
     5381
     5382
     5383
     5384
     5385
     5386
     5387
     5388
    42125389QT_END_NAMESPACE
Note: See TracChangeset for help on using the changeset viewer.