diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2012-05-24 15:51:27 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-05-30 09:45:35 +0200 |
commit | 0b3f46014764d6e35da321bbba2d0232ec99d1b1 (patch) | |
tree | 9d95514139075fa069acb69b451afd320838ff4f /src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp | |
parent | f7e3a33cb80f3cc289aea9e59f53111d730b5927 (diff) |
Uses new batching API to potentially speed up glyph cache
Give the cache information that a burst of requests/releases
are coming, so it can potentially optimize this.
Change-Id: Icfb591a63075c2f1e93bf269402649116de9e5be
Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
Diffstat (limited to 'src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp')
-rw-r--r-- | src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp | 93 |
1 files changed, 82 insertions, 11 deletions
diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp index 2dd872996a..e6bd529d52 100644 --- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp @@ -66,19 +66,25 @@ namespace { { public: QSGInvokeEvent(QPlatformSharedGraphicsCache *cache, - const QByteArray &cacheId, - const QVector<quint32> &glyphIds) + const QByteArray &cacheId = QByteArray(), + const QVector<quint32> &glyphIds = QVector<quint32>(), + bool inSceneGraphUpdate = false) : QEvent(User) , m_cache(cache) , m_cacheId(cacheId) , m_glyphIds(glyphIds) + , m_inSceneGraphUpdate(inSceneGraphUpdate) {} + bool inSceneGraphUpdate() const { return m_inSceneGraphUpdate; } + QPlatformSharedGraphicsCache *cache() const { return m_cache; } + virtual void invoke() = 0; protected: QPlatformSharedGraphicsCache *m_cache; QByteArray m_cacheId; QVector<quint32> m_glyphIds; + bool m_inSceneGraphUpdate; }; class QSGReleaseItemsEvent: public QSGInvokeEvent @@ -86,8 +92,9 @@ namespace { public: QSGReleaseItemsEvent(QPlatformSharedGraphicsCache *cache, const QByteArray &cacheId, - const QVector<quint32> &glyphIds) - : QSGInvokeEvent(cache, cacheId, glyphIds) + const QVector<quint32> &glyphIds, + bool inSceneGraphUpdate) + : QSGInvokeEvent(cache, cacheId, glyphIds, inSceneGraphUpdate) { } @@ -102,8 +109,9 @@ namespace { public: QSGRequestItemsEvent(QPlatformSharedGraphicsCache *cache, const QByteArray &cacheId, - const QVector<quint32> &glyphIds) - : QSGInvokeEvent(cache, cacheId, glyphIds) + const QVector<quint32> &glyphIds, + bool inSceneGraphUpdate) + : QSGInvokeEvent(cache, cacheId, glyphIds, inSceneGraphUpdate) { } @@ -119,8 +127,9 @@ namespace { QSGInsertItemsEvent(QPlatformSharedGraphicsCache *cache, const QByteArray &cacheId, const QVector<quint32> &glyphIds, - const QVector<QImage> &images) - : QSGInvokeEvent(cache, cacheId, glyphIds) + const QVector<QImage> &images, + bool inSceneGraphUpdate) + : QSGInvokeEvent(cache, cacheId, glyphIds, inSceneGraphUpdate) , m_images(images) { } @@ -134,6 +143,21 @@ namespace { QVector<QImage> m_images; }; + class QSGEndRequestBatchEvent: public QSGInvokeEvent + { + public: + QSGEndRequestBatchEvent(QPlatformSharedGraphicsCache *cache) + : QSGInvokeEvent(cache) + { + } + + void invoke() + { + if (m_cache->requestBatchStarted()) + m_cache->endRequestBatch(); + } + }; + class QSGMainThreadInvoker: public QObject { public: @@ -141,6 +165,14 @@ namespace { { if (e->type() == QEvent::User) { Q_ASSERT(QThread::currentThread() == QCoreApplication::instance()->thread()); + + QSGInvokeEvent *invokeEvent = static_cast<QSGInvokeEvent *>(e); + if (invokeEvent->inSceneGraphUpdate()) { + QPlatformSharedGraphicsCache *cache = invokeEvent->cache(); + if (!cache->requestBatchStarted()) + cache->beginRequestBatch(); + } + static_cast<QSGInvokeEvent *>(e)->invoke(); return true; } @@ -172,6 +204,8 @@ QSGSharedDistanceFieldGlyphCache::QSGSharedDistanceFieldGlyphCache(const QByteAr : QSGDistanceFieldGlyphCache(man, c, font) , m_cacheId(cacheId) , m_sharedGraphicsCache(sharedGraphicsCache) + , m_isInSceneGraphUpdate(false) + , m_hasPostedEvents(false) { #if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG) qDebug("QSGSharedDistanceFieldGlyphCache with id %s created in thread %p", @@ -193,6 +227,14 @@ QSGSharedDistanceFieldGlyphCache::QSGSharedDistanceFieldGlyphCache(const QByteAr connect(sharedGraphicsCache, SIGNAL(itemsInvalidated(QByteArray,QVector<quint32>)), this, SLOT(reportItemsInvalidated(QByteArray,QVector<quint32>)), Qt::DirectConnection); + + QQuickCanvas *canvas = static_cast<QQuickCanvas *>(c->surface()); + Q_ASSERT(canvas != 0); + + connect(canvas, SIGNAL(beforeSynchronizing()), this, SLOT(sceneGraphUpdateStarted()), + Qt::DirectConnection); + connect(canvas, SIGNAL(beforeRendering()), this, SLOT(sceneGraphUpdateDone()), + Qt::DirectConnection); } QSGSharedDistanceFieldGlyphCache::~QSGSharedDistanceFieldGlyphCache() @@ -235,14 +277,22 @@ void QSGSharedDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs glyphsVector.append(*it); } + m_hasPostedEvents = true; QSGMainThreadInvoker *invoker = QSGMainThreadInvoker::instance(); QCoreApplication::postEvent(invoker, new QSGRequestItemsEvent(m_sharedGraphicsCache, m_cacheId, - glyphsVector)); + glyphsVector, + m_isInSceneGraphUpdate)); } void QSGSharedDistanceFieldGlyphCache::waitForGlyphs() { + Q_ASSERT(!m_isInSceneGraphUpdate); + if (m_isInSceneGraphUpdate) { + qWarning("QSGSharedDistanceFieldGlyphCache::waitForGlyphs: Called from inside " + "scenegraph update. Will freeze."); + } + { QMutexLocker locker(&m_pendingGlyphsMutex); while (!m_requestedGlyphsThatHaveNotBeenReturned.isEmpty()) @@ -272,11 +322,13 @@ void QSGSharedDistanceFieldGlyphCache::storeGlyphs(const QHash<glyph_t, QImage> ++it; ++i; } + m_hasPostedEvents = true; QSGMainThreadInvoker *invoker = QSGMainThreadInvoker::instance(); QCoreApplication::postEvent(invoker, new QSGInsertItemsEvent(m_sharedGraphicsCache, m_cacheId, glyphIds, - images)); + images, + m_isInSceneGraphUpdate)); } processPendingGlyphs(); @@ -325,10 +377,12 @@ void QSGSharedDistanceFieldGlyphCache::releaseGlyphs(const QSet<glyph_t> &glyphs glyphsVector.append(*glyphsIt); } + m_hasPostedEvents = true; QSGMainThreadInvoker *mainThreadInvoker = QSGMainThreadInvoker::instance(); QCoreApplication::postEvent(mainThreadInvoker, new QSGReleaseItemsEvent(m_sharedGraphicsCache, m_cacheId, - glyphsVector)); + glyphsVector, + m_isInSceneGraphUpdate)); } void QSGSharedDistanceFieldGlyphCache::registerOwnerElement(QQuickItem *ownerElement) @@ -761,4 +815,21 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsMissing(const QByteArray &cach emit glyphsPending(); } +void QSGSharedDistanceFieldGlyphCache::sceneGraphUpdateStarted() +{ + m_isInSceneGraphUpdate = true; + m_hasPostedEvents = false; +} + +void QSGSharedDistanceFieldGlyphCache::sceneGraphUpdateDone() +{ + m_isInSceneGraphUpdate = false; + + if (m_hasPostedEvents) { + QSGMainThreadInvoker *invoker = QSGMainThreadInvoker::instance(); + QCoreApplication::postEvent(invoker, new QSGEndRequestBatchEvent(m_sharedGraphicsCache)); + m_hasPostedEvents = false; + } +} + QT_END_NAMESPACE |