diff -r 41300fa6a67c -r 2f34d5167611 tests/auto/qgl/tst_qgl.cpp --- 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 +#include +#include +#include #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 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(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"