tests/auto/qgl/tst_qgl.cpp
branchRCL_3
changeset 8 3f74d0d4af4c
parent 4 3b1da2848fc7
--- a/tests/auto/qgl/tst_qgl.cpp	Mon Mar 15 12:43:09 2010 +0200
+++ b/tests/auto/qgl/tst_qgl.cpp	Thu Apr 08 14:19:33 2010 +0300
@@ -56,6 +56,9 @@
 
 #ifdef QT_BUILD_INTERNAL
 #include <QtOpenGL/private/qgl_p.h>
+#include <QtGui/private/qpixmapdata_p.h>
+#include <QtGui/private/qimage_p.h>
+#include <QtGui/private/qimagepixmapcleanuphooks_p.h>
 #endif
 
 //TESTED_CLASS=
@@ -91,6 +94,8 @@
     void clipTest();
     void destroyFBOAfterContext();
     void shareRegister();
+    void qglContextDefaultBindTexture();
+    void textureCleanup();
 };
 
 tst_QGL::tst_QGL()
@@ -993,8 +998,7 @@
     QGLFramebufferObjectFormat fboFormat;
     fboFormat.setAttachment(QGLFramebufferObject::NoAttachment);
 
-    // Don't complicate things by using NPOT:
-    QGLFramebufferObject *fbo = new QGLFramebufferObject(256, 128, fboFormat);
+    QGLFramebufferObject *fbo = new QGLFramebufferObject(200, 100, fboFormat);
 
     fbo->bind();
 
@@ -1031,6 +1035,11 @@
     // Don't complicate things by using NPOT:
     QGLFramebufferObject *fbo = new QGLFramebufferObject(256, 128, fboFormat);
 
+    if (fbo->attachment() != QGLFramebufferObject::CombinedDepthStencil) {
+        delete fbo;
+        QSKIP("FBOs missing combined depth~stencil support", SkipSingle);
+    }
+
     QPainter fboPainter;
     bool painterBegun = fboPainter.begin(fbo);
     QVERIFY(painterBegun);
@@ -1093,6 +1102,16 @@
     QGLFramebufferObject *fbo2 = new QGLFramebufferObject(256, 128, fboFormat);
     QGLFramebufferObject *fbo3 = new QGLFramebufferObject(256, 128, fboFormat);
 
+    if ( (fbo1->attachment() != QGLFramebufferObject::CombinedDepthStencil) ||
+         (fbo2->attachment() != QGLFramebufferObject::CombinedDepthStencil) ||
+         (fbo3->attachment() != QGLFramebufferObject::CombinedDepthStencil)    )
+    {
+        delete fbo1;
+        delete fbo2;
+        delete fbo3;
+        QSKIP("FBOs missing combined depth~stencil support", SkipSingle);
+    }
+
     QPainter fbo1Painter;
     QPainter fbo2Painter;
     QPainter fbo3Painter;
@@ -1198,8 +1217,8 @@
         QPainter widgetPainter;
         widgetPainterBeginOk = widgetPainter.begin(this);
         QGLFramebufferObjectFormat fboFormat;
-        fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
-        QGLFramebufferObject *fbo = new QGLFramebufferObject(128, 128, fboFormat);
+        fboFormat.setAttachment(QGLFramebufferObject::NoAttachment);
+        QGLFramebufferObject *fbo = new QGLFramebufferObject(100, 100, fboFormat);
 
         QPainter fboPainter;
         fboPainterBeginOk = fboPainter.begin(fbo);
@@ -1223,7 +1242,7 @@
 #ifdef Q_WS_QWS
     w.setWindowFlags(Qt::FramelessWindowHint);
 #endif
-    w.resize(128, 128);
+    w.resize(100, 100);
     w.show();
 
 #ifdef Q_WS_X11
@@ -1335,6 +1354,10 @@
     QImage reference(fb.size(), QImage::Format_RGB32);
     reference.fill(0xffff0000);
 
+#ifdef QGL_EGL
+    QSKIP("renderPixmap() not yet supported under EGL", SkipAll);
+#endif
+
     QFUZZY_COMPARE_IMAGES(fb, reference);
 }
 
@@ -1938,5 +1961,248 @@
 #endif
 }
 
+// Tests QGLContext::bindTexture with default options
+void tst_QGL::qglContextDefaultBindTexture()
+{
+#ifdef QT_BUILD_INTERNAL
+    QGLWidget w;
+    w.makeCurrent();
+    QGLContext *ctx = const_cast<QGLContext*>(w.context());
+
+    QImage *boundImage = new QImage(256, 256, QImage::Format_RGB32);
+    boundImage->fill(0xFFFFFFFF);
+    QPixmap *boundPixmap = new QPixmap(256, 256);
+    boundPixmap->fill(Qt::red);
+
+    int startCacheItemCount = QGLTextureCache::instance()->size();
+
+    GLuint boundImageTextureId = ctx->bindTexture(*boundImage);
+    GLuint boundPixmapTextureId = ctx->bindTexture(*boundPixmap);
+
+    // Make sure the image & pixmap have been added to the cache:
+    QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
+
+    // Make sure the image & pixmap have the is_cached flag set:
+    QVERIFY(QImagePixmapCleanupHooks::isImageCached(*boundImage));
+    QVERIFY(QImagePixmapCleanupHooks::isPixmapCached(*boundPixmap));
+
+    // Make sure the texture IDs returned are valid:
+    QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_TRUE);
+    QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_TRUE);
+
+    // Make sure the textures are still valid after we delete the image/pixmap:
+    // Also check that although the textures are left intact, the cache entries are removed:
+    delete boundImage;
+    boundImage = 0;
+    QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_TRUE);
+    QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+    delete boundPixmap;
+    boundPixmap = 0;
+    QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_TRUE);
+    QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+
+    // Finally, make sure QGLContext::deleteTexture deletes the texture IDs:
+    ctx->deleteTexture(boundImageTextureId);
+    ctx->deleteTexture(boundPixmapTextureId);
+    QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_FALSE);
+    QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_FALSE);
+#endif
+}
+
+void tst_QGL::textureCleanup()
+{
+#ifdef QT_BUILD_INTERNAL
+    QGLWidget w;
+    w.resize(200,200);
+    w.show();
+    w.makeCurrent();
+
+    // Test pixmaps which have been loaded via QPixmapCache are removed from the texture cache
+    // when the pixmap cache is cleared
+    {
+        int startCacheItemCount = QGLTextureCache::instance()->size();
+        QPainter p(&w);
+
+        QPixmap boundPixmap(":designer.png");
+
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+
+        p.drawPixmap(0, 0, boundPixmap);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
+        p.end();
+
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        // Check that the texture doesn't get removed from the cache when the pixmap is cleared
+        // as it should still be in the cache:
+        boundPixmap = QPixmap();
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        QPixmapCache::clear();
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+    }
+
+    // Test pixmaps which have been loaded via QPixmapCache are removed from the texture cache
+    // when they are explicitly removed from the pixmap cache
+    {
+        int startCacheItemCount = QGLTextureCache::instance()->size();
+        QPainter p(&w);
+
+        QPixmap boundPixmap(128, 128);
+        QString cacheKey = QString::fromLatin1("myPixmap");
+        QPixmapCache::insert(cacheKey, boundPixmap);
+
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+
+        p.drawPixmap(0, 0, boundPixmap);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
+        p.end();
+
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        // Check that the texture doesn't get removed from the cache when the pixmap is cleared
+        // as it should still be in the cache:
+        boundPixmap = QPixmap();
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        // Finally, we check that the texture cache entry is removed when we remove the
+        // pixmap cache entry, which should hold the last reference:
+        QPixmapCache::remove(cacheKey);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+    }
+
+    // Check images & pixmaps are removed from the cache when they are deleted
+    {
+        int startCacheItemCount = QGLTextureCache::instance()->size();
+        QPainter p(&w);
+
+        QImage *boundImage = new QImage(256, 256, QImage::Format_RGB32);
+        boundImage->fill(0xFFFFFFFF);
+        QPixmap *boundPixmap = new QPixmap(256, 256);
+        boundPixmap->fill(Qt::red);
+
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+
+        p.drawImage(0, 0, *boundImage);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        p.drawPixmap(0, 0, *boundPixmap);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
+
+        // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
+        p.end();
+
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
+
+        delete boundImage;
+        boundImage = 0;
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        delete boundPixmap;
+        boundPixmap = 0;
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+    }
+
+    // Check images & pixmaps are removed from the cache when they are assigned to
+    {
+        int startCacheItemCount = QGLTextureCache::instance()->size();
+        QPainter p(&w);
+
+        QImage boundImage(256, 256, QImage::Format_RGB32);
+        boundImage.fill(0xFFFFFFFF);
+        QPixmap boundPixmap(256, 256);
+        boundPixmap.fill(Qt::red);
+
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+
+        p.drawImage(0, 0, boundImage);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        p.drawPixmap(0, 0, boundPixmap);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
+
+        // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
+        p.end();
+
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
+
+        boundImage = QImage(64, 64, QImage::Format_RGB32);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        boundPixmap = QPixmap(64, 64);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+    }
+
+    // Check images & pixmaps are removed from the cache when they are modified (detached)
+    {
+        int startCacheItemCount = QGLTextureCache::instance()->size();
+        QPainter p(&w);
+
+        QImage boundImage(256, 256, QImage::Format_RGB32);
+        boundImage.fill(0xFFFFFFFF);
+        QPixmap boundPixmap(256, 256);
+        boundPixmap.fill(Qt::red);
+
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+
+        p.drawImage(0, 0, boundImage);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        p.drawPixmap(0, 0, boundPixmap);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
+
+        // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
+        p.end();
+
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
+
+        boundImage.fill(0x00000000);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        boundPixmap.fill(Qt::blue);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+    }
+
+    // Check that images/pixmaps aren't removed from the cache if a shallow copy has been made
+    QImage copyOfImage;
+    QPixmap copyOfPixmap;
+    int startCacheItemCount = QGLTextureCache::instance()->size();
+    {
+        QPainter p(&w);
+
+        QImage boundImage(256, 256, QImage::Format_RGB32);
+        boundImage.fill(0xFFFFFFFF);
+        QPixmap boundPixmap(256, 256);
+        boundPixmap.fill(Qt::red);
+
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+
+        p.drawImage(0, 0, boundImage);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+        p.drawPixmap(0, 0, boundPixmap);
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
+
+        // Need to call end for the GL2 paint engine to release references to pixmap if using tfp
+        p.end();
+
+        copyOfImage = boundImage;
+        copyOfPixmap = boundPixmap;
+        QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
+    } // boundImage & boundPixmap would have been deleted when they went out of scope
+    QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2);
+
+    copyOfImage = QImage();
+    QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
+
+    copyOfPixmap = QPixmap();
+    QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
+#endif
+}
+
 QTEST_MAIN(tst_QGL)
 #include "tst_qgl.moc"