Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(983)

Side by Side Diff: src/gpu/effects/GrRRectEffect.cpp

Issue 491673002: Initial refactor of shaderbuilder (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/effects/GrOvalEffect.cpp ('k') | src/gpu/effects/GrSimpleTextureEffect.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "gl/builders/GrGLProgramBuilder.h"
8 #include "GrRRectEffect.h" 9 #include "GrRRectEffect.h"
9 10
10 #include "gl/GrGLEffect.h" 11 #include "gl/GrGLEffect.h"
11 #include "gl/GrGLShaderBuilder.h"
12 #include "gl/GrGLSL.h" 12 #include "gl/GrGLSL.h"
13 #include "GrConvexPolyEffect.h" 13 #include "GrConvexPolyEffect.h"
14 #include "GrOvalEffect.h" 14 #include "GrOvalEffect.h"
15 #include "GrTBackendEffectFactory.h" 15 #include "GrTBackendEffectFactory.h"
16 16
17 #include "SkRRect.h" 17 #include "SkRRect.h"
18 18
19 // The effects defined here only handle rrect radii >= kRadiusMin. 19 // The effects defined here only handle rrect radii >= kRadiusMin.
20 static const SkScalar kRadiusMin = SK_ScalarHalf; 20 static const SkScalar kRadiusMin = SK_ScalarHalf;
21 21
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 } while (NULL == effect); 127 } while (NULL == effect);
128 return effect; 128 return effect;
129 } 129 }
130 130
131 ////////////////////////////////////////////////////////////////////////////// 131 //////////////////////////////////////////////////////////////////////////////
132 132
133 class GLCircularRRectEffect : public GrGLEffect { 133 class GLCircularRRectEffect : public GrGLEffect {
134 public: 134 public:
135 GLCircularRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&); 135 GLCircularRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
136 136
137 virtual void emitCode(GrGLShaderBuilder* builder, 137 virtual void emitCode(GrGLProgramBuilder* builder,
138 const GrDrawEffect& drawEffect, 138 const GrDrawEffect& drawEffect,
139 const GrEffectKey& key, 139 const GrEffectKey& key,
140 const char* outputColor, 140 const char* outputColor,
141 const char* inputColor, 141 const char* inputColor,
142 const TransformedCoordsArray&, 142 const TransformedCoordsArray&,
143 const TextureSamplerArray&) SK_OVERRIDE; 143 const TextureSamplerArray&) SK_OVERRIDE;
144 144
145 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyB uilder*); 145 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyB uilder*);
146 146
147 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_ OVERRIDE; 147 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_ OVERRIDE;
148 148
149 private: 149 private:
150 GrGLProgramDataManager::UniformHandle fInnerRectUniform; 150 GrGLProgramDataManager::UniformHandle fInnerRectUniform;
151 GrGLProgramDataManager::UniformHandle fRadiusPlusHalfUniform; 151 GrGLProgramDataManager::UniformHandle fRadiusPlusHalfUniform;
152 SkRRect fPrevRRect; 152 SkRRect fPrevRRect;
153 typedef GrGLEffect INHERITED; 153 typedef GrGLEffect INHERITED;
154 }; 154 };
155 155
156 GLCircularRRectEffect::GLCircularRRectEffect(const GrBackendEffectFactory& facto ry, 156 GLCircularRRectEffect::GLCircularRRectEffect(const GrBackendEffectFactory& facto ry,
157 const GrDrawEffect& drawEffect) 157 const GrDrawEffect& drawEffect)
158 : INHERITED (factory) { 158 : INHERITED (factory) {
159 fPrevRRect.setEmpty(); 159 fPrevRRect.setEmpty();
160 } 160 }
161 161
162 void GLCircularRRectEffect::emitCode(GrGLShaderBuilder* builder, 162 void GLCircularRRectEffect::emitCode(GrGLProgramBuilder* builder,
163 const GrDrawEffect& drawEffect, 163 const GrDrawEffect& drawEffect,
164 const GrEffectKey& key, 164 const GrEffectKey& key,
165 const char* outputColor, 165 const char* outputColor,
166 const char* inputColor, 166 const char* inputColor,
167 const TransformedCoordsArray&, 167 const TransformedCoordsArray&,
168 const TextureSamplerArray& samplers) { 168 const TextureSamplerArray& samplers) {
169 const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect> (); 169 const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect> ();
170 const char *rectName; 170 const char *rectName;
171 const char *radiusPlusHalfName; 171 const char *radiusPlusHalfName;
172 // The inner rect is the rrect bounds inset by the radius. Its left, top, ri ght, and bottom 172 // The inner rect is the rrect bounds inset by the radius. Its left, top, ri ght, and bottom
173 // edges correspond to components x, y, z, and w, respectively. When a side of the rrect has 173 // edges correspond to components x, y, z, and w, respectively. When a side of the rrect has
174 // only rectangular corners, that side's value corresponds to the rect edge' s value outset by 174 // only rectangular corners, that side's value corresponds to the rect edge' s value outset by
175 // half a pixel. 175 // half a pixel.
176 fInnerRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibil ity, 176 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi lity,
177 kVec4f_GrSLType, 177 kVec4f_GrSLType,
178 "innerRect", 178 "innerRect",
179 &rectName); 179 &rectName);
180 fRadiusPlusHalfUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Vi sibility, 180 fRadiusPlusHalfUniform = builder->addUniform(GrGLProgramBuilder::kFragment_V isibility,
181 kFloat_GrSLType, 181 kFloat_GrSLType,
182 "radiusPlusHalf", 182 "radiusPlusHalf",
183 &radiusPlusHalfName); 183 &radiusPlusHalfName);
184 const char* fragmentPos = builder->fragmentPosition(); 184
185 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
186 const char* fragmentPos = fsBuilder->fragmentPosition();
185 // At each quarter-circle corner we compute a vector that is the offset of t he fragment position 187 // At each quarter-circle corner we compute a vector that is the offset of t he fragment position
186 // from the circle center. The vector is pinned in x and y to be in the quar ter-plane relevant 188 // from the circle center. The vector is pinned in x and y to be in the quar ter-plane relevant
187 // to that corner. This means that points near the interior near the rrect t op edge will have 189 // to that corner. This means that points near the interior near the rrect t op edge will have
188 // a vector that points straight up for both the TL left and TR corners. Com puting an 190 // a vector that points straight up for both the TL left and TR corners. Com puting an
189 // alpha from this vector at either the TR or TL corner will give the correc t result. Similarly, 191 // alpha from this vector at either the TR or TL corner will give the correc t result. Similarly,
190 // fragments near the other three edges will get the correct AA. Fragments i n the interior of 192 // fragments near the other three edges will get the correct AA. Fragments i n the interior of
191 // the rrect will have a (0,0) vector at all four corners. So long as the ra dius > 0.5 they will 193 // the rrect will have a (0,0) vector at all four corners. So long as the ra dius > 0.5 they will
192 // correctly produce an alpha value of 1 at all four corners. We take the mi n of all the alphas. 194 // correctly produce an alpha value of 1 at all four corners. We take the mi n of all the alphas.
193 // The code below is a simplified version of the above that performs maxs on the vector 195 // The code below is a simplified version of the above that performs maxs on the vector
194 // components before computing distances and alpha values so that only one d istance computation 196 // components before computing distances and alpha values so that only one d istance computation
195 // need be computed to determine the min alpha. 197 // need be computed to determine the min alpha.
196 // 198 //
197 // For the cases where one half of the rrect is rectangular we drop one of t he x or y 199 // For the cases where one half of the rrect is rectangular we drop one of t he x or y
198 // computations, compute a separate rect edge alpha for the rect side, and m ul the two computed 200 // computations, compute a separate rect edge alpha for the rect side, and m ul the two computed
199 // alphas together. 201 // alphas together.
200 switch (crre.getCircularCornerFlags()) { 202 switch (crre.getCircularCornerFlags()) {
201 case CircularRRectEffect::kAll_CornerFlags: 203 case CircularRRectEffect::kAll_CornerFlags:
202 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos); 204 fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
203 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP os, rectName); 205 fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP os, rectName);
204 builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n") ; 206 fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n") ;
205 builder->fsCodeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0. 0, 1.0);\n", 207 fsBuilder->codeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0. 0, 1.0);\n",
206 radiusPlusHalfName); 208 radiusPlusHalfName);
207 break; 209 break;
208 case CircularRRectEffect::kTopLeft_CornerFlag: 210 case CircularRRectEffect::kTopLeft_CornerFlag:
209 builder->fsCodeAppendf("\t\tvec2 dxy = max(%s.xy - %s.xy, 0.0);\n", 211 fsBuilder->codeAppendf("\t\tvec2 dxy = max(%s.xy - %s.xy, 0.0);\n",
210 rectName, fragmentPos); 212 rectName, fragmentPos);
211 builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0. 0, 1.0);\n", 213 fsBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0. 0, 1.0);\n",
212 rectName, fragmentPos); 214 rectName, fragmentPos);
213 builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0 .0, 1.0);\n", 215 fsBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0 .0, 1.0);\n",
214 rectName, fragmentPos); 216 rectName, fragmentPos);
215 builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n", 217 fsBuilder->codeAppendf("\t\tfloat alpha = bottomAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
216 radiusPlusHalfName); 218 radiusPlusHalfName);
217 break; 219 break;
218 case CircularRRectEffect::kTopRight_CornerFlag: 220 case CircularRRectEffect::kTopRight_CornerFlag:
219 builder->fsCodeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.z, %s.y - %s.y), 0.0);\n", 221 fsBuilder->codeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.z, %s.y - %s.y), 0.0);\n",
220 fragmentPos, rectName, rectName, fragmentPos) ; 222 fragmentPos, rectName, rectName, fragmentPos) ;
221 builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0 , 1.0);\n", 223 fsBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0 , 1.0);\n",
222 fragmentPos, rectName); 224 fragmentPos, rectName);
223 builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0 .0, 1.0);\n", 225 fsBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0 .0, 1.0);\n",
224 rectName, fragmentPos); 226 rectName, fragmentPos);
225 builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n", 227 fsBuilder->codeAppendf("\t\tfloat alpha = bottomAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
226 radiusPlusHalfName); 228 radiusPlusHalfName);
227 break; 229 break;
228 case CircularRRectEffect::kBottomRight_CornerFlag: 230 case CircularRRectEffect::kBottomRight_CornerFlag:
229 builder->fsCodeAppendf("\t\tvec2 dxy = max(%s.xy - %s.zw, 0.0);\n", 231 fsBuilder->codeAppendf("\t\tvec2 dxy = max(%s.xy - %s.zw, 0.0);\n",
230 fragmentPos, rectName); 232 fragmentPos, rectName);
231 builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0 , 1.0);\n", 233 fsBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0 , 1.0);\n",
232 fragmentPos, rectName); 234 fragmentPos, rectName);
233 builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n", 235 fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
234 fragmentPos, rectName); 236 fragmentPos, rectName);
235 builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * leftAlpha * cla mp(%s - length(dxy), 0.0, 1.0);\n", 237 fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * leftAlpha * cla mp(%s - length(dxy), 0.0, 1.0);\n",
236 radiusPlusHalfName); 238 radiusPlusHalfName);
237 break; 239 break;
238 case CircularRRectEffect::kBottomLeft_CornerFlag: 240 case CircularRRectEffect::kBottomLeft_CornerFlag:
239 builder->fsCodeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.x, %s.y - %s.w), 0.0);\n", 241 fsBuilder->codeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.x, %s.y - %s.w), 0.0);\n",
240 rectName, fragmentPos, fragmentPos, rectName) ; 242 rectName, fragmentPos, fragmentPos, rectName) ;
241 builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0. 0, 1.0);\n", 243 fsBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0. 0, 1.0);\n",
242 rectName, fragmentPos); 244 rectName, fragmentPos);
243 builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n", 245 fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
244 fragmentPos, rectName); 246 fragmentPos, rectName);
245 builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * rightAlpha * cl amp(%s - length(dxy), 0.0, 1.0);\n", 247 fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * rightAlpha * cl amp(%s - length(dxy), 0.0, 1.0);\n",
246 radiusPlusHalfName); 248 radiusPlusHalfName);
247 break; 249 break;
248 case CircularRRectEffect::kLeft_CornerFlags: 250 case CircularRRectEffect::kLeft_CornerFlags:
249 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos); 251 fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
250 builder->fsCodeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos , rectName); 252 fsBuilder->codeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos , rectName);
251 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, d y1)), 0.0);\n"); 253 fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, d y1)), 0.0);\n");
252 builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0. 0, 1.0);\n", 254 fsBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0. 0, 1.0);\n",
253 rectName, fragmentPos); 255 rectName, fragmentPos);
254 builder->fsCodeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - le ngth(dxy), 0.0, 1.0);\n", 256 fsBuilder->codeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - le ngth(dxy), 0.0, 1.0);\n",
255 radiusPlusHalfName); 257 radiusPlusHalfName);
256 break; 258 break;
257 case CircularRRectEffect::kTop_CornerFlags: 259 case CircularRRectEffect::kTop_CornerFlags:
258 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos); 260 fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
259 builder->fsCodeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos , rectName); 261 fsBuilder->codeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos , rectName);
260 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy 0.y), 0.0);\n"); 262 fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy 0.y), 0.0);\n");
261 builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0 .0, 1.0);\n", 263 fsBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0 .0, 1.0);\n",
262 rectName, fragmentPos); 264 rectName, fragmentPos);
263 builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * clamp(%s - l ength(dxy), 0.0, 1.0);\n", 265 fsBuilder->codeAppendf("\t\tfloat alpha = bottomAlpha * clamp(%s - l ength(dxy), 0.0, 1.0);\n",
264 radiusPlusHalfName); 266 radiusPlusHalfName);
265 break; 267 break;
266 case CircularRRectEffect::kRight_CornerFlags: 268 case CircularRRectEffect::kRight_CornerFlags:
267 builder->fsCodeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, f ragmentPos); 269 fsBuilder->codeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, f ragmentPos);
268 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP os, rectName); 270 fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP os, rectName);
269 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1 .y)), 0.0);\n"); 271 fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1 .y)), 0.0);\n");
270 builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0 , 1.0);\n", 272 fsBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0 , 1.0);\n",
271 fragmentPos, rectName); 273 fragmentPos, rectName);
272 builder->fsCodeAppendf("\t\tfloat alpha = leftAlpha * clamp(%s - len gth(dxy), 0.0, 1.0);\n", 274 fsBuilder->codeAppendf("\t\tfloat alpha = leftAlpha * clamp(%s - len gth(dxy), 0.0, 1.0);\n",
273 radiusPlusHalfName); 275 radiusPlusHalfName);
274 break; 276 break;
275 case CircularRRectEffect::kBottom_CornerFlags: 277 case CircularRRectEffect::kBottom_CornerFlags:
276 builder->fsCodeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, f ragmentPos); 278 fsBuilder->codeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, f ragmentPos);
277 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP os, rectName); 279 fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP os, rectName);
278 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy 1.y), 0.0);\n"); 280 fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy 1.y), 0.0);\n");
279 builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n", 281 fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
280 fragmentPos, rectName); 282 fragmentPos, rectName);
281 builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - leng th(dxy), 0.0, 1.0);\n", 283 fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - leng th(dxy), 0.0, 1.0);\n",
282 radiusPlusHalfName); 284 radiusPlusHalfName);
283 break; 285 break;
284 } 286 }
285 287
286 if (kInverseFillAA_GrEffectEdgeType == crre.getEdgeType()) { 288 if (kInverseFillAA_GrEffectEdgeType == crre.getEdgeType()) {
287 builder->fsCodeAppend("\t\talpha = 1.0 - alpha;\n"); 289 fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n");
288 } 290 }
289 291
290 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, 292 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
291 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r()); 293 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r());
292 } 294 }
293 295
294 void GLCircularRRectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCap s&, 296 void GLCircularRRectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCap s&,
295 GrEffectKeyBuilder* b) { 297 GrEffectKeyBuilder* b) {
296 const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect> (); 298 const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect> ();
297 GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8); 299 GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8);
298 b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType()); 300 b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType());
299 } 301 }
300 302
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 } while (NULL == effect); 481 } while (NULL == effect);
480 return effect; 482 return effect;
481 } 483 }
482 484
483 ////////////////////////////////////////////////////////////////////////////// 485 //////////////////////////////////////////////////////////////////////////////
484 486
485 class GLEllipticalRRectEffect : public GrGLEffect { 487 class GLEllipticalRRectEffect : public GrGLEffect {
486 public: 488 public:
487 GLEllipticalRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&); 489 GLEllipticalRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
488 490
489 virtual void emitCode(GrGLShaderBuilder* builder, 491 virtual void emitCode(GrGLProgramBuilder* builder,
490 const GrDrawEffect& drawEffect, 492 const GrDrawEffect& drawEffect,
491 const GrEffectKey& key, 493 const GrEffectKey& key,
492 const char* outputColor, 494 const char* outputColor,
493 const char* inputColor, 495 const char* inputColor,
494 const TransformedCoordsArray&, 496 const TransformedCoordsArray&,
495 const TextureSamplerArray&) SK_OVERRIDE; 497 const TextureSamplerArray&) SK_OVERRIDE;
496 498
497 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyB uilder*); 499 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyB uilder*);
498 500
499 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_ OVERRIDE; 501 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_ OVERRIDE;
500 502
501 private: 503 private:
502 GrGLProgramDataManager::UniformHandle fInnerRectUniform; 504 GrGLProgramDataManager::UniformHandle fInnerRectUniform;
503 GrGLProgramDataManager::UniformHandle fInvRadiiSqdUniform; 505 GrGLProgramDataManager::UniformHandle fInvRadiiSqdUniform;
504 SkRRect fPrevRRect; 506 SkRRect fPrevRRect;
505 typedef GrGLEffect INHERITED; 507 typedef GrGLEffect INHERITED;
506 }; 508 };
507 509
508 GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrBackendEffectFactory& f actory, 510 GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrBackendEffectFactory& f actory,
509 const GrDrawEffect& drawEffect) 511 const GrDrawEffect& drawEffect)
510 : INHERITED (factory) { 512 : INHERITED (factory) {
511 fPrevRRect.setEmpty(); 513 fPrevRRect.setEmpty();
512 } 514 }
513 515
514 void GLEllipticalRRectEffect::emitCode(GrGLShaderBuilder* builder, 516 void GLEllipticalRRectEffect::emitCode(GrGLProgramBuilder* builder,
515 const GrDrawEffect& drawEffect, 517 const GrDrawEffect& drawEffect,
516 const GrEffectKey& key, 518 const GrEffectKey& key,
517 const char* outputColor, 519 const char* outputColor,
518 const char* inputColor, 520 const char* inputColor,
519 const TransformedCoordsArray&, 521 const TransformedCoordsArray&,
520 const TextureSamplerArray& samplers) { 522 const TextureSamplerArray& samplers) {
521 const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEff ect>(); 523 const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEff ect>();
522 const char *rectName; 524 const char *rectName;
523 // The inner rect is the rrect bounds inset by the x/y radii 525 // The inner rect is the rrect bounds inset by the x/y radii
524 fInnerRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibil ity, 526 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi lity,
525 kVec4f_GrSLType, 527 kVec4f_GrSLType,
526 "innerRect", 528 "innerRect",
527 &rectName); 529 &rectName);
528 const char* fragmentPos = builder->fragmentPosition(); 530
531 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
532 const char* fragmentPos = fsBuilder->fragmentPosition();
529 // At each quarter-ellipse corner we compute a vector that is the offset of the fragment pos 533 // At each quarter-ellipse corner we compute a vector that is the offset of the fragment pos
530 // to the ellipse center. The vector is pinned in x and y to be in the quart er-plane relevant 534 // to the ellipse center. The vector is pinned in x and y to be in the quart er-plane relevant
531 // to that corner. This means that points near the interior near the rrect t op edge will have 535 // to that corner. This means that points near the interior near the rrect t op edge will have
532 // a vector that points straight up for both the TL left and TR corners. Com puting an 536 // a vector that points straight up for both the TL left and TR corners. Com puting an
533 // alpha from this vector at either the TR or TL corner will give the correc t result. Similarly, 537 // alpha from this vector at either the TR or TL corner will give the correc t result. Similarly,
534 // fragments near the other three edges will get the correct AA. Fragments i n the interior of 538 // fragments near the other three edges will get the correct AA. Fragments i n the interior of
535 // the rrect will have a (0,0) vector at all four corners. So long as the ra dii > 0.5 they will 539 // the rrect will have a (0,0) vector at all four corners. So long as the ra dii > 0.5 they will
536 // correctly produce an alpha value of 1 at all four corners. We take the mi n of all the alphas. 540 // correctly produce an alpha value of 1 at all four corners. We take the mi n of all the alphas.
537 // The code below is a simplified version of the above that performs maxs on the vector 541 // The code below is a simplified version of the above that performs maxs on the vector
538 // components before computing distances and alpha values so that only one d istance computation 542 // components before computing distances and alpha values so that only one d istance computation
539 // need be computed to determine the min alpha. 543 // need be computed to determine the min alpha.
540 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmen tPos); 544 fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmen tPos);
541 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rect Name); 545 fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rect Name);
542 switch (erre.getRRect().getType()) { 546 switch (erre.getRRect().getType()) {
543 case SkRRect::kSimple_Type: { 547 case SkRRect::kSimple_Type: {
544 const char *invRadiiXYSqdName; 548 const char *invRadiiXYSqdName;
545 fInvRadiiSqdUniform = builder->addUniform(GrGLShaderBuilder::kFragme nt_Visibility, 549 fInvRadiiSqdUniform = builder->addUniform(GrGLProgramBuilder::kFragm ent_Visibility,
546 kVec2f_GrSLType, 550 kVec2f_GrSLType,
547 "invRadiiXY", 551 "invRadiiXY",
548 &invRadiiXYSqdName); 552 &invRadiiXYSqdName);
549 builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n") ; 553 fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n") ;
550 // Z is the x/y offsets divided by squared radii. 554 // Z is the x/y offsets divided by squared radii.
551 builder->fsCodeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName ); 555 fsBuilder->codeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName );
552 break; 556 break;
553 } 557 }
554 case SkRRect::kNinePatch_Type: { 558 case SkRRect::kNinePatch_Type: {
555 const char *invRadiiLTRBSqdName; 559 const char *invRadiiLTRBSqdName;
556 fInvRadiiSqdUniform = builder->addUniform(GrGLShaderBuilder::kFragme nt_Visibility, 560 fInvRadiiSqdUniform = builder->addUniform(GrGLProgramBuilder::kFragm ent_Visibility,
557 kVec4f_GrSLType, 561 kVec4f_GrSLType,
558 "invRadiiLTRB", 562 "invRadiiLTRB",
559 &invRadiiLTRBSqdName); 563 &invRadiiLTRBSqdName);
560 builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n") ; 564 fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n") ;
561 // Z is the x/y offsets divided by squared radii. We only care about the (at most) one 565 // Z is the x/y offsets divided by squared radii. We only care about the (at most) one
562 // corner where both the x and y offsets are positive, hence the max es. (The inverse 566 // corner where both the x and y offsets are positive, hence the max es. (The inverse
563 // squared radii will always be positive.) 567 // squared radii will always be positive.)
564 builder->fsCodeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s .zw), 0.0);\n", 568 fsBuilder->codeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s .zw), 0.0);\n",
565 invRadiiLTRBSqdName, invRadiiLTRBSqdName); 569 invRadiiLTRBSqdName, invRadiiLTRBSqdName);
566 break; 570 break;
567 } 571 }
568 default: 572 default:
569 SkFAIL("RRect should always be simple or nine-patch."); 573 SkFAIL("RRect should always be simple or nine-patch.");
570 } 574 }
571 // implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1. 575 // implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1.
572 builder->fsCodeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n"); 576 fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n");
573 // grad_dot is the squared length of the gradient of the implicit. 577 // grad_dot is the squared length of the gradient of the implicit.
574 builder->fsCodeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n"); 578 fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
575 // avoid calling inversesqrt on zero. 579 // avoid calling inversesqrt on zero.
576 builder->fsCodeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n"); 580 fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
577 builder->fsCodeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_ dot);\n"); 581 fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_ dot);\n");
578 582
579 if (kFillAA_GrEffectEdgeType == erre.getEdgeType()) { 583 if (kFillAA_GrEffectEdgeType == erre.getEdgeType()) {
580 builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1 .0);\n"); 584 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1 .0);\n");
581 } else { 585 } else {
582 builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1 .0);\n"); 586 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1 .0);\n");
583 } 587 }
584 588
585 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, 589 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
586 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r()); 590 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r());
587 } 591 }
588 592
589 void GLEllipticalRRectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLC aps&, 593 void GLEllipticalRRectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLC aps&,
590 GrEffectKeyBuilder* b) { 594 GrEffectKeyBuilder* b) {
591 const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEff ect>(); 595 const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEff ect>();
592 GR_STATIC_ASSERT(kLast_GrEffectEdgeType < (1 << 3)); 596 GR_STATIC_ASSERT(kLast_GrEffectEdgeType < (1 << 3));
593 b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3); 597 b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3);
594 } 598 }
595 599
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 if (rrect.isNinePatch()) { 725 if (rrect.isNinePatch()) {
722 return EllipticalRRectEffect::Create(edgeType, rrect); 726 return EllipticalRRectEffect::Create(edgeType, rrect);
723 } 727 }
724 return NULL; 728 return NULL;
725 } 729 }
726 } 730 }
727 } 731 }
728 732
729 return NULL; 733 return NULL;
730 } 734 }
OLDNEW
« no previous file with comments | « src/gpu/effects/GrOvalEffect.cpp ('k') | src/gpu/effects/GrSimpleTextureEffect.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698