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 "gl/GrGLVertexEffect.h" | 12 #include "gl/GrGLVertexEffect.h" |
13 #include "GrTBackendEffectFactory.h" | 13 #include "GrTBackendEffectFactory.h" |
14 | 14 |
15 #include "SkPath.h" | 15 #include "SkPath.h" |
16 | 16 |
17 ////////////////////////////////////////////////////////////////////////////// | |
18 class GLAARectEffect; | |
19 | |
20 class AARectEffect : public GrEffect { | |
21 public: | |
22 typedef GLAARectEffect GLEffect; | |
23 | |
24 const SkRect& getRect() const { return fRect; } | |
25 | |
26 static const char* Name() { return "AARect"; } | |
27 | |
28 static GrEffectRef* Create(const SkRect& rect) { | |
29 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(AARectEffect, (rect))) ); | |
30 } | |
31 | |
32 virtual void getConstantColorComponents(GrColor* color, | |
33 uint32_t* validFlags) const SK_OVERR IDE { | |
34 if (fRect.isEmpty()) { | |
35 // An empty rect will have no coverage anywhere. | |
36 *color = 0x00000000; | |
37 *validFlags = kRGBA_GrColorComponentFlags; | |
38 } else { | |
39 *validFlags = 0; | |
40 } | |
41 } | |
42 | |
43 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | |
44 | |
45 private: | |
46 AARectEffect(const SkRect& rect) : fRect(rect) { | |
47 this->setWillReadFragmentPosition(); | |
48 } | |
49 | |
50 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | |
51 const AARectEffect& aare = CastEffect<AARectEffect>(other); | |
52 return fRect == aare.fRect; | |
53 } | |
54 | |
55 SkRect fRect; | |
56 typedef GrEffect INHERITED; | |
57 | |
58 GR_DECLARE_EFFECT_TEST; | |
59 | |
60 }; | |
61 | |
62 GR_DEFINE_EFFECT_TEST(AARectEffect); | |
63 | |
64 GrEffectRef* AARectEffect::TestCreate(SkRandom* random, | |
65 GrContext*, | |
66 const GrDrawTargetCaps& caps, | |
67 GrTexture*[]) { | |
68 SkRect rect = SkRect::MakeLTRB(random->nextSScalar1(), | |
69 random->nextSScalar1(), | |
70 random->nextSScalar1(), | |
71 random->nextSScalar1()); | |
72 return AARectEffect::Create(rect); | |
73 } | |
74 | |
75 ////////////////////////////////////////////////////////////////////////////// | |
76 | |
77 class GLAARectEffect : public GrGLEffect { | |
78 public: | |
79 GLAARectEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | |
80 | |
81 virtual void emitCode(GrGLShaderBuilder* builder, | |
82 const GrDrawEffect& drawEffect, | |
83 EffectKey key, | |
84 const char* outputColor, | |
85 const char* inputColor, | |
86 const TransformedCoordsArray&, | |
87 const TextureSamplerArray&) SK_OVERRIDE; | |
88 | |
89 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { retur n 0; } | |
90 | |
91 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE; | |
92 | |
93 private: | |
94 GrGLUniformManager::UniformHandle fRectUniform; | |
95 SkRect fPrevRect; | |
96 typedef GrGLEffect INHERITED; | |
97 }; | |
98 | |
99 GLAARectEffect::GLAARectEffect(const GrBackendEffectFactory& factory, | |
100 const GrDrawEffect& drawEffect) | |
robertphillips
2014/02/04 19:38:50
tab here?
bsalomon
2014/02/08 19:18:01
Done.
| |
101 : INHERITED (factory) { | |
102 fPrevRect.fLeft = SK_ScalarNaN; | |
103 } | |
104 | |
105 void GLAARectEffect::emitCode(GrGLShaderBuilder* builder, | |
106 const GrDrawEffect& drawEffect, | |
107 EffectKey key, | |
108 const char* outputColor, | |
109 const char* inputColor, | |
110 const TransformedCoordsArray&, | |
111 const TextureSamplerArray& samplers) { | |
112 const char *rectName; | |
113 fRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, | |
114 kVec4f_GrSLType, | |
115 "rect", | |
116 &rectName); | |
117 const char* fragmentPos = builder->fragmentPosition(); | |
118 // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bot tom - 0.5), | |
119 // respectively. | |
robertphillips
2014/02/04 19:38:50
Maybe a more expansive comment about how coverage
bsalomon
2014/02/08 19:18:01
Done.
| |
120 builder->fsCodeAppend("\t\tfloat xSub, ySub;\n"); | |
121 builder->fsCodeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, r ectName); | |
122 builder->fsCodeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fra gmentPos); | |
123 builder->fsCodeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, r ectName); | |
124 builder->fsCodeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fra gmentPos); | |
125 builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + m ax(ySub, -1.0));\n"); | |
126 | |
127 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, | |
128 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r()); | |
129 } | |
130 | |
131 void GLAARectEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) { | |
132 const AARectEffect& aare = drawEffect.castEffect<AARectEffect>(); | |
133 const SkRect& rect = aare.getRect(); | |
robertphillips
2014/02/04 19:38:50
Do you think this caching will actually pay off?
bsalomon
2014/02/08 19:18:01
We can have the same clip active for a lot of draw
| |
134 if (rect != fPrevRect) { | |
135 uman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f, | |
136 rect.fRight - 0.5f, rect.fBottom - 0.5f); | |
137 fPrevRect = rect; | |
138 } | |
139 } | |
140 | |
141 const GrBackendEffectFactory& AARectEffect::getFactory() const { | |
142 return GrTBackendEffectFactory<AARectEffect>::getInstance(); | |
143 } | |
144 | |
145 ////////////////////////////////////////////////////////////////////////////// | |
146 | |
17 class GrGLConvexPolyEffect : public GrGLEffect { | 147 class GrGLConvexPolyEffect : public GrGLEffect { |
18 public: | 148 public: |
19 GrGLConvexPolyEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | 149 GrGLConvexPolyEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
20 | 150 |
21 virtual void emitCode(GrGLShaderBuilder* builder, | 151 virtual void emitCode(GrGLShaderBuilder* builder, |
22 const GrDrawEffect& drawEffect, | 152 const GrDrawEffect& drawEffect, |
23 EffectKey key, | 153 EffectKey key, |
24 const char* outputColor, | 154 const char* outputColor, |
25 const char* inputColor, | 155 const char* inputColor, |
26 const TransformedCoordsArray&, | 156 const TransformedCoordsArray&, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
68 builder->fsCodeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n"); | 198 builder->fsCodeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n"); |
69 builder->fsCodeAppend("\t\talpha *= edge;\n"); | 199 builder->fsCodeAppend("\t\talpha *= edge;\n"); |
70 break; | 200 break; |
71 case GrConvexPolyEffect::kFillNoAA_EdgeType: | 201 case GrConvexPolyEffect::kFillNoAA_EdgeType: |
72 builder->fsCodeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n"); | 202 builder->fsCodeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n"); |
73 builder->fsCodeAppend("\t\talpha *= edge;\n"); | 203 builder->fsCodeAppend("\t\talpha *= edge;\n"); |
74 break; | 204 break; |
75 } | 205 } |
76 } | 206 } |
77 | 207 |
78 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, | 208 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, |
79 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r()); | 209 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r()); |
80 } | 210 } |
81 | 211 |
82 void GrGLConvexPolyEffect::setData(const GrGLUniformManager& uman, const GrDrawE ffect& drawEffect) { | 212 void GrGLConvexPolyEffect::setData(const GrGLUniformManager& uman, const GrDrawE ffect& drawEffect) { |
83 const GrConvexPolyEffect& cpe = drawEffect.castEffect<GrConvexPolyEffect>(); | 213 const GrConvexPolyEffect& cpe = drawEffect.castEffect<GrConvexPolyEffect>(); |
84 size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar); | 214 size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar); |
85 if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) { | 215 if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) { |
86 uman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges()); | 216 uman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges()); |
87 memcpy(fPrevEdges, cpe.getEdges(), byteSize); | 217 memcpy(fPrevEdges, cpe.getEdges(), byteSize); |
88 } | 218 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
127 edges[3 * n] = -v.fY; | 257 edges[3 * n] = -v.fY; |
128 edges[3 * n + 1] = v.fX; | 258 edges[3 * n + 1] = v.fX; |
129 } | 259 } |
130 edges[3 * n + 2] = -(edges[3 * n] * pts[i].fX + edges[3 * n + 1] * p ts[i].fY); | 260 edges[3 * n + 2] = -(edges[3 * n] * pts[i].fX + edges[3 * n + 1] * p ts[i].fY); |
131 ++n; | 261 ++n; |
132 } | 262 } |
133 } | 263 } |
134 return Create(type, n, edges); | 264 return Create(type, n, edges); |
135 } | 265 } |
136 | 266 |
267 GrEffectRef* GrConvexPolyEffect::Create(EdgeType type, const SkRect& rect) { | |
268 if (type == kFillAA_EdgeType) { | |
269 return AARectEffect::Create(rect); | |
270 } else { | |
robertphillips
2014/02/04 19:38:50
It seems like we would never want to take this pat
bsalomon
2014/02/08 19:18:01
True. I changed the function to CreateAAFillRect a
| |
271 SkPath path; | |
272 path.addRect(rect); | |
273 return Create(type, path); | |
274 } | |
275 } | |
276 | |
137 GrConvexPolyEffect::~GrConvexPolyEffect() {} | 277 GrConvexPolyEffect::~GrConvexPolyEffect() {} |
138 | 278 |
139 void GrConvexPolyEffect::getConstantColorComponents(GrColor* color, uint32_t* va lidFlags) const { | 279 void GrConvexPolyEffect::getConstantColorComponents(GrColor* color, uint32_t* va lidFlags) const { |
140 *validFlags = 0; | 280 *validFlags = 0; |
141 } | 281 } |
142 | 282 |
143 const GrBackendEffectFactory& GrConvexPolyEffect::getFactory() const { | 283 const GrBackendEffectFactory& GrConvexPolyEffect::getFactory() const { |
144 return GrTBackendEffectFactory<GrConvexPolyEffect>::getInstance(); | 284 return GrTBackendEffectFactory<GrConvexPolyEffect>::getInstance(); |
145 } | 285 } |
146 | 286 |
(...skipping 28 matching lines...) Expand all Loading... | |
175 GrTexture*[]) { | 315 GrTexture*[]) { |
176 EdgeType edgeType = static_cast<EdgeType>(random->nextULessThan(kEdgeTypeCnt )); | 316 EdgeType edgeType = static_cast<EdgeType>(random->nextULessThan(kEdgeTypeCnt )); |
177 int count = random->nextULessThan(kMaxEdges) + 1; | 317 int count = random->nextULessThan(kMaxEdges) + 1; |
178 SkScalar edges[kMaxEdges * 3]; | 318 SkScalar edges[kMaxEdges * 3]; |
179 for (int i = 0; i < 3 * count; ++i) { | 319 for (int i = 0; i < 3 * count; ++i) { |
180 edges[i] = random->nextSScalar1(); | 320 edges[i] = random->nextSScalar1(); |
181 } | 321 } |
182 | 322 |
183 return GrConvexPolyEffect::Create(edgeType, count, edges); | 323 return GrConvexPolyEffect::Create(edgeType, count, edges); |
184 } | 324 } |
OLD | NEW |