aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@nokia.com>2011-08-09 16:03:42 +0200
committerQt by Nokia <qt-info@nokia.com>2011-08-10 08:57:29 +0200
commit939f74ca4a5ff1df30c7fcd167fd6fb15945c6ab (patch)
treebc746915af5a57e986f5e0976a83ea34e0fa6752
parent2601011f1c0168f080c488be09c888042812f7cb (diff)
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 <gunnar.sletta@nokia.com>
-rw-r--r--src/declarative/items/qsgtext.cpp7
-rw-r--r--src/declarative/items/qsgtextnode.cpp7
-rw-r--r--src/declarative/scenegraph/qsgadaptationlayer_p.h3
-rw-r--r--src/declarative/scenegraph/qsgcontext.cpp50
-rw-r--r--src/declarative/scenegraph/qsgcontext_p.h3
-rw-r--r--src/declarative/scenegraph/qsgdefaultglyphnode_p.h2
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp194
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphcache_p.h79
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp10
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp6
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h8
11 files changed, 210 insertions, 159 deletions
diff --git a/src/declarative/items/qsgtext.cpp b/src/declarative/items/qsgtext.cpp
index a844f79cc6..d323e3bd54 100644
--- a/src/declarative/items/qsgtext.cpp
+++ b/src/declarative/items/qsgtext.cpp
@@ -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;
diff --git a/src/declarative/items/qsgtextnode.cpp b/src/declarative/items/qsgtextnode.cpp
index d36db1b6b6..c09a53ca49 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<QSGDistanceFieldGlyphNode *>(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 81b17a9000..369a4af86a 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 <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; }
diff --git a/src/declarative/scenegraph/qsgcontext.cpp b/src/declarative/scenegraph/qsgcontext.cpp
index c5e4a7de24..ce346aa1e0 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<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.
diff --git a/src/declarative/scenegraph/qsgcontext_p.h b/src/declarative/scenegraph/qsgcontext_p.h
index cc2be930f4..be7dff880a 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 16e267b605..993eabcd3c 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 90bd8c320d..db264bb281 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<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;
diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphcache_p.h b/src/declarative/scenegraph/qsgdistancefieldglyphcache_p.h
index 0284d5ab67..c4dd97bab5 100644
--- a/src/declarative/scenegraph/qsgdistancefieldglyphcache_p.h
+++ b/src/declarative/scenegraph/qsgdistancefieldglyphcache_p.h
@@ -48,21 +48,59 @@
#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
diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp
index 26326d0c75..c087a09835 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 e58febc49b..52879d751c 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 926a84383c..a5bdf36d16 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;