tests/auto/qgl/tst_qgl.cpp
changeset 18 2f34d5167611
parent 3 41300fa6a67c
child 19 fcece45ef507
equal deleted inserted replaced
3:41300fa6a67c 18:2f34d5167611
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the test suite of the Qt Toolkit.
     7 ** This file is part of the test suite of the Qt Toolkit.
     8 **
     8 **
    54 #include <QGraphicsProxyWidget>
    54 #include <QGraphicsProxyWidget>
    55 #include <QVBoxLayout>
    55 #include <QVBoxLayout>
    56 
    56 
    57 #ifdef QT_BUILD_INTERNAL
    57 #ifdef QT_BUILD_INTERNAL
    58 #include <QtOpenGL/private/qgl_p.h>
    58 #include <QtOpenGL/private/qgl_p.h>
       
    59 #include <QtGui/private/qpixmapdata_p.h>
       
    60 #include <QtGui/private/qimage_p.h>
       
    61 #include <QtGui/private/qimagepixmapcleanuphooks_p.h>
    59 #endif
    62 #endif
    60 
    63 
    61 //TESTED_CLASS=
    64 //TESTED_CLASS=
    62 //TESTED_FILES=
    65 //TESTED_FILES=
    63 
    66 
    89     void testDontCrashOnDanglingResources();
    92     void testDontCrashOnDanglingResources();
    90     void replaceClipping();
    93     void replaceClipping();
    91     void clipTest();
    94     void clipTest();
    92     void destroyFBOAfterContext();
    95     void destroyFBOAfterContext();
    93     void shareRegister();
    96     void shareRegister();
       
    97     void qglContextDefaultBindTexture();
       
    98     void textureCleanup();
    94 };
    99 };
    95 
   100 
    96 tst_QGL::tst_QGL()
   101 tst_QGL::tst_QGL()
    97 {
   102 {
    98 }
   103 }
  1822 #endif
  1827 #endif
  1823 
  1828 
  1824 void tst_QGL::shareRegister()
  1829 void tst_QGL::shareRegister()
  1825 {
  1830 {
  1826 #ifdef QT_BUILD_INTERNAL
  1831 #ifdef QT_BUILD_INTERNAL
  1827     QGLShareRegister *shareReg = qgl_share_reg();
       
  1828     QVERIFY(shareReg != 0);
       
  1829 
       
  1830     // Create a context.
  1832     // Create a context.
  1831     QGLWidget *glw1 = new QGLWidget();
  1833     QGLWidget *glw1 = new QGLWidget();
  1832     glw1->makeCurrent();
  1834     glw1->makeCurrent();
  1833 
  1835 
  1834     // Nothing should be sharing with glw1's context yet.
  1836     // Nothing should be sharing with glw1's context yet.
  1835     QList<const QGLContext *> list;
  1837     QVERIFY(!glw1->isSharing());
  1836     list = shareReg->shares(glw1->context());
       
  1837     QCOMPARE(list.size(), 0);
       
  1838 
  1838 
  1839     // Create a guard for the first context.
  1839     // Create a guard for the first context.
  1840     QGLSharedResourceGuard guard(glw1->context());
  1840     QGLSharedResourceGuard guard(glw1->context());
  1841     QVERIFY(guard.id() == 0);
  1841     QVERIFY(guard.id() == 0);
  1842     guard.setId(3);
  1842     guard.setId(3);
  1864     QVERIFY(qt_shared_test()->value(glw2->context()) == res1);
  1864     QVERIFY(qt_shared_test()->value(glw2->context()) == res1);
  1865 
  1865 
  1866     // Guard should still be the same.
  1866     // Guard should still be the same.
  1867     QVERIFY(guard.context() == glw1->context());
  1867     QVERIFY(guard.context() == glw1->context());
  1868     QVERIFY(guard.id() == 3);
  1868     QVERIFY(guard.id() == 3);
  1869 
       
  1870     // Now there are two items in the share lists.
       
  1871     list = shareReg->shares(glw1->context());
       
  1872     QCOMPARE(list.size(), 2);
       
  1873     QVERIFY(list.contains(glw1->context()));
       
  1874     QVERIFY(list.contains(glw2->context()));
       
  1875     list = shareReg->shares(glw2->context());
       
  1876     QCOMPARE(list.size(), 2);
       
  1877     QVERIFY(list.contains(glw1->context()));
       
  1878     QVERIFY(list.contains(glw2->context()));
       
  1879 
  1869 
  1880     // Check the sharing relationships.
  1870     // Check the sharing relationships.
  1881     QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context()));
  1871     QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context()));
  1882     QVERIFY(QGLContext::areSharing(glw2->context(), glw2->context()));
  1872     QVERIFY(QGLContext::areSharing(glw2->context(), glw2->context()));
  1883     QVERIFY(QGLContext::areSharing(glw1->context(), glw2->context()));
  1873     QVERIFY(QGLContext::areSharing(glw1->context(), glw2->context()));
  1899     QVERIFY(!qt_shared_test()->value(glw3->context()));
  1889     QVERIFY(!qt_shared_test()->value(glw3->context()));
  1900     qt_shared_test()->insert(glw3->context(), res3);
  1890     qt_shared_test()->insert(glw3->context(), res3);
  1901     QVERIFY(qt_shared_test()->value(glw1->context()) == res1);
  1891     QVERIFY(qt_shared_test()->value(glw1->context()) == res1);
  1902     QVERIFY(qt_shared_test()->value(glw2->context()) == res1);
  1892     QVERIFY(qt_shared_test()->value(glw2->context()) == res1);
  1903     QVERIFY(qt_shared_test()->value(glw3->context()) == res3);
  1893     QVERIFY(qt_shared_test()->value(glw3->context()) == res3);
  1904 
       
  1905     // First two should still be sharing, but third is in its own list.
       
  1906     list = shareReg->shares(glw1->context());
       
  1907     QCOMPARE(list.size(), 2);
       
  1908     QVERIFY(list.contains(glw1->context()));
       
  1909     QVERIFY(list.contains(glw2->context()));
       
  1910     list = shareReg->shares(glw2->context());
       
  1911     QCOMPARE(list.size(), 2);
       
  1912     QVERIFY(list.contains(glw1->context()));
       
  1913     QVERIFY(list.contains(glw2->context()));
       
  1914     list = shareReg->shares(glw3->context());
       
  1915     QCOMPARE(list.size(), 0);
       
  1916 
  1894 
  1917     // Check the sharing relationships again.
  1895     // Check the sharing relationships again.
  1918     QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context()));
  1896     QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context()));
  1919     QVERIFY(QGLContext::areSharing(glw2->context(), glw2->context()));
  1897     QVERIFY(QGLContext::areSharing(glw2->context(), glw2->context()));
  1920     QVERIFY(QGLContext::areSharing(glw1->context(), glw2->context()));
  1898     QVERIFY(QGLContext::areSharing(glw1->context(), glw2->context()));
  1949     QVERIFY(guard.context() == glw2->context());
  1927     QVERIFY(guard.context() == glw2->context());
  1950     QVERIFY(guard.id() == 3);
  1928     QVERIFY(guard.id() == 3);
  1951     QVERIFY(guard3.context() == glw3->context());
  1929     QVERIFY(guard3.context() == glw3->context());
  1952     QVERIFY(guard3.id() == 5);
  1930     QVERIFY(guard3.id() == 5);
  1953 
  1931 
  1954     // Re-check the share list for the second context (should be empty now).
       
  1955     list = shareReg->shares(glw2->context());
       
  1956     QCOMPARE(list.size(), 0);
       
  1957 
       
  1958     // Clean up and check that the resources are properly deleted.
  1932     // Clean up and check that the resources are properly deleted.
  1959     delete glw2;
  1933     delete glw2;
  1960     QCOMPARE(tst_QGLResource::deletions, 1);
  1934     QCOMPARE(tst_QGLResource::deletions, 1);
  1961     delete glw3;
  1935     delete glw3;
  1962     QCOMPARE(tst_QGLResource::deletions, 2);
  1936     QCOMPARE(tst_QGLResource::deletions, 2);
  1967     QVERIFY(guard3.context() == 0);
  1941     QVERIFY(guard3.context() == 0);
  1968     QVERIFY(guard3.id() == 0);
  1942     QVERIFY(guard3.id() == 0);
  1969 #endif
  1943 #endif
  1970 }
  1944 }
  1971 
  1945 
       
  1946 // Tests QGLContext::bindTexture with default options
       
  1947 void tst_QGL::qglContextDefaultBindTexture()
       
  1948 {
       
  1949 #ifdef QT_BUILD_INTERNAL
       
  1950     QGLWidget w;
       
  1951     w.makeCurrent();
       
  1952     QGLContext *ctx = const_cast<QGLContext*>(w.context());
       
  1953 
       
  1954     QImage *boundImage = new QImage(256, 256, QImage::Format_RGB32);
       
  1955     boundImage->fill(0xFFFFFFFF);
       
  1956     QPixmap *boundPixmap = new QPixmap(256, 256);
       
  1957     boundPixmap->fill(Qt::red);
       
  1958 
       
  1959     int startCacheItemCount = QGLTextureCache::instance()->size();
       
  1960 
       
  1961     GLuint boundImageTextureId = ctx->bindTexture(*boundImage);
       
  1962     GLuint boundPixmapTextureId = ctx->bindTexture(*boundPixmap);
       
  1963 
       
  1964     // Make sure the image & pixmap have been added to the cache:
       
  1965     QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  1966 
       
  1967     // Make sure the image & pixmap have the is_cached flag set:
       
  1968     QVERIFY(QImagePixmapCleanupHooks::isImageCached(*boundImage));
       
  1969     QVERIFY(QImagePixmapCleanupHooks::isPixmapCached(*boundPixmap));
       
  1970 
       
  1971     // Make sure the texture IDs returned are valid:
       
  1972     QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_TRUE);
       
  1973     QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_TRUE);
       
  1974 
       
  1975     // Make sure the textures are still valid after we delete the image/pixmap:
       
  1976     // Also check that although the textures are left intact, the cache entries are removed:
       
  1977     delete boundImage;
       
  1978     boundImage = 0;
       
  1979     QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_TRUE);
       
  1980     QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  1981     delete boundPixmap;
       
  1982     boundPixmap = 0;
       
  1983     QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_TRUE);
       
  1984     QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  1985 
       
  1986     // Finally, make sure QGLContext::deleteTexture deletes the texture IDs:
       
  1987     ctx->deleteTexture(boundImageTextureId);
       
  1988     ctx->deleteTexture(boundPixmapTextureId);
       
  1989     QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_FALSE);
       
  1990     QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_FALSE);
       
  1991 #endif
       
  1992 }
       
  1993 
       
  1994 void tst_QGL::textureCleanup()
       
  1995 {
       
  1996 #ifdef QT_BUILD_INTERNAL
       
  1997     QGLWidget w;
       
  1998     w.resize(200,200);
       
  1999     w.show();
       
  2000     w.makeCurrent();
       
  2001 
       
  2002     // Test pixmaps which have been loaded via QPixmapCache are removed from the texture cache
       
  2003     // when the pixmap cache is cleared
       
  2004     {
       
  2005         int startCacheItemCount = QGLTextureCache::instance()->size();
       
  2006         QPainter p(&w);
       
  2007 
       
  2008         QPixmap boundPixmap(":designer.png");
       
  2009 
       
  2010         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2011 
       
  2012         p.drawPixmap(0, 0, boundPixmap);
       
  2013         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2014 
       
  2015         // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
       
  2016         p.end();
       
  2017 
       
  2018         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2019 
       
  2020         // Check that the texture doesn't get removed from the cache when the pixmap is cleared
       
  2021         // as it should still be in the cache:
       
  2022         boundPixmap = QPixmap();
       
  2023         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2024 
       
  2025         QPixmapCache::clear();
       
  2026         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2027     }
       
  2028 
       
  2029     // Test pixmaps which have been loaded via QPixmapCache are removed from the texture cache
       
  2030     // when they are explicitly removed from the pixmap cache
       
  2031     {
       
  2032         int startCacheItemCount = QGLTextureCache::instance()->size();
       
  2033         QPainter p(&w);
       
  2034 
       
  2035         QPixmap boundPixmap(128, 128);
       
  2036         QString cacheKey = QString::fromLatin1("myPixmap");
       
  2037         QPixmapCache::insert(cacheKey, boundPixmap);
       
  2038 
       
  2039         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2040 
       
  2041         p.drawPixmap(0, 0, boundPixmap);
       
  2042         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2043 
       
  2044         // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
       
  2045         p.end();
       
  2046 
       
  2047         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2048 
       
  2049         // Check that the texture doesn't get removed from the cache when the pixmap is cleared
       
  2050         // as it should still be in the cache:
       
  2051         boundPixmap = QPixmap();
       
  2052         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2053 
       
  2054         // Finally, we check that the texture cache entry is removed when we remove the
       
  2055         // pixmap cache entry, which should hold the last reference:
       
  2056         QPixmapCache::remove(cacheKey);
       
  2057         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2058     }
       
  2059 
       
  2060     // Check images & pixmaps are removed from the cache when they are deleted
       
  2061     {
       
  2062         int startCacheItemCount = QGLTextureCache::instance()->size();
       
  2063         QPainter p(&w);
       
  2064 
       
  2065         QImage *boundImage = new QImage(256, 256, QImage::Format_RGB32);
       
  2066         boundImage->fill(0xFFFFFFFF);
       
  2067         QPixmap *boundPixmap = new QPixmap(256, 256);
       
  2068         boundPixmap->fill(Qt::red);
       
  2069 
       
  2070         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2071 
       
  2072         p.drawImage(0, 0, *boundImage);
       
  2073         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2074 
       
  2075         p.drawPixmap(0, 0, *boundPixmap);
       
  2076         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2077 
       
  2078         // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
       
  2079         p.end();
       
  2080 
       
  2081         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2082 
       
  2083         delete boundImage;
       
  2084         boundImage = 0;
       
  2085         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2086 
       
  2087         delete boundPixmap;
       
  2088         boundPixmap = 0;
       
  2089         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2090     }
       
  2091 
       
  2092     // Check images & pixmaps are removed from the cache when they are assigned to
       
  2093     {
       
  2094         int startCacheItemCount = QGLTextureCache::instance()->size();
       
  2095         QPainter p(&w);
       
  2096 
       
  2097         QImage boundImage(256, 256, QImage::Format_RGB32);
       
  2098         boundImage.fill(0xFFFFFFFF);
       
  2099         QPixmap boundPixmap(256, 256);
       
  2100         boundPixmap.fill(Qt::red);
       
  2101 
       
  2102         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2103 
       
  2104         p.drawImage(0, 0, boundImage);
       
  2105         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2106 
       
  2107         p.drawPixmap(0, 0, boundPixmap);
       
  2108         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2109 
       
  2110         // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
       
  2111         p.end();
       
  2112 
       
  2113         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2114 
       
  2115         boundImage = QImage(64, 64, QImage::Format_RGB32);
       
  2116         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2117 
       
  2118         boundPixmap = QPixmap(64, 64);
       
  2119         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2120     }
       
  2121 
       
  2122     // Check images & pixmaps are removed from the cache when they are modified (detached)
       
  2123     {
       
  2124         int startCacheItemCount = QGLTextureCache::instance()->size();
       
  2125         QPainter p(&w);
       
  2126 
       
  2127         QImage boundImage(256, 256, QImage::Format_RGB32);
       
  2128         boundImage.fill(0xFFFFFFFF);
       
  2129         QPixmap boundPixmap(256, 256);
       
  2130         boundPixmap.fill(Qt::red);
       
  2131 
       
  2132         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2133 
       
  2134         p.drawImage(0, 0, boundImage);
       
  2135         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2136 
       
  2137         p.drawPixmap(0, 0, boundPixmap);
       
  2138         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2139 
       
  2140         // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
       
  2141         p.end();
       
  2142 
       
  2143         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2144 
       
  2145         boundImage.fill(0x00000000);
       
  2146         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2147 
       
  2148         boundPixmap.fill(Qt::blue);
       
  2149         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2150     }
       
  2151 
       
  2152     // Check that images/pixmaps aren't removed from the cache if a shallow copy has been made
       
  2153     QImage copyOfImage;
       
  2154     QPixmap copyOfPixmap;
       
  2155     int startCacheItemCount = QGLTextureCache::instance()->size();
       
  2156     {
       
  2157         QPainter p(&w);
       
  2158 
       
  2159         QImage boundImage(256, 256, QImage::Format_RGB32);
       
  2160         boundImage.fill(0xFFFFFFFF);
       
  2161         QPixmap boundPixmap(256, 256);
       
  2162         boundPixmap.fill(Qt::red);
       
  2163 
       
  2164         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2165 
       
  2166         p.drawImage(0, 0, boundImage);
       
  2167         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2168 
       
  2169         p.drawPixmap(0, 0, boundPixmap);
       
  2170         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2171 
       
  2172         // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
       
  2173         p.end();
       
  2174 
       
  2175         copyOfImage = boundImage;
       
  2176         copyOfPixmap = boundPixmap;
       
  2177         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2178     } // boundImage & boundPixmap would have been deleted when they went out of scope
       
  2179     QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2180 
       
  2181     copyOfImage = QImage();
       
  2182     QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2183 
       
  2184     copyOfPixmap = QPixmap();
       
  2185     QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2186 #endif
       
  2187 }
       
  2188 
  1972 QTEST_MAIN(tst_QGL)
  2189 QTEST_MAIN(tst_QGL)
  1973 #include "tst_qgl.moc"
  2190 #include "tst_qgl.moc"