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

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

Issue 183833003: Make GrConvexPolyEffect support inverse fills and non-AA rects (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: update GM width Created 6 years, 9 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/effects/GrConvexPolyEffect.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 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 "GrConvexPolyEffect.h" 8 #include "GrConvexPolyEffect.h"
9 9
10 #include "gl/GrGLEffect.h" 10 #include "gl/GrGLEffect.h"
11 #include "gl/GrGLSL.h" 11 #include "gl/GrGLSL.h"
12 #include "GrTBackendEffectFactory.h" 12 #include "GrTBackendEffectFactory.h"
13 13
14 #include "SkPath.h" 14 #include "SkPath.h"
15 15
16 ////////////////////////////////////////////////////////////////////////////// 16 //////////////////////////////////////////////////////////////////////////////
17 class GLAARectEffect; 17 class GLAARectEffect;
18 18
19 class AARectEffect : public GrEffect { 19 class AARectEffect : public GrEffect {
20 public: 20 public:
21 typedef GLAARectEffect GLEffect; 21 typedef GLAARectEffect GLEffect;
22 typedef GrConvexPolyEffect::EdgeType EdgeType;
22 23
23 const SkRect& getRect() const { return fRect; } 24 const SkRect& getRect() const { return fRect; }
24 25
25 static const char* Name() { return "AARect"; } 26 static const char* Name() { return "AARect"; }
26 27
27 static GrEffectRef* Create(const SkRect& rect) { 28 static GrEffectRef* Create(EdgeType edgeType, const SkRect& rect) {
28 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(AARectEffect, (rect))) ); 29 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(AARectEffect, (edgeTyp e, rect))));
29 } 30 }
30 31
31 virtual void getConstantColorComponents(GrColor* color, 32 virtual void getConstantColorComponents(GrColor* color,
32 uint32_t* validFlags) const SK_OVERR IDE { 33 uint32_t* validFlags) const SK_OVERR IDE {
33 if (fRect.isEmpty()) { 34 if (fRect.isEmpty()) {
34 // An empty rect will have no coverage anywhere. 35 // An empty rect will have no coverage anywhere.
35 *color = 0x00000000; 36 *color = 0x00000000;
36 *validFlags = kRGBA_GrColorComponentFlags; 37 *validFlags = kRGBA_GrColorComponentFlags;
37 } else { 38 } else {
38 *validFlags = 0; 39 *validFlags = 0;
39 } 40 }
40 } 41 }
41 42
43 GrConvexPolyEffect::EdgeType getEdgeType() const { return fEdgeType; }
44
42 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; 45 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
43 46
44 private: 47 private:
45 AARectEffect(const SkRect& rect) : fRect(rect) { 48 AARectEffect(EdgeType edgeType, const SkRect& rect) : fRect(rect), fEdgeType (edgeType) {
46 this->setWillReadFragmentPosition(); 49 this->setWillReadFragmentPosition();
47 } 50 }
48 51
49 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { 52 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
50 const AARectEffect& aare = CastEffect<AARectEffect>(other); 53 const AARectEffect& aare = CastEffect<AARectEffect>(other);
51 return fRect == aare.fRect; 54 return fRect == aare.fRect;
52 } 55 }
53 56
54 SkRect fRect; 57 SkRect fRect;
58 EdgeType fEdgeType;
59
55 typedef GrEffect INHERITED; 60 typedef GrEffect INHERITED;
56 61
57 GR_DECLARE_EFFECT_TEST; 62 GR_DECLARE_EFFECT_TEST;
58 63
59 }; 64 };
60 65
61 GR_DEFINE_EFFECT_TEST(AARectEffect); 66 GR_DEFINE_EFFECT_TEST(AARectEffect);
62 67
63 GrEffectRef* AARectEffect::TestCreate(SkRandom* random, 68 GrEffectRef* AARectEffect::TestCreate(SkRandom* random,
64 GrContext*, 69 GrContext*,
65 const GrDrawTargetCaps& caps, 70 const GrDrawTargetCaps& caps,
66 GrTexture*[]) { 71 GrTexture*[]) {
72 EdgeType edgeType = static_cast<EdgeType>(
73 random->nextULessThan(GrConvexPolyEffect::kE dgeTypeCnt));
74
67 SkRect rect = SkRect::MakeLTRB(random->nextSScalar1(), 75 SkRect rect = SkRect::MakeLTRB(random->nextSScalar1(),
68 random->nextSScalar1(), 76 random->nextSScalar1(),
69 random->nextSScalar1(), 77 random->nextSScalar1(),
70 random->nextSScalar1()); 78 random->nextSScalar1());
71 return AARectEffect::Create(rect); 79 return AARectEffect::Create(edgeType, rect);
72 } 80 }
73 81
74 ////////////////////////////////////////////////////////////////////////////// 82 //////////////////////////////////////////////////////////////////////////////
75 83
76 class GLAARectEffect : public GrGLEffect { 84 class GLAARectEffect : public GrGLEffect {
77 public: 85 public:
78 GLAARectEffect(const GrBackendEffectFactory&, const GrDrawEffect&); 86 GLAARectEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
79 87
80 virtual void emitCode(GrGLShaderBuilder* builder, 88 virtual void emitCode(GrGLShaderBuilder* builder,
81 const GrDrawEffect& drawEffect, 89 const GrDrawEffect& drawEffect,
82 EffectKey key, 90 EffectKey key,
83 const char* outputColor, 91 const char* outputColor,
84 const char* inputColor, 92 const char* inputColor,
85 const TransformedCoordsArray&, 93 const TransformedCoordsArray&,
86 const TextureSamplerArray&) SK_OVERRIDE; 94 const TextureSamplerArray&) SK_OVERRIDE;
87 95
88 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { retur n 0; } 96 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
89 97
90 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE; 98 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE;
91 99
92 private: 100 private:
93 GrGLUniformManager::UniformHandle fRectUniform; 101 GrGLUniformManager::UniformHandle fRectUniform;
94 SkRect fPrevRect; 102 SkRect fPrevRect;
95 typedef GrGLEffect INHERITED; 103 typedef GrGLEffect INHERITED;
96 }; 104 };
97 105
98 GLAARectEffect::GLAARectEffect(const GrBackendEffectFactory& factory, 106 GLAARectEffect::GLAARectEffect(const GrBackendEffectFactory& factory,
99 const GrDrawEffect& drawEffect) 107 const GrDrawEffect& drawEffect)
100 : INHERITED (factory) { 108 : INHERITED (factory) {
101 fPrevRect.fLeft = SK_ScalarNaN; 109 fPrevRect.fLeft = SK_ScalarNaN;
102 } 110 }
103 111
104 void GLAARectEffect::emitCode(GrGLShaderBuilder* builder, 112 void GLAARectEffect::emitCode(GrGLShaderBuilder* builder,
105 const GrDrawEffect& drawEffect, 113 const GrDrawEffect& drawEffect,
106 EffectKey key, 114 EffectKey key,
107 const char* outputColor, 115 const char* outputColor,
108 const char* inputColor, 116 const char* inputColor,
109 const TransformedCoordsArray&, 117 const TransformedCoordsArray&,
110 const TextureSamplerArray& samplers) { 118 const TextureSamplerArray& samplers) {
119 const AARectEffect& aare = drawEffect.castEffect<AARectEffect>();
111 const char *rectName; 120 const char *rectName;
121 // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bot tom - 0.5),
122 // respectively.
112 fRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, 123 fRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
113 kVec4f_GrSLType, 124 kVec4f_GrSLType,
114 "rect", 125 "rect",
115 &rectName); 126 &rectName);
116 const char* fragmentPos = builder->fragmentPosition(); 127 const char* fragmentPos = builder->fragmentPosition();
117 // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bot tom - 0.5), 128 if (GrConvexPolyEffect::kFillAA_EdgeType == aare.getEdgeType() ||
118 // respectively. The amount of coverage removed in x and y by the edges is c omputed as a pair of 129 GrConvexPolyEffect::kInverseFillAA_EdgeType == aare.getEdgeType()) {
119 // negative numbers, xSub and ySub. 130 // The amount of coverage removed in x and y by the edges is computed as a pair of negative
120 builder->fsCodeAppend("\t\tfloat xSub, ySub;\n"); 131 // numbers, xSub and ySub.
121 builder->fsCodeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, r ectName); 132 builder->fsCodeAppend("\t\tfloat xSub, ySub;\n");
122 builder->fsCodeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fra gmentPos); 133 builder->fsCodeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPo s, rectName);
123 builder->fsCodeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, r ectName); 134 builder->fsCodeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos);
124 builder->fsCodeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fra gmentPos); 135 builder->fsCodeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPo s, rectName);
125 // Now compute coverage in x and y and multiply them to get the fraction of the pixel covered. 136 builder->fsCodeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos);
126 builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + m ax(ySub, -1.0));\n"); 137 // Now compute coverage in x and y and multiply them to get the fraction of the pixel
138 // covered.
139 builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
140 } else {
141 builder->fsCodeAppendf("\t\tfloat alpha = 1.0;\n");
142 builder->fsCodeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n ", fragmentPos, rectName);
143 builder->fsCodeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n ", rectName, fragmentPos);
144 builder->fsCodeAppendf("\t\talpha *= (%s.y - %s.y) > 0.5 ? 1.0 : 0.0;\n" , fragmentPos, rectName);
145 builder->fsCodeAppendf("\t\talpha *= (%s.w - %s.y) > 0.5 ? 1.0 : 0.0;\n" , rectName, fragmentPos);
146 }
127 147
148 if (GrConvexPolyEffect::kInverseFillAA_EdgeType == aare.getEdgeType() ||
149 GrConvexPolyEffect::kInverseFillNoAA_EdgeType == aare.getEdgeType()) {
150 builder->fsCodeAppend("\t\talpha = 1.0 - alpha;\n");
151 }
128 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, 152 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
129 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r()); 153 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r());
130 } 154 }
131 155
132 void GLAARectEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) { 156 void GLAARectEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
133 const AARectEffect& aare = drawEffect.castEffect<AARectEffect>(); 157 const AARectEffect& aare = drawEffect.castEffect<AARectEffect>();
134 const SkRect& rect = aare.getRect(); 158 const SkRect& rect = aare.getRect();
135 if (rect != fPrevRect) { 159 if (rect != fPrevRect) {
136 uman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f, 160 uman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f,
137 rect.fRight - 0.5f, rect.fBottom - 0.5f); 161 rect.fRight - 0.5f, rect.fBottom - 0.5f);
138 fPrevRect = rect; 162 fPrevRect = rect;
139 } 163 }
140 } 164 }
141 165
166 GrGLEffect::EffectKey GLAARectEffect::GenKey(const GrDrawEffect& drawEffect, con st GrGLCaps&) {
167 const AARectEffect& aare = drawEffect.castEffect<AARectEffect>();
168 return aare.getEdgeType();
169 }
170
142 const GrBackendEffectFactory& AARectEffect::getFactory() const { 171 const GrBackendEffectFactory& AARectEffect::getFactory() const {
143 return GrTBackendEffectFactory<AARectEffect>::getInstance(); 172 return GrTBackendEffectFactory<AARectEffect>::getInstance();
144 } 173 }
145 174
146 ////////////////////////////////////////////////////////////////////////////// 175 //////////////////////////////////////////////////////////////////////////////
147 176
148 class GrGLConvexPolyEffect : public GrGLEffect { 177 class GrGLConvexPolyEffect : public GrGLEffect {
149 public: 178 public:
150 GrGLConvexPolyEffect(const GrBackendEffectFactory&, const GrDrawEffect&); 179 GrGLConvexPolyEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
151 180
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 cpe.getEdgeCount(), 218 cpe.getEdgeCount(),
190 &edgeArrayName); 219 &edgeArrayName);
191 builder->fsCodeAppend("\t\tfloat alpha = 1.0;\n"); 220 builder->fsCodeAppend("\t\tfloat alpha = 1.0;\n");
192 builder->fsCodeAppend("\t\tfloat edge;\n"); 221 builder->fsCodeAppend("\t\tfloat edge;\n");
193 const char* fragmentPos = builder->fragmentPosition(); 222 const char* fragmentPos = builder->fragmentPosition();
194 for (int i = 0; i < cpe.getEdgeCount(); ++i) { 223 for (int i = 0; i < cpe.getEdgeCount(); ++i) {
195 builder->fsCodeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n", 224 builder->fsCodeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n",
196 edgeArrayName, i, fragmentPos, fragmentPos); 225 edgeArrayName, i, fragmentPos, fragmentPos);
197 switch (cpe.getEdgeType()) { 226 switch (cpe.getEdgeType()) {
198 case GrConvexPolyEffect::kFillAA_EdgeType: 227 case GrConvexPolyEffect::kFillAA_EdgeType:
228 case GrConvexPolyEffect::kInverseFillAA_EdgeType: // inverse handled at the end
199 builder->fsCodeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n"); 229 builder->fsCodeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n");
200 builder->fsCodeAppend("\t\talpha *= edge;\n");
201 break; 230 break;
202 case GrConvexPolyEffect::kFillNoAA_EdgeType: 231 case GrConvexPolyEffect::kFillNoAA_EdgeType:
232 case GrConvexPolyEffect::kInverseFillNoAA_EdgeType: // inverse handl ed at the end
203 builder->fsCodeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n"); 233 builder->fsCodeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n");
204 builder->fsCodeAppend("\t\talpha *= edge;\n");
205 break; 234 break;
206 } 235 }
236 builder->fsCodeAppend("\t\talpha *= edge;\n");
207 } 237 }
208 238
209 // Woe is me. See skbug.com/2149. 239 // Woe is me. See skbug.com/2149.
210 if (kTegra2_GrGLRenderer == builder->ctxInfo().renderer()) { 240 if (kTegra2_GrGLRenderer == builder->ctxInfo().renderer()) {
211 builder->fsCodeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n "); 241 builder->fsCodeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n ");
212 } 242 }
243
244 if (GrConvexPolyEffect::kInverseFillAA_EdgeType == cpe.getEdgeType() ||
245 GrConvexPolyEffect::kInverseFillNoAA_EdgeType == cpe.getEdgeType() ) {
246 builder->fsCodeAppend("\talpha = 1.0 - alpha;\n");
247 }
213 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, 248 builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
214 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r()); 249 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r());
215 } 250 }
216 251
217 void GrGLConvexPolyEffect::setData(const GrGLUniformManager& uman, const GrDrawE ffect& drawEffect) { 252 void GrGLConvexPolyEffect::setData(const GrGLUniformManager& uman, const GrDrawE ffect& drawEffect) {
218 const GrConvexPolyEffect& cpe = drawEffect.castEffect<GrConvexPolyEffect>(); 253 const GrConvexPolyEffect& cpe = drawEffect.castEffect<GrConvexPolyEffect>();
219 size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar); 254 size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar);
220 if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) { 255 if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) {
221 uman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges()); 256 uman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges());
222 memcpy(fPrevEdges, cpe.getEdges(), byteSize); 257 memcpy(fPrevEdges, cpe.getEdges(), byteSize);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 edges[3 * n + 1] = v.fX; 305 edges[3 * n + 1] = v.fX;
271 } 306 }
272 SkPoint p = pts[i] + t; 307 SkPoint p = pts[i] + t;
273 edges[3 * n + 2] = -(edges[3 * n] * p.fX + edges[3 * n + 1] * p.fY); 308 edges[3 * n + 2] = -(edges[3 * n] * p.fX + edges[3 * n + 1] * p.fY);
274 ++n; 309 ++n;
275 } 310 }
276 } 311 }
277 return Create(type, n, edges); 312 return Create(type, n, edges);
278 } 313 }
279 314
280 GrEffectRef* GrConvexPolyEffect::CreateForAAFillRect(const SkRect& rect) { 315 GrEffectRef* GrConvexPolyEffect::Create(EdgeType edgeType, const SkRect& rect) {
281 return AARectEffect::Create(rect); 316 return AARectEffect::Create(edgeType, rect);
282 } 317 }
283 318
284 GrConvexPolyEffect::~GrConvexPolyEffect() {} 319 GrConvexPolyEffect::~GrConvexPolyEffect() {}
285 320
286 void GrConvexPolyEffect::getConstantColorComponents(GrColor* color, uint32_t* va lidFlags) const { 321 void GrConvexPolyEffect::getConstantColorComponents(GrColor* color, uint32_t* va lidFlags) const {
287 *validFlags = 0; 322 *validFlags = 0;
288 } 323 }
289 324
290 const GrBackendEffectFactory& GrConvexPolyEffect::getFactory() const { 325 const GrBackendEffectFactory& GrConvexPolyEffect::getFactory() const {
291 return GrTBackendEffectFactory<GrConvexPolyEffect>::getInstance(); 326 return GrTBackendEffectFactory<GrConvexPolyEffect>::getInstance();
(...skipping 30 matching lines...) Expand all
322 GrTexture*[]) { 357 GrTexture*[]) {
323 EdgeType edgeType = static_cast<EdgeType>(random->nextULessThan(kEdgeTypeCnt )); 358 EdgeType edgeType = static_cast<EdgeType>(random->nextULessThan(kEdgeTypeCnt ));
324 int count = random->nextULessThan(kMaxEdges) + 1; 359 int count = random->nextULessThan(kMaxEdges) + 1;
325 SkScalar edges[kMaxEdges * 3]; 360 SkScalar edges[kMaxEdges * 3];
326 for (int i = 0; i < 3 * count; ++i) { 361 for (int i = 0; i < 3 * count; ++i) {
327 edges[i] = random->nextSScalar1(); 362 edges[i] = random->nextSScalar1();
328 } 363 }
329 364
330 return GrConvexPolyEffect::Create(edgeType, count, edges); 365 return GrConvexPolyEffect::Create(edgeType, count, edges);
331 } 366 }
OLDNEW
« no previous file with comments | « src/gpu/effects/GrConvexPolyEffect.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698