summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2010-12-21 08:49:35 +0100
committerGunnar Sletta <gunnar.sletta@nokia.com>2010-12-21 08:49:35 +0100
commitc69e112c892dbb017a83189dba56884b0717b171 (patch)
tree2bc28993692eb10e1de3279d0ade2c6a1fab9d74
parent4092945f09a12b53b545658cfa580f793864d2d9 (diff)
More sanity checks for the texture manager
-rw-r--r--src/adaptationlayers/qsgpartialuploadtexturemanager.cpp19
-rw-r--r--src/adaptationlayers/qsgpartialuploadtexturemanager.h3
-rw-r--r--src/scenegraph/coreapi/qsgcontext.cpp12
-rw-r--r--src/scenegraph/coreapi/qsgtexturemanager.cpp21
-rw-r--r--src/scenegraph/coreapi/qsgtexturemanager.h5
-rw-r--r--src/scenegraph/coreapi/qsgtexturemanager_p.h2
-rw-r--r--tests/auto/texturemanager/tst_texturemanagertest.cpp50
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);