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

Side by Side Diff: src/gpu/GrOvalRenderer.cpp

Issue 13344002: Move edge GrEffects to locally defined classes (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 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 "GrOvalRenderer.h" 8 #include "GrOvalRenderer.h"
9 9
10 #include "effects/GrCircleEdgeEffect.h" 10 #include "GrEffect.h"
11 #include "effects/GrEllipseEdgeEffect.h" 11 #include "gl/GrGLEffect.h"
12 #include "gl/GrGLSL.h"
13 #include "GrTBackendEffectFactory.h"
12 14
13 #include "GrDrawState.h" 15 #include "GrDrawState.h"
14 #include "GrDrawTarget.h" 16 #include "GrDrawTarget.h"
15 #include "SkStrokeRec.h" 17 #include "SkStrokeRec.h"
16 18
17 SK_DEFINE_INST_COUNT(GrOvalRenderer) 19 SK_DEFINE_INST_COUNT(GrOvalRenderer)
18 20
19 namespace { 21 namespace {
20 22
21 struct CircleVertex { 23 struct CircleVertex {
(...skipping 11 matching lines...) Expand all
33 SkScalar fInnerXRadius; 35 SkScalar fInnerXRadius;
34 SkScalar fInnerXYRatio; 36 SkScalar fInnerXYRatio;
35 }; 37 };
36 38
37 inline bool circle_stays_circle(const SkMatrix& m) { 39 inline bool circle_stays_circle(const SkMatrix& m) {
38 return m.isSimilarity(); 40 return m.isSimilarity();
39 } 41 }
40 42
41 } 43 }
42 44
45 ///////////////////////////////////////////////////////////////////////////////
46
47 /**
48 * The output of this effect is a modulation of the input color and coverage for a circle,
49 * specified as center_x, center_y, x_radius, inner radius and outer radius in w indow space
50 * (y-down).
51 */
52
53 class CircleEdgeEffect : public GrEffect {
54 public:
55 static GrEffectRef* Create(bool stroke) {
56 // we go through this so we only have one copy of each effect (stroked/f illed)
57 static SkAutoTUnref<GrEffectRef> gCircleStrokeEdgeEffectRef(
58 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircleEdgeEff ect, (true)))));
59 static SkAutoTUnref<GrEffectRef> gCircleFillEdgeEffectRef(
60 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircleEdgeEff ect, (false)))));
61
62 if (stroke) {
63 gCircleStrokeEdgeEffectRef.get()->ref();
64 return gCircleStrokeEdgeEffectRef;
65 } else {
66 gCircleFillEdgeEffectRef.get()->ref();
67 return gCircleFillEdgeEffectRef;
68 }
69 }
70
71 virtual void getConstantColorComponents(GrColor* color,
72 uint32_t* validFlags) const SK_OVERR IDE {
73 *validFlags = 0;
74 }
75
76 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
77 return GrTBackendEffectFactory<CircleEdgeEffect>::getInstance();
78 }
79
80 virtual ~CircleEdgeEffect() {}
81
82 static const char* Name() { return "CircleEdge"; }
83
84 inline bool isStroked() const { return fStroke; }
85
86 class GLEffect : public GrGLEffect {
87 public:
88 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
89 : INHERITED (factory) {}
90
91 virtual void emitCode(GrGLShaderBuilder* builder,
92 const GrDrawEffect& drawEffect,
93 EffectKey key,
94 const char* outputColor,
95 const char* inputColor,
96 const TextureSamplerArray& samplers) SK_OVERRIDE {
97 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE dgeEffect>();
98 const char *vsName, *fsName;
99 builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName) ;
100
101 const SkString* attrName =
102 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[0]);
103 builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
104
105 builder->fsCodeAppendf("\tfloat d = distance(%s.xy, %s.xy);\n",
106 builder->fragmentPosition(), fsName);
107 builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0 );\n", fsName);
108 if (circleEffect.isStroked()) {
109 builder->fsCodeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0 , 1.0);\n", fsName);
110 builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n");
111 }
112 SkString modulate;
113 GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha");
114 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str() );
115 }
116
117 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) {
118 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE dgeEffect>();
119
120 return circleEffect.isStroked() ? 0x1 : 0x0;
121 }
122
123 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_ OVERRIDE {
robertphillips 2013/03/31 22:59:08 put this '}' on prior line?
124 }
125
126 private:
127 typedef GrGLEffect INHERITED;
128 };
129
130
131 private:
132 CircleEdgeEffect(bool stroke) : GrEffect() {
133 this->addVertexAttrib(kVec4f_GrSLType);
134 fStroke = stroke;
135 }
136
137 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
138 const CircleEdgeEffect& cee = CastEffect<CircleEdgeEffect>(other);
139 return cee.fStroke == fStroke;
140 }
141
142 bool fStroke;
143
144 GR_DECLARE_EFFECT_TEST;
145
146 typedef GrEffect INHERITED;
147 };
148
149 GR_DEFINE_EFFECT_TEST(CircleEdgeEffect);
150
151 GrEffectRef* CircleEdgeEffect::TestCreate(SkMWCRandom* random,
152 GrContext* context,
153 const GrDrawTargetCaps&,
154 GrTexture* textures[]) {
155 return CircleEdgeEffect::Create(random->nextBool());
156 }
157
158 ///////////////////////////////////////////////////////////////////////////////
159
160 /**
161 * The output of this effect is a modulation of the input color and coverage for an axis-aligned
162 * ellipse, specified as center_x, center_y, x_radius, x_radius/y_radius in wind ow space (y-down).
163 */
164
165 class EllipseEdgeEffect : public GrEffect {
166 public:
167 static GrEffectRef* Create(bool stroke) {
168 // we go through this so we only have one copy of each effect (stroked/f illed)
169 static SkAutoTUnref<GrEffectRef> gEllipseStrokeEdgeEffectRef(
170 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEdgeEf fect, (true)))));
171 static SkAutoTUnref<GrEffectRef> gEllipseFillEdgeEffectRef(
172 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEdgeEf fect, (false)))));
173
174 if (stroke) {
175 gEllipseStrokeEdgeEffectRef.get()->ref();
176 return gEllipseStrokeEdgeEffectRef;
177 } else {
178 gEllipseFillEdgeEffectRef.get()->ref();
179 return gEllipseFillEdgeEffectRef;
180 }
181 }
182
183 virtual void getConstantColorComponents(GrColor* color,
184 uint32_t* validFlags) const SK_OVERR IDE {
185 *validFlags = 0;
186 }
187
188 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
189 return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance();
190 }
191
192 virtual ~EllipseEdgeEffect() {}
193
194 static const char* Name() { return "EllipseEdge"; }
195
196 inline bool isStroked() const { return fStroke; }
197
198 class GLEffect : public GrGLEffect {
199 public:
200 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
201 : INHERITED (factory) {}
202
203 virtual void emitCode(GrGLShaderBuilder* builder,
204 const GrDrawEffect& drawEffect,
205 EffectKey key,
206 const char* outputColor,
207 const char* inputColor,
208 const TextureSamplerArray& samplers) SK_OVERRIDE {
209 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>();
210
211 const char *vsCenterName, *fsCenterName;
212 const char *vsEdgeName, *fsEdgeName;
213
214 builder->addVarying(kVec2f_GrSLType, "EllipseCenter", &vsCenterName, &fsCenterName);
215 const SkString* attr0Name =
216 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[0]);
217 builder->vsCodeAppendf("\t%s = %s;\n", vsCenterName, attr0Name->c_st r());
218
219 builder->addVarying(kVec4f_GrSLType, "EllipseEdge", &vsEdgeName, &fs EdgeName);
220 const SkString* attr1Name =
221 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[1]);
222 builder->vsCodeAppendf("\t%s = %s;\n", vsEdgeName, attr1Name->c_str( ));
223
224 // translate to origin
225 builder->fsCodeAppendf("\tvec2 outerOffset = (%s.xy - %s.xy);\n",
226 builder->fragmentPosition(), fsCenterName);
227 builder->fsCodeAppend("\tvec2 innerOffset = outerOffset;\n");
228 // scale y by xRadius/yRadius
229 builder->fsCodeAppendf("\touterOffset.y *= %s.y;\n", fsEdgeName);
230 builder->fsCodeAppend("\tfloat dOuter = length(outerOffset);\n");
231 // compare outer lengths against xOuterRadius
232 builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.x-dOuter, 0.0, 1.0);\n", fsEdgeName);
233
234 if (ellipseEffect.isStroked()) {
235 builder->fsCodeAppendf("\tinnerOffset.y *= %s.w;\n", fsEdgeName) ;
236 builder->fsCodeAppend("\tfloat dInner = length(innerOffset);\n") ;
237
238 // compare inner lengths against xInnerRadius
robertphillips 2013/03/31 22:59:08 overlength
239 builder->fsCodeAppendf("\tfloat innerAlpha = clamp(dInner-%s.z, 0.0, 1.0);\n", fsEdgeName);
240 builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n");
241 }
242
243 SkString modulate;
244 GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha");
245 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str() );
246 }
247
248 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) {
249 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>();
250
251 return ellipseEffect.isStroked() ? 0x1 : 0x0;
252 }
253
254 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_ OVERRIDE {
255 }
256
257 private:
258 typedef GrGLEffect INHERITED;
259 };
260
261 private:
262 EllipseEdgeEffect(bool stroke) : GrEffect() {
263 this->addVertexAttrib(kVec2f_GrSLType);
264 this->addVertexAttrib(kVec4f_GrSLType);
265 fStroke = stroke;
266 }
267
268 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
269 const EllipseEdgeEffect& eee = CastEffect<EllipseEdgeEffect>(other);
270 return eee.fStroke == fStroke;
271 }
272
273 bool fStroke;
274
275 GR_DECLARE_EFFECT_TEST;
276
277 typedef GrEffect INHERITED;
278 };
279
280 GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect);
281
282 GrEffectRef* EllipseEdgeEffect::TestCreate(SkMWCRandom* random,
283 GrContext* context,
284 const GrDrawTargetCaps&,
285 GrTexture* textures[]) {
286 return EllipseEdgeEffect::Create(random->nextBool());
287 }
288
289 ///////////////////////////////////////////////////////////////////////////////
290
43 bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, co nst GrPaint& paint, 291 bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, co nst GrPaint& paint,
44 const GrRect& oval, const SkStrokeRec& stroke) 292 const GrRect& oval, const SkStrokeRec& stroke)
45 { 293 {
46 if (!paint.isAntiAlias()) { 294 if (!paint.isAntiAlias()) {
47 return false; 295 return false;
48 } 296 }
49 297
50 const SkMatrix& vm = context->getMatrix(); 298 const SkMatrix& vm = context->getMatrix();
51 299
52 // we can draw circles 300 // we can draw circles
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 SkStrokeRec::Style style = stroke.getStyle(); 351 SkStrokeRec::Style style = stroke.getStyle();
104 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl ine_Style == style); 352 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl ine_Style == style);
105 enum { 353 enum {
106 // the edge effects share this stage with glyph rendering 354 // the edge effects share this stage with glyph rendering
107 // (kGlyphMaskStage in GrTextContext) && SW path rendering 355 // (kGlyphMaskStage in GrTextContext) && SW path rendering
108 // (kPathMaskStage in GrSWMaskHelper) 356 // (kPathMaskStage in GrSWMaskHelper)
109 kEdgeEffectStage = GrPaint::kTotalStages, 357 kEdgeEffectStage = GrPaint::kTotalStages,
110 }; 358 };
111 drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings); 359 drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings);
112 360
113 GrEffectRef* effect = GrCircleEdgeEffect::Create(isStroked); 361 GrEffectRef* effect = CircleEdgeEffect::Create(isStroked);
114 static const int kCircleEdgeAttrIndex = 1; 362 static const int kCircleEdgeAttrIndex = 1;
115 drawState->setEffect(kEdgeEffectStage, effect, kCircleEdgeAttrIndex)->unref( ); 363 drawState->setEffect(kEdgeEffectStage, effect, kCircleEdgeAttrIndex)->unref( );
116 364
117 SkScalar innerRadius = 0.0f; 365 SkScalar innerRadius = 0.0f;
118 SkScalar outerRadius = radius; 366 SkScalar outerRadius = radius;
119 SkScalar halfWidth = 0; 367 SkScalar halfWidth = 0;
120 if (style != SkStrokeRec::kFill_Style) { 368 if (style != SkStrokeRec::kFill_Style) {
121 if (SkScalarNearlyZero(strokeWidth)) { 369 if (SkScalarNearlyZero(strokeWidth)) {
122 halfWidth = SK_ScalarHalf; 370 halfWidth = SK_ScalarHalf;
123 } else { 371 } else {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 SkStrokeRec::Style style = stroke.getStyle(); 450 SkStrokeRec::Style style = stroke.getStyle();
203 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl ine_Style == style); 451 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl ine_Style == style);
204 enum { 452 enum {
205 // the edge effects share this stage with glyph rendering 453 // the edge effects share this stage with glyph rendering
206 // (kGlyphMaskStage in GrTextContext) && SW path rendering 454 // (kGlyphMaskStage in GrTextContext) && SW path rendering
207 // (kPathMaskStage in GrSWMaskHelper) 455 // (kPathMaskStage in GrSWMaskHelper)
208 kEdgeEffectStage = GrPaint::kTotalStages, 456 kEdgeEffectStage = GrPaint::kTotalStages,
209 }; 457 };
210 drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings); 458 drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings);
211 459
212 GrEffectRef* effect = GrEllipseEdgeEffect::Create(isStroked); 460 GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked);
213 static const int kEllipseCenterAttrIndex = 1; 461 static const int kEllipseCenterAttrIndex = 1;
214 static const int kEllipseEdgeAttrIndex = 2; 462 static const int kEllipseEdgeAttrIndex = 2;
215 drawState->setEffect(kEdgeEffectStage, effect, 463 drawState->setEffect(kEdgeEffectStage, effect,
216 kEllipseCenterAttrIndex, kEllipseEdgeAttrIndex)->unref( ); 464 kEllipseCenterAttrIndex, kEllipseEdgeAttrIndex)->unref( );
217 465
218 SkScalar xRadius = SkScalarHalf(xformedRect.width()); 466 SkScalar xRadius = SkScalarHalf(xformedRect.width());
219 SkScalar yRadius = SkScalarHalf(xformedRect.height()); 467 SkScalar yRadius = SkScalarHalf(xformedRect.height());
220 SkScalar innerXRadius = 0.0f; 468 SkScalar innerXRadius = 0.0f;
221 SkScalar innerRatio = 1.0f; 469 SkScalar innerRatio = 1.0f;
222 470
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 T += center.fY - SK_ScalarHalf; 516 T += center.fY - SK_ScalarHalf;
269 B += center.fY + SK_ScalarHalf; 517 B += center.fY + SK_ScalarHalf;
270 518
271 verts[0].fPos = SkPoint::Make(L, T); 519 verts[0].fPos = SkPoint::Make(L, T);
272 verts[1].fPos = SkPoint::Make(R, T); 520 verts[1].fPos = SkPoint::Make(R, T);
273 verts[2].fPos = SkPoint::Make(L, B); 521 verts[2].fPos = SkPoint::Make(L, B);
274 verts[3].fPos = SkPoint::Make(R, B); 522 verts[3].fPos = SkPoint::Make(R, B);
275 523
276 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4); 524 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4);
277 } 525 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698