Merge lp:~loic.molinari/ubuntu-ui-toolkit/uitk-quad into lp:ubuntu-ui-toolkit/staging
- uitk-quad
- Merge into staging
Status: | Work in progress |
---|---|
Proposed branch: | lp:~loic.molinari/ubuntu-ui-toolkit/uitk-quad |
Merge into: | lp:ubuntu-ui-toolkit/staging |
Diff against target: |
7380 lines (+6275/-617) 51 files modified
src/UbuntuToolkit/UbuntuToolkit.pro (+43/-8) src/UbuntuToolkit/privates/shaders/color.frag (+7/-0) src/UbuntuToolkit/privates/shaders/color.vert (+12/-0) src/UbuntuToolkit/privates/shaders/color_opaque.frag (+6/-0) src/UbuntuToolkit/privates/shaders/colormask.frag (+10/-0) src/UbuntuToolkit/privates/shaders/colormask.vert (+15/-0) src/UbuntuToolkit/privates/shaders/colormask_opaque.frag (+9/-0) src/UbuntuToolkit/privates/shaders/fillcenterborder.frag (+14/-0) src/UbuntuToolkit/privates/shaders/fillcenterborder.vert (+18/-0) src/UbuntuToolkit/privates/shaders/fillcenterborder_opaque.frag (+12/-0) src/UbuntuToolkit/privates/shaders/fillcentershadow.frag (+16/-0) src/UbuntuToolkit/privates/shaders/fillcentershadow.vert (+21/-0) src/UbuntuToolkit/privates/shaders/fillcentershadow_opaque.frag (+14/-0) src/UbuntuToolkit/privates/shaders/fillcentershadowborder.frag (+22/-0) src/UbuntuToolkit/privates/shaders/fillcentershadowborder.vert (+27/-0) src/UbuntuToolkit/privates/shaders/fillcentershadowborder_opaque.frag (+20/-0) src/UbuntuToolkit/privates/shaders/fillcornersborder.frag (+17/-0) src/UbuntuToolkit/privates/shaders/fillcornersborder.vert (+21/-0) src/UbuntuToolkit/privates/shaders/fillcornersborder_opaque.frag (+16/-0) src/UbuntuToolkit/privates/shaders/fillcornersshadow.frag (+18/-0) src/UbuntuToolkit/privates/shaders/fillcornersshadow.vert (+24/-0) src/UbuntuToolkit/privates/shaders/fillcornersshadow_opaque.frag (+17/-0) src/UbuntuToolkit/privates/shaders/fillcornersshadowborder.frag (+24/-0) src/UbuntuToolkit/privates/shaders/fillcornersshadowborder.vert (+30/-0) src/UbuntuToolkit/privates/shaders/fillcornersshadowborder_opaque.frag (+23/-0) src/UbuntuToolkit/privates/shaders/frame.frag (+10/-28) src/UbuntuToolkit/privates/shaders/frame.vert (+0/-34) src/UbuntuToolkit/privates/shaders/texture2.vert (+18/-0) src/UbuntuToolkit/privates/ucshape.cpp (+434/-0) src/UbuntuToolkit/privates/ucshape_p.h (+162/-0) src/UbuntuToolkit/privates/ucshapedropshadownodes.cpp (+175/-0) src/UbuntuToolkit/privates/ucshapedropshadownodes_p.h (+57/-0) src/UbuntuToolkit/privates/ucshapefillnodes.cpp (+1431/-0) src/UbuntuToolkit/privates/ucshapefillnodes_p.h (+999/-0) src/UbuntuToolkit/privates/ucshapeframenodes.cpp (+392/-326) src/UbuntuToolkit/privates/ucshapeframenodes_p.h (+67/-78) src/UbuntuToolkit/privates/ucshaperesources.cpp (+19/-0) src/UbuntuToolkit/privates/ucshaperesources_p.h (+285/-0) src/UbuntuToolkit/privates/ucshapetexturefactory.cpp (+728/-0) src/UbuntuToolkit/privates/ucshapetexturefactory_p.h (+142/-0) src/UbuntuToolkit/privates/ucshapeutils_p.h (+134/-0) src/UbuntuToolkit/resources.qrc (+28/-4) src/UbuntuToolkit/tools/privates/createprivateshapetextures.cpp (+0/-125) src/UbuntuToolkit/tools/privates/privates.pro (+0/-5) src/UbuntuToolkit/ubuntutoolkitmodule.cpp (+2/-2) src/UbuntuToolkit/ucbottomedge.cpp (+1/-0) src/UbuntuToolkit/ucbottomedge_p.h (+0/-2) src/UbuntuToolkit/ucbottomedgeregion.cpp (+2/-0) src/imports/Components/Themes/Ambiance/1.3/FocusShape.qml (+3/-5) tests/resources/ubuntushape/QuadTest.qml (+549/-0) tests/resources/ubuntushape/ZoomPan.qml (+181/-0) |
To merge this branch: | bzr merge lp:~loic.molinari/ubuntu-ui-toolkit/uitk-quad |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Emanuele Antonio Faraone (community) | Approve | ||
Ubuntu SDK team | Pending | ||
Review via email: mp+307535@code.launchpad.net |
Commit message
Added new nodes and item with fast and dynamic shadow rendering.
Description of the change
Added new nodes and item with fast and dynamic shadow rendering.
- 2130. By Loïc Molinari
-
Improved test.
- 2131. By Loïc Molinari
-
Renamed color to fillColor.
- 2132. By Loïc Molinari
-
Removed a bunch of useless casts.
- 2133. By Loïc Molinari
-
Removed useless RESTRICT define.
- 2134. By Loïc Molinari
-
Added aligned allocs support.
- 2135. By Loïc Molinari
-
Simplified texture factory code.
- 2136. By Loïc Molinari
-
Cleaned up texture factory.
- 2137. By Loïc Molinari
-
Clean up.
- 2138. By Loïc Molinari
-
Added inner shadow support.
- 2139. By Loïc Molinari
-
Moved fill corners to new resources arch.
- 2140. By Loïc Molinari
-
Moved drop shadow to new resources arch.
- 2141. By Loïc Molinari
-
Added fill corners shadow.
- 2142. By Loïc Molinari
-
Added initial border support.
- 2143. By Loïc Molinari
-
Fixed ZoomPan.qml.
- 2144. By Loïc Molinari
-
Cleaned up shaders.
- 2145. By Loïc Molinari
-
Made a nice Quad tweaker tool.
- 2146. By Loïc Molinari
-
Added border support to fill center nodes.
- 2147. By Loïc Molinari
-
Merged lp:ubuntu-ui-toolkit/staging.
- 2148. By Loïc Molinari
-
Added shadow border support fill corners node.
- 2149. By Loïc Molinari
-
Added border support fill corners node.
- 2150. By Loïc Molinari
-
Improved quad tdeak colors.
- 2151. By Loïc Molinari
-
Fixed Quad Tweak color picking system.
- 2152. By Loïc Molinari
-
Fixed and cleaned up mask texture creation when radius=0.
- 2153. By Loïc Molinari
-
Reverted to 0 default radius in quad tweak.
- 2154. By Loïc Molinari
-
Cleaned up shadow texture creation code.
- 2155. By Loïc Molinari
-
Shadow texture fixes.
- 2156. By Loïc Molinari
-
Fixed 0 radius and shadow size issues.
- 2157. By Loïc Molinari
-
Fixed drop shadow visiblity states.
- 2158. By Loïc Molinari
-
Replaced shadow blur with extended box filtering algorithm.
- 2159. By Loïc Molinari
-
Cleaned up alignment strategies.
Emanuele Antonio Faraone (emanueleant03) : | # |
Unmerged revisions
- 2159. By Loïc Molinari
-
Cleaned up alignment strategies.
- 2158. By Loïc Molinari
-
Replaced shadow blur with extended box filtering algorithm.
- 2157. By Loïc Molinari
-
Fixed drop shadow visiblity states.
- 2156. By Loïc Molinari
-
Fixed 0 radius and shadow size issues.
- 2155. By Loïc Molinari
-
Shadow texture fixes.
- 2154. By Loïc Molinari
-
Cleaned up shadow texture creation code.
- 2153. By Loïc Molinari
-
Reverted to 0 default radius in quad tweak.
- 2152. By Loïc Molinari
-
Fixed and cleaned up mask texture creation when radius=0.
- 2151. By Loïc Molinari
-
Fixed Quad Tweak color picking system.
- 2150. By Loïc Molinari
-
Improved quad tdeak colors.
Preview Diff
1 | === modified file 'src/UbuntuToolkit/UbuntuToolkit.pro' |
2 | --- src/UbuntuToolkit/UbuntuToolkit.pro 2016-11-04 09:37:32 +0000 |
3 | +++ src/UbuntuToolkit/UbuntuToolkit.pro 2016-12-14 07:25:05 +0000 |
4 | @@ -45,13 +45,19 @@ |
5 | $$PWD/mousetouchadaptor_p.h \ |
6 | $$PWD/mousetouchadaptor_p_p.h \ |
7 | $$PWD/privates/appheaderbase_p.h \ |
8 | - $$PWD/privates/frame_p.h \ |
9 | $$PWD/privates/listitemdragarea_p.h \ |
10 | $$PWD/privates/listitemdraghandler_p.h \ |
11 | $$PWD/privates/listitemselection_p.h \ |
12 | $$PWD/privates/listviewextensions_p.h \ |
13 | $$PWD/privates/splitviewhandler_p.h \ |
14 | $$PWD/privates/threelabelsslot_p.h \ |
15 | + $$PWD/privates/ucshape_p.h \ |
16 | + $$PWD/privates/ucshapedropshadownodes_p.h \ |
17 | + $$PWD/privates/ucshapefillnodes_p.h \ |
18 | + $$PWD/privates/ucshapeframenodes_p.h \ |
19 | + $$PWD/privates/ucshaperesources_p.h \ |
20 | + $$PWD/privates/ucshapetexturefactory_p.h \ |
21 | + $$PWD/privates/ucshapeutils_p.h \ |
22 | $$PWD/privates/ucpagewrapper_p.h \ |
23 | $$PWD/privates/ucpagewrapper_p_p.h \ |
24 | $$PWD/privates/ucpagewrapperincubator_p.h \ |
25 | @@ -155,7 +161,6 @@ |
26 | $$PWD/menugroup.cpp \ |
27 | $$PWD/mousetouchadaptor.cpp \ |
28 | $$PWD/privates/appheaderbase.cpp \ |
29 | - $$PWD/privates/frame.cpp \ |
30 | $$PWD/privates/listitemdragarea.cpp \ |
31 | $$PWD/privates/listitemdraghandler.cpp \ |
32 | $$PWD/privates/listitemexpansion.cpp \ |
33 | @@ -163,6 +168,12 @@ |
34 | $$PWD/privates/listviewextensions.cpp \ |
35 | $$PWD/privates/splitviewhandler.cpp \ |
36 | $$PWD/privates/threelabelsslot_p.cpp \ |
37 | + $$PWD/privates/ucshape.cpp \ |
38 | + $$PWD/privates/ucshapedropshadownodes.cpp \ |
39 | + $$PWD/privates/ucshapefillnodes.cpp \ |
40 | + $$PWD/privates/ucshapeframenodes.cpp \ |
41 | + $$PWD/privates/ucshaperesources.cpp \ |
42 | + $$PWD/privates/ucshapetexturefactory.cpp \ |
43 | $$PWD/privates/ucpagewrapper.cpp \ |
44 | $$PWD/privates/ucpagewrapperincubator.cpp \ |
45 | $$PWD/privates/ucscrollbarutils.cpp \ |
46 | @@ -231,13 +242,37 @@ |
47 | $$PWD/resources.qrc |
48 | |
49 | OTHER_FILES += \ |
50 | + $$PWD/privates/shaders/color.frag \ |
51 | + $$PWD/privates/shaders/color.vert \ |
52 | + $$PWD/privates/shaders/color_opaque.frag \ |
53 | + $$PWD/privates/shaders/colormask.frag \ |
54 | + $$PWD/privates/shaders/colormask.vert \ |
55 | + $$PWD/privates/shaders/colormask_opaque.frag \ |
56 | + $$PWD/privates/shaders/fillcenterborder.frag \ |
57 | + $$PWD/privates/shaders/fillcenterborder.vert \ |
58 | + $$PWD/privates/shaders/fillcenterborder_opaque.frag \ |
59 | + $$PWD/privates/shaders/fillcentershadow.frag \ |
60 | + $$PWD/privates/shaders/fillcentershadow.vert \ |
61 | + $$PWD/privates/shaders/fillcentershadow_opaque.frag \ |
62 | + $$PWD/privates/shaders/fillcentershadowborder.frag \ |
63 | + $$PWD/privates/shaders/fillcentershadowborder.vert \ |
64 | + $$PWD/privates/shaders/fillcentershadowborder_opaque.frag \ |
65 | + $$PWD/privates/shaders/fillcornersborder.frag \ |
66 | + $$PWD/privates/shaders/fillcornersborder.vert \ |
67 | + $$PWD/privates/shaders/fillcornersborder_opaque.frag \ |
68 | + $$PWD/privates/shaders/fillcornersshadow.frag \ |
69 | + $$PWD/privates/shaders/fillcornersshadow.vert \ |
70 | + $$PWD/privates/shaders/fillcornersshadow_opaque.frag \ |
71 | + $$PWD/privates/shaders/fillcornersshadowborder.frag \ |
72 | + $$PWD/privates/shaders/fillcornersshadowborder.vert \ |
73 | + $$PWD/privates/shaders/fillcornersshadowborder_opaque.frag \ |
74 | + $$PWD/privates/shaders/frame.frag \ |
75 | + $$PWD/privates/shaders/texture2.vert \ |
76 | + $$PWD/shaders/shape.frag \ |
77 | $$PWD/shaders/shape.vert \ |
78 | - $$PWD/shaders/shape.frag \ |
79 | - $$PWD/shaders/shape_no_dfdy.frag \ |
80 | + $$PWD/shaders/shape_mipmap.frag \ |
81 | + $$PWD/shaders/shapeoverlay.frag \ |
82 | $$PWD/shaders/shapeoverlay.vert \ |
83 | - $$PWD/shaders/shapeoverlay.frag \ |
84 | - $$PWD/shaders/shapeoverlay_no_dfdy.frag \ |
85 | - $$PWD/privates/shaders/frame.vert \ |
86 | - $$PWD/privates/shaders/frame.frag |
87 | + $$PWD/shaders/shapeoverlay_mipmap.frag |
88 | |
89 | load(ubuntu_qt_module) |
90 | |
91 | === added file 'src/UbuntuToolkit/privates/shaders/color.frag' |
92 | --- src/UbuntuToolkit/privates/shaders/color.frag 1970-01-01 00:00:00 +0000 |
93 | +++ src/UbuntuToolkit/privates/shaders/color.frag 2016-12-14 07:25:05 +0000 |
94 | @@ -0,0 +1,7 @@ |
95 | +uniform lowp float opacity; |
96 | +varying lowp vec4 color; |
97 | + |
98 | +void main() |
99 | +{ |
100 | + gl_FragColor = vec4(opacity) * color; |
101 | +} |
102 | |
103 | === added file 'src/UbuntuToolkit/privates/shaders/color.vert' |
104 | --- src/UbuntuToolkit/privates/shaders/color.vert 1970-01-01 00:00:00 +0000 |
105 | +++ src/UbuntuToolkit/privates/shaders/color.vert 2016-12-14 07:25:05 +0000 |
106 | @@ -0,0 +1,12 @@ |
107 | +uniform highp mat4 matrix; |
108 | + |
109 | +attribute highp vec4 positionAttrib; |
110 | +attribute lowp vec4 colorAttrib; |
111 | + |
112 | +varying lowp vec4 color; |
113 | + |
114 | +void main() |
115 | +{ |
116 | + color = colorAttrib; |
117 | + gl_Position = matrix * positionAttrib; |
118 | +} |
119 | |
120 | === added file 'src/UbuntuToolkit/privates/shaders/color_opaque.frag' |
121 | --- src/UbuntuToolkit/privates/shaders/color_opaque.frag 1970-01-01 00:00:00 +0000 |
122 | +++ src/UbuntuToolkit/privates/shaders/color_opaque.frag 2016-12-14 07:25:05 +0000 |
123 | @@ -0,0 +1,6 @@ |
124 | +varying lowp vec4 color; |
125 | + |
126 | +void main() |
127 | +{ |
128 | + gl_FragColor = color; |
129 | +} |
130 | |
131 | === added file 'src/UbuntuToolkit/privates/shaders/colormask.frag' |
132 | --- src/UbuntuToolkit/privates/shaders/colormask.frag 1970-01-01 00:00:00 +0000 |
133 | +++ src/UbuntuToolkit/privates/shaders/colormask.frag 2016-12-14 07:25:05 +0000 |
134 | @@ -0,0 +1,10 @@ |
135 | +uniform sampler2D maskTexture; |
136 | +uniform lowp float opacity; |
137 | + |
138 | +varying mediump vec2 maskCoord; |
139 | +varying lowp vec4 color; |
140 | + |
141 | +void main() |
142 | +{ |
143 | + gl_FragColor = color * vec4(texture2D(maskTexture, maskCoord).r * opacity); |
144 | +} |
145 | |
146 | === added file 'src/UbuntuToolkit/privates/shaders/colormask.vert' |
147 | --- src/UbuntuToolkit/privates/shaders/colormask.vert 1970-01-01 00:00:00 +0000 |
148 | +++ src/UbuntuToolkit/privates/shaders/colormask.vert 2016-12-14 07:25:05 +0000 |
149 | @@ -0,0 +1,15 @@ |
150 | +uniform highp mat4 matrix; |
151 | + |
152 | +attribute highp vec4 positionAttrib; |
153 | +attribute mediump vec2 maskCoordAttrib; |
154 | +attribute lowp vec4 colorAttrib; |
155 | + |
156 | +varying mediump vec2 maskCoord; |
157 | +varying lowp vec4 color; |
158 | + |
159 | +void main() |
160 | +{ |
161 | + maskCoord = maskCoordAttrib; |
162 | + color = colorAttrib; |
163 | + gl_Position = matrix * positionAttrib; |
164 | +} |
165 | |
166 | === added file 'src/UbuntuToolkit/privates/shaders/colormask_opaque.frag' |
167 | --- src/UbuntuToolkit/privates/shaders/colormask_opaque.frag 1970-01-01 00:00:00 +0000 |
168 | +++ src/UbuntuToolkit/privates/shaders/colormask_opaque.frag 2016-12-14 07:25:05 +0000 |
169 | @@ -0,0 +1,9 @@ |
170 | +uniform sampler2D maskTexture; |
171 | + |
172 | +varying mediump vec2 maskCoord; |
173 | +varying lowp vec4 color; |
174 | + |
175 | +void main() |
176 | +{ |
177 | + gl_FragColor = color * vec4(texture2D(maskTexture, maskCoord).r); |
178 | +} |
179 | |
180 | === added file 'src/UbuntuToolkit/privates/shaders/fillcenterborder.frag' |
181 | --- src/UbuntuToolkit/privates/shaders/fillcenterborder.frag 1970-01-01 00:00:00 +0000 |
182 | +++ src/UbuntuToolkit/privates/shaders/fillcenterborder.frag 2016-12-14 07:25:05 +0000 |
183 | @@ -0,0 +1,14 @@ |
184 | +uniform sampler2D borderTexture; |
185 | +uniform lowp float opacity; |
186 | + |
187 | +varying mediump vec2 borderCoord; |
188 | +varying lowp vec4 color; |
189 | +varying lowp vec4 borderColor; |
190 | + |
191 | +void main() |
192 | +{ |
193 | + lowp float borderCoverage = 1.0 - texture2D(borderTexture, borderCoord).r; |
194 | + lowp vec4 border = borderColor * vec4(borderCoverage); |
195 | + lowp vec4 blend = border + (vec4(1.0 - border.a) * color); |
196 | + gl_FragColor = blend * vec4(opacity); |
197 | +} |
198 | |
199 | === added file 'src/UbuntuToolkit/privates/shaders/fillcenterborder.vert' |
200 | --- src/UbuntuToolkit/privates/shaders/fillcenterborder.vert 1970-01-01 00:00:00 +0000 |
201 | +++ src/UbuntuToolkit/privates/shaders/fillcenterborder.vert 2016-12-14 07:25:05 +0000 |
202 | @@ -0,0 +1,18 @@ |
203 | +uniform highp mat4 matrix; |
204 | + |
205 | +attribute highp vec4 positionAttrib; |
206 | +attribute mediump vec2 borderCoordAttrib; |
207 | +attribute lowp vec4 colorAttrib; |
208 | +attribute lowp vec4 borderColorAttrib; |
209 | + |
210 | +varying mediump vec2 borderCoord; |
211 | +varying lowp vec4 color; |
212 | +varying lowp vec4 borderColor; |
213 | + |
214 | +void main() |
215 | +{ |
216 | + borderCoord = borderCoordAttrib; |
217 | + color = colorAttrib; |
218 | + borderColor = borderColorAttrib; |
219 | + gl_Position = matrix * positionAttrib; |
220 | +} |
221 | |
222 | === added file 'src/UbuntuToolkit/privates/shaders/fillcenterborder_opaque.frag' |
223 | --- src/UbuntuToolkit/privates/shaders/fillcenterborder_opaque.frag 1970-01-01 00:00:00 +0000 |
224 | +++ src/UbuntuToolkit/privates/shaders/fillcenterborder_opaque.frag 2016-12-14 07:25:05 +0000 |
225 | @@ -0,0 +1,12 @@ |
226 | +uniform sampler2D borderTexture; |
227 | + |
228 | +varying mediump vec2 borderCoord; |
229 | +varying lowp vec4 color; |
230 | +varying lowp vec4 borderColor; |
231 | + |
232 | +void main() |
233 | +{ |
234 | + lowp float borderCoverage = 1.0 - texture2D(borderTexture, borderCoord).r; |
235 | + lowp vec4 border = borderColor * vec4(borderCoverage); |
236 | + gl_FragColor = border + (vec4(1.0 - border.a) * color); |
237 | +} |
238 | |
239 | === added file 'src/UbuntuToolkit/privates/shaders/fillcentershadow.frag' |
240 | --- src/UbuntuToolkit/privates/shaders/fillcentershadow.frag 1970-01-01 00:00:00 +0000 |
241 | +++ src/UbuntuToolkit/privates/shaders/fillcentershadow.frag 2016-12-14 07:25:05 +0000 |
242 | @@ -0,0 +1,16 @@ |
243 | +uniform sampler2D shadowTexture; |
244 | +uniform lowp float opacity; |
245 | + |
246 | +varying mediump vec2 shadowCoord; |
247 | +varying mediump vec2 midShadowCoord; |
248 | +varying lowp vec4 color; |
249 | +varying lowp vec4 shadowColor; |
250 | + |
251 | +void main() |
252 | +{ |
253 | + mediump vec2 shadowTextureCoord = midShadowCoord - abs(shadowCoord - midShadowCoord); |
254 | + lowp float shadowCoverage = 1.0 - texture2D(shadowTexture, shadowTextureCoord).r; |
255 | + lowp vec4 shadow = shadowColor * vec4(shadowCoverage); |
256 | + lowp vec4 blend = shadow + (vec4(1.0 - shadow.a) * color); |
257 | + gl_FragColor = blend * vec4(opacity); |
258 | +} |
259 | |
260 | === added file 'src/UbuntuToolkit/privates/shaders/fillcentershadow.vert' |
261 | --- src/UbuntuToolkit/privates/shaders/fillcentershadow.vert 1970-01-01 00:00:00 +0000 |
262 | +++ src/UbuntuToolkit/privates/shaders/fillcentershadow.vert 2016-12-14 07:25:05 +0000 |
263 | @@ -0,0 +1,21 @@ |
264 | +uniform highp mat4 matrix; |
265 | + |
266 | +attribute highp vec4 positionAttrib; |
267 | +attribute mediump vec2 shadowCoordAttrib; |
268 | +attribute mediump vec2 midShadowCoordAttrib; |
269 | +attribute lowp vec4 colorAttrib; |
270 | +attribute lowp vec4 shadowColorAttrib; |
271 | + |
272 | +varying mediump vec2 shadowCoord; |
273 | +varying mediump vec2 midShadowCoord; |
274 | +varying lowp vec4 color; |
275 | +varying lowp vec4 shadowColor; |
276 | + |
277 | +void main() |
278 | +{ |
279 | + shadowCoord = shadowCoordAttrib; |
280 | + midShadowCoord = midShadowCoordAttrib; |
281 | + color = colorAttrib; |
282 | + shadowColor = shadowColorAttrib; |
283 | + gl_Position = matrix * positionAttrib; |
284 | +} |
285 | |
286 | === added file 'src/UbuntuToolkit/privates/shaders/fillcentershadow_opaque.frag' |
287 | --- src/UbuntuToolkit/privates/shaders/fillcentershadow_opaque.frag 1970-01-01 00:00:00 +0000 |
288 | +++ src/UbuntuToolkit/privates/shaders/fillcentershadow_opaque.frag 2016-12-14 07:25:05 +0000 |
289 | @@ -0,0 +1,14 @@ |
290 | +uniform sampler2D shadowTexture; |
291 | + |
292 | +varying mediump vec2 shadowCoord; |
293 | +varying mediump vec2 midShadowCoord; |
294 | +varying lowp vec4 color; |
295 | +varying lowp vec4 shadowColor; |
296 | + |
297 | +void main() |
298 | +{ |
299 | + mediump vec2 shadowTextureCoord = midShadowCoord - abs(shadowCoord - midShadowCoord); |
300 | + lowp float shadowCoverage = 1.0 - texture2D(shadowTexture, shadowTextureCoord).r; |
301 | + lowp vec4 shadow = shadowColor * vec4(shadowCoverage); |
302 | + gl_FragColor = shadow + (vec4(1.0 - shadow.a) * color); |
303 | +} |
304 | |
305 | === added file 'src/UbuntuToolkit/privates/shaders/fillcentershadowborder.frag' |
306 | --- src/UbuntuToolkit/privates/shaders/fillcentershadowborder.frag 1970-01-01 00:00:00 +0000 |
307 | +++ src/UbuntuToolkit/privates/shaders/fillcentershadowborder.frag 2016-12-14 07:25:05 +0000 |
308 | @@ -0,0 +1,22 @@ |
309 | +uniform sampler2D shadowTexture; |
310 | +uniform sampler2D borderTexture; |
311 | +uniform lowp float opacity; |
312 | + |
313 | +varying mediump vec2 shadowCoord; |
314 | +varying mediump vec2 midShadowCoord; |
315 | +varying mediump vec2 borderCoord; |
316 | +varying lowp vec4 color; |
317 | +varying lowp vec4 shadowColor; |
318 | +varying lowp vec4 borderColor; |
319 | + |
320 | +void main() |
321 | +{ |
322 | + mediump vec2 shadowTextureCoord = midShadowCoord - abs(shadowCoord - midShadowCoord); |
323 | + lowp float shadowCoverage = 1.0 - texture2D(shadowTexture, shadowTextureCoord).r; |
324 | + lowp vec4 shadow = shadowColor * vec4(shadowCoverage); |
325 | + lowp vec4 blend = shadow + (vec4(1.0 - shadow.a) * color); |
326 | + lowp float borderCoverage = 1.0 - texture2D(borderTexture, borderCoord).r; |
327 | + lowp vec4 border = borderColor * vec4(borderCoverage); |
328 | + blend = border + (vec4(1.0 - border.a) * blend); |
329 | + gl_FragColor = blend * vec4(opacity); |
330 | +} |
331 | |
332 | === added file 'src/UbuntuToolkit/privates/shaders/fillcentershadowborder.vert' |
333 | --- src/UbuntuToolkit/privates/shaders/fillcentershadowborder.vert 1970-01-01 00:00:00 +0000 |
334 | +++ src/UbuntuToolkit/privates/shaders/fillcentershadowborder.vert 2016-12-14 07:25:05 +0000 |
335 | @@ -0,0 +1,27 @@ |
336 | +uniform highp mat4 matrix; |
337 | + |
338 | +attribute highp vec4 positionAttrib; |
339 | +attribute mediump vec2 shadowCoordAttrib; |
340 | +attribute mediump vec2 midShadowCoordAttrib; |
341 | +attribute mediump vec2 borderCoordAttrib; |
342 | +attribute lowp vec4 colorAttrib; |
343 | +attribute lowp vec4 shadowColorAttrib; |
344 | +attribute lowp vec4 borderColorAttrib; |
345 | + |
346 | +varying mediump vec2 shadowCoord; |
347 | +varying mediump vec2 midShadowCoord; |
348 | +varying mediump vec2 borderCoord; |
349 | +varying lowp vec4 color; |
350 | +varying lowp vec4 shadowColor; |
351 | +varying lowp vec4 borderColor; |
352 | + |
353 | +void main() |
354 | +{ |
355 | + shadowCoord = shadowCoordAttrib; |
356 | + midShadowCoord = midShadowCoordAttrib; |
357 | + borderCoord = borderCoordAttrib; |
358 | + color = colorAttrib; |
359 | + shadowColor = shadowColorAttrib; |
360 | + borderColor = borderColorAttrib; |
361 | + gl_Position = matrix * positionAttrib; |
362 | +} |
363 | |
364 | === added file 'src/UbuntuToolkit/privates/shaders/fillcentershadowborder_opaque.frag' |
365 | --- src/UbuntuToolkit/privates/shaders/fillcentershadowborder_opaque.frag 1970-01-01 00:00:00 +0000 |
366 | +++ src/UbuntuToolkit/privates/shaders/fillcentershadowborder_opaque.frag 2016-12-14 07:25:05 +0000 |
367 | @@ -0,0 +1,20 @@ |
368 | +uniform sampler2D shadowTexture; |
369 | +uniform sampler2D borderTexture; |
370 | + |
371 | +varying mediump vec2 shadowCoord; |
372 | +varying mediump vec2 midShadowCoord; |
373 | +varying mediump vec2 borderCoord; |
374 | +varying lowp vec4 color; |
375 | +varying lowp vec4 shadowColor; |
376 | +varying lowp vec4 borderColor; |
377 | + |
378 | +void main() |
379 | +{ |
380 | + mediump vec2 shadowTextureCoord = midShadowCoord - abs(shadowCoord - midShadowCoord); |
381 | + lowp float shadowCoverage = 1.0 - texture2D(shadowTexture, shadowTextureCoord).r; |
382 | + lowp vec4 shadow = shadowColor * vec4(shadowCoverage); |
383 | + lowp vec4 blend = shadow + (vec4(1.0 - shadow.a) * color); |
384 | + lowp float borderCoverage = 1.0 - texture2D(borderTexture, borderCoord).r; |
385 | + lowp vec4 border = borderColor * vec4(borderCoverage); |
386 | + gl_FragColor = border + (vec4(1.0 - border.a) * blend); |
387 | +} |
388 | |
389 | === added file 'src/UbuntuToolkit/privates/shaders/fillcornersborder.frag' |
390 | --- src/UbuntuToolkit/privates/shaders/fillcornersborder.frag 1970-01-01 00:00:00 +0000 |
391 | +++ src/UbuntuToolkit/privates/shaders/fillcornersborder.frag 2016-12-14 07:25:05 +0000 |
392 | @@ -0,0 +1,17 @@ |
393 | +uniform sampler2D maskTexture; |
394 | +uniform sampler2D borderTexture; |
395 | +uniform lowp float opacity; |
396 | + |
397 | +varying mediump vec2 maskCoord; |
398 | +varying mediump vec2 borderCoord; |
399 | +varying lowp vec4 color; |
400 | +varying lowp vec4 borderColor; |
401 | + |
402 | +void main() |
403 | +{ |
404 | + lowp float borderCoverage = 1.0 - texture2D(borderTexture, borderCoord).r; |
405 | + lowp vec4 border = borderColor * vec4(borderCoverage); |
406 | + lowp vec4 blend = border + (vec4(1.0 - border.a) * color); |
407 | + lowp float maskCoverage = texture2D(maskTexture, maskCoord).r; |
408 | + gl_FragColor = blend * vec4(maskCoverage * opacity); |
409 | +} |
410 | |
411 | === added file 'src/UbuntuToolkit/privates/shaders/fillcornersborder.vert' |
412 | --- src/UbuntuToolkit/privates/shaders/fillcornersborder.vert 1970-01-01 00:00:00 +0000 |
413 | +++ src/UbuntuToolkit/privates/shaders/fillcornersborder.vert 2016-12-14 07:25:05 +0000 |
414 | @@ -0,0 +1,21 @@ |
415 | +uniform highp mat4 matrix; |
416 | + |
417 | +attribute highp vec4 positionAttrib; |
418 | +attribute mediump vec2 maskCoordAttrib; |
419 | +attribute mediump vec2 borderCoordAttrib; |
420 | +attribute lowp vec4 colorAttrib; |
421 | +attribute lowp vec4 borderColorAttrib; |
422 | + |
423 | +varying mediump vec2 maskCoord; |
424 | +varying mediump vec2 borderCoord; |
425 | +varying lowp vec4 color; |
426 | +varying lowp vec4 borderColor; |
427 | + |
428 | +void main() |
429 | +{ |
430 | + maskCoord = maskCoordAttrib; |
431 | + borderCoord = borderCoordAttrib; |
432 | + color = colorAttrib; |
433 | + borderColor = borderColorAttrib; |
434 | + gl_Position = matrix * positionAttrib; |
435 | +} |
436 | |
437 | === added file 'src/UbuntuToolkit/privates/shaders/fillcornersborder_opaque.frag' |
438 | --- src/UbuntuToolkit/privates/shaders/fillcornersborder_opaque.frag 1970-01-01 00:00:00 +0000 |
439 | +++ src/UbuntuToolkit/privates/shaders/fillcornersborder_opaque.frag 2016-12-14 07:25:05 +0000 |
440 | @@ -0,0 +1,16 @@ |
441 | +uniform sampler2D maskTexture; |
442 | +uniform sampler2D borderTexture; |
443 | + |
444 | +varying mediump vec2 maskCoord; |
445 | +varying mediump vec2 borderCoord; |
446 | +varying lowp vec4 color; |
447 | +varying lowp vec4 borderColor; |
448 | + |
449 | +void main() |
450 | +{ |
451 | + lowp float borderCoverage = 1.0 - texture2D(borderTexture, borderCoord).r; |
452 | + lowp vec4 border = borderColor * vec4(borderCoverage); |
453 | + lowp vec4 blend = border + (vec4(1.0 - border.a) * color); |
454 | + lowp float maskCoverage = texture2D(maskTexture, maskCoord).r; |
455 | + gl_FragColor = blend * vec4(maskCoverage); |
456 | +} |
457 | |
458 | === added file 'src/UbuntuToolkit/privates/shaders/fillcornersshadow.frag' |
459 | --- src/UbuntuToolkit/privates/shaders/fillcornersshadow.frag 1970-01-01 00:00:00 +0000 |
460 | +++ src/UbuntuToolkit/privates/shaders/fillcornersshadow.frag 2016-12-14 07:25:05 +0000 |
461 | @@ -0,0 +1,18 @@ |
462 | +uniform sampler2D shadowTexture; |
463 | +uniform lowp float opacity; |
464 | + |
465 | +varying mediump vec2 maskCoord; |
466 | +varying mediump vec2 shadowCoord; |
467 | +varying mediump vec2 midShadowCoord; |
468 | +varying lowp vec4 color; |
469 | +varying lowp vec4 shadowColor; |
470 | + |
471 | +void main() |
472 | +{ |
473 | + lowp float maskCoverage = texture2D(shadowTexture, maskCoord).a; |
474 | + mediump vec2 shadowTextureCoord = midShadowCoord - abs(shadowCoord - midShadowCoord); |
475 | + lowp float shadowCoverage = 1.0 - texture2D(shadowTexture, shadowTextureCoord).r; |
476 | + lowp vec4 shadow = shadowColor * vec4(shadowCoverage); |
477 | + lowp vec4 blend = shadow + (vec4(1.0 - shadow.a) * color); |
478 | + gl_FragColor = blend * vec4(maskCoverage * opacity); |
479 | +} |
480 | |
481 | === added file 'src/UbuntuToolkit/privates/shaders/fillcornersshadow.vert' |
482 | --- src/UbuntuToolkit/privates/shaders/fillcornersshadow.vert 1970-01-01 00:00:00 +0000 |
483 | +++ src/UbuntuToolkit/privates/shaders/fillcornersshadow.vert 2016-12-14 07:25:05 +0000 |
484 | @@ -0,0 +1,24 @@ |
485 | +uniform highp mat4 matrix; |
486 | + |
487 | +attribute highp vec4 positionAttrib; |
488 | +attribute mediump vec2 maskCoordAttrib; |
489 | +attribute mediump vec2 shadowCoordAttrib; |
490 | +attribute mediump vec2 midShadowCoordAttrib; |
491 | +attribute lowp vec4 colorAttrib; |
492 | +attribute lowp vec4 shadowColorAttrib; |
493 | + |
494 | +varying mediump vec2 maskCoord; |
495 | +varying mediump vec2 shadowCoord; |
496 | +varying mediump vec2 midShadowCoord; |
497 | +varying lowp vec4 color; |
498 | +varying lowp vec4 shadowColor; |
499 | + |
500 | +void main() |
501 | +{ |
502 | + maskCoord = maskCoordAttrib; |
503 | + shadowCoord = shadowCoordAttrib; |
504 | + midShadowCoord = midShadowCoordAttrib; |
505 | + color = colorAttrib; |
506 | + shadowColor = shadowColorAttrib; |
507 | + gl_Position = matrix * positionAttrib; |
508 | +} |
509 | |
510 | === added file 'src/UbuntuToolkit/privates/shaders/fillcornersshadow_opaque.frag' |
511 | --- src/UbuntuToolkit/privates/shaders/fillcornersshadow_opaque.frag 1970-01-01 00:00:00 +0000 |
512 | +++ src/UbuntuToolkit/privates/shaders/fillcornersshadow_opaque.frag 2016-12-14 07:25:05 +0000 |
513 | @@ -0,0 +1,17 @@ |
514 | +uniform sampler2D shadowTexture; |
515 | + |
516 | +varying mediump vec2 maskCoord; |
517 | +varying mediump vec2 shadowCoord; |
518 | +varying mediump vec2 midShadowCoord; |
519 | +varying lowp vec4 color; |
520 | +varying lowp vec4 shadowColor; |
521 | + |
522 | +void main() |
523 | +{ |
524 | + lowp float maskCoverage = texture2D(shadowTexture, maskCoord).a; |
525 | + mediump vec2 shadowTextureCoord = midShadowCoord - abs(shadowCoord - midShadowCoord); |
526 | + lowp float shadowCoverage = 1.0 - texture2D(shadowTexture, shadowTextureCoord).r; |
527 | + lowp vec4 shadow = shadowColor * vec4(shadowCoverage); |
528 | + lowp vec4 blend = shadow + (vec4(1.0 - shadow.a) * color); |
529 | + gl_FragColor = blend * vec4(maskCoverage); |
530 | +} |
531 | |
532 | === added file 'src/UbuntuToolkit/privates/shaders/fillcornersshadowborder.frag' |
533 | --- src/UbuntuToolkit/privates/shaders/fillcornersshadowborder.frag 1970-01-01 00:00:00 +0000 |
534 | +++ src/UbuntuToolkit/privates/shaders/fillcornersshadowborder.frag 2016-12-14 07:25:05 +0000 |
535 | @@ -0,0 +1,24 @@ |
536 | +uniform sampler2D shadowTexture; |
537 | +uniform sampler2D borderTexture; |
538 | +uniform lowp float opacity; |
539 | + |
540 | +varying mediump vec2 maskCoord; |
541 | +varying mediump vec2 shadowCoord; |
542 | +varying mediump vec2 midShadowCoord; |
543 | +varying mediump vec2 borderCoord; |
544 | +varying lowp vec4 color; |
545 | +varying lowp vec4 shadowColor; |
546 | +varying lowp vec4 borderColor; |
547 | + |
548 | +void main() |
549 | +{ |
550 | + lowp float maskCoverage = texture2D(shadowTexture, maskCoord).a; |
551 | + mediump vec2 shadowTextureCoord = midShadowCoord - abs(shadowCoord - midShadowCoord); |
552 | + lowp float shadowCoverage = 1.0 - texture2D(shadowTexture, shadowTextureCoord).r; |
553 | + lowp vec4 shadow = shadowColor * vec4(shadowCoverage); |
554 | + lowp vec4 blend = shadow + (vec4(1.0 - shadow.a) * color); |
555 | + lowp float borderCoverage = 1.0 - texture2D(borderTexture, borderCoord).r; |
556 | + lowp vec4 border = borderColor * vec4(borderCoverage); |
557 | + blend = border + (vec4(1.0 - border.a) * blend); |
558 | + gl_FragColor = blend * vec4(maskCoverage * opacity); |
559 | +} |
560 | |
561 | === added file 'src/UbuntuToolkit/privates/shaders/fillcornersshadowborder.vert' |
562 | --- src/UbuntuToolkit/privates/shaders/fillcornersshadowborder.vert 1970-01-01 00:00:00 +0000 |
563 | +++ src/UbuntuToolkit/privates/shaders/fillcornersshadowborder.vert 2016-12-14 07:25:05 +0000 |
564 | @@ -0,0 +1,30 @@ |
565 | +uniform highp mat4 matrix; |
566 | + |
567 | +attribute highp vec4 positionAttrib; |
568 | +attribute mediump vec2 maskCoordAttrib; |
569 | +attribute mediump vec2 shadowCoordAttrib; |
570 | +attribute mediump vec2 midShadowCoordAttrib; |
571 | +attribute mediump vec2 borderCoordAttrib; |
572 | +attribute lowp vec4 colorAttrib; |
573 | +attribute lowp vec4 shadowColorAttrib; |
574 | +attribute lowp vec4 borderColorAttrib; |
575 | + |
576 | +varying mediump vec2 maskCoord; |
577 | +varying mediump vec2 shadowCoord; |
578 | +varying mediump vec2 midShadowCoord; |
579 | +varying mediump vec2 borderCoord; |
580 | +varying lowp vec4 color; |
581 | +varying lowp vec4 shadowColor; |
582 | +varying lowp vec4 borderColor; |
583 | + |
584 | +void main() |
585 | +{ |
586 | + maskCoord = maskCoordAttrib; |
587 | + shadowCoord = shadowCoordAttrib; |
588 | + midShadowCoord = midShadowCoordAttrib; |
589 | + borderCoord = borderCoordAttrib; |
590 | + color = colorAttrib; |
591 | + shadowColor = shadowColorAttrib; |
592 | + borderColor = borderColorAttrib; |
593 | + gl_Position = matrix * positionAttrib; |
594 | +} |
595 | |
596 | === added file 'src/UbuntuToolkit/privates/shaders/fillcornersshadowborder_opaque.frag' |
597 | --- src/UbuntuToolkit/privates/shaders/fillcornersshadowborder_opaque.frag 1970-01-01 00:00:00 +0000 |
598 | +++ src/UbuntuToolkit/privates/shaders/fillcornersshadowborder_opaque.frag 2016-12-14 07:25:05 +0000 |
599 | @@ -0,0 +1,23 @@ |
600 | +uniform sampler2D shadowTexture; |
601 | +uniform sampler2D borderTexture; |
602 | + |
603 | +varying mediump vec2 maskCoord; |
604 | +varying mediump vec2 shadowCoord; |
605 | +varying mediump vec2 midShadowCoord; |
606 | +varying mediump vec2 borderCoord; |
607 | +varying lowp vec4 color; |
608 | +varying lowp vec4 shadowColor; |
609 | +varying lowp vec4 borderColor; |
610 | + |
611 | +void main() |
612 | +{ |
613 | + lowp float maskCoverage = texture2D(shadowTexture, maskCoord).a; |
614 | + mediump vec2 shadowTextureCoord = midShadowCoord - abs(shadowCoord - midShadowCoord); |
615 | + lowp float shadowCoverage = 1.0 - texture2D(shadowTexture, shadowTextureCoord).r; |
616 | + lowp vec4 shadow = shadowColor * vec4(shadowCoverage); |
617 | + lowp vec4 blend = shadow + (vec4(1.0 - shadow.a) * color); |
618 | + lowp float borderCoverage = 1.0 - texture2D(borderTexture, borderCoord).r; |
619 | + lowp vec4 border = borderColor * vec4(borderCoverage); |
620 | + blend = border + (vec4(1.0 - border.a) * blend); |
621 | + gl_FragColor = blend * vec4(maskCoverage); |
622 | +} |
623 | |
624 | === modified file 'src/UbuntuToolkit/privates/shaders/frame.frag' |
625 | --- src/UbuntuToolkit/privates/shaders/frame.frag 2016-01-21 11:46:11 +0000 |
626 | +++ src/UbuntuToolkit/privates/shaders/frame.frag 2016-12-14 07:25:05 +0000 |
627 | @@ -1,33 +1,15 @@ |
628 | -/* |
629 | - * Copyright 2016 Canonical Ltd. |
630 | - * |
631 | - * This program is free software; you can redistribute it and/or modify |
632 | - * it under the terms of the GNU Lesser General Public License as published by |
633 | - * the Free Software Foundation; version 3. |
634 | - * |
635 | - * This program is distributed in the hope that it will be useful, |
636 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
637 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
638 | - * GNU Lesser General Public License for more details. |
639 | - * |
640 | - * You should have received a copy of the GNU Lesser General Public License |
641 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
642 | - * |
643 | - * Author: Loïc Molinari <loic.molinari@canonical.com> |
644 | - */ |
645 | - |
646 | -uniform sampler2D texture; |
647 | +uniform sampler2D texture[2]; |
648 | uniform lowp float opacity; |
649 | -varying mediump vec2 outerCoord; |
650 | -varying mediump vec2 innerCoord; |
651 | + |
652 | +varying mediump vec2 texCoord1; |
653 | +varying mediump vec2 texCoord2; |
654 | varying lowp vec4 color; |
655 | |
656 | -void main(void) |
657 | +void main() |
658 | { |
659 | - lowp float shapeOut = texture2D(texture, outerCoord).r; |
660 | - lowp float shapeIn = texture2D(texture, innerCoord).r; |
661 | - // Fused multiply-add friendly version of (shapeOut * (1.0 - shapeIn)) |
662 | - lowp float shape = (shapeOut * -shapeIn) + shapeOut; |
663 | - // shape is squared to make thinner corners (particularly visible at stroke 1). |
664 | - gl_FragColor = vec4(shape * shape * opacity) * color; |
665 | + lowp float outerShape = texture2D(texture[0], texCoord1).r; |
666 | + lowp float innerShape = texture2D(texture[1], texCoord2).r; |
667 | + // Fused multiply-add friendly version of (outerShape * (1.0 - innerShape)) |
668 | + lowp float shape = (outerShape * -innerShape) + outerShape; |
669 | + gl_FragColor = vec4(shape * opacity) * color; |
670 | } |
671 | |
672 | === removed file 'src/UbuntuToolkit/privates/shaders/frame.vert' |
673 | --- src/UbuntuToolkit/privates/shaders/frame.vert 2016-01-21 11:46:11 +0000 |
674 | +++ src/UbuntuToolkit/privates/shaders/frame.vert 1970-01-01 00:00:00 +0000 |
675 | @@ -1,34 +0,0 @@ |
676 | -/* |
677 | - * Copyright 2016 Canonical Ltd. |
678 | - * |
679 | - * This program is free software; you can redistribute it and/or modify |
680 | - * it under the terms of the GNU Lesser General Public License as published by |
681 | - * the Free Software Foundation; version 3. |
682 | - * |
683 | - * This program is distributed in the hope that it will be useful, |
684 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
685 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
686 | - * GNU Lesser General Public License for more details. |
687 | - * |
688 | - * You should have received a copy of the GNU Lesser General Public License |
689 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
690 | - * |
691 | - * Author: Loïc Molinari <loic.molinari@canonical.com> |
692 | - */ |
693 | - |
694 | -uniform highp mat4 matrix; |
695 | -attribute highp vec4 positionAttrib; |
696 | -attribute mediump vec2 outerCoordAttrib; |
697 | -attribute mediump vec2 innerCoordAttrib; |
698 | -attribute lowp vec4 colorAttrib; |
699 | -varying mediump vec2 outerCoord; |
700 | -varying mediump vec2 innerCoord; |
701 | -varying lowp vec4 color; |
702 | - |
703 | -void main() |
704 | -{ |
705 | - outerCoord = outerCoordAttrib; |
706 | - innerCoord = innerCoordAttrib; |
707 | - color = colorAttrib; |
708 | - gl_Position = matrix * positionAttrib; |
709 | -} |
710 | |
711 | === added file 'src/UbuntuToolkit/privates/shaders/texture2.vert' |
712 | --- src/UbuntuToolkit/privates/shaders/texture2.vert 1970-01-01 00:00:00 +0000 |
713 | +++ src/UbuntuToolkit/privates/shaders/texture2.vert 2016-12-14 07:25:05 +0000 |
714 | @@ -0,0 +1,18 @@ |
715 | +uniform highp mat4 matrix; |
716 | + |
717 | +attribute highp vec4 positionAttrib; |
718 | +attribute mediump vec2 texCoord1Attrib; |
719 | +attribute mediump vec2 texCoord2Attrib; |
720 | +attribute lowp vec4 colorAttrib; |
721 | + |
722 | +varying mediump vec2 texCoord1; |
723 | +varying mediump vec2 texCoord2; |
724 | +varying lowp vec4 color; |
725 | + |
726 | +void main() |
727 | +{ |
728 | + texCoord1 = texCoord1Attrib; |
729 | + texCoord2 = texCoord2Attrib; |
730 | + color = colorAttrib; |
731 | + gl_Position = matrix * positionAttrib; |
732 | +} |
733 | |
734 | === added file 'src/UbuntuToolkit/privates/ucshape.cpp' |
735 | --- src/UbuntuToolkit/privates/ucshape.cpp 1970-01-01 00:00:00 +0000 |
736 | +++ src/UbuntuToolkit/privates/ucshape.cpp 2016-12-14 07:25:05 +0000 |
737 | @@ -0,0 +1,434 @@ |
738 | +/* |
739 | + * Copyright 2016 Canonical Ltd. |
740 | + * |
741 | + * This program is free software; you can redistribute it and/or modify |
742 | + * it under the terms of the GNU Lesser General Public License as published by |
743 | + * the Free Software Foundation; version 3. |
744 | + * |
745 | + * This program is distributed in the hope that it will be useful, |
746 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
747 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
748 | + * GNU Lesser General Public License for more details. |
749 | + * |
750 | + * You should have received a copy of the GNU Lesser General Public License |
751 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
752 | + * |
753 | + * Author: Loïc Molinari <loic.molinari@canonical.com> |
754 | + */ |
755 | + |
756 | +// FIXME(loicm) Add a description of the techniques and terms used in the shape |
757 | +// item and nodes. |
758 | + |
759 | +// TODO(loicm): Try using half-sized textures to speed up CPU-based shadow |
760 | +// rendering, switching to bilinear texture sampling at runtime. Evaluate |
761 | +// the trade-off between texture creation (faster generation allows higher |
762 | +// max radius and shadow sizes) and rendering speed. |
763 | + |
764 | +// TODO(loicm): Outer shadow rendering should provide a clippedShape (or |
765 | +// knockedOutShape) mode that knocks out the pixels of the shape area. This |
766 | +// is often what we need and that would allow to optimise rendering by |
767 | +// removing transparent pixels (that are still rasterised, shaded and |
768 | +// blended by the GPU...) with a dedicated mesh. |
769 | + |
770 | +// TODO(loicm): Add support for negative distances. |
771 | + |
772 | +#include "ucshape_p.h" |
773 | + |
774 | +#include <math.h> |
775 | + |
776 | +#include "ucshapedropshadownodes_p.h" |
777 | +#include "ucshapefillnodes_p.h" |
778 | + |
779 | +UCShape::UCShape(QQuickItem* parent) |
780 | + : QQuickItem(parent) |
781 | + , m_fillColor(qRgba(0xe9, 0x54, 0x20, 0xff)) // Ubuntu orange. |
782 | + , m_dropShadowColor(qRgba(0, 0, 0, 0xff)) |
783 | + , m_innerShadowColor(qRgba(0, 0, 0, 0xff)) |
784 | + , m_borderColor(qRgba(0xff, 0xff, 0xff, 0xff)) |
785 | + , m_radius(0) |
786 | + , m_dropShadowSize(0) |
787 | + , m_dropShadowDistance(0) |
788 | + , m_dropShadowAngle(0) |
789 | + , m_innerShadowSize(0) |
790 | + , m_innerShadowDistance(0) |
791 | + , m_innerShadowAngle(0) |
792 | + , m_borderSize(0) |
793 | + // the flags must be in sync with the default values above! |
794 | + , m_flags(FillCenterVisible) |
795 | + , m_shape(Squircle) |
796 | +{ |
797 | + setFlag(ItemHasContents); |
798 | +} |
799 | + |
800 | +UCShape::Shape UCShape::shape() const |
801 | +{ |
802 | + return static_cast<Shape>(m_shape); |
803 | +} |
804 | + |
805 | +void UCShape::setShape(Shape shape) |
806 | +{ |
807 | + const quint8 newShape = shape; |
808 | + if (m_shape != newShape) { |
809 | + m_shape = newShape; |
810 | + update(); |
811 | + Q_EMIT shapeChanged(); |
812 | + } |
813 | +} |
814 | + |
815 | +qreal UCShape::radius() const |
816 | +{ |
817 | + return unquantizeFromU16(m_radius); |
818 | +} |
819 | + |
820 | +void UCShape::setRadius(qreal radius) |
821 | +{ |
822 | + const quint16 quantizedRadius = quantizeToU16(radius); |
823 | + if (m_radius != quantizedRadius) { |
824 | + if ((m_radius > 0) != (quantizedRadius > 0)) { |
825 | + if (qAlpha(m_fillColor) > 0) { |
826 | + if (quantizedRadius > 0) { |
827 | + m_flags |= FillCornersVisible | DirtyFillCornersVisibility; |
828 | + } else { |
829 | + m_flags = (m_flags & ~FillCornersVisible) | DirtyFillCornersVisibility; |
830 | + } |
831 | + } |
832 | + } |
833 | + m_radius = quantizedRadius; |
834 | + update(); |
835 | + Q_EMIT radiusChanged(); |
836 | + } |
837 | +} |
838 | + |
839 | +QColor UCShape::fillColor() const |
840 | +{ |
841 | + return QColor(qRed(m_fillColor), qGreen(m_fillColor), qBlue(m_fillColor), qAlpha(m_fillColor)); |
842 | +} |
843 | + |
844 | +void UCShape::setFillColor(const QColor& color) |
845 | +{ |
846 | + const QRgb rgbColor = qRgba(color.red(), color.green(), color.blue(), color.alpha()); |
847 | + if (m_fillColor != rgbColor) { |
848 | + if ((qAlpha(m_fillColor) > 0) != (qAlpha(rgbColor) > 0)) { |
849 | + if (qAlpha(rgbColor) > 0) { |
850 | + m_flags |= FillCenterVisible | DirtyFillCenterVisibility; |
851 | + if (m_radius > 0) { |
852 | + m_flags |= FillCornersVisible | DirtyFillCornersVisibility; |
853 | + } |
854 | + } else { |
855 | + m_flags &= ~FillCenterVisible; |
856 | + m_flags |= DirtyFillCenterVisibility; |
857 | + if (m_radius > 0) { |
858 | + m_flags &= ~FillCornersVisible; |
859 | + m_flags |= DirtyFillCornersVisibility; |
860 | + } |
861 | + } |
862 | + } |
863 | + m_fillColor = rgbColor; |
864 | + update(); |
865 | + Q_EMIT fillColorChanged(); |
866 | + } |
867 | +} |
868 | + |
869 | +qreal UCShape::dropShadowSize() const |
870 | +{ |
871 | + return unquantizeFromU16(m_dropShadowSize); |
872 | +} |
873 | + |
874 | +void UCShape::setDropShadowSize(qreal size) |
875 | +{ |
876 | + const quint16 quantizedSize = quantizeToU16(size); |
877 | + if (m_dropShadowSize != quantizedSize) { |
878 | + if (((m_dropShadowSize > 0) != (quantizedSize > 0)) |
879 | + && ((m_dropShadowDistance == 0) && (qAlpha(m_dropShadowColor) > 0))) { |
880 | + if (quantizedSize > 0) { |
881 | + m_flags |= DropShadowVisible; |
882 | + } else { |
883 | + m_flags &= ~DropShadowVisible; |
884 | + } |
885 | + m_flags |= DirtyDropShadowVisibility; |
886 | + } |
887 | + m_dropShadowSize = quantizedSize; |
888 | + update(); |
889 | + Q_EMIT dropShadowSizeChanged(); |
890 | + } |
891 | +} |
892 | + |
893 | +qreal UCShape::dropShadowDistance() const |
894 | +{ |
895 | + return unquantizeFromU16(m_dropShadowDistance); |
896 | +} |
897 | + |
898 | +void UCShape::setDropShadowDistance(qreal distance) |
899 | +{ |
900 | + const quint16 quantizedDistance = quantizeToU16(distance); |
901 | + if (m_dropShadowDistance != quantizedDistance) { |
902 | + if ((m_dropShadowDistance > 0) != (quantizedDistance > 0) |
903 | + && ((m_dropShadowSize == 0) && (qAlpha(m_dropShadowColor) > 0))) { |
904 | + if (quantizedDistance > 0) { |
905 | + m_flags |= DropShadowVisible; |
906 | + } else { |
907 | + m_flags &= ~DropShadowVisible; |
908 | + } |
909 | + m_flags |= DirtyDropShadowVisibility; |
910 | + } |
911 | + m_dropShadowDistance = quantizedDistance; |
912 | + update(); |
913 | + Q_EMIT dropShadowDistanceChanged(); |
914 | + } |
915 | +} |
916 | + |
917 | +qreal UCShape::dropShadowAngle() const |
918 | +{ |
919 | + return unquantizeFromU16(m_dropShadowAngle); |
920 | +} |
921 | + |
922 | +void UCShape::setDropShadowAngle(qreal angle) |
923 | +{ |
924 | + double clampedAngle = fmod(static_cast<double>(angle), 360.0); |
925 | + if (clampedAngle < 0.0) { |
926 | + clampedAngle += 360.0; |
927 | + } |
928 | + const quint16 quantizedAngle = quantizeToU16Clamped(clampedAngle); |
929 | + if (m_dropShadowAngle != quantizedAngle) { |
930 | + m_dropShadowAngle = quantizedAngle; |
931 | + update(); |
932 | + Q_EMIT dropShadowAngleChanged(); |
933 | + } |
934 | +} |
935 | + |
936 | +QColor UCShape::dropShadowColor() const |
937 | +{ |
938 | + return QColor( |
939 | + qRed(m_dropShadowColor), qGreen(m_dropShadowColor), qBlue(m_dropShadowColor), |
940 | + qAlpha(m_dropShadowColor)); |
941 | +} |
942 | + |
943 | +void UCShape::setDropShadowColor(const QColor& color) |
944 | +{ |
945 | + const QRgb rgbColor = qRgba(color.red(), color.green(), color.blue(), color.alpha()); |
946 | + if (m_dropShadowColor != rgbColor) { |
947 | + if (((qAlpha(m_dropShadowColor) > 0) != (qAlpha(rgbColor) > 0)) |
948 | + && ((m_dropShadowDistance > 0) || (m_dropShadowSize > 0))) { |
949 | + if (qAlpha(rgbColor) > 0) { |
950 | + m_flags |= DropShadowVisible; |
951 | + } else { |
952 | + m_flags &= ~DropShadowVisible; |
953 | + } |
954 | + m_flags |= DirtyDropShadowVisibility; |
955 | + } |
956 | + m_dropShadowColor = rgbColor; |
957 | + update(); |
958 | + Q_EMIT dropShadowColorChanged(); |
959 | + } |
960 | +} |
961 | + |
962 | +qreal UCShape::innerShadowSize() const |
963 | +{ |
964 | + return unquantizeFromU16(m_innerShadowSize); |
965 | +} |
966 | + |
967 | +void UCShape::setInnerShadowSize(qreal size) |
968 | +{ |
969 | + const quint16 quantizedSize = quantizeToU16(size); |
970 | + if (m_innerShadowSize != quantizedSize) { |
971 | + m_innerShadowSize = quantizedSize; |
972 | + update(); |
973 | + Q_EMIT innerShadowSizeChanged(); |
974 | + } |
975 | +} |
976 | + |
977 | +qreal UCShape::innerShadowDistance() const |
978 | +{ |
979 | + return unquantizeFromU16(m_innerShadowDistance); |
980 | +} |
981 | + |
982 | +void UCShape::setInnerShadowDistance(qreal distance) |
983 | +{ |
984 | + const quint16 quantizedDistance = quantizeToU16(distance); |
985 | + if (m_innerShadowDistance != quantizedDistance) { |
986 | + m_innerShadowDistance = quantizedDistance; |
987 | + update(); |
988 | + Q_EMIT innerShadowDistanceChanged(); |
989 | + } |
990 | +} |
991 | + |
992 | +qreal UCShape::innerShadowAngle() const |
993 | +{ |
994 | + return unquantizeFromU16(m_innerShadowAngle); |
995 | +} |
996 | + |
997 | +void UCShape::setInnerShadowAngle(qreal angle) |
998 | +{ |
999 | + double clampedAngle = fmod(static_cast<double>(angle), 360.0); |
1000 | + if (clampedAngle < 0.0) { |
1001 | + clampedAngle += 360.0; |
1002 | + } |
1003 | + const quint16 quantizedAngle = quantizeToU16Clamped(clampedAngle); |
1004 | + if (m_innerShadowAngle != quantizedAngle) { |
1005 | + m_innerShadowAngle = quantizedAngle; |
1006 | + update(); |
1007 | + Q_EMIT innerShadowAngleChanged(); |
1008 | + } |
1009 | +} |
1010 | + |
1011 | +QColor UCShape::innerShadowColor() const |
1012 | +{ |
1013 | + return QColor( |
1014 | + qRed(m_innerShadowColor), qGreen(m_innerShadowColor), qBlue(m_innerShadowColor), |
1015 | + qAlpha(m_innerShadowColor)); |
1016 | +} |
1017 | + |
1018 | +void UCShape::setInnerShadowColor(const QColor& color) |
1019 | +{ |
1020 | + const QRgb rgbColor = qRgba(color.red(), color.green(), color.blue(), color.alpha()); |
1021 | + if (m_innerShadowColor != rgbColor) { |
1022 | + m_innerShadowColor = rgbColor; |
1023 | + update(); |
1024 | + Q_EMIT innerShadowColorChanged(); |
1025 | + } |
1026 | +} |
1027 | + |
1028 | +qreal UCShape::borderSize() const |
1029 | +{ |
1030 | + return unquantizeFromU16(m_borderSize); |
1031 | +} |
1032 | + |
1033 | +void UCShape::setBorderSize(qreal size) |
1034 | +{ |
1035 | + const quint16 quantizedSize = quantizeToU16(size); |
1036 | + if (m_borderSize != quantizedSize) { |
1037 | + m_borderSize = quantizedSize; |
1038 | + update(); |
1039 | + Q_EMIT borderSizeChanged(); |
1040 | + } |
1041 | +} |
1042 | + |
1043 | +QColor UCShape::borderColor() const |
1044 | +{ |
1045 | + return QColor( |
1046 | + qRed(m_borderColor), qGreen(m_borderColor), qBlue(m_borderColor), qAlpha(m_borderColor)); |
1047 | +} |
1048 | + |
1049 | +void UCShape::setBorderColor(const QColor& color) |
1050 | +{ |
1051 | + const QRgb rgbColor = qRgba(color.red(), color.green(), color.blue(), color.alpha()); |
1052 | + if (m_borderColor != rgbColor) { |
1053 | + m_borderColor = rgbColor; |
1054 | + update(); |
1055 | + Q_EMIT borderColorChanged(); |
1056 | + } |
1057 | +} |
1058 | + |
1059 | +class UCShapeNode : public QSGNode |
1060 | +{ |
1061 | +public: |
1062 | + UCShapeNode() : QSGNode(), m_nodes{} { DLOG("creating UCShapeNode"); } |
1063 | + ~UCShapeNode() { DLOG("detroying UCShapeNode"); } |
1064 | + |
1065 | + // Sorted by rendering order from back to front. |
1066 | + enum NodeType { DropShadow = 0, FillCenter, FillCorners, NodeTypeCount }; |
1067 | + |
1068 | + QSGNode* node(NodeType type, bool instantiate = true) |
1069 | + { |
1070 | + DASSERT(static_cast<quint32>(type) < NodeTypeCount); |
1071 | + |
1072 | + if (m_nodes[type]) { |
1073 | + return m_nodes[type]; |
1074 | + } else if (!instantiate) { |
1075 | + return Q_NULLPTR; |
1076 | + } else { |
1077 | + switch (type) { |
1078 | + case DropShadow: m_nodes[DropShadow] = new UCShapeDropShadowNode; break; |
1079 | + case FillCenter: m_nodes[FillCenter] = new UCShapeFillCenterNode; break; |
1080 | + case FillCorners: m_nodes[FillCorners] = new UCShapeFillCornersNode; break; |
1081 | + default: DNOT_REACHED(); return Q_NULLPTR; |
1082 | + } |
1083 | + for (int i = type + 1; i < NodeTypeCount; ++i) { |
1084 | + if (m_nodes[i]) { |
1085 | + insertChildNodeBefore(m_nodes[type], m_nodes[i]); |
1086 | + return m_nodes[type]; |
1087 | + } |
1088 | + } |
1089 | + appendChildNode(m_nodes[type]); |
1090 | + return m_nodes[type]; |
1091 | + } |
1092 | + } |
1093 | + |
1094 | +private: |
1095 | + QSGNode* m_nodes[NodeTypeCount]; |
1096 | +}; |
1097 | + |
1098 | +QSGNode* UCShape::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) |
1099 | +{ |
1100 | + const QSizeF itemSize(width(), height()); |
1101 | + if (itemSize.isEmpty()) { |
1102 | + delete oldNode; |
1103 | + return Q_NULLPTR; |
1104 | + } |
1105 | + |
1106 | + UCShapeNode* shapeNode; |
1107 | + if (oldNode) { |
1108 | + shapeNode = static_cast<UCShapeNode*>(oldNode); |
1109 | + } else { |
1110 | + shapeNode = new UCShapeNode; |
1111 | + // Make sure the right visibility is set on the nodes. |
1112 | + m_flags |= DirtyFlags; |
1113 | + } |
1114 | + |
1115 | + // The strategy here is to instantiate shape node's children only when |
1116 | + // required (for instance corner nodes are instantiated only when radius is |
1117 | + // greater than 0). Once instantiated a child node is freed only when the |
1118 | + // parent is freed (for instance corner nodes are not freed when radius goes |
1119 | + // back to 0). That allows to minimise the memory usage to what the user |
1120 | + // needs (properties like radius and shadow sizes are set to 0 by default on |
1121 | + // purpose), to avoid complexifying the code and to avoid costly memory |
1122 | + // allocations when animating for instance a color back and forth to |
1123 | + // transparent (which would require a node deletion). |
1124 | + |
1125 | + // Drop shadow node. |
1126 | + const bool dropShadowVisible = static_cast<bool>(m_flags & DropShadowVisible); |
1127 | + if (dropShadowVisible) { |
1128 | + static_cast<UCShapeDropShadowNode*>(shapeNode->node(UCShapeNode::DropShadow))->update( |
1129 | + itemSize, static_cast<UCShapeType>(m_shape), unquantizeFromU16(m_radius), |
1130 | + unquantizeFromU16(m_dropShadowSize), unquantizeFromU16(m_dropShadowAngle), |
1131 | + unquantizeFromU16(m_dropShadowDistance), m_dropShadowColor); |
1132 | + } |
1133 | + if (m_flags & DirtyDropShadowVisibility) { |
1134 | + static_cast<UCShapeDropShadowNode*>(shapeNode->node(UCShapeNode::DropShadow))->setVisible( |
1135 | + dropShadowVisible); |
1136 | + } |
1137 | + |
1138 | + // Fill center node. |
1139 | + const bool fillCenterVisible = static_cast<bool>(m_flags & FillCenterVisible); |
1140 | + if (fillCenterVisible) { |
1141 | + static_cast<UCShapeFillCenterNode*>(shapeNode->node(UCShapeNode::FillCenter))->update( |
1142 | + itemSize, static_cast<UCShapeType>(m_shape), unquantizeFromU16(m_radius), m_fillColor, |
1143 | + unquantizeFromU16(m_innerShadowSize), unquantizeFromU16(m_innerShadowAngle), |
1144 | + unquantizeFromU16(m_innerShadowDistance), m_innerShadowColor, |
1145 | + unquantizeFromU16(m_borderSize), m_borderColor); |
1146 | + } |
1147 | + if (m_flags & DirtyFillCenterVisibility) { |
1148 | + static_cast<UCShapeFillCenterNode*>(shapeNode->node(UCShapeNode::FillCenter))->setVisible( |
1149 | + fillCenterVisible); |
1150 | + } |
1151 | + |
1152 | + // Fill corners node. |
1153 | + const bool fillCornersVisible = static_cast<bool>(m_flags & FillCornersVisible); |
1154 | + if (fillCornersVisible) { |
1155 | + static_cast<UCShapeFillCornersNode*>(shapeNode->node(UCShapeNode::FillCorners))->update( |
1156 | + itemSize, static_cast<UCShapeType>(m_shape), unquantizeFromU16(m_radius), m_fillColor, |
1157 | + unquantizeFromU16(m_innerShadowSize), unquantizeFromU16(m_innerShadowAngle), |
1158 | + unquantizeFromU16(m_innerShadowDistance), m_innerShadowColor, |
1159 | + unquantizeFromU16(m_borderSize), m_borderColor); |
1160 | + } |
1161 | + if (m_flags & DirtyFillCornersVisibility) { |
1162 | + UCShapeFillCornersNode* node = static_cast<UCShapeFillCornersNode*>( |
1163 | + shapeNode->node(UCShapeNode::FillCorners, false)); |
1164 | + if (node) { |
1165 | + node->setVisible(fillCornersVisible); |
1166 | + } |
1167 | + } |
1168 | + |
1169 | + m_flags &= ~DirtyFlags; |
1170 | + return shapeNode; |
1171 | +} |
1172 | |
1173 | === added file 'src/UbuntuToolkit/privates/ucshape_p.h' |
1174 | --- src/UbuntuToolkit/privates/ucshape_p.h 1970-01-01 00:00:00 +0000 |
1175 | +++ src/UbuntuToolkit/privates/ucshape_p.h 2016-12-14 07:25:05 +0000 |
1176 | @@ -0,0 +1,162 @@ |
1177 | +/* |
1178 | + * Copyright 2016 Canonical Ltd. |
1179 | + * |
1180 | + * This program is free software; you can redistribute it and/or modify |
1181 | + * it under the terms of the GNU Lesser General Public License as published by |
1182 | + * the Free Software Foundation; version 3. |
1183 | + * |
1184 | + * This program is distributed in the hope that it will be useful, |
1185 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1186 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1187 | + * GNU Lesser General Public License for more details. |
1188 | + * |
1189 | + * You should have received a copy of the GNU Lesser General Public License |
1190 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1191 | + * |
1192 | + * Author: Loïc Molinari <loic.molinari@canonical.com> |
1193 | + */ |
1194 | + |
1195 | +#ifndef UCSHAPE_P_H |
1196 | +#define UCSHAPE_P_H |
1197 | + |
1198 | +#include <QtQuick/QQuickItem> |
1199 | + |
1200 | +#include <UbuntuToolkit/private/ucshapetexturefactory_p.h> |
1201 | + |
1202 | +class UCShape : public QQuickItem |
1203 | +{ |
1204 | + Q_OBJECT |
1205 | + Q_ENUMS(Shape) |
1206 | + |
1207 | + // Shape of the corner. |
1208 | + Q_PROPERTY(Shape shape READ shape WRITE setShape NOTIFY shapeChanged) |
1209 | + |
1210 | + // Radius of the corners in pixels. |
1211 | + Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged) |
1212 | + |
1213 | + // Fill color of the shape. |
1214 | + Q_PROPERTY(QColor fillColor READ fillColor WRITE setFillColor NOTIFY fillColorChanged) |
1215 | + |
1216 | + // Size of the drop shadow in pixels. |
1217 | + Q_PROPERTY(qreal dropShadowSize READ dropShadowSize WRITE setDropShadowSize |
1218 | + NOTIFY dropShadowSizeChanged) |
1219 | + |
1220 | + // Offset of the drop shadow in pixels. |
1221 | + Q_PROPERTY(qreal dropShadowDistance READ dropShadowDistance WRITE setDropShadowDistance |
1222 | + NOTIFY dropShadowDistanceChanged) |
1223 | + |
1224 | + // Offset angle of the drop shadow in degrees. The virtual light points to |
1225 | + // the left by default and is rotated counter clockwise. |
1226 | + Q_PROPERTY(qreal dropShadowAngle READ dropShadowAngle WRITE setDropShadowAngle |
1227 | + NOTIFY dropShadowAngleChanged) |
1228 | + |
1229 | + // Color of the drop shadow. |
1230 | + Q_PROPERTY(QColor dropShadowColor READ dropShadowColor WRITE setDropShadowColor |
1231 | + NOTIFY dropShadowColorChanged) |
1232 | + |
1233 | + // Size of the inner shadow in pixels. |
1234 | + Q_PROPERTY(qreal innerShadowSize READ innerShadowSize WRITE setInnerShadowSize |
1235 | + NOTIFY innerShadowSizeChanged) |
1236 | + |
1237 | + // Offset of the inner shadow in pixels. |
1238 | + Q_PROPERTY(qreal innerShadowDistance READ innerShadowDistance WRITE setInnerShadowDistance |
1239 | + NOTIFY innerShadowDistanceChanged) |
1240 | + |
1241 | + // Offset angle of the inner shadow in degrees. The virtual light points to |
1242 | + // the left by default and is rotated counter clockwise. |
1243 | + Q_PROPERTY(qreal innerShadowAngle READ innerShadowAngle WRITE setInnerShadowAngle |
1244 | + NOTIFY innerShadowAngleChanged) |
1245 | + |
1246 | + // Color of the inner shadow. |
1247 | + Q_PROPERTY(QColor innerShadowColor READ innerShadowColor WRITE setInnerShadowColor |
1248 | + NOTIFY innerShadowColorChanged) |
1249 | + |
1250 | + // Size of the border in pixels. |
1251 | + Q_PROPERTY(qreal borderSize READ borderSize WRITE setBorderSize NOTIFY borderSizeChanged) |
1252 | + |
1253 | + // Color of the border. |
1254 | + Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor NOTIFY borderColorChanged) |
1255 | + |
1256 | +public: |
1257 | + UCShape(QQuickItem* parent = 0); |
1258 | + |
1259 | + enum Shape { Squircle = UCShapeType::Squircle, Circle = UCShapeType::Circle }; |
1260 | + |
1261 | + Shape shape() const; |
1262 | + void setShape(Shape shape); |
1263 | + qreal radius() const; |
1264 | + void setRadius(qreal radius); |
1265 | + QColor fillColor() const; |
1266 | + void setFillColor(const QColor& fillColor); |
1267 | + qreal dropShadowSize() const; |
1268 | + void setDropShadowSize(qreal size); |
1269 | + qreal dropShadowDistance() const; |
1270 | + void setDropShadowDistance(qreal distance); |
1271 | + qreal dropShadowAngle() const; |
1272 | + void setDropShadowAngle(qreal angle); |
1273 | + QColor dropShadowColor() const; |
1274 | + void setDropShadowColor(const QColor& color); |
1275 | + qreal innerShadowSize() const; |
1276 | + void setInnerShadowSize(qreal size); |
1277 | + qreal innerShadowDistance() const; |
1278 | + void setInnerShadowDistance(qreal distance); |
1279 | + qreal innerShadowAngle() const; |
1280 | + void setInnerShadowAngle(qreal angle); |
1281 | + QColor innerShadowColor() const; |
1282 | + void setInnerShadowColor(const QColor& color); |
1283 | + qreal borderSize() const; |
1284 | + void setBorderSize(qreal size); |
1285 | + QColor borderColor() const; |
1286 | + void setBorderColor(const QColor& color); |
1287 | + |
1288 | +Q_SIGNALS: |
1289 | + void shapeChanged(); |
1290 | + void radiusChanged(); |
1291 | + void fillColorChanged(); |
1292 | + void dropShadowSizeChanged(); |
1293 | + void dropShadowDistanceChanged(); |
1294 | + void dropShadowAngleChanged(); |
1295 | + void dropShadowColorChanged(); |
1296 | + void innerShadowSizeChanged(); |
1297 | + void innerShadowDistanceChanged(); |
1298 | + void innerShadowAngleChanged(); |
1299 | + void innerShadowColorChanged(); |
1300 | + void borderSizeChanged(); |
1301 | + void borderColorChanged(); |
1302 | + |
1303 | +private: |
1304 | + QSGNode* updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* data) Q_DECL_OVERRIDE; |
1305 | + |
1306 | + enum { |
1307 | + DropShadowVisible = (1 << 0), |
1308 | + FillCenterVisible = (1 << 1), |
1309 | + FillCornersVisible = (1 << 2), |
1310 | + DirtyDropShadowVisibility = (1 << 3), |
1311 | + DirtyFillCenterVisibility = (1 << 4), |
1312 | + DirtyFillCornersVisibility = (1 << 5), |
1313 | + DirtyFlags = |
1314 | + DirtyDropShadowVisibility | DirtyFillCenterVisibility | DirtyFillCornersVisibility |
1315 | + }; |
1316 | + |
1317 | + QRgb m_fillColor; |
1318 | + QRgb m_dropShadowColor; |
1319 | + QRgb m_innerShadowColor; |
1320 | + QRgb m_borderColor; |
1321 | + quint16 m_radius; |
1322 | + quint16 m_dropShadowSize; |
1323 | + quint16 m_dropShadowDistance; |
1324 | + quint16 m_dropShadowAngle; |
1325 | + quint16 m_innerShadowSize; |
1326 | + quint16 m_innerShadowDistance; |
1327 | + quint16 m_innerShadowAngle; |
1328 | + quint16 m_borderSize; |
1329 | + quint16 m_flags; |
1330 | + quint8 m_shape : 1; |
1331 | + quint8 __padding : 7; |
1332 | + |
1333 | + Q_DISABLE_COPY(UCShape) |
1334 | +}; |
1335 | + |
1336 | +QML_DECLARE_TYPE(UCShape) |
1337 | + |
1338 | +#endif // UCSHAPE_P_H |
1339 | |
1340 | === added file 'src/UbuntuToolkit/privates/ucshapedropshadownodes.cpp' |
1341 | --- src/UbuntuToolkit/privates/ucshapedropshadownodes.cpp 1970-01-01 00:00:00 +0000 |
1342 | +++ src/UbuntuToolkit/privates/ucshapedropshadownodes.cpp 2016-12-14 07:25:05 +0000 |
1343 | @@ -0,0 +1,175 @@ |
1344 | +/* |
1345 | + * Copyright 2016 Canonical Ltd. |
1346 | + * |
1347 | + * This program is free software; you can redistribute it and/or modify |
1348 | + * it under the terms of the GNU Lesser General Public License as published by |
1349 | + * the Free Software Foundation; version 3. |
1350 | + * |
1351 | + * This program is distributed in the hope that it will be useful, |
1352 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1353 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1354 | + * GNU Lesser General Public License for more details. |
1355 | + * |
1356 | + * You should have received a copy of the GNU Lesser General Public License |
1357 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1358 | + * |
1359 | + * Author: Loïc Molinari <loic.molinari@canonical.com> |
1360 | + */ |
1361 | + |
1362 | +#include "ucshapedropshadownodes_p.h" |
1363 | + |
1364 | +#include <QtGui/QGuiApplication> |
1365 | +#include <QtGui/QOpenGLFunctions> |
1366 | + |
1367 | +#include "ucshaperesources_p.h" |
1368 | + |
1369 | +// The geometry is made of 9 vertices indexed with a triangle strip mode. |
1370 | +// 0 --- 1 --- 2 |
1371 | +// | / | / | |
1372 | +// 3 --- 4 --- 5 |
1373 | +// | / | / | |
1374 | +// 6 --- 7 --- 8 |
1375 | +const quint16 indices[] = { |
1376 | + 0, 3, 1, 4, 2, 5, |
1377 | + 5, 3, // Degenerate triangle. |
1378 | + 3, 6, 4, 7, 5, 8 |
1379 | +}; |
1380 | +const int indexCount = ARRAY_SIZE(indices); |
1381 | +const int vertexCount = 9; |
1382 | + |
1383 | +UCShapeDropShadowNode::UCShapeDropShadowNode() |
1384 | + : QSGGeometryNode() |
1385 | + , m_resources(vertexCount, indexCount) |
1386 | + , m_radius(0) |
1387 | + , m_shadow(0) |
1388 | + , m_shape(UCShapeType::Squircle) |
1389 | + , m_flags(0) |
1390 | +{ |
1391 | + DLOG("creating UCShapeDropShadowNode"); |
1392 | + setFlag(QSGNode::UsePreprocess, true); |
1393 | + setMaterial(m_resources.material()); |
1394 | + m_resources.opaqueMaterial()->setFlag(QSGMaterial::Blending); |
1395 | + setOpaqueMaterial(m_resources.opaqueMaterial()); |
1396 | + memcpy(m_resources.geometry()->indexData(), indices, indexCount * sizeof(quint16)); |
1397 | + setGeometry(m_resources.geometry()); |
1398 | + qsgnode_set_description(this, QLatin1String("shapedropshadow")); |
1399 | +} |
1400 | + |
1401 | +UCShapeDropShadowNode::~UCShapeDropShadowNode() |
1402 | +{ |
1403 | + DLOG("detroying UCShapeDropShadowNode"); |
1404 | +} |
1405 | + |
1406 | +void UCShapeDropShadowNode::preprocess() |
1407 | +{ |
1408 | + if (m_flags & DirtyMask) { |
1409 | + static_cast<UCShapeColorMaskMaterial<false>*>( |
1410 | + m_resources.material())->updateShadowTexture( |
1411 | + static_cast<UCShapeType>(m_shape), m_radius, m_shadow); |
1412 | + static_cast<UCShapeColorMaskMaterial<true>*>( |
1413 | + m_resources.opaqueMaterial())->updateShadowTexture( |
1414 | + static_cast<UCShapeType>(m_shape), m_radius, m_shadow); |
1415 | + } |
1416 | + m_flags &= ~DirtyMask; |
1417 | +} |
1418 | + |
1419 | +void UCShapeDropShadowNode::setVisible(bool visible) |
1420 | +{ |
1421 | + DLOG("UCShapeDropShadowNode::setVisible %d", visible); |
1422 | + if (static_cast<bool>(m_flags & Visible) != visible) { |
1423 | + m_flags = (m_flags & ~Visible) | (visible ? Visible : 0); |
1424 | + markDirty(DirtySubtreeBlocked); |
1425 | + } |
1426 | +} |
1427 | + |
1428 | +void UCShapeDropShadowNode::update( |
1429 | + const QSizeF& itemSize, UCShapeType type, float radius, float shadowSize, float shadowAngle, |
1430 | + float shadowDistance, QRgb shadowColor) |
1431 | +{ |
1432 | + UCShapeColorMaskResources::Vertex* v = |
1433 | + reinterpret_cast<UCShapeColorMaskResources::Vertex*>(m_resources.geometry()->vertexData()); |
1434 | + float s, c; |
1435 | + sincosf((shadowAngle + 180.0f) * -(M_PI / 180.0f), &s, &c); |
1436 | + const float offsetX = roundf(c * shadowDistance); |
1437 | + const float offsetY = roundf(s * shadowDistance); |
1438 | + const float dpr = qGuiApp->devicePixelRatio(); |
1439 | + const float w = floorf(static_cast<float>(itemSize.width())); |
1440 | + const float h = floorf(static_cast<float>(itemSize.height())); |
1441 | + // Rounded down since renderShape() doesn't support sub-pixel rendering. |
1442 | + const float maxSize = floorf(qMin(w, h) * 0.5f); |
1443 | + const float clampedRadius = qMin(floorf(radius), maxSize); |
1444 | + const quint32 packedShadowColor = packColor(shadowColor); |
1445 | + const float clampedShadow = qMin(floorf(shadowSize), maxSize); |
1446 | + const float border = 1.0f; |
1447 | + const float textureSize = (2.0f * clampedShadow + 2.0f * border + clampedRadius) * dpr; |
1448 | + const float textureSizeRounded = roundUp(static_cast<int>(textureSize), textureRounding); |
1449 | + const float textureOffset = (textureSizeRounded - textureSize) / textureSizeRounded; |
1450 | + const float textureFactor = ((1.0f - textureOffset) * dpr) / textureSize; |
1451 | + const float midW = w * 0.5f; |
1452 | + const float midH = h * 0.5f; |
1453 | + const float midShadowS = (border + clampedShadow + midW) * textureFactor + textureOffset; |
1454 | + const float midShadowT = (border + clampedShadow + midH) * textureFactor + textureOffset; |
1455 | + |
1456 | + v[0].x = -clampedShadow + offsetX; |
1457 | + v[0].y = -clampedShadow + offsetY; |
1458 | + v[0].maskS = border * textureFactor + textureOffset; |
1459 | + v[0].maskT = border * textureFactor + textureOffset; |
1460 | + v[0].color = packedShadowColor; |
1461 | + v[1].x = midW + offsetX; |
1462 | + v[1].y = -clampedShadow + offsetY; |
1463 | + v[1].maskS = midShadowS; |
1464 | + v[1].maskT = border * textureFactor + textureOffset; |
1465 | + v[1].color = packedShadowColor; |
1466 | + v[2].x = w + clampedShadow + offsetX; |
1467 | + v[2].y = -clampedShadow + offsetY; |
1468 | + v[2].maskS = border * textureFactor + textureOffset; |
1469 | + v[2].maskT = border * textureFactor + textureOffset; |
1470 | + v[2].color = packedShadowColor; |
1471 | + v[3].x = -clampedShadow + offsetX; |
1472 | + v[3].y = midH + offsetY; |
1473 | + v[3].maskS = border * textureFactor + textureOffset; |
1474 | + v[3].maskT = midShadowT; |
1475 | + v[3].color = packedShadowColor; |
1476 | + v[4].x = midW + offsetX; |
1477 | + v[4].y = midH + offsetY; |
1478 | + v[4].maskS = midShadowS; |
1479 | + v[4].maskT = midShadowT; |
1480 | + v[4].color = packedShadowColor; |
1481 | + v[5].x = w + clampedShadow + offsetX; |
1482 | + v[5].y = midH + offsetY; |
1483 | + v[5].maskS = border * textureFactor + textureOffset; |
1484 | + v[5].maskT = midShadowT; |
1485 | + v[5].color = packedShadowColor; |
1486 | + v[6].x = -clampedShadow + offsetX; |
1487 | + v[6].y = h + clampedShadow + offsetY; |
1488 | + v[6].maskS = border * textureFactor + textureOffset; |
1489 | + v[6].maskT = border * textureFactor + textureOffset; |
1490 | + v[6].color = packedShadowColor; |
1491 | + v[7].x = midW + offsetX; |
1492 | + v[7].y = h + clampedShadow + offsetY; |
1493 | + v[7].maskS = midShadowS; |
1494 | + v[7].maskT = border * textureFactor + textureOffset; |
1495 | + v[7].color = packedShadowColor; |
1496 | + v[8].x = w + clampedShadow + offsetX; |
1497 | + v[8].y = h + clampedShadow + offsetY; |
1498 | + v[8].maskS = border * textureFactor + textureOffset; |
1499 | + v[8].maskT = border * textureFactor + textureOffset; |
1500 | + v[8].color = packedShadowColor; |
1501 | + markDirty(QSGNode::DirtyGeometry); |
1502 | + |
1503 | + // Update data for the preprocess() call. |
1504 | + const quint16 deviceShadow = static_cast<quint16>(clampedShadow * dpr); |
1505 | + if (m_shadow != deviceShadow) { |
1506 | + m_shadow = deviceShadow; |
1507 | + m_flags |= DirtyShadow; |
1508 | + } |
1509 | + const quint16 deviceRadius = static_cast<quint16>(clampedRadius * dpr); |
1510 | + if (m_radius != deviceRadius) { |
1511 | + m_radius = deviceRadius; |
1512 | + m_flags |= DirtyRadius; |
1513 | + } |
1514 | + if (m_shape != static_cast<quint8>(type)) { |
1515 | + m_shape = static_cast<quint8>(type); |
1516 | + m_flags |= DirtyShape; |
1517 | + } |
1518 | +} |
1519 | |
1520 | === added file 'src/UbuntuToolkit/privates/ucshapedropshadownodes_p.h' |
1521 | --- src/UbuntuToolkit/privates/ucshapedropshadownodes_p.h 1970-01-01 00:00:00 +0000 |
1522 | +++ src/UbuntuToolkit/privates/ucshapedropshadownodes_p.h 2016-12-14 07:25:05 +0000 |
1523 | @@ -0,0 +1,57 @@ |
1524 | +/* |
1525 | + * Copyright 2016 Canonical Ltd. |
1526 | + * |
1527 | + * This program is free software; you can redistribute it and/or modify |
1528 | + * it under the terms of the GNU Lesser General Public License as published by |
1529 | + * the Free Software Foundation; version 3. |
1530 | + * |
1531 | + * This program is distributed in the hope that it will be useful, |
1532 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1533 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1534 | + * GNU Lesser General Public License for more details. |
1535 | + * |
1536 | + * You should have received a copy of the GNU Lesser General Public License |
1537 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1538 | + * |
1539 | + * Author: Loïc Molinari <loic.molinari@canonical.com> |
1540 | + */ |
1541 | + |
1542 | +#ifndef UCSHAPEDROPSHADOWNODES_P_H |
1543 | +#define UCSHAPEDROPSHADOWNODES_P_H |
1544 | + |
1545 | +#include <QtQuick/QSGNode> |
1546 | + |
1547 | +#include <UbuntuToolkit/private/ucshaperesources_p.h> |
1548 | + |
1549 | +class UCShapeDropShadowNode : public QSGGeometryNode |
1550 | +{ |
1551 | +public: |
1552 | + UCShapeDropShadowNode(); |
1553 | + ~UCShapeDropShadowNode(); |
1554 | + |
1555 | + void preprocess() Q_DECL_OVERRIDE; |
1556 | + bool isSubtreeBlocked() const Q_DECL_OVERRIDE { return !(m_flags & Visible); } |
1557 | + |
1558 | + void setVisible(bool visible); |
1559 | + void update( |
1560 | + const QSizeF& itemSize, UCShapeType type, float radius, float shadowSize, float shadowAngle, |
1561 | + float shadowDistance, QRgb shadowColor); |
1562 | + |
1563 | +private: |
1564 | + enum { |
1565 | + DirtyRadius = (1 << 0), |
1566 | + DirtyShadow = (1 << 1), |
1567 | + DirtyShape = (1 << 2), |
1568 | + DirtyMask = (DirtyRadius | DirtyShadow | DirtyShape), |
1569 | + Visible = (1 << 3), |
1570 | + Blending = (1 << 4) |
1571 | + }; |
1572 | + |
1573 | + UCShapeColorMaskResources m_resources; |
1574 | + quint16 m_radius; |
1575 | + quint16 m_shadow; |
1576 | + quint8 m_shape; |
1577 | + quint8 m_flags; |
1578 | +}; |
1579 | + |
1580 | +#endif // UCSHAPEDROPSHADOWNODES_P_H |
1581 | |
1582 | === added file 'src/UbuntuToolkit/privates/ucshapefillnodes.cpp' |
1583 | --- src/UbuntuToolkit/privates/ucshapefillnodes.cpp 1970-01-01 00:00:00 +0000 |
1584 | +++ src/UbuntuToolkit/privates/ucshapefillnodes.cpp 2016-12-14 07:25:05 +0000 |
1585 | @@ -0,0 +1,1431 @@ |
1586 | +/* |
1587 | + * Copyright 2016 Canonical Ltd. |
1588 | + * |
1589 | + * This program is free software; you can redistribute it and/or modify |
1590 | + * it under the terms of the GNU Lesser General Public License as published by |
1591 | + * the Free Software Foundation; version 3. |
1592 | + * |
1593 | + * This program is distributed in the hope that it will be useful, |
1594 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1595 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1596 | + * GNU Lesser General Public License for more details. |
1597 | + * |
1598 | + * You should have received a copy of the GNU Lesser General Public License |
1599 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1600 | + * |
1601 | + * Author: Loïc Molinari <loic.molinari@canonical.com> |
1602 | + */ |
1603 | + |
1604 | +// FIXME(loicm) The midShadow coords force a dependent texture read which is |
1605 | +// quite slow on some platforms. We should maybe add geometry to deal with |
1606 | +// the coords inversion. That would add complexity but improve perf. |
1607 | + |
1608 | +#include "ucshapefillnodes_p.h" |
1609 | + |
1610 | +#include <QtGui/QOpenGLFunctions> |
1611 | +#include <QtGui/QGuiApplication> |
1612 | + |
1613 | +UCShapeFillCenterNode::UCShapeFillCenterNode() |
1614 | + : QSGGeometryNode() |
1615 | + , m_resources(Q_NULLPTR) |
1616 | + , m_radius(0) |
1617 | + , m_shadow(0) |
1618 | + , m_borderRadius(0) |
1619 | + , m_flags(0) |
1620 | + , m_shape(UCShapeType::Squircle) |
1621 | +{ |
1622 | + DLOG("creating UCShapeFillCenterNode"); |
1623 | + qsgnode_set_description(this, QLatin1String("shapefillcenter")); |
1624 | +} |
1625 | + |
1626 | +UCShapeFillCenterNode::~UCShapeFillCenterNode() |
1627 | +{ |
1628 | + DLOG("detroying UCShapeFillCenterNode"); |
1629 | + delete m_resources; |
1630 | +} |
1631 | + |
1632 | +void UCShapeFillCenterNode::preprocess() |
1633 | +{ |
1634 | + DASSERT(m_flags & Textured); |
1635 | + |
1636 | + // FIXME(loicm) Could be made more consise (texture update methods in the resources?). |
1637 | + |
1638 | + switch (m_flags & StyleMask) { |
1639 | + case (HasColor | HasShadow): |
1640 | + if (m_flags & (DirtyRadius | DirtyShadow | DirtyShape)) { |
1641 | + static_cast<UCShapeFillCenterShadowMaterial<false>*>( |
1642 | + m_resources->material())->updateShadowTexture( |
1643 | + static_cast<UCShapeType>(m_shape), m_radius, m_shadow); |
1644 | + static_cast<UCShapeFillCenterShadowMaterial<true>*>( |
1645 | + m_resources->opaqueMaterial())->updateShadowTexture( |
1646 | + static_cast<UCShapeType>(m_shape), m_radius, m_shadow); |
1647 | + } |
1648 | + break; |
1649 | + |
1650 | + case (HasColor | HasBorder): |
1651 | + if (m_flags & (DirtyBorderRadius | DirtyShape)) { |
1652 | + static_cast<UCShapeFillCenterBorderMaterial<false>*>( |
1653 | + m_resources->material())->updateBorderTexture( |
1654 | + static_cast<UCShapeType>(m_shape), m_borderRadius); |
1655 | + static_cast<UCShapeFillCenterBorderMaterial<true>*>( |
1656 | + m_resources->opaqueMaterial())->updateBorderTexture( |
1657 | + static_cast<UCShapeType>(m_shape), m_borderRadius); |
1658 | + } |
1659 | + break; |
1660 | + |
1661 | + case (HasColor | HasShadow | HasBorder): |
1662 | + if (m_flags & (DirtyRadius | DirtyShadow | DirtyShape)) { |
1663 | + static_cast<UCShapeFillCenterShadowBorderMaterial<false>*>( |
1664 | + m_resources->material())->updateShadowTexture( |
1665 | + static_cast<UCShapeType>(m_shape), m_radius, m_shadow); |
1666 | + static_cast<UCShapeFillCenterShadowBorderMaterial<true>*>( |
1667 | + m_resources->opaqueMaterial())->updateShadowTexture( |
1668 | + static_cast<UCShapeType>(m_shape), m_radius, m_shadow); |
1669 | + } |
1670 | + if (m_flags & (DirtyBorderRadius | DirtyShape)) { |
1671 | + static_cast<UCShapeFillCenterShadowBorderMaterial<false>*>( |
1672 | + m_resources->material())->updateBorderTexture( |
1673 | + static_cast<UCShapeType>(m_shape), m_borderRadius); |
1674 | + static_cast<UCShapeFillCenterShadowBorderMaterial<true>*>( |
1675 | + m_resources->opaqueMaterial())->updateBorderTexture( |
1676 | + static_cast<UCShapeType>(m_shape), m_borderRadius); |
1677 | + } |
1678 | + break; |
1679 | + |
1680 | + default: |
1681 | + NOT_REACHED(); |
1682 | + } |
1683 | + |
1684 | + m_flags &= ~DirtyMask; |
1685 | +} |
1686 | + |
1687 | +void UCShapeFillCenterNode::setVisible(bool visible) |
1688 | +{ |
1689 | + DLOG("UCShapeFillCenterNode::setVisible %d", visible); |
1690 | + if (static_cast<bool>(m_flags & Visible) != visible) { |
1691 | + m_flags = (m_flags & ~Visible) | (visible ? Visible : 0); |
1692 | + markDirty(DirtySubtreeBlocked); |
1693 | + } |
1694 | +} |
1695 | + |
1696 | +void UCShapeFillCenterNode::update( |
1697 | + const QSizeF& itemSize, UCShapeType type, float radius, QRgb color, float shadowSize, |
1698 | + float shadowAngle, float shadowDistance, QRgb shadowColor, float borderSize, QRgb borderColor) |
1699 | +{ |
1700 | + // Without border, the geometry is made of 8 vertices indexed with a |
1701 | + // triangle strip mode. With border, the geometry is made of 13 vertices |
1702 | + // indexed with a triangle strip mode. |
1703 | + // |
1704 | + // Without border: With border: |
1705 | + // 0 ----- 1 0 - 1 - 2 |
1706 | + // / \ / | \ ("-Werror=comment" GCC guard) |
1707 | + // 2 3 3 | 4 |
1708 | + // | | | | | |
1709 | + // | | 5 ----- 6 ----- 7 |
1710 | + // | | | | | |
1711 | + // 4 5 8 | 9 |
1712 | + // \ / \ | / |
1713 | + // 6 ----- 7 10 -11-12 |
1714 | + const quint16 noBorderIndices[] = { |
1715 | + 2, 4, 0, 6, 1, 7, 3, 5 |
1716 | + }; |
1717 | + const quint16 borderIndices[] = { |
1718 | + 3, 5, 0, 6, 1, 7, 2, 4, |
1719 | + 4, 8, // Degenerate triangle. |
1720 | + 8, 10, 5, 11, 6, 12, 7, 9 |
1721 | + }; |
1722 | + const int noBorderIndexCount = ARRAY_SIZE(noBorderIndices); |
1723 | + const int borderIndexCount = ARRAY_SIZE(borderIndices); |
1724 | + const int noBorderVertexCount = 8; |
1725 | + const int borderVertexCount = 13; |
1726 | + |
1727 | + quint16 style = ((shadowSize <= 0.0f && shadowDistance <= 0.0f) || (qAlpha(shadowColor) == 0)) ? |
1728 | + HasColor : (HasColor | HasShadow); |
1729 | + if (borderSize >= 1.0f) { |
1730 | + style |= HasBorder; |
1731 | + } |
1732 | + |
1733 | + // Create new material/geometry set if needed. |
1734 | + if (style != (m_flags & StyleMask)) { |
1735 | + delete m_resources; |
1736 | + switch (style) { |
1737 | + case HasColor: |
1738 | + m_resources = new UCShapeColorResources(noBorderVertexCount, noBorderIndexCount); |
1739 | + memcpy(m_resources->geometry()->indexData(), noBorderIndices, |
1740 | + noBorderIndexCount * sizeof(quint16)); |
1741 | + setFlag(QSGNode::UsePreprocess, false); |
1742 | + break; |
1743 | + case (HasColor | HasShadow): |
1744 | + m_resources = new UCShapeFillCenterShadowResources( |
1745 | + noBorderVertexCount, noBorderIndexCount); |
1746 | + memcpy(m_resources->geometry()->indexData(), noBorderIndices, |
1747 | + noBorderIndexCount * sizeof(quint16)); |
1748 | + setFlag(QSGNode::UsePreprocess, true); |
1749 | + break; |
1750 | + case (HasColor | HasBorder): |
1751 | + m_resources = new UCShapeFillCenterBorderResources(borderVertexCount, borderIndexCount); |
1752 | + memcpy(m_resources->geometry()->indexData(), borderIndices, |
1753 | + borderIndexCount * sizeof(quint16)); |
1754 | + setFlag(QSGNode::UsePreprocess, true); |
1755 | + break; |
1756 | + case (HasColor | HasShadow | HasBorder): |
1757 | + m_resources = new UCShapeFillCenterShadowBorderResources( |
1758 | + borderVertexCount, borderIndexCount); |
1759 | + memcpy(m_resources->geometry()->indexData(), borderIndices, |
1760 | + borderIndexCount * sizeof(quint16)); |
1761 | + setFlag(QSGNode::UsePreprocess, true); |
1762 | + break; |
1763 | + default: |
1764 | + NOT_REACHED(); |
1765 | + } |
1766 | + setMaterial(m_resources->material()); |
1767 | + setOpaqueMaterial(m_resources->opaqueMaterial()); |
1768 | + setGeometry(m_resources->geometry()); |
1769 | + m_flags = (m_flags & ~StyleMask) | style | DirtyMask; |
1770 | + } |
1771 | + |
1772 | + const float dpr = qGuiApp->devicePixelRatio(); |
1773 | + const float w = floorf(static_cast<float>(itemSize.width())); |
1774 | + const float h = floorf(static_cast<float>(itemSize.height())); |
1775 | + // Rounded down since Shadow doesn't support sub-pixel rendering. |
1776 | + const float maxSize = floorf(qMin(w, h) * 0.5f); |
1777 | + const float clampedRadius = qMin(floorf(radius), maxSize); |
1778 | + const quint32 packedColor = packColor(color); |
1779 | + |
1780 | + // Update geometry depending on the style. |
1781 | + switch (style) { |
1782 | + case HasColor: { |
1783 | + UCShapeColorResources::Vertex* v = |
1784 | + reinterpret_cast<UCShapeColorResources::Vertex*>(m_resources->geometry()->vertexData()); |
1785 | + v[0].x = clampedRadius; |
1786 | + v[0].y = 0.0f; |
1787 | + v[0].color = packedColor; |
1788 | + v[1].x = w - clampedRadius; |
1789 | + v[1].y = 0.0f; |
1790 | + v[1].color = packedColor; |
1791 | + v[2].x = 0.0f; |
1792 | + v[2].y = clampedRadius; |
1793 | + v[2].color = packedColor; |
1794 | + v[3].x = w; |
1795 | + v[3].y = clampedRadius; |
1796 | + v[3].color = packedColor; |
1797 | + v[4].x = 0.0f; |
1798 | + v[4].y = h - clampedRadius; |
1799 | + v[4].color = packedColor; |
1800 | + v[5].x = w; |
1801 | + v[5].y = h - clampedRadius; |
1802 | + v[5].color = packedColor; |
1803 | + v[6].x = clampedRadius; |
1804 | + v[6].y = h; |
1805 | + v[6].color = packedColor; |
1806 | + v[7].x = w - clampedRadius; |
1807 | + v[7].y = h; |
1808 | + v[7].color = packedColor; |
1809 | + markDirty(QSGNode::DirtyGeometry); |
1810 | + break; |
1811 | + } |
1812 | + |
1813 | + case (HasColor | HasShadow): { |
1814 | + UCShapeFillCenterShadowResources::Vertex* v = |
1815 | + reinterpret_cast<UCShapeFillCenterShadowResources::Vertex*>( |
1816 | + m_resources->geometry()->vertexData()); |
1817 | + float s, c; |
1818 | + sincosf(shadowAngle * -(M_PI / 180.0f), &s, &c); |
1819 | + const float offsetX = roundf(c * shadowDistance); |
1820 | + const float offsetY = roundf(s * shadowDistance); |
1821 | + const float clampedShadow = qMin(floorf(shadowSize), maxSize); |
1822 | + const float border = 1.0f; |
1823 | + const float textureSize = (2.0f * clampedShadow + 2.0f * border + clampedRadius) * dpr; |
1824 | + const float textureSizeRounded = roundUp(static_cast<int>(textureSize), textureRounding); |
1825 | + const float textureOffset = (textureSizeRounded - textureSize) / textureSizeRounded; |
1826 | + const float textureFactor = ((1.0f - textureOffset) * dpr) / textureSize; |
1827 | + const float midShadowS = |
1828 | + (border + clampedShadow + (w * 0.5f)) * textureFactor + textureOffset; |
1829 | + const float midShadowT = |
1830 | + (border + clampedShadow + (h * 0.5f)) * textureFactor + textureOffset; |
1831 | + const quint32 packedShadowColor = packColor(shadowColor); |
1832 | + v[0].x = clampedRadius; |
1833 | + v[0].y = 0.0f; |
1834 | + v[0].shadowS = (offsetX + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
1835 | + v[0].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
1836 | + v[0].midShadowS = midShadowS; |
1837 | + v[0].midShadowT = midShadowT; |
1838 | + v[0].color = packedColor; |
1839 | + v[0].shadowColor = packedShadowColor; |
1840 | + v[1].x = w - clampedRadius; |
1841 | + v[1].y = 0.0f; |
1842 | + v[1].shadowS = |
1843 | + (offsetX + border + clampedShadow + (w - clampedRadius)) * textureFactor + textureOffset; |
1844 | + v[1].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
1845 | + v[1].midShadowS = midShadowS; |
1846 | + v[1].midShadowT = midShadowT; |
1847 | + v[1].color = packedColor; |
1848 | + v[1].shadowColor = packedShadowColor; |
1849 | + v[2].x = 0.0f; |
1850 | + v[2].y = clampedRadius; |
1851 | + v[2].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
1852 | + v[2].shadowT = (offsetY + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
1853 | + v[2].midShadowS = midShadowS; |
1854 | + v[2].midShadowT = midShadowT; |
1855 | + v[2].color = packedColor; |
1856 | + v[2].shadowColor = packedShadowColor; |
1857 | + v[3].x = w; |
1858 | + v[3].y = clampedRadius; |
1859 | + v[3].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
1860 | + v[3].shadowT = (offsetY + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
1861 | + v[3].midShadowS = midShadowS; |
1862 | + v[3].midShadowT = midShadowT; |
1863 | + v[3].color = packedColor; |
1864 | + v[3].shadowColor = packedShadowColor; |
1865 | + v[4].x = 0.0f; |
1866 | + v[4].y = h - clampedRadius; |
1867 | + v[4].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
1868 | + v[4].shadowT = |
1869 | + (offsetY + border + clampedShadow + (h - clampedRadius)) * textureFactor + textureOffset; |
1870 | + v[4].midShadowS = midShadowS; |
1871 | + v[4].midShadowT = midShadowT; |
1872 | + v[4].color = packedColor; |
1873 | + v[4].shadowColor = packedShadowColor; |
1874 | + v[5].x = w; |
1875 | + v[5].y = h - clampedRadius; |
1876 | + v[5].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
1877 | + v[5].shadowT = |
1878 | + (offsetY + border + clampedShadow + (h - clampedRadius)) * textureFactor + textureOffset; |
1879 | + v[5].midShadowS = midShadowS; |
1880 | + v[5].midShadowT = midShadowT; |
1881 | + v[5].color = packedColor; |
1882 | + v[5].shadowColor = packedShadowColor; |
1883 | + v[6].x = clampedRadius; |
1884 | + v[6].y = h; |
1885 | + v[6].shadowS = (offsetX + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
1886 | + v[6].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
1887 | + v[6].midShadowS = midShadowS; |
1888 | + v[6].midShadowT = midShadowT; |
1889 | + v[6].color = packedColor; |
1890 | + v[6].shadowColor = packedShadowColor; |
1891 | + v[7].x = w - clampedRadius; |
1892 | + v[7].y = h; |
1893 | + v[7].shadowS = |
1894 | + (offsetX + border + clampedShadow + (w - clampedRadius)) * textureFactor + textureOffset; |
1895 | + v[7].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
1896 | + v[7].midShadowS = midShadowS; |
1897 | + v[7].midShadowT = midShadowT; |
1898 | + v[7].color = packedColor; |
1899 | + v[7].shadowColor = packedShadowColor; |
1900 | + markDirty(QSGNode::DirtyGeometry); |
1901 | + |
1902 | + // Update data for the preprocess() call. |
1903 | + const quint16 deviceShadow = static_cast<quint16>(clampedShadow * dpr); |
1904 | + if (m_shadow != deviceShadow) { |
1905 | + m_shadow = deviceShadow; |
1906 | + m_flags |= DirtyShadow; |
1907 | + } |
1908 | + const quint16 deviceRadius = static_cast<quint16>(clampedRadius * dpr); |
1909 | + if (m_radius != deviceRadius) { |
1910 | + m_radius = deviceRadius; |
1911 | + m_flags |= DirtyRadius; |
1912 | + } |
1913 | + if (m_shape != static_cast<quint8>(type)) { |
1914 | + m_shape = static_cast<quint8>(type); |
1915 | + m_flags |= DirtyShape; |
1916 | + } |
1917 | + break; |
1918 | + } |
1919 | + |
1920 | + case (HasColor | HasBorder): { |
1921 | + UCShapeFillCenterBorderResources::Vertex* v = |
1922 | + reinterpret_cast<UCShapeFillCenterBorderResources::Vertex*>( |
1923 | + m_resources->geometry()->vertexData()); |
1924 | + const float midW = w * 0.5f; |
1925 | + const float midH = h * 0.5f; |
1926 | + const float clampedBorder = qMin(floorf(borderSize), maxSize); |
1927 | + const float clampedBorderRadius = |
1928 | + floorf(((maxSize - clampedBorder) / maxSize) * clampedRadius); |
1929 | + const float textureBorder = 1.0f; |
1930 | + const float borderTextureSize = (2.0f * textureBorder + clampedBorderRadius) * dpr; |
1931 | + const float borderTextureSizeRounded = |
1932 | + roundUp(static_cast<int>(borderTextureSize), textureRounding); |
1933 | + const float borderTextureOffset = |
1934 | + (borderTextureSizeRounded - borderTextureSize) / borderTextureSizeRounded; |
1935 | + const float borderTextureFactor = ((1.0f - borderTextureOffset) * dpr) / borderTextureSize; |
1936 | + const float borderOffset = -(clampedBorder - textureBorder); |
1937 | + const quint32 packedBorderColor = packColor(borderColor); |
1938 | + v[0].x = clampedRadius; |
1939 | + v[0].y = 0.0f; |
1940 | + v[0].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
1941 | + v[0].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
1942 | + v[0].color = packedColor; |
1943 | + v[0].borderColor = packedBorderColor; |
1944 | + v[1].x = midW; |
1945 | + v[1].y = 0.0f; |
1946 | + v[1].borderS = (midW + borderOffset) * borderTextureFactor + borderTextureOffset; |
1947 | + v[1].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
1948 | + v[1].color = packedColor; |
1949 | + v[1].borderColor = packedBorderColor; |
1950 | + v[2].x = w - clampedRadius; |
1951 | + v[2].y = 0.0f; |
1952 | + v[2].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
1953 | + v[2].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
1954 | + v[2].color = packedColor; |
1955 | + v[2].borderColor = packedBorderColor; |
1956 | + v[3].x = 0.0f; |
1957 | + v[3].y = clampedRadius; |
1958 | + v[3].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
1959 | + v[3].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
1960 | + v[3].color = packedColor; |
1961 | + v[3].borderColor = packedBorderColor; |
1962 | + v[4].x = w; |
1963 | + v[4].y = clampedRadius; |
1964 | + v[4].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
1965 | + v[4].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
1966 | + v[4].color = packedColor; |
1967 | + v[4].borderColor = packedBorderColor; |
1968 | + v[5].x = 0.0f; |
1969 | + v[5].y = midH; |
1970 | + v[5].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
1971 | + v[5].borderT = (midH + borderOffset) * borderTextureFactor + borderTextureOffset; |
1972 | + v[5].color = packedColor; |
1973 | + v[5].borderColor = packedBorderColor; |
1974 | + v[6].x = midW; |
1975 | + v[6].y = midH; |
1976 | + v[6].borderS = (midW + borderOffset) * borderTextureFactor + borderTextureOffset; |
1977 | + v[6].borderT = (midH + borderOffset) * borderTextureFactor + borderTextureOffset; |
1978 | + v[6].color = packedColor; |
1979 | + v[6].borderColor = packedBorderColor; |
1980 | + v[7].x = w; |
1981 | + v[7].y = midH; |
1982 | + v[7].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
1983 | + v[7].borderT = (midH + borderOffset) * borderTextureFactor + borderTextureOffset; |
1984 | + v[7].color = packedColor; |
1985 | + v[7].borderColor = packedBorderColor; |
1986 | + v[8].x = 0.0f; |
1987 | + v[8].y = h - clampedRadius; |
1988 | + v[8].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
1989 | + v[8].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
1990 | + v[8].color = packedColor; |
1991 | + v[8].borderColor = packedBorderColor; |
1992 | + v[9].x = w; |
1993 | + v[9].y = h - clampedRadius; |
1994 | + v[9].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
1995 | + v[9].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
1996 | + v[9].color = packedColor; |
1997 | + v[9].borderColor = packedBorderColor; |
1998 | + v[10].x = clampedRadius; |
1999 | + v[10].y = h; |
2000 | + v[10].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2001 | + v[10].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2002 | + v[10].color = packedColor; |
2003 | + v[10].borderColor = packedBorderColor; |
2004 | + v[11].x = midW; |
2005 | + v[11].y = h; |
2006 | + v[11].borderS = (midW + borderOffset) * borderTextureFactor + borderTextureOffset; |
2007 | + v[11].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2008 | + v[11].color = packedColor; |
2009 | + v[11].borderColor = packedBorderColor; |
2010 | + v[12].x = w - clampedRadius; |
2011 | + v[12].y = h; |
2012 | + v[12].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2013 | + v[12].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2014 | + v[12].color = packedColor; |
2015 | + v[12].borderColor = packedBorderColor; |
2016 | + markDirty(QSGNode::DirtyGeometry); |
2017 | + |
2018 | + // Update data for the preprocess() call. |
2019 | + const quint16 deviceRadius = static_cast<quint16>(clampedRadius * dpr); |
2020 | + if (m_radius != deviceRadius) { |
2021 | + m_radius = deviceRadius; |
2022 | + m_flags |= DirtyRadius; |
2023 | + } |
2024 | + const quint16 deviceBorderRadius = static_cast<quint16>(clampedBorderRadius * dpr); |
2025 | + if (m_borderRadius != deviceBorderRadius) { |
2026 | + m_borderRadius = deviceBorderRadius; |
2027 | + m_flags |= DirtyBorderRadius; |
2028 | + } |
2029 | + if (m_shape != static_cast<quint8>(type)) { |
2030 | + m_shape = static_cast<quint8>(type); |
2031 | + m_flags |= DirtyShape; |
2032 | + } |
2033 | + break; |
2034 | + } |
2035 | + |
2036 | + case (HasColor | HasShadow | HasBorder): { |
2037 | + UCShapeFillCenterShadowBorderResources::Vertex* v = |
2038 | + reinterpret_cast<UCShapeFillCenterShadowBorderResources::Vertex*>( |
2039 | + m_resources->geometry()->vertexData()); |
2040 | + float s, c; |
2041 | + sincosf(shadowAngle * -(M_PI / 180.0f), &s, &c); |
2042 | + const float offsetX = roundf(c * shadowDistance); |
2043 | + const float offsetY = roundf(s * shadowDistance); |
2044 | + const float clampedShadow = qMin(floorf(shadowSize), maxSize); |
2045 | + const float border = 1.0f; |
2046 | + const float textureSize = (2.0f * clampedShadow + 2.0f * border + clampedRadius) * dpr; |
2047 | + const float textureSizeRounded = roundUp(static_cast<int>(textureSize), textureRounding); |
2048 | + const float textureOffset = (textureSizeRounded - textureSize) / textureSizeRounded; |
2049 | + const float textureFactor = ((1.0f - textureOffset) * dpr) / textureSize; |
2050 | + const float midW = w * 0.5f; |
2051 | + const float midH = h * 0.5f; |
2052 | + const float midShadowS = (border + clampedShadow + midW) * textureFactor + textureOffset; |
2053 | + const float midShadowT = (border + clampedShadow + midH) * textureFactor + textureOffset; |
2054 | + const float clampedBorder = qMin(floorf(borderSize), maxSize); |
2055 | + const float clampedBorderRadius = |
2056 | + floorf(((maxSize - clampedBorder) / maxSize) * clampedRadius); |
2057 | + const float textureBorder = 1.0f; |
2058 | + const float borderTextureSize = (2.0f * textureBorder + clampedBorderRadius) * dpr; |
2059 | + const float borderTextureSizeRounded = |
2060 | + roundUp(static_cast<int>(borderTextureSize), textureRounding); |
2061 | + const float borderTextureOffset = |
2062 | + (borderTextureSizeRounded - borderTextureSize) / borderTextureSizeRounded; |
2063 | + const float borderTextureFactor = ((1.0f - borderTextureOffset) * dpr) / borderTextureSize; |
2064 | + const float borderOffset = -(clampedBorder - textureBorder); |
2065 | + const quint32 packedShadowColor = packColor(shadowColor); |
2066 | + const quint32 packedBorderColor = packColor(borderColor); |
2067 | + v[0].x = clampedRadius; |
2068 | + v[0].y = 0.0f; |
2069 | + v[0].shadowS = (offsetX + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2070 | + v[0].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
2071 | + v[0].midShadowS = midShadowS; |
2072 | + v[0].midShadowT = midShadowT; |
2073 | + v[0].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2074 | + v[0].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2075 | + v[0].color = packedColor; |
2076 | + v[0].shadowColor = packedShadowColor; |
2077 | + v[0].borderColor = packedBorderColor; |
2078 | + v[1].x = midW; |
2079 | + v[1].y = 0.0f; |
2080 | + v[1].shadowS = (offsetX + border + clampedShadow + midW) * textureFactor + textureOffset; |
2081 | + v[1].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
2082 | + v[1].midShadowS = midShadowS; |
2083 | + v[1].midShadowT = midShadowT; |
2084 | + v[1].borderS = (midW + borderOffset) * borderTextureFactor + borderTextureOffset; |
2085 | + v[1].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2086 | + v[1].color = packedColor; |
2087 | + v[1].shadowColor = packedShadowColor; |
2088 | + v[1].borderColor = packedBorderColor; |
2089 | + v[2].x = w - clampedRadius; |
2090 | + v[2].y = 0.0f; |
2091 | + v[2].shadowS = |
2092 | + (offsetX + border + clampedShadow + (w - clampedRadius)) * textureFactor + textureOffset; |
2093 | + v[2].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
2094 | + v[2].midShadowS = midShadowS; |
2095 | + v[2].midShadowT = midShadowT; |
2096 | + v[2].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2097 | + v[2].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2098 | + v[2].color = packedColor; |
2099 | + v[2].shadowColor = packedShadowColor; |
2100 | + v[2].borderColor = packedBorderColor; |
2101 | + v[3].x = 0.0f; |
2102 | + v[3].y = clampedRadius; |
2103 | + v[3].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
2104 | + v[3].shadowT = (offsetY + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2105 | + v[3].midShadowS = midShadowS; |
2106 | + v[3].midShadowT = midShadowT; |
2107 | + v[3].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2108 | + v[3].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2109 | + v[3].color = packedColor; |
2110 | + v[3].shadowColor = packedShadowColor; |
2111 | + v[3].borderColor = packedBorderColor; |
2112 | + v[4].x = w; |
2113 | + v[4].y = clampedRadius; |
2114 | + v[4].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
2115 | + v[4].shadowT = (offsetY + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2116 | + v[4].midShadowS = midShadowS; |
2117 | + v[4].midShadowT = midShadowT; |
2118 | + v[4].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2119 | + v[4].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2120 | + v[4].color = packedColor; |
2121 | + v[4].shadowColor = packedShadowColor; |
2122 | + v[4].borderColor = packedBorderColor; |
2123 | + v[5].x = 0.0f; |
2124 | + v[5].y = midH; |
2125 | + v[5].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
2126 | + v[5].shadowT = (offsetY + border + clampedShadow + midH) * textureFactor + textureOffset; |
2127 | + v[5].midShadowS = midShadowS; |
2128 | + v[5].midShadowT = midShadowT; |
2129 | + v[5].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2130 | + v[5].borderT = (midH + borderOffset) * borderTextureFactor + borderTextureOffset; |
2131 | + v[5].color = packedColor; |
2132 | + v[5].shadowColor = packedShadowColor; |
2133 | + v[5].borderColor = packedBorderColor; |
2134 | + v[6].x = midW; |
2135 | + v[6].y = midH; |
2136 | + v[6].shadowS = (offsetX + border + clampedShadow + midW) * textureFactor + textureOffset; |
2137 | + v[6].shadowT = (offsetY + border + clampedShadow + midH) * textureFactor + textureOffset; |
2138 | + v[6].midShadowS = midShadowS; |
2139 | + v[6].midShadowT = midShadowT; |
2140 | + v[6].borderS = (midW + borderOffset) * borderTextureFactor + borderTextureOffset; |
2141 | + v[6].borderT = (midH + borderOffset) * borderTextureFactor + borderTextureOffset; |
2142 | + v[6].color = packedColor; |
2143 | + v[6].shadowColor = packedShadowColor; |
2144 | + v[6].borderColor = packedBorderColor; |
2145 | + v[7].x = w; |
2146 | + v[7].y = midH; |
2147 | + v[7].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
2148 | + v[7].shadowT = (offsetY + border + clampedShadow + midH) * textureFactor + textureOffset; |
2149 | + v[7].midShadowS = midShadowS; |
2150 | + v[7].midShadowT = midShadowT; |
2151 | + v[7].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2152 | + v[7].borderT = (midH + borderOffset) * borderTextureFactor + borderTextureOffset; |
2153 | + v[7].color = packedColor; |
2154 | + v[7].shadowColor = packedShadowColor; |
2155 | + v[7].borderColor = packedBorderColor; |
2156 | + v[8].x = 0.0f; |
2157 | + v[8].y = h - clampedRadius; |
2158 | + v[8].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
2159 | + v[8].shadowT = |
2160 | + (offsetY + border + clampedShadow + (h - clampedRadius)) * textureFactor + textureOffset; |
2161 | + v[8].midShadowS = midShadowS; |
2162 | + v[8].midShadowT = midShadowT; |
2163 | + v[8].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2164 | + v[8].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2165 | + v[8].color = packedColor; |
2166 | + v[8].shadowColor = packedShadowColor; |
2167 | + v[8].borderColor = packedBorderColor; |
2168 | + v[9].x = w; |
2169 | + v[9].y = h - clampedRadius; |
2170 | + v[9].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
2171 | + v[9].shadowT = |
2172 | + (offsetY + border + clampedShadow + (h - clampedRadius)) * textureFactor + textureOffset; |
2173 | + v[9].midShadowS = midShadowS; |
2174 | + v[9].midShadowT = midShadowT; |
2175 | + v[9].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2176 | + v[9].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2177 | + v[9].color = packedColor; |
2178 | + v[9].shadowColor = packedShadowColor; |
2179 | + v[9].borderColor = packedBorderColor; |
2180 | + v[10].x = clampedRadius; |
2181 | + v[10].y = h; |
2182 | + v[10].shadowS = (offsetX + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2183 | + v[10].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
2184 | + v[10].midShadowS = midShadowS; |
2185 | + v[10].midShadowT = midShadowT; |
2186 | + v[10].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2187 | + v[10].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2188 | + v[10].color = packedColor; |
2189 | + v[10].shadowColor = packedShadowColor; |
2190 | + v[10].borderColor = packedBorderColor; |
2191 | + v[11].x = midW; |
2192 | + v[11].y = h; |
2193 | + v[11].shadowS = (offsetX + border + clampedShadow + midW) * textureFactor + textureOffset; |
2194 | + v[11].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
2195 | + v[11].midShadowS = midShadowS; |
2196 | + v[11].midShadowT = midShadowT; |
2197 | + v[11].borderS = (midW + borderOffset) * borderTextureFactor + borderTextureOffset; |
2198 | + v[11].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2199 | + v[11].color = packedColor; |
2200 | + v[11].shadowColor = packedShadowColor; |
2201 | + v[11].borderColor = packedBorderColor; |
2202 | + v[12].x = w - clampedRadius; |
2203 | + v[12].y = h; |
2204 | + v[12].shadowS = |
2205 | + (offsetX + border + clampedShadow + (w - clampedRadius)) * textureFactor + textureOffset; |
2206 | + v[12].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
2207 | + v[12].midShadowS = midShadowS; |
2208 | + v[12].midShadowT = midShadowT; |
2209 | + v[12].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2210 | + v[12].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2211 | + v[12].color = packedColor; |
2212 | + v[12].shadowColor = packedShadowColor; |
2213 | + v[12].borderColor = packedBorderColor; |
2214 | + markDirty(QSGNode::DirtyGeometry); |
2215 | + |
2216 | + // Update data for the preprocess() call. |
2217 | + const quint16 deviceRadius = static_cast<quint16>(clampedRadius * dpr); |
2218 | + if (m_radius != deviceRadius) { |
2219 | + m_radius = deviceRadius; |
2220 | + m_flags |= DirtyRadius; |
2221 | + } |
2222 | + const quint16 deviceShadow = static_cast<quint16>(clampedShadow * dpr); |
2223 | + if (m_shadow != deviceShadow) { |
2224 | + m_shadow = deviceShadow; |
2225 | + m_flags |= DirtyShadow; |
2226 | + } |
2227 | + const quint16 deviceBorderRadius = static_cast<quint16>(clampedBorderRadius * dpr); |
2228 | + if (m_borderRadius != deviceBorderRadius) { |
2229 | + m_borderRadius = deviceBorderRadius; |
2230 | + m_flags |= DirtyBorderRadius; |
2231 | + } |
2232 | + if (m_shape != static_cast<quint8>(type)) { |
2233 | + m_shape = static_cast<quint8>(type); |
2234 | + m_flags |= DirtyShape; |
2235 | + } |
2236 | + break; |
2237 | + } |
2238 | + |
2239 | + default: |
2240 | + DNOT_REACHED(); |
2241 | + } |
2242 | + |
2243 | + // Update the blending state of the opaque material (in QSG terms, an opaque |
2244 | + // material is the material automatically used when the opacity is 1, but |
2245 | + // even if the opacity is 1 we have to handle the case where the alpha of |
2246 | + // the specified color is less than 1). |
2247 | + const bool blending = qAlpha(color) < 255; |
2248 | + if (blending != static_cast<bool>(m_flags & Blending)) { |
2249 | + m_resources->opaqueMaterial()->setFlag(QSGMaterial::Blending, blending); |
2250 | + markDirty(QSGNode::DirtyMaterial); |
2251 | + m_flags = (m_flags & ~Blending) | (blending ? Blending : 0); |
2252 | + } |
2253 | +} |
2254 | + |
2255 | +UCShapeFillCornersNode::UCShapeFillCornersNode() |
2256 | + : QSGGeometryNode() |
2257 | + , m_resources(Q_NULLPTR) |
2258 | + , m_radius(0) |
2259 | + , m_shadow(0) |
2260 | + , m_borderRadius(0) |
2261 | + , m_flags(0) |
2262 | + , m_shape(UCShapeType::Squircle) |
2263 | +{ |
2264 | + DLOG("creating UCShapeFillCornersNode"); |
2265 | + setFlag(QSGNode::UsePreprocess, true); |
2266 | + qsgnode_set_description(this, QLatin1String("shapefillcorners")); |
2267 | +} |
2268 | + |
2269 | +UCShapeFillCornersNode::~UCShapeFillCornersNode() |
2270 | +{ |
2271 | + DLOG("detroying UCShapeFillCornersNode"); |
2272 | + delete m_resources; |
2273 | +} |
2274 | + |
2275 | +void UCShapeFillCornersNode::preprocess() |
2276 | +{ |
2277 | + // FIXME(loicm) Could be made more consise (texture update methods in the resources?). |
2278 | + |
2279 | + switch (m_flags & StyleMask) { |
2280 | + case (HasColor): |
2281 | + if (m_flags & (DirtyRadius | DirtyShape)) { |
2282 | + static_cast<UCShapeColorMaskMaterial<false>*>( |
2283 | + m_resources->material())->updateMaskTexture( |
2284 | + static_cast<UCShapeType>(m_shape), m_radius); |
2285 | + static_cast<UCShapeColorMaskMaterial<true>*>( |
2286 | + m_resources->opaqueMaterial())->updateMaskTexture( |
2287 | + static_cast<UCShapeType>(m_shape), m_radius); |
2288 | + } |
2289 | + break; |
2290 | + |
2291 | + case (HasColor | HasShadow): |
2292 | + if (m_flags & (DirtyRadius | DirtyShadow | DirtyShape)) { |
2293 | + static_cast<UCShapeFillCornersShadowMaterial<false>*>( |
2294 | + m_resources->material())->updateShadowTexture( |
2295 | + static_cast<UCShapeType>(m_shape), m_radius, m_shadow); |
2296 | + static_cast<UCShapeFillCornersShadowMaterial<true>*>( |
2297 | + m_resources->opaqueMaterial())->updateShadowTexture( |
2298 | + static_cast<UCShapeType>(m_shape), m_radius, m_shadow); |
2299 | + } |
2300 | + break; |
2301 | + |
2302 | + case (HasColor | HasBorder): |
2303 | + if (m_flags & (DirtyRadius | DirtyShape)) { |
2304 | + static_cast<UCShapeFillCornersBorderMaterial<false>*>( |
2305 | + m_resources->material())->updateMaskTexture( |
2306 | + static_cast<UCShapeType>(m_shape), m_radius); |
2307 | + static_cast<UCShapeFillCornersBorderMaterial<true>*>( |
2308 | + m_resources->opaqueMaterial())->updateMaskTexture( |
2309 | + static_cast<UCShapeType>(m_shape), m_radius); |
2310 | + } |
2311 | + if (m_flags & (DirtyBorderRadius | DirtyShape)) { |
2312 | + static_cast<UCShapeFillCornersBorderMaterial<false>*>( |
2313 | + m_resources->material())->updateBorderTexture( |
2314 | + static_cast<UCShapeType>(m_shape), m_borderRadius); |
2315 | + static_cast<UCShapeFillCornersBorderMaterial<true>*>( |
2316 | + m_resources->opaqueMaterial())->updateBorderTexture( |
2317 | + static_cast<UCShapeType>(m_shape), m_borderRadius); |
2318 | + } |
2319 | + break; |
2320 | + |
2321 | + case (HasColor | HasShadow | HasBorder): |
2322 | + if (m_flags & (DirtyRadius | DirtyShadow | DirtyShape)) { |
2323 | + static_cast<UCShapeFillCornersShadowBorderMaterial<false>*>( |
2324 | + m_resources->material())->updateShadowTexture( |
2325 | + static_cast<UCShapeType>(m_shape), m_radius, m_shadow); |
2326 | + static_cast<UCShapeFillCornersShadowBorderMaterial<true>*>( |
2327 | + m_resources->opaqueMaterial())->updateShadowTexture( |
2328 | + static_cast<UCShapeType>(m_shape), m_radius, m_shadow); |
2329 | + } |
2330 | + if (m_flags & (DirtyBorderRadius | DirtyShape)) { |
2331 | + static_cast<UCShapeFillCornersShadowBorderMaterial<false>*>( |
2332 | + m_resources->material())->updateBorderTexture( |
2333 | + static_cast<UCShapeType>(m_shape), m_borderRadius); |
2334 | + static_cast<UCShapeFillCornersShadowBorderMaterial<true>*>( |
2335 | + m_resources->opaqueMaterial())->updateBorderTexture( |
2336 | + static_cast<UCShapeType>(m_shape), m_borderRadius); |
2337 | + } |
2338 | + break; |
2339 | + |
2340 | + default: |
2341 | + NOT_REACHED(); |
2342 | + } |
2343 | + |
2344 | + m_flags &= ~DirtyMask; |
2345 | +} |
2346 | + |
2347 | +void UCShapeFillCornersNode::setVisible(bool visible) |
2348 | +{ |
2349 | + DLOG("UCShapeFillCornersNode::setVisible %d", visible); |
2350 | + if (static_cast<bool>(m_flags & Visible) != visible) { |
2351 | + m_flags = (m_flags & ~Visible) | (visible ? Visible : 0); |
2352 | + markDirty(DirtySubtreeBlocked); |
2353 | + } |
2354 | +} |
2355 | + |
2356 | +void UCShapeFillCornersNode::update( |
2357 | + const QSizeF& itemSize, UCShapeType type, float radius, QRgb color, float shadowSize, |
2358 | + float shadowAngle, float shadowDistance, QRgb shadowColor, float borderSize, QRgb borderColor) |
2359 | +{ |
2360 | + // The geometry is made of 12 vertices indexed with a triangles mode. |
2361 | + // 0 - 1 2 - 3 |
2362 | + // | / \ | |
2363 | + // 4 5 |
2364 | + // |
2365 | + // 6 7 |
2366 | + // | \ / | |
2367 | + // 8 - 9 10 - 11 |
2368 | + const quint16 indices[] = { 1, 0, 4, 6, 8, 9, 10, 11, 7, 5, 3, 2 }; |
2369 | + const int indexCount = ARRAY_SIZE(indices); |
2370 | + const int vertexCount = 12; |
2371 | + |
2372 | + quint16 style = ((shadowSize <= 0.0f && shadowDistance <= 0.0f) || (qAlpha(shadowColor) == 0)) ? |
2373 | + HasColor : (HasColor | HasShadow); |
2374 | + if (borderSize >= 1.0f) { |
2375 | + style |= HasBorder; |
2376 | + } |
2377 | + |
2378 | + // Create new material/geometry set if needed. |
2379 | + if (style != (m_flags & StyleMask)) { |
2380 | + delete m_resources; |
2381 | + switch (style) { |
2382 | + case HasColor: |
2383 | + m_resources = new UCShapeColorMaskResources(vertexCount, indexCount); |
2384 | + break; |
2385 | + case (HasColor | HasShadow): |
2386 | + m_resources = new UCShapeFillCornersShadowResources(vertexCount, indexCount); |
2387 | + break; |
2388 | + case (HasColor | HasBorder): |
2389 | + m_resources = new UCShapeFillCornersBorderResources(vertexCount, indexCount); |
2390 | + break; |
2391 | + case (HasColor | HasShadow | HasBorder): |
2392 | + m_resources = new UCShapeFillCornersShadowBorderResources(vertexCount, indexCount); |
2393 | + break; |
2394 | + default: |
2395 | + NOT_REACHED(); |
2396 | + } |
2397 | + setMaterial(m_resources->material()); |
2398 | + m_resources->opaqueMaterial()->setFlag(QSGMaterial::Blending); |
2399 | + setOpaqueMaterial(m_resources->opaqueMaterial()); |
2400 | + memcpy(m_resources->geometry()->indexData(), indices, indexCount * sizeof(quint16)); |
2401 | + setGeometry(m_resources->geometry()); |
2402 | + m_flags = (m_flags & ~StyleMask) | style | DirtyMask; |
2403 | + } |
2404 | + |
2405 | + const float dpr = qGuiApp->devicePixelRatio(); |
2406 | + const float w = floorf(static_cast<float>(itemSize.width())); |
2407 | + const float h = floorf(static_cast<float>(itemSize.height())); |
2408 | + // Rounded down since Shadow doesn't support sub-pixel rendering. |
2409 | + const float maxSize = floorf(qMin(w, h) * 0.5f); |
2410 | + const float clampedRadius = qMin(floorf(radius), maxSize); |
2411 | + const quint32 packedColor = packColor(color); |
2412 | + |
2413 | + // Update geometry depending on the style. |
2414 | + switch (style) { |
2415 | + case HasColor: { |
2416 | + UCShapeColorMaskResources::Vertex* v = |
2417 | + reinterpret_cast<UCShapeColorMaskResources::Vertex*>( |
2418 | + m_resources->geometry()->vertexData()); |
2419 | + const float deviceRadius = clampedRadius * dpr; |
2420 | + const float border = 1.0f; |
2421 | + const float textureSize = deviceRadius + 2 * border; |
2422 | + const float textureSizeRounded = roundUp(static_cast<int>(textureSize), textureRounding); |
2423 | + const float textureStart = (textureSizeRounded - textureSize + border) / textureSizeRounded; |
2424 | + const float textureEnd = (textureSizeRounded - border) / textureSizeRounded; |
2425 | + v[0].x = 0.0f; |
2426 | + v[0].y = 0.0f; |
2427 | + v[0].maskS = textureStart; |
2428 | + v[0].maskT = textureStart; |
2429 | + v[0].color = packedColor; |
2430 | + v[1].x = clampedRadius; |
2431 | + v[1].y = 0.0f; |
2432 | + v[1].maskS = textureEnd; |
2433 | + v[1].maskT = textureStart; |
2434 | + v[1].color = packedColor; |
2435 | + v[2].x = w - clampedRadius; |
2436 | + v[2].y = 0.0f; |
2437 | + v[2].maskS = textureEnd; |
2438 | + v[2].maskT = textureStart; |
2439 | + v[2].color = packedColor; |
2440 | + v[3].x = w; |
2441 | + v[3].y = 0.0f; |
2442 | + v[3].maskS = textureStart; |
2443 | + v[3].maskT = textureStart; |
2444 | + v[3].color = packedColor; |
2445 | + v[4].x = 0.0f; |
2446 | + v[4].y = clampedRadius; |
2447 | + v[4].maskS = textureStart; |
2448 | + v[4].maskT = textureEnd; |
2449 | + v[4].color = packedColor; |
2450 | + v[5].x = w; |
2451 | + v[5].y = clampedRadius; |
2452 | + v[5].maskS = textureStart; |
2453 | + v[5].maskT = textureEnd; |
2454 | + v[5].color = packedColor; |
2455 | + v[6].x = 0.0f; |
2456 | + v[6].y = h - clampedRadius; |
2457 | + v[6].maskS = textureStart; |
2458 | + v[6].maskT = textureEnd; |
2459 | + v[6].color = packedColor; |
2460 | + v[7].x = w; |
2461 | + v[7].y = h - clampedRadius; |
2462 | + v[7].maskS = textureStart; |
2463 | + v[7].maskT = textureEnd; |
2464 | + v[7].color = packedColor; |
2465 | + v[8].x = 0.0f; |
2466 | + v[8].y = h; |
2467 | + v[8].maskS = textureStart; |
2468 | + v[8].maskT = textureStart; |
2469 | + v[8].color = packedColor; |
2470 | + v[9].x = clampedRadius; |
2471 | + v[9].y = h; |
2472 | + v[9].maskS = textureEnd; |
2473 | + v[9].maskT = textureStart; |
2474 | + v[9].color = packedColor; |
2475 | + v[10].x = w - clampedRadius; |
2476 | + v[10].y = h; |
2477 | + v[10].maskS = textureEnd; |
2478 | + v[10].maskT = textureStart; |
2479 | + v[10].color = packedColor; |
2480 | + v[11].x = w; |
2481 | + v[11].y = h; |
2482 | + v[11].maskS = textureStart; |
2483 | + v[11].maskT = textureStart; |
2484 | + v[11].color = packedColor; |
2485 | + markDirty(QSGNode::DirtyGeometry); |
2486 | + |
2487 | + // Update data for the preprocess() call. |
2488 | + if (m_radius != static_cast<quint16>(deviceRadius)) { |
2489 | + m_radius = static_cast<quint16>(deviceRadius); |
2490 | + m_flags |= DirtyRadius; |
2491 | + } |
2492 | + if (m_shape != static_cast<quint8>(type)) { |
2493 | + m_shape = static_cast<quint8>(type); |
2494 | + m_flags |= DirtyShape; |
2495 | + } |
2496 | + break; |
2497 | + } |
2498 | + |
2499 | + case (HasColor | HasShadow): { |
2500 | + UCShapeFillCornersShadowResources::Vertex* v = |
2501 | + reinterpret_cast<UCShapeFillCornersShadowResources::Vertex*>( |
2502 | + m_resources->geometry()->vertexData()); |
2503 | + float s, c; |
2504 | + sincosf(shadowAngle * -(M_PI / 180.0f), &s, &c); |
2505 | + const float offsetX = roundf(c * shadowDistance); |
2506 | + const float offsetY = roundf(s * shadowDistance); |
2507 | + const float clampedShadow = qMin(floorf(shadowSize), maxSize); |
2508 | + const float border = 1.0f; |
2509 | + const float textureSize = (2.0f * clampedShadow + 2.0f * border + clampedRadius) * dpr; |
2510 | + const float textureSizeRounded = roundUp(static_cast<int>(textureSize), textureRounding); |
2511 | + const float textureOffset = (textureSizeRounded - textureSize) / textureSizeRounded; |
2512 | + const float textureFactor = ((1.0f - textureOffset) * dpr) / textureSize; |
2513 | + const float midShadowS = (border + clampedShadow + (w * 0.5f)) * textureFactor + textureOffset; |
2514 | + const float midShadowT = (border + clampedShadow + (h * 0.5f)) * textureFactor + textureOffset; |
2515 | + const quint32 packedShadowColor = packColor(shadowColor); |
2516 | + v[0].x = 0.0f; |
2517 | + v[0].y = 0.0f; |
2518 | + v[0].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2519 | + v[0].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2520 | + v[0].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
2521 | + v[0].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
2522 | + v[0].midShadowS = midShadowS; |
2523 | + v[0].midShadowT = midShadowT; |
2524 | + v[0].color = packedColor; |
2525 | + v[0].shadowColor = packedShadowColor; |
2526 | + v[1].x = clampedRadius; |
2527 | + v[1].y = 0.0f; |
2528 | + v[1].maskS = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2529 | + v[1].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2530 | + v[1].shadowS = (offsetX + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2531 | + v[1].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
2532 | + v[1].midShadowS = midShadowS; |
2533 | + v[1].midShadowT = midShadowT; |
2534 | + v[1].color = packedColor; |
2535 | + v[1].shadowColor = packedShadowColor; |
2536 | + v[2].x = w - clampedRadius; |
2537 | + v[2].y = 0.0f; |
2538 | + v[2].maskS = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2539 | + v[2].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2540 | + v[2].shadowS = |
2541 | + (offsetX + border + clampedShadow + (w - clampedRadius)) * textureFactor + textureOffset; |
2542 | + v[2].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
2543 | + v[2].midShadowS = midShadowS; |
2544 | + v[2].midShadowT = midShadowT; |
2545 | + v[2].color = packedColor; |
2546 | + v[2].shadowColor = packedShadowColor; |
2547 | + v[3].x = w; |
2548 | + v[3].y = 0.0f; |
2549 | + v[3].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2550 | + v[3].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2551 | + v[3].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
2552 | + v[3].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
2553 | + v[3].midShadowS = midShadowS; |
2554 | + v[3].midShadowT = midShadowT; |
2555 | + v[3].color = packedColor; |
2556 | + v[3].shadowColor = packedShadowColor; |
2557 | + v[4].x = 0.0f; |
2558 | + v[4].y = clampedRadius; |
2559 | + v[4].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2560 | + v[4].maskT = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2561 | + v[4].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
2562 | + v[4].shadowT = (offsetY + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2563 | + v[4].midShadowS = midShadowS; |
2564 | + v[4].midShadowT = midShadowT; |
2565 | + v[4].color = packedColor; |
2566 | + v[4].shadowColor = packedShadowColor; |
2567 | + v[5].x = w; |
2568 | + v[5].y = clampedRadius; |
2569 | + v[5].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2570 | + v[5].maskT = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2571 | + v[5].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
2572 | + v[5].shadowT = (offsetY + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2573 | + v[5].midShadowS = midShadowS; |
2574 | + v[5].midShadowT = midShadowT; |
2575 | + v[5].color = packedColor; |
2576 | + v[5].shadowColor = packedShadowColor; |
2577 | + v[6].x = 0.0f; |
2578 | + v[6].y = h - clampedRadius; |
2579 | + v[6].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2580 | + v[6].maskT = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2581 | + v[6].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
2582 | + v[6].shadowT = |
2583 | + (offsetY + border + clampedShadow + (h - clampedRadius)) * textureFactor + textureOffset; |
2584 | + v[6].midShadowS = midShadowS; |
2585 | + v[6].midShadowT = midShadowT; |
2586 | + v[6].color = packedColor; |
2587 | + v[6].shadowColor = packedShadowColor; |
2588 | + v[7].x = w; |
2589 | + v[7].y = h - clampedRadius; |
2590 | + v[7].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2591 | + v[7].maskT = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2592 | + v[7].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
2593 | + v[7].shadowT = |
2594 | + (offsetY + border + clampedShadow + (h - clampedRadius)) * textureFactor + textureOffset; |
2595 | + v[7].midShadowS = midShadowS; |
2596 | + v[7].midShadowT = midShadowT; |
2597 | + v[7].color = packedColor; |
2598 | + v[7].shadowColor = packedShadowColor; |
2599 | + v[8].x = 0.0f; |
2600 | + v[8].y = h; |
2601 | + v[8].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2602 | + v[8].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2603 | + v[8].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
2604 | + v[8].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
2605 | + v[8].midShadowS = midShadowS; |
2606 | + v[8].midShadowT = midShadowT; |
2607 | + v[8].color = packedColor; |
2608 | + v[8].shadowColor = packedShadowColor; |
2609 | + v[9].x = clampedRadius; |
2610 | + v[9].y = h; |
2611 | + v[9].maskS = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2612 | + v[9].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2613 | + v[9].shadowS = (offsetX + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2614 | + v[9].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
2615 | + v[9].midShadowS = midShadowS; |
2616 | + v[9].midShadowT = midShadowT; |
2617 | + v[9].color = packedColor; |
2618 | + v[9].shadowColor = packedShadowColor; |
2619 | + v[10].x = w - clampedRadius; |
2620 | + v[10].y = h; |
2621 | + v[10].maskS = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2622 | + v[10].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2623 | + v[10].shadowS = |
2624 | + (offsetX + border + clampedShadow + (w - clampedRadius)) * textureFactor + textureOffset; |
2625 | + v[10].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
2626 | + v[10].midShadowS = midShadowS; |
2627 | + v[10].midShadowT = midShadowT; |
2628 | + v[10].color = packedColor; |
2629 | + v[10].shadowColor = packedShadowColor; |
2630 | + v[11].x = w; |
2631 | + v[11].y = h; |
2632 | + v[11].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2633 | + v[11].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2634 | + v[11].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
2635 | + v[11].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
2636 | + v[11].midShadowS = midShadowS; |
2637 | + v[11].midShadowT = midShadowT; |
2638 | + v[11].color = packedColor; |
2639 | + v[11].shadowColor = packedShadowColor; |
2640 | + markDirty(QSGNode::DirtyGeometry); |
2641 | + |
2642 | + // Update data for the preprocess() call. |
2643 | + const quint16 deviceShadow = static_cast<quint16>(clampedShadow * dpr); |
2644 | + if (m_shadow != deviceShadow) { |
2645 | + m_shadow = deviceShadow; |
2646 | + m_flags |= DirtyShadow; |
2647 | + } |
2648 | + const quint16 deviceRadius = static_cast<quint16>(clampedRadius * dpr); |
2649 | + if (m_radius != deviceRadius) { |
2650 | + m_radius = deviceRadius; |
2651 | + m_flags |= DirtyRadius; |
2652 | + } |
2653 | + if (m_shape != static_cast<quint8>(type)) { |
2654 | + m_shape = static_cast<quint8>(type); |
2655 | + m_flags |= DirtyShape; |
2656 | + } |
2657 | + break; |
2658 | + } |
2659 | + |
2660 | + case (HasColor | HasBorder): { |
2661 | + UCShapeFillCornersBorderResources::Vertex* v = |
2662 | + reinterpret_cast<UCShapeFillCornersBorderResources::Vertex*>( |
2663 | + m_resources->geometry()->vertexData()); |
2664 | + const float deviceRadius = clampedRadius * dpr; |
2665 | + const float maskBorder = 1.0f; |
2666 | + const float maskTextureSize = deviceRadius + 2.0f * maskBorder; |
2667 | + const float maskTextureSizeRounded = |
2668 | + roundUp(static_cast<int>(maskTextureSize), textureRounding); |
2669 | + const float maskTextureStart = |
2670 | + (maskTextureSizeRounded - maskTextureSize + maskBorder) / maskTextureSizeRounded; |
2671 | + const float maskTextureEnd = (maskTextureSizeRounded - maskBorder) / maskTextureSizeRounded; |
2672 | + const float clampedBorder = qMin(floorf(borderSize), maxSize); |
2673 | + const float clampedBorderRadius = |
2674 | + floorf(((maxSize - clampedBorder) / maxSize) * clampedRadius); |
2675 | + const float textureBorder = 1.0f; |
2676 | + const float borderTextureSize = (2.0f * textureBorder + clampedBorderRadius) * dpr; |
2677 | + const float borderTextureSizeRounded = |
2678 | + roundUp(static_cast<int>(borderTextureSize), textureRounding); |
2679 | + const float borderTextureOffset = |
2680 | + (borderTextureSizeRounded - borderTextureSize) / borderTextureSizeRounded; |
2681 | + const float borderTextureFactor = ((1.0f - borderTextureOffset) * dpr) / borderTextureSize; |
2682 | + const float borderOffset = -(clampedBorder - textureBorder); |
2683 | + const quint32 packedBorderColor = packColor(borderColor); |
2684 | + v[0].x = 0.0f; |
2685 | + v[0].y = 0.0f; |
2686 | + v[0].maskS = maskTextureStart; |
2687 | + v[0].maskT = maskTextureStart; |
2688 | + v[0].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2689 | + v[0].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2690 | + v[0].color = packedColor; |
2691 | + v[0].borderColor = packedBorderColor; |
2692 | + v[1].x = clampedRadius; |
2693 | + v[1].y = 0.0f; |
2694 | + v[1].maskS = maskTextureEnd; |
2695 | + v[1].maskT = maskTextureStart; |
2696 | + v[1].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2697 | + v[1].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2698 | + v[1].color = packedColor; |
2699 | + v[1].borderColor = packedBorderColor; |
2700 | + v[2].x = w - clampedRadius; |
2701 | + v[2].y = 0.0f; |
2702 | + v[2].maskS = maskTextureEnd; |
2703 | + v[2].maskT = maskTextureStart; |
2704 | + v[2].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2705 | + v[2].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2706 | + v[2].color = packedColor; |
2707 | + v[2].borderColor = packedBorderColor; |
2708 | + v[3].x = w; |
2709 | + v[3].y = 0.0f; |
2710 | + v[3].maskS = maskTextureStart; |
2711 | + v[3].maskT = maskTextureStart; |
2712 | + v[3].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2713 | + v[3].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2714 | + v[3].color = packedColor; |
2715 | + v[3].borderColor = packedBorderColor; |
2716 | + v[4].x = 0.0f; |
2717 | + v[4].y = clampedRadius; |
2718 | + v[4].maskS = maskTextureStart; |
2719 | + v[4].maskT = maskTextureEnd; |
2720 | + v[4].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2721 | + v[4].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2722 | + v[4].color = packedColor; |
2723 | + v[4].borderColor = packedBorderColor; |
2724 | + v[5].x = w; |
2725 | + v[5].y = clampedRadius; |
2726 | + v[5].maskS = maskTextureStart; |
2727 | + v[5].maskT = maskTextureEnd; |
2728 | + v[5].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2729 | + v[5].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2730 | + v[5].color = packedColor; |
2731 | + v[5].borderColor = packedBorderColor; |
2732 | + v[6].x = 0.0f; |
2733 | + v[6].y = h - clampedRadius; |
2734 | + v[6].maskS = maskTextureStart; |
2735 | + v[6].maskT = maskTextureEnd; |
2736 | + v[6].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2737 | + v[6].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2738 | + v[6].color = packedColor; |
2739 | + v[6].borderColor = packedBorderColor; |
2740 | + v[7].x = w; |
2741 | + v[7].y = h - clampedRadius; |
2742 | + v[7].maskS = maskTextureStart; |
2743 | + v[7].maskT = maskTextureEnd; |
2744 | + v[7].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2745 | + v[7].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2746 | + v[7].color = packedColor; |
2747 | + v[7].borderColor = packedBorderColor; |
2748 | + v[8].x = 0.0f; |
2749 | + v[8].y = h; |
2750 | + v[8].maskS = maskTextureStart; |
2751 | + v[8].maskT = maskTextureStart; |
2752 | + v[8].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2753 | + v[8].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2754 | + v[8].color = packedColor; |
2755 | + v[8].borderColor = packedBorderColor; |
2756 | + v[9].x = clampedRadius; |
2757 | + v[9].y = h; |
2758 | + v[9].maskS = maskTextureEnd; |
2759 | + v[9].maskT = maskTextureStart; |
2760 | + v[9].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2761 | + v[9].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2762 | + v[9].color = packedColor; |
2763 | + v[9].borderColor = packedBorderColor; |
2764 | + v[10].x = w - clampedRadius; |
2765 | + v[10].y = h; |
2766 | + v[10].maskS = maskTextureEnd; |
2767 | + v[10].maskT = maskTextureStart; |
2768 | + v[10].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2769 | + v[10].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2770 | + v[10].color = packedColor; |
2771 | + v[10].borderColor = packedBorderColor; |
2772 | + v[11].x = w; |
2773 | + v[11].y = h; |
2774 | + v[11].maskS = maskTextureStart; |
2775 | + v[11].maskT = maskTextureStart; |
2776 | + v[11].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2777 | + v[11].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2778 | + v[11].color = packedColor; |
2779 | + v[11].borderColor = packedBorderColor; |
2780 | + markDirty(QSGNode::DirtyGeometry); |
2781 | + |
2782 | + // Update data for the preprocess() call. |
2783 | + if (m_radius != static_cast<quint16>(deviceRadius)) { |
2784 | + m_radius = static_cast<quint16>(deviceRadius); |
2785 | + m_flags |= DirtyRadius; |
2786 | + } |
2787 | + const quint16 deviceBorderRadius = static_cast<quint16>(clampedBorderRadius * dpr); |
2788 | + if (m_borderRadius != deviceBorderRadius) { |
2789 | + m_borderRadius = deviceBorderRadius; |
2790 | + m_flags |= DirtyBorderRadius; |
2791 | + } |
2792 | + if (m_shape != static_cast<quint8>(type)) { |
2793 | + m_shape = static_cast<quint8>(type); |
2794 | + m_flags |= DirtyShape; |
2795 | + } |
2796 | + break; |
2797 | + } |
2798 | + |
2799 | + case (HasColor | HasShadow | HasBorder): { |
2800 | + UCShapeFillCornersShadowBorderResources::Vertex* v = |
2801 | + reinterpret_cast<UCShapeFillCornersShadowBorderResources::Vertex*>( |
2802 | + m_resources->geometry()->vertexData()); |
2803 | + float s, c; |
2804 | + sincosf(shadowAngle * -(M_PI / 180.0f), &s, &c); |
2805 | + const float offsetX = roundf(c * shadowDistance); |
2806 | + const float offsetY = roundf(s * shadowDistance); |
2807 | + const float clampedShadow = qMin(floorf(shadowSize), maxSize); |
2808 | + const float border = 1.0f; |
2809 | + const float textureSize = (2.0f * clampedShadow + 2.0f * border + clampedRadius) * dpr; |
2810 | + const float textureSizeRounded = roundUp(static_cast<int>(textureSize), textureRounding); |
2811 | + const float textureOffset = (textureSizeRounded - textureSize) / textureSizeRounded; |
2812 | + const float textureFactor = ((1.0f - textureOffset) * dpr) / textureSize; |
2813 | + const float midShadowS = (border + clampedShadow + (w * 0.5f)) * textureFactor + textureOffset; |
2814 | + const float midShadowT = (border + clampedShadow + (h * 0.5f)) * textureFactor + textureOffset; |
2815 | + const float clampedBorder = qMin(floorf(borderSize), maxSize); |
2816 | + const float clampedBorderRadius = |
2817 | + floorf(((maxSize - clampedBorder) / maxSize) * clampedRadius); |
2818 | + const float textureBorder = 1.0f; |
2819 | + const float borderTextureSize = (2.0f * textureBorder + clampedBorderRadius) * dpr; |
2820 | + const float borderTextureSizeRounded = |
2821 | + roundUp(static_cast<int>(borderTextureSize), textureRounding); |
2822 | + const float borderTextureOffset = |
2823 | + (borderTextureSizeRounded - borderTextureSize) / borderTextureSizeRounded; |
2824 | + const float borderTextureFactor = ((1.0f - borderTextureOffset) * dpr) / borderTextureSize; |
2825 | + const float borderOffset = -(clampedBorder - textureBorder); |
2826 | + const quint32 packedShadowColor = packColor(shadowColor); |
2827 | + const quint32 packedBorderColor = packColor(borderColor); |
2828 | + v[0].x = 0.0f; |
2829 | + v[0].y = 0.0f; |
2830 | + v[0].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2831 | + v[0].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2832 | + v[0].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
2833 | + v[0].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
2834 | + v[0].midShadowS = midShadowS; |
2835 | + v[0].midShadowT = midShadowT; |
2836 | + v[0].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2837 | + v[0].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2838 | + v[0].color = packedColor; |
2839 | + v[0].shadowColor = packedShadowColor; |
2840 | + v[0].borderColor = packedBorderColor; |
2841 | + v[1].x = clampedRadius; |
2842 | + v[1].y = 0.0f; |
2843 | + v[1].maskS = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2844 | + v[1].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2845 | + v[1].shadowS = (offsetX + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2846 | + v[1].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
2847 | + v[1].midShadowS = midShadowS; |
2848 | + v[1].midShadowT = midShadowT; |
2849 | + v[1].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2850 | + v[1].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2851 | + v[1].color = packedColor; |
2852 | + v[1].shadowColor = packedShadowColor; |
2853 | + v[1].borderColor = packedBorderColor; |
2854 | + v[2].x = w - clampedRadius; |
2855 | + v[2].y = 0.0f; |
2856 | + v[2].maskS = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2857 | + v[2].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2858 | + v[2].shadowS = |
2859 | + (offsetX + border + clampedShadow + (w - clampedRadius)) * textureFactor + textureOffset; |
2860 | + v[2].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
2861 | + v[2].midShadowS = midShadowS; |
2862 | + v[2].midShadowT = midShadowT; |
2863 | + v[2].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2864 | + v[2].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2865 | + v[2].color = packedColor; |
2866 | + v[2].shadowColor = packedShadowColor; |
2867 | + v[2].borderColor = packedBorderColor; |
2868 | + v[3].x = w; |
2869 | + v[3].y = 0.0f; |
2870 | + v[3].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2871 | + v[3].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2872 | + v[3].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
2873 | + v[3].shadowT = (offsetY + border + clampedShadow) * textureFactor + textureOffset; |
2874 | + v[3].midShadowS = midShadowS; |
2875 | + v[3].midShadowT = midShadowT; |
2876 | + v[3].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2877 | + v[3].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2878 | + v[3].color = packedColor; |
2879 | + v[3].shadowColor = packedShadowColor; |
2880 | + v[3].borderColor = packedBorderColor; |
2881 | + v[4].x = 0.0f; |
2882 | + v[4].y = clampedRadius; |
2883 | + v[4].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2884 | + v[4].maskT = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2885 | + v[4].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
2886 | + v[4].shadowT = (offsetY + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2887 | + v[4].midShadowS = midShadowS; |
2888 | + v[4].midShadowT = midShadowT; |
2889 | + v[4].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2890 | + v[4].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2891 | + v[4].color = packedColor; |
2892 | + v[4].shadowColor = packedShadowColor; |
2893 | + v[4].borderColor = packedBorderColor; |
2894 | + v[5].x = w; |
2895 | + v[5].y = clampedRadius; |
2896 | + v[5].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2897 | + v[5].maskT = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2898 | + v[5].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
2899 | + v[5].shadowT = (offsetY + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2900 | + v[5].midShadowS = midShadowS; |
2901 | + v[5].midShadowT = midShadowT; |
2902 | + v[5].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2903 | + v[5].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2904 | + v[5].color = packedColor; |
2905 | + v[5].shadowColor = packedShadowColor; |
2906 | + v[5].borderColor = packedBorderColor; |
2907 | + v[6].x = 0.0f; |
2908 | + v[6].y = h - clampedRadius; |
2909 | + v[6].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2910 | + v[6].maskT = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2911 | + v[6].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
2912 | + v[6].shadowT = |
2913 | + (offsetY + border + clampedShadow + (h - clampedRadius)) * textureFactor + textureOffset; |
2914 | + v[6].midShadowS = midShadowS; |
2915 | + v[6].midShadowT = midShadowT; |
2916 | + v[6].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2917 | + v[6].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2918 | + v[6].color = packedColor; |
2919 | + v[6].shadowColor = packedShadowColor; |
2920 | + v[6].borderColor = packedBorderColor; |
2921 | + v[7].x = w; |
2922 | + v[7].y = h - clampedRadius; |
2923 | + v[7].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2924 | + v[7].maskT = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2925 | + v[7].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
2926 | + v[7].shadowT = |
2927 | + (offsetY + border + clampedShadow + (h - clampedRadius)) * textureFactor + textureOffset; |
2928 | + v[7].midShadowS = midShadowS; |
2929 | + v[7].midShadowT = midShadowT; |
2930 | + v[7].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2931 | + v[7].borderT = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2932 | + v[7].color = packedColor; |
2933 | + v[7].shadowColor = packedShadowColor; |
2934 | + v[7].borderColor = packedBorderColor; |
2935 | + v[8].x = 0.0f; |
2936 | + v[8].y = h; |
2937 | + v[8].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2938 | + v[8].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2939 | + v[8].shadowS = (offsetX + border + clampedShadow) * textureFactor + textureOffset; |
2940 | + v[8].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
2941 | + v[8].midShadowS = midShadowS; |
2942 | + v[8].midShadowT = midShadowT; |
2943 | + v[8].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2944 | + v[8].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2945 | + v[8].color = packedColor; |
2946 | + v[8].shadowColor = packedShadowColor; |
2947 | + v[8].borderColor = packedBorderColor; |
2948 | + v[9].x = clampedRadius; |
2949 | + v[9].y = h; |
2950 | + v[9].maskS = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2951 | + v[9].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2952 | + v[9].shadowS = (offsetX + border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2953 | + v[9].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
2954 | + v[9].midShadowS = midShadowS; |
2955 | + v[9].midShadowT = midShadowT; |
2956 | + v[9].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2957 | + v[9].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2958 | + v[9].color = packedColor; |
2959 | + v[9].shadowColor = packedShadowColor; |
2960 | + v[9].borderColor = packedBorderColor; |
2961 | + v[10].x = w - clampedRadius; |
2962 | + v[10].y = h; |
2963 | + v[10].maskS = (border + clampedShadow + clampedRadius) * textureFactor + textureOffset; |
2964 | + v[10].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2965 | + v[10].shadowS = |
2966 | + (offsetX + border + clampedShadow + (w - clampedRadius)) * textureFactor + textureOffset; |
2967 | + v[10].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
2968 | + v[10].midShadowS = midShadowS; |
2969 | + v[10].midShadowT = midShadowT; |
2970 | + v[10].borderS = (clampedRadius + borderOffset) * borderTextureFactor + borderTextureOffset; |
2971 | + v[10].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2972 | + v[10].color = packedColor; |
2973 | + v[10].shadowColor = packedShadowColor; |
2974 | + v[10].borderColor = packedBorderColor; |
2975 | + v[11].x = w; |
2976 | + v[11].y = h; |
2977 | + v[11].maskS = (border + clampedShadow) * textureFactor + textureOffset; |
2978 | + v[11].maskT = (border + clampedShadow) * textureFactor + textureOffset; |
2979 | + v[11].shadowS = (offsetX + border + clampedShadow + w) * textureFactor + textureOffset; |
2980 | + v[11].shadowT = (offsetY + border + clampedShadow + h) * textureFactor + textureOffset; |
2981 | + v[11].midShadowS = midShadowS; |
2982 | + v[11].midShadowT = midShadowT; |
2983 | + v[11].borderS = borderOffset * borderTextureFactor + borderTextureOffset; |
2984 | + v[11].borderT = borderOffset * borderTextureFactor + borderTextureOffset; |
2985 | + v[11].color = packedColor; |
2986 | + v[11].shadowColor = packedShadowColor; |
2987 | + v[11].borderColor = packedBorderColor; |
2988 | + markDirty(QSGNode::DirtyGeometry); |
2989 | + |
2990 | + // Update data for the preprocess() call. |
2991 | + const quint16 deviceRadius = static_cast<quint16>(clampedRadius * dpr); |
2992 | + if (m_radius != deviceRadius) { |
2993 | + m_radius = deviceRadius; |
2994 | + m_flags |= DirtyRadius; |
2995 | + } |
2996 | + const quint16 deviceShadow = static_cast<quint16>(clampedShadow * dpr); |
2997 | + if (m_shadow != deviceShadow) { |
2998 | + m_shadow = deviceShadow; |
2999 | + m_flags |= DirtyShadow; |
3000 | + } |
3001 | + const quint16 deviceBorderRadius = static_cast<quint16>(clampedBorderRadius * dpr); |
3002 | + if (m_borderRadius != deviceBorderRadius) { |
3003 | + m_borderRadius = deviceBorderRadius; |
3004 | + m_flags |= DirtyBorderRadius; |
3005 | + } |
3006 | + if (m_shape != static_cast<quint8>(type)) { |
3007 | + m_shape = static_cast<quint8>(type); |
3008 | + m_flags |= DirtyShape; |
3009 | + } |
3010 | + break; |
3011 | + } |
3012 | + |
3013 | + default: |
3014 | + DNOT_REACHED(); |
3015 | + } |
3016 | +} |
3017 | |
3018 | === added file 'src/UbuntuToolkit/privates/ucshapefillnodes_p.h' |
3019 | --- src/UbuntuToolkit/privates/ucshapefillnodes_p.h 1970-01-01 00:00:00 +0000 |
3020 | +++ src/UbuntuToolkit/privates/ucshapefillnodes_p.h 2016-12-14 07:25:05 +0000 |
3021 | @@ -0,0 +1,999 @@ |
3022 | +/* |
3023 | + * Copyright 2016 Canonical Ltd. |
3024 | + * |
3025 | + * This program is free software; you can redistribute it and/or modify |
3026 | + * it under the terms of the GNU Lesser General Public License as published by |
3027 | + * the Free Software Foundation; version 3. |
3028 | + * |
3029 | + * This program is distributed in the hope that it will be useful, |
3030 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3031 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3032 | + * GNU Lesser General Public License for more details. |
3033 | + * |
3034 | + * You should have received a copy of the GNU Lesser General Public License |
3035 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3036 | + * |
3037 | + * Author: Loïc Molinari <loic.molinari@canonical.com> |
3038 | + */ |
3039 | + |
3040 | +#ifndef UCSHAPEFILLNODES_P_H |
3041 | +#define UCSHAPEFILLNODES_P_H |
3042 | + |
3043 | +#include <QtQuick/QSGNode> |
3044 | + |
3045 | +#include <UbuntuToolkit/private/ucshapetexturefactory_p.h> |
3046 | +#include <UbuntuToolkit/private/ucshaperesources_p.h> |
3047 | + |
3048 | +// ################################ |
3049 | +// # Fill center shadow materials # |
3050 | +// ################################ |
3051 | + |
3052 | +class UCShapeFillCenterShadowOpaqueShader : public QSGMaterialShader |
3053 | +{ |
3054 | +public: |
3055 | + UCShapeFillCenterShadowOpaqueShader() { |
3056 | + setShaderSourceFile(QOpenGLShader::Vertex, |
3057 | + QStringLiteral(":/uc/privates/shaders/fillcentershadow.vert")); |
3058 | + setShaderSourceFile(QOpenGLShader::Fragment, |
3059 | + QStringLiteral(":/uc/privates/shaders/fillcentershadow_opaque.frag")); |
3060 | + } |
3061 | + char const* const* attributeNames() const Q_DECL_OVERRIDE { |
3062 | + static char const* const attributes[] = { |
3063 | + "positionAttrib", "shadowCoordAttrib", "midShadowCoordAttrib", "colorAttrib", |
3064 | + "shadowColorAttrib", 0 |
3065 | + }; |
3066 | + return attributes; |
3067 | + } |
3068 | + void initialize() Q_DECL_OVERRIDE { |
3069 | + QSGMaterialShader::initialize(); |
3070 | + program()->bind(); |
3071 | + program()->setUniformValue("shadowTexture", 0); |
3072 | + m_matrixId = program()->uniformLocation("matrix"); |
3073 | + } |
3074 | + void updateState( |
3075 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial*) Q_DECL_OVERRIDE { |
3076 | + QOpenGLFunctions* funcs = QOpenGLContext::currentContext()->functions(); |
3077 | + UCShapeTextureProvider* provider = dynamic_cast<UCShapeTextureProvider*>(newEffect); |
3078 | + funcs->glBindTexture(GL_TEXTURE_2D, provider->textureId()); |
3079 | + if (state.isMatrixDirty()) { |
3080 | + program()->setUniformValue(m_matrixId, state.combinedMatrix()); |
3081 | + } |
3082 | + } |
3083 | + |
3084 | +private: |
3085 | + int m_matrixId; |
3086 | +}; |
3087 | + |
3088 | +class UCShapeFillCenterShadowShader : public UCShapeFillCenterShadowOpaqueShader |
3089 | +{ |
3090 | +public: |
3091 | + UCShapeFillCenterShadowShader() : UCShapeFillCenterShadowOpaqueShader() { |
3092 | + setShaderSourceFile(QOpenGLShader::Fragment, |
3093 | + QStringLiteral(":/uc/privates/shaders/fillcentershadow.frag")); |
3094 | + } |
3095 | + void initialize() Q_DECL_OVERRIDE { |
3096 | + UCShapeFillCenterShadowOpaqueShader::initialize(); |
3097 | + m_opacityId = program()->uniformLocation("opacity"); |
3098 | + } |
3099 | + void updateState( |
3100 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect) Q_DECL_OVERRIDE { |
3101 | + UCShapeFillCenterShadowOpaqueShader::updateState(state, newEffect, oldEffect); |
3102 | + if (state.isOpacityDirty()) { |
3103 | + program()->setUniformValue(m_opacityId, state.opacity()); |
3104 | + } |
3105 | + } |
3106 | + |
3107 | +private: |
3108 | + int m_opacityId; |
3109 | +}; |
3110 | + |
3111 | +template <bool opaque> |
3112 | +class UCShapeFillCenterShadowMaterial : public QSGMaterial, public UCShapeTextureProvider |
3113 | +{ |
3114 | +public: |
3115 | + UCShapeFillCenterShadowMaterial() : m_textureId(0) { |
3116 | + setFlag(Blending, !opaque); |
3117 | + } |
3118 | + |
3119 | + QSGMaterialType* type() const Q_DECL_OVERRIDE { |
3120 | + static QSGMaterialType type[2]; |
3121 | + return opaque ? &type[0] : &type[1]; |
3122 | + } |
3123 | + QSGMaterialShader* createShader() const Q_DECL_OVERRIDE { |
3124 | + return opaque ? new UCShapeFillCenterShadowOpaqueShader : new UCShapeFillCenterShadowShader; |
3125 | + } |
3126 | + int compare(const QSGMaterial* other) const Q_DECL_OVERRIDE { |
3127 | + return reinterpret_cast<const UCShapeTextureProvider*>(other)->textureId() - m_textureId; |
3128 | + } |
3129 | + |
3130 | + quint32 textureId(int) const Q_DECL_OVERRIDE { |
3131 | + return m_textureId; |
3132 | + } |
3133 | + void updateShadowTexture(UCShapeType type, quint16 radius, quint16 shadow) { |
3134 | + m_textureId = m_textureFactory.shadowTexture(0, type, radius, shadow); |
3135 | + } |
3136 | + |
3137 | +private: |
3138 | + UCShapeTextureFactory<1> m_textureFactory; |
3139 | + quint32 m_textureId; |
3140 | +}; |
3141 | + |
3142 | +class UCShapeFillCenterShadowResources : public UCShapeResources |
3143 | +{ |
3144 | +public: |
3145 | + UCShapeFillCenterShadowResources( |
3146 | + int vertexCount, int indexCount, int indexType = GL_UNSIGNED_SHORT) |
3147 | + : m_geometry(attributeSet(), vertexCount, indexCount, indexType) { |
3148 | + m_geometry.setDrawingMode(GL_TRIANGLE_STRIP); |
3149 | + m_geometry.setIndexDataPattern(QSGGeometry::StaticPattern); |
3150 | + m_geometry.setVertexDataPattern(QSGGeometry::AlwaysUploadPattern); |
3151 | + } |
3152 | + |
3153 | + QSGMaterial* material() Q_DECL_OVERRIDE { return &m_material; } |
3154 | + QSGMaterial* opaqueMaterial() Q_DECL_OVERRIDE { return &m_opaqueMaterial; } |
3155 | + QSGGeometry* geometry() Q_DECL_OVERRIDE { return &m_geometry; } |
3156 | + |
3157 | + struct Vertex { |
3158 | + float x, y; |
3159 | + float shadowS, shadowT; |
3160 | + float midShadowS, midShadowT; |
3161 | + quint32 color; |
3162 | + quint32 shadowColor; |
3163 | + }; |
3164 | + |
3165 | +private: |
3166 | + static const QSGGeometry::AttributeSet& attributeSet() { |
3167 | + static const QSGGeometry::Attribute attributes[] = { |
3168 | + QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // x, y |
3169 | + QSGGeometry::Attribute::create(1, 2, GL_FLOAT), // shadowS, shadowT |
3170 | + QSGGeometry::Attribute::create(2, 2, GL_FLOAT), // midShadowS, midShadowT |
3171 | + QSGGeometry::Attribute::create(3, 4, GL_UNSIGNED_BYTE), // color |
3172 | + QSGGeometry::Attribute::create(4, 4, GL_UNSIGNED_BYTE) // shadowColor |
3173 | + }; |
3174 | + static const QSGGeometry::AttributeSet attributeSet = { |
3175 | + 5, sizeof(Vertex), attributes |
3176 | + }; |
3177 | + return attributeSet; |
3178 | + } |
3179 | + |
3180 | + UCShapeFillCenterShadowMaterial<false> m_material; |
3181 | + UCShapeFillCenterShadowMaterial<true> m_opaqueMaterial; |
3182 | + QSGGeometry m_geometry; |
3183 | +}; |
3184 | + |
3185 | +// ################################ |
3186 | +// # Fill center border materials # |
3187 | +// ################################ |
3188 | + |
3189 | +class UCShapeFillCenterBorderOpaqueShader : public QSGMaterialShader |
3190 | +{ |
3191 | +public: |
3192 | + UCShapeFillCenterBorderOpaqueShader() { |
3193 | + setShaderSourceFile( |
3194 | + QOpenGLShader::Vertex, QStringLiteral(":/uc/privates/shaders/fillcenterborder.vert")); |
3195 | + setShaderSourceFile( |
3196 | + QOpenGLShader::Fragment, QStringLiteral( |
3197 | + ":/uc/privates/shaders/fillcenterborder_opaque.frag")); |
3198 | + } |
3199 | + char const* const* attributeNames() const Q_DECL_OVERRIDE { |
3200 | + static char const* const attributes[] = { |
3201 | + "positionAttrib", "borderCoordAttrib", "colorAttrib", "borderColorAttrib", 0 |
3202 | + }; |
3203 | + return attributes; |
3204 | + } |
3205 | + void initialize() Q_DECL_OVERRIDE { |
3206 | + QSGMaterialShader::initialize(); |
3207 | + program()->bind(); |
3208 | + program()->setUniformValue("borderTexture", 0); |
3209 | + m_matrixId = program()->uniformLocation("matrix"); |
3210 | + } |
3211 | + void updateState( |
3212 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial*) Q_DECL_OVERRIDE { |
3213 | + QOpenGLFunctions* funcs = QOpenGLContext::currentContext()->functions(); |
3214 | + UCShapeTextureProvider* provider = dynamic_cast<UCShapeTextureProvider*>(newEffect); |
3215 | + funcs->glBindTexture(GL_TEXTURE_2D, provider->textureId()); |
3216 | + if (state.isMatrixDirty()) { |
3217 | + program()->setUniformValue(m_matrixId, state.combinedMatrix()); |
3218 | + } |
3219 | + } |
3220 | + |
3221 | +private: |
3222 | + int m_matrixId; |
3223 | +}; |
3224 | + |
3225 | +class UCShapeFillCenterBorderShader : public UCShapeFillCenterBorderOpaqueShader |
3226 | +{ |
3227 | +public: |
3228 | + UCShapeFillCenterBorderShader() : UCShapeFillCenterBorderOpaqueShader() { |
3229 | + setShaderSourceFile( |
3230 | + QOpenGLShader::Fragment, QStringLiteral(":/uc/privates/shaders/fillcenterborder.frag")); |
3231 | + } |
3232 | + void initialize() Q_DECL_OVERRIDE { |
3233 | + UCShapeFillCenterBorderOpaqueShader::initialize(); |
3234 | + m_opacityId = program()->uniformLocation("opacity"); |
3235 | + } |
3236 | + void updateState( |
3237 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect) Q_DECL_OVERRIDE { |
3238 | + UCShapeFillCenterBorderOpaqueShader::updateState(state, newEffect, oldEffect); |
3239 | + if (state.isOpacityDirty()) { |
3240 | + program()->setUniformValue(m_opacityId, state.opacity()); |
3241 | + } |
3242 | + } |
3243 | + |
3244 | +private: |
3245 | + int m_opacityId; |
3246 | +}; |
3247 | + |
3248 | +template <bool opaque> |
3249 | +class UCShapeFillCenterBorderMaterial : public QSGMaterial, public UCShapeTextureProvider |
3250 | +{ |
3251 | +public: |
3252 | + UCShapeFillCenterBorderMaterial() : m_textureId(0) { |
3253 | + setFlag(Blending, !opaque); |
3254 | + } |
3255 | + |
3256 | + QSGMaterialType* type() const Q_DECL_OVERRIDE { |
3257 | + static QSGMaterialType type[2]; |
3258 | + return opaque ? &type[0] : &type[1]; |
3259 | + } |
3260 | + QSGMaterialShader* createShader() const Q_DECL_OVERRIDE { |
3261 | + return opaque ? |
3262 | + new UCShapeFillCenterBorderOpaqueShader : new UCShapeFillCenterBorderShader; |
3263 | + } |
3264 | + int compare(const QSGMaterial* other) const Q_DECL_OVERRIDE { |
3265 | + return reinterpret_cast<const UCShapeTextureProvider*>(other)->textureId() - m_textureId; |
3266 | + } |
3267 | + |
3268 | + quint32 textureId(int) const Q_DECL_OVERRIDE { |
3269 | + return m_textureId; |
3270 | + } |
3271 | + void updateBorderTexture(UCShapeType type, quint16 radius) { |
3272 | + m_textureId = m_textureFactory.maskTexture(0, type, radius); |
3273 | + } |
3274 | + |
3275 | +private: |
3276 | + UCShapeTextureFactory<1> m_textureFactory; |
3277 | + quint32 m_textureId; |
3278 | +}; |
3279 | + |
3280 | +class UCShapeFillCenterBorderResources : public UCShapeResources |
3281 | +{ |
3282 | +public: |
3283 | + UCShapeFillCenterBorderResources( |
3284 | + int vertexCount, int indexCount, int indexType = GL_UNSIGNED_SHORT) |
3285 | + : m_geometry(attributeSet(), vertexCount, indexCount, indexType) { |
3286 | + m_geometry.setDrawingMode(GL_TRIANGLE_STRIP); |
3287 | + m_geometry.setIndexDataPattern(QSGGeometry::StaticPattern); |
3288 | + m_geometry.setVertexDataPattern(QSGGeometry::AlwaysUploadPattern); |
3289 | + } |
3290 | + |
3291 | + QSGMaterial* material() Q_DECL_OVERRIDE { return &m_material; } |
3292 | + QSGMaterial* opaqueMaterial() Q_DECL_OVERRIDE { return &m_opaqueMaterial; } |
3293 | + QSGGeometry* geometry() Q_DECL_OVERRIDE { return &m_geometry; } |
3294 | + |
3295 | + struct Vertex { |
3296 | + float x, y; |
3297 | + float borderS, borderT; |
3298 | + quint32 color; |
3299 | + quint32 borderColor; |
3300 | + }; |
3301 | + |
3302 | +private: |
3303 | + static const QSGGeometry::AttributeSet& attributeSet() { |
3304 | + static const QSGGeometry::Attribute attributes[] = { |
3305 | + QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // x, y |
3306 | + QSGGeometry::Attribute::create(1, 2, GL_FLOAT), // borderS, borderT |
3307 | + QSGGeometry::Attribute::create(2, 4, GL_UNSIGNED_BYTE), // color |
3308 | + QSGGeometry::Attribute::create(3, 4, GL_UNSIGNED_BYTE) // borderColor |
3309 | + }; |
3310 | + static const QSGGeometry::AttributeSet attributeSet = { |
3311 | + 4, sizeof(Vertex), attributes |
3312 | + }; |
3313 | + return attributeSet; |
3314 | + } |
3315 | + |
3316 | + UCShapeFillCenterBorderMaterial<false> m_material; |
3317 | + UCShapeFillCenterBorderMaterial<true> m_opaqueMaterial; |
3318 | + QSGGeometry m_geometry; |
3319 | +}; |
3320 | + |
3321 | +// ####################################### |
3322 | +// # Fill center shadow border materials # |
3323 | +// ####################################### |
3324 | + |
3325 | +class UCShapeFillCenterShadowBorderOpaqueShader : public QSGMaterialShader |
3326 | +{ |
3327 | +public: |
3328 | + UCShapeFillCenterShadowBorderOpaqueShader() { |
3329 | + setShaderSourceFile( |
3330 | + QOpenGLShader::Vertex, QStringLiteral( |
3331 | + ":/uc/privates/shaders/fillcentershadowborder.vert")); |
3332 | + setShaderSourceFile( |
3333 | + QOpenGLShader::Fragment, QStringLiteral( |
3334 | + ":/uc/privates/shaders/fillcentershadowborder_opaque.frag")); |
3335 | + } |
3336 | + char const* const* attributeNames() const Q_DECL_OVERRIDE { |
3337 | + static char const* const attributes[] = { |
3338 | + "positionAttrib", "shadowCoordAttrib", "midShadowCoordAttrib", "borderCoordAttrib", |
3339 | + "colorAttrib", "shadowColorAttrib", "borderColorAttrib", 0 |
3340 | + }; |
3341 | + return attributes; |
3342 | + } |
3343 | + void initialize() Q_DECL_OVERRIDE { |
3344 | + QSGMaterialShader::initialize(); |
3345 | + program()->bind(); |
3346 | + program()->setUniformValue("shadowTexture", 0); |
3347 | + program()->setUniformValue("borderTexture", 1); |
3348 | + m_matrixId = program()->uniformLocation("matrix"); |
3349 | + } |
3350 | + void updateState( |
3351 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial*) Q_DECL_OVERRIDE { |
3352 | + QOpenGLFunctions* funcs = QOpenGLContext::currentContext()->functions(); |
3353 | + UCShapeTextureProvider* provider = dynamic_cast<UCShapeTextureProvider*>(newEffect); |
3354 | + funcs->glActiveTexture(GL_TEXTURE1); |
3355 | + funcs->glBindTexture(GL_TEXTURE_2D, provider->textureId(1)); |
3356 | + funcs->glActiveTexture(GL_TEXTURE0); |
3357 | + funcs->glBindTexture(GL_TEXTURE_2D, provider->textureId(0)); |
3358 | + if (state.isMatrixDirty()) { |
3359 | + program()->setUniformValue(m_matrixId, state.combinedMatrix()); |
3360 | + } |
3361 | + } |
3362 | + |
3363 | +private: |
3364 | + int m_matrixId; |
3365 | +}; |
3366 | + |
3367 | +class UCShapeFillCenterShadowBorderShader : public UCShapeFillCenterShadowBorderOpaqueShader |
3368 | +{ |
3369 | +public: |
3370 | + UCShapeFillCenterShadowBorderShader() : UCShapeFillCenterShadowBorderOpaqueShader() { |
3371 | + setShaderSourceFile( |
3372 | + QOpenGLShader::Fragment, QStringLiteral( |
3373 | + ":/uc/privates/shaders/fillcentershadowborder.frag")); |
3374 | + } |
3375 | + void initialize() Q_DECL_OVERRIDE { |
3376 | + UCShapeFillCenterShadowBorderOpaqueShader::initialize(); |
3377 | + m_opacityId = program()->uniformLocation("opacity"); |
3378 | + } |
3379 | + void updateState( |
3380 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect) Q_DECL_OVERRIDE { |
3381 | + UCShapeFillCenterShadowBorderOpaqueShader::updateState(state, newEffect, oldEffect); |
3382 | + if (state.isOpacityDirty()) { |
3383 | + program()->setUniformValue(m_opacityId, state.opacity()); |
3384 | + } |
3385 | + } |
3386 | + |
3387 | +private: |
3388 | + int m_opacityId; |
3389 | +}; |
3390 | + |
3391 | +template <bool opaque> |
3392 | +class UCShapeFillCenterShadowBorderMaterial : public QSGMaterial, public UCShapeTextureProvider |
3393 | +{ |
3394 | +public: |
3395 | + UCShapeFillCenterShadowBorderMaterial() : m_textureId{0, 0} { |
3396 | + setFlag(Blending, !opaque); |
3397 | + } |
3398 | + |
3399 | + QSGMaterialType* type() const Q_DECL_OVERRIDE { |
3400 | + static QSGMaterialType type[2]; |
3401 | + return opaque ? &type[0] : &type[1]; |
3402 | + } |
3403 | + QSGMaterialShader* createShader() const Q_DECL_OVERRIDE { |
3404 | + return opaque ? |
3405 | + new UCShapeFillCenterShadowBorderOpaqueShader : new UCShapeFillCenterShadowBorderShader; |
3406 | + } |
3407 | + int compare(const QSGMaterial* other) const Q_DECL_OVERRIDE { |
3408 | + const UCShapeTextureProvider* provider = |
3409 | + reinterpret_cast<const UCShapeTextureProvider*>(other); |
3410 | + if (provider->textureId(0) == m_textureId[0]) { |
3411 | + return provider->textureId(1) - m_textureId[1]; |
3412 | + } else { |
3413 | + return -1; |
3414 | + } |
3415 | + } |
3416 | + |
3417 | + quint32 textureId(int index) const Q_DECL_OVERRIDE { |
3418 | + DASSERT(index <= 1); |
3419 | + return m_textureId[index]; |
3420 | + } |
3421 | + void updateShadowTexture(UCShapeType type, quint16 radius, quint16 shadow) { |
3422 | + m_textureId[0] = m_textureFactory.shadowTexture(0, type, radius, shadow); |
3423 | + } |
3424 | + void updateBorderTexture(UCShapeType type, quint16 radius) { |
3425 | + m_textureId[1] = m_textureFactory.maskTexture(1, type, radius); |
3426 | + } |
3427 | + |
3428 | +private: |
3429 | + UCShapeTextureFactory<2> m_textureFactory; |
3430 | + quint32 m_textureId[2]; |
3431 | +}; |
3432 | + |
3433 | +class UCShapeFillCenterShadowBorderResources : public UCShapeResources |
3434 | +{ |
3435 | +public: |
3436 | + UCShapeFillCenterShadowBorderResources( |
3437 | + int vertexCount, int indexCount, int indexType = GL_UNSIGNED_SHORT) |
3438 | + : m_geometry(attributeSet(), vertexCount, indexCount, indexType) { |
3439 | + m_geometry.setDrawingMode(GL_TRIANGLE_STRIP); |
3440 | + m_geometry.setIndexDataPattern(QSGGeometry::StaticPattern); |
3441 | + m_geometry.setVertexDataPattern(QSGGeometry::AlwaysUploadPattern); |
3442 | + } |
3443 | + |
3444 | + QSGMaterial* material() Q_DECL_OVERRIDE { return &m_material; } |
3445 | + QSGMaterial* opaqueMaterial() Q_DECL_OVERRIDE { return &m_opaqueMaterial; } |
3446 | + QSGGeometry* geometry() Q_DECL_OVERRIDE { return &m_geometry; } |
3447 | + |
3448 | + struct Vertex { |
3449 | + float x, y; |
3450 | + float shadowS, shadowT; |
3451 | + float midShadowS, midShadowT; |
3452 | + float borderS, borderT; |
3453 | + quint32 color; |
3454 | + quint32 shadowColor; |
3455 | + quint32 borderColor; |
3456 | + }; |
3457 | + |
3458 | +private: |
3459 | + static const QSGGeometry::AttributeSet& attributeSet() { |
3460 | + static const QSGGeometry::Attribute attributes[] = { |
3461 | + QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // x, y |
3462 | + QSGGeometry::Attribute::create(1, 2, GL_FLOAT), // shadowS, shadowT |
3463 | + QSGGeometry::Attribute::create(2, 2, GL_FLOAT), // midShadowS, midShadowT |
3464 | + QSGGeometry::Attribute::create(3, 2, GL_FLOAT), // borderS, borderT |
3465 | + QSGGeometry::Attribute::create(4, 4, GL_UNSIGNED_BYTE), // color |
3466 | + QSGGeometry::Attribute::create(5, 4, GL_UNSIGNED_BYTE), // shadowColor |
3467 | + QSGGeometry::Attribute::create(6, 4, GL_UNSIGNED_BYTE) // borderColor |
3468 | + }; |
3469 | + static const QSGGeometry::AttributeSet attributeSet = { |
3470 | + 7, sizeof(Vertex), attributes |
3471 | + }; |
3472 | + return attributeSet; |
3473 | + } |
3474 | + |
3475 | + UCShapeFillCenterShadowBorderMaterial<false> m_material; |
3476 | + UCShapeFillCenterShadowBorderMaterial<true> m_opaqueMaterial; |
3477 | + QSGGeometry m_geometry; |
3478 | +}; |
3479 | + |
3480 | +// #################### |
3481 | +// # Fill center node # |
3482 | +// #################### |
3483 | + |
3484 | +class UCShapeFillCenterNode : public QSGGeometryNode |
3485 | +{ |
3486 | +public: |
3487 | + UCShapeFillCenterNode(); |
3488 | + ~UCShapeFillCenterNode(); |
3489 | + |
3490 | + void preprocess() Q_DECL_OVERRIDE; |
3491 | + bool isSubtreeBlocked() const Q_DECL_OVERRIDE { return !(m_flags & Visible); } |
3492 | + |
3493 | + void setVisible(bool visible); |
3494 | + void update( |
3495 | + const QSizeF& itemSize, UCShapeType type, float radius, QRgb color, float shadowSize, |
3496 | + float shadowAngle, float shadowDistance, QRgb shadowColor, float borderSize, |
3497 | + QRgb borderColor); |
3498 | + |
3499 | +private: |
3500 | + enum { |
3501 | + HasColor = (1 << 0), |
3502 | + HasShadow = (1 << 1), |
3503 | + HasBorder = (1 << 2), |
3504 | + StyleMask = (HasColor | HasShadow | HasBorder), |
3505 | + Textured = (HasShadow | HasBorder), |
3506 | + DirtyRadius = (1 << 3), |
3507 | + DirtyShadow = (1 << 4), |
3508 | + DirtyShape = (1 << 5), |
3509 | + DirtyBorderRadius = (1 << 6), |
3510 | + DirtyMask = (DirtyRadius | DirtyShadow | DirtyShape | DirtyBorderRadius), |
3511 | + Visible = (1 << 7), |
3512 | + Blending = (1 << 8) |
3513 | + }; |
3514 | + |
3515 | + UCShapeResources* m_resources; |
3516 | + quint16 m_radius; |
3517 | + quint16 m_shadow; |
3518 | + quint16 m_borderRadius; |
3519 | + quint16 m_flags; |
3520 | + quint8 m_shape; |
3521 | +}; |
3522 | + |
3523 | +// ################################# |
3524 | +// # Fill corners shadow materials # |
3525 | +// ################################# |
3526 | + |
3527 | +class UCShapeFillCornersShadowOpaqueShader : public QSGMaterialShader |
3528 | +{ |
3529 | +public: |
3530 | + UCShapeFillCornersShadowOpaqueShader() { |
3531 | + setShaderSourceFile(QOpenGLShader::Vertex, |
3532 | + QStringLiteral(":/uc/privates/shaders/fillcornersshadow.vert")); |
3533 | + setShaderSourceFile(QOpenGLShader::Fragment, |
3534 | + QStringLiteral(":/uc/privates/shaders/fillcornersshadow_opaque.frag")); |
3535 | + } |
3536 | + char const* const* attributeNames() const Q_DECL_OVERRIDE { |
3537 | + static char const* const attributes[] = { |
3538 | + "positionAttrib", "maskCoordAttrib", "shadowCoordAttrib", "midShadowCoordAttrib", |
3539 | + "colorAttrib", "shadowColorAttrib", 0 |
3540 | + }; |
3541 | + return attributes; |
3542 | + } |
3543 | + void initialize() Q_DECL_OVERRIDE { |
3544 | + QSGMaterialShader::initialize(); |
3545 | + program()->bind(); |
3546 | + program()->setUniformValue("shadowTexture", 0); |
3547 | + m_matrixId = program()->uniformLocation("matrix"); |
3548 | + } |
3549 | + void updateState( |
3550 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial*) Q_DECL_OVERRIDE { |
3551 | + QOpenGLFunctions* funcs = QOpenGLContext::currentContext()->functions(); |
3552 | + UCShapeTextureProvider* provider = dynamic_cast<UCShapeTextureProvider*>(newEffect); |
3553 | + funcs->glBindTexture(GL_TEXTURE_2D, provider->textureId()); |
3554 | + if (state.isMatrixDirty()) { |
3555 | + program()->setUniformValue(m_matrixId, state.combinedMatrix()); |
3556 | + } |
3557 | + } |
3558 | + |
3559 | +private: |
3560 | + int m_matrixId; |
3561 | +}; |
3562 | + |
3563 | +class UCShapeFillCornersShadowShader : public UCShapeFillCornersShadowOpaqueShader |
3564 | +{ |
3565 | +public: |
3566 | + UCShapeFillCornersShadowShader() : UCShapeFillCornersShadowOpaqueShader() { |
3567 | + setShaderSourceFile(QOpenGLShader::Fragment, |
3568 | + QStringLiteral(":/uc/privates/shaders/fillcornersshadow.frag")); |
3569 | + } |
3570 | + void initialize() Q_DECL_OVERRIDE { |
3571 | + UCShapeFillCornersShadowOpaqueShader::initialize(); |
3572 | + m_opacityId = program()->uniformLocation("opacity"); |
3573 | + } |
3574 | + void updateState( |
3575 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect) Q_DECL_OVERRIDE { |
3576 | + UCShapeFillCornersShadowOpaqueShader::updateState(state, newEffect, oldEffect); |
3577 | + if (state.isOpacityDirty()) { |
3578 | + program()->setUniformValue(m_opacityId, state.opacity()); |
3579 | + } |
3580 | + } |
3581 | + |
3582 | +private: |
3583 | + int m_opacityId; |
3584 | +}; |
3585 | + |
3586 | +template <bool opaque> |
3587 | +class UCShapeFillCornersShadowMaterial : public QSGMaterial, public UCShapeTextureProvider |
3588 | +{ |
3589 | +public: |
3590 | + UCShapeFillCornersShadowMaterial() : m_textureId(0) { |
3591 | + setFlag(Blending, !opaque); |
3592 | + } |
3593 | + |
3594 | + QSGMaterialType* type() const Q_DECL_OVERRIDE { |
3595 | + static QSGMaterialType type[2]; |
3596 | + return opaque ? &type[0] : &type[1]; |
3597 | + } |
3598 | + QSGMaterialShader* createShader() const Q_DECL_OVERRIDE { |
3599 | + return opaque ? |
3600 | + new UCShapeFillCornersShadowOpaqueShader : new UCShapeFillCornersShadowShader; |
3601 | + } |
3602 | + int compare(const QSGMaterial* other) const Q_DECL_OVERRIDE { |
3603 | + return reinterpret_cast<const UCShapeTextureProvider*>(other)->textureId() - m_textureId; |
3604 | + } |
3605 | + |
3606 | + quint32 textureId(int) const Q_DECL_OVERRIDE { |
3607 | + return m_textureId; |
3608 | + } |
3609 | + void updateShadowTexture(UCShapeType type, quint16 radius, quint16 shadow) { |
3610 | + m_textureId = m_textureFactory.shadowTexture(0, type, radius, shadow); |
3611 | + } |
3612 | + |
3613 | +private: |
3614 | + UCShapeTextureFactory<1> m_textureFactory; |
3615 | + quint32 m_textureId; |
3616 | +}; |
3617 | + |
3618 | +class UCShapeFillCornersShadowResources : public UCShapeResources |
3619 | +{ |
3620 | +public: |
3621 | + UCShapeFillCornersShadowResources( |
3622 | + int vertexCount, int indexCount, int indexType = GL_UNSIGNED_SHORT) |
3623 | + : m_geometry(attributeSet(), vertexCount, indexCount, indexType) { |
3624 | + m_geometry.setDrawingMode(GL_TRIANGLE_STRIP); |
3625 | + m_geometry.setIndexDataPattern(QSGGeometry::StaticPattern); |
3626 | + m_geometry.setVertexDataPattern(QSGGeometry::AlwaysUploadPattern); |
3627 | + } |
3628 | + |
3629 | + QSGMaterial* material() Q_DECL_OVERRIDE { return &m_material; } |
3630 | + QSGMaterial* opaqueMaterial() Q_DECL_OVERRIDE { return &m_opaqueMaterial; } |
3631 | + QSGGeometry* geometry() Q_DECL_OVERRIDE { return &m_geometry; } |
3632 | + |
3633 | + struct Vertex { |
3634 | + float x, y; |
3635 | + float maskS, maskT; |
3636 | + float shadowS, shadowT; |
3637 | + float midShadowS, midShadowT; |
3638 | + quint32 color; |
3639 | + quint32 shadowColor; |
3640 | + }; |
3641 | + |
3642 | +private: |
3643 | + static const QSGGeometry::AttributeSet& attributeSet() { |
3644 | + static const QSGGeometry::Attribute attributes[] = { |
3645 | + QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // x, y |
3646 | + QSGGeometry::Attribute::create(1, 2, GL_FLOAT), // maskS, maskT |
3647 | + QSGGeometry::Attribute::create(2, 2, GL_FLOAT), // shadowS, shadowT |
3648 | + QSGGeometry::Attribute::create(3, 2, GL_FLOAT), // midShadowS, midShadowT |
3649 | + QSGGeometry::Attribute::create(4, 4, GL_UNSIGNED_BYTE), // color |
3650 | + QSGGeometry::Attribute::create(5, 4, GL_UNSIGNED_BYTE) // shadowColor |
3651 | + }; |
3652 | + static const QSGGeometry::AttributeSet attributeSet = { |
3653 | + 6, sizeof(Vertex), attributes |
3654 | + }; |
3655 | + return attributeSet; |
3656 | + } |
3657 | + |
3658 | + UCShapeFillCornersShadowMaterial<false> m_material; |
3659 | + UCShapeFillCornersShadowMaterial<true> m_opaqueMaterial; |
3660 | + QSGGeometry m_geometry; |
3661 | +}; |
3662 | + |
3663 | +// ################################# |
3664 | +// # Fill corners border materials # |
3665 | +// ################################# |
3666 | + |
3667 | +class UCShapeFillCornersBorderOpaqueShader : public QSGMaterialShader |
3668 | +{ |
3669 | +public: |
3670 | + UCShapeFillCornersBorderOpaqueShader() { |
3671 | + setShaderSourceFile( |
3672 | + QOpenGLShader::Vertex, QStringLiteral(":/uc/privates/shaders/fillcornersborder.vert")); |
3673 | + setShaderSourceFile( |
3674 | + QOpenGLShader::Fragment, QStringLiteral( |
3675 | + ":/uc/privates/shaders/fillcornersborder_opaque.frag")); |
3676 | + } |
3677 | + char const* const* attributeNames() const Q_DECL_OVERRIDE { |
3678 | + static char const* const attributes[] = { |
3679 | + "positionAttrib", "maskCoordAttrib", "borderCoordAttrib", "colorAttrib", |
3680 | + "borderColorAttrib", 0 |
3681 | + }; |
3682 | + return attributes; |
3683 | + } |
3684 | + void initialize() Q_DECL_OVERRIDE { |
3685 | + QSGMaterialShader::initialize(); |
3686 | + program()->bind(); |
3687 | + program()->setUniformValue("maskTexture", 0); |
3688 | + program()->setUniformValue("borderTexture", 1); |
3689 | + m_matrixId = program()->uniformLocation("matrix"); |
3690 | + } |
3691 | + void updateState( |
3692 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial*) Q_DECL_OVERRIDE { |
3693 | + QOpenGLFunctions* funcs = QOpenGLContext::currentContext()->functions(); |
3694 | + UCShapeTextureProvider* provider = dynamic_cast<UCShapeTextureProvider*>(newEffect); |
3695 | + funcs->glActiveTexture(GL_TEXTURE1); |
3696 | + funcs->glBindTexture(GL_TEXTURE_2D, provider->textureId(1)); |
3697 | + funcs->glActiveTexture(GL_TEXTURE0); |
3698 | + funcs->glBindTexture(GL_TEXTURE_2D, provider->textureId(0)); |
3699 | + if (state.isMatrixDirty()) { |
3700 | + program()->setUniformValue(m_matrixId, state.combinedMatrix()); |
3701 | + } |
3702 | + } |
3703 | + |
3704 | +private: |
3705 | + int m_matrixId; |
3706 | +}; |
3707 | + |
3708 | +class UCShapeFillCornersBorderShader : public UCShapeFillCornersBorderOpaqueShader |
3709 | +{ |
3710 | +public: |
3711 | + UCShapeFillCornersBorderShader() : UCShapeFillCornersBorderOpaqueShader() { |
3712 | + setShaderSourceFile( |
3713 | + QOpenGLShader::Fragment, QStringLiteral( |
3714 | + ":/uc/privates/shaders/fillcornersborder.frag")); |
3715 | + } |
3716 | + void initialize() Q_DECL_OVERRIDE { |
3717 | + UCShapeFillCornersBorderOpaqueShader::initialize(); |
3718 | + m_opacityId = program()->uniformLocation("opacity"); |
3719 | + } |
3720 | + void updateState( |
3721 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect) Q_DECL_OVERRIDE { |
3722 | + UCShapeFillCornersBorderOpaqueShader::updateState(state, newEffect, oldEffect); |
3723 | + if (state.isOpacityDirty()) { |
3724 | + program()->setUniformValue(m_opacityId, state.opacity()); |
3725 | + } |
3726 | + } |
3727 | + |
3728 | +private: |
3729 | + int m_opacityId; |
3730 | +}; |
3731 | + |
3732 | +template <bool opaque> |
3733 | +class UCShapeFillCornersBorderMaterial : public QSGMaterial, public UCShapeTextureProvider |
3734 | +{ |
3735 | +public: |
3736 | + UCShapeFillCornersBorderMaterial() : m_textureId{0, 0} { |
3737 | + setFlag(Blending, !opaque); |
3738 | + } |
3739 | + |
3740 | + QSGMaterialType* type() const Q_DECL_OVERRIDE { |
3741 | + static QSGMaterialType type[2]; |
3742 | + return opaque ? &type[0] : &type[1]; |
3743 | + } |
3744 | + QSGMaterialShader* createShader() const Q_DECL_OVERRIDE { |
3745 | + return opaque ? |
3746 | + new UCShapeFillCornersBorderOpaqueShader : new UCShapeFillCornersBorderShader; |
3747 | + } |
3748 | + int compare(const QSGMaterial* other) const Q_DECL_OVERRIDE { |
3749 | + const UCShapeTextureProvider* provider = |
3750 | + reinterpret_cast<const UCShapeTextureProvider*>(other); |
3751 | + if (provider->textureId(0) == m_textureId[0]) { |
3752 | + return provider->textureId(1) - m_textureId[1]; |
3753 | + } else { |
3754 | + return -1; |
3755 | + } |
3756 | + } |
3757 | + |
3758 | + quint32 textureId(int index) const Q_DECL_OVERRIDE { |
3759 | + DASSERT(index <= 1); |
3760 | + return m_textureId[index]; |
3761 | + } |
3762 | + void updateMaskTexture(UCShapeType type, quint16 radius) { |
3763 | + m_textureId[0] = m_textureFactory.maskTexture(0, type, radius); |
3764 | + } |
3765 | + void updateBorderTexture(UCShapeType type, quint16 radius) { |
3766 | + m_textureId[1] = m_textureFactory.maskTexture(1, type, radius); |
3767 | + } |
3768 | + |
3769 | +private: |
3770 | + UCShapeTextureFactory<2> m_textureFactory; |
3771 | + quint32 m_textureId[2]; |
3772 | +}; |
3773 | + |
3774 | +class UCShapeFillCornersBorderResources : public UCShapeResources |
3775 | +{ |
3776 | +public: |
3777 | + UCShapeFillCornersBorderResources( |
3778 | + int vertexCount, int indexCount, int indexType = GL_UNSIGNED_SHORT) |
3779 | + : m_geometry(attributeSet(), vertexCount, indexCount, indexType) { |
3780 | + m_geometry.setDrawingMode(GL_TRIANGLE_STRIP); |
3781 | + m_geometry.setIndexDataPattern(QSGGeometry::StaticPattern); |
3782 | + m_geometry.setVertexDataPattern(QSGGeometry::AlwaysUploadPattern); |
3783 | + } |
3784 | + |
3785 | + QSGMaterial* material() Q_DECL_OVERRIDE { return &m_material; } |
3786 | + QSGMaterial* opaqueMaterial() Q_DECL_OVERRIDE { return &m_opaqueMaterial; } |
3787 | + QSGGeometry* geometry() Q_DECL_OVERRIDE { return &m_geometry; } |
3788 | + |
3789 | + struct Vertex { |
3790 | + float x, y; |
3791 | + float maskS, maskT; |
3792 | + float borderS, borderT; |
3793 | + quint32 color; |
3794 | + quint32 borderColor; |
3795 | + }; |
3796 | + |
3797 | +private: |
3798 | + static const QSGGeometry::AttributeSet& attributeSet() { |
3799 | + static const QSGGeometry::Attribute attributes[] = { |
3800 | + QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // x, y |
3801 | + QSGGeometry::Attribute::create(1, 2, GL_FLOAT), // maskS, maskT |
3802 | + QSGGeometry::Attribute::create(2, 2, GL_FLOAT), // borderS, borderT |
3803 | + QSGGeometry::Attribute::create(3, 4, GL_UNSIGNED_BYTE), // color |
3804 | + QSGGeometry::Attribute::create(4, 4, GL_UNSIGNED_BYTE) // borderColor |
3805 | + }; |
3806 | + static const QSGGeometry::AttributeSet attributeSet = { |
3807 | + 5, sizeof(Vertex), attributes |
3808 | + }; |
3809 | + return attributeSet; |
3810 | + } |
3811 | + |
3812 | + UCShapeFillCornersBorderMaterial<false> m_material; |
3813 | + UCShapeFillCornersBorderMaterial<true> m_opaqueMaterial; |
3814 | + QSGGeometry m_geometry; |
3815 | +}; |
3816 | + |
3817 | +// ######################################## |
3818 | +// # Fill corners shadow border materials # |
3819 | +// ######################################## |
3820 | + |
3821 | +class UCShapeFillCornersShadowBorderOpaqueShader : public QSGMaterialShader |
3822 | +{ |
3823 | +public: |
3824 | + UCShapeFillCornersShadowBorderOpaqueShader() { |
3825 | + setShaderSourceFile( |
3826 | + QOpenGLShader::Vertex, QStringLiteral( |
3827 | + ":/uc/privates/shaders/fillcornersshadowborder.vert")); |
3828 | + setShaderSourceFile( |
3829 | + QOpenGLShader::Fragment, QStringLiteral( |
3830 | + ":/uc/privates/shaders/fillcornersshadowborder_opaque.frag")); |
3831 | + } |
3832 | + char const* const* attributeNames() const Q_DECL_OVERRIDE { |
3833 | + static char const* const attributes[] = { |
3834 | + "positionAttrib", "maskCoordAttrib", "shadowCoordAttrib", "midShadowCoordAttrib", |
3835 | + "borderCoordAttrib", "colorAttrib", "shadowColorAttrib", "borderColorAttrib", 0 |
3836 | + }; |
3837 | + return attributes; |
3838 | + } |
3839 | + void initialize() Q_DECL_OVERRIDE { |
3840 | + QSGMaterialShader::initialize(); |
3841 | + program()->bind(); |
3842 | + program()->setUniformValue("shadowtexture", 0); |
3843 | + program()->setUniformValue("borderTexture", 1); |
3844 | + m_matrixId = program()->uniformLocation("matrix"); |
3845 | + } |
3846 | + void updateState( |
3847 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial*) Q_DECL_OVERRIDE { |
3848 | + QOpenGLFunctions* funcs = QOpenGLContext::currentContext()->functions(); |
3849 | + UCShapeTextureProvider* provider = dynamic_cast<UCShapeTextureProvider*>(newEffect); |
3850 | + funcs->glActiveTexture(GL_TEXTURE1); |
3851 | + funcs->glBindTexture(GL_TEXTURE_2D, provider->textureId(1)); |
3852 | + funcs->glActiveTexture(GL_TEXTURE0); |
3853 | + funcs->glBindTexture(GL_TEXTURE_2D, provider->textureId(0)); |
3854 | + if (state.isMatrixDirty()) { |
3855 | + program()->setUniformValue(m_matrixId, state.combinedMatrix()); |
3856 | + } |
3857 | + } |
3858 | + |
3859 | +private: |
3860 | + int m_matrixId; |
3861 | +}; |
3862 | + |
3863 | +class UCShapeFillCornersShadowBorderShader : public UCShapeFillCornersShadowBorderOpaqueShader |
3864 | +{ |
3865 | +public: |
3866 | + UCShapeFillCornersShadowBorderShader() : UCShapeFillCornersShadowBorderOpaqueShader() { |
3867 | + setShaderSourceFile(QOpenGLShader::Fragment, |
3868 | + QStringLiteral(":/uc/privates/shaders/fillcornersshadowborder.frag")); |
3869 | + } |
3870 | + void initialize() Q_DECL_OVERRIDE { |
3871 | + UCShapeFillCornersShadowBorderOpaqueShader::initialize(); |
3872 | + m_opacityId = program()->uniformLocation("opacity"); |
3873 | + } |
3874 | + void updateState( |
3875 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect) Q_DECL_OVERRIDE { |
3876 | + UCShapeFillCornersShadowBorderOpaqueShader::updateState(state, newEffect, oldEffect); |
3877 | + if (state.isOpacityDirty()) { |
3878 | + program()->setUniformValue(m_opacityId, state.opacity()); |
3879 | + } |
3880 | + } |
3881 | + |
3882 | +private: |
3883 | + int m_opacityId; |
3884 | +}; |
3885 | + |
3886 | +template <bool opaque> |
3887 | +class UCShapeFillCornersShadowBorderMaterial : public QSGMaterial, public UCShapeTextureProvider |
3888 | +{ |
3889 | +public: |
3890 | + UCShapeFillCornersShadowBorderMaterial() : m_textureId{0, 0} { |
3891 | + setFlag(Blending, !opaque); |
3892 | + } |
3893 | + |
3894 | + QSGMaterialType* type() const Q_DECL_OVERRIDE { |
3895 | + static QSGMaterialType type[2]; |
3896 | + return opaque ? &type[0] : &type[1]; |
3897 | + } |
3898 | + QSGMaterialShader* createShader() const Q_DECL_OVERRIDE { |
3899 | + return opaque ? |
3900 | + new UCShapeFillCornersShadowBorderOpaqueShader : |
3901 | + new UCShapeFillCornersShadowBorderShader; |
3902 | + } |
3903 | + int compare(const QSGMaterial* other) const Q_DECL_OVERRIDE { |
3904 | + const UCShapeTextureProvider* provider = |
3905 | + reinterpret_cast<const UCShapeTextureProvider*>(other); |
3906 | + if (provider->textureId(0) == m_textureId[0]) { |
3907 | + return provider->textureId(1) - m_textureId[1]; |
3908 | + } else { |
3909 | + return -1; |
3910 | + } |
3911 | + } |
3912 | + |
3913 | + quint32 textureId(int index) const Q_DECL_OVERRIDE { |
3914 | + DASSERT(index <= 1); |
3915 | + return m_textureId[index]; |
3916 | + } |
3917 | + void updateShadowTexture(UCShapeType type, quint16 radius, quint16 shadow) { |
3918 | + m_textureId[0] = m_textureFactory.shadowTexture(0, type, radius, shadow); |
3919 | + } |
3920 | + void updateBorderTexture(UCShapeType type, quint16 radius) { |
3921 | + m_textureId[1] = m_textureFactory.maskTexture(1, type, radius); |
3922 | + } |
3923 | + |
3924 | +private: |
3925 | + UCShapeTextureFactory<2> m_textureFactory; |
3926 | + quint32 m_textureId[2]; |
3927 | +}; |
3928 | + |
3929 | +class UCShapeFillCornersShadowBorderResources : public UCShapeResources |
3930 | +{ |
3931 | +public: |
3932 | + UCShapeFillCornersShadowBorderResources( |
3933 | + int vertexCount, int indexCount, int indexType = GL_UNSIGNED_SHORT) |
3934 | + : m_geometry(attributeSet(), vertexCount, indexCount, indexType) { |
3935 | + m_geometry.setDrawingMode(GL_TRIANGLE_STRIP); |
3936 | + m_geometry.setIndexDataPattern(QSGGeometry::StaticPattern); |
3937 | + m_geometry.setVertexDataPattern(QSGGeometry::AlwaysUploadPattern); |
3938 | + } |
3939 | + |
3940 | + QSGMaterial* material() Q_DECL_OVERRIDE { return &m_material; } |
3941 | + QSGMaterial* opaqueMaterial() Q_DECL_OVERRIDE { return &m_opaqueMaterial; } |
3942 | + QSGGeometry* geometry() Q_DECL_OVERRIDE { return &m_geometry; } |
3943 | + |
3944 | + struct Vertex { |
3945 | + float x, y; |
3946 | + float maskS, maskT; |
3947 | + float shadowS, shadowT; |
3948 | + float midShadowS, midShadowT; |
3949 | + float borderS, borderT; |
3950 | + quint32 color; |
3951 | + quint32 shadowColor; |
3952 | + quint32 borderColor; |
3953 | + }; |
3954 | + |
3955 | +private: |
3956 | + static const QSGGeometry::AttributeSet& attributeSet() { |
3957 | + static const QSGGeometry::Attribute attributes[] = { |
3958 | + QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), // x, y |
3959 | + QSGGeometry::Attribute::create(1, 2, GL_FLOAT), // maskS, maskT |
3960 | + QSGGeometry::Attribute::create(2, 2, GL_FLOAT), // shadowS, shadowT |
3961 | + QSGGeometry::Attribute::create(3, 2, GL_FLOAT), // midShadowS, midShadowT |
3962 | + QSGGeometry::Attribute::create(4, 2, GL_FLOAT), // borderS, borderT |
3963 | + QSGGeometry::Attribute::create(5, 4, GL_UNSIGNED_BYTE), // color |
3964 | + QSGGeometry::Attribute::create(6, 4, GL_UNSIGNED_BYTE), // shadowColor |
3965 | + QSGGeometry::Attribute::create(7, 4, GL_UNSIGNED_BYTE) // borderColor |
3966 | + }; |
3967 | + static const QSGGeometry::AttributeSet attributeSet = { |
3968 | + 8, sizeof(Vertex), attributes |
3969 | + }; |
3970 | + return attributeSet; |
3971 | + } |
3972 | + |
3973 | + UCShapeFillCornersShadowBorderMaterial<false> m_material; |
3974 | + UCShapeFillCornersShadowBorderMaterial<true> m_opaqueMaterial; |
3975 | + QSGGeometry m_geometry; |
3976 | +}; |
3977 | + |
3978 | +// ##################### |
3979 | +// # Fill corners node # |
3980 | +// ##################### |
3981 | + |
3982 | +class UCShapeFillCornersNode : public QSGGeometryNode |
3983 | +{ |
3984 | +public: |
3985 | + UCShapeFillCornersNode(); |
3986 | + ~UCShapeFillCornersNode(); |
3987 | + |
3988 | + void preprocess() Q_DECL_OVERRIDE; |
3989 | + bool isSubtreeBlocked() const Q_DECL_OVERRIDE { return !(m_flags & Visible); } |
3990 | + |
3991 | + void setVisible(bool visible); |
3992 | + void update( |
3993 | + const QSizeF& itemSize, UCShapeType type, float radius, QRgb color, float shadowSize, |
3994 | + float shadowAngle, float shadowDistance, QRgb shadowColor, float borderSize, |
3995 | + QRgb borderColor); |
3996 | + |
3997 | +private: |
3998 | + enum { |
3999 | + HasColor = (1 << 0), |
4000 | + HasShadow = (1 << 1), |
4001 | + HasBorder = (1 << 2), |
4002 | + StyleMask = (HasColor | HasShadow | HasBorder), |
4003 | + DirtyRadius = (1 << 3), |
4004 | + DirtyShadow = (1 << 4), |
4005 | + DirtyShape = (1 << 5), |
4006 | + DirtyBorderRadius = (1 << 6), |
4007 | + DirtyMask = (DirtyRadius | DirtyShadow | DirtyShape | DirtyBorderRadius), |
4008 | + Visible = (1 << 7), |
4009 | + Blending = (1 << 8) |
4010 | + }; |
4011 | + |
4012 | + UCShapeResources* m_resources; |
4013 | + quint16 m_radius; |
4014 | + quint16 m_shadow; |
4015 | + quint16 m_borderRadius; |
4016 | + quint16 m_flags; |
4017 | + quint8 m_shape; |
4018 | +}; |
4019 | + |
4020 | +#endif // UCSHAPEFILLNODES_P_H |
4021 | |
4022 | === renamed file 'src/UbuntuToolkit/privates/frame.cpp' => 'src/UbuntuToolkit/privates/ucshapeframenodes.cpp' |
4023 | --- src/UbuntuToolkit/privates/frame.cpp 2016-09-09 17:49:07 +0000 |
4024 | +++ src/UbuntuToolkit/privates/ucshapeframenodes.cpp 2016-12-14 07:25:05 +0000 |
4025 | @@ -16,68 +16,191 @@ |
4026 | * Author: Loïc Molinari <loic.molinari@canonical.com> |
4027 | */ |
4028 | |
4029 | -#include "privates/frame_p.h" |
4030 | +#include "ucshapeframenodes_p.h" |
4031 | |
4032 | -#include <QtGui/QOpenGLContext> |
4033 | +#include <QtGui/QGuiApplication> |
4034 | #include <QtGui/QOpenGLFunctions> |
4035 | |
4036 | -#include "privates/textures_p.h" |
4037 | - |
4038 | -UT_NAMESPACE_BEGIN |
4039 | - |
4040 | -const QRgb defaultColor = qRgba(255, 255, 255, 255); |
4041 | -const float defaultThickness = 20.0f; |
4042 | -const float defaultRadius = 50.0f; |
4043 | - |
4044 | -// --- Shader --- |
4045 | - |
4046 | -class FrameShader : public QSGMaterialShader |
4047 | +UCShapeFrameEdgesNode::UCShapeFrameEdgesNode() |
4048 | + : QSGGeometryNode() |
4049 | + , m_resources(16, 22, GL_UNSIGNED_SHORT) |
4050 | + , m_visible(0) |
4051 | + , m_blending(0) |
4052 | +{ |
4053 | + DLOG("creating UCShapeFrameEdgesNode"); |
4054 | + |
4055 | + setMaterial(m_resources.material()); |
4056 | + setOpaqueMaterial(m_resources.opaqueMaterial()); |
4057 | + |
4058 | + // The geometry is made of 16 vertices indexed with a triangle strip mode. |
4059 | + // 0 ----- 1 |
4060 | + // 2 --- 3 |
4061 | + // 4 5 |
4062 | + // | 6 7 | |
4063 | + // | | | | |
4064 | + // | 8 9 | |
4065 | + // 10 11 |
4066 | + // 12 --- 13 |
4067 | + // 14 ----- 15 |
4068 | + const quint16 indices[] = { |
4069 | + 0, 2, 1, 3, |
4070 | + 3, 4, // Degenerate triangle. |
4071 | + 4, 10, 6, 8, |
4072 | + 8, 7, // Degenerate triangle. |
4073 | + 7, 9, 5, 11, |
4074 | + 11, 12, // Degenerate triangle. |
4075 | + 12, 14, 13, 15 |
4076 | + }; |
4077 | + memcpy(m_resources.geometry()->indexData(), indices, 22 * sizeof(quint16)); |
4078 | + setGeometry(m_resources.geometry()); |
4079 | + |
4080 | + qsgnode_set_description(this, QLatin1String("shapeframeedges")); |
4081 | +} |
4082 | + |
4083 | +UCShapeFrameEdgesNode::~UCShapeFrameEdgesNode() |
4084 | +{ |
4085 | + DLOG("detroying UCShapeFrameEdgesNode"); |
4086 | +} |
4087 | + |
4088 | +void UCShapeFrameEdgesNode::setVisible(bool visible) |
4089 | +{ |
4090 | + DLOG("UCShapeFrameEdgesNode::setVisible %d", visible); |
4091 | + if (m_visible != visible) { |
4092 | + m_visible = visible; |
4093 | + markDirty(DirtySubtreeBlocked); |
4094 | + } |
4095 | +} |
4096 | + |
4097 | +void UCShapeFrameEdgesNode::update( |
4098 | + const QSizeF& itemSize, float radius, float thickness, float space, QRgb color) |
4099 | +{ |
4100 | + Q_UNUSED(space); |
4101 | + // FIXME(loicm) Add space support. |
4102 | + |
4103 | + UCShapeColorResources::Vertex* v = |
4104 | + reinterpret_cast<UCShapeColorResources::Vertex*>(m_resources.geometry()->vertexData()); |
4105 | + const float w = static_cast<float>(itemSize.width()); |
4106 | + const float h = static_cast<float>(itemSize.height()); |
4107 | + // FIXME(loicm) Rounded down since renderShape() doesn't support sub-pixel rendering. |
4108 | + const float maxSize = floorf(qMin(w, h) * 0.5f); |
4109 | + const float clampedThickness = qMin(floorf(thickness), maxSize); |
4110 | + const float outerRadius = qMin(floorf(radius), maxSize); |
4111 | + // FIXME(loicm) Rounded down since renderShape() doesn't support sub-pixel rendering. |
4112 | + const float innerRadius = floorf(outerRadius * ((maxSize - clampedThickness) / maxSize)); |
4113 | + const quint32 packedColor = packColor(color); |
4114 | + |
4115 | + v[0].x = outerRadius; |
4116 | + v[0].y = 0.0f; |
4117 | + v[0].color = packedColor; |
4118 | + v[1].x = w - outerRadius; |
4119 | + v[1].y = 0.0f; |
4120 | + v[1].color = packedColor; |
4121 | + v[2].x = clampedThickness + innerRadius; |
4122 | + v[2].y = clampedThickness; |
4123 | + v[2].color = packedColor; |
4124 | + v[3].x = w - clampedThickness - innerRadius; |
4125 | + v[3].y = clampedThickness; |
4126 | + v[3].color = packedColor; |
4127 | + v[4].x = 0.0f; |
4128 | + v[4].y = outerRadius; |
4129 | + v[4].color = packedColor; |
4130 | + v[5].x = w; |
4131 | + v[5].y = outerRadius; |
4132 | + v[5].color = packedColor; |
4133 | + v[6].x = clampedThickness; |
4134 | + v[6].y = clampedThickness + innerRadius; |
4135 | + v[6].color = packedColor; |
4136 | + v[7].x = w - clampedThickness; |
4137 | + v[7].y = clampedThickness + innerRadius; |
4138 | + v[7].color = packedColor; |
4139 | + v[8].x = clampedThickness; |
4140 | + v[8].y = h - clampedThickness - innerRadius; |
4141 | + v[8].color = packedColor; |
4142 | + v[9].x = w - clampedThickness; |
4143 | + v[9].y = h - clampedThickness - innerRadius; |
4144 | + v[9].color = packedColor; |
4145 | + v[10].x = 0.0f; |
4146 | + v[10].y = h - outerRadius; |
4147 | + v[10].color = packedColor; |
4148 | + v[11].x = w; |
4149 | + v[11].y = h - outerRadius; |
4150 | + v[11].color = packedColor; |
4151 | + v[12].x = clampedThickness + innerRadius; |
4152 | + v[12].y = h - clampedThickness; |
4153 | + v[12].color = packedColor; |
4154 | + v[13].x = w - clampedThickness - innerRadius; |
4155 | + v[13].y = h - clampedThickness; |
4156 | + v[13].color = packedColor; |
4157 | + v[14].x = outerRadius; |
4158 | + v[14].y = h; |
4159 | + v[14].color = packedColor; |
4160 | + v[15].x = w - outerRadius; |
4161 | + v[15].y = h; |
4162 | + v[15].color = packedColor; |
4163 | + markDirty(QSGNode::DirtyGeometry); |
4164 | + |
4165 | + // Update the blending state of the opaque material (in QSG terms, an opaque |
4166 | + // material is the material automatically used when the opacity is 1, but |
4167 | + // even if the opacity is 1 we have to handle the case where the alpha of |
4168 | + // the specified color is less than 1). |
4169 | + const bool blending = qAlpha(color) < 255; |
4170 | + if (blending != static_cast<bool>(m_blending)) { |
4171 | + m_resources.opaqueMaterial()->setFlag(QSGMaterial::Blending, blending); |
4172 | + markDirty(QSGNode::DirtyMaterial); |
4173 | + } |
4174 | +} |
4175 | + |
4176 | +class UCShapeFrameCornersShader : public QSGMaterialShader |
4177 | { |
4178 | public: |
4179 | - FrameShader(); |
4180 | - char const* const* attributeNames() const override; |
4181 | - void initialize() override; |
4182 | + UCShapeFrameCornersShader(); |
4183 | + char const* const* attributeNames() const Q_DECL_OVERRIDE; |
4184 | + void initialize() Q_DECL_OVERRIDE; |
4185 | void updateState( |
4186 | - const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect) override; |
4187 | + const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect) Q_DECL_OVERRIDE; |
4188 | |
4189 | private: |
4190 | int m_matrixId; |
4191 | int m_opacityId; |
4192 | }; |
4193 | |
4194 | -FrameShader::FrameShader() |
4195 | +UCShapeFrameCornersShader::UCShapeFrameCornersShader() |
4196 | { |
4197 | - setShaderSourceFile( |
4198 | - QOpenGLShader::Vertex, QStringLiteral(":/uc/privates/shaders/frame.vert")); |
4199 | - setShaderSourceFile( |
4200 | - QOpenGLShader::Fragment, QStringLiteral(":/uc/privates/shaders/frame.frag")); |
4201 | + setShaderSourceFile(QOpenGLShader::Vertex, |
4202 | + QStringLiteral(":/uc/privates/shaders/texture2.vert")); |
4203 | + setShaderSourceFile(QOpenGLShader::Fragment, |
4204 | + QStringLiteral(":/uc/privates/shaders/frame.frag")); |
4205 | } |
4206 | |
4207 | -char const* const* FrameShader::attributeNames() const |
4208 | +char const* const* UCShapeFrameCornersShader::attributeNames() const |
4209 | { |
4210 | static char const* const attributes[] = { |
4211 | - "positionAttrib", "outerCoordAttrib", "innerCoordAttrib", "colorAttrib", 0 |
4212 | + "positionAttrib", "texCoord1Attrib", "texCoord2Attrib", "colorAttrib", 0 |
4213 | }; |
4214 | return attributes; |
4215 | } |
4216 | |
4217 | -void FrameShader::initialize() |
4218 | +void UCShapeFrameCornersShader::initialize() |
4219 | { |
4220 | QSGMaterialShader::initialize(); |
4221 | program()->bind(); |
4222 | - program()->setUniformValue("texture", 0); |
4223 | + const GLint values[2] = { 0, 1 }; |
4224 | + program()->setUniformValueArray("texture", values, 2); |
4225 | m_matrixId = program()->uniformLocation("matrix"); |
4226 | m_opacityId = program()->uniformLocation("opacity"); |
4227 | } |
4228 | |
4229 | -void FrameShader::updateState( |
4230 | +void UCShapeFrameCornersShader::updateState( |
4231 | const RenderState& state, QSGMaterial* newEffect, QSGMaterial* oldEffect) |
4232 | { |
4233 | Q_UNUSED(oldEffect); |
4234 | |
4235 | QOpenGLFunctions* funcs = QOpenGLContext::currentContext()->functions(); |
4236 | - funcs->glBindTexture( |
4237 | - GL_TEXTURE_2D, static_cast<UCFrameMaterial*>(newEffect)->textureId()); |
4238 | + UCShapeFrameCornersMaterial* material = static_cast<UCShapeFrameCornersMaterial*>(newEffect); |
4239 | + funcs->glActiveTexture(GL_TEXTURE1); |
4240 | + funcs->glBindTexture(GL_TEXTURE_2D, material->innerTextureId()); |
4241 | + funcs->glActiveTexture(GL_TEXTURE0); |
4242 | + funcs->glBindTexture(GL_TEXTURE_2D, material->outerTextureId()); |
4243 | |
4244 | if (state.isMatrixDirty()) { |
4245 | program()->setUniformValue(m_matrixId, state.combinedMatrix()); |
4246 | @@ -87,136 +210,87 @@ |
4247 | } |
4248 | } |
4249 | |
4250 | -// --- Material --- |
4251 | - |
4252 | -const int maxTextures = 16; |
4253 | -static struct { QOpenGLContext* openglContext; quint32 textureId; } textures[maxTextures]; |
4254 | - |
4255 | -// Gets the textures' slot used by the given context, or -1 if not stored. |
4256 | -static int getTexturesIndex(const QOpenGLContext* openglContext) |
4257 | -{ |
4258 | - int index = 0; |
4259 | - while (textures[index].openglContext != openglContext) { |
4260 | - index++; |
4261 | - if (index == maxTextures) { |
4262 | - return -1; |
4263 | - } |
4264 | - } |
4265 | - return index; |
4266 | -} |
4267 | - |
4268 | -// Gets an empty textures' slot. |
4269 | -static int getEmptyTexturesIndex() |
4270 | -{ |
4271 | - int index = 0; |
4272 | - while (textures[index].openglContext) { |
4273 | - index++; |
4274 | - if (index == maxTextures) { |
4275 | - // Don't bother with a dynamic array, let's just set a high enough |
4276 | - // maxTextures and increase the static array size if ever needed. |
4277 | - qFatal("reached maximum number of OpenGL contexts supported per item."); |
4278 | - } |
4279 | - } |
4280 | - return index; |
4281 | -} |
4282 | - |
4283 | -UCFrameMaterial::UCFrameMaterial() |
4284 | +UCShapeFrameCornersMaterial::UCShapeFrameCornersMaterial() |
4285 | { |
4286 | setFlag(Blending, true); |
4287 | - |
4288 | - // Get the texture stored per context and shared by all materials of the same type. |
4289 | - QOpenGLContext* openglContext = QOpenGLContext::currentContext(); |
4290 | - int index = getTexturesIndex(openglContext); |
4291 | - if (index < 0) { |
4292 | - QOpenGLFunctions* funcs = openglContext->functions(); |
4293 | - index = getEmptyTexturesIndex(); |
4294 | - textures[index].openglContext = openglContext; |
4295 | - funcs->glGenTextures(1, &textures[index].textureId); |
4296 | - funcs->glBindTexture(GL_TEXTURE_2D, textures[index].textureId); |
4297 | - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
4298 | - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
4299 | - // FIXME(loicm) GL_LINEAR_MIPMAP_[NEAREST,LINEAR] perf/quality tradeoff. |
4300 | - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); |
4301 | - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); |
4302 | - // Set the highest mipmap level in order to avoid clamp to edge issues |
4303 | - // with inner corners starting from mipmap level 5 (OpenGL ES 2 doesn't |
4304 | - // support GL_TEXTURE_MAX_LOD). |
4305 | - funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4.0f); |
4306 | - for (int i = 0; i < shapeMipmapCount; i++) { |
4307 | - funcs->glTexImage2D(GL_TEXTURE_2D, i, GL_LUMINANCE, shapeMipmapBaseSize >> i, |
4308 | - shapeMipmapBaseSize >> i, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, |
4309 | - &shapeMipmapData[shapeMipmapOffsets[i]]); |
4310 | - } |
4311 | - QObject::connect( |
4312 | - openglContext, &QOpenGLContext::aboutToBeDestroyed, [index] { |
4313 | - QOpenGLFunctions* funcs = textures[index].openglContext->functions(); |
4314 | - funcs->glDeleteTextures(1, &textures[index].textureId); |
4315 | - textures[index].openglContext = NULL; |
4316 | - }); |
4317 | - } |
4318 | - m_textureId = textures[index].textureId; |
4319 | } |
4320 | |
4321 | -QSGMaterialType* UCFrameMaterial::type() const |
4322 | +QSGMaterialType* UCShapeFrameCornersMaterial::type() const |
4323 | { |
4324 | static QSGMaterialType type; |
4325 | return &type; |
4326 | } |
4327 | |
4328 | -QSGMaterialShader* UCFrameMaterial::createShader() const |
4329 | -{ |
4330 | - return new FrameShader; |
4331 | -} |
4332 | - |
4333 | -int UCFrameMaterial::compare(const QSGMaterial* other) const |
4334 | -{ |
4335 | - Q_UNUSED(other); |
4336 | - return 0; |
4337 | -} |
4338 | - |
4339 | -// --- Node --- |
4340 | - |
4341 | -UCFrameNode::UCFrameNode() |
4342 | +QSGMaterialShader* UCShapeFrameCornersMaterial::createShader() const |
4343 | +{ |
4344 | + return new UCShapeFrameCornersShader; |
4345 | +} |
4346 | + |
4347 | +int UCShapeFrameCornersMaterial::compare(const QSGMaterial* other) const |
4348 | +{ |
4349 | + const UCShapeFrameCornersMaterial* otherFrameCornersMaterial = |
4350 | + static_cast<const UCShapeFrameCornersMaterial*>(other); |
4351 | + if (otherFrameCornersMaterial->outerTextureId() != m_textureId[0]) { |
4352 | + return -1; |
4353 | + } |
4354 | + return otherFrameCornersMaterial->innerTextureId() - m_textureId[1]; |
4355 | +} |
4356 | + |
4357 | +void UCShapeFrameCornersMaterial::updateTexture(int index, UCShapeType type, quint16 radius) |
4358 | +{ |
4359 | + DASSERT(index >= 0 && index < 2); |
4360 | + //DASSERT(radius >= 0); |
4361 | + m_textureId[index] = m_textureFactory.maskTexture(index, type, radius); |
4362 | +} |
4363 | + |
4364 | +UCShapeFrameCornersNode::UCShapeFrameCornersNode() |
4365 | : QSGGeometryNode() |
4366 | , m_material() |
4367 | - , m_geometry(attributeSet(), 20, 34, GL_UNSIGNED_SHORT) |
4368 | + , m_geometry(attributeSet(), 20, 26, GL_UNSIGNED_SHORT) |
4369 | + , m_radius{0, 0} |
4370 | + , m_newRadius{0, 0} |
4371 | + , m_type(0) |
4372 | + , m_newType(0) |
4373 | + , m_visible(0) |
4374 | { |
4375 | - memcpy(m_geometry.indexData(), indices(), 34 * sizeof(unsigned short)); |
4376 | + DLOG("creating UCShapeFrameCornersNode"); |
4377 | + setFlag(QSGNode::UsePreprocess); |
4378 | + memcpy(m_geometry.indexData(), indices(), 26 * sizeof(quint16)); |
4379 | m_geometry.setDrawingMode(GL_TRIANGLE_STRIP); |
4380 | m_geometry.setIndexDataPattern(QSGGeometry::StaticPattern); |
4381 | m_geometry.setVertexDataPattern(QSGGeometry::AlwaysUploadPattern); |
4382 | setMaterial(&m_material); |
4383 | setGeometry(&m_geometry); |
4384 | - qsgnode_set_description(this, QLatin1String("frame")); |
4385 | + qsgnode_set_description(this, QLatin1String("shapeframecorners")); |
4386 | } |
4387 | |
4388 | // static |
4389 | -const unsigned short* UCFrameNode::indices() |
4390 | +const quint16* UCShapeFrameCornersNode::indices() |
4391 | { |
4392 | // The geometry is made of 20 vertices indexed with a triangle strip mode. |
4393 | - // 0 -1 ----- 2- 3 |
4394 | - // | 4 --- 5 | |
4395 | - // 6 / \ 9 |
4396 | - // | 7 8 | |
4397 | - // | | | | |
4398 | - // | 11 12 | |
4399 | - // 10 \ / 13 |
4400 | - // | 14---15 | |
4401 | - // 16 -17 --- 18- 19 |
4402 | - static const unsigned short indices[] = { |
4403 | - 6, 7, 0, 4, 1, 5, 2, |
4404 | - 2, 2, // Degenerate triangle. |
4405 | - 2, 5, 3, 8, 9, 12, 13, |
4406 | - 13, 13, // Degenerate triangle. |
4407 | - 13, 12, 19, 15, 18, 14, 17, |
4408 | - 17, 17, // Degenerate triangle. |
4409 | - 17, 14, 16, 11, 10, 7, 6 |
4410 | + // 0 -1 2- 3 |
4411 | + // | 4 5 | |
4412 | + // 6 / \ 7 |
4413 | + // 8 9 |
4414 | + // |
4415 | + // 10 11 |
4416 | + // 12 \ / 13 |
4417 | + // | 14 15 | |
4418 | + // 16 -17 18- 19 |
4419 | + static const quint16 indices[] = { |
4420 | + 0, 6, 1, 8, 4, |
4421 | + 4, 5, // Degenerate triangle. |
4422 | + 5, 9, 2, 7, 3, |
4423 | + 3, 16, // Degenerate triangle. |
4424 | + 16, 12, 17, 10, 14, |
4425 | + 14, 15, // Degenerate triangle. |
4426 | + 15, 11, 18, 13, 19 |
4427 | }; |
4428 | return indices; |
4429 | } |
4430 | |
4431 | // static |
4432 | -const QSGGeometry::AttributeSet& UCFrameNode::attributeSet() |
4433 | +const QSGGeometry::AttributeSet& UCShapeFrameCornersNode::attributeSet() |
4434 | { |
4435 | static const QSGGeometry::Attribute attributes[] = { |
4436 | QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), |
4437 | @@ -230,246 +304,238 @@ |
4438 | return attributeSet; |
4439 | } |
4440 | |
4441 | -// Pack a color in a premultiplied 32-bit ABGR value. |
4442 | -static quint32 packColor(QRgb color) |
4443 | -{ |
4444 | - const quint32 a = qAlpha(color); |
4445 | - const quint32 b = ((qBlue(color) * a) + 0xff) >> 8; |
4446 | - const quint32 g = ((qGreen(color) * a) + 0xff) >> 8; |
4447 | - const quint32 r = ((qRed(color) * a) + 0xff) >> 8; |
4448 | - return (a << 24) | ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff); |
4449 | -} |
4450 | - |
4451 | -void UCFrameNode::updateGeometry( |
4452 | - const QSizeF& itemSize, float thickness, float radius, QRgb color) |
4453 | -{ |
4454 | - UCFrameNode::Vertex* v = reinterpret_cast<UCFrameNode::Vertex*>(m_geometry.vertexData()); |
4455 | +void UCShapeFrameCornersNode::preprocess() |
4456 | +{ |
4457 | + const bool hasNewType = m_newType != m_type; |
4458 | + for (int i = 0; i < 2; i++) { |
4459 | + if (hasNewType || m_newRadius[i] != m_radius[i]) { |
4460 | + m_material.updateTexture(i, static_cast<UCShapeType>(m_newType), m_newRadius[i]); |
4461 | + m_radius[i] = m_newRadius[i]; |
4462 | + } |
4463 | + } |
4464 | + if (hasNewType) { |
4465 | + m_type = m_newType; |
4466 | + } |
4467 | +} |
4468 | + |
4469 | +void UCShapeFrameCornersNode::setVisible(bool visible) |
4470 | +{ |
4471 | + DLOG("UCShapeFrameCornersNode::setVisible %d", visible); |
4472 | + if (m_visible != visible) { |
4473 | + m_visible = visible; |
4474 | + markDirty(DirtySubtreeBlocked); |
4475 | + } |
4476 | +} |
4477 | + |
4478 | +void UCShapeFrameCornersNode::update( |
4479 | + const QSizeF& itemSize, UCShapeType type, float radius, float thickness, float space, |
4480 | + QRgb color) |
4481 | +{ |
4482 | + Q_UNUSED(space); |
4483 | + // FIXME(loicm) Add space support. |
4484 | + |
4485 | + // FIXME(loicm) Temp hack to hide the broken rendering of corners which |
4486 | + // slightly appears when the thickness is less than 1. |
4487 | + if (thickness < 1.0f) { |
4488 | + radius = 0.0f; |
4489 | + } |
4490 | + |
4491 | + UCShapeFrameCornersNode::Vertex* v = |
4492 | + reinterpret_cast<UCShapeFrameCornersNode::Vertex*>(m_geometry.vertexData()); |
4493 | + const float devicePixelRatio = qGuiApp->devicePixelRatio(); |
4494 | const float w = static_cast<float>(itemSize.width()); |
4495 | const float h = static_cast<float>(itemSize.height()); |
4496 | - const float maxSize = qMin(w, h) * 0.5f; |
4497 | - const float clampedThickness = qMin(thickness, maxSize); |
4498 | - const float radiusOut = qBound(0.01f, radius, maxSize); |
4499 | - const float radiusIn = radiusOut * ((maxSize - clampedThickness) / maxSize); |
4500 | - const float outerCoord1 = |
4501 | - (((1.0f - shapeOffset) / radiusOut) * (clampedThickness + radiusIn)) + shapeOffset; |
4502 | - const float outerCoord2 = |
4503 | - (((1.0f - shapeOffset) / radiusOut) * clampedThickness) + shapeOffset; |
4504 | - const float innerCoord1 = |
4505 | - (((1.0f - shapeOffset) / radiusIn) * -clampedThickness) + shapeOffset; |
4506 | - const float innerCoord2 = |
4507 | - (((1.0f - shapeOffset) / radiusIn) * (radiusOut - clampedThickness)) + shapeOffset; |
4508 | + // FIXME(loicm) Rounded down since renderShape() doesn't support sub-pixel rendering. |
4509 | + const float maxSize = floorf(qMin(w, h) * 0.5f); |
4510 | + const float clampedThickness = qMin(floorf(thickness), maxSize); |
4511 | + const float deviceThickness = clampedThickness * devicePixelRatio; |
4512 | + const float border = 1.0f; |
4513 | + const float outerRadius = qMin(floorf(radius), maxSize); |
4514 | + const float deviceOuterRadius = outerRadius * devicePixelRatio; |
4515 | + // FIXME(loicm) Rounded down since renderShape() doesn't support sub-pixel rendering. |
4516 | + const float outerRadiusRounded = |
4517 | + roundUp(static_cast<int>(deviceOuterRadius + 2 * border), textureRounding); |
4518 | + const float innerRadius = floorf(outerRadius * ((maxSize - clampedThickness) / maxSize)); |
4519 | + const float deviceInnerRadius = innerRadius * devicePixelRatio; |
4520 | + const float innerRadiusRounded = |
4521 | + roundUp(static_cast<int>(deviceInnerRadius + 2 * border), textureRounding); |
4522 | + |
4523 | + const float outerRadiusOffset = outerRadiusRounded - deviceOuterRadius - border; |
4524 | + const float outerTextureFactor = 1.0f / outerRadiusRounded; |
4525 | + const float outerS0 = outerTextureFactor * outerRadiusOffset; |
4526 | + const float outerS1 = outerTextureFactor * (outerRadiusOffset + deviceOuterRadius); |
4527 | + const float outerS2 = outerTextureFactor * (outerRadiusOffset + deviceThickness); |
4528 | + const float outerS3 = |
4529 | + outerTextureFactor * (outerRadiusOffset + deviceThickness + deviceInnerRadius); |
4530 | + |
4531 | + const float innerRadiusOffset = innerRadiusRounded - deviceInnerRadius - border; |
4532 | + const float innerTextureFactor = 1.0f / innerRadiusRounded; |
4533 | + const float innerS0 = innerTextureFactor * innerRadiusOffset; |
4534 | + const float innerS1 = innerTextureFactor * (innerRadiusOffset + deviceInnerRadius); |
4535 | + const float innerS2 = innerTextureFactor * (innerRadiusOffset - deviceThickness); |
4536 | + const float innerS3 = |
4537 | + innerTextureFactor * (innerRadiusOffset - deviceThickness + deviceOuterRadius); |
4538 | + |
4539 | const quint32 packedColor = packColor(color); |
4540 | |
4541 | - // 1st row. |
4542 | v[0].x = 0.0f; |
4543 | v[0].y = 0.0f; |
4544 | - v[0].s1 = shapeOffset; |
4545 | - v[0].t1 = shapeOffset; |
4546 | - v[0].s2 = innerCoord1; |
4547 | - v[0].t2 = innerCoord1; |
4548 | + v[0].outerS = outerS0; |
4549 | + v[0].outerT = outerS0; |
4550 | + v[0].innerS = innerS2; |
4551 | + v[0].innerT = innerS2; |
4552 | v[0].color = packedColor; |
4553 | - v[1].x = radiusOut; |
4554 | + v[1].x = outerRadius; |
4555 | v[1].y = 0.0f; |
4556 | - v[1].s1 = 1.0f; |
4557 | - v[1].t1 = shapeOffset; |
4558 | - v[1].s2 = innerCoord2; |
4559 | - v[1].t2 = innerCoord1; |
4560 | + v[1].outerS = outerS1; |
4561 | + v[1].outerT = outerS0; |
4562 | + v[1].innerS = innerS3; |
4563 | + v[1].innerT = innerS2; |
4564 | v[1].color = packedColor; |
4565 | - v[2].x = w - radiusOut; |
4566 | + v[2].x = w - outerRadius; |
4567 | v[2].y = 0.0f; |
4568 | - v[2].s1 = 1.0f; |
4569 | - v[2].t1 = shapeOffset; |
4570 | - v[2].s2 = innerCoord2; |
4571 | - v[2].t2 = innerCoord1; |
4572 | + v[2].outerS = outerS1; |
4573 | + v[2].outerT = outerS0; |
4574 | + v[2].innerS = innerS3; |
4575 | + v[2].innerT = innerS2; |
4576 | v[2].color = packedColor; |
4577 | v[3].x = w; |
4578 | v[3].y = 0.0f; |
4579 | - v[3].s1 = shapeOffset; |
4580 | - v[3].t1 = shapeOffset; |
4581 | - v[3].s2 = innerCoord1; |
4582 | - v[3].t2 = innerCoord1; |
4583 | + v[3].outerS = outerS0; |
4584 | + v[3].outerT = outerS0; |
4585 | + v[3].innerS = innerS2; |
4586 | + v[3].innerT = innerS2; |
4587 | v[3].color = packedColor; |
4588 | |
4589 | - // 2nd row. |
4590 | - v[4].x = clampedThickness + radiusIn; |
4591 | + v[4].x = clampedThickness + innerRadius; |
4592 | v[4].y = clampedThickness; |
4593 | - v[4].s1 = outerCoord1; |
4594 | - v[4].t1 = outerCoord2; |
4595 | - v[4].s2 = 1.0f; |
4596 | - v[4].t2 = shapeOffset; |
4597 | + v[4].outerS = outerS3; |
4598 | + v[4].outerT = outerS2; |
4599 | + v[4].innerS = innerS1; |
4600 | + v[4].innerT = innerS0; |
4601 | v[4].color = packedColor; |
4602 | - v[5].x = w - (clampedThickness + radiusIn); |
4603 | + v[5].x = w - (clampedThickness + innerRadius); |
4604 | v[5].y = clampedThickness; |
4605 | - v[5].s1 = outerCoord1; |
4606 | - v[5].t1 = outerCoord2; |
4607 | - v[5].s2 = 1.0f; |
4608 | - v[5].t2 = shapeOffset; |
4609 | + v[5].outerS = outerS3; |
4610 | + v[5].outerT = outerS2; |
4611 | + v[5].innerS = innerS1; |
4612 | + v[5].innerT = innerS0; |
4613 | v[5].color = packedColor; |
4614 | |
4615 | - // 3rd row. |
4616 | v[6].x = 0.0f; |
4617 | - v[6].y = radiusOut; |
4618 | - v[6].s1 = shapeOffset; |
4619 | - v[6].t1 = 1.0f; |
4620 | - v[6].s2 = innerCoord1; |
4621 | - v[6].t2 = innerCoord2; |
4622 | + v[6].y = outerRadius; |
4623 | + v[6].outerS = outerS0; |
4624 | + v[6].outerT = outerS1; |
4625 | + v[6].innerS = innerS2; |
4626 | + v[6].innerT = innerS3; |
4627 | v[6].color = packedColor; |
4628 | - v[7].x = clampedThickness; |
4629 | - v[7].y = clampedThickness + radiusIn; |
4630 | - v[7].s1 = outerCoord2; |
4631 | - v[7].t1 = outerCoord1; |
4632 | - v[7].s2 = shapeOffset; |
4633 | - v[7].t2 = 1.0f; |
4634 | + v[7].x = w; |
4635 | + v[7].y = outerRadius; |
4636 | + v[7].outerS = outerS0; |
4637 | + v[7].outerT = outerS1; |
4638 | + v[7].innerS = innerS2; |
4639 | + v[7].innerT = innerS3; |
4640 | v[7].color = packedColor; |
4641 | - v[8].x = w - clampedThickness; |
4642 | - v[8].y = clampedThickness + radiusIn; |
4643 | - v[8].s1 = outerCoord2; |
4644 | - v[8].t1 = outerCoord1; |
4645 | - v[8].s2 = shapeOffset; |
4646 | - v[8].t2 = 1.0f; |
4647 | + |
4648 | + v[8].x = clampedThickness; |
4649 | + v[8].y = clampedThickness + innerRadius; |
4650 | + v[8].outerS = outerS2; |
4651 | + v[8].outerT = outerS3; |
4652 | + v[8].innerS = innerS0; |
4653 | + v[8].innerT = innerS1; |
4654 | v[8].color = packedColor; |
4655 | - v[9].x = w; |
4656 | - v[9].y = radiusOut; |
4657 | - v[9].s1 = shapeOffset; |
4658 | - v[9].t1 = 1.0f; |
4659 | - v[9].s2 = innerCoord1; |
4660 | - v[9].t2 = innerCoord2; |
4661 | + v[9].x = w - clampedThickness; |
4662 | + v[9].y = clampedThickness + innerRadius; |
4663 | + v[9].outerS = outerS2; |
4664 | + v[9].outerT = outerS3; |
4665 | + v[9].innerS = innerS0; |
4666 | + v[9].innerT = innerS1; |
4667 | v[9].color = packedColor; |
4668 | |
4669 | - // 4th row. |
4670 | - v[10].x = 0.0f; |
4671 | - v[10].y = h - radiusOut; |
4672 | - v[10].s1 = shapeOffset; |
4673 | - v[10].t1 = 1.0f; |
4674 | - v[10].s2 = innerCoord1; |
4675 | - v[10].t2 = innerCoord2; |
4676 | + v[10].x = clampedThickness; |
4677 | + v[10].y = h - (clampedThickness + innerRadius); |
4678 | + v[10].outerS = outerS2; |
4679 | + v[10].outerT = outerS3; |
4680 | + v[10].innerS = innerS0; |
4681 | + v[10].innerT = innerS1; |
4682 | v[10].color = packedColor; |
4683 | - v[11].x = clampedThickness; |
4684 | - v[11].y = h - (clampedThickness + radiusIn); |
4685 | - v[11].s1 = outerCoord2; |
4686 | - v[11].t1 = outerCoord1; |
4687 | - v[11].s2 = shapeOffset; |
4688 | - v[11].t2 = 1.0f; |
4689 | + v[11].x = w - clampedThickness; |
4690 | + v[11].y = h - (clampedThickness + innerRadius); |
4691 | + v[11].outerS = outerS2; |
4692 | + v[11].outerT = outerS3; |
4693 | + v[11].innerS = innerS0; |
4694 | + v[11].innerT = innerS1; |
4695 | v[11].color = packedColor; |
4696 | - v[12].x = w - clampedThickness; |
4697 | - v[12].y = h - (clampedThickness + radiusIn); |
4698 | - v[12].s1 = outerCoord2; |
4699 | - v[12].t1 = outerCoord1; |
4700 | - v[12].s2 = shapeOffset; |
4701 | - v[12].t2 = 1.0f; |
4702 | + |
4703 | + v[12].x = 0.0f; |
4704 | + v[12].y = h - outerRadius; |
4705 | + v[12].outerS = outerS0; |
4706 | + v[12].outerT = outerS1; |
4707 | + v[12].innerS = innerS2; |
4708 | + v[12].innerT = innerS3; |
4709 | v[12].color = packedColor; |
4710 | v[13].x = w; |
4711 | - v[13].y = h - radiusOut; |
4712 | - v[13].s1 = shapeOffset; |
4713 | - v[13].t1 = 1.0f; |
4714 | - v[13].s2 = innerCoord1; |
4715 | - v[13].t2 = innerCoord2; |
4716 | + v[13].y = h - outerRadius; |
4717 | + v[13].outerS = outerS0; |
4718 | + v[13].outerT = outerS1; |
4719 | + v[13].innerS = innerS2; |
4720 | + v[13].innerT = innerS3; |
4721 | v[13].color = packedColor; |
4722 | |
4723 | - // 5th row. |
4724 | - v[14].x = clampedThickness + radiusIn; |
4725 | + v[14].x = clampedThickness + innerRadius; |
4726 | v[14].y = h - clampedThickness; |
4727 | - v[14].s1 = outerCoord1; |
4728 | - v[14].t1 = outerCoord2; |
4729 | - v[14].s2 = 1.0f; |
4730 | - v[14].t2 = shapeOffset; |
4731 | + v[14].outerS = outerS3; |
4732 | + v[14].outerT = outerS2; |
4733 | + v[14].innerS = innerS1; |
4734 | + v[14].innerT = innerS0; |
4735 | v[14].color = packedColor; |
4736 | - v[15].x = w - (clampedThickness + radiusIn); |
4737 | + v[15].x = w - (clampedThickness + innerRadius); |
4738 | v[15].y = h - clampedThickness; |
4739 | - v[15].s1 = outerCoord1; |
4740 | - v[15].t1 = outerCoord2; |
4741 | - v[15].s2 = 1.0f; |
4742 | - v[15].t2 = shapeOffset; |
4743 | + v[15].outerS = outerS3; |
4744 | + v[15].outerT = outerS2; |
4745 | + v[15].innerS = innerS1; |
4746 | + v[15].innerT = innerS0; |
4747 | v[15].color = packedColor; |
4748 | |
4749 | - // 6th row. |
4750 | v[16].x = 0.0f; |
4751 | v[16].y = h; |
4752 | - v[16].s1 = shapeOffset; |
4753 | - v[16].t1 = shapeOffset; |
4754 | - v[16].s2 = innerCoord1; |
4755 | - v[16].t2 = innerCoord1; |
4756 | + v[16].outerS = outerS0; |
4757 | + v[16].outerT = outerS0; |
4758 | + v[16].innerS = innerS2; |
4759 | + v[16].innerT = innerS2; |
4760 | v[16].color = packedColor; |
4761 | - v[17].x = radiusOut; |
4762 | + v[17].x = outerRadius; |
4763 | v[17].y = h; |
4764 | - v[17].s1 = 1.0f; |
4765 | - v[17].t1 = shapeOffset; |
4766 | - v[17].s2 = innerCoord2; |
4767 | - v[17].t2 = innerCoord1; |
4768 | + v[17].outerS = outerS1; |
4769 | + v[17].outerT = outerS0; |
4770 | + v[17].innerS = innerS3; |
4771 | + v[17].innerT = innerS2; |
4772 | v[17].color = packedColor; |
4773 | - v[18].x = w - radiusOut; |
4774 | + v[18].x = w - outerRadius; |
4775 | v[18].y = h; |
4776 | - v[18].s1 = 1.0f; |
4777 | - v[18].t1 = shapeOffset; |
4778 | - v[18].s2 = innerCoord2; |
4779 | - v[18].t2 = innerCoord1; |
4780 | + v[18].outerS = outerS1; |
4781 | + v[18].outerT = outerS0; |
4782 | + v[18].innerS = innerS3; |
4783 | + v[18].innerT = innerS2; |
4784 | v[18].color = packedColor; |
4785 | v[19].x = w; |
4786 | v[19].y = h; |
4787 | - v[19].s1 = shapeOffset; |
4788 | - v[19].t1 = shapeOffset; |
4789 | - v[19].s2 = innerCoord1; |
4790 | - v[19].t2 = innerCoord1; |
4791 | + v[19].outerS = outerS0; |
4792 | + v[19].outerT = outerS0; |
4793 | + v[19].innerS = innerS2; |
4794 | + v[19].innerT = innerS2; |
4795 | v[19].color = packedColor; |
4796 | |
4797 | markDirty(QSGNode::DirtyGeometry); |
4798 | -} |
4799 | - |
4800 | -// --- Item --- |
4801 | - |
4802 | -UCFrame::UCFrame(QQuickItem* parent) |
4803 | - : QQuickItem(parent) |
4804 | - , m_color(defaultColor) |
4805 | - , m_thickness(defaultThickness) |
4806 | - , m_radius(defaultRadius) |
4807 | -{ |
4808 | - setFlag(ItemHasContents); |
4809 | -} |
4810 | - |
4811 | -void UCFrame::setThickness(qreal thickness) |
4812 | -{ |
4813 | - thickness = qMax(0.0f, static_cast<float>(thickness)); |
4814 | - if (m_thickness != thickness) { |
4815 | - m_thickness = thickness; |
4816 | - update(); |
4817 | - Q_EMIT thicknessChanged(); |
4818 | - } |
4819 | -} |
4820 | - |
4821 | -void UCFrame::setRadius(qreal radius) |
4822 | -{ |
4823 | - radius = qMax(0.0f, static_cast<float>(radius)); |
4824 | - if (m_radius != radius) { |
4825 | - m_radius = radius; |
4826 | - update(); |
4827 | - Q_EMIT radiusChanged(); |
4828 | - } |
4829 | -} |
4830 | - |
4831 | -void UCFrame::setColor(const QColor& color) |
4832 | -{ |
4833 | - const QRgb rgbColor = qRgba(color.red(), color.green(), color.blue(), color.alpha()); |
4834 | - if (m_color != rgbColor) { |
4835 | - m_color = rgbColor; |
4836 | - update(); |
4837 | - Q_EMIT colorChanged(); |
4838 | - } |
4839 | -} |
4840 | - |
4841 | -QSGNode* UCFrame::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* data) |
4842 | -{ |
4843 | - Q_UNUSED(data); |
4844 | - |
4845 | - const QSizeF itemSize(width(), height()); |
4846 | - if (itemSize.isEmpty() || m_thickness <= 0.0f) { |
4847 | - delete oldNode; |
4848 | - return NULL; |
4849 | - } |
4850 | - |
4851 | - UCFrameNode* node = oldNode ? static_cast<UCFrameNode*>(oldNode) : new UCFrameNode(); |
4852 | - node->updateGeometry(itemSize, m_thickness, m_radius, m_color); |
4853 | - |
4854 | - return node; |
4855 | -} |
4856 | - |
4857 | -UT_NAMESPACE_END |
4858 | + |
4859 | + // Update data for the preprocess() call. |
4860 | + if (m_radius[0] != static_cast<quint16>(deviceOuterRadius)) { |
4861 | + m_newRadius[0] = static_cast<quint16>(deviceOuterRadius); |
4862 | + } |
4863 | + if (m_radius[1] != static_cast<quint16>(deviceInnerRadius)) { |
4864 | + m_newRadius[1] = static_cast<quint16>(deviceInnerRadius); |
4865 | + } |
4866 | + if (m_type != static_cast<quint8>(type)) { |
4867 | + m_newType = static_cast<quint8>(type); |
4868 | + } |
4869 | +} |
4870 | |
4871 | === renamed file 'src/UbuntuToolkit/privates/frame_p.h' => 'src/UbuntuToolkit/privates/ucshapeframenodes_p.h' |
4872 | --- src/UbuntuToolkit/privates/frame_p.h 2016-09-09 17:49:07 +0000 |
4873 | +++ src/UbuntuToolkit/privates/ucshapeframenodes_p.h 2016-12-14 07:25:05 +0000 |
4874 | @@ -16,90 +16,79 @@ |
4875 | * Author: Loïc Molinari <loic.molinari@canonical.com> |
4876 | */ |
4877 | |
4878 | -#ifndef FRAME_P_H |
4879 | -#define FRAME_P_H |
4880 | +#ifndef UCSHAPEFRAMENODES_P_H |
4881 | +#define UCSHAPEFRAMENODES_P_H |
4882 | |
4883 | #include <QtQuick/QQuickItem> |
4884 | -#include <QtQuick/QSGMaterial> |
4885 | #include <QtQuick/QSGNode> |
4886 | |
4887 | -#include <UbuntuToolkit/ubuntutoolkitglobal.h> |
4888 | - |
4889 | -UT_NAMESPACE_BEGIN |
4890 | - |
4891 | -class UCFrameMaterial : public QSGMaterial |
4892 | -{ |
4893 | -public: |
4894 | - UCFrameMaterial(); |
4895 | - QSGMaterialType* type() const override; |
4896 | - QSGMaterialShader* createShader() const override; |
4897 | - int compare(const QSGMaterial* other) const override; |
4898 | - |
4899 | - quint32 textureId() const { return m_textureId; } |
4900 | - |
4901 | -private: |
4902 | - quint32 m_textureId; |
4903 | -}; |
4904 | - |
4905 | -class UCFrameNode : public QSGGeometryNode |
4906 | -{ |
4907 | -public: |
4908 | - struct Vertex { float x, y, s1, t1, s2, t2; quint32 color; }; |
4909 | - |
4910 | - static const unsigned short* indices(); |
4911 | +#include <UbuntuToolkit/private/ucshapetexturefactory_p.h> |
4912 | +#include <UbuntuToolkit/private/ucshaperesources_p.h> |
4913 | + |
4914 | +class UCShapeFrameEdgesNode : public QSGGeometryNode |
4915 | +{ |
4916 | +public: |
4917 | + UCShapeFrameEdgesNode(); |
4918 | + ~UCShapeFrameEdgesNode(); |
4919 | + |
4920 | + bool isSubtreeBlocked() const Q_DECL_OVERRIDE { return m_visible == 0; } |
4921 | + |
4922 | + void setVisible(bool visible); |
4923 | + void update(const QSizeF& itemSize, float radius, float thickness, float space, QRgb color); |
4924 | + |
4925 | +private: |
4926 | + UCShapeColorResources m_resources; |
4927 | + quint8 m_visible : 1; |
4928 | + quint8 m_blending : 1; |
4929 | + quint8 __padding : 6; |
4930 | +}; |
4931 | + |
4932 | +class UCShapeFrameCornersMaterial : public QSGMaterial |
4933 | +{ |
4934 | +public: |
4935 | + UCShapeFrameCornersMaterial(); |
4936 | + QSGMaterialType* type() const Q_DECL_OVERRIDE; |
4937 | + QSGMaterialShader* createShader() const Q_DECL_OVERRIDE; |
4938 | + int compare(const QSGMaterial* other) const Q_DECL_OVERRIDE; |
4939 | + |
4940 | + quint32 outerTextureId() const { return m_textureId[0]; } |
4941 | + quint32 innerTextureId() const { return m_textureId[1]; } |
4942 | + void updateTexture(int index, UCShapeType type, quint16 radius); |
4943 | + |
4944 | +private: |
4945 | + UCShapeTextureFactory<2> m_textureFactory; |
4946 | + quint32 m_textureId[2]; |
4947 | +}; |
4948 | + |
4949 | +class UCShapeFrameCornersNode : public QSGGeometryNode |
4950 | +{ |
4951 | +public: |
4952 | + struct Vertex { float x, y, outerS, outerT, innerS, innerT; quint32 color; }; |
4953 | + |
4954 | + static const quint16* indices(); |
4955 | static const QSGGeometry::AttributeSet& attributeSet(); |
4956 | |
4957 | - UCFrameNode(); |
4958 | - void updateGeometry(const QSizeF& itemSize, float thickness, float radius, QRgb color); |
4959 | + UCShapeFrameCornersNode(); |
4960 | + ~UCShapeFrameCornersNode() { DLOG("detroying UCShapeFrameCornersNode"); } |
4961 | + |
4962 | + void preprocess() Q_DECL_OVERRIDE; |
4963 | + bool isSubtreeBlocked() const Q_DECL_OVERRIDE { return m_visible == 0; } |
4964 | + |
4965 | + void setVisible(bool visible); |
4966 | + void update( |
4967 | + const QSizeF& itemSize, UCShapeType type, float radius, float thickness, float space, |
4968 | + QRgb color); |
4969 | |
4970 | private: |
4971 | - UCFrameMaterial m_material; |
4972 | + UCShapeFrameCornersMaterial m_material; |
4973 | QSGGeometry m_geometry; |
4974 | -}; |
4975 | - |
4976 | -// Renders the frame (border) of a shape. |
4977 | -class UBUNTUTOOLKIT_EXPORT UCFrame : public QQuickItem |
4978 | -{ |
4979 | - Q_OBJECT |
4980 | - |
4981 | - // Thickness of the frame in pixels. |
4982 | - Q_PROPERTY(qreal thickness READ thickness WRITE setThickness NOTIFY thicknessChanged) |
4983 | - |
4984 | - // Radius of the shape in pixels. A rectangle frame could be obtained using |
4985 | - // a radius of 0 but it's recommended to use a Ractangle with a border for |
4986 | - // that as it is a bit more efficient in term of rendering speed (reason is |
4987 | - // we don't bother to specify a dedicated mesh and shader when radius is 0). |
4988 | - Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged) |
4989 | - |
4990 | - // Color of the frame. Translucent colors are supported too. |
4991 | - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) |
4992 | - |
4993 | -public: |
4994 | - UCFrame(QQuickItem* parent = 0); |
4995 | - |
4996 | - qreal thickness() const { return m_thickness; } |
4997 | - void setThickness(qreal thickness); |
4998 | - qreal radius() const { return m_radius; } |
4999 | - void setRadius(qreal radius); |
5000 | - QColor color() const { |