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

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: rebase to head revision 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
« no previous file with comments | « src/gpu/GrAAHairLinePathRenderer.cpp ('k') | src/gpu/effects/GrCircleEdgeEffect.h » ('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 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 {}
124
125 private:
126 typedef GrGLEffect INHERITED;
127 };
128
129
130 private:
131 CircleEdgeEffect(bool stroke) : GrEffect() {
132 this->addVertexAttrib(kVec4f_GrSLType);
133 fStroke = stroke;
134 }
135
136 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
137 const CircleEdgeEffect& cee = CastEffect<CircleEdgeEffect>(other);
138 return cee.fStroke == fStroke;
139 }
140
141 bool fStroke;
142
143 GR_DECLARE_EFFECT_TEST;
144
145 typedef GrEffect INHERITED;
146 };
147
148 GR_DEFINE_EFFECT_TEST(CircleEdgeEffect);
149
150 GrEffectRef* CircleEdgeEffect::TestCreate(SkMWCRandom* random,
151 GrContext* context,
152 const GrDrawTargetCaps&,
153 GrTexture* textures[]) {
154 return CircleEdgeEffect::Create(random->nextBool());
155 }
156
157 ///////////////////////////////////////////////////////////////////////////////
158
159 /**
160 * The output of this effect is a modulation of the input color and coverage for an axis-aligned
161 * ellipse, specified as center_x, center_y, x_radius, x_radius/y_radius in wind ow space (y-down).
162 */
163
164 class EllipseEdgeEffect : public GrEffect {
165 public:
166 static GrEffectRef* Create(bool stroke) {
167 // we go through this so we only have one copy of each effect (stroked/f illed)
168 static SkAutoTUnref<GrEffectRef> gEllipseStrokeEdgeEffectRef(
169 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEdgeEf fect, (true)))));
170 static SkAutoTUnref<GrEffectRef> gEllipseFillEdgeEffectRef(
171 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEdgeEf fect, (false)))));
172
173 if (stroke) {
174 gEllipseStrokeEdgeEffectRef.get()->ref();
175 return gEllipseStrokeEdgeEffectRef;
176 } else {
177 gEllipseFillEdgeEffectRef.get()->ref();
178 return gEllipseFillEdgeEffectRef;
179 }
180 }
181
182 virtual void getConstantColorComponents(GrColor* color,
183 uint32_t* validFlags) const SK_OVERR IDE {
184 *validFlags = 0;
185 }
186
187 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
188 return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance();
189 }
190
191 virtual ~EllipseEdgeEffect() {}
192
193 static const char* Name() { return "EllipseEdge"; }
194
195 inline bool isStroked() const { return fStroke; }
196
197 class GLEffect : public GrGLEffect {
198 public:
199 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
200 : INHERITED (factory) {}
201
202 virtual void emitCode(GrGLShaderBuilder* builder,
203 const GrDrawEffect& drawEffect,
204 EffectKey key,
205 const char* outputColor,
206 const char* inputColor,
207 const TextureSamplerArray& samplers) SK_OVERRIDE {
208 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>();
209
210 const char *vsCenterName, *fsCenterName;
211 const char *vsEdgeName, *fsEdgeName;
212
213 builder->addVarying(kVec2f_GrSLType, "EllipseCenter", &vsCenterName, &fsCenterName);
214 const SkString* attr0Name =
215 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[0]);
216 builder->vsCodeAppendf("\t%s = %s;\n", vsCenterName, attr0Name->c_st r());
217
218 builder->addVarying(kVec4f_GrSLType, "EllipseEdge", &vsEdgeName, &fs EdgeName);
219 const SkString* attr1Name =
220 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[1]);
221 builder->vsCodeAppendf("\t%s = %s;\n", vsEdgeName, attr1Name->c_str( ));
222
223 // translate to origin
224 builder->fsCodeAppendf("\tvec2 outerOffset = (%s.xy - %s.xy);\n",
225 builder->fragmentPosition(), fsCenterName);
226 builder->fsCodeAppend("\tvec2 innerOffset = outerOffset;\n");
227 // scale y by xRadius/yRadius
228 builder->fsCodeAppendf("\touterOffset.y *= %s.y;\n", fsEdgeName);
229 builder->fsCodeAppend("\tfloat dOuter = length(outerOffset);\n");
230 // compare outer lengths against xOuterRadius
231 builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.x-dOuter, 0.0, 1.0);\n",
232 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
239 builder->fsCodeAppendf("\tfloat innerAlpha = clamp(dInner-%s.z, 0.0, 1.0);\n",
240 fsEdgeName);
241 builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n");
242 }
243
244 SkString modulate;
245 GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha");
246 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str() );
247 }
248
249 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) {
250 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>();
251
252 return ellipseEffect.isStroked() ? 0x1 : 0x0;
253 }
254
255 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_ OVERRIDE {
256 }
257
258 private:
259 typedef GrGLEffect INHERITED;
260 };
261
262 private:
263 EllipseEdgeEffect(bool stroke) : GrEffect() {
264 this->addVertexAttrib(kVec2f_GrSLType);
265 this->addVertexAttrib(kVec4f_GrSLType);
266 fStroke = stroke;
267 }
268
269 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
270 const EllipseEdgeEffect& eee = CastEffect<EllipseEdgeEffect>(other);
271 return eee.fStroke == fStroke;
272 }
273
274 bool fStroke;
275
276 GR_DECLARE_EFFECT_TEST;
277
278 typedef GrEffect INHERITED;
279 };
280
281 GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect);
282
283 GrEffectRef* EllipseEdgeEffect::TestCreate(SkMWCRandom* random,
284 GrContext* context,
285 const GrDrawTargetCaps&,
286 GrTexture* textures[]) {
287 return EllipseEdgeEffect::Create(random->nextBool());
288 }
289
290 ///////////////////////////////////////////////////////////////////////////////
291
43 bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, co nst GrPaint& paint, 292 bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, co nst GrPaint& paint,
44 const GrRect& oval, const SkStrokeRec& stroke) 293 const GrRect& oval, const SkStrokeRec& stroke)
45 { 294 {
46 if (!paint.isAntiAlias()) { 295 if (!paint.isAntiAlias()) {
47 return false; 296 return false;
48 } 297 }
49 298
50 const SkMatrix& vm = context->getMatrix(); 299 const SkMatrix& vm = context->getMatrix();
51 300
52 // we can draw circles 301 // we can draw circles
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 350
102 SkStrokeRec::Style style = stroke.getStyle(); 351 SkStrokeRec::Style style = stroke.getStyle();
103 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl ine_Style == style); 352 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl ine_Style == style);
104 enum { 353 enum {
105 // the edge effects share this stage with glyph rendering 354 // the edge effects share this stage with glyph rendering
106 // (kGlyphMaskStage in GrTextContext) && SW path rendering 355 // (kGlyphMaskStage in GrTextContext) && SW path rendering
107 // (kPathMaskStage in GrSWMaskHelper) 356 // (kPathMaskStage in GrSWMaskHelper)
108 kEdgeEffectStage = GrPaint::kTotalStages, 357 kEdgeEffectStage = GrPaint::kTotalStages,
109 }; 358 };
110 359
111 GrEffectRef* effect = GrCircleEdgeEffect::Create(isStroked); 360 GrEffectRef* effect = CircleEdgeEffect::Create(isStroked);
112 static const int kCircleEdgeAttrIndex = 1; 361 static const int kCircleEdgeAttrIndex = 1;
113 drawState->setEffect(kEdgeEffectStage, effect, kCircleEdgeAttrIndex)->unref( ); 362 drawState->setEffect(kEdgeEffectStage, effect, kCircleEdgeAttrIndex)->unref( );
114 363
115 SkScalar innerRadius = 0.0f; 364 SkScalar innerRadius = 0.0f;
116 SkScalar outerRadius = radius; 365 SkScalar outerRadius = radius;
117 SkScalar halfWidth = 0; 366 SkScalar halfWidth = 0;
118 if (style != SkStrokeRec::kFill_Style) { 367 if (style != SkStrokeRec::kFill_Style) {
119 if (SkScalarNearlyZero(strokeWidth)) { 368 if (SkScalarNearlyZero(strokeWidth)) {
120 halfWidth = SK_ScalarHalf; 369 halfWidth = SK_ScalarHalf;
121 } else { 370 } else {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 449
201 SkStrokeRec::Style style = stroke.getStyle(); 450 SkStrokeRec::Style style = stroke.getStyle();
202 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl ine_Style == style); 451 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl ine_Style == style);
203 enum { 452 enum {
204 // the edge effects share this stage with glyph rendering 453 // the edge effects share this stage with glyph rendering
205 // (kGlyphMaskStage in GrTextContext) && SW path rendering 454 // (kGlyphMaskStage in GrTextContext) && SW path rendering
206 // (kPathMaskStage in GrSWMaskHelper) 455 // (kPathMaskStage in GrSWMaskHelper)
207 kEdgeEffectStage = GrPaint::kTotalStages, 456 kEdgeEffectStage = GrPaint::kTotalStages,
208 }; 457 };
209 458
210 GrEffectRef* effect = GrEllipseEdgeEffect::Create(isStroked); 459 GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked);
211 static const int kEllipseCenterAttrIndex = 1; 460 static const int kEllipseCenterAttrIndex = 1;
212 static const int kEllipseEdgeAttrIndex = 2; 461 static const int kEllipseEdgeAttrIndex = 2;
213 drawState->setEffect(kEdgeEffectStage, effect, 462 drawState->setEffect(kEdgeEffectStage, effect,
214 kEllipseCenterAttrIndex, kEllipseEdgeAttrIndex)->unref( ); 463 kEllipseCenterAttrIndex, kEllipseEdgeAttrIndex)->unref( );
215 464
216 SkScalar xRadius = SkScalarHalf(xformedRect.width()); 465 SkScalar xRadius = SkScalarHalf(xformedRect.width());
217 SkScalar yRadius = SkScalarHalf(xformedRect.height()); 466 SkScalar yRadius = SkScalarHalf(xformedRect.height());
218 SkScalar innerXRadius = 0.0f; 467 SkScalar innerXRadius = 0.0f;
219 SkScalar innerRatio = 1.0f; 468 SkScalar innerRatio = 1.0f;
220 469
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 T += center.fY - SK_ScalarHalf; 515 T += center.fY - SK_ScalarHalf;
267 B += center.fY + SK_ScalarHalf; 516 B += center.fY + SK_ScalarHalf;
268 517
269 verts[0].fPos = SkPoint::Make(L, T); 518 verts[0].fPos = SkPoint::Make(L, T);
270 verts[1].fPos = SkPoint::Make(R, T); 519 verts[1].fPos = SkPoint::Make(R, T);
271 verts[2].fPos = SkPoint::Make(L, B); 520 verts[2].fPos = SkPoint::Make(L, B);
272 verts[3].fPos = SkPoint::Make(R, B); 521 verts[3].fPos = SkPoint::Make(R, B);
273 522
274 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4); 523 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4);
275 } 524 }
OLDNEW
« no previous file with comments | « src/gpu/GrAAHairLinePathRenderer.cpp ('k') | src/gpu/effects/GrCircleEdgeEffect.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698