From: Yoann Lopes Date: Thu, 11 Aug 2011 11:37:23 +0000 (+0200) Subject: Added a faster subpixel antialiasing material for distance field text. X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=b3c391608c8a8abcc811adf85bf77c5b3d471cf2;p=konrad%2Fqtdeclarative.git Added a faster subpixel antialiasing material for distance field text. Based on two texture samples instead of five. Can be enabled with qmlscene --text-subpixel-antialiasing-lowq Change-Id: I726f73d812b93aa9ca38ce142d1e97b9a40d200a Reviewed-on: http://codereview.qt.nokia.com/2861 Reviewed-by: Qt Sanity Bot Reviewed-by: Yoann Lopes --- diff --git a/src/declarative/scenegraph/qsgadaptationlayer_p.h b/src/declarative/scenegraph/qsgadaptationlayer_p.h index 369a4af..7533e00 100644 --- a/src/declarative/scenegraph/qsgadaptationlayer_p.h +++ b/src/declarative/scenegraph/qsgadaptationlayer_p.h @@ -101,7 +101,8 @@ public: enum AntialiasingMode { GrayAntialiasing, - SubPixelAntialiasing + LowQualitySubPixelAntialiasing, + HighQualitySubPixelAntialiasing }; virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs) = 0; diff --git a/src/declarative/scenegraph/qsgcontext.cpp b/src/declarative/scenegraph/qsgcontext.cpp index ce346aa..1f6f6e1 100644 --- a/src/declarative/scenegraph/qsgcontext.cpp +++ b/src/declarative/scenegraph/qsgcontext.cpp @@ -297,6 +297,7 @@ QSGGlyphNode *QSGContext::createGlyphNode() // ### 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) { @@ -305,7 +306,9 @@ QSGGlyphNode *QSGContext::createGlyphNode() if (!d->distanceFieldCacheManager) { d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager(d->gl); if (doSubpixel) - d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::SubPixelAntialiasing); + d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::HighQualitySubPixelAntialiasing); + else if (doLowQualSubpixel) + d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::LowQualitySubPixelAntialiasing); else if (doGray) d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::GrayAntialiasing); } diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp index db264bb..73a2d2a 100644 --- a/src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp +++ b/src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp @@ -804,7 +804,7 @@ QSGDistanceFieldGlyphCacheManager::QSGDistanceFieldGlyphCacheManager(const QGLCo , m_maxTextureSize(0) { #ifndef QT_OPENGL_ES - m_defaultAntialiasingMode = QSGGlyphNode::SubPixelAntialiasing; + m_defaultAntialiasingMode = QSGGlyphNode::HighQualitySubPixelAntialiasing; #else m_defaultAntialiasingMode = QSGGlyphNode::GrayAntialiasing; #endif diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp index c087a09..beeda1e 100644 --- a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp +++ b/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp @@ -252,10 +252,18 @@ void QSGDistanceFieldGlyphNode::updateMaterial() delete m_material; if (m_style == QSGText::Normal) { - if (m_antialiasingMode == SubPixelAntialiasing) - m_material = new QSGSubPixelDistanceFieldTextMaterial; - else + switch (m_antialiasingMode) { + case HighQualitySubPixelAntialiasing: + m_material = new QSGHiQSubPixelDistanceFieldTextMaterial; + break; + case LowQualitySubPixelAntialiasing: + m_material = new QSGLoQSubPixelDistanceFieldTextMaterial; + break; + case GrayAntialiasing: + default: m_material = new QSGDistanceFieldTextMaterial; + break; + } } else { QSGDistanceFieldStyledTextMaterial *material; if (m_style == QSGText::Outline) { diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp index 52879d7..4255da4 100644 --- a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp +++ b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp @@ -499,7 +499,7 @@ QSGMaterialShader *QSGDistanceFieldShiftedStyleTextMaterial::createShader() cons } -class QSGSubPixelDistanceFieldTextMaterialShader : public QSGDistanceFieldTextMaterialShader +class QSGHiQSubPixelDistanceFieldTextMaterialShader : public QSGDistanceFieldTextMaterialShader { public: virtual void initialize(); @@ -516,7 +516,7 @@ private: int m_vecDelta_id; }; -const char *QSGSubPixelDistanceFieldTextMaterialShader::vertexShader() const { +const char *QSGHiQSubPixelDistanceFieldTextMaterialShader::vertexShader() const { return "uniform highp mat4 matrix; \n" "uniform highp vec2 textureScale; \n" @@ -548,7 +548,7 @@ const char *QSGSubPixelDistanceFieldTextMaterialShader::vertexShader() const { "}"; } -const char *QSGSubPixelDistanceFieldTextMaterialShader::fragmentShader() const { +const char *QSGHiQSubPixelDistanceFieldTextMaterialShader::fragmentShader() const { return "varying highp vec2 sampleCoord; \n" "varying highp vec3 sampleFarLeft; \n" @@ -582,7 +582,7 @@ const char *QSGSubPixelDistanceFieldTextMaterialShader::fragmentShader() const { "}"; } -//const char *QSGSubPixelDistanceFieldTextMaterialShader::fragmentShader() const { +//const char *QSGHiQSubPixelDistanceFieldTextMaterialShader::fragmentShader() const { // return // "#extension GL_OES_standard_derivatives: enable \n" // "varying highp vec2 sampleCoord; \n" @@ -604,26 +604,26 @@ const char *QSGSubPixelDistanceFieldTextMaterialShader::fragmentShader() const { // "}"; //} -void QSGSubPixelDistanceFieldTextMaterialShader::initialize() +void QSGHiQSubPixelDistanceFieldTextMaterialShader::initialize() { QSGDistanceFieldTextMaterialShader::initialize(); m_fontScale_id = program()->uniformLocation("fontScale"); m_vecDelta_id = program()->uniformLocation("vecDelta"); } -void QSGSubPixelDistanceFieldTextMaterialShader::activate() +void QSGHiQSubPixelDistanceFieldTextMaterialShader::activate() { QSGDistanceFieldTextMaterialShader::activate(); glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR); } -void QSGSubPixelDistanceFieldTextMaterialShader::deactivate() +void QSGHiQSubPixelDistanceFieldTextMaterialShader::deactivate() { QSGDistanceFieldTextMaterialShader::deactivate(); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } -void QSGSubPixelDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) +void QSGHiQSubPixelDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); QSGDistanceFieldTextMaterial *material = static_cast(newEffect); @@ -646,16 +646,77 @@ void QSGSubPixelDistanceFieldTextMaterialShader::updateState(const RenderState & QSGDistanceFieldTextMaterialShader::updateState(state, newEffect, oldEffect); } -QSGMaterialType *QSGSubPixelDistanceFieldTextMaterial::type() const +QSGMaterialType *QSGHiQSubPixelDistanceFieldTextMaterial::type() const { static QSGMaterialType type; return &type; } -QSGMaterialShader *QSGSubPixelDistanceFieldTextMaterial::createShader() const +QSGMaterialShader *QSGHiQSubPixelDistanceFieldTextMaterial::createShader() const { - return new QSGSubPixelDistanceFieldTextMaterialShader; + return new QSGHiQSubPixelDistanceFieldTextMaterialShader; } +class QSGLoQSubPixelDistanceFieldTextMaterialShader : public QSGHiQSubPixelDistanceFieldTextMaterialShader +{ +protected: + virtual const char *vertexShader() const; + virtual const char *fragmentShader() const; +}; + +const char *QSGLoQSubPixelDistanceFieldTextMaterialShader::vertexShader() const { + return + "uniform highp mat4 matrix; \n" + "uniform highp vec2 textureScale; \n" + "uniform highp float fontScale; \n" + "uniform highp vec4 vecDelta; \n" + "attribute highp vec4 vCoord; \n" + "attribute highp vec2 tCoord; \n" + "varying highp vec3 sampleNearLeft; \n" + "varying highp vec3 sampleNearRight; \n" + "void main() { \n" + " highp vec2 sampleCoord = tCoord * textureScale; \n" + " gl_Position = matrix * vCoord; \n" + // Calculate neighbour pixel position in item space. + " highp vec3 wDelta = gl_Position.w * vecDelta.xyw; \n" + " highp vec3 nearLeft = vCoord.xyw - 0.25 * wDelta; \n" + " highp vec3 nearRight = vCoord.xyw + 0.25 * wDelta; \n" + // Calculate neighbour texture coordinate. + " highp vec2 scale = textureScale / fontScale; \n" + " highp vec2 base = sampleCoord - scale * vCoord.xy; \n" + " sampleNearLeft = vec3(base * nearLeft.z + scale * nearLeft.xy, nearLeft.z); \n" + " sampleNearRight = vec3(base * nearRight.z + scale * nearRight.xy, nearRight.z); \n" + "}"; +} + +const char *QSGLoQSubPixelDistanceFieldTextMaterialShader::fragmentShader() const { + return + "varying highp vec3 sampleNearLeft; \n" + "varying highp vec3 sampleNearRight; \n" + "uniform sampler2D texture; \n" + "uniform lowp vec4 color; \n" + "uniform highp float alphaMin; \n" + "uniform highp float alphaMax; \n" + "void main() { \n" + " highp vec2 n; \n" + " n.x = texture2DProj(texture, sampleNearLeft).a; \n" + " n.y = texture2DProj(texture, sampleNearRight).a; \n" + " n = smoothstep(alphaMin, alphaMax, n); \n" + " highp float c = 0.5 * (n.x + n.y); \n" + " gl_FragColor = vec4(n.x, c, n.y, c) * color.w; \n" + "}"; +} + +QSGMaterialType *QSGLoQSubPixelDistanceFieldTextMaterial::type() const +{ + static QSGMaterialType type; + return &type; +} + +QSGMaterialShader *QSGLoQSubPixelDistanceFieldTextMaterial::createShader() const +{ + return new QSGLoQSubPixelDistanceFieldTextMaterialShader; +} + QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p_p.h b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p_p.h index c120ffe..8733edf 100644 --- a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p_p.h +++ b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p_p.h @@ -116,7 +116,14 @@ protected: QPointF m_shift; }; -class QSGSubPixelDistanceFieldTextMaterial : public QSGDistanceFieldTextMaterial +class QSGHiQSubPixelDistanceFieldTextMaterial : public QSGDistanceFieldTextMaterial +{ +public: + virtual QSGMaterialType *type() const; + virtual QSGMaterialShader *createShader() const; +}; + +class QSGLoQSubPixelDistanceFieldTextMaterial : public QSGDistanceFieldTextMaterial { public: virtual QSGMaterialType *type() const;