aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@nokia.com>2011-08-11 13:37:23 +0200
committerQt by Nokia <qt-info@nokia.com>2011-08-11 13:43:31 +0200
commitb3c391608c8a8abcc811adf85bf77c5b3d471cf2 (patch)
tree6a7865ed408078ef66fc4dcb7d3abe058ec27aa8
parent89b694ea15e46461aef5e1695e820582152c67c5 (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>
-rw-r--r--src/declarative/scenegraph/qsgadaptationlayer_p.h3
-rw-r--r--src/declarative/scenegraph/qsgcontext.cpp5
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp2
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp14
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp83
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphnode_p_p.h9
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;