tests/auto/qgl/tst_qgl.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 
       
    45 #include <qcoreapplication.h>
       
    46 #include <qdebug.h>
       
    47 #include <qgl.h>
       
    48 #include <qglpixelbuffer.h>
       
    49 #include <qglframebufferobject.h>
       
    50 #include <qglcolormap.h>
       
    51 #include <qpaintengine.h>
       
    52 
       
    53 #include <QGraphicsView>
       
    54 #include <QGraphicsProxyWidget>
       
    55 #include <QVBoxLayout>
       
    56 
       
    57 #ifdef QT_BUILD_INTERNAL
       
    58 #include <QtOpenGL/private/qgl_p.h>
       
    59 #endif
       
    60 
       
    61 //TESTED_CLASS=
       
    62 //TESTED_FILES=
       
    63 
       
    64 class tst_QGL : public QObject
       
    65 {
       
    66 Q_OBJECT
       
    67 
       
    68 public:
       
    69     tst_QGL();
       
    70     virtual ~tst_QGL();
       
    71 
       
    72 private slots:
       
    73     void getSetCheck();
       
    74     void openGLVersionCheck();
       
    75     void graphicsViewClipping();
       
    76     void partialGLWidgetUpdates_data();
       
    77     void partialGLWidgetUpdates();
       
    78     void glWidgetRendering();
       
    79     void glFBORendering();
       
    80     void multipleFBOInterleavedRendering();
       
    81     void glFBOUseInGLWidget();
       
    82     void glPBufferRendering();
       
    83     void glWidgetReparent();
       
    84     void glWidgetRenderPixmap();
       
    85     void stackedFBOs();
       
    86     void colormap();
       
    87     void fboFormat();
       
    88     void testDontCrashOnDanglingResources();
       
    89     void replaceClipping();
       
    90     void clipTest();
       
    91     void destroyFBOAfterContext();
       
    92     void shareRegister();
       
    93 };
       
    94 
       
    95 tst_QGL::tst_QGL()
       
    96 {
       
    97 }
       
    98 
       
    99 tst_QGL::~tst_QGL()
       
   100 {
       
   101 }
       
   102 
       
   103 class MyGLContext : public QGLContext
       
   104 {
       
   105 public:
       
   106     MyGLContext(const QGLFormat& format) : QGLContext(format) {}
       
   107     bool windowCreated() const { return QGLContext::windowCreated(); }
       
   108     void setWindowCreated(bool on) { QGLContext::setWindowCreated(on); }
       
   109     bool initialized() const { return QGLContext::initialized(); }
       
   110     void setInitialized(bool on) { QGLContext::setInitialized(on); }
       
   111 };
       
   112 
       
   113 class MyGLWidget : public QGLWidget
       
   114 {
       
   115 public:
       
   116     MyGLWidget() : QGLWidget() {}
       
   117     bool autoBufferSwap() const { return QGLWidget::autoBufferSwap(); }
       
   118     void setAutoBufferSwap(bool on) { QGLWidget::setAutoBufferSwap(on); }
       
   119 };
       
   120 
       
   121 // Using INT_MIN and INT_MAX will cause failures on systems
       
   122 // where "int" is 64-bit, so use the explicit values instead.
       
   123 #define TEST_INT_MIN    (-2147483647 - 1)
       
   124 #define TEST_INT_MAX    2147483647
       
   125 
       
   126 // Testing get/set functions
       
   127 void tst_QGL::getSetCheck()
       
   128 {
       
   129     if (!QGLFormat::hasOpenGL())
       
   130         QSKIP("QGL not supported on this platform", SkipAll);
       
   131 
       
   132     QGLFormat obj1;
       
   133     // int QGLFormat::depthBufferSize()
       
   134     // void QGLFormat::setDepthBufferSize(int)
       
   135     QCOMPARE(-1, obj1.depthBufferSize());
       
   136     obj1.setDepthBufferSize(0);
       
   137     QCOMPARE(0, obj1.depthBufferSize());
       
   138     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setDepthBufferSize: Cannot set negative depth buffer size -2147483648");
       
   139     obj1.setDepthBufferSize(TEST_INT_MIN);
       
   140     QCOMPARE(0, obj1.depthBufferSize()); // Makes no sense with a negative buffer size
       
   141     obj1.setDepthBufferSize(3);
       
   142     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setDepthBufferSize: Cannot set negative depth buffer size -1");
       
   143     obj1.setDepthBufferSize(-1);
       
   144     QCOMPARE(3, obj1.depthBufferSize());
       
   145     obj1.setDepthBufferSize(TEST_INT_MAX);
       
   146     QCOMPARE(TEST_INT_MAX, obj1.depthBufferSize());
       
   147 
       
   148     // int QGLFormat::accumBufferSize()
       
   149     // void QGLFormat::setAccumBufferSize(int)
       
   150     QCOMPARE(-1, obj1.accumBufferSize());
       
   151     obj1.setAccumBufferSize(0);
       
   152     QCOMPARE(0, obj1.accumBufferSize());
       
   153     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setAccumBufferSize: Cannot set negative accumulate buffer size -2147483648");
       
   154     obj1.setAccumBufferSize(TEST_INT_MIN);
       
   155     QCOMPARE(0, obj1.accumBufferSize()); // Makes no sense with a negative buffer size
       
   156     obj1.setAccumBufferSize(3);
       
   157     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setAccumBufferSize: Cannot set negative accumulate buffer size -1");
       
   158     obj1.setAccumBufferSize(-1);
       
   159     QCOMPARE(3, obj1.accumBufferSize());
       
   160     obj1.setAccumBufferSize(TEST_INT_MAX);
       
   161     QCOMPARE(TEST_INT_MAX, obj1.accumBufferSize());
       
   162 
       
   163     // int QGLFormat::redBufferSize()
       
   164     // void QGLFormat::setRedBufferSize(int)
       
   165     QCOMPARE(-1, obj1.redBufferSize());
       
   166     obj1.setRedBufferSize(0);
       
   167     QCOMPARE(0, obj1.redBufferSize());
       
   168     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setRedBufferSize: Cannot set negative red buffer size -2147483648");
       
   169     obj1.setRedBufferSize(TEST_INT_MIN);
       
   170     QCOMPARE(0, obj1.redBufferSize()); // Makes no sense with a negative buffer size
       
   171     obj1.setRedBufferSize(3);
       
   172     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setRedBufferSize: Cannot set negative red buffer size -1");
       
   173     obj1.setRedBufferSize(-1);
       
   174     QCOMPARE(3, obj1.redBufferSize());
       
   175     obj1.setRedBufferSize(TEST_INT_MAX);
       
   176     QCOMPARE(TEST_INT_MAX, obj1.redBufferSize());
       
   177 
       
   178     // int QGLFormat::greenBufferSize()
       
   179     // void QGLFormat::setGreenBufferSize(int)
       
   180     QCOMPARE(-1, obj1.greenBufferSize());
       
   181     obj1.setGreenBufferSize(0);
       
   182     QCOMPARE(0, obj1.greenBufferSize());
       
   183     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setGreenBufferSize: Cannot set negative green buffer size -2147483648");
       
   184     obj1.setGreenBufferSize(TEST_INT_MIN);
       
   185     QCOMPARE(0, obj1.greenBufferSize()); // Makes no sense with a negative buffer size
       
   186     obj1.setGreenBufferSize(3);
       
   187     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setGreenBufferSize: Cannot set negative green buffer size -1");
       
   188     obj1.setGreenBufferSize(-1);
       
   189     QCOMPARE(3, obj1.greenBufferSize());
       
   190     obj1.setGreenBufferSize(TEST_INT_MAX);
       
   191     QCOMPARE(TEST_INT_MAX, obj1.greenBufferSize());
       
   192 
       
   193     // int QGLFormat::blueBufferSize()
       
   194     // void QGLFormat::setBlueBufferSize(int)
       
   195     QCOMPARE(-1, obj1.blueBufferSize());
       
   196     obj1.setBlueBufferSize(0);
       
   197     QCOMPARE(0, obj1.blueBufferSize());
       
   198     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setBlueBufferSize: Cannot set negative blue buffer size -2147483648");
       
   199     obj1.setBlueBufferSize(TEST_INT_MIN);
       
   200     QCOMPARE(0, obj1.blueBufferSize()); // Makes no sense with a negative buffer size
       
   201     obj1.setBlueBufferSize(3);
       
   202     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setBlueBufferSize: Cannot set negative blue buffer size -1");
       
   203     obj1.setBlueBufferSize(-1);
       
   204     QCOMPARE(3, obj1.blueBufferSize());
       
   205     obj1.setBlueBufferSize(TEST_INT_MAX);
       
   206     QCOMPARE(TEST_INT_MAX, obj1.blueBufferSize());
       
   207 
       
   208     // int QGLFormat::alphaBufferSize()
       
   209     // void QGLFormat::setAlphaBufferSize(int)
       
   210     QCOMPARE(-1, obj1.alphaBufferSize());
       
   211     QCOMPARE(false, obj1.alpha());
       
   212     QVERIFY(!obj1.testOption(QGL::AlphaChannel));
       
   213     QVERIFY(obj1.testOption(QGL::NoAlphaChannel));
       
   214     obj1.setAlphaBufferSize(0);
       
   215     QCOMPARE(true, obj1.alpha());   // setAlphaBufferSize() enables alpha.
       
   216     QCOMPARE(0, obj1.alphaBufferSize());
       
   217     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setAlphaBufferSize: Cannot set negative alpha buffer size -2147483648");
       
   218     obj1.setAlphaBufferSize(TEST_INT_MIN);
       
   219     QCOMPARE(0, obj1.alphaBufferSize()); // Makes no sense with a negative buffer size
       
   220     obj1.setAlphaBufferSize(3);
       
   221     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setAlphaBufferSize: Cannot set negative alpha buffer size -1");
       
   222     obj1.setAlphaBufferSize(-1);
       
   223     QCOMPARE(3, obj1.alphaBufferSize());
       
   224     obj1.setAlphaBufferSize(TEST_INT_MAX);
       
   225     QCOMPARE(TEST_INT_MAX, obj1.alphaBufferSize());
       
   226 
       
   227     // int QGLFormat::stencilBufferSize()
       
   228     // void QGLFormat::setStencilBufferSize(int)
       
   229     QCOMPARE(-1, obj1.stencilBufferSize());
       
   230     obj1.setStencilBufferSize(0);
       
   231     QCOMPARE(0, obj1.stencilBufferSize());
       
   232     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setStencilBufferSize: Cannot set negative stencil buffer size -2147483648");
       
   233     obj1.setStencilBufferSize(TEST_INT_MIN);
       
   234     QCOMPARE(0, obj1.stencilBufferSize()); // Makes no sense with a negative buffer size
       
   235     obj1.setStencilBufferSize(3);
       
   236     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setStencilBufferSize: Cannot set negative stencil buffer size -1");
       
   237     obj1.setStencilBufferSize(-1);
       
   238     QCOMPARE(3, obj1.stencilBufferSize());
       
   239     obj1.setStencilBufferSize(TEST_INT_MAX);
       
   240     QCOMPARE(TEST_INT_MAX, obj1.stencilBufferSize());
       
   241 
       
   242     // bool QGLFormat::sampleBuffers()
       
   243     // void QGLFormat::setSampleBuffers(bool)
       
   244 #if !defined(QT_OPENGL_ES_2)
       
   245     QCOMPARE(false, obj1.sampleBuffers());
       
   246     QVERIFY(!obj1.testOption(QGL::SampleBuffers));
       
   247     QVERIFY(obj1.testOption(QGL::NoSampleBuffers));
       
   248 #else
       
   249     QCOMPARE(true, obj1.sampleBuffers());
       
   250     QVERIFY(obj1.testOption(QGL::SampleBuffers));
       
   251     QVERIFY(!obj1.testOption(QGL::NoSampleBuffers));
       
   252 #endif
       
   253     obj1.setSampleBuffers(false);
       
   254     QCOMPARE(false, obj1.sampleBuffers());
       
   255     QVERIFY(obj1.testOption(QGL::NoSampleBuffers));
       
   256     obj1.setSampleBuffers(true);
       
   257     QCOMPARE(true, obj1.sampleBuffers());
       
   258     QVERIFY(obj1.testOption(QGL::SampleBuffers));
       
   259 
       
   260     // int QGLFormat::samples()
       
   261     // void QGLFormat::setSamples(int)
       
   262     QCOMPARE(-1, obj1.samples());
       
   263     obj1.setSamples(0);
       
   264     QCOMPARE(0, obj1.samples());
       
   265     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setSamples: Cannot have negative number of samples per pixel -2147483648");
       
   266     obj1.setSamples(TEST_INT_MIN);
       
   267     QCOMPARE(0, obj1.samples());  // Makes no sense with a negative sample size
       
   268     obj1.setSamples(3);
       
   269     QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setSamples: Cannot have negative number of samples per pixel -1");
       
   270     obj1.setSamples(-1);
       
   271     QCOMPARE(3, obj1.samples());
       
   272     obj1.setSamples(TEST_INT_MAX);
       
   273     QCOMPARE(TEST_INT_MAX, obj1.samples());
       
   274 
       
   275     // int QGLFormat::swapInterval()
       
   276     // void QGLFormat::setSwapInterval(int)
       
   277     QCOMPARE(-1, obj1.swapInterval());
       
   278     obj1.setSwapInterval(0);
       
   279     QCOMPARE(0, obj1.swapInterval());
       
   280     obj1.setSwapInterval(TEST_INT_MIN);
       
   281     QCOMPARE(TEST_INT_MIN, obj1.swapInterval());
       
   282     obj1.setSwapInterval(-1);
       
   283     QCOMPARE(-1, obj1.swapInterval());
       
   284     obj1.setSwapInterval(TEST_INT_MAX);
       
   285     QCOMPARE(TEST_INT_MAX, obj1.swapInterval());
       
   286 
       
   287     // bool QGLFormat::doubleBuffer()
       
   288     // void QGLFormat::setDoubleBuffer(bool)
       
   289     QCOMPARE(true, obj1.doubleBuffer());
       
   290     QVERIFY(obj1.testOption(QGL::DoubleBuffer));
       
   291     QVERIFY(!obj1.testOption(QGL::SingleBuffer));
       
   292     obj1.setDoubleBuffer(false);
       
   293     QCOMPARE(false, obj1.doubleBuffer());
       
   294     QVERIFY(!obj1.testOption(QGL::DoubleBuffer));
       
   295     QVERIFY(obj1.testOption(QGL::SingleBuffer));
       
   296     obj1.setDoubleBuffer(true);
       
   297     QCOMPARE(true, obj1.doubleBuffer());
       
   298     QVERIFY(obj1.testOption(QGL::DoubleBuffer));
       
   299     QVERIFY(!obj1.testOption(QGL::SingleBuffer));
       
   300 
       
   301     // bool QGLFormat::depth()
       
   302     // void QGLFormat::setDepth(bool)
       
   303     QCOMPARE(true, obj1.depth());
       
   304     QVERIFY(obj1.testOption(QGL::DepthBuffer));
       
   305     QVERIFY(!obj1.testOption(QGL::NoDepthBuffer));
       
   306     obj1.setDepth(false);
       
   307     QCOMPARE(false, obj1.depth());
       
   308     QVERIFY(!obj1.testOption(QGL::DepthBuffer));
       
   309     QVERIFY(obj1.testOption(QGL::NoDepthBuffer));
       
   310     obj1.setDepth(true);
       
   311     QCOMPARE(true, obj1.depth());
       
   312     QVERIFY(obj1.testOption(QGL::DepthBuffer));
       
   313     QVERIFY(!obj1.testOption(QGL::NoDepthBuffer));
       
   314 
       
   315     // bool QGLFormat::rgba()
       
   316     // void QGLFormat::setRgba(bool)
       
   317     QCOMPARE(true, obj1.rgba());
       
   318     QVERIFY(obj1.testOption(QGL::Rgba));
       
   319     QVERIFY(!obj1.testOption(QGL::ColorIndex));
       
   320     obj1.setRgba(false);
       
   321     QCOMPARE(false, obj1.rgba());
       
   322     QVERIFY(!obj1.testOption(QGL::Rgba));
       
   323     QVERIFY(obj1.testOption(QGL::ColorIndex));
       
   324     obj1.setRgba(true);
       
   325     QCOMPARE(true, obj1.rgba());
       
   326     QVERIFY(obj1.testOption(QGL::Rgba));
       
   327     QVERIFY(!obj1.testOption(QGL::ColorIndex));
       
   328 
       
   329     // bool QGLFormat::alpha()
       
   330     // void QGLFormat::setAlpha(bool)
       
   331     QVERIFY(obj1.testOption(QGL::AlphaChannel));
       
   332     QVERIFY(!obj1.testOption(QGL::NoAlphaChannel));
       
   333     obj1.setAlpha(false);
       
   334     QCOMPARE(false, obj1.alpha());
       
   335     QVERIFY(!obj1.testOption(QGL::AlphaChannel));
       
   336     QVERIFY(obj1.testOption(QGL::NoAlphaChannel));
       
   337     obj1.setAlpha(true);
       
   338     QCOMPARE(true, obj1.alpha());
       
   339     QVERIFY(obj1.testOption(QGL::AlphaChannel));
       
   340     QVERIFY(!obj1.testOption(QGL::NoAlphaChannel));
       
   341 
       
   342     // bool QGLFormat::accum()
       
   343     // void QGLFormat::setAccum(bool)
       
   344     QCOMPARE(false, obj1.accum());
       
   345     QVERIFY(!obj1.testOption(QGL::AccumBuffer));
       
   346     QVERIFY(obj1.testOption(QGL::NoAccumBuffer));
       
   347     obj1.setAccum(false);
       
   348     QCOMPARE(false, obj1.accum());
       
   349     QVERIFY(!obj1.testOption(QGL::AccumBuffer));
       
   350     QVERIFY(obj1.testOption(QGL::NoAccumBuffer));
       
   351     obj1.setAccum(true);
       
   352     QCOMPARE(true, obj1.accum());
       
   353     QVERIFY(obj1.testOption(QGL::AccumBuffer));
       
   354     QVERIFY(!obj1.testOption(QGL::NoAccumBuffer));
       
   355 
       
   356     // bool QGLFormat::stencil()
       
   357     // void QGLFormat::setStencil(bool)
       
   358     QCOMPARE(true, obj1.stencil());
       
   359     QVERIFY(obj1.testOption(QGL::StencilBuffer));
       
   360     QVERIFY(!obj1.testOption(QGL::NoStencilBuffer));
       
   361     obj1.setStencil(false);
       
   362     QCOMPARE(false, obj1.stencil());
       
   363     QVERIFY(!obj1.testOption(QGL::StencilBuffer));
       
   364     QVERIFY(obj1.testOption(QGL::NoStencilBuffer));
       
   365     obj1.setStencil(true);
       
   366     QCOMPARE(true, obj1.stencil());
       
   367     QVERIFY(obj1.testOption(QGL::StencilBuffer));
       
   368     QVERIFY(!obj1.testOption(QGL::NoStencilBuffer));
       
   369 
       
   370     // bool QGLFormat::stereo()
       
   371     // void QGLFormat::setStereo(bool)
       
   372     QCOMPARE(false, obj1.stereo());
       
   373     QVERIFY(!obj1.testOption(QGL::StereoBuffers));
       
   374     QVERIFY(obj1.testOption(QGL::NoStereoBuffers));
       
   375     obj1.setStereo(false);
       
   376     QCOMPARE(false, obj1.stereo());
       
   377     QVERIFY(!obj1.testOption(QGL::StereoBuffers));
       
   378     QVERIFY(obj1.testOption(QGL::NoStereoBuffers));
       
   379     obj1.setStereo(true);
       
   380     QCOMPARE(true, obj1.stereo());
       
   381     QVERIFY(obj1.testOption(QGL::StereoBuffers));
       
   382     QVERIFY(!obj1.testOption(QGL::NoStereoBuffers));
       
   383 
       
   384     // bool QGLFormat::directRendering()
       
   385     // void QGLFormat::setDirectRendering(bool)
       
   386     QCOMPARE(true, obj1.directRendering());
       
   387     QVERIFY(obj1.testOption(QGL::DirectRendering));
       
   388     QVERIFY(!obj1.testOption(QGL::IndirectRendering));
       
   389     obj1.setDirectRendering(false);
       
   390     QCOMPARE(false, obj1.directRendering());
       
   391     QVERIFY(!obj1.testOption(QGL::DirectRendering));
       
   392     QVERIFY(obj1.testOption(QGL::IndirectRendering));
       
   393     obj1.setDirectRendering(true);
       
   394     QCOMPARE(true, obj1.directRendering());
       
   395     QVERIFY(obj1.testOption(QGL::DirectRendering));
       
   396     QVERIFY(!obj1.testOption(QGL::IndirectRendering));
       
   397 
       
   398     // bool QGLFormat::overlay()
       
   399     // void QGLFormat::setOverlay(bool)
       
   400     QCOMPARE(false, obj1.hasOverlay());
       
   401     QVERIFY(!obj1.testOption(QGL::HasOverlay));
       
   402     QVERIFY(obj1.testOption(QGL::NoOverlay));
       
   403     obj1.setOverlay(false);
       
   404     QCOMPARE(false, obj1.hasOverlay());
       
   405     QVERIFY(!obj1.testOption(QGL::HasOverlay));
       
   406     QVERIFY(obj1.testOption(QGL::NoOverlay));
       
   407     obj1.setOverlay(true);
       
   408     QCOMPARE(true, obj1.hasOverlay());
       
   409     QVERIFY(obj1.testOption(QGL::HasOverlay));
       
   410     QVERIFY(!obj1.testOption(QGL::NoOverlay));
       
   411 
       
   412     // int QGLFormat::plane()
       
   413     // void QGLFormat::setPlane(int)
       
   414     QCOMPARE(0, obj1.plane());
       
   415     obj1.setPlane(0);
       
   416     QCOMPARE(0, obj1.plane());
       
   417     obj1.setPlane(TEST_INT_MIN);
       
   418     QCOMPARE(TEST_INT_MIN, obj1.plane());
       
   419     obj1.setPlane(TEST_INT_MAX);
       
   420     QCOMPARE(TEST_INT_MAX, obj1.plane());
       
   421 
       
   422     // operator== and operator!= for QGLFormat
       
   423     QGLFormat format1;
       
   424     QGLFormat format2;
       
   425 
       
   426     QVERIFY(format1 == format2);
       
   427     QVERIFY(!(format1 != format2));
       
   428     format1.setDoubleBuffer(false);
       
   429     QVERIFY(!(format1 == format2));
       
   430     QVERIFY(format1 != format2);
       
   431     format2.setDoubleBuffer(false);
       
   432     QVERIFY(format1 == format2);
       
   433     QVERIFY(!(format1 != format2));
       
   434 
       
   435     format1.setDepthBufferSize(8);
       
   436     QVERIFY(!(format1 == format2));
       
   437     QVERIFY(format1 != format2);
       
   438     format2.setDepthBufferSize(8);
       
   439     QVERIFY(format1 == format2);
       
   440     QVERIFY(!(format1 != format2));
       
   441 
       
   442     format1.setAccumBufferSize(8);
       
   443     QVERIFY(!(format1 == format2));
       
   444     QVERIFY(format1 != format2);
       
   445     format2.setAccumBufferSize(8);
       
   446     QVERIFY(format1 == format2);
       
   447     QVERIFY(!(format1 != format2));
       
   448 
       
   449     format1.setRedBufferSize(8);
       
   450     QVERIFY(!(format1 == format2));
       
   451     QVERIFY(format1 != format2);
       
   452     format2.setRedBufferSize(8);
       
   453     QVERIFY(format1 == format2);
       
   454     QVERIFY(!(format1 != format2));
       
   455 
       
   456     format1.setGreenBufferSize(8);
       
   457     QVERIFY(!(format1 == format2));
       
   458     QVERIFY(format1 != format2);
       
   459     format2.setGreenBufferSize(8);
       
   460     QVERIFY(format1 == format2);
       
   461     QVERIFY(!(format1 != format2));
       
   462 
       
   463     format1.setBlueBufferSize(8);
       
   464     QVERIFY(!(format1 == format2));
       
   465     QVERIFY(format1 != format2);
       
   466     format2.setBlueBufferSize(8);
       
   467     QVERIFY(format1 == format2);
       
   468     QVERIFY(!(format1 != format2));
       
   469 
       
   470     format1.setAlphaBufferSize(8);
       
   471     QVERIFY(!(format1 == format2));
       
   472     QVERIFY(format1 != format2);
       
   473     format2.setAlphaBufferSize(8);
       
   474     QVERIFY(format1 == format2);
       
   475     QVERIFY(!(format1 != format2));
       
   476 
       
   477     format1.setStencilBufferSize(8);
       
   478     QVERIFY(!(format1 == format2));
       
   479     QVERIFY(format1 != format2);
       
   480     format2.setStencilBufferSize(8);
       
   481     QVERIFY(format1 == format2);
       
   482     QVERIFY(!(format1 != format2));
       
   483 
       
   484     format1.setSamples(8);
       
   485     QVERIFY(!(format1 == format2));
       
   486     QVERIFY(format1 != format2);
       
   487     format2.setSamples(8);
       
   488     QVERIFY(format1 == format2);
       
   489     QVERIFY(!(format1 != format2));
       
   490 
       
   491     format1.setSwapInterval(8);
       
   492     QVERIFY(!(format1 == format2));
       
   493     QVERIFY(format1 != format2);
       
   494     format2.setSwapInterval(8);
       
   495     QVERIFY(format1 == format2);
       
   496     QVERIFY(!(format1 != format2));
       
   497 
       
   498     format1.setPlane(8);
       
   499     QVERIFY(!(format1 == format2));
       
   500     QVERIFY(format1 != format2);
       
   501     format2.setPlane(8);
       
   502     QVERIFY(format1 == format2);
       
   503     QVERIFY(!(format1 != format2));
       
   504 
       
   505     // Copy constructor and assignment for QGLFormat.
       
   506     QGLFormat format3(format1);
       
   507     QGLFormat format4;
       
   508     QVERIFY(format1 == format3);
       
   509     QVERIFY(format1 != format4);
       
   510     format4 = format1;
       
   511     QVERIFY(format1 == format4);
       
   512 
       
   513     // Check that modifying a copy doesn't affect the original.
       
   514     format3.setRedBufferSize(16);
       
   515     format4.setPlane(16);
       
   516     QCOMPARE(format1.redBufferSize(), 8);
       
   517     QCOMPARE(format1.plane(), 8);
       
   518 
       
   519     // Check the QGLFormat constructor that takes an option list.
       
   520     QGLFormat format5
       
   521         (QGL::DepthBuffer | QGL::StereoBuffers | QGL::ColorIndex, 3);
       
   522     QVERIFY(format5.depth());
       
   523     QVERIFY(format5.stereo());
       
   524     QVERIFY(format5.doubleBuffer());        // From defaultFormat()
       
   525     QVERIFY(!format5.hasOverlay());         // From defaultFormat()
       
   526     QVERIFY(!format5.rgba());
       
   527     QCOMPARE(format5.plane(), 3);
       
   528 
       
   529     // The default format should be the same as QGLFormat().
       
   530     QVERIFY(QGLFormat::defaultFormat() == QGLFormat());
       
   531 
       
   532     // Modify the default format and check that it was changed.
       
   533     QGLFormat::setDefaultFormat(format1);
       
   534     QVERIFY(QGLFormat::defaultFormat() == format1);
       
   535 
       
   536     // Restore the default format.
       
   537     QGLFormat::setDefaultFormat(QGLFormat());
       
   538     QVERIFY(QGLFormat::defaultFormat() == QGLFormat());
       
   539 
       
   540     // Check the default overlay format's expected values.
       
   541     QGLFormat overlay(QGLFormat::defaultOverlayFormat());
       
   542     QCOMPARE(overlay.depthBufferSize(), -1);
       
   543     QCOMPARE(overlay.accumBufferSize(), -1);
       
   544     QCOMPARE(overlay.redBufferSize(), -1);
       
   545     QCOMPARE(overlay.greenBufferSize(), -1);
       
   546     QCOMPARE(overlay.blueBufferSize(), -1);
       
   547     QCOMPARE(overlay.alphaBufferSize(), -1);
       
   548     QCOMPARE(overlay.samples(), -1);
       
   549     QCOMPARE(overlay.swapInterval(), -1);
       
   550     QCOMPARE(overlay.plane(), 1);
       
   551     QVERIFY(!overlay.sampleBuffers());
       
   552     QVERIFY(!overlay.doubleBuffer());
       
   553     QVERIFY(!overlay.depth());
       
   554     QVERIFY(!overlay.rgba());
       
   555     QVERIFY(!overlay.alpha());
       
   556     QVERIFY(!overlay.accum());
       
   557     QVERIFY(!overlay.stencil());
       
   558     QVERIFY(!overlay.stereo());
       
   559     QVERIFY(overlay.directRendering()); // Only option that should be on.
       
   560     QVERIFY(!overlay.hasOverlay());     // Overlay doesn't need an overlay!
       
   561 
       
   562     // Modify the default overlay format and check that it was changed.
       
   563     QGLFormat::setDefaultOverlayFormat(format1);
       
   564     QVERIFY(QGLFormat::defaultOverlayFormat() == format1);
       
   565 
       
   566     // Restore the default overlay format.
       
   567     QGLFormat::setDefaultOverlayFormat(overlay);
       
   568     QVERIFY(QGLFormat::defaultOverlayFormat() == overlay);
       
   569 
       
   570     MyGLContext obj2(obj1);
       
   571     // bool QGLContext::windowCreated()
       
   572     // void QGLContext::setWindowCreated(bool)
       
   573     obj2.setWindowCreated(false);
       
   574     QCOMPARE(false, obj2.windowCreated());
       
   575     obj2.setWindowCreated(true);
       
   576     QCOMPARE(true, obj2.windowCreated());
       
   577 
       
   578     // bool QGLContext::initialized()
       
   579     // void QGLContext::setInitialized(bool)
       
   580     obj2.setInitialized(false);
       
   581     QCOMPARE(false, obj2.initialized());
       
   582     obj2.setInitialized(true);
       
   583     QCOMPARE(true, obj2.initialized());
       
   584 
       
   585     MyGLWidget obj3;
       
   586     // bool QGLWidget::autoBufferSwap()
       
   587     // void QGLWidget::setAutoBufferSwap(bool)
       
   588     obj3.setAutoBufferSwap(false);
       
   589     QCOMPARE(false, obj3.autoBufferSwap());
       
   590     obj3.setAutoBufferSwap(true);
       
   591     QCOMPARE(true, obj3.autoBufferSwap());
       
   592 }
       
   593 
       
   594 #ifdef QT_BUILD_INTERNAL
       
   595 QT_BEGIN_NAMESPACE
       
   596 extern QGLFormat::OpenGLVersionFlags qOpenGLVersionFlagsFromString(const QString &versionString);
       
   597 QT_END_NAMESPACE
       
   598 #endif
       
   599 
       
   600 void tst_QGL::openGLVersionCheck()
       
   601 {
       
   602 #ifdef QT_BUILD_INTERNAL
       
   603     if (!QGLFormat::hasOpenGL())
       
   604         QSKIP("QGL not supported on this platform", SkipAll);
       
   605 
       
   606     QString versionString;
       
   607     QGLFormat::OpenGLVersionFlags expectedFlag;
       
   608     QGLFormat::OpenGLVersionFlags versionFlag;
       
   609 
       
   610     versionString = "1.1 Irix 6.5";
       
   611     expectedFlag = QGLFormat::OpenGL_Version_1_1;
       
   612     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   613     QCOMPARE(versionFlag, expectedFlag);
       
   614 
       
   615     versionString = "1.2 Microsoft";
       
   616     expectedFlag = QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1;
       
   617     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   618     QCOMPARE(versionFlag, expectedFlag);
       
   619 
       
   620     versionString = "1.2.1";
       
   621     expectedFlag = QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1;
       
   622     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   623     QCOMPARE(versionFlag, expectedFlag);
       
   624 
       
   625     versionString = "1.3 NVIDIA";
       
   626     expectedFlag = QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1;
       
   627     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   628     QCOMPARE(versionFlag, expectedFlag);
       
   629 
       
   630     versionString = "1.4";
       
   631     expectedFlag = QGLFormat::OpenGL_Version_1_4 | QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1;
       
   632     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   633     QCOMPARE(versionFlag, expectedFlag);
       
   634 
       
   635     versionString = "1.5 NVIDIA";
       
   636     expectedFlag = QGLFormat::OpenGL_Version_1_5 | QGLFormat::OpenGL_Version_1_4 | QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1;
       
   637     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   638     QCOMPARE(versionFlag, expectedFlag);
       
   639 
       
   640     versionString = "2.0.2 NVIDIA 87.62";
       
   641     expectedFlag = QGLFormat::OpenGL_Version_2_0 | QGLFormat::OpenGL_Version_1_5 | QGLFormat::OpenGL_Version_1_4 | QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1;
       
   642     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   643     QCOMPARE(versionFlag, expectedFlag);
       
   644 
       
   645     versionString = "2.1 NVIDIA";
       
   646     expectedFlag = QGLFormat::OpenGL_Version_2_1 | QGLFormat::OpenGL_Version_2_0 | QGLFormat::OpenGL_Version_1_5 | QGLFormat::OpenGL_Version_1_4 | QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1;
       
   647     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   648     QCOMPARE(versionFlag, expectedFlag);
       
   649 
       
   650     versionString = "2.1";
       
   651     expectedFlag = QGLFormat::OpenGL_Version_2_1 | QGLFormat::OpenGL_Version_2_0 | QGLFormat::OpenGL_Version_1_5 | QGLFormat::OpenGL_Version_1_4 | QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1;
       
   652     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   653     QCOMPARE(versionFlag, expectedFlag);
       
   654 
       
   655     versionString = "OpenGL ES-CM 1.0 ATI";
       
   656     expectedFlag = QGLFormat::OpenGL_ES_Common_Version_1_0 | QGLFormat::OpenGL_ES_CommonLite_Version_1_0;
       
   657     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   658     QCOMPARE(versionFlag, expectedFlag);
       
   659 
       
   660     versionString = "OpenGL ES-CL 1.0 ATI";
       
   661     expectedFlag = QGLFormat::OpenGL_ES_CommonLite_Version_1_0;
       
   662     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   663     QCOMPARE(versionFlag, expectedFlag);
       
   664 
       
   665     versionString = "OpenGL ES-CM 1.1 ATI";
       
   666     expectedFlag = QGLFormat::OpenGL_ES_Common_Version_1_1 | QGLFormat::OpenGL_ES_CommonLite_Version_1_1 | QGLFormat::OpenGL_ES_Common_Version_1_0 | QGLFormat::OpenGL_ES_CommonLite_Version_1_0;
       
   667     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   668     QCOMPARE(versionFlag, expectedFlag);
       
   669 
       
   670     versionString = "OpenGL ES-CL 1.1 ATI";
       
   671     expectedFlag = QGLFormat::OpenGL_ES_CommonLite_Version_1_1 | QGLFormat::OpenGL_ES_CommonLite_Version_1_0;
       
   672     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   673     QCOMPARE(versionFlag, expectedFlag);
       
   674 
       
   675     versionString = "OpenGL ES 2.0 ATI";
       
   676     expectedFlag = QGLFormat::OpenGL_ES_Version_2_0;
       
   677     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   678     QCOMPARE(versionFlag, expectedFlag);
       
   679 
       
   680     versionString = "3.0";
       
   681     expectedFlag = QGLFormat::OpenGL_Version_3_0 | QGLFormat::OpenGL_Version_2_1 | QGLFormat::OpenGL_Version_2_0 | QGLFormat::OpenGL_Version_1_5 | QGLFormat::OpenGL_Version_1_4 | QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1;
       
   682     versionFlag = qOpenGLVersionFlagsFromString(versionString);
       
   683     QCOMPARE(versionFlag, expectedFlag);
       
   684 
       
   685     QGLWidget glWidget;
       
   686     glWidget.show();
       
   687     glWidget.makeCurrent();
       
   688 
       
   689     // This is unfortunately the only test we can make on the actual openGLVersionFlags()
       
   690     // However, the complicated parts are in openGLVersionFlags(const QString &versionString)
       
   691     // tested above
       
   692 
       
   693 #if defined(QT_OPENGL_ES_1)
       
   694     QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Common_Version_1_0);
       
   695 #elif defined(QT_OPENGL_ES_1_CL)
       
   696     QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_CommonLite_Version_1_0);
       
   697 #elif defined(QT_OPENGL_ES_2)
       
   698     QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0);
       
   699 #else
       
   700     QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1);
       
   701 #endif //defined(QT_OPENGL_ES_1)
       
   702 #endif //QT_BUILD_INTERNAL
       
   703 }
       
   704 
       
   705 class UnclippedWidget : public QWidget
       
   706 {
       
   707 public:
       
   708     void paintEvent(QPaintEvent *)
       
   709     {
       
   710         QPainter p(this);
       
   711         p.fillRect(rect().adjusted(-1000, -1000, 1000, 1000), Qt::black);
       
   712     }
       
   713 };
       
   714 
       
   715 void tst_QGL::graphicsViewClipping()
       
   716 {
       
   717     const int size = 64;
       
   718     UnclippedWidget *widget = new UnclippedWidget;
       
   719     widget->setFixedSize(size, size);
       
   720 
       
   721     QGraphicsScene scene;
       
   722 
       
   723     scene.addWidget(widget)->setPos(0, 0);
       
   724 
       
   725     QGraphicsView view(&scene);
       
   726     view.resize(2*size, 2*size);
       
   727 
       
   728     QGLWidget *viewport = new QGLWidget;
       
   729     view.setViewport(viewport);
       
   730     view.show();
       
   731 
       
   732     if (!viewport->isValid())
       
   733         return;
       
   734 
       
   735     scene.setSceneRect(view.viewport()->rect());
       
   736 
       
   737 #ifdef Q_WS_X11
       
   738     qt_x11_wait_for_window_manager(&view);
       
   739 #endif
       
   740     QTest::qWait(500);
       
   741 
       
   742     QImage image = viewport->grabFrameBuffer();
       
   743     QImage expected = image;
       
   744 
       
   745     QPainter p(&expected);
       
   746     p.fillRect(expected.rect(), Qt::white);
       
   747     p.fillRect(QRect(0, 0, size, size), Qt::black);
       
   748     p.end();
       
   749 
       
   750     QCOMPARE(image, expected);
       
   751 }
       
   752 
       
   753 void tst_QGL::partialGLWidgetUpdates_data()
       
   754 {
       
   755     QTest::addColumn<bool>("doubleBufferedContext");
       
   756     QTest::addColumn<bool>("autoFillBackground");
       
   757     QTest::addColumn<bool>("supportsPartialUpdates");
       
   758 
       
   759     QTest::newRow("Double buffered context") << true << true << false;
       
   760     QTest::newRow("Double buffered context without auto-fill background") << true << false << false;
       
   761     QTest::newRow("Single buffered context") << false << true << false;
       
   762     QTest::newRow("Single buffered context without auto-fill background") << false << false << true;
       
   763 }
       
   764 
       
   765 void tst_QGL::partialGLWidgetUpdates()
       
   766 {
       
   767     if (!QGLFormat::hasOpenGL())
       
   768         QSKIP("QGL not supported on this platform", SkipAll);
       
   769 
       
   770     QFETCH(bool, doubleBufferedContext);
       
   771     QFETCH(bool, autoFillBackground);
       
   772     QFETCH(bool, supportsPartialUpdates);
       
   773 
       
   774     class MyGLWidget : public QGLWidget
       
   775     {
       
   776         public:
       
   777             QRegion paintEventRegion;
       
   778             void paintEvent(QPaintEvent *e)
       
   779             {
       
   780                 paintEventRegion = e->region();
       
   781             }
       
   782     };
       
   783 
       
   784     QGLFormat format = QGLFormat::defaultFormat();
       
   785     format.setDoubleBuffer(doubleBufferedContext);
       
   786     QGLFormat::setDefaultFormat(format);
       
   787 
       
   788     MyGLWidget widget;
       
   789     widget.setFixedSize(150, 150);
       
   790     widget.setAutoFillBackground(autoFillBackground);
       
   791     widget.show();
       
   792 #ifdef Q_WS_X11
       
   793     qt_x11_wait_for_window_manager(&widget);
       
   794 #endif
       
   795     QTest::qWait(200);
       
   796 
       
   797     if (widget.format().doubleBuffer() != doubleBufferedContext)
       
   798         QSKIP("Platform does not support requested format", SkipAll);
       
   799 
       
   800     widget.paintEventRegion = QRegion();
       
   801     widget.repaint(50, 50, 50, 50);
       
   802 #ifdef Q_WS_MAC
       
   803     // repaint() is not immediate on the Mac; it has to go through the event loop.
       
   804     QTest::qWait(200);
       
   805 #endif
       
   806     if (supportsPartialUpdates)
       
   807         QCOMPARE(widget.paintEventRegion, QRegion(50, 50, 50, 50));
       
   808     else
       
   809         QCOMPARE(widget.paintEventRegion, QRegion(widget.rect()));
       
   810 }
       
   811 
       
   812 
       
   813 // This tests that rendering to a QGLPBuffer using QPainter works.
       
   814 void tst_QGL::glPBufferRendering()
       
   815 {
       
   816     if (!QGLPixelBuffer::hasOpenGLPbuffers())
       
   817         QSKIP("QGLPixelBuffer not supported on this platform", SkipSingle);
       
   818 
       
   819     QGLPixelBuffer* pbuf = new QGLPixelBuffer(128, 128);
       
   820 
       
   821     QPainter p;
       
   822     bool begun = p.begin(pbuf);
       
   823     QVERIFY(begun);
       
   824 
       
   825     QPaintEngine::Type engineType = p.paintEngine()->type();
       
   826     QVERIFY(engineType == QPaintEngine::OpenGL || engineType == QPaintEngine::OpenGL2);
       
   827 
       
   828     p.fillRect(0, 0, 128, 128, Qt::red);
       
   829     p.fillRect(32, 32, 64, 64, Qt::blue);
       
   830     p.end();
       
   831 
       
   832     QImage fb = pbuf->toImage();
       
   833     delete pbuf;
       
   834 
       
   835     QImage reference(128, 128, fb.format());
       
   836     p.begin(&reference);
       
   837     p.fillRect(0, 0, 128, 128, Qt::red);
       
   838     p.fillRect(32, 32, 64, 64, Qt::blue);
       
   839     p.end();
       
   840 
       
   841     QCOMPARE(fb, reference);
       
   842 }
       
   843 
       
   844 class GLWidget : public QGLWidget
       
   845 {
       
   846 public:
       
   847     GLWidget(QWidget* p = 0)
       
   848             : QGLWidget(p), beginOk(false), engineType(QPaintEngine::MaxUser) {}
       
   849     bool beginOk;
       
   850     QPaintEngine::Type engineType;
       
   851     void paintGL()
       
   852     {
       
   853         QPainter p;
       
   854         beginOk = p.begin(this);
       
   855         QPaintEngine* pe = p.paintEngine();
       
   856         engineType = pe->type();
       
   857 
       
   858         // This test only ensures it's possible to paint onto a QGLWidget. Full
       
   859         // paint engine feature testing is way out of scope!
       
   860 
       
   861         p.fillRect(0, 0, width(), height(), Qt::red);
       
   862         // No p.end() or swap buffers, should be done automatically
       
   863     }
       
   864 
       
   865 };
       
   866 
       
   867 void tst_QGL::glWidgetRendering()
       
   868 {
       
   869     GLWidget w;
       
   870     w.show();
       
   871 
       
   872 #ifdef Q_WS_X11
       
   873     qt_x11_wait_for_window_manager(&w);
       
   874 #endif
       
   875     QTest::qWait(200);
       
   876 
       
   877     QVERIFY(w.beginOk);
       
   878     QVERIFY(w.engineType == QPaintEngine::OpenGL || w.engineType == QPaintEngine::OpenGL2);
       
   879 
       
   880     QImage fb = w.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32);
       
   881     QImage reference(fb.size(), QImage::Format_RGB32);
       
   882     reference.fill(0xffff0000);
       
   883 
       
   884     QCOMPARE(fb, reference);
       
   885 }
       
   886 
       
   887 // NOTE: This tests that CombinedDepthStencil attachment works by assuming the
       
   888 //       GL2 engine is being used and is implemented the same way as it was when
       
   889 //       this autotest was written. If this is not the case, there may be some
       
   890 //       false-positives: I.e. The test passes when either the depth or stencil
       
   891 //       buffer is actually missing. But that's probably ok anyway.
       
   892 void tst_QGL::glFBORendering()
       
   893 {
       
   894     if (!QGLFramebufferObject::hasOpenGLFramebufferObjects())
       
   895         QSKIP("QGLFramebufferObject not supported on this platform", SkipSingle);
       
   896 
       
   897     QGLWidget glw;
       
   898     glw.makeCurrent();
       
   899 
       
   900     // No multisample with combined depth/stencil attachment:
       
   901     QGLFramebufferObjectFormat fboFormat;
       
   902     fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
       
   903 
       
   904     // Don't complicate things by using NPOT:
       
   905     QGLFramebufferObject *fbo = new QGLFramebufferObject(256, 128, fboFormat);
       
   906 
       
   907     QPainter fboPainter;
       
   908     bool painterBegun = fboPainter.begin(fbo);
       
   909     QVERIFY(painterBegun);
       
   910 
       
   911     QPainterPath intersectingPath;
       
   912     intersectingPath.moveTo(0, 0);
       
   913     intersectingPath.lineTo(100, 0);
       
   914     intersectingPath.lineTo(0, 100);
       
   915     intersectingPath.lineTo(100, 100);
       
   916     intersectingPath.closeSubpath();
       
   917 
       
   918     QPainterPath trianglePath;
       
   919     trianglePath.moveTo(50, 0);
       
   920     trianglePath.lineTo(100, 100);
       
   921     trianglePath.lineTo(0, 100);
       
   922     trianglePath.closeSubpath();
       
   923 
       
   924     fboPainter.fillRect(0, 0, fbo->width(), fbo->height(), Qt::red); // Background
       
   925     fboPainter.translate(14, 14);
       
   926     fboPainter.fillPath(intersectingPath, Qt::blue); // Test stencil buffer works
       
   927     fboPainter.translate(128, 0);
       
   928     fboPainter.setClipPath(trianglePath); // Test depth buffer works
       
   929     fboPainter.setTransform(QTransform()); // reset xform
       
   930     fboPainter.fillRect(0, 0, fbo->width(), fbo->height(), Qt::green);
       
   931     fboPainter.end();
       
   932 
       
   933     QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32);
       
   934     delete fbo;
       
   935 
       
   936     // As we're doing more than trivial painting, we can't just compare to
       
   937     // an image rendered with raster. Instead, we sample at well-defined
       
   938     // test-points:
       
   939     QCOMPARE(fb.pixel(39, 64), QColor(Qt::red).rgb());
       
   940     QCOMPARE(fb.pixel(89, 64), QColor(Qt::red).rgb());
       
   941     QCOMPARE(fb.pixel(64, 39), QColor(Qt::blue).rgb());
       
   942     QCOMPARE(fb.pixel(64, 89), QColor(Qt::blue).rgb());
       
   943 
       
   944     QCOMPARE(fb.pixel(167, 39), QColor(Qt::red).rgb());
       
   945     QCOMPARE(fb.pixel(217, 39), QColor(Qt::red).rgb());
       
   946     QCOMPARE(fb.pixel(192, 64), QColor(Qt::green).rgb());
       
   947 }
       
   948 
       
   949 
       
   950 // Tests multiple QPainters active on different FBOs at the same time, with
       
   951 // interleaving painting. Performance-wise, this is sub-optimal, but it still
       
   952 // has to work flawlessly
       
   953 void tst_QGL::multipleFBOInterleavedRendering()
       
   954 {
       
   955     if (!QGLFramebufferObject::hasOpenGLFramebufferObjects())
       
   956         QSKIP("QGLFramebufferObject not supported on this platform", SkipSingle);
       
   957 
       
   958     QGLWidget glw;
       
   959     glw.makeCurrent();
       
   960 
       
   961     // No multisample with combined depth/stencil attachment:
       
   962     QGLFramebufferObjectFormat fboFormat;
       
   963     fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
       
   964 
       
   965     QGLFramebufferObject *fbo1 = new QGLFramebufferObject(256, 128, fboFormat);
       
   966     QGLFramebufferObject *fbo2 = new QGLFramebufferObject(256, 128, fboFormat);
       
   967     QGLFramebufferObject *fbo3 = new QGLFramebufferObject(256, 128, fboFormat);
       
   968 
       
   969     QPainter fbo1Painter;
       
   970     QPainter fbo2Painter;
       
   971     QPainter fbo3Painter;
       
   972 
       
   973     QVERIFY(fbo1Painter.begin(fbo1));
       
   974     QVERIFY(fbo2Painter.begin(fbo2));
       
   975     QVERIFY(fbo3Painter.begin(fbo3));
       
   976 
       
   977     // Confirm we're using the GL2 engine, as interleaved rendering isn't supported
       
   978     // on the GL1 engine:
       
   979     if (fbo1Painter.paintEngine()->type() != QPaintEngine::OpenGL2)
       
   980         QSKIP("Interleaved GL rendering requires OpenGL 2.0 or higher", SkipSingle);
       
   981 
       
   982     QPainterPath intersectingPath;
       
   983     intersectingPath.moveTo(0, 0);
       
   984     intersectingPath.lineTo(100, 0);
       
   985     intersectingPath.lineTo(0, 100);
       
   986     intersectingPath.lineTo(100, 100);
       
   987     intersectingPath.closeSubpath();
       
   988 
       
   989     QPainterPath trianglePath;
       
   990     trianglePath.moveTo(50, 0);
       
   991     trianglePath.lineTo(100, 100);
       
   992     trianglePath.lineTo(0, 100);
       
   993     trianglePath.closeSubpath();
       
   994 
       
   995     fbo1Painter.fillRect(0, 0, fbo1->width(), fbo1->height(), Qt::red); // Background
       
   996     fbo2Painter.fillRect(0, 0, fbo2->width(), fbo2->height(), Qt::green); // Background
       
   997     fbo3Painter.fillRect(0, 0, fbo3->width(), fbo3->height(), Qt::blue); // Background
       
   998 
       
   999     fbo1Painter.translate(14, 14);
       
  1000     fbo2Painter.translate(14, 14);
       
  1001     fbo3Painter.translate(14, 14);
       
  1002 
       
  1003     fbo1Painter.fillPath(intersectingPath, Qt::blue); // Test stencil buffer works
       
  1004     fbo2Painter.fillPath(intersectingPath, Qt::red); // Test stencil buffer works
       
  1005     fbo3Painter.fillPath(intersectingPath, Qt::green); // Test stencil buffer works
       
  1006 
       
  1007     fbo1Painter.translate(128, 0);
       
  1008     fbo2Painter.translate(128, 0);
       
  1009     fbo3Painter.translate(128, 0);
       
  1010 
       
  1011     fbo1Painter.setClipPath(trianglePath);
       
  1012     fbo2Painter.setClipPath(trianglePath);
       
  1013     fbo3Painter.setClipPath(trianglePath);
       
  1014 
       
  1015     fbo1Painter.setTransform(QTransform()); // reset xform
       
  1016     fbo2Painter.setTransform(QTransform()); // reset xform
       
  1017     fbo3Painter.setTransform(QTransform()); // reset xform
       
  1018 
       
  1019     fbo1Painter.fillRect(0, 0, fbo1->width(), fbo1->height(), Qt::green);
       
  1020     fbo2Painter.fillRect(0, 0, fbo2->width(), fbo2->height(), Qt::blue);
       
  1021     fbo3Painter.fillRect(0, 0, fbo3->width(), fbo3->height(), Qt::red);
       
  1022 
       
  1023     fbo1Painter.end();
       
  1024     fbo2Painter.end();
       
  1025     fbo3Painter.end();
       
  1026 
       
  1027     QImage fb1 = fbo1->toImage().convertToFormat(QImage::Format_RGB32);
       
  1028     QImage fb2 = fbo2->toImage().convertToFormat(QImage::Format_RGB32);
       
  1029     QImage fb3 = fbo3->toImage().convertToFormat(QImage::Format_RGB32);
       
  1030     delete fbo1;
       
  1031     delete fbo2;
       
  1032     delete fbo3;
       
  1033 
       
  1034     // As we're doing more than trivial painting, we can't just compare to
       
  1035     // an image rendered with raster. Instead, we sample at well-defined
       
  1036     // test-points:
       
  1037     QCOMPARE(fb1.pixel(39, 64), QColor(Qt::red).rgb());
       
  1038     QCOMPARE(fb1.pixel(89, 64), QColor(Qt::red).rgb());
       
  1039     QCOMPARE(fb1.pixel(64, 39), QColor(Qt::blue).rgb());
       
  1040     QCOMPARE(fb1.pixel(64, 89), QColor(Qt::blue).rgb());
       
  1041     QCOMPARE(fb1.pixel(167, 39), QColor(Qt::red).rgb());
       
  1042     QCOMPARE(fb1.pixel(217, 39), QColor(Qt::red).rgb());
       
  1043     QCOMPARE(fb1.pixel(192, 64), QColor(Qt::green).rgb());
       
  1044 
       
  1045     QCOMPARE(fb2.pixel(39, 64), QColor(Qt::green).rgb());
       
  1046     QCOMPARE(fb2.pixel(89, 64), QColor(Qt::green).rgb());
       
  1047     QCOMPARE(fb2.pixel(64, 39), QColor(Qt::red).rgb());
       
  1048     QCOMPARE(fb2.pixel(64, 89), QColor(Qt::red).rgb());
       
  1049     QCOMPARE(fb2.pixel(167, 39), QColor(Qt::green).rgb());
       
  1050     QCOMPARE(fb2.pixel(217, 39), QColor(Qt::green).rgb());
       
  1051     QCOMPARE(fb2.pixel(192, 64), QColor(Qt::blue).rgb());
       
  1052 
       
  1053     QCOMPARE(fb3.pixel(39, 64), QColor(Qt::blue).rgb());
       
  1054     QCOMPARE(fb3.pixel(89, 64), QColor(Qt::blue).rgb());
       
  1055     QCOMPARE(fb3.pixel(64, 39), QColor(Qt::green).rgb());
       
  1056     QCOMPARE(fb3.pixel(64, 89), QColor(Qt::green).rgb());
       
  1057     QCOMPARE(fb3.pixel(167, 39), QColor(Qt::blue).rgb());
       
  1058     QCOMPARE(fb3.pixel(217, 39), QColor(Qt::blue).rgb());
       
  1059     QCOMPARE(fb3.pixel(192, 64), QColor(Qt::red).rgb());
       
  1060 }
       
  1061 
       
  1062 class FBOUseInGLWidget : public QGLWidget
       
  1063 {
       
  1064 public:
       
  1065     bool widgetPainterBeginOk;
       
  1066     bool fboPainterBeginOk;
       
  1067     QImage fboImage;
       
  1068 protected:
       
  1069     void paintEvent(QPaintEvent*)
       
  1070     {
       
  1071         QPainter widgetPainter;
       
  1072         widgetPainterBeginOk = widgetPainter.begin(this);
       
  1073         QGLFramebufferObjectFormat fboFormat;
       
  1074         fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
       
  1075         QGLFramebufferObject *fbo = new QGLFramebufferObject(128, 128, fboFormat);
       
  1076 
       
  1077         QPainter fboPainter;
       
  1078         fboPainterBeginOk = fboPainter.begin(fbo);
       
  1079         fboPainter.fillRect(0, 0, 128, 128, Qt::red);
       
  1080         fboPainter.end();
       
  1081         fboImage = fbo->toImage();
       
  1082 
       
  1083         widgetPainter.fillRect(rect(), Qt::blue);
       
  1084 
       
  1085         delete fbo;
       
  1086     }
       
  1087 
       
  1088 };
       
  1089 
       
  1090 void tst_QGL::glFBOUseInGLWidget()
       
  1091 {
       
  1092     if (!QGLFramebufferObject::hasOpenGLFramebufferObjects())
       
  1093         QSKIP("QGLFramebufferObject not supported on this platform", SkipSingle);
       
  1094 
       
  1095     FBOUseInGLWidget w;
       
  1096     w.resize(128, 128);
       
  1097     w.show();
       
  1098 
       
  1099 #ifdef Q_WS_X11
       
  1100     qt_x11_wait_for_window_manager(&w);
       
  1101 #endif
       
  1102     QTest::qWait(200);
       
  1103 
       
  1104     QVERIFY(w.widgetPainterBeginOk);
       
  1105     QVERIFY(w.fboPainterBeginOk);
       
  1106 
       
  1107     QImage widgetFB = w.grabFrameBuffer(false);
       
  1108     QImage widgetReference(widgetFB.size(), widgetFB.format());
       
  1109     widgetReference.fill(0xff0000ff);
       
  1110     QCOMPARE(widgetFB, widgetReference);
       
  1111 
       
  1112     QImage fboReference(w.fboImage.size(), w.fboImage.format());
       
  1113     fboReference.fill(0xffff0000);
       
  1114     QCOMPARE(w.fboImage, fboReference);
       
  1115 }
       
  1116 
       
  1117 void tst_QGL::glWidgetReparent()
       
  1118 {
       
  1119     // Try it as a top-level first:
       
  1120     GLWidget *widget = new GLWidget;
       
  1121     widget->setGeometry(0, 0, 200, 30);
       
  1122     widget->show();
       
  1123 
       
  1124     QWidget grandParentWidget;
       
  1125     grandParentWidget.setPalette(Qt::blue);
       
  1126     QVBoxLayout grandParentLayout(&grandParentWidget);
       
  1127 
       
  1128     QWidget parentWidget(&grandParentWidget);
       
  1129     grandParentLayout.addWidget(&parentWidget);
       
  1130     parentWidget.setPalette(Qt::green);
       
  1131     parentWidget.setAutoFillBackground(true);
       
  1132     QVBoxLayout parentLayout(&parentWidget);
       
  1133 
       
  1134     grandParentWidget.setGeometry(0, 100, 200, 200);
       
  1135     grandParentWidget.show();
       
  1136 
       
  1137 #ifdef Q_WS_X11
       
  1138     qt_x11_wait_for_window_manager(widget);
       
  1139     qt_x11_wait_for_window_manager(&parentWidget);
       
  1140 #endif
       
  1141     QTest::qWait(200);
       
  1142 
       
  1143     QVERIFY(parentWidget.children().count() == 1); // The layout
       
  1144 
       
  1145     // Now both widgets should be created & shown, time to re-parent:
       
  1146     parentLayout.addWidget(widget);
       
  1147 
       
  1148 #ifdef Q_WS_X11
       
  1149     qt_x11_wait_for_window_manager(&parentWidget);
       
  1150 #endif
       
  1151     QTest::qWait(200);
       
  1152 
       
  1153     QVERIFY(parentWidget.children().count() == 2); // Layout & glwidget
       
  1154     QVERIFY(parentWidget.children().contains(widget));
       
  1155     QVERIFY(widget->height() > 30);
       
  1156 
       
  1157     delete widget;
       
  1158 
       
  1159 #ifdef Q_WS_X11
       
  1160     qt_x11_wait_for_window_manager(&parentWidget);
       
  1161 #endif
       
  1162     QTest::qWait(200);
       
  1163 
       
  1164     QVERIFY(parentWidget.children().count() == 1); // The layout
       
  1165 
       
  1166     // Now do pretty much the same thing, but don't show the
       
  1167     // widget first:
       
  1168     widget = new GLWidget;
       
  1169     parentLayout.addWidget(widget);
       
  1170 
       
  1171 #ifdef Q_WS_X11
       
  1172     qt_x11_wait_for_window_manager(&parentWidget);
       
  1173 #endif
       
  1174     QTest::qWait(200);
       
  1175 
       
  1176     QVERIFY(parentWidget.children().count() == 2); // Layout & glwidget
       
  1177     QVERIFY(parentWidget.children().contains(widget));
       
  1178     QVERIFY(widget->height() > 30);
       
  1179 
       
  1180     delete widget;
       
  1181 }
       
  1182 
       
  1183 class RenderPixmapWidget : public QGLWidget
       
  1184 {
       
  1185 protected:
       
  1186     void initializeGL() {
       
  1187         // Set some gl state:
       
  1188         glClearColor(1.0, 0.0, 0.0, 1.0);
       
  1189     }
       
  1190 
       
  1191     void paintGL() {
       
  1192         glClear(GL_COLOR_BUFFER_BIT);
       
  1193     }
       
  1194 };
       
  1195 
       
  1196 void tst_QGL::glWidgetRenderPixmap()
       
  1197 {
       
  1198     RenderPixmapWidget *w = new RenderPixmapWidget;
       
  1199 
       
  1200     QPixmap pm = w->renderPixmap(100, 100, false);
       
  1201 
       
  1202     delete w;
       
  1203 
       
  1204     QImage fb = pm.toImage().convertToFormat(QImage::Format_RGB32);
       
  1205     QImage reference(fb.size(), QImage::Format_RGB32);
       
  1206     reference.fill(0xffff0000);
       
  1207 
       
  1208     QCOMPARE(fb, reference);
       
  1209 }
       
  1210 
       
  1211 
       
  1212 // When using multiple FBOs at the same time, unbinding one FBO should re-bind the
       
  1213 // previous. I.e. It should be possible to have a stack of FBOs where pop'ing there
       
  1214 // top re-binds the one underneeth.
       
  1215 void tst_QGL::stackedFBOs()
       
  1216 {
       
  1217     if (!QGLFramebufferObject::hasOpenGLFramebufferObjects())
       
  1218         QSKIP("QGLFramebufferObject not supported on this platform", SkipSingle);
       
  1219 
       
  1220     QGLWidget glw;
       
  1221     glw.show();
       
  1222 
       
  1223 #ifdef Q_WS_X11
       
  1224     qt_x11_wait_for_window_manager(&glw);
       
  1225 #endif
       
  1226     QTest::qWait(200);
       
  1227 
       
  1228     glw.makeCurrent();
       
  1229 
       
  1230     // No multisample with combined depth/stencil attachment:
       
  1231     QGLFramebufferObjectFormat fboFormat;
       
  1232     fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
       
  1233 
       
  1234     // Don't complicate things by using NPOT:
       
  1235     QGLFramebufferObject *fbo1 = new QGLFramebufferObject(128, 128, fboFormat);
       
  1236     QGLFramebufferObject *fbo2 = new QGLFramebufferObject(128, 128, fboFormat);
       
  1237     QGLFramebufferObject *fbo3 = new QGLFramebufferObject(128, 128, fboFormat);
       
  1238 
       
  1239     glClearColor(1.0, 0.0, 1.0, 1.0);
       
  1240     glClear(GL_COLOR_BUFFER_BIT);
       
  1241 
       
  1242     fbo1->bind();
       
  1243         glClearColor(1.0, 0.0, 0.0, 1.0);
       
  1244         glClear(GL_COLOR_BUFFER_BIT);
       
  1245 
       
  1246         fbo2->bind();
       
  1247             glClearColor(0.0, 1.0, 0.0, 1.0);
       
  1248             glClear(GL_COLOR_BUFFER_BIT);
       
  1249 
       
  1250             fbo3->bind();
       
  1251                 glClearColor(0.0, 0.0, 1.0, 1.0);
       
  1252                 glClear(GL_COLOR_BUFFER_BIT);
       
  1253                 glScissor(32, 32, 64, 64);
       
  1254                 glEnable(GL_SCISSOR_TEST);
       
  1255                 glClearColor(0.0, 1.0, 1.0, 1.0);
       
  1256                 glClear(GL_COLOR_BUFFER_BIT);
       
  1257             fbo3->release();
       
  1258 
       
  1259             // Scissor rect & test should be left untouched by the fbo release...
       
  1260             glClearColor(0.0, 0.0, 0.0, 1.0);
       
  1261             glClear(GL_COLOR_BUFFER_BIT);
       
  1262         fbo2->release();
       
  1263 
       
  1264         glClearColor(1.0, 1.0, 1.0, 1.0);
       
  1265         glClear(GL_COLOR_BUFFER_BIT);
       
  1266     fbo1->release();
       
  1267 
       
  1268     glClearColor(1.0, 1.0, 0.0, 1.0);
       
  1269     glClear(GL_COLOR_BUFFER_BIT);
       
  1270 
       
  1271     glw.swapBuffers();
       
  1272 
       
  1273     QImage widgetFB = glw.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32);
       
  1274     QImage fb1 = fbo1->toImage().convertToFormat(QImage::Format_RGB32);
       
  1275     QImage fb2 = fbo2->toImage().convertToFormat(QImage::Format_RGB32);
       
  1276     QImage fb3 = fbo3->toImage().convertToFormat(QImage::Format_RGB32);
       
  1277 
       
  1278     delete fbo1;
       
  1279     delete fbo2;
       
  1280     delete fbo3;
       
  1281 
       
  1282     QImage widgetReference(widgetFB.size(), widgetFB.format());
       
  1283     QImage fb1Reference(fb1.size(), fb1.format());
       
  1284     QImage fb2Reference(fb2.size(), fb2.format());
       
  1285     QImage fb3Reference(fb3.size(), fb3.format());
       
  1286 
       
  1287     QPainter widgetReferencePainter(&widgetReference);
       
  1288     QPainter fb1ReferencePainter(&fb1Reference);
       
  1289     QPainter fb2ReferencePainter(&fb2Reference);
       
  1290     QPainter fb3ReferencePainter(&fb3Reference);
       
  1291 
       
  1292     widgetReferencePainter.fillRect(0, 0, widgetReference.width(), widgetReference.height(), Qt::magenta);
       
  1293     fb1ReferencePainter.fillRect(0, 0, fb1Reference.width(), fb1Reference.height(), Qt::red);
       
  1294     fb2ReferencePainter.fillRect(0, 0, fb2Reference.width(), fb2Reference.height(), Qt::green);
       
  1295     fb3ReferencePainter.fillRect(0, 0, fb3Reference.width(), fb3Reference.height(), Qt::blue);
       
  1296 
       
  1297     // Flip y-coords to match GL for the widget (which can be any size)
       
  1298     widgetReferencePainter.fillRect(32, glw.height() - 96, 64, 64, Qt::yellow);
       
  1299     fb1ReferencePainter.fillRect(32, 32, 64, 64, Qt::white);
       
  1300     fb2ReferencePainter.fillRect(32, 32, 64, 64, Qt::black);
       
  1301     fb3ReferencePainter.fillRect(32, 32, 64, 64, Qt::cyan);
       
  1302 
       
  1303     widgetReferencePainter.end();
       
  1304     fb1ReferencePainter.end();
       
  1305     fb2ReferencePainter.end();
       
  1306     fb3ReferencePainter.end();
       
  1307 
       
  1308     QCOMPARE(widgetFB, widgetReference);
       
  1309     QCOMPARE(fb1, fb1Reference);
       
  1310     QCOMPARE(fb2, fb2Reference);
       
  1311     QCOMPARE(fb3, fb3Reference);
       
  1312 }
       
  1313 
       
  1314 
       
  1315 class ColormapExtended : public QGLColormap
       
  1316 {
       
  1317 public:
       
  1318     ColormapExtended() {}
       
  1319 
       
  1320     Qt::HANDLE handle() { return QGLColormap::handle(); }
       
  1321     void setHandle(Qt::HANDLE handle) { QGLColormap::setHandle(handle); }
       
  1322 };
       
  1323 
       
  1324 void tst_QGL::colormap()
       
  1325 {
       
  1326     // Check the properties of the default empty colormap.
       
  1327     QGLColormap cmap1;
       
  1328     QVERIFY(cmap1.isEmpty());
       
  1329     QCOMPARE(cmap1.size(), 0);
       
  1330     QVERIFY(cmap1.entryRgb(0) == 0);
       
  1331     QVERIFY(cmap1.entryRgb(-1) == 0);
       
  1332     QVERIFY(cmap1.entryRgb(100) == 0);
       
  1333     QVERIFY(!cmap1.entryColor(0).isValid());
       
  1334     QVERIFY(!cmap1.entryColor(-1).isValid());
       
  1335     QVERIFY(!cmap1.entryColor(100).isValid());
       
  1336     QCOMPARE(cmap1.find(qRgb(255, 0, 0)), -1);
       
  1337     QCOMPARE(cmap1.findNearest(qRgb(255, 0, 0)), -1);
       
  1338 
       
  1339     // Set an entry and re-test.
       
  1340     cmap1.setEntry(56, qRgb(255, 0, 0));
       
  1341     // The colormap is still considered "empty" even though it
       
  1342     // has entries in it now.  The isEmpty() method is used to
       
  1343     // detect when the colormap is in use by a GL widget,
       
  1344     // not to detect when it is empty!
       
  1345     QVERIFY(cmap1.isEmpty());
       
  1346     QCOMPARE(cmap1.size(), 256);
       
  1347     QVERIFY(cmap1.entryRgb(0) == 0);
       
  1348     QVERIFY(cmap1.entryColor(0) == QColor(0, 0, 0, 255));
       
  1349     QVERIFY(cmap1.entryRgb(56) == qRgb(255, 0, 0));
       
  1350     QVERIFY(cmap1.entryColor(56) == QColor(255, 0, 0, 255));
       
  1351     QCOMPARE(cmap1.find(qRgb(255, 0, 0)), 56);
       
  1352     QCOMPARE(cmap1.findNearest(qRgb(255, 0, 0)), 56);
       
  1353 
       
  1354     // Set some more entries.
       
  1355     static QRgb const colors[] = {
       
  1356         qRgb(255, 0, 0),
       
  1357         qRgb(0, 255, 0),
       
  1358         qRgb(255, 255, 255),
       
  1359         qRgb(0, 0, 255),
       
  1360         qRgb(0, 0, 0)
       
  1361     };
       
  1362     cmap1.setEntry(57, QColor(0, 255, 0));
       
  1363     cmap1.setEntries(3, colors + 2, 58);
       
  1364     cmap1.setEntries(5, colors, 251);
       
  1365     int idx;
       
  1366     for (idx = 0; idx < 5; ++idx) {
       
  1367         QVERIFY(cmap1.entryRgb(56 + idx) == colors[idx]);
       
  1368         QVERIFY(cmap1.entryColor(56 + idx) == QColor(colors[idx]));
       
  1369         QVERIFY(cmap1.entryRgb(251 + idx) == colors[idx]);
       
  1370         QVERIFY(cmap1.entryColor(251 + idx) == QColor(colors[idx]));
       
  1371     }
       
  1372     QCOMPARE(cmap1.size(), 256);
       
  1373 
       
  1374     // Perform color lookups.
       
  1375     QCOMPARE(cmap1.find(qRgb(255, 0, 0)), 56);
       
  1376     QCOMPARE(cmap1.find(qRgb(0, 0, 0)), 60); // Actually finds 0, 0, 0, 255.
       
  1377     QCOMPARE(cmap1.find(qRgba(0, 0, 0, 0)), 0);
       
  1378     QCOMPARE(cmap1.find(qRgb(0, 255, 0)), 57);
       
  1379     QCOMPARE(cmap1.find(qRgb(255, 255, 255)), 58);
       
  1380     QCOMPARE(cmap1.find(qRgb(0, 0, 255)), 59);
       
  1381     QCOMPARE(cmap1.find(qRgb(140, 0, 0)), -1);
       
  1382     QCOMPARE(cmap1.find(qRgb(0, 140, 0)), -1);
       
  1383     QCOMPARE(cmap1.find(qRgb(0, 0, 140)), -1);
       
  1384     QCOMPARE(cmap1.find(qRgb(64, 0, 0)), -1);
       
  1385     QCOMPARE(cmap1.find(qRgb(0, 64, 0)), -1);
       
  1386     QCOMPARE(cmap1.find(qRgb(0, 0, 64)), -1);
       
  1387     QCOMPARE(cmap1.findNearest(qRgb(255, 0, 0)), 56);
       
  1388     QCOMPARE(cmap1.findNearest(qRgb(0, 0, 0)), 60);
       
  1389     QCOMPARE(cmap1.findNearest(qRgba(0, 0, 0, 0)), 0);
       
  1390     QCOMPARE(cmap1.findNearest(qRgb(0, 255, 0)), 57);
       
  1391     QCOMPARE(cmap1.findNearest(qRgb(255, 255, 255)), 58);
       
  1392     QCOMPARE(cmap1.findNearest(qRgb(0, 0, 255)), 59);
       
  1393     QCOMPARE(cmap1.findNearest(qRgb(140, 0, 0)), 56);
       
  1394     QCOMPARE(cmap1.findNearest(qRgb(0, 140, 0)), 57);
       
  1395     QCOMPARE(cmap1.findNearest(qRgb(0, 0, 140)), 59);
       
  1396     QCOMPARE(cmap1.findNearest(qRgb(64, 0, 0)), 0);
       
  1397     QCOMPARE(cmap1.findNearest(qRgb(0, 64, 0)), 0);
       
  1398     QCOMPARE(cmap1.findNearest(qRgb(0, 0, 64)), 0);
       
  1399 
       
  1400     // Make some copies of the colormap and check that they are the same.
       
  1401     QGLColormap cmap2(cmap1);
       
  1402     QGLColormap cmap3;
       
  1403     cmap3 = cmap1;
       
  1404     QVERIFY(cmap2.isEmpty());
       
  1405     QVERIFY(cmap3.isEmpty());
       
  1406     QCOMPARE(cmap2.size(), 256);
       
  1407     QCOMPARE(cmap3.size(), 256);
       
  1408     for (idx = 0; idx < 256; ++idx) {
       
  1409         QCOMPARE(cmap1.entryRgb(idx), cmap2.entryRgb(idx));
       
  1410         QCOMPARE(cmap1.entryRgb(idx), cmap3.entryRgb(idx));
       
  1411     }
       
  1412 
       
  1413     // Modify an entry in one of the copies and recheck the original.
       
  1414     cmap2.setEntry(45, qRgb(255, 0, 0));
       
  1415     for (idx = 0; idx < 256; ++idx) {
       
  1416         if (idx != 45)
       
  1417             QCOMPARE(cmap1.entryRgb(idx), cmap2.entryRgb(idx));
       
  1418         else
       
  1419             QCOMPARE(cmap2.entryRgb(45), qRgb(255, 0, 0));
       
  1420         QCOMPARE(cmap1.entryRgb(idx), cmap3.entryRgb(idx));
       
  1421     }
       
  1422 
       
  1423     // Check that setting the handle will cause isEmpty() to work right.
       
  1424     ColormapExtended cmap4;
       
  1425     cmap4.setEntry(56, qRgb(255, 0, 0));
       
  1426     QVERIFY(cmap4.isEmpty());
       
  1427     QCOMPARE(cmap4.size(), 256);
       
  1428     cmap4.setHandle(Qt::HANDLE(42));
       
  1429     QVERIFY(cmap4.handle() == Qt::HANDLE(42));
       
  1430     QVERIFY(!cmap4.isEmpty());
       
  1431     QCOMPARE(cmap4.size(), 256);
       
  1432 }
       
  1433 
       
  1434 #ifndef QT_OPENGL_ES
       
  1435 #define DEFAULT_FORMAT GL_RGBA8
       
  1436 #else
       
  1437 #define DEFAULT_FORMAT GL_RGBA
       
  1438 #endif
       
  1439 
       
  1440 #ifndef GL_TEXTURE_3D
       
  1441 #define GL_TEXTURE_3D 0x806F
       
  1442 #endif
       
  1443 
       
  1444 #ifndef GL_RGB16
       
  1445 #define GL_RGB16 0x8054
       
  1446 #endif
       
  1447 
       
  1448 void tst_QGL::fboFormat()
       
  1449 {
       
  1450     // Check the initial conditions.
       
  1451     QGLFramebufferObjectFormat format1;
       
  1452     QCOMPARE(format1.samples(), 0);
       
  1453     QVERIFY(format1.attachment() == QGLFramebufferObject::NoAttachment);
       
  1454     QCOMPARE(int(format1.textureTarget()), int(GL_TEXTURE_2D));
       
  1455     QCOMPARE(int(format1.internalTextureFormat()), int(DEFAULT_FORMAT));
       
  1456 
       
  1457     // Modify the values and re-check.
       
  1458     format1.setSamples(8);
       
  1459     format1.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
       
  1460     format1.setTextureTarget(GL_TEXTURE_3D);
       
  1461     format1.setInternalTextureFormat(GL_RGB16);
       
  1462     QCOMPARE(format1.samples(), 8);
       
  1463     QVERIFY(format1.attachment() == QGLFramebufferObject::CombinedDepthStencil);
       
  1464     QCOMPARE(int(format1.textureTarget()), int(GL_TEXTURE_3D));
       
  1465     QCOMPARE(int(format1.internalTextureFormat()), int(GL_RGB16));
       
  1466 
       
  1467     // Make copies and check that they are the same.
       
  1468     QGLFramebufferObjectFormat format2(format1);
       
  1469     QGLFramebufferObjectFormat format3;
       
  1470     QCOMPARE(format2.samples(), 8);
       
  1471     QVERIFY(format2.attachment() == QGLFramebufferObject::CombinedDepthStencil);
       
  1472     QCOMPARE(int(format2.textureTarget()), int(GL_TEXTURE_3D));
       
  1473     QCOMPARE(int(format2.internalTextureFormat()), int(GL_RGB16));
       
  1474     format3 = format1;
       
  1475     QCOMPARE(format3.samples(), 8);
       
  1476     QVERIFY(format3.attachment() == QGLFramebufferObject::CombinedDepthStencil);
       
  1477     QCOMPARE(int(format3.textureTarget()), int(GL_TEXTURE_3D));
       
  1478     QCOMPARE(int(format3.internalTextureFormat()), int(GL_RGB16));
       
  1479 
       
  1480     // Modify the copies and check that the original is unchanged.
       
  1481     format2.setSamples(9);
       
  1482     format3.setTextureTarget(GL_TEXTURE_2D);
       
  1483     QCOMPARE(format1.samples(), 8);
       
  1484     QVERIFY(format1.attachment() == QGLFramebufferObject::CombinedDepthStencil);
       
  1485     QCOMPARE(int(format1.textureTarget()), int(GL_TEXTURE_3D));
       
  1486     QCOMPARE(int(format1.internalTextureFormat()), int(GL_RGB16));
       
  1487 
       
  1488     // operator== and operator!= for QGLFramebufferObjectFormat.
       
  1489     QGLFramebufferObjectFormat format1c;
       
  1490     QGLFramebufferObjectFormat format2c;
       
  1491 
       
  1492     QVERIFY(format1c == format2c);
       
  1493     QVERIFY(!(format1c != format2c));
       
  1494     format1c.setSamples(8);
       
  1495     QVERIFY(!(format1c == format2c));
       
  1496     QVERIFY(format1c != format2c);
       
  1497     format2c.setSamples(8);
       
  1498     QVERIFY(format1c == format2c);
       
  1499     QVERIFY(!(format1c != format2c));
       
  1500 
       
  1501     format1c.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
       
  1502     QVERIFY(!(format1c == format2c));
       
  1503     QVERIFY(format1c != format2c);
       
  1504     format2c.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
       
  1505     QVERIFY(format1c == format2c);
       
  1506     QVERIFY(!(format1c != format2c));
       
  1507 
       
  1508     format1c.setTextureTarget(GL_TEXTURE_3D);
       
  1509     QVERIFY(!(format1c == format2c));
       
  1510     QVERIFY(format1c != format2c);
       
  1511     format2c.setTextureTarget(GL_TEXTURE_3D);
       
  1512     QVERIFY(format1c == format2c);
       
  1513     QVERIFY(!(format1c != format2c));
       
  1514 
       
  1515     format1c.setInternalTextureFormat(GL_RGB16);
       
  1516     QVERIFY(!(format1c == format2c));
       
  1517     QVERIFY(format1c != format2c);
       
  1518     format2c.setInternalTextureFormat(GL_RGB16);
       
  1519     QVERIFY(format1c == format2c);
       
  1520     QVERIFY(!(format1c != format2c));
       
  1521 
       
  1522     QGLFramebufferObjectFormat format3c(format1c);
       
  1523     QGLFramebufferObjectFormat format4c;
       
  1524     QVERIFY(format1c == format3c);
       
  1525     QVERIFY(!(format1c != format3c));
       
  1526     format3c.setInternalTextureFormat(DEFAULT_FORMAT);
       
  1527     QVERIFY(!(format1c == format3c));
       
  1528     QVERIFY(format1c != format3c);
       
  1529 
       
  1530     format4c = format1c;
       
  1531     QVERIFY(format1c == format4c);
       
  1532     QVERIFY(!(format1c != format4c));
       
  1533     format4c.setInternalTextureFormat(DEFAULT_FORMAT);
       
  1534     QVERIFY(!(format1c == format4c));
       
  1535     QVERIFY(format1c != format4c);
       
  1536 }
       
  1537 
       
  1538 void tst_QGL::testDontCrashOnDanglingResources()
       
  1539 {
       
  1540     // We have a number of Q_GLOBAL_STATICS inside the QtOpenGL
       
  1541     // library. This test is verify that we don't crash as a result of
       
  1542     // them calling into libgl on application shutdown.
       
  1543     QWidget *widget = new UnclippedWidget();
       
  1544     widget->show();
       
  1545     qApp->processEvents();
       
  1546     widget->hide();
       
  1547 }
       
  1548 
       
  1549 class ReplaceClippingGLWidget : public QGLWidget
       
  1550 {
       
  1551 public:
       
  1552     void paint(QPainter *painter)
       
  1553     {
       
  1554         painter->fillRect(rect(), Qt::white);
       
  1555 
       
  1556         QPainterPath path;
       
  1557         path.addRect(0, 0, 100, 100);
       
  1558         path.addRect(50, 50, 100, 100);
       
  1559 
       
  1560         painter->setClipRect(0, 0, 150, 150);
       
  1561         painter->fillPath(path, Qt::red);
       
  1562 
       
  1563         painter->translate(150, 150);
       
  1564         painter->setClipRect(0, 0, 150, 150);
       
  1565         painter->fillPath(path, Qt::red);
       
  1566     }
       
  1567 
       
  1568 protected:
       
  1569     void paintEvent(QPaintEvent*)
       
  1570     {
       
  1571         // clear the stencil with junk
       
  1572         glStencilMask(0xFFFF);
       
  1573         glClearStencil(0xFFFF);
       
  1574         glDisable(GL_STENCIL_TEST);
       
  1575         glDisable(GL_SCISSOR_TEST);
       
  1576         glClear(GL_STENCIL_BUFFER_BIT);
       
  1577 
       
  1578         QPainter painter(this);
       
  1579         paint(&painter);
       
  1580     }
       
  1581 };
       
  1582 
       
  1583 void tst_QGL::replaceClipping()
       
  1584 {
       
  1585     ReplaceClippingGLWidget glw;
       
  1586     glw.resize(300, 300);
       
  1587     glw.show();
       
  1588 
       
  1589 #ifdef Q_WS_X11
       
  1590     qt_x11_wait_for_window_manager(&glw);
       
  1591 #endif
       
  1592     QTest::qWait(200);
       
  1593 
       
  1594     QImage reference(300, 300, QImage::Format_RGB32);
       
  1595     QPainter referencePainter(&reference);
       
  1596     glw.paint(&referencePainter);
       
  1597     referencePainter.end();
       
  1598 
       
  1599     const QImage widgetFB = glw.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32);
       
  1600 
       
  1601     QCOMPARE(widgetFB, reference);
       
  1602 }
       
  1603 
       
  1604 class ClipTestGLWidget : public QGLWidget
       
  1605 {
       
  1606 public:
       
  1607     void paint(QPainter *painter)
       
  1608     {
       
  1609         painter->fillRect(rect(), Qt::white);
       
  1610         painter->setClipRect(10, 10, width()-20, height()-20);
       
  1611         painter->fillRect(rect(), Qt::cyan);
       
  1612 
       
  1613         painter->save();
       
  1614         painter->setClipRect(10, 10, 100, 100, Qt::IntersectClip);
       
  1615 
       
  1616         painter->fillRect(rect(), Qt::blue);
       
  1617 
       
  1618         painter->save();
       
  1619         painter->setClipRect(10, 10, 50, 50, Qt::IntersectClip);
       
  1620         painter->fillRect(rect(), Qt::red);
       
  1621         painter->restore();
       
  1622         painter->fillRect(0, 0, 40, 40, Qt::white);
       
  1623         painter->save();
       
  1624 
       
  1625         painter->setClipRect(0, 0, 35, 35, Qt::IntersectClip);
       
  1626         painter->fillRect(rect(), Qt::black);
       
  1627         painter->restore();
       
  1628 
       
  1629         painter->fillRect(0, 0, 30, 30, Qt::magenta);
       
  1630 
       
  1631         painter->save();
       
  1632         painter->setClipRect(60, 10, 50, 50, Qt::ReplaceClip);
       
  1633         painter->fillRect(rect(), Qt::green);
       
  1634         painter->restore();
       
  1635 
       
  1636         painter->save();
       
  1637         painter->setClipRect(0, 60, 60, 25, Qt::IntersectClip);
       
  1638         painter->setClipRect(60, 60, 50, 25, Qt::UniteClip);
       
  1639         painter->fillRect(rect(), Qt::yellow);
       
  1640         painter->restore();
       
  1641 
       
  1642         painter->restore();
       
  1643 
       
  1644         painter->translate(100, 100);
       
  1645 
       
  1646         {
       
  1647             QPainterPath path;
       
  1648             path.addRect(10, 10, 100, 100);
       
  1649             path.addRect(10, 10, 10, 10);
       
  1650             painter->setClipPath(path, Qt::IntersectClip);
       
  1651         }
       
  1652 
       
  1653         painter->fillRect(rect(), Qt::blue);
       
  1654 
       
  1655         painter->save();
       
  1656         {
       
  1657             QPainterPath path;
       
  1658             path.addRect(10, 10, 50, 50);
       
  1659             path.addRect(10, 10, 10, 10);
       
  1660             painter->setClipPath(path, Qt::IntersectClip);
       
  1661         }
       
  1662         painter->fillRect(rect(), Qt::red);
       
  1663         painter->restore();
       
  1664         painter->fillRect(0, 0, 40, 40, Qt::white);
       
  1665         painter->save();
       
  1666 
       
  1667         {
       
  1668             QPainterPath path;
       
  1669             path.addRect(0, 0, 35, 35);
       
  1670             path.addRect(10, 10, 10, 10);
       
  1671             painter->setClipPath(path, Qt::IntersectClip);
       
  1672         }
       
  1673         painter->fillRect(rect(), Qt::black);
       
  1674         painter->restore();
       
  1675 
       
  1676         painter->fillRect(0, 0, 30, 30, Qt::magenta);
       
  1677 
       
  1678         painter->save();
       
  1679         {
       
  1680             QPainterPath path;
       
  1681             path.addRect(60, 10, 50, 50);
       
  1682             path.addRect(10, 10, 10, 10);
       
  1683             painter->setClipPath(path, Qt::ReplaceClip);
       
  1684         }
       
  1685         painter->fillRect(rect(), Qt::green);
       
  1686         painter->restore();
       
  1687 
       
  1688         painter->save();
       
  1689         {
       
  1690             QPainterPath path;
       
  1691             path.addRect(0, 60, 60, 25);
       
  1692             path.addRect(10, 10, 10, 10);
       
  1693             painter->setClipPath(path, Qt::IntersectClip);
       
  1694         }
       
  1695         painter->setClipRect(60, 60, 50, 25, Qt::UniteClip);
       
  1696         painter->fillRect(rect(), Qt::yellow);
       
  1697         painter->restore();
       
  1698     }
       
  1699 
       
  1700 protected:
       
  1701     void paintEvent(QPaintEvent*)
       
  1702     {
       
  1703         QPainter painter(this);
       
  1704         paint(&painter);
       
  1705     }
       
  1706 };
       
  1707 
       
  1708 void tst_QGL::clipTest()
       
  1709 {
       
  1710     ClipTestGLWidget glw;
       
  1711     glw.resize(220, 220);
       
  1712     glw.show();
       
  1713 
       
  1714 #ifdef Q_WS_X11
       
  1715     qt_x11_wait_for_window_manager(&glw);
       
  1716 #endif
       
  1717     QTest::qWait(200);
       
  1718 
       
  1719     QImage reference(glw.size(), QImage::Format_RGB32);
       
  1720     QPainter referencePainter(&reference);
       
  1721     glw.paint(&referencePainter);
       
  1722     referencePainter.end();
       
  1723 
       
  1724     const QImage widgetFB = glw.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32);
       
  1725 
       
  1726     QCOMPARE(widgetFB, reference);
       
  1727 }
       
  1728 
       
  1729 void tst_QGL::destroyFBOAfterContext()
       
  1730 {
       
  1731     if (!QGLFramebufferObject::hasOpenGLFramebufferObjects())
       
  1732         QSKIP("QGLFramebufferObject not supported on this platform", SkipSingle);
       
  1733 
       
  1734     QGLWidget *glw = new QGLWidget();
       
  1735     glw->makeCurrent();
       
  1736 
       
  1737     // No multisample with combined depth/stencil attachment:
       
  1738     QGLFramebufferObjectFormat fboFormat;
       
  1739     fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
       
  1740 
       
  1741     // Don't complicate things by using NPOT:
       
  1742     QGLFramebufferObject *fbo = new QGLFramebufferObject(256, 128, fboFormat);
       
  1743 
       
  1744     // The handle should be valid until the context is destroyed.
       
  1745     QVERIFY(fbo->handle() != 0);
       
  1746     QVERIFY(fbo->isValid());
       
  1747 
       
  1748     delete glw;
       
  1749 
       
  1750     // The handle should now be zero.
       
  1751     QVERIFY(fbo->handle() == 0);
       
  1752     QVERIFY(!fbo->isValid());
       
  1753 
       
  1754     delete fbo;
       
  1755 }
       
  1756 
       
  1757 #ifdef QT_BUILD_INTERNAL
       
  1758 
       
  1759 class tst_QGLResource : public QObject
       
  1760 {
       
  1761     Q_OBJECT
       
  1762 public:
       
  1763     tst_QGLResource(QObject *parent = 0) : QObject(parent) {}
       
  1764     ~tst_QGLResource() { ++deletions; }
       
  1765 
       
  1766     static int deletions;
       
  1767 };
       
  1768 
       
  1769 int tst_QGLResource::deletions = 0;
       
  1770 
       
  1771 static void qt_shared_test_free(void *data)
       
  1772 {
       
  1773     delete reinterpret_cast<tst_QGLResource *>(data);
       
  1774 }
       
  1775 
       
  1776 Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_shared_test, (qt_shared_test_free))
       
  1777 
       
  1778 #endif
       
  1779 
       
  1780 void tst_QGL::shareRegister()
       
  1781 {
       
  1782 #ifdef QT_BUILD_INTERNAL
       
  1783     QGLShareRegister *shareReg = qgl_share_reg();
       
  1784     QVERIFY(shareReg != 0);
       
  1785 
       
  1786     // Create a context.
       
  1787     QGLWidget *glw1 = new QGLWidget();
       
  1788     glw1->makeCurrent();
       
  1789 
       
  1790     // Nothing should be sharing with glw1's context yet.
       
  1791     QList<const QGLContext *> list;
       
  1792     list = shareReg->shares(glw1->context());
       
  1793     QCOMPARE(list.size(), 0);
       
  1794 
       
  1795     // Create a guard for the first context.
       
  1796     QGLSharedResourceGuard guard(glw1->context());
       
  1797     QVERIFY(guard.id() == 0);
       
  1798     guard.setId(3);
       
  1799     QVERIFY(guard.id() == 3);
       
  1800 
       
  1801     // Add a resource to the first context.
       
  1802     tst_QGLResource *res1 = new tst_QGLResource();
       
  1803     QVERIFY(!qt_shared_test()->value(glw1->context()));
       
  1804     qt_shared_test()->insert(glw1->context(), res1);
       
  1805     QVERIFY(qt_shared_test()->value(glw1->context()) == res1);
       
  1806 
       
  1807     // Create another context that shares with the first.
       
  1808     QGLWidget *glw2 = new QGLWidget(0, glw1);
       
  1809     if (!glw2->isSharing()) {
       
  1810         delete glw2;
       
  1811         delete glw1;
       
  1812         QSKIP("Context sharing is not supported", SkipSingle);
       
  1813     }
       
  1814     QVERIFY(glw1->context() != glw2->context());
       
  1815 
       
  1816     // Check that the first context's resource is also on the second.
       
  1817     QVERIFY(qt_shared_test()->value(glw1->context()) == res1);
       
  1818     QVERIFY(qt_shared_test()->value(glw2->context()) == res1);
       
  1819 
       
  1820     // Guard should still be the same.
       
  1821     QVERIFY(guard.context() == glw1->context());
       
  1822     QVERIFY(guard.id() == 3);
       
  1823 
       
  1824     // Now there are two items in the share lists.
       
  1825     list = shareReg->shares(glw1->context());
       
  1826     QCOMPARE(list.size(), 2);
       
  1827     QVERIFY(list.contains(glw1->context()));
       
  1828     QVERIFY(list.contains(glw2->context()));
       
  1829     list = shareReg->shares(glw2->context());
       
  1830     QCOMPARE(list.size(), 2);
       
  1831     QVERIFY(list.contains(glw1->context()));
       
  1832     QVERIFY(list.contains(glw2->context()));
       
  1833 
       
  1834     // Check the sharing relationships.
       
  1835     QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context()));
       
  1836     QVERIFY(QGLContext::areSharing(glw2->context(), glw2->context()));
       
  1837     QVERIFY(QGLContext::areSharing(glw1->context(), glw2->context()));
       
  1838     QVERIFY(QGLContext::areSharing(glw2->context(), glw1->context()));
       
  1839     QVERIFY(!QGLContext::areSharing(0, glw2->context()));
       
  1840     QVERIFY(!QGLContext::areSharing(glw1->context(), 0));
       
  1841     QVERIFY(!QGLContext::areSharing(0, 0));
       
  1842 
       
  1843     // Create a third context, not sharing with the others.
       
  1844     QGLWidget *glw3 = new QGLWidget();
       
  1845 
       
  1846     // Create a guard on the standalone context.
       
  1847     QGLSharedResourceGuard guard3(glw3->context());
       
  1848     guard3.setId(5);
       
  1849 
       
  1850     // Add a resource to the third context.
       
  1851     tst_QGLResource *res3 = new tst_QGLResource();
       
  1852     QVERIFY(!qt_shared_test()->value(glw3->context()));
       
  1853     qt_shared_test()->insert(glw3->context(), res3);
       
  1854     QVERIFY(qt_shared_test()->value(glw1->context()) == res1);
       
  1855     QVERIFY(qt_shared_test()->value(glw2->context()) == res1);
       
  1856     QVERIFY(qt_shared_test()->value(glw3->context()) == res3);
       
  1857 
       
  1858     // First two should still be sharing, but third is in its own list.
       
  1859     list = shareReg->shares(glw1->context());
       
  1860     QCOMPARE(list.size(), 2);
       
  1861     QVERIFY(list.contains(glw1->context()));
       
  1862     QVERIFY(list.contains(glw2->context()));
       
  1863     list = shareReg->shares(glw2->context());
       
  1864     QCOMPARE(list.size(), 2);
       
  1865     QVERIFY(list.contains(glw1->context()));
       
  1866     QVERIFY(list.contains(glw2->context()));
       
  1867     list = shareReg->shares(glw3->context());
       
  1868     QCOMPARE(list.size(), 0);
       
  1869 
       
  1870     // Check the sharing relationships again.
       
  1871     QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context()));
       
  1872     QVERIFY(QGLContext::areSharing(glw2->context(), glw2->context()));
       
  1873     QVERIFY(QGLContext::areSharing(glw1->context(), glw2->context()));
       
  1874     QVERIFY(QGLContext::areSharing(glw2->context(), glw1->context()));
       
  1875     QVERIFY(!QGLContext::areSharing(glw1->context(), glw3->context()));
       
  1876     QVERIFY(!QGLContext::areSharing(glw2->context(), glw3->context()));
       
  1877     QVERIFY(!QGLContext::areSharing(glw3->context(), glw1->context()));
       
  1878     QVERIFY(!QGLContext::areSharing(glw3->context(), glw2->context()));
       
  1879     QVERIFY(QGLContext::areSharing(glw3->context(), glw3->context()));
       
  1880     QVERIFY(!QGLContext::areSharing(0, glw2->context()));
       
  1881     QVERIFY(!QGLContext::areSharing(glw1->context(), 0));
       
  1882     QVERIFY(!QGLContext::areSharing(0, glw3->context()));
       
  1883     QVERIFY(!QGLContext::areSharing(glw3->context(), 0));
       
  1884     QVERIFY(!QGLContext::areSharing(0, 0));
       
  1885 
       
  1886     // Shared guard should still be the same.
       
  1887     QVERIFY(guard.context() == glw1->context());
       
  1888     QVERIFY(guard.id() == 3);
       
  1889 
       
  1890     // Delete the first context.
       
  1891     delete glw1;
       
  1892 
       
  1893     // The first context's resource should transfer to the second context.
       
  1894     QCOMPARE(tst_QGLResource::deletions, 0);
       
  1895     QVERIFY(qt_shared_test()->value(glw2->context()) == res1);
       
  1896     QVERIFY(qt_shared_test()->value(glw3->context()) == res3);
       
  1897 
       
  1898     // Shared guard should now be the second context, with the id the same.
       
  1899     QVERIFY(guard.context() == glw2->context());
       
  1900     QVERIFY(guard.id() == 3);
       
  1901     QVERIFY(guard3.context() == glw3->context());
       
  1902     QVERIFY(guard3.id() == 5);
       
  1903 
       
  1904     // Re-check the share list for the second context (should be empty now).
       
  1905     list = shareReg->shares(glw2->context());
       
  1906     QCOMPARE(list.size(), 0);
       
  1907 
       
  1908     // Clean up and check that the resources are properly deleted.
       
  1909     delete glw2;
       
  1910     QCOMPARE(tst_QGLResource::deletions, 1);
       
  1911     delete glw3;
       
  1912     QCOMPARE(tst_QGLResource::deletions, 2);
       
  1913 
       
  1914     // Guards should now be null and the id zero.
       
  1915     QVERIFY(guard.context() == 0);
       
  1916     QVERIFY(guard.id() == 0);
       
  1917     QVERIFY(guard3.context() == 0);
       
  1918     QVERIFY(guard3.id() == 0);
       
  1919 #endif
       
  1920 }
       
  1921 
       
  1922 QTEST_MAIN(tst_QGL)
       
  1923 #include "tst_qgl.moc"