Work around mis-optimisation on QNX/SGX in AA vertex shader
authorSean Harmer <sean.harmer.qnx@kdab.com>
Mon, 24 Sep 2012 12:08:16 +0000 (13:08 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Wed, 26 Sep 2012 10:06:01 +0000 (12:06 +0200)
The new AA algorithm which is implemented in the vertex shader of
SmoothColorMaterialShader and SmoothTextureMaterialShader exposes
a driver bug in the glsl compiler/optimiser for the GPU used in
the BlackBerry PlayBook.

The bug results in the if (scale < 0.0) scale = 1.0 code always
being executed even when the condition is false. This leads to
massive corrupion of Image, Rectangle, and BorderImage elements
when the antialiasing property is enabled.

This commit works around the compiler bug by refactoring the
vertex shader to explicitly include an else clause. The check for
negative values is now performed on the numerator only as the
denominator is dot(dir, dir) which is always positive (square of
magnitude of dir vector).

This gives the correct behaviour on all platforms (that I have
access to).

Change-Id: I236542c9b59ff2915e95cbd9300b442be316bba9
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
src/quick/scenegraph/qsgdefaultimagenode.cpp
src/quick/scenegraph/qsgdefaultrectanglenode.cpp

index b165b2d..d9c04e1 100644 (file)
@@ -159,8 +159,12 @@ const char *SmoothTextureMaterialShader::vertexShader() const
             "        highp vec2 dir = delta.xy * pos.w - pos.xy * delta.w; \n"
             "        highp vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);  \n"
             "        dir -= ndir * delta.w * pos.w; \n"
-            "        highp float scale = min(1., dot(dir, ndir * pos.w * pos.w) / dot(dir, dir)); \n"
-            "        if (scale < 0.) scale = 1.; \n"
+            "        highp float numerator = dot(dir, ndir * pos.w * pos.w); \n"
+            "        highp float scale = 0.0; \n"
+            "        if (numerator < 0.0) \n"
+            "            scale = 1.0; \n"
+            "        else \n"
+            "            scale = min(1.0, numerator / dot(dir, dir)); \n"
             "        gl_Position += scale * delta; \n"
             "        texCoord.x += scale * texCoordOffset.x; \n"
             "    } \n"
@@ -170,8 +174,12 @@ const char *SmoothTextureMaterialShader::vertexShader() const
             "        highp vec2 dir = delta.xy * pos.w - pos.xy * delta.w; \n"
             "        highp vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);  \n"
             "        dir -= ndir * delta.w * pos.w; \n"
-            "        highp float scale = min(1., dot(dir, ndir * pos.w * pos.w) / dot(dir, dir)); \n"
-            "        if (scale < 0.) scale = 1.; \n"
+            "        highp float numerator = dot(dir, ndir * pos.w * pos.w); \n"
+            "        highp float scale = 0.0; \n"
+            "        if (numerator < 0.0) \n"
+            "            scale = 1.0; \n"
+            "        else \n"
+            "            scale = min(1.0, numerator / dot(dir, dir)); \n"
             "        gl_Position += scale * delta; \n"
             "        texCoord.y += scale * texCoordOffset.y; \n"
             "    } \n"
index 2da8e3c..dab8550 100644 (file)
@@ -175,8 +175,12 @@ const char *SmoothColorMaterialShader::vertexShader() const
             "        highp vec2 dir = delta.xy * pos.w - pos.xy * delta.w; \n"
             "        highp vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);  \n"
             "        dir -= ndir * delta.w * pos.w; \n"
-            "        highp float scale = min(1., dot(dir, ndir * pos.w * pos.w) / dot(dir, dir)); \n"
-            "        if (scale < 0.) scale = 1.; \n"
+            "        highp float numerator = dot(dir, ndir * pos.w * pos.w); \n"
+            "        highp float scale = 0.0; \n"
+            "        if (numerator < 0.0) \n"
+            "            scale = 1.0; \n"
+            "        else \n"
+            "            scale = min(1.0, numerator / dot(dir, dir)); \n"
             "        gl_Position += scale * delta; \n"
             "    } \n"
 
@@ -185,8 +189,12 @@ const char *SmoothColorMaterialShader::vertexShader() const
             "        highp vec2 dir = delta.xy * pos.w - pos.xy * delta.w; \n"
             "        highp vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);  \n"
             "        dir -= ndir * delta.w * pos.w; \n"
-            "        highp float scale = min(1., dot(dir, ndir * pos.w * pos.w) / dot(dir, dir)); \n"
-            "        if (scale < 0.) scale = 1.; \n"
+            "        highp float numerator = dot(dir, ndir * pos.w * pos.w); \n"
+            "        highp float scale = 0.0; \n"
+            "        if (numerator < 0.0) \n"
+            "            scale = 1.0; \n"
+            "        else \n"
+            "            scale = min(1.0, numerator / dot(dir, dir)); \n"
             "        gl_Position += scale * delta; \n"
             "    } \n"