Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Decouple QSGDistanceFieldGlyphNode from it's cache manager.
To implement a custom distance field glyph node currently it's
necessary to also provide a duplicate implementation of
QSGContext::createDistanceFieldGlyphCache() as the default implemention
references the cache manager created by createGlyphNode().  By isolating
references to the cache manager to just createDistanceFieldGlyph() cache
it becomes possible to just overwrite createGlyphNode() and still use
the default cache.

Change-Id: I7261bdbf247966b55512d2671e2ee85239bcca05
Reviewed-by: Yoann Lopes <yoann.lopes@nokia.com>
  • Loading branch information
Andrew den Exter authored and Qt by Nokia committed Mar 20, 2012
1 parent e20c351 commit dfdea38
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 83 deletions.
5 changes: 2 additions & 3 deletions src/quick/scenegraph/qsgadaptationlayer.cpp
Expand Up @@ -222,7 +222,7 @@ void QSGDistanceFieldGlyphCache::setGlyphsPosition(const QList<GlyphPosition> &g
}

if (!invalidatedGlyphs.isEmpty()) {
QLinkedList<QSGDistanceFieldGlyphNode *>::iterator it = m_registeredNodes.begin();
QLinkedList<QSGDistanceFieldGlyphConsumer *>::iterator it = m_registeredNodes.begin();
while (it != m_registeredNodes.end()) {
(*it)->invalidateGlyphs(invalidatedGlyphs);
++it;
Expand Down Expand Up @@ -268,7 +268,7 @@ void QSGDistanceFieldGlyphCache::setGlyphsTexture(const QVector<glyph_t> &glyphs
}

if (!invalidatedGlyphs.isEmpty()) {
QLinkedList<QSGDistanceFieldGlyphNode *>::iterator it = m_registeredNodes.begin();
QLinkedList<QSGDistanceFieldGlyphConsumer*>::iterator it = m_registeredNodes.begin();
while (it != m_registeredNodes.end()) {
(*it)->invalidateGlyphs(invalidatedGlyphs);
++it;
Expand Down Expand Up @@ -296,5 +296,4 @@ void QSGDistanceFieldGlyphCache::updateTexture(GLuint oldTex, GLuint newTex, con
}
}


QT_END_NAMESPACE
14 changes: 11 additions & 3 deletions src/quick/scenegraph/qsgadaptationlayer_p.h
Expand Up @@ -134,6 +134,14 @@ class Q_QUICK_EXPORT QSGGlyphNode : public QSGGeometryNode
QQuickItem *m_ownerElement;
};

class Q_QUICK_EXPORT QSGDistanceFieldGlyphConsumer
{
public:
virtual ~QSGDistanceFieldGlyphConsumer() {}

virtual void invalidateGlyphs(const QVector<quint32> &glyphs) = 0;
};

class Q_QUICK_EXPORT QSGDistanceFieldGlyphCache
{
public:
Expand Down Expand Up @@ -195,8 +203,8 @@ class Q_QUICK_EXPORT QSGDistanceFieldGlyphCache

void update();

void registerGlyphNode(QSGDistanceFieldGlyphNode *node) { m_registeredNodes.append(node); }
void unregisterGlyphNode(QSGDistanceFieldGlyphNode *node) { m_registeredNodes.removeOne(node); }
void registerGlyphNode(QSGDistanceFieldGlyphConsumer *node) { m_registeredNodes.append(node); }
void unregisterGlyphNode(QSGDistanceFieldGlyphConsumer *node) { m_registeredNodes.removeOne(node); }

virtual void registerOwnerElement(QQuickItem *ownerElement);
virtual void unregisterOwnerElement(QQuickItem *ownerElement);
Expand Down Expand Up @@ -247,7 +255,7 @@ class Q_QUICK_EXPORT QSGDistanceFieldGlyphCache
QList<Texture> m_textures;
QHash<glyph_t, GlyphData> m_glyphsData;
QDataBuffer<glyph_t> m_pendingGlyphs;
QLinkedList<QSGDistanceFieldGlyphNode*> m_registeredNodes;
QLinkedList<QSGDistanceFieldGlyphConsumer*> m_registeredNodes;

static Texture s_emptyTexture;
};
Expand Down
98 changes: 55 additions & 43 deletions src/quick/scenegraph/qsgcontext.cpp
Expand Up @@ -97,6 +97,11 @@ class QSGContextPrivate : public QObjectPrivate
QSGContextPrivate()
: gl(0)
, distanceFieldCacheManager(0)
#ifndef QT_OPENGL_ES
, distanceFieldAntialiasing(QSGGlyphNode::HighQualitySubPixelAntialiasing)
#else
, distanceFieldAntialiasing(QSGGlyphNode::GrayAntialiasing)
#endif
, flashMode(qmlFlashMode())
, distanceFieldDisabled(qmlDisableDistanceField())
{
Expand All @@ -115,6 +120,8 @@ class QSGContextPrivate : public QObjectPrivate

QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager;

QSGDistanceFieldGlyphNode::AntialiasingMode distanceFieldAntialiasing;

bool flashMode;
float renderAlpha;
bool distanceFieldDisabled;
Expand Down Expand Up @@ -142,6 +149,17 @@ class QSGTextureCleanupEvent : public QEvent
QSGContext::QSGContext(QObject *parent) :
QObject(*(new QSGContextPrivate), parent)
{
Q_D(QSGContext);
// ### Do something with these before final release...
static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing"));
static bool doLowQualSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing-lowq"));
static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing"));
if (doSubpixel)
d->distanceFieldAntialiasing = QSGGlyphNode::HighQualitySubPixelAntialiasing;
else if (doLowQualSubpixel)
d->distanceFieldAntialiasing = QSGGlyphNode::LowQualitySubPixelAntialiasing;
else if (doGray)
d->distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing;
}


Expand Down Expand Up @@ -271,39 +289,47 @@ QSGImageNode *QSGContext::createImageNode()
/*!
Factory function for scene graph backends of the distance-field glyph cache.
*/
QSGDistanceFieldGlyphCache *QSGContext::createDistanceFieldGlyphCache(const QRawFont &font)
QSGDistanceFieldGlyphCache *QSGContext::distanceFieldGlyphCache(const QRawFont &font)
{
Q_D(QSGContext);

QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
if (platformIntegration != 0
&& platformIntegration->hasCapability(QPlatformIntegration::SharedGraphicsCache)) {
QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
if (!fe->faceId().filename.isEmpty()) {
QByteArray keyName = fe->faceId().filename;
if (font.style() != QFont::StyleNormal)
keyName += QByteArray(" I");
if (font.weight() != QFont::Normal)
keyName += " " + QByteArray::number(font.weight());
keyName += QByteArray(" DF");
QPlatformSharedGraphicsCache *sharedGraphicsCache =
platformIntegration->createPlatformSharedGraphicsCache(keyName);

if (sharedGraphicsCache != 0) {
sharedGraphicsCache->ensureCacheInitialized(keyName,
QPlatformSharedGraphicsCache::OpenGLTexture,
QPlatformSharedGraphicsCache::Alpha8);

return new QSGSharedDistanceFieldGlyphCache(keyName,
sharedGraphicsCache,
d->distanceFieldCacheManager,
glContext(),
font);
if (!d->distanceFieldCacheManager)
d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager;

QSGDistanceFieldGlyphCache *cache = d->distanceFieldCacheManager->cache(font);
if (!cache) {
QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
if (platformIntegration != 0
&& platformIntegration->hasCapability(QPlatformIntegration::SharedGraphicsCache)) {
QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
if (!fe->faceId().filename.isEmpty()) {
QByteArray keyName = fe->faceId().filename;
if (font.style() != QFont::StyleNormal)
keyName += QByteArray(" I");
if (font.weight() != QFont::Normal)
keyName += " " + QByteArray::number(font.weight());
keyName += QByteArray(" DF");
QPlatformSharedGraphicsCache *sharedGraphicsCache =
platformIntegration->createPlatformSharedGraphicsCache(keyName);

if (sharedGraphicsCache != 0) {
sharedGraphicsCache->ensureCacheInitialized(keyName,
QPlatformSharedGraphicsCache::OpenGLTexture,
QPlatformSharedGraphicsCache::Alpha8);

cache = new QSGSharedDistanceFieldGlyphCache(keyName,
sharedGraphicsCache,
d->distanceFieldCacheManager,
glContext(),
font);
}
}
}
if (!cache)
cache = new QSGDefaultDistanceFieldGlyphCache(d->distanceFieldCacheManager, glContext(), font);
d->distanceFieldCacheManager->insertCache(font, cache);
}

return new QSGDefaultDistanceFieldGlyphCache(d->distanceFieldCacheManager, glContext(), font);
return cache;
}

/*!
Expand All @@ -313,25 +339,11 @@ 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 doLowQualSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing-lowq"));
static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing"));

if (d->distanceFieldDisabled) {
return new QSGDefaultGlyphNode;
} else {
if (!d->distanceFieldCacheManager) {
d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager(this);
if (doSubpixel)
d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::HighQualitySubPixelAntialiasing);
else if (doLowQualSubpixel)
d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::LowQualitySubPixelAntialiasing);
else if (doGray)
d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
}

QSGGlyphNode *node = new QSGDistanceFieldGlyphNode(d->distanceFieldCacheManager);
QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(this);
node->setPreferredAntialiasingMode(d->distanceFieldAntialiasing);
return node;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/quick/scenegraph/qsgcontext_p.h
Expand Up @@ -95,7 +95,7 @@ class Q_QUICK_EXPORT QSGContext : public QObject

virtual void renderNextFrame(QSGRenderer *renderer, GLuint fboId);

virtual QSGDistanceFieldGlyphCache *createDistanceFieldGlyphCache(const QRawFont &font);
virtual QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font);

virtual QSGRectangleNode *createRectangleNode();
virtual QSGImageNode *createImageNode();
Expand Down
11 changes: 5 additions & 6 deletions src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
Expand Up @@ -46,9 +46,9 @@

QT_BEGIN_NAMESPACE

QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode(QSGDistanceFieldGlyphCacheManager *cacheManager)
: m_material(0)
, m_glyph_cacheManager(cacheManager)
QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode(QSGContext *context)
: m_context(context)
, m_material(0)
, m_glyph_cache(0)
, m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0)
, m_style(QQuickText::Normal)
Expand All @@ -59,7 +59,6 @@ QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode(QSGDistanceFieldGlyphCacheM
{
m_geometry.setDrawingMode(GL_TRIANGLES);
setGeometry(&m_geometry);
setPreferredAntialiasingMode(cacheManager->defaultAntialiasingMode());
setFlag(UsePreprocess);
#ifdef QML_RUNTIME_TESTING
description = QLatin1String("glyphs");
Expand Down Expand Up @@ -108,7 +107,7 @@ void QSGDistanceFieldGlyphNode::setGlyphs(const QPointF &position, const QGlyphR
m_glyphs = glyphs;

QSGDistanceFieldGlyphCache *oldCache = m_glyph_cache;
m_glyph_cache = m_glyph_cacheManager->cache(m_glyphs.rawFont());
m_glyph_cache = m_context->distanceFieldGlyphCache(m_glyphs.rawFont());
if (m_glyph_cache != oldCache) {
Q_ASSERT(ownerElement() != 0);
if (oldCache) {
Expand Down Expand Up @@ -290,7 +289,7 @@ void QSGDistanceFieldGlyphNode::updateGeometry()
while (ite != glyphsInOtherTextures.constEnd()) {
QHash<const QSGDistanceFieldGlyphCache::Texture *, QSGDistanceFieldGlyphNode *>::iterator subIt = m_subNodes.find(ite.key());
if (subIt == m_subNodes.end()) {
QSGDistanceFieldGlyphNode *subNode = new QSGDistanceFieldGlyphNode(m_glyph_cacheManager);
QSGDistanceFieldGlyphNode *subNode = new QSGDistanceFieldGlyphNode(m_context);
subNode->setOwnerElement(m_ownerElement);
subNode->setColor(m_color);
subNode->setStyle(m_style);
Expand Down
7 changes: 4 additions & 3 deletions src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
Expand Up @@ -51,12 +51,13 @@ QT_BEGIN_HEADER

QT_BEGIN_NAMESPACE

class QSGContext;
class QSGDistanceFieldGlyphCacheManager;
class QSGDistanceFieldTextMaterial;
class QSGDistanceFieldGlyphNode: public QSGGlyphNode
class QSGDistanceFieldGlyphNode: public QSGGlyphNode, public QSGDistanceFieldGlyphConsumer
{
public:
QSGDistanceFieldGlyphNode(QSGDistanceFieldGlyphCacheManager *cacheManager);
QSGDistanceFieldGlyphNode(QSGContext *context);
~QSGDistanceFieldGlyphNode();

virtual QPointF baseLine() const { return m_baseLine; }
Expand All @@ -80,11 +81,11 @@ class QSGDistanceFieldGlyphNode: public QSGGlyphNode

QColor m_color;
QPointF m_baseLine;
QSGContext *m_context;
QSGDistanceFieldTextMaterial *m_material;
QPointF m_originalPosition;
QPointF m_position;
QGlyphRun m_glyphs;
QSGDistanceFieldGlyphCacheManager *m_glyph_cacheManager;
QSGDistanceFieldGlyphCache *m_glyph_cache;
QSGGeometry m_geometry;
QQuickText::TextStyle m_style;
Expand Down
12 changes: 6 additions & 6 deletions src/quick/scenegraph/qsgdistancefieldglyphnode_p_p.h
Expand Up @@ -48,7 +48,7 @@

QT_BEGIN_NAMESPACE

class QSGDistanceFieldTextMaterial: public QSGMaterial
class Q_QUICK_EXPORT QSGDistanceFieldTextMaterial: public QSGMaterial
{
public:
QSGDistanceFieldTextMaterial();
Expand Down Expand Up @@ -82,7 +82,7 @@ class QSGDistanceFieldTextMaterial: public QSGMaterial
qreal m_fontScale;
};

class QSGDistanceFieldStyledTextMaterial : public QSGDistanceFieldTextMaterial
class Q_QUICK_EXPORT QSGDistanceFieldStyledTextMaterial : public QSGDistanceFieldTextMaterial
{
public:
QSGDistanceFieldStyledTextMaterial();
Expand All @@ -99,7 +99,7 @@ class QSGDistanceFieldStyledTextMaterial : public QSGDistanceFieldTextMaterial
QColor m_styleColor;
};

class QSGDistanceFieldOutlineTextMaterial : public QSGDistanceFieldStyledTextMaterial
class Q_QUICK_EXPORT QSGDistanceFieldOutlineTextMaterial : public QSGDistanceFieldStyledTextMaterial
{
public:
QSGDistanceFieldOutlineTextMaterial();
Expand All @@ -109,7 +109,7 @@ class QSGDistanceFieldOutlineTextMaterial : public QSGDistanceFieldStyledTextMat
virtual QSGMaterialShader *createShader() const;
};

class QSGDistanceFieldShiftedStyleTextMaterial : public QSGDistanceFieldStyledTextMaterial
class Q_QUICK_EXPORT QSGDistanceFieldShiftedStyleTextMaterial : public QSGDistanceFieldStyledTextMaterial
{
public:
QSGDistanceFieldShiftedStyleTextMaterial();
Expand All @@ -125,14 +125,14 @@ class QSGDistanceFieldShiftedStyleTextMaterial : public QSGDistanceFieldStyledTe
QPointF m_shift;
};

class QSGHiQSubPixelDistanceFieldTextMaterial : public QSGDistanceFieldTextMaterial
class Q_QUICK_EXPORT QSGHiQSubPixelDistanceFieldTextMaterial : public QSGDistanceFieldTextMaterial
{
public:
virtual QSGMaterialType *type() const;
virtual QSGMaterialShader *createShader() const;
};

class QSGLoQSubPixelDistanceFieldTextMaterial : public QSGDistanceFieldTextMaterial
class Q_QUICK_EXPORT QSGLoQSubPixelDistanceFieldTextMaterial : public QSGDistanceFieldTextMaterial
{
public:
virtual QSGMaterialType *type() const;
Expand Down
25 changes: 13 additions & 12 deletions src/quick/scenegraph/util/qsgdistancefieldutil.cpp
Expand Up @@ -62,16 +62,10 @@ static float defaultAntialiasingSpreadFunc(float glyphScale)
return range / glyphScale;
}

QSGDistanceFieldGlyphCacheManager::QSGDistanceFieldGlyphCacheManager(QSGContext *c)
: sgCtx(c)
, m_threshold_func(defaultThresholdFunc)
QSGDistanceFieldGlyphCacheManager::QSGDistanceFieldGlyphCacheManager()
: m_threshold_func(defaultThresholdFunc)
, m_antialiasingSpread_func(defaultAntialiasingSpreadFunc)
{
#ifndef QT_OPENGL_ES
m_defaultAntialiasingMode = QSGGlyphNode::HighQualitySubPixelAntialiasing;
#else
m_defaultAntialiasingMode = QSGGlyphNode::GrayAntialiasing;
#endif
}

QSGDistanceFieldGlyphCacheManager::~QSGDistanceFieldGlyphCacheManager()
Expand All @@ -86,10 +80,17 @@ QSGDistanceFieldGlyphCache *QSGDistanceFieldGlyphCacheManager::cache(const QRawF
.arg(font.styleName())
.arg(font.weight())
.arg(font.style());
QHash<QString , QSGDistanceFieldGlyphCache *>::iterator cache = m_caches.find(key);
if (cache == m_caches.end())
cache = m_caches.insert(key, sgCtx->createDistanceFieldGlyphCache(font));
return cache.value();
return m_caches.value(key, 0);
}

void QSGDistanceFieldGlyphCacheManager::insertCache(const QRawFont &font, QSGDistanceFieldGlyphCache *cache)
{
QString key = QString::fromLatin1("%1_%2_%3_%4")
.arg(font.familyName())
.arg(font.styleName())
.arg(font.weight())
.arg(font.style());
m_caches.insert(key, cache);
}

QT_END_NAMESPACE
8 changes: 2 additions & 6 deletions src/quick/scenegraph/util/qsgdistancefieldutil_p.h
Expand Up @@ -58,13 +58,11 @@ class QSGContext;
class Q_QUICK_EXPORT QSGDistanceFieldGlyphCacheManager
{
public:
QSGDistanceFieldGlyphCacheManager(QSGContext *c);
QSGDistanceFieldGlyphCacheManager();
~QSGDistanceFieldGlyphCacheManager();

QSGDistanceFieldGlyphCache *cache(const QRawFont &font);

QSGGlyphNode::AntialiasingMode defaultAntialiasingMode() const { return m_defaultAntialiasingMode; }
void setDefaultAntialiasingMode(QSGGlyphNode::AntialiasingMode mode) { m_defaultAntialiasingMode = mode; }
void insertCache(const QRawFont &font, QSGDistanceFieldGlyphCache *cache);

ThresholdFunc thresholdFunc() const { return m_threshold_func; }
void setThresholdFunc(ThresholdFunc func) { m_threshold_func = func; }
Expand All @@ -75,8 +73,6 @@ class Q_QUICK_EXPORT QSGDistanceFieldGlyphCacheManager
private:
QHash<QString, QSGDistanceFieldGlyphCache *> m_caches;

QSGContext *sgCtx;

QSGGlyphNode::AntialiasingMode m_defaultAntialiasingMode;
ThresholdFunc m_threshold_func;
AntialiasingSpreadFunc m_antialiasingSpread_func;
Expand Down

0 comments on commit dfdea38

Please sign in to comment.