QSGDistanceFieldGlyphCache code refactoring.
authorYoann Lopes <yoann.lopes@nokia.com>
Tue, 9 Aug 2011 14:03:42 +0000 (16:03 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 10 Aug 2011 06:57:29 +0000 (08:57 +0200)
The distance field glyph caches are now contained in the QSGContext.

Change-Id: Ifc5d155917314b1cc5905ef86fdad0bbc5635c7d
Reviewed-on: http://codereview.qt.nokia.com/2787
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
src/declarative/items/qsgtext.cpp
src/declarative/items/qsgtextnode.cpp
src/declarative/scenegraph/qsgadaptationlayer_p.h
src/declarative/scenegraph/qsgcontext.cpp
src/declarative/scenegraph/qsgcontext_p.h
src/declarative/scenegraph/qsgdefaultglyphnode_p.h
src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp
src/declarative/scenegraph/qsgdistancefieldglyphcache_p.h
src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp
src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp
src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h

index a844f79..d323e3b 100644 (file)
@@ -91,6 +91,7 @@ private:
     static QSet<QUrl> errors;
 };
 
+DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
 DEFINE_BOOL_CONFIG_OPTION(enableImageCache, QML_ENABLE_TEXT_IMAGE_CACHE);
 
 QString QSGTextPrivate::elideChar = QString(0x2026);
@@ -574,7 +575,7 @@ void QSGTextPrivate::invalidateImageCache()
 {
     Q_Q(QSGText);
 
-    if(richTextAsImage || cacheAllTextAsImage || (!QSGDistanceFieldGlyphCache::distanceFieldEnabled() && style != QSGText::Normal)){//If actually using the image cache
+    if(richTextAsImage || cacheAllTextAsImage || (qmlDisableDistanceField() && style != QSGText::Normal)){//If actually using the image cache
         if (imageCacheDirty)
             return;
 
@@ -906,7 +907,7 @@ void QSGText::setFont(const QFont &font)
     d->sourceFont = font;
     QFont oldFont = d->font;
     d->font = font;
-    if (QSGDistanceFieldGlyphCache::distanceFieldEnabled())
+    if (!qmlDisableDistanceField())
         d->font.setHintingPreference(QFont::PreferNoHinting);
 
     if (d->font.pointSizeF() != -1) {
@@ -1483,7 +1484,7 @@ QSGNode *QSGText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
         d->updateLayout();
 
     // XXX todo - some styled text can be done by the QSGTextNode
-    if (d->richTextAsImage || d->cacheAllTextAsImage || (!QSGDistanceFieldGlyphCache::distanceFieldEnabled() && d->style != Normal)) {
+    if (d->richTextAsImage || d->cacheAllTextAsImage || (qmlDisableDistanceField() && d->style != Normal)) {
         bool wasDirty = d->textureImageCacheDirty;
         d->textureImageCacheDirty = false;
 
index d36db1b..c09a53c 100644 (file)
@@ -156,11 +156,8 @@ QSGGlyphNode *QSGTextNode::addGlyphs(const QPointF &position, const QGlyphRun &g
     node->setGlyphs(position, glyphs);
 
     if (node != prevNode) {
-        if (QSGDistanceFieldGlyphCache::distanceFieldEnabled()) {
-            QSGDistanceFieldGlyphNode *dfNode = static_cast<QSGDistanceFieldGlyphNode *>(node);
-            dfNode->setStyle(style);
-            dfNode->setStyleColor(styleColor);
-        }
+        node->setStyle(style);
+        node->setStyleColor(styleColor);
         node->setColor(color);
     }
 
index 81b17a9..369a4af 100644 (file)
@@ -44,6 +44,7 @@
 
 #include "qsgnode.h"
 #include "qsgtexture.h"
+#include "qsgtext_p.h"
 
 #include <QtCore/qobject.h>
 #include <QtCore/qrect.h>
@@ -105,6 +106,8 @@ public:
 
     virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs) = 0;
     virtual void setColor(const QColor &color) = 0;
+    virtual void setStyle(QSGText::TextStyle style) = 0;
+    virtual void setStyleColor(const QColor &color) = 0;
     virtual QPointF baseLine() const = 0;
 
     virtual QRectF boundingRect() const { return m_bounding_rect; }
index c5e4a7d..ce346aa 100644 (file)
@@ -62,6 +62,7 @@
 
 DEFINE_BOOL_CONFIG_OPTION(qmlFlashMode, QML_FLASH_MODE)
 DEFINE_BOOL_CONFIG_OPTION(qmlTranslucentMode, QML_TRANSLUCENT_MODE)
+DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
 
 /*
     Comments about this class from Gunnar:
@@ -90,12 +91,14 @@ public:
         : rootNode(0)
         , renderer(0)
         , gl(0)
+        , distanceFieldCacheManager(0)
         , flashMode(qmlFlashMode())
+        , distanceFieldDisabled(qmlDisableDistanceField())
     {
         renderAlpha = qmlTranslucentMode() ? 0.5 : 1;
     }
 
-    ~QSGContextPrivate() 
+    ~QSGContextPrivate()
     {
     }
 
@@ -108,11 +111,14 @@ public:
 
     QHash<QSGMaterialType *, QSGMaterialShader *> materials;
 
+    QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager;
+
     QMutex textureMutex;
     QList<QSGTexture *> texturesToClean;
 
     bool flashMode;
     float renderAlpha;
+    bool distanceFieldDisabled;
 };
 
 
@@ -142,6 +148,7 @@ QSGContext::~QSGContext()
     delete d->rootNode;
     cleanupTextures();
     qDeleteAll(d->materials.values());
+    delete d->distanceFieldCacheManager;
 }
 
 /*!
@@ -286,20 +293,25 @@ QSGImageNode *QSGContext::createImageNode()
  */
 QSGGlyphNode *QSGContext::createGlyphNode()
 {
+    Q_D(QSGContext);
+
     // ### Do something with these before final release...
     static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing"));
     static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing"));
 
-    if (QSGDistanceFieldGlyphCache::distanceFieldEnabled()) {
-        QSGGlyphNode *node = new QSGDistanceFieldGlyphNode;
-
-        if (doSubpixel)
-            node->setPreferredAntialiasingMode(QSGGlyphNode::SubPixelAntialiasing);
-        else if (doGray)
-            node->setPreferredAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
-        return node;
-    } else {
+    if (d->distanceFieldDisabled) {
         return new QSGDefaultGlyphNode;
+    } else {
+        if (!d->distanceFieldCacheManager) {
+            d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager(d->gl);
+            if (doSubpixel)
+                d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::SubPixelAntialiasing);
+            else if (doGray)
+               d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
+        }
+
+        QSGGlyphNode *node = new QSGDistanceFieldGlyphNode(d->distanceFieldCacheManager);
+        return node;
     }
 }
 
@@ -449,6 +461,24 @@ qreal QSGContext::renderAlpha() const
 }
 
 
+/*!
+    Sets whether or not the scene graph should use the distance field technique to render text
+  */
+void QSGContext::setDistanceFieldEnabled(bool enabled)
+{
+    d_func()->distanceFieldDisabled = !enabled;
+}
+
+
+/*!
+    Returns true if the scene graph uses the distance field technique to render text
+ */
+bool QSGContext::isDistanceFieldEnabled() const
+{
+    return !d_func()->distanceFieldDisabled;
+}
+
+
 
 /*!
     Creates a new animation driver.
index cc2be93..be7dff8 100644 (file)
@@ -114,6 +114,9 @@ public:
     void setRenderAlpha(qreal renderAlpha);
     qreal renderAlpha() const;
 
+    void setDistanceFieldEnabled(bool enabled);
+    bool isDistanceFieldEnabled() const;
+
     virtual QAnimationDriver *createAnimationDriver(QObject *parent);
 
 signals:
index 16e267b..993eabc 100644 (file)
@@ -64,6 +64,8 @@ public:
     virtual void setColor(const QColor &color);
 
     virtual void setPreferredAntialiasingMode(AntialiasingMode) { }
+    virtual void setStyle(QSGText::TextStyle) { }
+    virtual void setStyleColor(const QColor &) { }
 
     virtual void update() { }
 
index 90bd8c3..db264bb 100644 (file)
@@ -797,48 +797,17 @@ static bool fontHasNarrowOutlines(const QRawFont &f)
     return minHThick == 1 || minVThick == 1;
 }
 
-DEFINE_BOOL_CONFIG_OPTION(disableDistanceField, QML_DISABLE_DISTANCEFIELD)
-
-QHash<QPair<const QGLContext *, QFontEngine *>, QSGDistanceFieldGlyphCache *> QSGDistanceFieldGlyphCache::m_caches;
-QHash<QFontEngine *, QGLContextGroupResource<QSGDistanceFieldGlyphCache::DistanceFieldTextureData> > QSGDistanceFieldGlyphCache::m_textures_data;
-
-QSGDistanceFieldGlyphCache *QSGDistanceFieldGlyphCache::get(const QGLContext *ctx, const QRawFont &font)
-{
-    QRawFontPrivate *fontD = QRawFontPrivate::get(font);
-    QPair<const QGLContext *, QFontEngine *> key(ctx, fontD->fontEngine);
-    QHash<QPair<const QGLContext *, QFontEngine *>, QSGDistanceFieldGlyphCache *>::iterator atlas = m_caches.find(key);
-    if (atlas == m_caches.end())
-        atlas = m_caches.insert(key, new QSGDistanceFieldGlyphCache(ctx, font));
-
-    return atlas.value();
-}
-
-QSGDistanceFieldGlyphCache::DistanceFieldTextureData *QSGDistanceFieldGlyphCache::textureData()
-{
-    return m_textures_data[QRawFontPrivate::get(m_font)->fontEngine].value(ctx);
-}
-
-QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(const QGLContext *c, const QRawFont &font)
-    : QObject()
-    , m_maxTextureSize(0)
-    , ctx(c)
-    , m_blitProgram(0)
+QSGDistanceFieldGlyphCacheManager::QSGDistanceFieldGlyphCacheManager(const QGLContext *c)
+    : ctx(c)
     , m_threshold_func(defaultThresholdFunc)
     , m_antialiasingSpread_func(defaultAntialiasingSpreadFunc)
+    , m_maxTextureSize(0)
 {
-    Q_ASSERT(font.isValid());
-    m_font = font;
-
-    m_textureData = textureData();
-
-    QRawFontPrivate *fontD = QRawFontPrivate::get(m_font);
-    m_glyphCount = fontD->fontEngine->glyphCount();
-
-    m_textureData->doubleGlyphResolution = fontHasNarrowOutlines(font) && m_glyphCount < QT_DISTANCEFIELD_HIGHGLYPHCOUNT;
-
-    m_referenceFont = m_font;
-    m_referenceFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE);
-    Q_ASSERT(m_referenceFont.isValid());
+#ifndef QT_OPENGL_ES
+    m_defaultAntialiasingMode = QSGGlyphNode::SubPixelAntialiasing;
+#else
+    m_defaultAntialiasingMode = QSGGlyphNode::GrayAntialiasing;
+#endif
 
     m_vertexCoordinateArray[0] = -1.0f;
     m_vertexCoordinateArray[1] = -1.0f;
@@ -858,24 +827,88 @@ QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(const QGLContext *c, cons
     m_textureCoordinateArray[6] = 0.0f;
     m_textureCoordinateArray[7] = 1.0f;
 
-    connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)),
-            this, SLOT(onContextDestroyed(const QGLContext*)));
+    m_blitProgram = new QGLShaderProgram;
+    {
+        QString source;
+        source.append(QLatin1String(qglslMainWithTexCoordsVertexShader));
+        source.append(QLatin1String(qglslUntransformedPositionVertexShader));
+
+        QGLShader *vertexShader = new QGLShader(QGLShader::Vertex, m_blitProgram);
+        vertexShader->compileSourceCode(source);
+
+        m_blitProgram->addShader(vertexShader);
+    }
+    {
+        QString source;
+        source.append(QLatin1String(qglslMainFragmentShader));
+        source.append(QLatin1String(qglslImageSrcFragmentShader));
+
+        QGLShader *fragmentShader = new QGLShader(QGLShader::Fragment, m_blitProgram);
+        fragmentShader->compileSourceCode(source);
+
+        m_blitProgram->addShader(fragmentShader);
+    }
+    m_blitProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
+    m_blitProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
+    m_blitProgram->link();
 }
 
-QSGDistanceFieldGlyphCache::~QSGDistanceFieldGlyphCache()
+QSGDistanceFieldGlyphCacheManager::~QSGDistanceFieldGlyphCacheManager()
 {
     delete m_blitProgram;
+    qDeleteAll(m_caches.values());
 }
 
-void QSGDistanceFieldGlyphCache::onContextDestroyed(const QGLContext *context)
+QSGDistanceFieldGlyphCache *QSGDistanceFieldGlyphCacheManager::cache(const QRawFont &font)
 {
-    if (context != ctx)
-        return;
+    QRawFontPrivate *fontD = QRawFontPrivate::get(font);
+    QHash<QFontEngine *, QSGDistanceFieldGlyphCache *>::iterator cache = m_caches.find(fontD->fontEngine);
+    if (cache == m_caches.end())
+        cache = m_caches.insert(fontD->fontEngine, new QSGDistanceFieldGlyphCache(this, ctx, font));
+    return cache.value();
+}
+
+int QSGDistanceFieldGlyphCacheManager::maxTextureSize() const
+{
+    if (!m_maxTextureSize)
+        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
+    return m_maxTextureSize;
+}
+
+
+QHash<QString, QGLContextGroupResource<QSGDistanceFieldGlyphCache::DistanceFieldTextureData> > QSGDistanceFieldGlyphCache::m_textures_data;
+
+QSGDistanceFieldGlyphCache::DistanceFieldTextureData *QSGDistanceFieldGlyphCache::textureData()
+{
+    QString key = QString::fromLatin1("%1_%2_%3_%4")
+            .arg(m_font.familyName())
+            .arg(m_font.styleName())
+            .arg(m_font.weight())
+            .arg(m_font.style());
+    return m_textures_data[key].value(ctx);
+}
+
+QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, const QGLContext *c, const QRawFont &font)
+    : m_manager(man)
+    , ctx(c)
+{
+    Q_ASSERT(font.isValid());
+    m_font = font;
+
+    m_textureData = textureData();
 
     QRawFontPrivate *fontD = QRawFontPrivate::get(m_font);
-    QPair<const QGLContext *, QFontEngine *> key(context, fontD->fontEngine);
-    m_caches.remove(key);
-    deleteLater();
+    m_glyphCount = fontD->fontEngine->glyphCount();
+
+    m_textureData->doubleGlyphResolution = fontHasNarrowOutlines(font) && m_glyphCount < QT_DISTANCEFIELD_HIGHGLYPHCOUNT;
+
+    m_referenceFont = m_font;
+    m_referenceFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE);
+    Q_ASSERT(m_referenceFont.isValid());
+}
+
+QSGDistanceFieldGlyphCache::~QSGDistanceFieldGlyphCache()
+{
 }
 
 GLuint QSGDistanceFieldGlyphCache::texture()
@@ -888,13 +921,6 @@ QSize QSGDistanceFieldGlyphCache::textureSize() const
     return m_textureData->size;
 }
 
-int QSGDistanceFieldGlyphCache::maxTextureSize() const
-{
-    if (!m_maxTextureSize)
-        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
-    return m_maxTextureSize;
-}
-
 QSGDistanceFieldGlyphCache::Metrics QSGDistanceFieldGlyphCache::glyphMetrics(glyph_t glyph)
 {
     QHash<glyph_t, Metrics>::iterator metric = m_metrics.find(glyph);
@@ -987,7 +1013,7 @@ void QSGDistanceFieldGlyphCache::populate(int count, const glyph_t *glyphs)
 
         if (!cacheIsFull()) {
             m_textureData->currX += QT_DISTANCEFIELD_TILESIZE;
-            if (m_textureData->currX >= maxTextureSize()) {
+            if (m_textureData->currX >= m_manager->maxTextureSize()) {
                 m_textureData->currX = 0;
                 m_textureData->currY += QT_DISTANCEFIELD_TILESIZE;
             }
@@ -1003,7 +1029,7 @@ void QSGDistanceFieldGlyphCache::populate(int count, const glyph_t *glyphs)
             }
         }
 
-        if (c.y < maxTextureSize()) {
+        if (c.y < m_manager->maxTextureSize()) {
             m_textureData->texCoords.insert(glyphIndex, c);
             m_textureData->pendingGlyphs.add(glyphIndex);
         }
@@ -1107,45 +1133,14 @@ void QSGDistanceFieldGlyphCache::resizeTexture(int width, int height)
 
     glViewport(0, 0, oldWidth, oldHeight);
 
-    if (m_blitProgram == 0) {
-        m_blitProgram = new QGLShaderProgram;
-
-        {
-            QString source;
-            source.append(QLatin1String(qglslMainWithTexCoordsVertexShader));
-            source.append(QLatin1String(qglslUntransformedPositionVertexShader));
-
-            QGLShader *vertexShader = new QGLShader(QGLShader::Vertex, m_blitProgram);
-            vertexShader->compileSourceCode(source);
-
-            m_blitProgram->addShader(vertexShader);
-        }
+    ctx->functions()->glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_manager->blitVertexArray());
+    ctx->functions()->glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_manager->blitTextureArray());
 
-        {
-            QString source;
-            source.append(QLatin1String(qglslMainFragmentShader));
-            source.append(QLatin1String(qglslImageSrcFragmentShader));
-
-            QGLShader *fragmentShader = new QGLShader(QGLShader::Fragment, m_blitProgram);
-            fragmentShader->compileSourceCode(source);
-
-            m_blitProgram->addShader(fragmentShader);
-        }
-
-        m_blitProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
-        m_blitProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
-
-        m_blitProgram->link();
-    }
-
-    ctx->functions()->glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_vertexCoordinateArray);
-    ctx->functions()->glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_textureCoordinateArray);
-
-    m_blitProgram->bind();
-    m_blitProgram->enableAttributeArray(int(QT_VERTEX_COORDS_ATTR));
-    m_blitProgram->enableAttributeArray(int(QT_TEXTURE_COORDS_ATTR));
-    m_blitProgram->disableAttributeArray(int(QT_OPACITY_ATTR));
-    m_blitProgram->setUniformValue("imageTexture", GLuint(0));
+    m_manager->blitProgram()->bind();
+    m_manager->blitProgram()->enableAttributeArray(int(QT_VERTEX_COORDS_ATTR));
+    m_manager->blitProgram()->enableAttributeArray(int(QT_TEXTURE_COORDS_ATTR));
+    m_manager->blitProgram()->disableAttributeArray(int(QT_OPACITY_ATTR));
+    m_manager->blitProgram()->setUniformValue("imageTexture", GLuint(0));
 
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
@@ -1177,9 +1172,9 @@ void QSGDistanceFieldGlyphCache::updateCache()
     if (m_textureData->pendingGlyphs.isEmpty())
         return;
 
-    int requiredWidth = maxTextureSize();
+    int requiredWidth = m_manager->maxTextureSize();
     int rows = 128 / (requiredWidth / QT_DISTANCEFIELD_TILESIZE); // Enough rows to fill the latin1 set by default..
-    int requiredHeight = qMin(maxTextureSize(), qMax(m_textureData->currY + QT_DISTANCEFIELD_TILESIZE, QT_DISTANCEFIELD_TILESIZE * rows));
+    int requiredHeight = qMin(m_manager->maxTextureSize(), qMax(m_textureData->currY + QT_DISTANCEFIELD_TILESIZE, QT_DISTANCEFIELD_TILESIZE * rows));
 
     resizeTexture((requiredWidth), (requiredHeight));
     glBindTexture(GL_TEXTURE_2D, m_textureData->texture);
@@ -1256,11 +1251,6 @@ bool QSGDistanceFieldGlyphCache::useWorkaroundBrokenFBOReadback() const
     return ctx->d_ptr->workaround_brokenFBOReadBack;
 }
 
-bool QSGDistanceFieldGlyphCache::distanceFieldEnabled()
-{
-    return !disableDistanceField();
-}
-
 int QSGDistanceFieldGlyphCache::glyphCount() const
 {
     return m_glyphCount;
index 0284d5a..c4dd97b 100644 (file)
 #include <private/qfont_p.h>
 #include <private/qfontengine_p.h>
 #include <QtGui/private/qdatabuffer_p.h>
+#include <private/qsgadaptationlayer_p.h>
 
 QT_BEGIN_NAMESPACE
 
-class QGLShaderProgram;
-
 typedef float (*ThresholdFunc)(float glyphScale);
 typedef float (*AntialiasingSpreadFunc)(float glyphScale);
 
-class Q_DECLARATIVE_EXPORT QSGDistanceFieldGlyphCache : public QObject
+class QGLShaderProgram;
+class QSGDistanceFieldGlyphCache;
+
+class Q_DECLARATIVE_EXPORT QSGDistanceFieldGlyphCacheManager
 {
-    Q_OBJECT
 public:
-    ~QSGDistanceFieldGlyphCache();
+    QSGDistanceFieldGlyphCacheManager(const QGLContext *c);
+    ~QSGDistanceFieldGlyphCacheManager();
+
+    QSGDistanceFieldGlyphCache *cache(const QRawFont &font);
+
+    QSGGlyphNode::AntialiasingMode defaultAntialiasingMode() const { return m_defaultAntialiasingMode; }
+    void setDefaultAntialiasingMode(QSGGlyphNode::AntialiasingMode mode) { m_defaultAntialiasingMode = mode; }
+
+    ThresholdFunc thresholdFunc() const { return m_threshold_func; }
+    void setThresholdFunc(ThresholdFunc func) { m_threshold_func = func; }
+
+    AntialiasingSpreadFunc antialiasingSpreadFunc() const { return m_antialiasingSpread_func; }
+    void setAntialiasingSpreadFunc(AntialiasingSpreadFunc func) { m_antialiasingSpread_func = func; }
 
-    static QSGDistanceFieldGlyphCache *get(const QGLContext *ctx, const QRawFont &font);
+    QGLShaderProgram *blitProgram() { return m_blitProgram; }
+    const GLfloat *blitVertexArray() const { return &m_vertexCoordinateArray[0]; }
+    const GLfloat *blitTextureArray() const { return &m_textureCoordinateArray[0]; }
+
+    int maxTextureSize() const;
+
+private:
+    QHash<QFontEngine *, QSGDistanceFieldGlyphCache *> m_caches;
+
+    const QGLContext *ctx;
+
+    QSGGlyphNode::AntialiasingMode m_defaultAntialiasingMode;
+    ThresholdFunc m_threshold_func;
+    AntialiasingSpreadFunc m_antialiasingSpread_func;
+
+    mutable int m_maxTextureSize;
+
+    QGLShaderProgram *m_blitProgram;
+    GLfloat m_vertexCoordinateArray[8];
+    GLfloat m_textureCoordinateArray[8];
+};
+
+class Q_DECLARATIVE_EXPORT QSGDistanceFieldGlyphCache
+{
+public:
+    ~QSGDistanceFieldGlyphCache();
 
     struct Metrics {
         qreal width;
@@ -88,9 +126,10 @@ public:
     };
     TexCoord glyphTexCoord(glyph_t glyph);
 
+    const QSGDistanceFieldGlyphCacheManager *manager() const { return m_manager; }
+
     GLuint texture();
     QSize textureSize() const;
-    int maxTextureSize() const;
     qreal fontScale() const;
     int distanceFieldRadius() const;
     QImage renderDistanceFieldGlyph(glyph_t glyph) const;
@@ -101,35 +140,23 @@ public:
     void derefGlyphs(int count, const glyph_t *glyphs);
     void updateCache();
 
-    bool cacheIsFull() const { return m_textureData->currY >= maxTextureSize(); }
+    bool cacheIsFull() const { return m_textureData->currY >= m_manager->maxTextureSize(); }
 
     bool useWorkaroundBrokenFBOReadback() const;
 
-    static bool distanceFieldEnabled();
-
-    ThresholdFunc thresholdFunc() const { return m_threshold_func; }
-    void setThresholdFunc(ThresholdFunc func) { m_threshold_func = func; }
-
-    AntialiasingSpreadFunc antialiasingSpreadFunc() const { return m_antialiasingSpread_func; }
-    void setAntialiasingSpreadFunc(AntialiasingSpreadFunc func) { m_antialiasingSpread_func = func; }
-
-private Q_SLOTS:
-    void onContextDestroyed(const QGLContext *context);
-
 private:
-    QSGDistanceFieldGlyphCache(const QGLContext *c, const QRawFont &font);
+    QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, const QGLContext *c, const QRawFont &font);
 
     void createTexture(int width, int height);
     void resizeTexture(int width, int height);
 
-    static QHash<QPair<const QGLContext *, QFontEngine *>, QSGDistanceFieldGlyphCache *> m_caches;
+    QSGDistanceFieldGlyphCacheManager *m_manager;
 
     QRawFont m_font;
     QRawFont m_referenceFont;
 
     int m_glyphCount;
     QHash<glyph_t, Metrics> m_metrics;
-    mutable int m_maxTextureSize;
 
     struct DistanceFieldTextureData {
         GLuint texture;
@@ -155,15 +182,11 @@ private:
     };
     DistanceFieldTextureData *textureData();
     DistanceFieldTextureData *m_textureData;
-    static QHash<QFontEngine *, QGLContextGroupResource<DistanceFieldTextureData> > m_textures_data;
+    static QHash<QString, QGLContextGroupResource<DistanceFieldTextureData> > m_textures_data;
 
     const QGLContext *ctx;
-    QGLShaderProgram *m_blitProgram;
-    GLfloat m_vertexCoordinateArray[8];
-    GLfloat m_textureCoordinateArray[8];
 
-    ThresholdFunc m_threshold_func;
-    AntialiasingSpreadFunc m_antialiasingSpread_func;
+    friend class QSGDistanceFieldGlyphCacheManager;
 };
 
 QT_END_NAMESPACE
index 26326d0..c087a09 100644 (file)
@@ -46,8 +46,9 @@
 
 QT_BEGIN_NAMESPACE
 
-QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode()
+QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode(QSGDistanceFieldGlyphCacheManager *cacheManager)
     : m_material(0)
+    , m_glyph_cacheManager(cacheManager)
     , m_glyph_cache(0)
     , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0)
     , m_style(QSGText::Normal)
@@ -58,10 +59,7 @@ QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode()
 {
     m_geometry.setDrawingMode(GL_TRIANGLES);
     setGeometry(&m_geometry);
-
-#ifndef QT_OPENGL_ES
-    setPreferredAntialiasingMode(QSGGlyphNode::SubPixelAntialiasing);
-#endif
+    setPreferredAntialiasingMode(cacheManager->defaultAntialiasingMode());
 }
 
 QSGDistanceFieldGlyphNode::~QSGDistanceFieldGlyphNode()
@@ -245,7 +243,7 @@ void QSGDistanceFieldGlyphNode::updateGeometry()
 
 void QSGDistanceFieldGlyphNode::updateFont()
 {
-    m_glyph_cache = QSGDistanceFieldGlyphCache::get(QGLContext::currentContext(), m_glyphs.rawFont());
+    m_glyph_cache = m_glyph_cacheManager->cache(m_glyphs.rawFont());
     m_dirtyFont = false;
 }
 
index e58febc..52879d7 100644 (file)
@@ -162,8 +162,10 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q
         m_matrixScale = qSqrt(state.modelViewMatrix().determinant());
         updateRange = true;
     }
-    if (updateRange)
-        updateAlphaRange(material->glyphCache()->thresholdFunc(), material->glyphCache()->antialiasingSpreadFunc());
+    if (updateRange) {
+        updateAlphaRange(material->glyphCache()->manager()->thresholdFunc(),
+                         material->glyphCache()->manager()->antialiasingSpreadFunc());
+    }
 
     Q_ASSERT(material->glyphCache());
 
index 926a843..a5bdf36 100644 (file)
@@ -53,11 +53,12 @@ QT_BEGIN_NAMESPACE
 QT_MODULE(Declarative)
 
 class QSGDistanceFieldGlyphCache;
+class QSGDistanceFieldGlyphCacheManager;
 class QSGDistanceFieldTextMaterial;
 class QSGDistanceFieldGlyphNode: public QSGGlyphNode
 {
 public:
-    QSGDistanceFieldGlyphNode();
+    QSGDistanceFieldGlyphNode(QSGDistanceFieldGlyphCacheManager *cacheManager);
     ~QSGDistanceFieldGlyphNode();
 
     virtual QPointF baseLine() const { return m_baseLine; }
@@ -66,8 +67,8 @@ public:
 
     virtual void setPreferredAntialiasingMode(AntialiasingMode mode);
 
-    void setStyle(QSGText::TextStyle style);
-    void setStyleColor(const QColor &color);
+    virtual void setStyle(QSGText::TextStyle style);
+    virtual void setStyleColor(const QColor &color);
 
     virtual void update();
 
@@ -81,6 +82,7 @@ private:
     QSGDistanceFieldTextMaterial *m_material;
     QPointF m_position;
     QGlyphRun m_glyphs;
+    QSGDistanceFieldGlyphCacheManager *m_glyph_cacheManager;
     QSGDistanceFieldGlyphCache *m_glyph_cache;
     QSGGeometry m_geometry;
     QSGText::TextStyle m_style;