diff options
author | Gunnar Sletta <gunnar.sletta@nokia.com> | 2010-12-21 08:49:35 +0100 |
---|---|---|
committer | Gunnar Sletta <gunnar.sletta@nokia.com> | 2010-12-21 08:49:35 +0100 |
commit | c69e112c892dbb017a83189dba56884b0717b171 (patch) | |
tree | 2bc28993692eb10e1de3279d0ade2c6a1fab9d74 | |
parent | 4092945f09a12b53b545658cfa580f793864d2d9 (diff) |
More sanity checks for the texture manager
-rw-r--r-- | src/adaptationlayers/qsgpartialuploadtexturemanager.cpp | 19 | ||||
-rw-r--r-- | src/adaptationlayers/qsgpartialuploadtexturemanager.h | 3 | ||||
-rw-r--r-- | src/scenegraph/coreapi/qsgcontext.cpp | 12 | ||||
-rw-r--r-- | src/scenegraph/coreapi/qsgtexturemanager.cpp | 21 | ||||
-rw-r--r-- | src/scenegraph/coreapi/qsgtexturemanager.h | 5 | ||||
-rw-r--r-- | src/scenegraph/coreapi/qsgtexturemanager_p.h | 2 | ||||
-rw-r--r-- | tests/auto/texturemanager/tst_texturemanagertest.cpp | 50 |
7 files changed, 93 insertions, 19 deletions
diff --git a/src/adaptationlayers/qsgpartialuploadtexturemanager.cpp b/src/adaptationlayers/qsgpartialuploadtexturemanager.cpp index ba162c3..2696eeb 100644 --- a/src/adaptationlayers/qsgpartialuploadtexturemanager.cpp +++ b/src/adaptationlayers/qsgpartialuploadtexturemanager.cpp @@ -49,10 +49,19 @@ class QSGPartialUploadTexture : public QSGTexture { Q_OBJECT public: + QSGPartialUploadTexture(QSGPartialUploadTextureManager *m) + : manager(m) + { + } + + ~QSGPartialUploadTexture(); + int chunkCount; int progress; QImage image; + + QSGPartialUploadTextureManager *manager; }; @@ -77,6 +86,12 @@ public: QList<QSGPartialUploadTexture *> requests; }; +QSGPartialUploadTexture::~QSGPartialUploadTexture() +{ + manager->d_func()->requests.removeOne(this); + manager->d_func()->removeTextureFromCache(this); +} + QSGPartialUploadTextureManager::QSGPartialUploadTextureManager() : QSGTextureManager(*(new QSGPartialUploadTextureManagerPrivate)) @@ -102,7 +117,7 @@ QSGTextureRef QSGPartialUploadTextureManager::requestUpload(const QImage &image, if (texture) return QSGTextureRef(texture); - QSGPartialUploadTexture *ptex = new QSGPartialUploadTexture; + QSGPartialUploadTexture *ptex = new QSGPartialUploadTexture(this); ptex->progress = 0; ptex->image = image; @@ -133,7 +148,7 @@ QSGTextureRef QSGPartialUploadTextureManager::upload(const QImage &image) if (texture) { QSGPartialUploadTexture *ptex = qobject_cast<QSGPartialUploadTexture *>(texture); - if (ptex && ptex->progress == ptex->chunkCount || !ptex) { + if ((ptex && ptex->progress == ptex->chunkCount) || !ptex) { // Already fully uploaded... Just return return QSGTextureRef(texture); diff --git a/src/adaptationlayers/qsgpartialuploadtexturemanager.h b/src/adaptationlayers/qsgpartialuploadtexturemanager.h index c6c8146..4ad8cab 100644 --- a/src/adaptationlayers/qsgpartialuploadtexturemanager.h +++ b/src/adaptationlayers/qsgpartialuploadtexturemanager.h @@ -46,6 +46,7 @@ #include "qsgtexturemanager.h" class QSGPartialUploadTextureManagerPrivate; +class QSGPartialUploadTexture; class QSGPartialUploadTextureManager : public QSGTextureManager { @@ -65,6 +66,8 @@ private slots: protected: void timerEvent(QTimerEvent *); +private: + friend class QSGPartialUploadTexture; }; #endif // QSGPARTIALUPLOADTEXTUREMANAGER_H diff --git a/src/scenegraph/coreapi/qsgcontext.cpp b/src/scenegraph/coreapi/qsgcontext.cpp index b71a952..a52bd95 100644 --- a/src/scenegraph/coreapi/qsgcontext.cpp +++ b/src/scenegraph/coreapi/qsgcontext.cpp @@ -185,13 +185,13 @@ QSGTextureManager *QSGContext::createTextureManager() QSGTextureManager *manager; - if (args.contains("--partial-texture-manager")) { - printf("QSGContext: Using partial upload texture manager\n"); +// if (args.contains("--partial-texture-manager")) { +// printf("QSGContext: Using partial upload texture manager\n"); manager = new QSGPartialUploadTextureManager; - } else { - printf("QSGContext: Using basic texture manager\n"); - manager = new QSGTextureManager; - } +// } else { +// printf("QSGContext: Using basic texture manager\n"); +// manager = new QSGTextureManager; +// } // } else if (args.contains("--threaded-texture-manager")) { // printf("QSGContext: Using threaded texture manager\n"); diff --git a/src/scenegraph/coreapi/qsgtexturemanager.cpp b/src/scenegraph/coreapi/qsgtexturemanager.cpp index c0ba364..bb1a2e2 100644 --- a/src/scenegraph/coreapi/qsgtexturemanager.cpp +++ b/src/scenegraph/coreapi/qsgtexturemanager.cpp @@ -52,6 +52,19 @@ #define GL_BGRA 0x80E1 #endif + +void QSGTextureManagerPrivate::removeTextureFromCache(QSGTexture *texture) +{ + for (QHash<QSGTextureCacheKey, QSGTexture *>::iterator it = cache.begin(); + it != cache.end(); ++it) { + if (it.value() == texture) { + cache.remove(it.key()); + break; + } + } +} + + QSGTexture::QSGTexture() : m_status(Null) , m_texture_id(0) @@ -138,13 +151,7 @@ QSGContext *QSGTextureManager::context() const void QSGTextureManager::textureDestroyed(QObject *destroyed) { Q_D(QSGTextureManager); - for (QHash<QSGTextureCacheKey, QSGTexture *>::iterator it = d->cache.begin(); - it != d->cache.end(); ++it) { - if (it.value() == destroyed) { - d->cache.remove(it.key()); - break; - } - } + d->removeTextureFromCache(static_cast<QSGTexture *>(destroyed)); } diff --git a/src/scenegraph/coreapi/qsgtexturemanager.h b/src/scenegraph/coreapi/qsgtexturemanager.h index 1abca84..40424c2 100644 --- a/src/scenegraph/coreapi/qsgtexturemanager.h +++ b/src/scenegraph/coreapi/qsgtexturemanager.h @@ -139,7 +139,8 @@ public: QSGTextureRef &operator=(const QSGTextureRef &other) { - ++other.m_texture->m_ref_count; + if (other.m_texture) + ++other.m_texture->m_ref_count; deref(); m_texture = other.m_texture; m_sub_rect = other.m_sub_rect; @@ -175,7 +176,7 @@ public: QSGContext *context() const; virtual QSGTextureRef upload(const QImage &image); - virtual QSGTextureRef requestUpload(const QImage &image, const QObject *listener, const char *slot); + virtual QSGTextureRef requestUpload(const QImage &image, const QObject *listener=0, const char *slot=0); static void swizzleBGRAToRGBA(QImage *image); diff --git a/src/scenegraph/coreapi/qsgtexturemanager_p.h b/src/scenegraph/coreapi/qsgtexturemanager_p.h index 8ed7a17..28cdd17 100644 --- a/src/scenegraph/coreapi/qsgtexturemanager_p.h +++ b/src/scenegraph/coreapi/qsgtexturemanager_p.h @@ -68,6 +68,8 @@ public: uint upload(const QImage &image, GLuint id); QSGTextureRef upload(const QImage &image, const QObject *listener, const char *slot); + void removeTextureFromCache(QSGTexture *texture); + QSGContext *context; QHash<QSGTextureCacheKey, QSGTexture *> cache; diff --git a/tests/auto/texturemanager/tst_texturemanagertest.cpp b/tests/auto/texturemanager/tst_texturemanagertest.cpp index 3d29eb4..9805478 100644 --- a/tests/auto/texturemanager/tst_texturemanagertest.cpp +++ b/tests/auto/texturemanager/tst_texturemanagertest.cpp @@ -70,6 +70,8 @@ private Q_SLOTS: void gracefullyRunOutOfMemory(); void gracefullyFailOnTooLarge(); + void deletingTextures(); + void maxTextureSize(); public slots: @@ -156,7 +158,7 @@ void TextureManagerTest::requestUpload() QVERIFY(t->status() == QSGTexture::Ready || t->status() == QSGTexture::Loading); QTime time; time.start(); - while (t->status() == QSGTexture::Loading && time.elapsed() < 1000) { + while (t->status() == QSGTexture::Loading && time.elapsed() < 10000) { QTest::qWait(50); QApplication::processEvents(); } @@ -181,7 +183,7 @@ void TextureManagerTest::requestUploadSameImageTwiceWithDelay() QTime time; time.start(); - while (t->status() == QSGTexture::Loading && time.elapsed() < 1000) { + while (t->status() == QSGTexture::Loading && time.elapsed() < 10000) { QTest::qWait(50); QApplication::processEvents(); } @@ -297,6 +299,50 @@ void TextureManagerTest::uploadAfterRequestUpload() +void TextureManagerTest::deletingTextures() +{ + QImage image(100, 100, QImage::Format_ARGB32_Premultiplied); + + // Verify that scheduling several textures which are then removed + // does not cause problems for a following requests. + // - Async when async is deleted + for (int i=0; i<100; ++i) + QSGTextureRef async2 = tm->requestUpload(image.copy()); + QSGTextureRef async1 = tm->requestUpload(image); + QTime time; + time.start(); + while (!async1.isReady() && time.elapsed() < 10000) { + QTest::qWait(50); + QApplication::processEvents(); + } + QVERIFY(async1.isReady()); + + + // Delete the uploaded texture and force upload it again + // - sync when async is deleted + async1 = QSGTextureRef(); + QSGTextureRef sync = tm->upload(image); + QVERIFY(sync.isReady()); + + + // Delete the sync texture and upload again + // - sync when sync is deleted + sync = QSGTextureRef(); + sync = tm->upload(image); + + + // Delete the sync texture and upload it async + // - async when sync is deleted + sync = QSGTextureRef(); + async1 = tm->requestUpload(image); + time.start(); + while (!async1.isReady() && time.elapsed() < 10000) { + QTest::qWait(50); + QApplication::processEvents(); + } + QVERIFY(async1.isReady()); +} + QTEST_MAIN(TextureManagerTest); |