tests/auto/qgl/tst_qgl.cpp
changeset 18 2f34d5167611
parent 3 41300fa6a67c
child 19 fcece45ef507
--- a/tests/auto/qgl/tst_qgl.cpp	Tue Feb 02 00:43:10 2010 +0200
+++ b/tests/auto/qgl/tst_qgl.cpp	Fri Apr 16 15:50:13 2010 +0300
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
 **
@@ -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()
@@ -1824,17 +1829,12 @@
 void tst_QGL::shareRegister()
 {
 #ifdef QT_BUILD_INTERNAL
-    QGLShareRegister *shareReg = qgl_share_reg();
-    QVERIFY(shareReg != 0);
-
     // Create a context.
     QGLWidget *glw1 = new QGLWidget();
     glw1->makeCurrent();
 
     // Nothing should be sharing with glw1's context yet.
-    QList<const QGLContext *> list;
-    list = shareReg->shares(glw1->context());
-    QCOMPARE(list.size(), 0);
+    QVERIFY(!glw1->isSharing());
 
     // Create a guard for the first context.
     QGLSharedResourceGuard guard(glw1->context());
@@ -1867,16 +1867,6 @@
     QVERIFY(guard.context() == glw1->context());
     QVERIFY(guard.id() == 3);
 
-    // Now there are two items in the share lists.
-    list = shareReg->shares(glw1->context());
-    QCOMPARE(list.size(), 2);
-    QVERIFY(list.contains(glw1->context()));
-    QVERIFY(list.contains(glw2->context()));
-    list = shareReg->shares(glw2->context());
-    QCOMPARE(list.size(), 2);
-    QVERIFY(list.contains(glw1->context()));
-    QVERIFY(list.contains(glw2->context()));
-
     // Check the sharing relationships.
     QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context()));
     QVERIFY(QGLContext::areSharing(glw2->context(), glw2->context()));
@@ -1902,18 +1892,6 @@
     QVERIFY(qt_shared_test()->value(glw2->context()) == res1);
     QVERIFY(qt_shared_test()->value(glw3->context()) == res3);
 
-    // First two should still be sharing, but third is in its own list.
-    list = shareReg->shares(glw1->context());
-    QCOMPARE(list.size(), 2);
-    QVERIFY(list.contains(glw1->context()));
-    QVERIFY(list.contains(glw2->context()));
-    list = shareReg->shares(glw2->context());
-    QCOMPARE(list.size(), 2);
-    QVERIFY(list.contains(glw1->context()));
-    QVERIFY(list.contains(glw2->context()));
-    list = shareReg->shares(glw3->context());
-    QCOMPARE(list.size(), 0);
-
     // Check the sharing relationships again.
     QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context()));
     QVERIFY(QGLContext::areSharing(glw2->context(), glw2->context()));
@@ -1951,10 +1929,6 @@
     QVERIFY(guard3.context() == glw3->context());
     QVERIFY(guard3.id() == 5);
 
-    // Re-check the share list for the second context (should be empty now).
-    list = shareReg->shares(glw2->context());
-    QCOMPARE(list.size(), 0);
-
     // Clean up and check that the resources are properly deleted.
     delete glw2;
     QCOMPARE(tst_QGLResource::deletions, 1);
@@ -1969,5 +1943,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"