Commit 0b3f4601 authored by Eskil Abrahamsen Blomfeldt's avatar Eskil Abrahamsen Blomfeldt Committed by Qt by Nokia
Browse files

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: default avatarJiang Jiang <jiang.jiang@nokia.com>
parent f7e3a33c
dev 5.10 5.11 5.12 5.12.1 5.12.10 5.12.11 5.12.12 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13 5.13.0 5.13.1 5.13.2 5.14 5.14.0 5.14.1 5.14.2 5.15 5.15.0 5.15.1 5.15.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.9.8 6.0 6.0.0 6.1 6.1.0 6.1.1 6.1.2 6.1.3 6.2 6.2.0 6.2.1 6.2.2 old/5.0 old/5.1 old/5.2 wip/cmake wip/dbus wip/gc wip/itemviews wip/nacl wip/new-backend wip/pointerhandler wip/propertycache-refactor wip/qquickdeliveryagent wip/scenegraphng wip/tizen wip/webassembly v5.15.0-alpha1 v5.14.1 v5.14.0 v5.14.0-rc2 v5.14.0-rc1 v5.14.0-beta3 v5.14.0-beta2 v5.14.0-beta1 v5.14.0-alpha1 v5.13.2 v5.13.1 v5.13.0 v5.13.0-rc3 v5.13.0-rc2 v5.13.0-rc1 v5.13.0-beta4 v5.13.0-beta3 v5.13.0-beta2 v5.13.0-beta1 v5.13.0-alpha1 v5.12.7 v5.12.6 v5.12.5 v5.12.4 v5.12.3 v5.12.2 v5.12.1 v5.12.0 v5.12.0-rc2 v5.12.0-rc1 v5.12.0-beta4 v5.12.0-beta3 v5.12.0-beta2 v5.12.0-beta1 v5.12.0-alpha1 v5.11.3 v5.11.2 v5.11.1 v5.11.0 v5.11.0-rc2 v5.11.0-rc1 v5.11.0-beta4 v5.11.0-beta3 v5.11.0-beta2 v5.11.0-beta1 v5.11.0-alpha1 v5.10.1 v5.10.0 v5.10.0-rc3 v5.10.0-rc2 v5.10.0-rc1 v5.10.0-beta4 v5.10.0-beta3 v5.10.0-beta2 v5.10.0-beta1 v5.10.0-alpha1 v5.9.9 v5.9.8 v5.9.7 v5.9.6 v5.9.5 v5.9.4 v5.9.3 v5.9.2 v5.9.1 v5.9.0 v5.9.0-rc2 v5.9.0-rc1 v5.9.0-beta4 v5.9.0-beta3 v5.9.0-beta2 v5.9.0-beta1 v5.9.0-alpha1 v5.8.0 v5.8.0-rc1 v5.8.0-beta1 v5.8.0-alpha1 v5.7.1 v5.7.0 v5.7.0-rc1 v5.7.0-beta1 v5.7.0-alpha1 v5.6.3 v5.6.2 v5.6.1 v5.6.1-1 v5.6.0 v5.6.0-rc1 v5.6.0-beta1 v5.6.0-alpha1 v5.5.1 v5.5.0 v5.5.0-rc1 v5.5.0-beta1 v5.5.0-alpha1 v5.4.2 v5.4.1 v5.4.0 v5.4.0-rc1 v5.4.0-beta1 v5.4.0-alpha1 v5.3.2 v5.3.1 v5.3.0 v5.3.0-rc1 v5.3.0-beta1 v5.3.0-alpha1 v5.2.1 v5.2.0 v5.2.0-rc1 v5.2.0-beta1 v5.2.0-alpha1 v5.1.1 v5.1.0 v5.1.0-rc2 v5.1.0-rc1 v5.1.0-beta1 v5.1.0-alpha1 v5.0.2 v5.0.1 v5.0.0 v5.0.0-rc2 v5.0.0-rc1 v5.0.0-beta2 v5.0.0-beta1
No related merge requests found
Showing with 97 additions and 11 deletions
...@@ -282,6 +282,9 @@ void forceUpdate(QQuickItem *item) ...@@ -282,6 +282,9 @@ void forceUpdate(QQuickItem *item)
void QQuickCanvasPrivate::syncSceneGraph() void QQuickCanvasPrivate::syncSceneGraph()
{ {
QML_MEMORY_SCOPE_STRING("SceneGraph"); QML_MEMORY_SCOPE_STRING("SceneGraph");
Q_Q(QQuickCanvas);
emit q->beforeSynchronizing();
if (!renderer) { if (!renderer) {
forceUpdate(rootItem); forceUpdate(rootItem);
...@@ -787,6 +790,11 @@ void QQuickCanvasPrivate::cleanup(QSGNode *n) ...@@ -787,6 +790,11 @@ void QQuickCanvasPrivate::cleanup(QSGNode *n)
\list \list
\li The QQuickCanvas::beforeSynchronizing() signal is emitted.
Applications can make direct connections (Qt::DirectConnection)
to this signal to do any preparation required before calls to
QQuickItem::updatePaintNode().
\li Synchronzation of the QML state into the scene graph. This is \li Synchronzation of the QML state into the scene graph. This is
done by calling the QQuickItem::updatePaintNode() function on all done by calling the QQuickItem::updatePaintNode() function on all
items that have changed since the previous frame. When a dedicated items that have changed since the previous frame. When a dedicated
......
...@@ -125,6 +125,7 @@ Q_SIGNALS: ...@@ -125,6 +125,7 @@ Q_SIGNALS:
void frameSwapped(); void frameSwapped();
void sceneGraphInitialized(); void sceneGraphInitialized();
void sceneGraphInvalidated(); void sceneGraphInvalidated();
void beforeSynchronizing();
void beforeRendering(); void beforeRendering();
void afterRendering(); void afterRendering();
void clearColorChanged(const QColor &); void clearColorChanged(const QColor &);
......
...@@ -66,19 +66,25 @@ namespace { ...@@ -66,19 +66,25 @@ namespace {
{ {
public: public:
QSGInvokeEvent(QPlatformSharedGraphicsCache *cache, QSGInvokeEvent(QPlatformSharedGraphicsCache *cache,
const QByteArray &cacheId, const QByteArray &cacheId = QByteArray(),
const QVector<quint32> &glyphIds) const QVector<quint32> &glyphIds = QVector<quint32>(),
bool inSceneGraphUpdate = false)
: QEvent(User) : QEvent(User)
, m_cache(cache) , m_cache(cache)
, m_cacheId(cacheId) , m_cacheId(cacheId)
, m_glyphIds(glyphIds) , m_glyphIds(glyphIds)
, m_inSceneGraphUpdate(inSceneGraphUpdate)
{} {}
bool inSceneGraphUpdate() const { return m_inSceneGraphUpdate; }
QPlatformSharedGraphicsCache *cache() const { return m_cache; }
virtual void invoke() = 0; virtual void invoke() = 0;
protected: protected:
QPlatformSharedGraphicsCache *m_cache; QPlatformSharedGraphicsCache *m_cache;
QByteArray m_cacheId; QByteArray m_cacheId;
QVector<quint32> m_glyphIds; QVector<quint32> m_glyphIds;
bool m_inSceneGraphUpdate;
}; };
class QSGReleaseItemsEvent: public QSGInvokeEvent class QSGReleaseItemsEvent: public QSGInvokeEvent
...@@ -86,8 +92,9 @@ namespace { ...@@ -86,8 +92,9 @@ namespace {
public: public:
QSGReleaseItemsEvent(QPlatformSharedGraphicsCache *cache, QSGReleaseItemsEvent(QPlatformSharedGraphicsCache *cache,
const QByteArray &cacheId, const QByteArray &cacheId,
const QVector<quint32> &glyphIds) const QVector<quint32> &glyphIds,
: QSGInvokeEvent(cache, cacheId, glyphIds) bool inSceneGraphUpdate)
: QSGInvokeEvent(cache, cacheId, glyphIds, inSceneGraphUpdate)
{ {
} }
...@@ -102,8 +109,9 @@ namespace { ...@@ -102,8 +109,9 @@ namespace {
public: public:
QSGRequestItemsEvent(QPlatformSharedGraphicsCache *cache, QSGRequestItemsEvent(QPlatformSharedGraphicsCache *cache,
const QByteArray &cacheId, const QByteArray &cacheId,
const QVector<quint32> &glyphIds) const QVector<quint32> &glyphIds,
: QSGInvokeEvent(cache, cacheId, glyphIds) bool inSceneGraphUpdate)
: QSGInvokeEvent(cache, cacheId, glyphIds, inSceneGraphUpdate)
{ {
} }
...@@ -119,8 +127,9 @@ namespace { ...@@ -119,8 +127,9 @@ namespace {
QSGInsertItemsEvent(QPlatformSharedGraphicsCache *cache, QSGInsertItemsEvent(QPlatformSharedGraphicsCache *cache,
const QByteArray &cacheId, const QByteArray &cacheId,
const QVector<quint32> &glyphIds, const QVector<quint32> &glyphIds,
const QVector<QImage> &images) const QVector<QImage> &images,
: QSGInvokeEvent(cache, cacheId, glyphIds) bool inSceneGraphUpdate)
: QSGInvokeEvent(cache, cacheId, glyphIds, inSceneGraphUpdate)
, m_images(images) , m_images(images)
{ {
} }
...@@ -134,6 +143,21 @@ namespace { ...@@ -134,6 +143,21 @@ namespace {
QVector<QImage> m_images; 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 class QSGMainThreadInvoker: public QObject
{ {
public: public:
...@@ -141,6 +165,14 @@ namespace { ...@@ -141,6 +165,14 @@ namespace {
{ {
if (e->type() == QEvent::User) { if (e->type() == QEvent::User) {
Q_ASSERT(QThread::currentThread() == QCoreApplication::instance()->thread()); 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(); static_cast<QSGInvokeEvent *>(e)->invoke();
return true; return true;
} }
...@@ -172,6 +204,8 @@ QSGSharedDistanceFieldGlyphCache::QSGSharedDistanceFieldGlyphCache(const QByteAr ...@@ -172,6 +204,8 @@ QSGSharedDistanceFieldGlyphCache::QSGSharedDistanceFieldGlyphCache(const QByteAr
: QSGDistanceFieldGlyphCache(man, c, font) : QSGDistanceFieldGlyphCache(man, c, font)
, m_cacheId(cacheId) , m_cacheId(cacheId)
, m_sharedGraphicsCache(sharedGraphicsCache) , m_sharedGraphicsCache(sharedGraphicsCache)
, m_isInSceneGraphUpdate(false)
, m_hasPostedEvents(false)
{ {
#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG) #if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG)
qDebug("QSGSharedDistanceFieldGlyphCache with id %s created in thread %p", qDebug("QSGSharedDistanceFieldGlyphCache with id %s created in thread %p",
...@@ -193,6 +227,14 @@ QSGSharedDistanceFieldGlyphCache::QSGSharedDistanceFieldGlyphCache(const QByteAr ...@@ -193,6 +227,14 @@ QSGSharedDistanceFieldGlyphCache::QSGSharedDistanceFieldGlyphCache(const QByteAr
connect(sharedGraphicsCache, SIGNAL(itemsInvalidated(QByteArray,QVector<quint32>)), connect(sharedGraphicsCache, SIGNAL(itemsInvalidated(QByteArray,QVector<quint32>)),
this, SLOT(reportItemsInvalidated(QByteArray,QVector<quint32>)), this, SLOT(reportItemsInvalidated(QByteArray,QVector<quint32>)),
Qt::DirectConnection); 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() QSGSharedDistanceFieldGlyphCache::~QSGSharedDistanceFieldGlyphCache()
...@@ -235,14 +277,22 @@ void QSGSharedDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs ...@@ -235,14 +277,22 @@ void QSGSharedDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs
glyphsVector.append(*it); glyphsVector.append(*it);
} }
m_hasPostedEvents = true;
QSGMainThreadInvoker *invoker = QSGMainThreadInvoker::instance(); QSGMainThreadInvoker *invoker = QSGMainThreadInvoker::instance();
QCoreApplication::postEvent(invoker, new QSGRequestItemsEvent(m_sharedGraphicsCache, QCoreApplication::postEvent(invoker, new QSGRequestItemsEvent(m_sharedGraphicsCache,
m_cacheId, m_cacheId,
glyphsVector)); glyphsVector,
m_isInSceneGraphUpdate));
} }
void QSGSharedDistanceFieldGlyphCache::waitForGlyphs() void QSGSharedDistanceFieldGlyphCache::waitForGlyphs()
{ {
Q_ASSERT(!m_isInSceneGraphUpdate);
if (m_isInSceneGraphUpdate) {
qWarning("QSGSharedDistanceFieldGlyphCache::waitForGlyphs: Called from inside "
"scenegraph update. Will freeze.");
}
{ {
QMutexLocker locker(&m_pendingGlyphsMutex); QMutexLocker locker(&m_pendingGlyphsMutex);
while (!m_requestedGlyphsThatHaveNotBeenReturned.isEmpty()) while (!m_requestedGlyphsThatHaveNotBeenReturned.isEmpty())
...@@ -272,11 +322,13 @@ void QSGSharedDistanceFieldGlyphCache::storeGlyphs(const QHash<glyph_t, QImage> ...@@ -272,11 +322,13 @@ void QSGSharedDistanceFieldGlyphCache::storeGlyphs(const QHash<glyph_t, QImage>
++it; ++i; ++it; ++i;
} }
m_hasPostedEvents = true;
QSGMainThreadInvoker *invoker = QSGMainThreadInvoker::instance(); QSGMainThreadInvoker *invoker = QSGMainThreadInvoker::instance();
QCoreApplication::postEvent(invoker, new QSGInsertItemsEvent(m_sharedGraphicsCache, QCoreApplication::postEvent(invoker, new QSGInsertItemsEvent(m_sharedGraphicsCache,
m_cacheId, m_cacheId,
glyphIds, glyphIds,
images)); images,
m_isInSceneGraphUpdate));
} }
processPendingGlyphs(); processPendingGlyphs();
...@@ -325,10 +377,12 @@ void QSGSharedDistanceFieldGlyphCache::releaseGlyphs(const QSet<glyph_t> &glyphs ...@@ -325,10 +377,12 @@ void QSGSharedDistanceFieldGlyphCache::releaseGlyphs(const QSet<glyph_t> &glyphs
glyphsVector.append(*glyphsIt); glyphsVector.append(*glyphsIt);
} }
m_hasPostedEvents = true;
QSGMainThreadInvoker *mainThreadInvoker = QSGMainThreadInvoker::instance(); QSGMainThreadInvoker *mainThreadInvoker = QSGMainThreadInvoker::instance();
QCoreApplication::postEvent(mainThreadInvoker, new QSGReleaseItemsEvent(m_sharedGraphicsCache, QCoreApplication::postEvent(mainThreadInvoker, new QSGReleaseItemsEvent(m_sharedGraphicsCache,
m_cacheId, m_cacheId,
glyphsVector)); glyphsVector,
m_isInSceneGraphUpdate));
} }
void QSGSharedDistanceFieldGlyphCache::registerOwnerElement(QQuickItem *ownerElement) void QSGSharedDistanceFieldGlyphCache::registerOwnerElement(QQuickItem *ownerElement)
...@@ -761,4 +815,21 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsMissing(const QByteArray &cach ...@@ -761,4 +815,21 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsMissing(const QByteArray &cach
emit glyphsPending(); 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 QT_END_NAMESPACE
...@@ -86,6 +86,9 @@ private Q_SLOTS: ...@@ -86,6 +86,9 @@ private Q_SLOTS:
const QVector<QPoint> &positions); const QVector<QPoint> &positions);
void reportItemsInvalidated(const QByteArray &cacheId, const QVector<quint32> &itemIds); void reportItemsInvalidated(const QByteArray &cacheId, const QVector<quint32> &itemIds);
void sceneGraphUpdateStarted();
void sceneGraphUpdateDone();
private: private:
void waitForGlyphs(); void waitForGlyphs();
void saveTexture(GLuint textureId, int width, int height); void saveTexture(GLuint textureId, int width, int height);
...@@ -122,6 +125,9 @@ private: ...@@ -122,6 +125,9 @@ private:
QHash<quint32, PendingGlyph> m_pendingReadyGlyphs; QHash<quint32, PendingGlyph> m_pendingReadyGlyphs;
QHash<glyph_t, void *> m_bufferForGlyph; QHash<glyph_t, void *> m_bufferForGlyph;
QHash<QQuickItem *, Owner> m_registeredOwners; QHash<QQuickItem *, Owner> m_registeredOwners;
bool m_isInSceneGraphUpdate;
bool m_hasPostedEvents;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment