From: Yoann Lopes Date: Tue, 9 Aug 2011 14:03:42 +0000 (+0200) Subject: QSGDistanceFieldGlyphCache code refactoring. X-Git-Tag: qt-v5.0.0-alpha1~1952 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=939f74ca4a5ff1df30c7fcd167fd6fb15945c6ab;p=profile%2Fivi%2Fqtdeclarative.git QSGDistanceFieldGlyphCache code refactoring. 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 --- diff --git a/src/declarative/items/qsgtext.cpp b/src/declarative/items/qsgtext.cpp index a844f79..d323e3b 100644 --- a/src/declarative/items/qsgtext.cpp +++ b/src/declarative/items/qsgtext.cpp @@ -91,6 +91,7 @@ private: static QSet 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; diff --git a/src/declarative/items/qsgtextnode.cpp b/src/declarative/items/qsgtextnode.cpp index d36db1b..c09a53c 100644 --- a/src/declarative/items/qsgtextnode.cpp +++ b/src/declarative/items/qsgtextnode.cpp @@ -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(node); - dfNode->setStyle(style); - dfNode->setStyleColor(styleColor); - } + node->setStyle(style); + node->setStyleColor(styleColor); node->setColor(color); } diff --git a/src/declarative/scenegraph/qsgadaptationlayer_p.h b/src/declarative/scenegraph/qsgadaptationlayer_p.h index 81b17a9..369a4af 100644 --- a/src/declarative/scenegraph/qsgadaptationlayer_p.h +++ b/src/declarative/scenegraph/qsgadaptationlayer_p.h @@ -44,6 +44,7 @@ #include "qsgnode.h" #include "qsgtexture.h" +#include "qsgtext_p.h" #include #include @@ -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; } diff --git a/src/declarative/scenegraph/qsgcontext.cpp b/src/declarative/scenegraph/qsgcontext.cpp index c5e4a7d..ce346aa 100644 --- a/src/declarative/scenegraph/qsgcontext.cpp +++ b/src/declarative/scenegraph/qsgcontext.cpp @@ -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 materials; + QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager; + QMutex textureMutex; QList 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. diff --git a/src/declarative/scenegraph/qsgcontext_p.h b/src/declarative/scenegraph/qsgcontext_p.h index cc2be93..be7dff8 100644 --- a/src/declarative/scenegraph/qsgcontext_p.h +++ b/src/declarative/scenegraph/qsgcontext_p.h @@ -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: diff --git a/src/declarative/scenegraph/qsgdefaultglyphnode_p.h b/src/declarative/scenegraph/qsgdefaultglyphnode_p.h index 16e267b..993eabc 100644 --- a/src/declarative/scenegraph/qsgdefaultglyphnode_p.h +++ b/src/declarative/scenegraph/qsgdefaultglyphnode_p.h @@ -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() { } diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp index 90bd8c3..db264bb 100644 --- a/src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp +++ b/src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp @@ -797,48 +797,17 @@ static bool fontHasNarrowOutlines(const QRawFont &f) return minHThick == 1 || minVThick == 1; } -DEFINE_BOOL_CONFIG_OPTION(disableDistanceField, QML_DISABLE_DISTANCEFIELD) - -QHash, QSGDistanceFieldGlyphCache *> QSGDistanceFieldGlyphCache::m_caches; -QHash > QSGDistanceFieldGlyphCache::m_textures_data; - -QSGDistanceFieldGlyphCache *QSGDistanceFieldGlyphCache::get(const QGLContext *ctx, const QRawFont &font) -{ - QRawFontPrivate *fontD = QRawFontPrivate::get(font); - QPair key(ctx, fontD->fontEngine); - QHash, 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::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 > 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 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::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; diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphcache_p.h b/src/declarative/scenegraph/qsgdistancefieldglyphcache_p.h index 0284d5a..c4dd97b 100644 --- a/src/declarative/scenegraph/qsgdistancefieldglyphcache_p.h +++ b/src/declarative/scenegraph/qsgdistancefieldglyphcache_p.h @@ -48,21 +48,59 @@ #include #include #include +#include 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 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, QSGDistanceFieldGlyphCache *> m_caches; + QSGDistanceFieldGlyphCacheManager *m_manager; QRawFont m_font; QRawFont m_referenceFont; int m_glyphCount; QHash m_metrics; - mutable int m_maxTextureSize; struct DistanceFieldTextureData { GLuint texture; @@ -155,15 +182,11 @@ private: }; DistanceFieldTextureData *textureData(); DistanceFieldTextureData *m_textureData; - static QHash > m_textures_data; + static QHash > 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 diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp index 26326d0..c087a09 100644 --- a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp +++ b/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp @@ -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; } diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp index e58febc..52879d7 100644 --- a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp +++ b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp @@ -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()); diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h index 926a843..a5bdf36 100644 --- a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h +++ b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h @@ -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;