summaryrefslogtreecommitdiffstats
path: root/src/opengl/qgl.cpp
diff options
context:
space:
mode:
authorTrond Kjernåsen <trond.kjernasen@nokia.com>2010-06-22 11:02:54 (GMT)
committerTrond Kjernåsen <trond.kjernasen@nokia.com>2010-07-02 10:25:02 (GMT)
commit80a2ebd93346f885d904e4e1020e112cc635dbaf (patch)
treed84a7d29f51a140a047bacff7139ffa340c2cd8d /src/opengl/qgl.cpp
parent4c3ac765b26e56fbf08c9f70cf43aa00a6565cae (diff)
downloadQt-80a2ebd93346f885d904e4e1020e112cc635dbaf.zip
Qt-80a2ebd93346f885d904e4e1020e112cc635dbaf.tar.gz
Qt-80a2ebd93346f885d904e4e1020e112cc635dbaf.tar.bz2
Redesigned how GL resource management works.
The usage of QGLContextResource has changed: You're now have to subclass QGLContextResource and reimplement the freeResource() function and add your cleanup code there instead of using a plain callback function. It's now also possible to delete a QGLContextResource *before* the QGLContextGroup it refers to is destroyed, as the resource will remove itself from the context groups it's a member of. The QGLTextureGlyphCache is no longer a QObject, and it no longer depends on the aboutToDestroyContext() signal. That concept doesn't work in a threaded environment, as it relies on an eventloop to dispatch the signal to the thread. It's common to *not* have an eventloop running in a thread, which means the signal might never be delivered. QGLTextureGlyphCache now inherits from QGLContextResource, and gets cleaned up correctly when the group context is destroyed. Note that up until now the glyph cache has never been shared among sharing contexts for the GL 2 engine. Made the gradient and pixmap blur caches use the new QGLContextResource scheme. Added a template that wraps the common init code for paintEngine() function implementations for QGLWidget, QGLPixelBuffer and QGLFramebufferObject. Fixed a bug in QFontCache where the font caches weren't cleared when a thread other than the main thread exited (backported to 4.6.3), which caused resource leaks.
Diffstat (limited to 'src/opengl/qgl.cpp')
-rw-r--r--src/opengl/qgl.cpp61
1 files changed, 16 insertions, 45 deletions
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 1223552..753a984 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2028,6 +2028,7 @@ QGLContext::~QGLContext()
// remove any textures cached in this context
QGLTextureCache::instance()->removeContextTextures(this);
+ qDebug() << "~QGLContext(): about to clean up" << hex << this;
d_ptr->group->cleanupResources(this);
QGLSignalProxy::instance()->emitAboutToDestroyContext(this);
@@ -2533,7 +2534,6 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target,
}
#endif
- printf(" -> bindTexture key: %llx\n", key);
if (!texture) {
QImage image = pixmap.toImage();
// If the system depth is 16 and the pixmap doesn't have an alpha channel
@@ -5029,41 +5029,12 @@ void QGLWidget::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QM
}
#endif
-#if !defined(QT_OPENGL_ES_1)
-class QtGL2EngineStorage
-{
-public:
- QPaintEngine *engine() {
- QPaintEngine *localEngine = storage.localData();
- if (!localEngine) {
- localEngine = new QGL2PaintEngineEx;
- storage.setLocalData(localEngine);
- }
- return localEngine;
- }
-
-private:
- QThreadStorage<QPaintEngine *> storage;
-};
-Q_GLOBAL_STATIC(QtGL2EngineStorage, qt_gl_2_engine)
+#ifndef QT_OPENGL_ES_1
+Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_gl_2_engine)
#endif
#ifndef QT_OPENGL_ES_2
-class QtGL1EngineStorage
-{
-public:
- QPaintEngine *engine() {
- QPaintEngine *localEngine = storage.localData();
- if (!localEngine) {
- localEngine = new QOpenGLPaintEngine;
- storage.setLocalData(localEngine);
- }
- return localEngine;
- }
-private:
- QThreadStorage<QPaintEngine *> storage;
-};
-Q_GLOBAL_STATIC(QtGL1EngineStorage, qt_gl_engine)
+Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_gl_engine)
#endif
Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine()
@@ -5339,13 +5310,17 @@ void QGLContextGroup::removeShare(const QGLContext *context) {
group->m_shares.clear();
}
-QGLContextResource::QGLContextResource(FreeFunc f)
- : free(f), active(0)
+QGLContextResource::QGLContextResource()
+ : active(0)
{
}
QGLContextResource::~QGLContextResource()
{
+ for (int i = 0; i < m_groups.size(); ++i) {
+ m_groups.at(i)->m_resources.remove(this);
+ active.deref();
+ }
#ifndef QT_NO_DEBUG
if (active != 0) {
qWarning("QtOpenGL: Resources are still available at program shutdown.\n"
@@ -5360,6 +5335,7 @@ void QGLContextResource::insert(const QGLContext *key, void *value)
QGLContextGroup *group = QGLContextPrivate::contextGroup(key);
Q_ASSERT(!group->m_resources.contains(this));
group->m_resources.insert(this, value);
+ m_groups.append(group);
active.ref();
}
@@ -5371,23 +5347,18 @@ void *QGLContextResource::value(const QGLContext *key)
void QGLContextResource::cleanup(const QGLContext *ctx, void *value)
{
- qDebug() << "QGLContextResource::cleanup() this:" << hex << this << "thread:" << QThread::currentThread();
+ qDebug() << "QGLContextResource::cleanup() this:" << hex << this << "ctx:" << ctx << "thread:" << (void *)QThread::currentThread();
QGLShareContextScope scope(ctx);
- free(value);
+ freeResource(value);
active.deref();
-}
-void QGLContextResource::remove(const QGLContext *ctx)
-{
- if (ctx) {
- QGLContextGroup *group = QGLContextPrivate::contextGroup(ctx);
- group->m_resources.remove(this);
- active.deref();
- }
+ QGLContextGroup *group = QGLContextPrivate::contextGroup(ctx);
+ m_groups.removeOne(group);
}
void QGLContextGroup::cleanupResources(const QGLContext *ctx)
{
+ qDebug() << "QGLContextGroup::cleanupResources() for ctx:" << hex << ctx << "shares:" << m_shares.size() << "res:" << m_resources.size();
// If there are still shares, then no cleanup to be done yet.
if (m_shares.size() > 1)
return;