tests/auto/qgl/tst_qgl.cpp
branchRCL_3
changeset 8 3f74d0d4af4c
parent 4 3b1da2848fc7
equal deleted inserted replaced
6:dee5afe5301f 8:3f74d0d4af4c
    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 }
   991 
   996 
   992     // No multisample with combined depth/stencil attachment:
   997     // No multisample with combined depth/stencil attachment:
   993     QGLFramebufferObjectFormat fboFormat;
   998     QGLFramebufferObjectFormat fboFormat;
   994     fboFormat.setAttachment(QGLFramebufferObject::NoAttachment);
   999     fboFormat.setAttachment(QGLFramebufferObject::NoAttachment);
   995 
  1000 
   996     // Don't complicate things by using NPOT:
  1001     QGLFramebufferObject *fbo = new QGLFramebufferObject(200, 100, fboFormat);
   997     QGLFramebufferObject *fbo = new QGLFramebufferObject(256, 128, fboFormat);
       
   998 
  1002 
   999     fbo->bind();
  1003     fbo->bind();
  1000 
  1004 
  1001     glClearColor(1.0, 0.0, 0.0, 1.0);
  1005     glClearColor(1.0, 0.0, 0.0, 1.0);
  1002     glClear(GL_COLOR_BUFFER_BIT);
  1006     glClear(GL_COLOR_BUFFER_BIT);
  1028     QGLFramebufferObjectFormat fboFormat;
  1032     QGLFramebufferObjectFormat fboFormat;
  1029     fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
  1033     fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
  1030 
  1034 
  1031     // Don't complicate things by using NPOT:
  1035     // Don't complicate things by using NPOT:
  1032     QGLFramebufferObject *fbo = new QGLFramebufferObject(256, 128, fboFormat);
  1036     QGLFramebufferObject *fbo = new QGLFramebufferObject(256, 128, fboFormat);
       
  1037 
       
  1038     if (fbo->attachment() != QGLFramebufferObject::CombinedDepthStencil) {
       
  1039         delete fbo;
       
  1040         QSKIP("FBOs missing combined depth~stencil support", SkipSingle);
       
  1041     }
  1033 
  1042 
  1034     QPainter fboPainter;
  1043     QPainter fboPainter;
  1035     bool painterBegun = fboPainter.begin(fbo);
  1044     bool painterBegun = fboPainter.begin(fbo);
  1036     QVERIFY(painterBegun);
  1045     QVERIFY(painterBegun);
  1037 
  1046 
  1090     fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
  1099     fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
  1091 
  1100 
  1092     QGLFramebufferObject *fbo1 = new QGLFramebufferObject(256, 128, fboFormat);
  1101     QGLFramebufferObject *fbo1 = new QGLFramebufferObject(256, 128, fboFormat);
  1093     QGLFramebufferObject *fbo2 = new QGLFramebufferObject(256, 128, fboFormat);
  1102     QGLFramebufferObject *fbo2 = new QGLFramebufferObject(256, 128, fboFormat);
  1094     QGLFramebufferObject *fbo3 = new QGLFramebufferObject(256, 128, fboFormat);
  1103     QGLFramebufferObject *fbo3 = new QGLFramebufferObject(256, 128, fboFormat);
       
  1104 
       
  1105     if ( (fbo1->attachment() != QGLFramebufferObject::CombinedDepthStencil) ||
       
  1106          (fbo2->attachment() != QGLFramebufferObject::CombinedDepthStencil) ||
       
  1107          (fbo3->attachment() != QGLFramebufferObject::CombinedDepthStencil)    )
       
  1108     {
       
  1109         delete fbo1;
       
  1110         delete fbo2;
       
  1111         delete fbo3;
       
  1112         QSKIP("FBOs missing combined depth~stencil support", SkipSingle);
       
  1113     }
  1095 
  1114 
  1096     QPainter fbo1Painter;
  1115     QPainter fbo1Painter;
  1097     QPainter fbo2Painter;
  1116     QPainter fbo2Painter;
  1098     QPainter fbo3Painter;
  1117     QPainter fbo3Painter;
  1099 
  1118 
  1196     void paintEvent(QPaintEvent*)
  1215     void paintEvent(QPaintEvent*)
  1197     {
  1216     {
  1198         QPainter widgetPainter;
  1217         QPainter widgetPainter;
  1199         widgetPainterBeginOk = widgetPainter.begin(this);
  1218         widgetPainterBeginOk = widgetPainter.begin(this);
  1200         QGLFramebufferObjectFormat fboFormat;
  1219         QGLFramebufferObjectFormat fboFormat;
  1201         fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
  1220         fboFormat.setAttachment(QGLFramebufferObject::NoAttachment);
  1202         QGLFramebufferObject *fbo = new QGLFramebufferObject(128, 128, fboFormat);
  1221         QGLFramebufferObject *fbo = new QGLFramebufferObject(100, 100, fboFormat);
  1203 
  1222 
  1204         QPainter fboPainter;
  1223         QPainter fboPainter;
  1205         fboPainterBeginOk = fboPainter.begin(fbo);
  1224         fboPainterBeginOk = fboPainter.begin(fbo);
  1206         fboPainter.fillRect(-1, -1, 130, 130, Qt::red);
  1225         fboPainter.fillRect(-1, -1, 130, 130, Qt::red);
  1207         fboPainter.end();
  1226         fboPainter.end();
  1221 
  1240 
  1222     FBOUseInGLWidget w;
  1241     FBOUseInGLWidget w;
  1223 #ifdef Q_WS_QWS
  1242 #ifdef Q_WS_QWS
  1224     w.setWindowFlags(Qt::FramelessWindowHint);
  1243     w.setWindowFlags(Qt::FramelessWindowHint);
  1225 #endif
  1244 #endif
  1226     w.resize(128, 128);
  1245     w.resize(100, 100);
  1227     w.show();
  1246     w.show();
  1228 
  1247 
  1229 #ifdef Q_WS_X11
  1248 #ifdef Q_WS_X11
  1230     qt_x11_wait_for_window_manager(&w);
  1249     qt_x11_wait_for_window_manager(&w);
  1231 #endif
  1250 #endif
  1332     delete w;
  1351     delete w;
  1333 
  1352 
  1334     QImage fb = pm.toImage().convertToFormat(QImage::Format_RGB32);
  1353     QImage fb = pm.toImage().convertToFormat(QImage::Format_RGB32);
  1335     QImage reference(fb.size(), QImage::Format_RGB32);
  1354     QImage reference(fb.size(), QImage::Format_RGB32);
  1336     reference.fill(0xffff0000);
  1355     reference.fill(0xffff0000);
       
  1356 
       
  1357 #ifdef QGL_EGL
       
  1358     QSKIP("renderPixmap() not yet supported under EGL", SkipAll);
       
  1359 #endif
  1337 
  1360 
  1338     QFUZZY_COMPARE_IMAGES(fb, reference);
  1361     QFUZZY_COMPARE_IMAGES(fb, reference);
  1339 }
  1362 }
  1340 
  1363 
  1341 class ColormapExtended : public QGLColormap
  1364 class ColormapExtended : public QGLColormap
  1936     QVERIFY(guard3.context() == 0);
  1959     QVERIFY(guard3.context() == 0);
  1937     QVERIFY(guard3.id() == 0);
  1960     QVERIFY(guard3.id() == 0);
  1938 #endif
  1961 #endif
  1939 }
  1962 }
  1940 
  1963 
       
  1964 // Tests QGLContext::bindTexture with default options
       
  1965 void tst_QGL::qglContextDefaultBindTexture()
       
  1966 {
       
  1967 #ifdef QT_BUILD_INTERNAL
       
  1968     QGLWidget w;
       
  1969     w.makeCurrent();
       
  1970     QGLContext *ctx = const_cast<QGLContext*>(w.context());
       
  1971 
       
  1972     QImage *boundImage = new QImage(256, 256, QImage::Format_RGB32);
       
  1973     boundImage->fill(0xFFFFFFFF);
       
  1974     QPixmap *boundPixmap = new QPixmap(256, 256);
       
  1975     boundPixmap->fill(Qt::red);
       
  1976 
       
  1977     int startCacheItemCount = QGLTextureCache::instance()->size();
       
  1978 
       
  1979     GLuint boundImageTextureId = ctx->bindTexture(*boundImage);
       
  1980     GLuint boundPixmapTextureId = ctx->bindTexture(*boundPixmap);
       
  1981 
       
  1982     // Make sure the image & pixmap have been added to the cache:
       
  1983     QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  1984 
       
  1985     // Make sure the image & pixmap have the is_cached flag set:
       
  1986     QVERIFY(QImagePixmapCleanupHooks::isImageCached(*boundImage));
       
  1987     QVERIFY(QImagePixmapCleanupHooks::isPixmapCached(*boundPixmap));
       
  1988 
       
  1989     // Make sure the texture IDs returned are valid:
       
  1990     QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_TRUE);
       
  1991     QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_TRUE);
       
  1992 
       
  1993     // Make sure the textures are still valid after we delete the image/pixmap:
       
  1994     // Also check that although the textures are left intact, the cache entries are removed:
       
  1995     delete boundImage;
       
  1996     boundImage = 0;
       
  1997     QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_TRUE);
       
  1998     QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  1999     delete boundPixmap;
       
  2000     boundPixmap = 0;
       
  2001     QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_TRUE);
       
  2002     QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2003 
       
  2004     // Finally, make sure QGLContext::deleteTexture deletes the texture IDs:
       
  2005     ctx->deleteTexture(boundImageTextureId);
       
  2006     ctx->deleteTexture(boundPixmapTextureId);
       
  2007     QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_FALSE);
       
  2008     QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_FALSE);
       
  2009 #endif
       
  2010 }
       
  2011 
       
  2012 void tst_QGL::textureCleanup()
       
  2013 {
       
  2014 #ifdef QT_BUILD_INTERNAL
       
  2015     QGLWidget w;
       
  2016     w.resize(200,200);
       
  2017     w.show();
       
  2018     w.makeCurrent();
       
  2019 
       
  2020     // Test pixmaps which have been loaded via QPixmapCache are removed from the texture cache
       
  2021     // when the pixmap cache is cleared
       
  2022     {
       
  2023         int startCacheItemCount = QGLTextureCache::instance()->size();
       
  2024         QPainter p(&w);
       
  2025 
       
  2026         QPixmap boundPixmap(":designer.png");
       
  2027 
       
  2028         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2029 
       
  2030         p.drawPixmap(0, 0, boundPixmap);
       
  2031         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2032 
       
  2033         // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
       
  2034         p.end();
       
  2035 
       
  2036         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2037 
       
  2038         // Check that the texture doesn't get removed from the cache when the pixmap is cleared
       
  2039         // as it should still be in the cache:
       
  2040         boundPixmap = QPixmap();
       
  2041         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2042 
       
  2043         QPixmapCache::clear();
       
  2044         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2045     }
       
  2046 
       
  2047     // Test pixmaps which have been loaded via QPixmapCache are removed from the texture cache
       
  2048     // when they are explicitly removed from the pixmap cache
       
  2049     {
       
  2050         int startCacheItemCount = QGLTextureCache::instance()->size();
       
  2051         QPainter p(&w);
       
  2052 
       
  2053         QPixmap boundPixmap(128, 128);
       
  2054         QString cacheKey = QString::fromLatin1("myPixmap");
       
  2055         QPixmapCache::insert(cacheKey, boundPixmap);
       
  2056 
       
  2057         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2058 
       
  2059         p.drawPixmap(0, 0, boundPixmap);
       
  2060         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2061 
       
  2062         // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
       
  2063         p.end();
       
  2064 
       
  2065         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2066 
       
  2067         // Check that the texture doesn't get removed from the cache when the pixmap is cleared
       
  2068         // as it should still be in the cache:
       
  2069         boundPixmap = QPixmap();
       
  2070         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2071 
       
  2072         // Finally, we check that the texture cache entry is removed when we remove the
       
  2073         // pixmap cache entry, which should hold the last reference:
       
  2074         QPixmapCache::remove(cacheKey);
       
  2075         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2076     }
       
  2077 
       
  2078     // Check images & pixmaps are removed from the cache when they are deleted
       
  2079     {
       
  2080         int startCacheItemCount = QGLTextureCache::instance()->size();
       
  2081         QPainter p(&w);
       
  2082 
       
  2083         QImage *boundImage = new QImage(256, 256, QImage::Format_RGB32);
       
  2084         boundImage->fill(0xFFFFFFFF);
       
  2085         QPixmap *boundPixmap = new QPixmap(256, 256);
       
  2086         boundPixmap->fill(Qt::red);
       
  2087 
       
  2088         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2089 
       
  2090         p.drawImage(0, 0, *boundImage);
       
  2091         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2092 
       
  2093         p.drawPixmap(0, 0, *boundPixmap);
       
  2094         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2095 
       
  2096         // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
       
  2097         p.end();
       
  2098 
       
  2099         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2100 
       
  2101         delete boundImage;
       
  2102         boundImage = 0;
       
  2103         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2104 
       
  2105         delete boundPixmap;
       
  2106         boundPixmap = 0;
       
  2107         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2108     }
       
  2109 
       
  2110     // Check images & pixmaps are removed from the cache when they are assigned to
       
  2111     {
       
  2112         int startCacheItemCount = QGLTextureCache::instance()->size();
       
  2113         QPainter p(&w);
       
  2114 
       
  2115         QImage boundImage(256, 256, QImage::Format_RGB32);
       
  2116         boundImage.fill(0xFFFFFFFF);
       
  2117         QPixmap boundPixmap(256, 256);
       
  2118         boundPixmap.fill(Qt::red);
       
  2119 
       
  2120         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2121 
       
  2122         p.drawImage(0, 0, boundImage);
       
  2123         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2124 
       
  2125         p.drawPixmap(0, 0, boundPixmap);
       
  2126         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2127 
       
  2128         // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
       
  2129         p.end();
       
  2130 
       
  2131         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2132 
       
  2133         boundImage = QImage(64, 64, QImage::Format_RGB32);
       
  2134         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2135 
       
  2136         boundPixmap = QPixmap(64, 64);
       
  2137         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2138     }
       
  2139 
       
  2140     // Check images & pixmaps are removed from the cache when they are modified (detached)
       
  2141     {
       
  2142         int startCacheItemCount = QGLTextureCache::instance()->size();
       
  2143         QPainter p(&w);
       
  2144 
       
  2145         QImage boundImage(256, 256, QImage::Format_RGB32);
       
  2146         boundImage.fill(0xFFFFFFFF);
       
  2147         QPixmap boundPixmap(256, 256);
       
  2148         boundPixmap.fill(Qt::red);
       
  2149 
       
  2150         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2151 
       
  2152         p.drawImage(0, 0, boundImage);
       
  2153         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2154 
       
  2155         p.drawPixmap(0, 0, boundPixmap);
       
  2156         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2157 
       
  2158         // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
       
  2159         p.end();
       
  2160 
       
  2161         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2162 
       
  2163         boundImage.fill(0x00000000);
       
  2164         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2165 
       
  2166         boundPixmap.fill(Qt::blue);
       
  2167         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2168     }
       
  2169 
       
  2170     // Check that images/pixmaps aren't removed from the cache if a shallow copy has been made
       
  2171     QImage copyOfImage;
       
  2172     QPixmap copyOfPixmap;
       
  2173     int startCacheItemCount = QGLTextureCache::instance()->size();
       
  2174     {
       
  2175         QPainter p(&w);
       
  2176 
       
  2177         QImage boundImage(256, 256, QImage::Format_RGB32);
       
  2178         boundImage.fill(0xFFFFFFFF);
       
  2179         QPixmap boundPixmap(256, 256);
       
  2180         boundPixmap.fill(Qt::red);
       
  2181 
       
  2182         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2183 
       
  2184         p.drawImage(0, 0, boundImage);
       
  2185         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2186 
       
  2187         p.drawPixmap(0, 0, boundPixmap);
       
  2188         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2189 
       
  2190         // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
       
  2191         p.end();
       
  2192 
       
  2193         copyOfImage = boundImage;
       
  2194         copyOfPixmap = boundPixmap;
       
  2195         QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2196     } // boundImage & boundPixmap would have been deleted when they went out of scope
       
  2197     QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
       
  2198 
       
  2199     copyOfImage = QImage();
       
  2200     QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
       
  2201 
       
  2202     copyOfPixmap = QPixmap();
       
  2203     QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
       
  2204 #endif
       
  2205 }
       
  2206 
  1941 QTEST_MAIN(tst_QGL)
  2207 QTEST_MAIN(tst_QGL)
  1942 #include "tst_qgl.moc"
  2208 #include "tst_qgl.moc"