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) {
continue;
}
+ ++m_cacheData->glyphRefCount[glyphIndex];
+ referencedGlyphs.insert(glyphIndex);
+
if (m_cacheData->texCoords.contains(glyphIndex) || newGlyphs.contains(glyphIndex))
continue;
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()
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);
QHash<glyph_t, QPainterPath> glyphPaths;
bool doubleGlyphResolution;
QLinkedList<QSGDistanceFieldGlyphNode*> m_registeredNodes;
+ QHash<glyph_t, quint32> glyphRefCount;
GlyphCacheData(QOpenGLContext *ctx)
: QOpenGLSharedResource(ctx->shareGroup())
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);
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)
#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>
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;
GLuint texture;
GLuint fbo;
QSize size;
- QHash<glyph_t, quint32> glyphRefCount;
QSet<glyph_t> unusedGlyphs;
int currX;
int currY;
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);
}