diff options
author | Trond Kjernåsen <trond.kjernasen@nokia.com> | 2010-06-22 11:02:54 (GMT) |
---|---|---|
committer | Trond Kjernåsen <trond.kjernasen@nokia.com> | 2010-07-02 10:25:02 (GMT) |
commit | 80a2ebd93346f885d904e4e1020e112cc635dbaf (patch) | |
tree | d84a7d29f51a140a047bacff7139ffa340c2cd8d /src/opengl/qgl.cpp | |
parent | 4c3ac765b26e56fbf08c9f70cf43aa00a6565cae (diff) | |
download | Qt-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.cpp | 61 |
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; |