aboutsummaryrefslogtreecommitdiffstats
path: root/src
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 /src
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>
Diffstat (limited to 'src')
-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);
}