aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@nokia.com>2011-12-15 14:17:33 +0100
committerQt by Nokia <qt-info@nokia.com>2011-12-21 12:16:25 +0100
commit3d8986d7475ef6fdd04ea1286d840d2b570133a0 (patch)
tree66cec7e44c432c904b0e33dec4ce34ef622c7b67
parent0febfa03b62a4449c42ad1e675777b7b099ebaa3 (diff)
Reference count glyphs in QSGDistanceFieldGlyphCache.
This was previously done only in the default cache implementation. It has been moved to the base class. releaseGlyphs() is called when a glyph is not referenced anymore by any node. Added a virtual function referenceGlyphs() that is called everytime glyphs are being used in a node. This function is called just before requestGlyphs(). Change-Id: If90f86c328c18ae2a5977847a6adf50b99ea1241 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp22
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h6
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp36
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h8
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode.cpp5
5 files changed, 38 insertions, 39 deletions
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index 57c0990f1d..73ac81fd5b 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -132,6 +132,7 @@ const QSGDistanceFieldGlyphCache::Texture *QSGDistanceFieldGlyphCache::glyphText
void QSGDistanceFieldGlyphCache::populate(const QVector<glyph_t> &glyphs)
{
+ QSet<glyph_t> referencedGlyphs;
QSet<glyph_t> newGlyphs;
int count = glyphs.count();
for (int i = 0; i < count; ++i) {
@@ -141,6 +142,9 @@ void QSGDistanceFieldGlyphCache::populate(const QVector<glyph_t> &glyphs)
continue;
}
+ ++m_cacheData->glyphRefCount[glyphIndex];
+ referencedGlyphs.insert(glyphIndex);
+
if (m_cacheData->texCoords.contains(glyphIndex) || newGlyphs.contains(glyphIndex))
continue;
@@ -160,18 +164,20 @@ void QSGDistanceFieldGlyphCache::populate(const QVector<glyph_t> &glyphs)
if (newGlyphs.isEmpty())
return;
- QVector<glyph_t> glyphsVec;
- QSet<glyph_t>::const_iterator it = newGlyphs.constBegin();
- while (it != newGlyphs.constEnd()) {
- glyphsVec.append(*it);
- ++it;
- }
- requestGlyphs(glyphsVec);
+ referenceGlyphs(referencedGlyphs);
+ requestGlyphs(newGlyphs);
}
void QSGDistanceFieldGlyphCache::release(const QVector<glyph_t> &glyphs)
{
- releaseGlyphs(glyphs);
+ QSet<glyph_t> unusedGlyphs;
+ int count = glyphs.count();
+ for (int i = 0; i < count; ++i) {
+ glyph_t glyphIndex = glyphs.at(i);
+ if (--m_cacheData->glyphRefCount[glyphIndex] == 0 && !glyphTexCoord(glyphIndex).isNull())
+ unusedGlyphs.insert(glyphIndex);
+ }
+ releaseGlyphs(unusedGlyphs);
}
void QSGDistanceFieldGlyphCache::update()
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index 0c777ef639..c4851c326b 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -191,9 +191,10 @@ protected:
QPointF position;
};
- virtual void requestGlyphs(const QVector<glyph_t> &glyphs) = 0;
+ virtual void requestGlyphs(const QSet<glyph_t> &glyphs) = 0;
virtual void storeGlyphs(const QHash<glyph_t, QImage> &glyphs) = 0;
- virtual void releaseGlyphs(const QVector<glyph_t> &glyphs) = 0;
+ virtual void referenceGlyphs(const QSet<glyph_t> &glyphs) = 0;
+ virtual void releaseGlyphs(const QSet<glyph_t> &glyphs) = 0;
void setGlyphsPosition(const QList<GlyphPosition> &glyphs);
void setGlyphsTexture(const QVector<glyph_t> &glyphs, const Texture &tex);
@@ -215,6 +216,7 @@ private:
QHash<glyph_t, QPainterPath> glyphPaths;
bool doubleGlyphResolution;
QLinkedList<QSGDistanceFieldGlyphNode*> m_registeredNodes;
+ QHash<glyph_t, quint32> glyphRefCount;
GlyphCacheData(QOpenGLContext *ctx)
: QOpenGLSharedResource(ctx->shareGroup())
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
index 4f69ad8c44..57a9a8741c 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
@@ -65,31 +65,19 @@ QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QSGDistance
m_textureData = textureData(c);
}
-void QSGDefaultDistanceFieldGlyphCache::requestGlyphs(const QVector<glyph_t> &glyphs)
+void QSGDefaultDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs)
{
- int count = glyphs.count();
-
- // Avoid useless and costly glyph re-generation
- if (cacheIsFull() && !m_textureData->unusedGlyphs.isEmpty()) {
- for (int i = 0; i < count; ++i) {
- glyph_t glyphIndex = glyphs.at(i);
- if (containsGlyph(glyphIndex) && m_textureData->unusedGlyphs.contains(glyphIndex))
- m_textureData->unusedGlyphs.remove(glyphIndex);
- }
- }
-
QList<GlyphPosition> glyphPositions;
QVector<glyph_t> glyphsToRender;
- for (int i = 0; i < count; ++i) {
- glyph_t glyphIndex = glyphs.at(i);
-
- if (++m_textureData->glyphRefCount[glyphIndex] == 1)
- m_textureData->unusedGlyphs.remove(glyphIndex);
+ for (QSet<glyph_t>::const_iterator it = glyphs.constBegin(); it != glyphs.constEnd() ; ++it) {
+ glyph_t glyphIndex = *it;
if (cacheIsFull() && m_textureData->unusedGlyphs.isEmpty())
continue;
+ m_textureData->unusedGlyphs.remove(glyphIndex);
+
GlyphPosition p;
p.glyph = glyphIndex;
p.position = QPointF(m_textureData->currX, m_textureData->currY);
@@ -162,14 +150,14 @@ void QSGDefaultDistanceFieldGlyphCache::storeGlyphs(const QHash<glyph_t, QImage>
setGlyphsTexture(glyphTextures, t);
}
-void QSGDefaultDistanceFieldGlyphCache::releaseGlyphs(const QVector<glyph_t> &glyphs)
+void QSGDefaultDistanceFieldGlyphCache::referenceGlyphs(const QSet<glyph_t> &glyphs)
{
- int count = glyphs.count();
- for (int i = 0; i < count; ++i) {
- glyph_t glyphIndex = glyphs.at(i);
- if (--m_textureData->glyphRefCount[glyphIndex] == 0 && !glyphTexCoord(glyphIndex).isNull())
- m_textureData->unusedGlyphs.insert(glyphIndex);
- }
+ m_textureData->unusedGlyphs -= glyphs;
+}
+
+void QSGDefaultDistanceFieldGlyphCache::releaseGlyphs(const QSet<glyph_t> &glyphs)
+{
+ m_textureData->unusedGlyphs += glyphs;
}
void QSGDefaultDistanceFieldGlyphCache::createTexture(int width, int height)
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
index b52ec45107..06f9283bcc 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
@@ -42,8 +42,8 @@
#ifndef QSGDEFAULTDISTANCEFIELDGLYPHCACHE_H
#define QSGDEFAULTDISTANCEFIELDGLYPHCACHE_H
+#include "qsgadaptationlayer_p.h"
#include <QtGui/qopenglfunctions.h>
-#include <private/qsgadaptationlayer_p.h>
#include <qopenglshaderprogram.h>
#include <QtGui/private/qopenglengineshadersource_p.h>
@@ -54,9 +54,10 @@ class Q_QUICK_EXPORT QSGDefaultDistanceFieldGlyphCache : public QSGDistanceField
public:
QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font);
- void requestGlyphs(const QVector<glyph_t> &glyphs);
+ void requestGlyphs(const QSet<glyph_t> &glyphs);
void storeGlyphs(const QHash<glyph_t, QImage> &glyphs);
- void releaseGlyphs(const QVector<glyph_t> &glyphs);
+ void referenceGlyphs(const QSet<glyph_t> &glyphs);
+ void releaseGlyphs(const QSet<glyph_t> &glyphs);
bool cacheIsFull() const { return m_textureData->currY >= maxTextureSize(); }
bool useWorkaroundBrokenFBOReadback() const;
@@ -72,7 +73,6 @@ private:
GLuint texture;
GLuint fbo;
QSize size;
- QHash<glyph_t, quint32> glyphRefCount;
QSet<glyph_t> unusedGlyphs;
int currX;
int currY;
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
index fe5f16a0a2..f192573624 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
@@ -71,7 +71,10 @@ QSGDistanceFieldGlyphNode::~QSGDistanceFieldGlyphNode()
delete m_material;
if (m_glyph_cache) {
- m_glyph_cache->release(m_glyphs.glyphIndexes());
+ QVector<quint32> glyphIndexes;
+ for (int i = 0; i < m_allGlyphs.count(); ++i)
+ glyphIndexes.append(m_allGlyphs.at(i).glyphIndex);
+ m_glyph_cache->release(glyphIndexes);
m_glyph_cache->unregisterGlyphNode(this);
}