diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2012-03-07 22:00:57 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@nokia.com> | 2012-03-07 22:01:11 +0100 |
commit | 616bbd1988f3b92f7d980b6c9a1278f11b712573 (patch) | |
tree | c6f9489bc1b53649130be21de858870f574db906 /src/quick/scenegraph | |
parent | 3bc907d155034fe64efc8cb6056b48f0c6401bfb (diff) | |
parent | 70966df1be02dd94ecf9a122ff9e4976245aeb92 (diff) |
Merge remote-tracking branch 'origin/master' into api_changes
Change-Id: I121cb9c9316b5e47476dcb982bc28b6f3f358f78
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r-- | src/quick/scenegraph/qsgadaptationlayer.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext.cpp | 27 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext_p.h | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontextplugin.cpp | 18 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontextplugin_p.h | 4 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp | 35 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h | 1 |
7 files changed, 71 insertions, 18 deletions
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index 92045c55f4..9608ebe861 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -243,6 +243,8 @@ void QSGDistanceFieldGlyphCache::setGlyphsPosition(const QList<GlyphPosition> &g for (int i = 0; i < count; ++i) { GlyphPosition glyph = glyphs.at(i); + Q_ASSERT(m_cacheData->glyphPaths.contains(glyph.glyph)); + QPainterPath path = m_cacheData->glyphPaths.value(glyph.glyph); QRectF br = path.boundingRect(); TexCoord c; diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index ffc64b6edc..02fbaa1a7f 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -109,6 +109,7 @@ public: QOpenGLContext *gl; QHash<QSGMaterialType *, QSGMaterialShader *> materials; + QMutex textureMutex; QHash<QQuickTextureFactory *, QSGTexture *> textures; QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager; @@ -118,6 +119,13 @@ public: bool distanceFieldDisabled; }; +class QSGTextureCleanupEvent : public QEvent +{ +public: + QSGTextureCleanupEvent(QSGTexture *t) : QEvent(QEvent::User), texture(t) { } + ~QSGTextureCleanupEvent() { delete texture; } + QSGTexture *texture; +}; /*! \class QSGContext @@ -146,8 +154,10 @@ QSGContext::~QSGContext() void QSGContext::invalidate() { Q_D(QSGContext); + d->textureMutex.lock(); qDeleteAll(d->textures.values()); d->textures.clear(); + d->textureMutex.unlock(); qDeleteAll(d->materials.values()); d->materials.clear(); delete d->distanceFieldCacheManager; @@ -165,6 +175,7 @@ QSGTexture *QSGContext::textureForFactory(QQuickTextureFactory *factory, QQuickC if (!factory) return 0; + d->textureMutex.lock(); QSGTexture *texture = d->textures.value(factory); if (!texture) { if (QQuickDefaultTextureFactory *dtf = qobject_cast<QQuickDefaultTextureFactory *>(factory)) @@ -172,8 +183,9 @@ QSGTexture *QSGContext::textureForFactory(QQuickTextureFactory *factory, QQuickC else texture = factory->createTexture(canvas); d->textures.insert(factory, texture); - connect(factory, SIGNAL(destroyed(QObject *)), this, SLOT(textureFactoryDestroyed(QObject *))); + connect(factory, SIGNAL(destroyed(QObject *)), this, SLOT(textureFactoryDestroyed(QObject *)), Qt::DirectConnection); } + d->textureMutex.unlock(); return texture; } @@ -183,9 +195,16 @@ void QSGContext::textureFactoryDestroyed(QObject *o) Q_D(QSGContext); QQuickTextureFactory *f = static_cast<QQuickTextureFactory *>(o); - // This function will only be called on the scene graph thread, so it is - // safe to directly delete the texture here. - delete d->textures.take(f); + d->textureMutex.lock(); + QSGTexture *t = d->textures.take(f); + d->textureMutex.unlock(); + + if (t) { + if (t->thread() == thread()) + t->deleteLater(); + else + QCoreApplication::postEvent(this, new QSGTextureCleanupEvent(t)); + } } diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index 0f8b5ae1de..dfb960f420 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -68,6 +68,7 @@ class QSGTexture; class QSGMaterial; class QSGMaterialShader; class QSGEngine; +class QQuickWindowManager; class QOpenGLContext; class QOpenGLFramebufferObject; @@ -122,6 +123,7 @@ public: virtual QAnimationDriver *createAnimationDriver(QObject *parent); static QQuickTextureFactory *createTextureFactoryFromImage(const QImage &image); + static QQuickWindowManager *createWindowManager(); public slots: diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp index b8a66fd0c0..bd1c4cece8 100644 --- a/src/quick/scenegraph/qsgcontextplugin.cpp +++ b/src/quick/scenegraph/qsgcontextplugin.cpp @@ -152,5 +152,23 @@ QQuickTextureFactory *QSGContext::createTextureFactoryFromImage(const QImage &im } +/*! + \fn QQuickWindowManager *createWindowManager() + + Calls into the scene graph adaptation if available and creates a hardware + specific window manager. + */ + +QQuickWindowManager *QSGContext::createWindowManager() +{ + QSGAdaptionPluginData *plugin = contextFactory(); + if (plugin->factory) + return plugin->factory->createWindowManager(); + return 0; +} + + + + QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgcontextplugin_p.h b/src/quick/scenegraph/qsgcontextplugin_p.h index acff222fb0..2c4531c239 100644 --- a/src/quick/scenegraph/qsgcontextplugin_p.h +++ b/src/quick/scenegraph/qsgcontextplugin_p.h @@ -53,11 +53,14 @@ QT_BEGIN_NAMESPACE class QSGContext; +class QQuickWindowManager; + struct Q_QUICK_EXPORT QSGContextFactoryInterface : public QFactoryInterface { virtual QSGContext *create(const QString &key) const = 0; virtual QQuickTextureFactory *createTextureFactoryFromImage(const QImage &image) = 0; + virtual QQuickWindowManager *createWindowManager() = 0; }; #define QSGContextFactoryInterface_iid \ @@ -76,6 +79,7 @@ public: virtual QSGContext *create(const QString &key) const = 0; virtual QQuickTextureFactory *createTextureFactoryFromImage(const QImage &) { return 0; } + virtual QQuickWindowManager *createWindowManager() { return 0; } }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp index 46bd141909..76fb9036f4 100644 --- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp @@ -126,6 +126,7 @@ void QSGSharedDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs #endif m_requestedGlyphsThatHaveNotBeenReturned.unite(glyphs); + m_requestedGlyphs.unite(glyphs); QVector<quint32> glyphsVector; glyphsVector.reserve(glyphs.size()); @@ -198,6 +199,8 @@ void QSGSharedDistanceFieldGlyphCache::releaseGlyphs(const QSet<glyph_t> &glyphs m_cacheId.constData(), glyphs.size()); #endif + m_requestedGlyphs.subtract(glyphs); + QVector<quint32> glyphsVector; glyphsVector.reserve(glyphs.size()); @@ -588,19 +591,21 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsUpdated(const QByteArray &cach #endif for (int i=0; i<itemIds.size(); ++i) { - PendingGlyph &pendingGlyph = m_pendingReadyGlyphs[itemIds.at(i)]; - void *oldBuffer = pendingGlyph.buffer; - Q_ASSERT(bufferSize.height() >= pendingGlyph.bufferSize.height()); + if (m_requestedGlyphs.contains(itemIds.at(i))) { + PendingGlyph &pendingGlyph = m_pendingReadyGlyphs[itemIds.at(i)]; + void *oldBuffer = pendingGlyph.buffer; + Q_ASSERT(bufferSize.height() >= pendingGlyph.bufferSize.height()); - pendingGlyph.buffer = bufferId; - pendingGlyph.position = positions.at(i); - pendingGlyph.bufferSize = bufferSize; + pendingGlyph.buffer = bufferId; + pendingGlyph.position = positions.at(i); + pendingGlyph.bufferSize = bufferSize; - m_sharedGraphicsCache->referenceBuffer(bufferId); - if (oldBuffer != 0) - m_sharedGraphicsCache->dereferenceBuffer(oldBuffer); + m_sharedGraphicsCache->referenceBuffer(bufferId); + if (oldBuffer != 0) + m_sharedGraphicsCache->dereferenceBuffer(oldBuffer); - m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i)); + m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i)); + } } } @@ -616,8 +621,10 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsInvalidated(const QByteArray & if (m_cacheId != cacheId) return; - for (int i=0; i<itemIds.size(); ++i) - m_pendingInvalidatedGlyphs.insert(itemIds.at(i)); + for (int i=0; i<itemIds.size(); ++i) { + if (m_requestedGlyphs.contains(itemIds.at(i))) + m_pendingInvalidatedGlyphs.insert(itemIds.at(i)); + } } emit glyphsPending(); @@ -638,8 +645,8 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsMissing(const QByteArray &cach #endif for (int i=0; i<itemIds.size(); ++i) { - m_pendingMissingGlyphs.insert(itemIds.at(i)); - m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i)); + if (m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i))) + m_pendingMissingGlyphs.insert(itemIds.at(i)); } } diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h index 3052f20813..4a91b4473a 100644 --- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h +++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h @@ -87,6 +87,7 @@ private: void saveTexture(GLuint textureId, int width, int height); QSet<quint32> m_requestedGlyphsThatHaveNotBeenReturned; + QSet<quint32> m_requestedGlyphs; QWaitCondition m_pendingGlyphsCondition; QByteArray m_cacheId; QPlatformSharedGraphicsCache *m_sharedGraphicsCache; |