OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |