Merge lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/no-dFdy-trunk into lp:ubuntu-ui-toolkit

Proposed by Tim Peeters
Status: Merged
Approved by: Florian Boucault
Approved revision: 1218
Merged at revision: 1217
Proposed branch: lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/no-dFdy-trunk
Merge into: lp:ubuntu-ui-toolkit
Diff against target: 316 lines (+258/-3)
6 files modified
src/Ubuntu/Components/plugin/plugin.pri (+3/-1)
src/Ubuntu/Components/plugin/plugin.qrc (+2/-0)
src/Ubuntu/Components/plugin/shaders/shape_no_dfdy.frag (+112/-0)
src/Ubuntu/Components/plugin/shaders/shapeoverlay_no_dfdy.frag (+121/-0)
src/Ubuntu/Components/plugin/ucubuntushape.cpp (+10/-1)
src/Ubuntu/Components/plugin/ucubuntushapeoverlay.cpp (+10/-1)
To merge this branch: bzr merge lp:~ubuntu-sdk-team/ubuntu-ui-toolkit/no-dFdy-trunk
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Tim Peeters Abstain
Review via email: mp+268405@code.launchpad.net

Commit message

Do not use the GL_OES_standard_derivatives extension in the emulator (and other possible unsupported platforms).

Description of the change

Do not use the GL_OES_standard_derivatives extension in the emulator (and other possible unsupported platforms).

This will make the rendering less pretty on systems that do not support the extension.

To post a comment you must log in.
Revision history for this message
Tim Peeters (tpeeters) wrote :

I discovered a problem with this MR, see this screenshot: https://www.dropbox.com/s/uy6sro2spmyiq53/Screenshot%202015-08-19%2000.32.46.png?dl=0

On the left you see the rendering without the extension (you would see that in the emulator), and on the right, the rendering with extension. The fix that we have for rendering without the extension has a shadow at the bottom of the shape that the correct one only has at the top.

Revision history for this message
Tim Peeters (tpeeters) wrote :

^The image is ugly because I made it inside a vm that scales the screen resolution, but dropbox made it even uglier. Use this link to download the png https://www.dropbox.com/s/uy6sro2spmyiq53/Screenshot%202015-08-19%2000.32.46.png?dl=1

Revision history for this message
Tim Peeters (tpeeters) wrote :

I did not yet verify that this works on the emulator and that it does not break the rendering on devices. We need to do that before landing this.

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
1218. By Tim Peeters

remove incorrect inset and dropshadow

Revision history for this message
Tim Peeters (tpeeters) wrote :

The visual issues mentioned above are now avoided by disabling inset and dropshadows when the required extension is not available.

Revision history for this message
Tim Peeters (tpeeters) :
review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/Ubuntu/Components/plugin/plugin.pri'
--- src/Ubuntu/Components/plugin/plugin.pri 2015-08-12 09:54:40 +0000
+++ src/Ubuntu/Components/plugin/plugin.pri 2015-08-19 13:59:00 +0000
@@ -143,5 +143,7 @@
143OTHER_FILES += \143OTHER_FILES += \
144 $$PWD/shaders/shape.vert \144 $$PWD/shaders/shape.vert \
145 $$PWD/shaders/shape.frag \145 $$PWD/shaders/shape.frag \
146 $$PWD/shaders/shape_no_dfdy.frag \
146 $$PWD/shaders/shapeoverlay.vert \147 $$PWD/shaders/shapeoverlay.vert \
147 $$PWD/shaders/shapeoverlay.frag148 $$PWD/shaders/shapeoverlay.frag \
149 $$PWD/shaders/shapeoverlay_no_dfdy.frag
148150
=== modified file 'src/Ubuntu/Components/plugin/plugin.qrc'
--- src/Ubuntu/Components/plugin/plugin.qrc 2014-12-01 19:26:16 +0000
+++ src/Ubuntu/Components/plugin/plugin.qrc 2015-08-19 13:59:00 +0000
@@ -1,8 +1,10 @@
1<RCC>1<RCC>
2 <qresource prefix="/uc">2 <qresource prefix="/uc">
3 <file>shaders/shape.frag</file>3 <file>shaders/shape.frag</file>
4 <file>shaders/shape_no_dfdy.frag</file>
4 <file>shaders/shape.vert</file>5 <file>shaders/shape.vert</file>
5 <file>shaders/shapeoverlay.frag</file>6 <file>shaders/shapeoverlay.frag</file>
7 <file>shaders/shapeoverlay_no_dfdy.frag</file>
6 <file>shaders/shapeoverlay.vert</file>8 <file>shaders/shapeoverlay.vert</file>
7 </qresource>9 </qresource>
8</RCC>10</RCC>
911
=== added file 'src/Ubuntu/Components/plugin/shaders/shape_no_dfdy.frag'
--- src/Ubuntu/Components/plugin/shaders/shape_no_dfdy.frag 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/shaders/shape_no_dfdy.frag 2015-08-19 13:59:00 +0000
@@ -0,0 +1,112 @@
1// Copyright © 2015 Canonical Ltd.
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU Lesser General Public License as published by
5// the Free Software Foundation; version 3.
6//
7// This program is distributed in the hope that it will be useful,
8// but WITHOUT ANY WARRANTY; without even the implied warranty of
9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10// GNU Lesser General Public License for more details.
11//
12// You should have received a copy of the GNU Lesser General Public License
13// along with this program. If not, see <http://www.gnu.org/licenses/>.
14//
15// Author: Loïc Molinari <loic.molinari@canonical.com>
16
17// Static flow control (branching on a uniform value) is fast on most GPUs (including ultra-low
18// power ones) because it allows to use the same shader execution path for an entire draw call. We
19// rely on that technique here (also known as "uber-shader" solution) to avoid the complexity of
20// dealing with a multiple shaders solution.
21// FIXME(loicm) Validate GPU behavior with regards to static flow control.
22
23uniform sampler2D shapeTexture;
24uniform sampler2D sourceTexture;
25uniform lowp vec2 opacityFactors;
26uniform lowp float dfdtFactor;
27uniform lowp float sourceOpacity;
28uniform lowp float distanceAA;
29uniform bool textured;
30uniform mediump int aspect;
31
32varying mediump vec2 shapeCoord;
33varying mediump vec4 sourceCoord;
34varying lowp vec4 backgroundColor;
35
36const mediump int FLAT = 0x08; // 1 << 3
37const mediump int INSET = 0x10; // 1 << 4
38const mediump int DROP_SHADOW = 0x20; // 1 << 5
39
40void main(void)
41{
42 lowp vec4 shapeData = texture2D(shapeTexture, shapeCoord);
43 lowp vec4 color = backgroundColor;
44
45 // FIXME(loicm) Would be better to use a bitfield but bitwise ops have only been integrated in
46 // GLSL 1.3 (OpenGL 3) and GLSL ES 3 (OpenGL ES 3).
47 if (textured) {
48 // Blend the source over the current color.
49 // FIXME(loicm) sign() is far from optimal. Call texture2D() at beginning of scope.
50 lowp vec2 axisMask = -sign((sourceCoord.zw * sourceCoord.zw) - vec2(1.0));
51 lowp float mask = clamp(axisMask.x + axisMask.y, 0.0, 1.0);
52 lowp vec4 source = texture2D(sourceTexture, sourceCoord.st) * vec4(sourceOpacity * mask);
53 color = vec4(1.0 - source.a) * color + source;
54 }
55
56 // FIXME: Workaround for systems that do not support dFdy()
57 lowp float dfdt = -0.0285;
58
59#define NO_DFDY 1
60 // only FLAT aspect is supported when the dFdy function is not available because
61 // dFdy() is used to determine on which side (top or bottom) in the shape we are.
62
63#ifndef NO_DFDY
64 if (aspect == FLAT) {
65#endif
66 // Mask the current color with an anti-aliased and resolution independent shape mask built
67 // from distance fields.
68 lowp float distanceMin = abs(dfdt) * -distanceAA + 0.5;
69 lowp float distanceMax = abs(dfdt) * distanceAA + 0.5;
70 color *= smoothstep(distanceMin, distanceMax, shapeData.b);
71#ifndef NO_DFDY
72
73 } else if (aspect == INSET) {
74 // The vertex layout of the shape is made so that the derivative is negative from top to
75 // middle and positive from middle to bottom.
76 lowp float shapeSide = dfdt * dfdtFactor <= 0.0 ? 0.0 : 1.0;
77 // Blend the shape inner shadow over the current color. The shadow color is black, its
78 // translucency is stored in the texture.
79 lowp float shadow = shapeData[int(shapeSide)];
80 color = vec4(1.0 - shadow) * color + vec4(0.0, 0.0, 0.0, shadow);
81 // Get the anti-aliased and resolution independent shape mask using distance fields.
82 lowp float distanceMin = abs(dfdt) * -distanceAA + 0.5;
83 lowp float distanceMax = abs(dfdt) * distanceAA + 0.5;
84 lowp vec2 mask = smoothstep(distanceMin, distanceMax, shapeData.ba);
85 // Get the bevel color. The bevel is made of the top mask masked with the bottom mask. A
86 // gradient from the bottom (1) to the middle (0) of the shape is used to factor out values
87 // resulting from the mask anti-aliasing. The bevel color is white with 60% opacity.
88 lowp float bevel = (mask.x * -mask.y) + mask.x; // -ab + a = a(1 - b)
89 lowp float gradient = clamp((shapeSide * -shapeCoord.t) + shapeSide, 0.0, 1.0);
90 bevel *= gradient * 0.6;
91 // Mask the current color then blend the bevel over the resulting color. We simply use
92 // additive blending since the bevel has already been masked.
93 color = (color * vec4(mask[int(shapeSide)])) + vec4(bevel);
94
95 } else if (aspect == DROP_SHADOW) {
96 // The vertex layout of the shape is made so that the derivative is negative from top to
97 // middle and positive from middle to bottom.
98 lowp int shapeSide = dfdt * dfdtFactor <= 0.0 ? 0 : 1;
99 // Get the anti-aliased and resolution independent shape mask using distance fields.
100 lowp float distanceMin = abs(dfdt) * -distanceAA + 0.5;
101 lowp float distanceMax = abs(dfdt) * distanceAA + 0.5;
102 lowp float mask = smoothstep(distanceMin, distanceMax, shapeData[shapeSide]);
103 // Get the shadow color outside of the shape mask.
104 lowp float shadow = (shapeData.b * -mask) + shapeData.b; // -ab + a = a(1 - b)
105 // Mask the current color then blend the shadow over the resulting color. We simply use
106 // additive blending since the shadow has already been masked.
107 color = (color * vec4(mask)) + vec4(0.0, 0.0, 0.0, shadow);
108 }
109#endif
110
111 gl_FragColor = color * opacityFactors.xxxy;
112}
0113
=== added file 'src/Ubuntu/Components/plugin/shaders/shapeoverlay_no_dfdy.frag'
--- src/Ubuntu/Components/plugin/shaders/shapeoverlay_no_dfdy.frag 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/shaders/shapeoverlay_no_dfdy.frag 2015-08-19 13:59:00 +0000
@@ -0,0 +1,121 @@
1// Copyright © 2015 Canonical Ltd.
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU Lesser General Public License as published by
5// the Free Software Foundation; version 3.
6//
7// This program is distributed in the hope that it will be useful,
8// but WITHOUT ANY WARRANTY; without even the implied warranty of
9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10// GNU Lesser General Public License for more details.
11//
12// You should have received a copy of the GNU Lesser General Public License
13// along with this program. If not, see <http://www.gnu.org/licenses/>.
14//
15// Author: Loïc Molinari <loic.molinari@canonical.com>
16
17// Static flow control (branching on a uniform value) is fast on most GPUs (including ultra-low
18// power ones) because it allows to use the same shader execution path for an entire draw call. We
19// rely on that technique here (also known as "uber-shader" solution) to avoid the complexity of
20// dealing with a multiple shaders solution.
21// FIXME(loicm) Validate GPU behavior with regards to static flow control.
22
23uniform sampler2D shapeTexture;
24uniform sampler2D sourceTexture;
25uniform lowp vec2 opacityFactors;
26uniform lowp float dfdtFactor;
27uniform lowp float sourceOpacity;
28uniform lowp float distanceAA;
29uniform bool textured;
30uniform mediump int aspect;
31
32varying mediump vec2 shapeCoord;
33varying mediump vec4 sourceCoord;
34varying lowp vec4 backgroundColor;
35varying mediump vec2 overlayCoord;
36varying lowp vec4 overlayColor;
37
38const mediump int FLAT = 0x08; // 1 << 3
39const mediump int INSET = 0x10; // 1 << 4
40const mediump int DROP_SHADOW = 0x20; // 1 << 5
41
42void main(void)
43{
44 lowp vec4 shapeData = texture2D(shapeTexture, shapeCoord);
45 lowp vec4 color = backgroundColor;
46
47 // FIXME(loicm) Would be better to use a bitfield but bitwise ops have only been integrated in
48 // GLSL 1.3 (OpenGL 3) and GLSL ES 3 (OpenGL ES 3).
49 if (textured) {
50 // Blend the source over the current color.
51 // FIXME(loicm) sign() is far from optimal. Call texture2D() at beginning of scope.
52 lowp vec2 axisMask = -sign((sourceCoord.zw * sourceCoord.zw) - vec2(1.0));
53 lowp float mask = clamp(axisMask.x + axisMask.y, 0.0, 1.0);
54 lowp vec4 source = texture2D(sourceTexture, sourceCoord.st) * vec4(sourceOpacity * mask);
55 color = vec4(1.0 - source.a) * color + source;
56 }
57
58 // Blend the overlay over the current color.
59 // FIXME(loicm) sign() is far from optimal.
60 lowp vec2 overlayAxisMask = -sign((overlayCoord * overlayCoord) - vec2(1.0));
61 lowp float overlayMask = clamp(overlayAxisMask.x + overlayAxisMask.y, 0.0, 1.0);
62 lowp vec4 overlay = overlayColor * vec4(overlayMask);
63 color = vec4(1.0 - overlay.a) * color + overlay;
64
65 // FIXME: Workaround for systems that do not support dFdy()
66 lowp float dfdt = -0.0285;
67
68#define NO_DFDY 1
69 // only FLAT aspect is supported when the dFdy function is not available because
70 // dFdy() is used to determine on which side (top or bottom) in the shape we are.
71
72#ifndef NO_DFDY
73 if (aspect == FLAT) {
74#endif
75 // Mask the current color with an anti-aliased and resolution independent shape mask built
76 // from distance fields.
77 lowp float distanceMin = abs(dfdt) * -distanceAA + 0.5;
78 lowp float distanceMax = abs(dfdt) * distanceAA + 0.5;
79 color *= smoothstep(distanceMin, distanceMax, shapeData.b);
80
81#ifndef NO_DFDY
82 } else if (aspect == INSET) {
83 // The vertex layout of the shape is made so that the derivative is negative from top to
84 // middle and positive from middle to bottom.
85 lowp float shapeSide = dfdt * dfdtFactor <= 0.0 ? 0.0 : 1.0;
86 // Blend the shape inner shadow over the current color. The shadow color is black, its
87 // translucency is stored in the texture.
88 lowp float shadow = shapeData[int(shapeSide)];
89 color = vec4(1.0 - shadow) * color + vec4(0.0, 0.0, 0.0, shadow);
90 // Get the anti-aliased and resolution independent shape mask using distance fields.
91 lowp float distanceMin = abs(dfdt) * -distanceAA + 0.5;
92 lowp float distanceMax = abs(dfdt) * distanceAA + 0.5;
93 lowp vec2 mask = smoothstep(distanceMin, distanceMax, shapeData.ba);
94 // Get the bevel color. The bevel is made of the top mask masked with the bottom mask. A
95 // gradient from the bottom (1) to the middle (0) of the shape is used to factor out values
96 // resulting from the mask anti-aliasing. The bevel color is white with 60% opacity.
97 lowp float bevel = (mask.x * -mask.y) + mask.x; // -ab + a = a(1 - b)
98 lowp float gradient = clamp((shapeSide * -shapeCoord.t) + shapeSide, 0.0, 1.0);
99 bevel *= gradient * 0.6;
100 // Mask the current color then blend the bevel over the resulting color. We simply use
101 // additive blending since the bevel has already been masked.
102 color = (color * vec4(mask[int(shapeSide)])) + vec4(bevel);
103
104 } else if (aspect == DROP_SHADOW) {
105 // The vertex layout of the shape is made so that the derivative is negative from top to
106 // middle and positive from middle to bottom.
107 lowp int shapeSide = dfdt * dfdtFactor <= 0.0 ? 0 : 1;
108 // Get the anti-aliased and resolution independent shape mask using distance fields.
109 lowp float distanceMin = abs(dfdt) * -distanceAA + 0.5;
110 lowp float distanceMax = abs(dfdt) * distanceAA + 0.5;
111 lowp float mask = smoothstep(distanceMin, distanceMax, shapeData[shapeSide]);
112 // Get the shadow color outside of the shape mask.
113 lowp float shadow = (shapeData.b * -mask) + shapeData.b; // -ab + a = a(1 - b)
114 // Mask the current color then blend the shadow over the resulting color. We simply use
115 // additive blending since the shadow has already been masked.
116 color = (color * vec4(mask)) + vec4(0.0, 0.0, 0.0, shadow);
117 }
118#endif
119
120 gl_FragColor = color * opacityFactors.xxxy;
121}
0122
=== modified file 'src/Ubuntu/Components/plugin/ucubuntushape.cpp'
--- src/Ubuntu/Components/plugin/ucubuntushape.cpp 2015-08-06 13:16:24 +0000
+++ src/Ubuntu/Components/plugin/ucubuntushape.cpp 2015-08-19 13:59:00 +0000
@@ -52,8 +52,17 @@
5252
53ShapeShader::ShapeShader()53ShapeShader::ShapeShader()
54{54{
55 QOpenGLContext* context = QOpenGLContext::currentContext();
55 setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/uc/shaders/shape.vert"));56 setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/uc/shaders/shape.vert"));
56 setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/uc/shaders/shape.frag"));57
58 if ( context->isOpenGLES() &&
59 !context->hasExtension(QByteArrayLiteral("GL_OES_standard_derivatives")) ) {
60 // dFdy function is not available in fragment shaders
61 qWarning() << "GL_OES_standard_derivatives not available. Using fallback shader for shape.";
62 setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/uc/shaders/shape_no_dfdy.frag"));
63 } else {
64 setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/uc/shaders/shape.frag"));
65 }
57}66}
5867
59char const* const* ShapeShader::attributeNames() const68char const* const* ShapeShader::attributeNames() const
6069
=== modified file 'src/Ubuntu/Components/plugin/ucubuntushapeoverlay.cpp'
--- src/Ubuntu/Components/plugin/ucubuntushapeoverlay.cpp 2015-04-30 19:51:26 +0000
+++ src/Ubuntu/Components/plugin/ucubuntushapeoverlay.cpp 2015-08-19 13:59:00 +0000
@@ -26,8 +26,17 @@
2626
27ShapeOverlayShader::ShapeOverlayShader()27ShapeOverlayShader::ShapeOverlayShader()
28{28{
29 QOpenGLContext* context = QOpenGLContext::currentContext();
29 setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/uc/shaders/shapeoverlay.vert"));30 setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/uc/shaders/shapeoverlay.vert"));
30 setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/uc/shaders/shapeoverlay.frag"));31
32 if ( context->isOpenGLES() &&
33 !context->hasExtension(QByteArrayLiteral("GL_OES_standard_derivatives")) ) {
34 // dFdy function is not available in fragment shaders
35 qWarning() << "GL_OES_standard_derivatives not available. Using fallback shader for shape overlay.";
36 setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/uc/shaders/shapeoverlay_no_dfdy.frag"));
37 } else {
38 setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/uc/shaders/shapeoverlay.frag"));
39 }
31}40}
3241
33char const* const* ShapeOverlayShader::attributeNames() const42char const* const* ShapeOverlayShader::attributeNames() const

Subscribers

People subscribed via source and target branches

to status/vote changes: