diff options
Diffstat (limited to 'src/scenegraph/coreapi/qsgtexturemanager.cpp')
-rw-r--r-- | src/scenegraph/coreapi/qsgtexturemanager.cpp | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/src/scenegraph/coreapi/qsgtexturemanager.cpp b/src/scenegraph/coreapi/qsgtexturemanager.cpp index a26d353..11228e5 100644 --- a/src/scenegraph/coreapi/qsgtexturemanager.cpp +++ b/src/scenegraph/coreapi/qsgtexturemanager.cpp @@ -197,13 +197,27 @@ QSGTextureRef QSGTextureManager::upload(const QImage &image) { Q_ASSERT(!image.isNull()); + // Check if the image is already uploaded and cached QSGTextureCacheKey key = { image.cacheKey() }; QSGTexture *texture = d->cache.value(key); if (texture) return QSGTextureRef(texture); - while (glGetError() != GL_NO_ERROR) {} + // Check if the image is already scheduled for asynchronous upload... + // If so, kill the partial texture and upload in one go below using a new texture.. + for (int i=0; i<d->asyncUploads.size(); ++i) { + const QSGTextureAsyncUpload &work = d->asyncUploads.at(i); + if (work.image.cacheKey() == image.cacheKey()) { + texture = work.texture; + GLuint tid = texture->textureId(); + if (tid) + glDeleteTextures(1, &tid); + d->asyncUploads.removeAt(i); + } + } + // image not already scheduled, upload normally... + while (glGetError() != GL_NO_ERROR) {} GLuint id; glGenTextures(1, &id); @@ -227,7 +241,8 @@ QSGTextureRef QSGTextureManager::upload(const QImage &image) return QSGTextureRef(); } - texture = new QSGTexture; + if (!texture) + texture = new QSGTexture; texture->setTextureId(id); texture->setTextureSize(image.size()); texture->setAlphaChannel(image.hasAlphaChannel()); @@ -242,6 +257,12 @@ QSGTextureRef QSGTextureManager::upload(const QImage &image) } +/*! + Schedules \a image to be uploaded. + + The function returns a texture reference which is + + */ QSGTextureRef QSGTextureManager::requestUpload(const QImage &image, const QObject *listener, const char *slot) @@ -249,14 +270,12 @@ QSGTextureRef QSGTextureManager::requestUpload(const QImage &image, Q_ASSERT(!image.isNull()); QSGTexture *t = 0; - // Check if the image is already uploaded and thus part of the cache.. QSGTextureCacheKey key = { image.cacheKey() }; t = d->cache.value(key); if (t) return QSGTextureRef(t); - // Check if the image is already scheduled for asynchronous upload... for (int i=0; i<d->asyncUploads.size(); ++i) { const QSGTextureAsyncUpload &work = d->asyncUploads.at(i); @@ -265,7 +284,7 @@ QSGTextureRef QSGTextureManager::requestUpload(const QImage &image, } } - + // Not present in any caches, upload normally... t = new QSGTexture(); t->setStatus(QSGTexture::Loading); if (listener && slot) @@ -310,7 +329,6 @@ void QSGTextureManager::processAsyncTextures() time.start(); d->lastUpload.restart(); - while (!d->asyncUploads.isEmpty()) { QSGTextureAsyncUpload &upload = d->asyncUploads.first(); @@ -343,6 +361,7 @@ void QSGTextureManager::processAsyncTextures() if (error != GL_NO_ERROR) { glBindTexture(GL_TEXTURE_2D, 0); glDeleteTextures(1, &id); + d->asyncUploads.dequeue(); if (error != GL_OUT_OF_MEMORY) { qWarning("QSGTextureManager::async upload failed, OpenGL error code: %x", error); t->setStatus(QSGTexture::Error); @@ -368,7 +387,6 @@ void QSGTextureManager::processAsyncTextures() int y = (upload.progress / hChunkCount) * d->uploadChunkSize; QRect area = QRect(x, y, d->uploadChunkSize, d->uploadChunkSize) & upload.image.rect(); - QImage subImage = upload.image.copy(area); // printf("ASYNC: - doing another batch: %d (x=%d, y=%d, w=%d, h=%d\n", // upload.progress, @@ -382,7 +400,8 @@ void QSGTextureManager::processAsyncTextures() if (upload.progress == chunkCount) { t->setStatus(QSGTexture::Ready); - disconnect(t, SIGNAL(destroyed(QObject*)), this, SLOT(textureDestroyed(QObject*))); + QSGTextureCacheKey key = { upload.image.cacheKey() }; + d->cache.insert(key, t); d->asyncUploads.dequeue(); if (d->asyncUploads.size() == 0) { killTimer(d->uploadTimer); |