diff options
author | Yoann Lopes <yoann.lopes@nokia.com> | 2011-08-11 13:37:23 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-08-11 13:43:31 +0200 |
commit | b3c391608c8a8abcc811adf85bf77c5b3d471cf2 (patch) | |
tree | 6a7865ed408078ef66fc4dcb7d3abe058ec27aa8 | |
parent | 89b694ea15e46461aef5e1695e820582152c67c5 (diff) |
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 <qt_sanity_bot@ovi.com>
Reviewed-by: Yoann Lopes <yoann.lopes@nokia.com>
6 files changed, 98 insertions, 18 deletions
diff --git a/src/declarative/scenegraph/qsgadaptationlayer_p.h b/src/declarative/scenegraph/qsgadaptationlayer_p.h index 369a4af86a..7533e00278 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 ce346aa1e0..1f6f6e1e2a 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 db264bb281..73a2d2a65c 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 c087a09835..beeda1e476 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 52879d751c..4255da4fce 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<QSGDistanceFieldTextMaterial *>(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 c120ffe466..8733edf203 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; |