summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJani Hautakangas <jani.hautakangas@nokia.com>2011-05-10 20:41:09 (GMT)
committerJani Hautakangas <jani.hautakangas@nokia.com>2011-06-09 10:31:54 (GMT)
commit489baff3d49f7acce8d36dd98d27885ca207d6e7 (patch)
treef9b7a0decd67048b52c0513b7665ccd46135a8ce
parent7b0762c17f9899e68c0f67480a81b25c6f0c7dda (diff)
downloadQt-489baff3d49f7acce8d36dd98d27885ca207d6e7.zip
Qt-489baff3d49f7acce8d36dd98d27885ca207d6e7.tar.gz
Qt-489baff3d49f7acce8d36dd98d27885ca207d6e7.tar.bz2
Simplify texture pooling logic in GL graphics system.
Remove ugly TemporarilyCachedBindOption and use QGLTexture objects as texture pool entries instead of QGLPixmapData. Make texture pooling totally Symbian specific, remove VG like texture pooling code and use common texture binding path which is used on other platforms also on Symbian. QGLPixmapData should be only used to bind SgImage based textures (will be implemented by another commit). Task-number: QTBUG-19180 Reviewed-by: Samuel Rødal
-rw-r--r--src/gui/image/qpixmapdata_p.h5
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp28
-rw-r--r--src/opengl/opengl.pro4
-rw-r--r--src/opengl/qgl.cpp33
-rw-r--r--src/opengl/qgl.h1
-rw-r--r--src/opengl/qgl_p.h27
-rw-r--r--src/opengl/qgltexturepool.cpp136
-rw-r--r--src/opengl/qgltexturepool_p.h37
-rw-r--r--src/opengl/qgraphicssystem_gl.cpp3
-rw-r--r--src/opengl/qpixmapdata_gl_p.h28
-rw-r--r--src/opengl/qpixmapdata_symbiangl.cpp (renamed from src/opengl/qpixmapdata_poolgl.cpp)123
-rw-r--r--src/opengl/qwindowsurface_gl.cpp62
-rw-r--r--src/openvg/qpixmapdata_vg_p.h1
13 files changed, 197 insertions, 291 deletions
diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h
index 3e5699d..099c61c 100644
--- a/src/gui/image/qpixmapdata_p.h
+++ b/src/gui/image/qpixmapdata_p.h
@@ -56,6 +56,10 @@
#include <QtGui/qpixmap.h>
#include <QtCore/qatomic.h>
+#ifdef Q_OS_SYMBIAN
+#include <QtGui/private/qvolatileimage_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QImageReader;
@@ -134,6 +138,7 @@ public:
}
#if defined(Q_OS_SYMBIAN)
+ virtual QVolatileImage toVolatileImage() const { return QVolatileImage(); }
virtual void* toNativeType(NativeType type);
virtual void fromNativeType(void* pixmap, NativeType type);
#endif
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 56c1fd0..803f949 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1331,14 +1331,11 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c
ensureActive();
d->transferMode(ImageDrawingMode);
- QGLContext::BindOptions bindOptions = QGLContext::InternalBindOption|QGLContext::CanFlipNativePixmapBindOption;
-#ifdef QGL_USE_TEXTURE_POOL
- bindOptions |= QGLContext::TemporarilyCachedBindOption;
-#endif
-
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
QGLTexture *texture =
- ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, bindOptions);
+ ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA,
+ QGLContext::InternalBindOption
+ | QGLContext::CanFlipNativePixmapBindOption);
GLfloat top = texture->options & QGLContext::InvertedYBindOption ? (pixmap.height() - src.top()) : src.top();
GLfloat bottom = texture->options & QGLContext::InvertedYBindOption ? (pixmap.height() - src.bottom()) : src.bottom();
@@ -1350,12 +1347,6 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c
d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, texture->id);
d->drawTexture(dest, srcRect, pixmap.size(), isOpaque, isBitmap);
-
- if (texture->options&QGLContext::TemporarilyCachedBindOption) {
- // pixmap was temporarily cached as a QImage texture by pooling system
- // and should be destroyed immediately
- QGLTextureCache::instance()->remove(ctx, texture->id);
- }
}
void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const QRectF& src,
@@ -1380,23 +1371,12 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
- QGLContext::BindOptions bindOptions = QGLContext::InternalBindOption;
-#ifdef QGL_USE_TEXTURE_POOL
- bindOptions |= QGLContext::TemporarilyCachedBindOption;
-#endif
-
- QGLTexture *texture = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, bindOptions);
+ QGLTexture *texture = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption);
GLuint id = texture->id;
d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, id);
d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel());
-
- if (texture->options&QGLContext::TemporarilyCachedBindOption) {
- // image was temporarily cached by texture pooling system
- // and should be destroyed immediately
- QGLTextureCache::instance()->remove(ctx, texture->id);
- }
}
void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem)
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index 6d79584..4375358 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -148,10 +148,10 @@ embedded {
}
symbian {
- DEFINES += QGL_USE_TEXTURE_POOL QGL_NO_PRESERVED_SWAP
+ DEFINES += QGL_NO_PRESERVED_SWAP
SOURCES -= qpixmapdata_gl.cpp
SOURCES += qgl_symbian.cpp \
- qpixmapdata_poolgl.cpp \
+ qpixmapdata_symbiangl.cpp \
qglpixelbuffer_egl.cpp \
qgl_egl.cpp \
qgltexturepool.cpp
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index d09190f..6248cfe 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -93,7 +93,7 @@
#include "qlibrary.h"
#include <qmutex.h>
-#ifdef QGL_USE_TEXTURE_POOL
+#ifdef Q_OS_SYMBIAN
#include <private/qgltexturepool_p.h>
#endif
@@ -1835,6 +1835,7 @@ QGLTextureCache::~QGLTextureCache()
void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, int cost)
{
QWriteLocker locker(&m_lock);
+
if (m_cache.totalCost() + cost > m_cache.maxCost()) {
// the cache is full - make an attempt to remove something
const QList<QGLTextureCacheKey> keys = m_cache.keys();
@@ -2026,10 +2027,6 @@ struct DDSFormat {
the pixmap/image that it stems from, e.g. installing destruction
hooks in them.
- \omitvalue TemporarilyCachedBindOption Used by paint engines on some
- platforms to indicate that the pixmap or image texture is possibly
- cached only temporarily and must be destroyed immediately after the use.
-
\omitvalue InternalBindOption
*/
@@ -2537,7 +2534,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
#endif
const QImage &constRef = img; // to avoid detach in bits()...
-#ifdef QGL_USE_TEXTURE_POOL
+#ifdef Q_OS_SYMBIAN
+ // On Symbian we always use texture pool to reserve the texture
QGLTexturePool::instance()->createPermanentTexture(tx_id,
target,
0, internalFormat,
@@ -2549,6 +2547,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
pixel_type, constRef.bits());
#endif
+
#if defined(QT_OPENGL_ES_2)
if (genMipmap)
glGenerateMipmap(target);
@@ -2572,6 +2571,13 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
QGLTexture *texture = new QGLTexture(q, tx_id, target, options);
QGLTextureCache::instance()->insert(q, key, texture, cost);
+#ifdef Q_OS_SYMBIAN
+ // Store the key so that QGLTexturePool
+ // is able to release this texture when needed.
+ texture->boundKey = key;
+ // And append to LRU list
+ QGLTexturePool::instance()->useTexture(texture);
+#endif
return texture;
}
@@ -2651,6 +2657,20 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target,
#endif
if (!texture) {
+#ifdef Q_OS_SYMBIAN
+ // On Symbian pixmaps are backed up by native CFbsBitmap
+ // which can be shared across processes. QVolatileImage wraps
+ // it and provides locking mechanism to pixel access.
+ QVolatileImage volatileImage = pd->toVolatileImage();
+ if (volatileImage.isNull()) { // TODO: raster graphics system don't provide volatile image (yet)
+ // NOTE! On Symbian raster graphics system QPixmap::toImage() makes deep copy
+ texture = bindTexture(pixmap.toImage(), target, format, key, options);
+ } else {
+ volatileImage.beginDataAccess();
+ texture = bindTexture(volatileImage.imageRef(), target, format, key, options);
+ volatileImage.endDataAccess(true);
+ }
+#else
QImage image = pixmap.toImage();
// If the system depth is 16 and the pixmap doesn't have an alpha channel
// then we convert it to RGB16 in the hope that it gets uploaded as a 16
@@ -2658,6 +2678,7 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target,
if (pixmap.depth() == 16 && !image.hasAlphaChannel() )
image = image.convertToFormat(QImage::Format_RGB16);
texture = bindTexture(image, target, format, key, options);
+#endif
}
// NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null
Q_ASSERT(texture);
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index e070f5f..cd61ee5 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -329,7 +329,6 @@ public:
MemoryManagedBindOption = 0x0010, // internal flag
CanFlipNativePixmapBindOption = 0x0020, // internal flag
- TemporarilyCachedBindOption = 0x0040, // internal flag
DefaultBindOption = LinearFilteringBindOption
| InvertedYBindOption
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index f64c65b..2fb7e58 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -64,6 +64,12 @@
#include "qcache.h"
#include "qglpaintdevice_p.h"
+#ifdef Q_OS_SYMBIAN
+#include "qgltexturepool_p.h"
+
+class QGLPixmapData;
+#endif
+
#ifndef QT_NO_EGL
#include <QtGui/private/qegl_p.h>
#endif
@@ -540,6 +546,14 @@ public:
options(opt)
#if defined(Q_WS_X11)
, boundPixmap(0)
+#elif defined(Q_OS_SYMBIAN)
+ , boundPixmap(0)
+ , boundKey(0)
+ , nextLRU(0)
+ , prevLRU(0)
+ , inLRU(false)
+ , failedToAlloc(false)
+ , inTexturePool(false)
#endif
{}
@@ -551,7 +565,7 @@ public:
#endif
context->d_ptr->texture_destroyer->emitFreeTexture(context, boundPixmap, id);
}
- }
+ }
QGLContext *context;
GLuint id;
@@ -571,6 +585,17 @@ public:
(const char *buf, int len, const char *format = 0);
QSize bindCompressedTextureDDS(const char *buf, int len);
QSize bindCompressedTexturePVR(const char *buf, int len);
+
+#ifdef Q_OS_SYMBIAN
+ QGLPixmapData* boundPixmap;
+ qint64 boundKey;
+
+ QGLTexture *nextLRU;
+ QGLTexture *prevLRU;
+ mutable bool inLRU;
+ mutable bool failedToAlloc;
+ mutable bool inTexturePool;
+#endif
};
struct QGLTextureCacheKey {
diff --git a/src/opengl/qgltexturepool.cpp b/src/opengl/qgltexturepool.cpp
index d809328..9ad66f2 100644
--- a/src/opengl/qgltexturepool.cpp
+++ b/src/opengl/qgltexturepool.cpp
@@ -41,6 +41,7 @@
#include "qgltexturepool_p.h"
#include "qpixmapdata_gl_p.h"
+#include "qgl_p.h"
QT_BEGIN_NAMESPACE
@@ -53,8 +54,8 @@ class QGLTexturePoolPrivate
public:
QGLTexturePoolPrivate() : lruFirst(0), lruLast(0) {}
- QGLPixmapData *lruFirst;
- QGLPixmapData *lruLast;
+ QGLTexture *lruFirst;
+ QGLTexture *lruLast;
};
QGLTexturePool::QGLTexturePool()
@@ -73,36 +74,36 @@ QGLTexturePool *QGLTexturePool::instance()
return qt_gl_texture_pool;
}
-GLuint QGLTexturePool::createTextureForPixmap(GLenum target,
+GLuint QGLTexturePool::createTexture(GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
- QGLPixmapData *data)
+ QGLTexture *texture)
{
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(target, texture);
+ GLuint tex;
+ glGenTextures(1, &tex);
+ glBindTexture(target, tex);
do {
glTexImage2D(target, level, internalformat, width, height, 0, format, type, 0);
GLenum error = glGetError();
if (error == GL_NO_ERROR) {
- if (data)
- moveToHeadOfLRU(data);
- return texture;
+ if (texture)
+ moveToHeadOfLRU(texture);
+ return tex;
} else if (error != GL_OUT_OF_MEMORY) {
qWarning("QGLTexturePool: cannot create temporary texture because of invalid params");
return 0;
}
- } while (reclaimSpace(internalformat, width, height, format, type, data));
- qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d pixmap",
+ } while (reclaimSpace(internalformat, width, height, format, type, texture));
+ qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d texture",
width, height);
return 0;
}
-bool QGLTexturePool::createPermanentTexture(GLuint texture,
+bool QGLTexturePool::createPermanentTexture(GLuint tex,
GLenum target,
GLint level,
GLint internalformat,
@@ -112,7 +113,7 @@ bool QGLTexturePool::createPermanentTexture(GLuint texture,
GLenum type,
const GLvoid *data)
{
- glBindTexture(target, texture);
+ glBindTexture(target, tex);
do {
glTexImage2D(target, level, internalformat, width, height, 0, format, type, data);
@@ -124,32 +125,21 @@ bool QGLTexturePool::createPermanentTexture(GLuint texture,
return false;
}
} while (reclaimSpace(internalformat, width, height, format, type, 0));
- qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d pixmap",
+ qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d texture",
width, height);
return 0;
}
-void QGLTexturePool::releaseTexture(QGLPixmapData *data, GLuint texture)
+void QGLTexturePool::useTexture(QGLTexture *texture)
{
- // Very simple strategy at the moment: just destroy the texture.
- if (data)
- removeFromLRU(data);
-
- QGLWidget *shareWidget = qt_gl_share_widget();
- if (shareWidget) {
- QGLShareContextScope ctx(shareWidget->context());
- glDeleteTextures(1, &texture);
- }
-}
-
-void QGLTexturePool::useTexture(QGLPixmapData *data)
-{
- moveToHeadOfLRU(data);
+ moveToHeadOfLRU(texture);
+ texture->inTexturePool = true;
}
-void QGLTexturePool::detachTexture(QGLPixmapData *data)
+void QGLTexturePool::detachTexture(QGLTexture *texture)
{
- removeFromLRU(data);
+ removeFromLRU(texture);
+ texture->inTexturePool = false;
}
bool QGLTexturePool::reclaimSpace(GLint internalformat,
@@ -157,7 +147,7 @@ bool QGLTexturePool::reclaimSpace(GLint internalformat,
GLsizei height,
GLenum format,
GLenum type,
- QGLPixmapData *data)
+ QGLTexture *texture)
{
Q_UNUSED(internalformat); // For future use in picking the best texture to eject.
Q_UNUSED(width);
@@ -167,19 +157,22 @@ bool QGLTexturePool::reclaimSpace(GLint internalformat,
bool succeeded = false;
bool wasInLRU = false;
- if (data) {
- wasInLRU = data->inLRU;
- moveToHeadOfLRU(data);
+ if (texture) {
+ wasInLRU = texture->inLRU;
+ moveToHeadOfLRU(texture);
}
- QGLPixmapData *lrudata = pixmapLRU();
- if (lrudata && lrudata != data) {
- lrudata->reclaimTexture();
+ QGLTexture *lrutexture = textureLRU();
+ if (lrutexture && lrutexture != texture) {
+ if (lrutexture->boundPixmap)
+ lrutexture->boundPixmap->reclaimTexture();
+ else
+ QGLTextureCache::instance()->remove(lrutexture->boundKey);
succeeded = true;
}
- if (data && !wasInLRU)
- removeFromLRU(data);
+ if (texture && !wasInLRU)
+ removeFromLRU(texture);
return succeeded;
}
@@ -187,55 +180,58 @@ bool QGLTexturePool::reclaimSpace(GLint internalformat,
void QGLTexturePool::hibernate()
{
Q_D(QGLTexturePool);
- QGLPixmapData *pd = d->lruLast;
- while (pd) {
- QGLPixmapData *prevLRU = pd->prevLRU;
- pd->inTexturePool = false;
- pd->inLRU = false;
- pd->nextLRU = 0;
- pd->prevLRU = 0;
- pd->hibernate();
- pd = prevLRU;
+ QGLTexture *texture = d->lruLast;
+ while (texture) {
+ QGLTexture *prevLRU = texture->prevLRU;
+ texture->inTexturePool = false;
+ texture->inLRU = false;
+ texture->nextLRU = 0;
+ texture->prevLRU = 0;
+ if (texture->boundPixmap)
+ texture->boundPixmap->hibernate();
+ else
+ QGLTextureCache::instance()->remove(texture->boundKey);
+ texture = prevLRU;
}
d->lruFirst = 0;
d->lruLast = 0;
}
-void QGLTexturePool::moveToHeadOfLRU(QGLPixmapData *data)
+void QGLTexturePool::moveToHeadOfLRU(QGLTexture *texture)
{
Q_D(QGLTexturePool);
- if (data->inLRU) {
- if (!data->prevLRU)
+ if (texture->inLRU) {
+ if (!texture->prevLRU)
return; // Already at the head of the list.
- removeFromLRU(data);
+ removeFromLRU(texture);
}
- data->inLRU = true;
- data->nextLRU = d->lruFirst;
- data->prevLRU = 0;
+ texture->inLRU = true;
+ texture->nextLRU = d->lruFirst;
+ texture->prevLRU = 0;
if (d->lruFirst)
- d->lruFirst->prevLRU = data;
+ d->lruFirst->prevLRU = texture;
else
- d->lruLast = data;
- d->lruFirst = data;
+ d->lruLast = texture;
+ d->lruFirst = texture;
}
-void QGLTexturePool::removeFromLRU(QGLPixmapData *data)
+void QGLTexturePool::removeFromLRU(QGLTexture *texture)
{
Q_D(QGLTexturePool);
- if (!data->inLRU)
+ if (!texture->inLRU)
return;
- if (data->nextLRU)
- data->nextLRU->prevLRU = data->prevLRU;
+ if (texture->nextLRU)
+ texture->nextLRU->prevLRU = texture->prevLRU;
else
- d->lruLast = data->prevLRU;
- if (data->prevLRU)
- data->prevLRU->nextLRU = data->nextLRU;
+ d->lruLast = texture->prevLRU;
+ if (texture->prevLRU)
+ texture->prevLRU->nextLRU = texture->nextLRU;
else
- d->lruFirst = data->nextLRU;
- data->inLRU = false;
+ d->lruFirst = texture->nextLRU;
+ texture->inLRU = false;
}
-QGLPixmapData *QGLTexturePool::pixmapLRU()
+QGLTexture *QGLTexturePool::textureLRU()
{
Q_D(QGLTexturePool);
return d->lruLast;
diff --git a/src/opengl/qgltexturepool_p.h b/src/opengl/qgltexturepool_p.h
index 27b730c..07f9700 100644
--- a/src/opengl/qgltexturepool_p.h
+++ b/src/opengl/qgltexturepool_p.h
@@ -58,7 +58,7 @@
QT_BEGIN_NAMESPACE
-class QGLPixmapData;
+class QGLTexture;
class QGLTexturePoolPrivate;
class QGLTexturePool
@@ -70,18 +70,18 @@ public:
static QGLTexturePool *instance();
// Create a new texture with the specified parameters and associate
- // it with "data". The QGLPixmapData will be notified when the
+ // it with "texture". The QGLTexture will be notified when the
// texture needs to be reclaimed by the pool.
//
// This function will call reclaimSpace() when texture creation fails.
- GLuint createTextureForPixmap(GLenum target,
+ GLuint createTexture(GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
- QGLPixmapData *data);
+ QGLTexture *texture);
// Create a permanent texture with the specified parameters.
// If there is insufficient space for the texture,
@@ -100,40 +100,37 @@ public:
GLenum type,
const GLvoid *data);
- // Release a texture that is no longer required.
- void releaseTexture(QGLPixmapData *data, GLuint texture);
-
- // Notify the pool that a QGLPixmapData object is using
+ // Notify the pool that a QGLTexture object is using
// an texture again. This allows the pool to move the texture
- // within a least-recently-used list of QGLPixmapData objects.
- void useTexture(QGLPixmapData *data);
+ // within a least-recently-used list of QGLTexture objects.
+ void useTexture(QGLTexture *texture);
// Notify the pool that the texture associated with a
- // QGLPixmapData is being detached from the pool. The caller
+ // QGLTexture is being detached from the pool. The caller
// will become responsible for calling glDeleteTextures().
- void detachTexture(QGLPixmapData *data);
+ void detachTexture(QGLTexture *texture);
// Reclaim space for an image allocation with the specified parameters.
// Returns true if space was reclaimed, or false if there is no
- // further space that can be reclaimed. The "data" parameter
- // indicates the pixmap that is trying to obtain space which should
+ // further space that can be reclaimed. The "texture" parameter
+ // indicates the texture that is trying to obtain space which should
// not itself be reclaimed.
bool reclaimSpace(GLint internalformat,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
- QGLPixmapData *data);
+ QGLTexture *data);
- // Hibernate the image pool because the context is about to be
+ // Hibernate the texture pool because the context is about to be
// destroyed. All textures left in the pool should be released.
void hibernate();
protected:
- // Helper functions for managing the LRU list of QGLPixmapData objects.
- void moveToHeadOfLRU(QGLPixmapData *data);
- void removeFromLRU(QGLPixmapData *data);
- QGLPixmapData *pixmapLRU();
+ // Helper functions for managing the LRU list of QGLTexture objects.
+ void moveToHeadOfLRU(QGLTexture *texture);
+ void removeFromLRU(QGLTexture *texture);
+ QGLTexture *textureLRU();
private:
QScopedPointer<QGLTexturePoolPrivate> d_ptr;
diff --git a/src/opengl/qgraphicssystem_gl.cpp b/src/opengl/qgraphicssystem_gl.cpp
index 8530b52..265bf22 100644
--- a/src/opengl/qgraphicssystem_gl.cpp
+++ b/src/opengl/qgraphicssystem_gl.cpp
@@ -55,9 +55,6 @@
#if defined(Q_OS_SYMBIAN)
#include <QtGui/private/qapplication_p.h>
-#endif
-
-#ifdef QGL_USE_TEXTURE_POOL
#include "private/qgltexturepool_p.h"
#endif
diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h
index 909f264..bf1a303 100644
--- a/src/opengl/qpixmapdata_gl_p.h
+++ b/src/opengl/qpixmapdata_gl_p.h
@@ -70,12 +70,6 @@ class QGLFramebufferObject;
class QGLFramebufferObjectFormat;
class QGLPixmapData;
-#ifdef QGL_USE_TEXTURE_POOL
-void qt_gl_register_pixmap(QGLPixmapData *pd);
-void qt_gl_unregister_pixmap(QGLPixmapData *pd);
-void qt_gl_hibernate_pixmaps();
-#endif
-
#ifdef Q_OS_SYMBIAN
class QNativeImageHandleProvider;
#endif
@@ -143,7 +137,7 @@ public:
GLuint bind(bool copyBack = true) const;
QGLTexture *texture() const;
-#ifdef QGL_USE_TEXTURE_POOL
+#ifdef Q_OS_SYMBIAN
void destroyTexture();
// Detach this image from the image pool.
void detachTextureFromPool();
@@ -158,9 +152,8 @@ public:
// texture objects to reuse storage.
void reclaimTexture();
void forceToImage();
-#endif
-#ifdef Q_OS_SYMBIAN
+ QVolatileImage toVolatileImage() const { return m_source; }
QImage::Format idealFormat(QImage &image, Qt::ImageConversionFlags flags);
void* toNativeType(NativeType type);
void fromNativeType(void* pixmap, NativeType type);
@@ -218,23 +211,6 @@ private:
mutable QGLPixmapGLPaintDevice m_glDevice;
-#ifdef QGL_USE_TEXTURE_POOL
- QGLPixmapData *nextLRU;
- QGLPixmapData *prevLRU;
- mutable bool inLRU;
- mutable bool failedToAlloc;
- mutable bool inTexturePool;
-
- QGLPixmapData *next;
- QGLPixmapData *prev;
-
- friend class QGLTexturePool;
-
- friend void qt_gl_register_pixmap(QGLPixmapData *pd);
- friend void qt_gl_unregister_pixmap(QGLPixmapData *pd);
- friend void qt_gl_hibernate_pixmaps();
-#endif
-
friend class QGLPixmapGLPaintDevice;
friend class QMeeGoPixmapData;
friend class QMeeGoLivePixmapData;
diff --git a/src/opengl/qpixmapdata_poolgl.cpp b/src/opengl/qpixmapdata_symbiangl.cpp
index c69ac5d..8c3d61a 100644
--- a/src/opengl/qpixmapdata_poolgl.cpp
+++ b/src/opengl/qpixmapdata_symbiangl.cpp
@@ -247,43 +247,14 @@ QGLPixmapData::QGLPixmapData(PixelType type)
, m_dirty(false)
, m_hasFillColor(false)
, m_hasAlpha(false)
- , inLRU(false)
- , failedToAlloc(false)
- , inTexturePool(false)
{
setSerialNumber(++qt_gl_pixmap_serial);
m_glDevice.setPixmapData(this);
-
- qt_gl_register_pixmap(this);
}
QGLPixmapData::~QGLPixmapData()
{
delete m_engine;
-
- destroyTexture();
- qt_gl_unregister_pixmap(this);
-}
-
-void QGLPixmapData::destroyTexture()
-{
- if (inTexturePool) {
- QGLTexturePool *pool = QGLTexturePool::instance();
- if (m_texture.id)
- pool->releaseTexture(this, m_texture.id);
- } else {
- if (m_texture.id) {
- QGLWidget *shareWidget = qt_gl_share_widget();
- if (shareWidget) {
- QGLShareContextScope ctx(shareWidget->context());
- glDeleteTextures(1, &m_texture.id);
- }
- }
- }
- m_texture.id = 0;
- inTexturePool = false;
-
- releaseNativeImageHandle();
}
QPixmapData *QGLPixmapData::createCompatiblePixmapData() const
@@ -298,11 +269,13 @@ bool QGLPixmapData::isValid() const
bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
{
- if (ctx == m_ctx)
- return true;
-
- const QGLContext *share_ctx = qt_gl_share_widget()->context();
- return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
+ // On Symbian, we usually want to treat QGLPixmapData as
+ // raster pixmap data because that's well known and tested
+ // execution path which is used on other platforms as well.
+ // That's why if source pixels are valid we return false
+ // to simulate raster pixmaps. Only QPixmaps created from
+ // SgImage will enable usage of QGLPixmapData.
+ return false;
}
void QGLPixmapData::resize(int width, int height)
@@ -353,27 +326,25 @@ void QGLPixmapData::ensureCreated() const
if (!m_source.isNull() && m_source.format() == QImage::Format_RGB16)
type = GL_UNSIGNED_SHORT_5_6_5;
- m_texture.options &= ~QGLContext::MemoryManagedBindOption;
-
if (!m_texture.id) {
- m_texture.id = QGLTexturePool::instance()->createTextureForPixmap(
+ m_texture.id = QGLTexturePool::instance()->createTexture(
target,
0, internal_format,
w, h,
external_format,
type,
- const_cast<QGLPixmapData*>(this));
+ &m_texture);
if (!m_texture.id) {
- failedToAlloc = true;
+ m_texture.failedToAlloc = true;
return;
}
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- inTexturePool = true;
- } else if (inTexturePool) {
+ m_texture.inTexturePool = true;
+ } else if (m_texture.inTexturePool) {
glBindTexture(target, m_texture.id);
- QGLTexturePool::instance()->useTexture(const_cast<QGLPixmapData*>(this));
+ QGLTexturePool::instance()->useTexture(&m_texture);
}
if (!m_source.isNull() && m_texture.id) {
@@ -753,15 +724,8 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
bool QGLPixmapData::useFramebufferObjects() const
{
-#ifdef Q_OS_SYMBIAN
- // We don't want to use FBOs on Symbian
+ // We don't use FBOs on Symbian for now
return false;
-#else
- return QGLFramebufferObject::hasOpenGLFramebufferObjects()
- && QGLFramebufferObject::hasOpenGLFramebufferBlit()
- && qt_gl_preferGL2Engine()
- && (w * h > 32*32); // avoid overhead of FBOs for small pixmaps
-#endif
}
QPaintEngine* QGLPixmapData::paintEngine() const
@@ -845,40 +809,6 @@ QGLTexture* QGLPixmapData::texture() const
return &m_texture;
}
-void QGLPixmapData::detachTextureFromPool()
-{
- if (inTexturePool) {
- QGLTexturePool::instance()->detachTexture(this);
- inTexturePool = false;
- }
-}
-
-void QGLPixmapData::hibernate()
-{
- // If the image was imported (e.g, from an SgImage under Symbian), then
- // skip the hibernation, there is no sense in copying it back to main
- // memory because the data is most likely shared between several processes.
- bool skipHibernate = (m_texture.id && m_source.isNull());
-#if defined(Q_OS_SYMBIAN)
- // However we have to proceed normally if the image was retrieved via
- // a handle provider.
- skipHibernate &= !nativeImageHandleProvider;
-#endif
- if (skipHibernate)
- return;
-
- forceToImage();
- destroyTexture();
-}
-
-void QGLPixmapData::reclaimTexture()
-{
- if (!inTexturePool)
- return;
- forceToImage();
- destroyTexture();
-}
-
Q_GUI_EXPORT int qt_defaultDpiX();
Q_GUI_EXPORT int qt_defaultDpiY();
@@ -928,6 +858,31 @@ void QGLPixmapData::forceToImage()
m_dirty = true;
}
+void QGLPixmapData::destroyTexture()
+{
+ // Destroy SgImage texture
+}
+
+void QGLPixmapData::detachTextureFromPool()
+{
+ QGLTexturePool::instance()->detachTexture(&m_texture);
+}
+
+void QGLPixmapData::hibernate()
+{
+ destroyTexture();
+}
+
+void QGLPixmapData::reclaimTexture()
+{
+ if (!m_texture.inTexturePool)
+ return;
+
+ forceToImage();
+
+ destroyTexture();
+}
+
QGLPaintDevice *QGLPixmapData::glDevice() const
{
return &m_glDevice;
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index 238d127..17b2044 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -184,7 +184,7 @@ QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL)
class QGLGlobalShareWidget
{
public:
- QGLGlobalShareWidget() : firstPixmap(0), widgetRefCount(0), widget(0), initializing(false) {}
+ QGLGlobalShareWidget() : refCount(0), widget(0), initializing(false) {}
QGLWidget *shareWidget() {
if (!initializing && !widget && !cleanedUp) {
@@ -223,9 +223,7 @@ public:
}
static bool cleanedUp;
-
- QGLPixmapData *firstPixmap;
- int widgetRefCount;
+ int refCount;
private:
QGLWidget *widget;
@@ -257,43 +255,6 @@ void qt_destroy_gl_share_widget()
_qt_gl_share_widget()->destroy();
}
-#ifdef QGL_USE_TEXTURE_POOL
-void qt_gl_register_pixmap(QGLPixmapData *pd)
-{
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
- pd->next = shared->firstPixmap;
- pd->prev = 0;
- if (shared->firstPixmap)
- shared->firstPixmap->prev = pd;
- shared->firstPixmap = pd;
-}
-
-void qt_gl_unregister_pixmap(QGLPixmapData *pd)
-{
- if (pd->next)
- pd->next->prev = pd->prev;
- if (pd->prev) {
- pd->prev->next = pd->next;
- } else {
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
- if (shared)
- shared->firstPixmap = pd->next;
- }
-}
-
-void qt_gl_hibernate_pixmaps()
-{
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
-
- // Scan all QGLPixmapData objects in the system and hibernate them.
- QGLPixmapData *pd = shared->firstPixmap;
- while (pd != 0) {
- pd->hibernate();
- pd = pd->next;
- }
-}
-#endif
-
struct QGLWindowSurfacePrivate
{
QGLFramebufferObject *fbo;
@@ -393,18 +354,10 @@ QGLWindowSurface::~QGLWindowSurface()
if (QGLGlobalShareWidget::cleanedUp)
return;
- --(_qt_gl_share_widget()->widgetRefCount);
-
-#ifdef QGL_USE_TEXTURE_POOL
- if (_qt_gl_share_widget()->widgetRefCount <= 0) {
- // All of the widget window surfaces have been destroyed
- // but we still have GL pixmaps active. Ask them to hibernate
- // to free up GPU resources until a widget is shown again.
- // This may eventually cause the EGLContext to be destroyed
- // because nothing in the system needs a context, which will
- // free up even more GPU resources.
- qt_gl_hibernate_pixmaps();
+ --(_qt_gl_share_widget()->refCount);
+#ifdef Q_OS_SYMBIAN
+ if (_qt_gl_share_widget()->refCount <= 0) {
// Destroy the context if necessary.
if (!qt_gl_share_widget()->context()->isSharing())
qt_destroy_gl_share_widget();
@@ -458,7 +411,7 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
ctx->create(qt_gl_share_widget()->context());
if (widget != qt_gl_share_widget())
- ++(_qt_gl_share_widget()->widgetRefCount);
+ ++(_qt_gl_share_widget()->refCount);
#ifndef QT_NO_EGL
static bool checkedForNOKSwapRegion = false;
@@ -495,6 +448,7 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
voidPtr = &widgetPrivate->extraData()->glContext;
d_ptr->contexts << ctxPtr;
+
#ifndef Q_OS_SYMBIAN
qDebug() << "hijackWindow() context created for" << widget << d_ptr->contexts.size();
#endif
@@ -870,7 +824,7 @@ void QGLWindowSurface::updateGeometry() {
#ifdef Q_OS_SYMBIAN // Symbian needs to recreate the context when native window size changes
if (d_ptr->size != geometry().size()) {
if (window() != qt_gl_share_widget())
- --(_qt_gl_share_widget()->widgetRefCount);
+ --(_qt_gl_share_widget()->refCount);
delete wd->extraData()->glContext;
wd->extraData()->glContext = 0;
diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h
index 901bad9..18846f3 100644
--- a/src/openvg/qpixmapdata_vg_p.h
+++ b/src/openvg/qpixmapdata_vg_p.h
@@ -138,6 +138,7 @@ public:
QSize size() const { return QSize(w, h); }
#if defined(Q_OS_SYMBIAN)
+ QVolatileImage toVolatileImage() const { return source; }
void* toNativeType(NativeType type);
void fromNativeType(void* pixmap, NativeType type);
bool initFromNativeImageHandle(void *handle, const QString &type);