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

Side by Side Diff: src/effects/SkRRectsGaussianEdgeShader.cpp

Issue 2344963002: Fix color bug in SkRRectsGaussianEdgeShader (Closed)
Patch Set: Add new constant to GM Created 4 years, 3 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 | « include/effects/SkRRectsGaussianEdgeShader.h ('k') | no next file » | 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 2016 Google Inc. 2 * Copyright 2016 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 "SkRRectsGaussianEdgeShader.h" 8 #include "SkRRectsGaussianEdgeShader.h"
9 #include "SkReadBuffer.h" 9 #include "SkReadBuffer.h"
10 #include "SkWriteBuffer.h" 10 #include "SkWriteBuffer.h"
11 11
12 /** \class SkRRectsGaussianEdgeShaderImpl 12 /** \class SkRRectsGaussianEdgeShaderImpl
13 * This shader applies a gaussian edge to the intersection of two round rects. 13 * This shader applies a gaussian edge to the intersection of two round rects.
14 * The round rects must have the same radii at each corner and the x&y radii 14 * The round rects must have the same radii at each corner and the x&y radii
15 * must also be equal. 15 * must also be equal.
16 */ 16 */
17 class SkRRectsGaussianEdgeShaderImpl : public SkShader { 17 class SkRRectsGaussianEdgeShaderImpl : public SkShader {
18 public: 18 public:
19 SkRRectsGaussianEdgeShaderImpl(const SkRRect& first, const SkRRect& second, 19 SkRRectsGaussianEdgeShaderImpl(const SkRRect& first, const SkRRect& second, SkScalar radius)
20 SkScalar radius, SkScalar pad)
21 : fFirst(first) 20 : fFirst(first)
22 , fSecond(second) 21 , fSecond(second)
23 , fRadius(radius) 22 , fRadius(radius) {
24 , fPad(pad) {
25 } 23 }
26 24
27 bool isOpaque() const override { return false; } 25 bool isOpaque() const override { return false; }
28 26
29 #if SK_SUPPORT_GPU 27 #if SK_SUPPORT_GPU
30 sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const overri de; 28 sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const overri de;
31 #endif 29 #endif
32 30
33 class GaussianEdgeShaderContext : public SkShader::Context { 31 class GaussianEdgeShaderContext : public SkShader::Context {
34 public: 32 public:
(...skipping 16 matching lines...) Expand all
51 49
52 protected: 50 protected:
53 void flatten(SkWriteBuffer&) const override; 51 void flatten(SkWriteBuffer&) const override;
54 size_t onContextSize(const ContextRec&) const override; 52 size_t onContextSize(const ContextRec&) const override;
55 Context* onCreateContext(const ContextRec&, void*) const override; 53 Context* onCreateContext(const ContextRec&, void*) const override;
56 54
57 private: 55 private:
58 SkRRect fFirst; 56 SkRRect fFirst;
59 SkRRect fSecond; 57 SkRRect fSecond;
60 SkScalar fRadius; 58 SkScalar fRadius;
61 SkScalar fPad;
62 59
63 friend class SkRRectsGaussianEdgeShader; // for serialization registration s ystem 60 friend class SkRRectsGaussianEdgeShader; // for serialization registration s ystem
64 61
65 typedef SkShader INHERITED; 62 typedef SkShader INHERITED;
66 }; 63 };
67 64
68 //////////////////////////////////////////////////////////////////////////// 65 ////////////////////////////////////////////////////////////////////////////
69 66
70 #if SK_SUPPORT_GPU 67 #if SK_SUPPORT_GPU
71 68
72 #include "GrCoordTransform.h" 69 #include "GrCoordTransform.h"
73 #include "GrFragmentProcessor.h" 70 #include "GrFragmentProcessor.h"
74 #include "GrInvariantOutput.h" 71 #include "GrInvariantOutput.h"
75 #include "glsl/GrGLSLFragmentProcessor.h" 72 #include "glsl/GrGLSLFragmentProcessor.h"
76 #include "glsl/GrGLSLFragmentShaderBuilder.h" 73 #include "glsl/GrGLSLFragmentShaderBuilder.h"
77 #include "glsl/GrGLSLProgramDataManager.h" 74 #include "glsl/GrGLSLProgramDataManager.h"
78 #include "glsl/GrGLSLUniformHandler.h" 75 #include "glsl/GrGLSLUniformHandler.h"
79 #include "SkGr.h" 76 #include "SkGr.h"
80 #include "SkGrPriv.h" 77 #include "SkGrPriv.h"
81 78
82 class RRectsGaussianEdgeFP : public GrFragmentProcessor { 79 class RRectsGaussianEdgeFP : public GrFragmentProcessor {
83 public: 80 public:
84 enum Mode { 81 enum Mode {
85 kCircle_Mode, 82 kCircle_Mode,
86 kRect_Mode, 83 kRect_Mode,
87 kSimpleCircular_Mode, 84 kSimpleCircular_Mode,
88 }; 85 };
89 86
90 RRectsGaussianEdgeFP(const SkRRect& first, const SkRRect& second, 87 RRectsGaussianEdgeFP(const SkRRect& first, const SkRRect& second, SkScalar r adius)
91 SkScalar radius, SkScalar pad)
92 : fFirst(first) 88 : fFirst(first)
93 , fSecond(second) 89 , fSecond(second)
94 , fRadius(radius) 90 , fRadius(radius) {
95 , fPad(pad) {
96 this->initClassID<RRectsGaussianEdgeFP>(); 91 this->initClassID<RRectsGaussianEdgeFP>();
97 this->setWillReadFragmentPosition(); 92 this->setWillReadFragmentPosition();
98 93
99 fFirstMode = ComputeMode(fFirst); 94 fFirstMode = ComputeMode(fFirst);
100 fSecondMode = ComputeMode(fSecond); 95 fSecondMode = ComputeMode(fSecond);
101 } 96 }
102 97
103 class GLSLRRectsGaussianEdgeFP : public GrGLSLFragmentProcessor { 98 class GLSLRRectsGaussianEdgeFP : public GrGLSLFragmentProcessor {
104 public: 99 public:
105 GLSLRRectsGaussianEdgeFP() { } 100 GLSLRRectsGaussianEdgeFP() { }
106 101
107 // This method emits code so that, for each shape, the distance from the edge is returned 102 // This method emits code so that, for each shape, the distance from the edge is returned
108 // in 'outputName' clamped to 0..1 with positive distance being towards the center of the 103 // in 'outputName' clamped to 0..1 with positive distance being towards the center of the
109 // shape. The distance will have been normalized by the radius. 104 // shape. The distance will have been normalized by the radius.
110 void emitModeCode(Mode mode, 105 void emitModeCode(Mode mode,
111 GrGLSLFPFragmentBuilder* fragBuilder, 106 GrGLSLFPFragmentBuilder* fragBuilder,
112 const char* posName, 107 const char* posName,
113 const char* sizesName, 108 const char* sizesName,
114 const char* radiiName, 109 const char* radiiName,
115 const char* padRadName, 110 const char* radName,
116 const char* outputName, 111 const char* outputName,
117 const char indices[2]) { // how to access the params for the 2 rrects 112 const char indices[2]) { // how to access the params for the 2 rrects
118 113
119 // positive distance is towards the center of the circle 114 // positive distance is towards the center of the circle
120 fragBuilder->codeAppendf("vec2 delta = %s.xy - %s.%s;", 115 fragBuilder->codeAppendf("vec2 delta = %s.xy - %s.%s;",
121 fragBuilder->fragmentPosition(), posName, i ndices); 116 fragBuilder->fragmentPosition(), posName, i ndices);
122 117
123 switch (mode) { 118 switch (mode) {
124 case kCircle_Mode: 119 case kCircle_Mode:
125 fragBuilder->codeAppendf("%s = clamp((%s.%c - length(delta))/%s. y, 0.0, 1.0);", 120 fragBuilder->codeAppendf("%s = clamp((%s.%c - length(delta))/%s, 0.0, 1.0);",
126 outputName, sizesName, indices[0], padR adName); 121 outputName, sizesName, indices[0], radN ame);
127 break; 122 break;
128 case kRect_Mode: 123 case kRect_Mode:
129 fragBuilder->codeAppendf( 124 fragBuilder->codeAppendf(
130 "vec2 rectDist = vec2(1.0 - clamp((%s.%c - abs(delta.x))/%s. y, 0.0, 1.0)," 125 "vec2 rectDist = vec2(1.0 - clamp((%s.%c - abs(delta.x))/%s, 0.0, 1.0),"
131 "1.0 - clamp((%s.%c - abs(delta.y))/%s. y, 0.0, 1.0));", 126 "1.0 - clamp((%s.%c - abs(delta.y))/%s, 0.0, 1.0));",
132 sizesName, indices[0], padRadName, 127 sizesName, indices[0], radName,
133 sizesName, indices[1], padRadName); 128 sizesName, indices[1], radName);
134 fragBuilder->codeAppendf("%s = 1.0 - length(rectDist);", outputN ame); 129 fragBuilder->codeAppendf("%s = 1.0 - length(rectDist);", outputN ame);
135 break; 130 break;
136 case kSimpleCircular_Mode: 131 case kSimpleCircular_Mode:
137 // For the circular round rect we first compute the distance 132 // For the circular round rect we first compute the distance
138 // to the rect. Then we compute a multiplier that is 1 if the 133 // to the rect. Then we compute a multiplier that is 1 if the
139 // point is in one of the circular corners. We then compute the 134 // point is in one of the circular corners. We then compute the
140 // distance from the corner and then use the multiplier to mask 135 // distance from the corner and then use the multiplier to mask
141 // between the two distances. 136 // between the two distances.
142 fragBuilder->codeAppendf("float xDist = clamp((%s.%c - abs(delta .x))/%s.y," 137 fragBuilder->codeAppendf("float xDist = clamp((%s.%c - abs(delta .x))/%s,"
143 " 0.0, 1.0);", 138 " 0.0, 1.0);",
144 sizesName, indices[0], padRadName); 139 sizesName, indices[0], radName);
145 fragBuilder->codeAppendf("float yDist = clamp((%s.%c - abs(delta .y))/%s.y," 140 fragBuilder->codeAppendf("float yDist = clamp((%s.%c - abs(delta .y))/%s,"
146 "0.0, 1.0);", 141 "0.0, 1.0);",
147 sizesName, indices[1], padRadName); 142 sizesName, indices[1], radName);
148 fragBuilder->codeAppend("float rectDist = min(xDist, yDist);"); 143 fragBuilder->codeAppend("float rectDist = min(xDist, yDist);");
149 144
150 fragBuilder->codeAppendf("vec2 cornerCenter = %s.%s - %s.%s;", 145 fragBuilder->codeAppendf("vec2 cornerCenter = %s.%s - %s.%s;",
151 sizesName, indices, radiiName, indices) ; 146 sizesName, indices, radiiName, indices) ;
152 fragBuilder->codeAppend("delta = vec2(abs(delta.x) - cornerCente r.x," 147 fragBuilder->codeAppend("delta = vec2(abs(delta.x) - cornerCente r.x,"
153 "abs(delta.y) - cornerCente r.y);"); 148 "abs(delta.y) - cornerCente r.y);");
154 fragBuilder->codeAppendf("xDist = %s.%c - abs(delta.x);", radiiN ame, indices[0]); 149 fragBuilder->codeAppendf("xDist = %s.%c - abs(delta.x);", radiiN ame, indices[0]);
155 fragBuilder->codeAppendf("yDist = %s.%c - abs(delta.y);", radiiN ame, indices[1]); 150 fragBuilder->codeAppendf("yDist = %s.%c - abs(delta.y);", radiiN ame, indices[1]);
156 fragBuilder->codeAppend("float cornerDist = min(xDist, yDist);") ; 151 fragBuilder->codeAppend("float cornerDist = min(xDist, yDist);") ;
157 fragBuilder->codeAppend("float multiplier = step(0.0, cornerDist );"); 152 fragBuilder->codeAppend("float multiplier = step(0.0, cornerDist );");
158 153
159 fragBuilder->codeAppendf("delta += %s.%s;", radiiName, indices); 154 fragBuilder->codeAppendf("delta += %s.%s;", radiiName, indices);
160 155
161 fragBuilder->codeAppendf("cornerDist = clamp((2.0 * %s.%c - leng th(delta))/%s.y," 156 fragBuilder->codeAppendf("cornerDist = clamp((2.0 * %s.%c - leng th(delta))/%s,"
162 "0.0, 1.0);", 157 "0.0, 1.0);",
163 radiiName, indices[0], padRadName); 158 radiiName, indices[0], radName);
164 159
165 fragBuilder->codeAppendf("%s = (multiplier * cornerDist) +" 160 fragBuilder->codeAppendf("%s = (multiplier * cornerDist) +"
166 "((1.0-multiplier) * rectDist);", 161 "((1.0-multiplier) * rectDist);",
167 outputName); 162 outputName);
168 break; 163 break;
169 } 164 }
170 } 165 }
171 166
172 void emitCode(EmitArgs& args) override { 167 void emitCode(EmitArgs& args) override {
173 const RRectsGaussianEdgeFP& fp = args.fFp.cast<RRectsGaussianEdgeFP> (); 168 const RRectsGaussianEdgeFP& fp = args.fFp.cast<RRectsGaussianEdgeFP> ();
174 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 169 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
175 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 170 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
176 171
177 const char* positionsUniName = nullptr; 172 const char* positionsUniName = nullptr;
178 fPositionsUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 173 fPositionsUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
179 kVec4f_GrSLType, kDefault _GrSLPrecision, 174 kVec4f_GrSLType, kDefault _GrSLPrecision,
180 "Positions", &positionsUn iName); 175 "Positions", &positionsUn iName);
181 const char* sizesUniName = nullptr; 176 const char* sizesUniName = nullptr;
182 fSizesUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 177 fSizesUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
183 kVec4f_GrSLType, kDefault_GrS LPrecision, 178 kVec4f_GrSLType, kDefault_GrS LPrecision,
184 "Sizes", &sizesUniName); 179 "Sizes", &sizesUniName);
185 const char* radiiUniName = nullptr; 180 const char* radiiUniName = nullptr;
186 if (fp.fFirstMode == kSimpleCircular_Mode || fp.fSecondMode == kSimp leCircular_Mode) { 181 if (fp.fFirstMode == kSimpleCircular_Mode || fp.fSecondMode == kSimp leCircular_Mode) {
187 fRadiiUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 182 fRadiiUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
188 kVec4f_GrSLType, kDefault _GrSLPrecision, 183 kVec4f_GrSLType, kDefault _GrSLPrecision,
189 "Radii", &radiiUniName); 184 "Radii", &radiiUniName);
190 } 185 }
191 const char* padRadUniName = nullptr; 186 const char* radUniName = nullptr;
192 fPadRadUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 187 fRadiusUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
193 kVec2f_GrSLType, kDefault_Gr SLPrecision, 188 kFloat_GrSLType, kDefault_Gr SLPrecision,
194 "PadRad", &padRadUniName); 189 "Radius", &radUniName);
195 190
196 fragBuilder->codeAppend("float firstDist;"); 191 fragBuilder->codeAppend("float firstDist;");
197 fragBuilder->codeAppend("{"); 192 fragBuilder->codeAppend("{");
198 this->emitModeCode(fp.firstMode(), fragBuilder, 193 this->emitModeCode(fp.firstMode(), fragBuilder,
199 positionsUniName, sizesUniName, radiiUniName, 194 positionsUniName, sizesUniName, radiiUniName,
200 padRadUniName, "firstDist", "xy"); 195 radUniName, "firstDist", "xy");
201 fragBuilder->codeAppend("}"); 196 fragBuilder->codeAppend("}");
202 197
203 fragBuilder->codeAppend("float secondDist;"); 198 fragBuilder->codeAppend("float secondDist;");
204 fragBuilder->codeAppend("{"); 199 fragBuilder->codeAppend("{");
205 this->emitModeCode(fp.secondMode(), fragBuilder, 200 this->emitModeCode(fp.secondMode(), fragBuilder,
206 positionsUniName, sizesUniName, radiiUniName, 201 positionsUniName, sizesUniName, radiiUniName,
207 padRadUniName, "secondDist", "zw"); 202 radUniName, "secondDist", "zw");
208 fragBuilder->codeAppend("}"); 203 fragBuilder->codeAppend("}");
209 204
210 fragBuilder->codeAppendf("float dist = %s.y * firstDist * secondDist ;", 205 fragBuilder->codeAppendf("float dist = %s * firstDist * secondDist;" , radUniName);
211 padRadUniName);
212 206
213 // Finally use the distance to apply the Gaussian edge 207 // Finally use the distance to apply the Gaussian edge
214 // TODO: we undo the multiply by the radius here - we should just sk ip both 208 // TODO: we undo the multiply by the radius here - we should just sk ip both
215 fragBuilder->codeAppendf("float factor = 1.0 - clamp((dist - %s.x)/% s.y, 0.0, 1.0);", 209 fragBuilder->codeAppendf("float factor = 1.0 - clamp(dist/%s, 0.0, 1 .0);", radUniName);
216 padRadUniName, padRadUniName);
217 fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.01 8;"); 210 fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.01 8;");
218 fragBuilder->codeAppendf("%s = vec4(%s.rgb, factor);", 211 fragBuilder->codeAppendf("%s = factor*%s;",
219 args.fOutputColor, args.fInputColor); 212 args.fOutputColor, args.fInputColor);
220 } 213 }
221 214
222 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, 215 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
223 GrProcessorKeyBuilder* b) { 216 GrProcessorKeyBuilder* b) {
224 const RRectsGaussianEdgeFP& fp = proc.cast<RRectsGaussianEdgeFP>(); 217 const RRectsGaussianEdgeFP& fp = proc.cast<RRectsGaussianEdgeFP>();
225 218
226 b->add32(fp.firstMode() | (fp.secondMode() << 4)); 219 b->add32(fp.firstMode() | (fp.secondMode() << 4));
227 } 220 }
228 221
(...skipping 20 matching lines...) Expand all
249 edgeFP.secondMode() == kSimpleCircular_Mode) { 242 edgeFP.secondMode() == kSimpleCircular_Mode) {
250 // This is a bit of overkill since fX should equal fY for both r ound rects but it 243 // This is a bit of overkill since fX should equal fY for both r ound rects but it
251 // makes the shader code simpler. 244 // makes the shader code simpler.
252 pdman.set4f(fRadiiUni, 245 pdman.set4f(fRadiiUni,
253 0.5f * first.getSimpleRadii().fX, 246 0.5f * first.getSimpleRadii().fX,
254 0.5f * first.getSimpleRadii().fY, 247 0.5f * first.getSimpleRadii().fY,
255 0.5f * second.getSimpleRadii().fX, 248 0.5f * second.getSimpleRadii().fX,
256 0.5f * second.getSimpleRadii().fY); 249 0.5f * second.getSimpleRadii().fY);
257 } 250 }
258 251
259 pdman.set2f(fPadRadUni, edgeFP.pad(), edgeFP.radius()); 252 pdman.set1f(fRadiusUni, edgeFP.radius());
260 } 253 }
261 254
262 private: 255 private:
263 // The centers of the two round rects (x1, y1, x2, y2) 256 // The centers of the two round rects (x1, y1, x2, y2)
264 GrGLSLProgramDataManager::UniformHandle fPositionsUni; 257 GrGLSLProgramDataManager::UniformHandle fPositionsUni;
265 258
266 // The half widths and half heights of the two round rects (w1/2, h1/2, w2/2, h2/2) 259 // The half widths and half heights of the two round rects (w1/2, h1/2, w2/2, h2/2)
267 // For circles we still upload both width & height to simplify things 260 // For circles we still upload both width & height to simplify things
268 GrGLSLProgramDataManager::UniformHandle fSizesUni; 261 GrGLSLProgramDataManager::UniformHandle fSizesUni;
269 262
270 // The half corner radii of the two round rects (rx1/2, ry1/2, rx2/2, ry 2/2) 263 // The half corner radii of the two round rects (rx1/2, ry1/2, rx2/2, ry 2/2)
271 // We upload both the x&y radii (although they are currently always the same) to make 264 // We upload both the x&y radii (although they are currently always the same) to make
272 // the indexing in the shader code simpler. In some future world we coul d also support 265 // the indexing in the shader code simpler. In some future world we coul d also support
273 // non-circular corner round rects & ellipses. 266 // non-circular corner round rects & ellipses.
274 GrGLSLProgramDataManager::UniformHandle fRadiiUni; 267 GrGLSLProgramDataManager::UniformHandle fRadiiUni;
275 268
276 // The pad and radius parameters (padding, radius) 269 // The radius parameters (radius)
277 GrGLSLProgramDataManager::UniformHandle fPadRadUni; 270 GrGLSLProgramDataManager::UniformHandle fRadiusUni;
278 271
279 typedef GrGLSLFragmentProcessor INHERITED; 272 typedef GrGLSLFragmentProcessor INHERITED;
280 }; 273 };
281 274
282 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { 275 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
283 GLSLRRectsGaussianEdgeFP::GenKey(*this, caps, b); 276 GLSLRRectsGaussianEdgeFP::GenKey(*this, caps, b);
284 } 277 }
285 278
286 const char* name() const override { return "RRectsGaussianEdgeFP"; } 279 const char* name() const override { return "RRectsGaussianEdgeFP"; }
287 280
288 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 281 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
289 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); 282 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
290 } 283 }
291 284
292 const SkRRect& first() const { return fFirst; } 285 const SkRRect& first() const { return fFirst; }
293 Mode firstMode() const { return fFirstMode; } 286 Mode firstMode() const { return fFirstMode; }
294 const SkRRect& second() const { return fSecond; } 287 const SkRRect& second() const { return fSecond; }
295 Mode secondMode() const { return fSecondMode; } 288 Mode secondMode() const { return fSecondMode; }
296 SkScalar radius() const { return fRadius; } 289 SkScalar radius() const { return fRadius; }
297 SkScalar pad() const { return fPad; }
298 290
299 private: 291 private:
300 static Mode ComputeMode(const SkRRect& rr) { 292 static Mode ComputeMode(const SkRRect& rr) {
301 if (rr.isCircle()) { 293 if (rr.isCircle()) {
302 return kCircle_Mode; 294 return kCircle_Mode;
303 } else if (rr.isRect()) { 295 } else if (rr.isRect()) {
304 return kRect_Mode; 296 return kRect_Mode;
305 } else { 297 } else {
306 SkASSERT(rr.isSimpleCircular()); 298 SkASSERT(rr.isSimpleCircular());
307 return kSimpleCircular_Mode; 299 return kSimpleCircular_Mode;
308 } 300 }
309 } 301 }
310 302
311 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 303 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
312 return new GLSLRRectsGaussianEdgeFP; 304 return new GLSLRRectsGaussianEdgeFP;
313 } 305 }
314 306
315 bool onIsEqual(const GrFragmentProcessor& proc) const override { 307 bool onIsEqual(const GrFragmentProcessor& proc) const override {
316 const RRectsGaussianEdgeFP& edgeFP = proc.cast<RRectsGaussianEdgeFP>(); 308 const RRectsGaussianEdgeFP& edgeFP = proc.cast<RRectsGaussianEdgeFP>();
317 return fFirst == edgeFP.fFirst && fSecond == edgeFP.fSecond && 309 return fFirst == edgeFP.fFirst &&
318 fRadius == edgeFP.fRadius && fPad == edgeFP.fPad; 310 fSecond == edgeFP.fSecond &&
311 fRadius == edgeFP.fRadius;
319 } 312 }
320 313
321 SkRRect fFirst; 314 SkRRect fFirst;
322 Mode fFirstMode; 315 Mode fFirstMode;
323 SkRRect fSecond; 316 SkRRect fSecond;
324 Mode fSecondMode; 317 Mode fSecondMode;
325 SkScalar fRadius; 318 SkScalar fRadius;
326 SkScalar fPad;
327 319
328 typedef GrFragmentProcessor INHERITED; 320 typedef GrFragmentProcessor INHERITED;
329 }; 321 };
330 322
331 //////////////////////////////////////////////////////////////////////////// 323 ////////////////////////////////////////////////////////////////////////////
332 324
333 sk_sp<GrFragmentProcessor> SkRRectsGaussianEdgeShaderImpl::asFragmentProcessor( 325 sk_sp<GrFragmentProcessor> SkRRectsGaussianEdgeShaderImpl::asFragmentProcessor(
334 const AsFPAr gs& args) const { 326 const AsFPAr gs& args) const {
335 return sk_make_sp<RRectsGaussianEdgeFP>(fFirst, fSecond, fRadius, fPad); 327 return sk_make_sp<RRectsGaussianEdgeFP>(fFirst, fSecond, fRadius);
336 } 328 }
337 329
338 #endif 330 #endif
339 331
340 //////////////////////////////////////////////////////////////////////////// 332 ////////////////////////////////////////////////////////////////////////////
341 333
342 SkRRectsGaussianEdgeShaderImpl::GaussianEdgeShaderContext::GaussianEdgeShaderCon text( 334 SkRRectsGaussianEdgeShaderImpl::GaussianEdgeShaderContext::GaussianEdgeShaderCon text(
343 const SkRRectsGaussianEdgeSh aderImpl& shader, 335 const SkRRectsGaussianEdgeSh aderImpl& shader,
344 const ContextRec& rec) 336 const ContextRec& rec)
345 : INHERITED(shader, rec) { 337 : INHERITED(shader, rec) {
(...skipping 27 matching lines...) Expand all
373 365
374 buf.readRect(&rect1); 366 buf.readRect(&rect1);
375 SkScalar xRad1 = buf.readScalar(); 367 SkScalar xRad1 = buf.readScalar();
376 SkScalar yRad1 = buf.readScalar(); 368 SkScalar yRad1 = buf.readScalar();
377 369
378 buf.readRect(&rect2); 370 buf.readRect(&rect2);
379 SkScalar xRad2 = buf.readScalar(); 371 SkScalar xRad2 = buf.readScalar();
380 SkScalar yRad2 = buf.readScalar(); 372 SkScalar yRad2 = buf.readScalar();
381 373
382 SkScalar radius = buf.readScalar(); 374 SkScalar radius = buf.readScalar();
383 SkScalar pad = buf.readScalar();
384 375
385 return sk_make_sp<SkRRectsGaussianEdgeShaderImpl>(SkRRect::MakeRectXY(rect1, xRad1, yRad1), 376 return sk_make_sp<SkRRectsGaussianEdgeShaderImpl>(SkRRect::MakeRectXY(rect1, xRad1, yRad1),
386 SkRRect::MakeRectXY(rect2, xRad2, yRad2), 377 SkRRect::MakeRectXY(rect2, xRad2, yRad2),
387 radius, pad); 378 radius);
388 } 379 }
389 380
390 void SkRRectsGaussianEdgeShaderImpl::flatten(SkWriteBuffer& buf) const { 381 void SkRRectsGaussianEdgeShaderImpl::flatten(SkWriteBuffer& buf) const {
391 INHERITED::flatten(buf); 382 INHERITED::flatten(buf);
392 383
393 SkASSERT(fFirst.isRect() || fFirst.isCircle() || fFirst.isSimpleCircular()); 384 SkASSERT(fFirst.isRect() || fFirst.isCircle() || fFirst.isSimpleCircular());
394 buf.writeRect(fFirst.rect()); 385 buf.writeRect(fFirst.rect());
395 const SkVector& radii1 = fFirst.getSimpleRadii(); 386 const SkVector& radii1 = fFirst.getSimpleRadii();
396 buf.writeScalar(radii1.fX); 387 buf.writeScalar(radii1.fX);
397 buf.writeScalar(radii1.fY); 388 buf.writeScalar(radii1.fY);
398 389
399 SkASSERT(fSecond.isRect() || fSecond.isCircle() || fSecond.isSimpleCircular( )); 390 SkASSERT(fSecond.isRect() || fSecond.isCircle() || fSecond.isSimpleCircular( ));
400 buf.writeRect(fSecond.rect()); 391 buf.writeRect(fSecond.rect());
401 const SkVector& radii2 = fSecond.getSimpleRadii(); 392 const SkVector& radii2 = fSecond.getSimpleRadii();
402 buf.writeScalar(radii2.fX); 393 buf.writeScalar(radii2.fX);
403 buf.writeScalar(radii2.fY); 394 buf.writeScalar(radii2.fY);
404 395
405 buf.writeScalar(fRadius); 396 buf.writeScalar(fRadius);
406 buf.writeScalar(fPad);
407 } 397 }
408 398
409 size_t SkRRectsGaussianEdgeShaderImpl::onContextSize(const ContextRec& rec) cons t { 399 size_t SkRRectsGaussianEdgeShaderImpl::onContextSize(const ContextRec& rec) cons t {
410 return sizeof(GaussianEdgeShaderContext); 400 return sizeof(GaussianEdgeShaderContext);
411 } 401 }
412 402
413 SkShader::Context* SkRRectsGaussianEdgeShaderImpl::onCreateContext(const Context Rec& rec, 403 SkShader::Context* SkRRectsGaussianEdgeShaderImpl::onCreateContext(const Context Rec& rec,
414 void* storage ) const { 404 void* storage ) const {
415 return new (storage) GaussianEdgeShaderContext(*this, rec); 405 return new (storage) GaussianEdgeShaderContext(*this, rec);
416 } 406 }
417 407
418 /////////////////////////////////////////////////////////////////////////////// 408 ///////////////////////////////////////////////////////////////////////////////
419 409
420 sk_sp<SkShader> SkRRectsGaussianEdgeShader::Make(const SkRRect& first, 410 sk_sp<SkShader> SkRRectsGaussianEdgeShader::Make(const SkRRect& first,
421 const SkRRect& second, 411 const SkRRect& second,
422 SkScalar radius, 412 SkScalar radius) {
423 SkScalar pad) {
424 if ((!first.isRect() && !first.isCircle() && !first.isSimpleCircular()) || 413 if ((!first.isRect() && !first.isCircle() && !first.isSimpleCircular()) ||
425 (!second.isRect() && !second.isCircle() && !second.isSimpleCircular())) { 414 (!second.isRect() && !second.isCircle() && !second.isSimpleCircular())) {
426 // we only deal with the shapes where the x & y radii are equal 415 // we only deal with the shapes where the x & y radii are equal
427 // and the same for all four corners 416 // and the same for all four corners
428 return nullptr; 417 return nullptr;
429 } 418 }
430 419
431 return sk_make_sp<SkRRectsGaussianEdgeShaderImpl>(first, second, radius, pad ); 420 return sk_make_sp<SkRRectsGaussianEdgeShaderImpl>(first, second, radius);
432 } 421 }
433 422
434 /////////////////////////////////////////////////////////////////////////////// 423 ///////////////////////////////////////////////////////////////////////////////
435 424
436 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkRRectsGaussianEdgeShader) 425 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkRRectsGaussianEdgeShader)
437 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRRectsGaussianEdgeShaderImpl) 426 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRRectsGaussianEdgeShaderImpl)
438 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 427 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
439 428
440 /////////////////////////////////////////////////////////////////////////////// 429 ///////////////////////////////////////////////////////////////////////////////
OLDNEW
« no previous file with comments | « include/effects/SkRRectsGaussianEdgeShader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698