blob: c2874e00451c45c9fe395c0c876031ba59832964 [file] [log] [blame]
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +00001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
joshualitt30ba4362014-08-21 20:18:45 -07008#include "gl/builders/GrGLProgramBuilder.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +00009#include "GrConvexPolyEffect.h"
egdaniel605dd0f2014-11-12 08:35:25 -080010#include "GrInvariantOutput.h"
joshualittb0a8a372014-09-23 09:50:21 -070011#include "gl/GrGLProcessor.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000012#include "gl/GrGLSL.h"
joshualittb0a8a372014-09-23 09:50:21 -070013#include "GrTBackendProcessorFactory.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000014
15#include "SkPath.h"
16
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000017//////////////////////////////////////////////////////////////////////////////
18class GLAARectEffect;
19
joshualittb0a8a372014-09-23 09:50:21 -070020class AARectEffect : public GrFragmentProcessor {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000021public:
joshualittb0a8a372014-09-23 09:50:21 -070022 typedef GLAARectEffect GLProcessor;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000023
24 const SkRect& getRect() const { return fRect; }
25
26 static const char* Name() { return "AARect"; }
27
joshualittb0a8a372014-09-23 09:50:21 -070028 static GrFragmentProcessor* Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) {
bsalomon55fad7a2014-07-08 07:34:20 -070029 return SkNEW_ARGS(AARectEffect, (edgeType, rect));
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000030 }
31
joshualittb0a8a372014-09-23 09:50:21 -070032 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +000033
joshualittb0a8a372014-09-23 09:50:21 -070034 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000035
36private:
joshualittb0a8a372014-09-23 09:50:21 -070037 AARectEffect(GrPrimitiveEdgeType edgeType, const SkRect& rect) : fRect(rect), fEdgeType(edgeType) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000038 this->setWillReadFragmentPosition();
39 }
40
bsalomon0e08fc12014-10-15 08:19:04 -070041 virtual bool onIsEqual(const GrFragmentProcessor& other) const SK_OVERRIDE {
joshualitt49586be2014-09-16 08:21:41 -070042 const AARectEffect& aare = other.cast<AARectEffect>();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000043 return fRect == aare.fRect;
44 }
45
egdaniel605dd0f2014-11-12 08:35:25 -080046 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
egdaniel1a8ecdf2014-10-03 06:24:12 -070047 if (fRect.isEmpty()) {
48 // An empty rect will have no coverage anywhere.
egdaniel9e4d6d12014-10-15 13:49:02 -070049 inout->mulByKnownAlpha(0);
egdaniel1a8ecdf2014-10-03 06:24:12 -070050 } else {
egdanielccb2e382014-10-13 12:53:46 -070051 inout->mulByUnknownAlpha();
egdaniel1a8ecdf2014-10-03 06:24:12 -070052 }
egdaniel1a8ecdf2014-10-03 06:24:12 -070053 }
54
joshualittb0a8a372014-09-23 09:50:21 -070055 SkRect fRect;
56 GrPrimitiveEdgeType fEdgeType;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +000057
joshualittb0a8a372014-09-23 09:50:21 -070058 typedef GrFragmentProcessor INHERITED;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000059
joshualittb0a8a372014-09-23 09:50:21 -070060 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000061
62};
63
joshualittb0a8a372014-09-23 09:50:21 -070064GR_DEFINE_FRAGMENT_PROCESSOR_TEST(AARectEffect);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000065
joshualittb0a8a372014-09-23 09:50:21 -070066GrFragmentProcessor* AARectEffect::TestCreate(SkRandom* random,
67 GrContext*,
68 const GrDrawTargetCaps& caps,
69 GrTexture*[]) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000070 SkRect rect = SkRect::MakeLTRB(random->nextSScalar1(),
71 random->nextSScalar1(),
72 random->nextSScalar1(),
73 random->nextSScalar1());
joshualittb0a8a372014-09-23 09:50:21 -070074 GrFragmentProcessor* fp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000075 do {
joshualittb0a8a372014-09-23 09:50:21 -070076 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->nextULessThan(
77 kGrProcessorEdgeTypeCnt));
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000078
joshualittb0a8a372014-09-23 09:50:21 -070079 fp = AARectEffect::Create(edgeType, rect);
80 } while (NULL == fp);
81 return fp;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000082}
83
84//////////////////////////////////////////////////////////////////////////////
85
joshualittb0a8a372014-09-23 09:50:21 -070086class GLAARectEffect : public GrGLFragmentProcessor {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000087public:
joshualittb0a8a372014-09-23 09:50:21 -070088 GLAARectEffect(const GrBackendProcessorFactory&, const GrProcessor&);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000089
joshualitt15988992014-10-09 15:04:05 -070090 virtual void emitCode(GrGLFPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -070091 const GrFragmentProcessor& fp,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000092 const char* outputColor,
93 const char* inputColor,
94 const TransformedCoordsArray&,
95 const TextureSamplerArray&) SK_OVERRIDE;
96
joshualittb0a8a372014-09-23 09:50:21 -070097 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000098
joshualittb0a8a372014-09-23 09:50:21 -070099 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000100
101private:
kkinnunen7510b222014-07-30 00:04:16 -0700102 GrGLProgramDataManager::UniformHandle fRectUniform;
103 SkRect fPrevRect;
joshualittb0a8a372014-09-23 09:50:21 -0700104 typedef GrGLFragmentProcessor INHERITED;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000105};
106
joshualittb0a8a372014-09-23 09:50:21 -0700107GLAARectEffect::GLAARectEffect(const GrBackendProcessorFactory& factory,
108 const GrProcessor& effect)
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000109 : INHERITED (factory) {
110 fPrevRect.fLeft = SK_ScalarNaN;
111}
112
joshualitt15988992014-10-09 15:04:05 -0700113void GLAARectEffect::emitCode(GrGLFPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -0700114 const GrFragmentProcessor& fp,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000115 const char* outputColor,
116 const char* inputColor,
117 const TransformedCoordsArray&,
118 const TextureSamplerArray& samplers) {
joshualittb0a8a372014-09-23 09:50:21 -0700119 const AARectEffect& aare = fp.cast<AARectEffect>();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000120 const char *rectName;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000121 // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5),
122 // respectively.
joshualitt30ba4362014-08-21 20:18:45 -0700123 fRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000124 kVec4f_GrSLType,
125 "rect",
126 &rectName);
joshualitt30ba4362014-08-21 20:18:45 -0700127
joshualitt15988992014-10-09 15:04:05 -0700128 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
joshualitt30ba4362014-08-21 20:18:45 -0700129 const char* fragmentPos = fsBuilder->fragmentPosition();
joshualittb0a8a372014-09-23 09:50:21 -0700130 if (GrProcessorEdgeTypeIsAA(aare.getEdgeType())) {
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000131 // The amount of coverage removed in x and y by the edges is computed as a pair of negative
132 // numbers, xSub and ySub.
joshualitt30ba4362014-08-21 20:18:45 -0700133 fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n");
134 fsBuilder->codeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName);
135 fsBuilder->codeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos);
136 fsBuilder->codeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName);
137 fsBuilder->codeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000138 // Now compute coverage in x and y and multiply them to get the fraction of the pixel
139 // covered.
joshualitt30ba4362014-08-21 20:18:45 -0700140 fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000141 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700142 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
143 fsBuilder->codeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
144 fsBuilder->codeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
145 fsBuilder->codeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
146 fsBuilder->codeAppendf("\t\talpha *= (%s.w - %s.y) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000147 }
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000148
joshualittb0a8a372014-09-23 09:50:21 -0700149 if (GrProcessorEdgeTypeIsInverseFill(aare.getEdgeType())) {
joshualitt30ba4362014-08-21 20:18:45 -0700150 fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n");
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000151 }
joshualitt30ba4362014-08-21 20:18:45 -0700152 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000153 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
154}
155
joshualittb0a8a372014-09-23 09:50:21 -0700156void GLAARectEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
157 const AARectEffect& aare = processor.cast<AARectEffect>();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000158 const SkRect& rect = aare.getRect();
159 if (rect != fPrevRect) {
kkinnunen7510b222014-07-30 00:04:16 -0700160 pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000161 rect.fRight - 0.5f, rect.fBottom - 0.5f);
162 fPrevRect = rect;
163 }
164}
165
joshualittb0a8a372014-09-23 09:50:21 -0700166void GLAARectEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
167 GrProcessorKeyBuilder* b) {
168 const AARectEffect& aare = processor.cast<AARectEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700169 b->add32(aare.getEdgeType());
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000170}
171
joshualittb0a8a372014-09-23 09:50:21 -0700172const GrBackendFragmentProcessorFactory& AARectEffect::getFactory() const {
173 return GrTBackendFragmentProcessorFactory<AARectEffect>::getInstance();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000174}
175
176//////////////////////////////////////////////////////////////////////////////
177
joshualittb0a8a372014-09-23 09:50:21 -0700178class GrGLConvexPolyEffect : public GrGLFragmentProcessor {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000179public:
joshualittb0a8a372014-09-23 09:50:21 -0700180 GrGLConvexPolyEffect(const GrBackendProcessorFactory&, const GrProcessor&);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000181
joshualitt15988992014-10-09 15:04:05 -0700182 virtual void emitCode(GrGLFPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -0700183 const GrFragmentProcessor& fp,
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000184 const char* outputColor,
185 const char* inputColor,
186 const TransformedCoordsArray&,
187 const TextureSamplerArray&) SK_OVERRIDE;
188
joshualittb0a8a372014-09-23 09:50:21 -0700189 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000190
joshualittb0a8a372014-09-23 09:50:21 -0700191 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000192
193private:
kkinnunen7510b222014-07-30 00:04:16 -0700194 GrGLProgramDataManager::UniformHandle fEdgeUniform;
195 SkScalar fPrevEdges[3 * GrConvexPolyEffect::kMaxEdges];
joshualittb0a8a372014-09-23 09:50:21 -0700196 typedef GrGLFragmentProcessor INHERITED;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000197};
198
joshualittb0a8a372014-09-23 09:50:21 -0700199GrGLConvexPolyEffect::GrGLConvexPolyEffect(const GrBackendProcessorFactory& factory,
200 const GrProcessor&)
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000201 : INHERITED (factory) {
202 fPrevEdges[0] = SK_ScalarNaN;
203}
204
joshualitt15988992014-10-09 15:04:05 -0700205void GrGLConvexPolyEffect::emitCode(GrGLFPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -0700206 const GrFragmentProcessor& fp,
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000207 const char* outputColor,
208 const char* inputColor,
209 const TransformedCoordsArray&,
210 const TextureSamplerArray& samplers) {
joshualittb0a8a372014-09-23 09:50:21 -0700211 const GrConvexPolyEffect& cpe = fp.cast<GrConvexPolyEffect>();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000212
213 const char *edgeArrayName;
joshualitt30ba4362014-08-21 20:18:45 -0700214 fEdgeUniform = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000215 kVec3f_GrSLType,
216 "edges",
217 cpe.getEdgeCount(),
218 &edgeArrayName);
joshualitt15988992014-10-09 15:04:05 -0700219 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
joshualitt30ba4362014-08-21 20:18:45 -0700220 fsBuilder->codeAppend("\t\tfloat alpha = 1.0;\n");
221 fsBuilder->codeAppend("\t\tfloat edge;\n");
222 const char* fragmentPos = fsBuilder->fragmentPosition();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000223 for (int i = 0; i < cpe.getEdgeCount(); ++i) {
joshualitt30ba4362014-08-21 20:18:45 -0700224 fsBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n",
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000225 edgeArrayName, i, fragmentPos, fragmentPos);
joshualittb0a8a372014-09-23 09:50:21 -0700226 if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) {
joshualitt30ba4362014-08-21 20:18:45 -0700227 fsBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n");
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000228 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700229 fsBuilder->codeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n");
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000230 }
joshualitt30ba4362014-08-21 20:18:45 -0700231 fsBuilder->codeAppend("\t\talpha *= edge;\n");
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000232 }
233
commit-bot@chromium.org6dee8752014-02-07 22:39:01 +0000234 // Woe is me. See skbug.com/2149.
235 if (kTegra2_GrGLRenderer == builder->ctxInfo().renderer()) {
joshualitt30ba4362014-08-21 20:18:45 -0700236 fsBuilder->codeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n");
commit-bot@chromium.org6dee8752014-02-07 22:39:01 +0000237 }
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000238
joshualittb0a8a372014-09-23 09:50:21 -0700239 if (GrProcessorEdgeTypeIsInverseFill(cpe.getEdgeType())) {
joshualitt30ba4362014-08-21 20:18:45 -0700240 fsBuilder->codeAppend("\talpha = 1.0 - alpha;\n");
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000241 }
joshualitt30ba4362014-08-21 20:18:45 -0700242 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000243 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
244}
245
joshualittb0a8a372014-09-23 09:50:21 -0700246void GrGLConvexPolyEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& effect) {
joshualitt49586be2014-09-16 08:21:41 -0700247 const GrConvexPolyEffect& cpe = effect.cast<GrConvexPolyEffect>();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000248 size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar);
249 if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) {
kkinnunen7510b222014-07-30 00:04:16 -0700250 pdman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges());
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000251 memcpy(fPrevEdges, cpe.getEdges(), byteSize);
252 }
253}
254
joshualittb0a8a372014-09-23 09:50:21 -0700255void GrGLConvexPolyEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
256 GrProcessorKeyBuilder* b) {
257 const GrConvexPolyEffect& cpe = processor.cast<GrConvexPolyEffect>();
258 GR_STATIC_ASSERT(kGrProcessorEdgeTypeCnt <= 8);
bsalomon63e99f72014-07-21 08:03:14 -0700259 uint32_t key = (cpe.getEdgeCount() << 3) | cpe.getEdgeType();
260 b->add32(key);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000261}
262
263//////////////////////////////////////////////////////////////////////////////
264
joshualittb0a8a372014-09-23 09:50:21 -0700265GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType type, const SkPath& path,
266 const SkVector* offset) {
267 if (kHairlineAA_GrProcessorEdgeType == type) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000268 return NULL;
269 }
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000270 if (path.getSegmentMasks() != SkPath::kLine_SegmentMask ||
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000271 !path.isConvex()) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000272 return NULL;
273 }
274
275 if (path.countPoints() > kMaxEdges) {
276 return NULL;
277 }
278
279 SkPoint pts[kMaxEdges];
280 SkScalar edges[3 * kMaxEdges];
281
282 SkPath::Direction dir;
283 SkAssertResult(path.cheapComputeDirection(&dir));
284
commit-bot@chromium.orgb21fac12014-02-07 21:13:11 +0000285 SkVector t;
286 if (NULL == offset) {
287 t.set(0, 0);
288 } else {
289 t = *offset;
290 }
291
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000292 int count = path.getPoints(pts, kMaxEdges);
293 int n = 0;
294 for (int lastPt = count - 1, i = 0; i < count; lastPt = i++) {
295 if (pts[lastPt] != pts[i]) {
296 SkVector v = pts[i] - pts[lastPt];
297 v.normalize();
298 if (SkPath::kCCW_Direction == dir) {
299 edges[3 * n] = v.fY;
300 edges[3 * n + 1] = -v.fX;
301 } else {
302 edges[3 * n] = -v.fY;
303 edges[3 * n + 1] = v.fX;
304 }
commit-bot@chromium.orgb21fac12014-02-07 21:13:11 +0000305 SkPoint p = pts[i] + t;
306 edges[3 * n + 2] = -(edges[3 * n] * p.fX + edges[3 * n + 1] * p.fY);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000307 ++n;
308 }
309 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000310 if (path.isInverseFillType()) {
joshualittb0a8a372014-09-23 09:50:21 -0700311 type = GrInvertProcessorEdgeType(type);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000312 }
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000313 return Create(type, n, edges);
314}
315
joshualittb0a8a372014-09-23 09:50:21 -0700316GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) {
317 if (kHairlineAA_GrProcessorEdgeType == edgeType){
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000318 return NULL;
319 }
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000320 return AARectEffect::Create(edgeType, rect);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000321}
322
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000323GrConvexPolyEffect::~GrConvexPolyEffect() {}
324
egdaniel605dd0f2014-11-12 08:35:25 -0800325void GrConvexPolyEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
egdanielccb2e382014-10-13 12:53:46 -0700326 inout->mulByUnknownAlpha();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000327}
328
joshualittb0a8a372014-09-23 09:50:21 -0700329const GrBackendFragmentProcessorFactory& GrConvexPolyEffect::getFactory() const {
330 return GrTBackendFragmentProcessorFactory<GrConvexPolyEffect>::getInstance();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000331}
332
joshualittb0a8a372014-09-23 09:50:21 -0700333GrConvexPolyEffect::GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, const SkScalar edges[])
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000334 : fEdgeType(edgeType)
335 , fEdgeCount(n) {
336 // Factory function should have already ensured this.
337 SkASSERT(n <= kMaxEdges);
338 memcpy(fEdges, edges, 3 * n * sizeof(SkScalar));
339 // Outset the edges by 0.5 so that a pixel with center on an edge is 50% covered in the AA case
340 // and 100% covered in the non-AA case.
341 for (int i = 0; i < n; ++i) {
342 fEdges[3 * i + 2] += SK_ScalarHalf;
343 }
344 this->setWillReadFragmentPosition();
345}
346
bsalomon0e08fc12014-10-15 08:19:04 -0700347bool GrConvexPolyEffect::onIsEqual(const GrFragmentProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700348 const GrConvexPolyEffect& cpe = other.cast<GrConvexPolyEffect>();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000349 // ignore the fact that 0 == -0 and just use memcmp.
350 return (cpe.fEdgeType == fEdgeType && cpe.fEdgeCount == fEdgeCount &&
351 0 == memcmp(cpe.fEdges, fEdges, 3 * fEdgeCount * sizeof(SkScalar)));
352}
353
354//////////////////////////////////////////////////////////////////////////////
355
joshualittb0a8a372014-09-23 09:50:21 -0700356GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConvexPolyEffect);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000357
joshualittb0a8a372014-09-23 09:50:21 -0700358GrFragmentProcessor* GrConvexPolyEffect::TestCreate(SkRandom* random,
359 GrContext*,
360 const GrDrawTargetCaps& caps,
361 GrTexture*[]) {
commit-bot@chromium.org65ee5f42014-02-04 17:49:48 +0000362 int count = random->nextULessThan(kMaxEdges) + 1;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000363 SkScalar edges[kMaxEdges * 3];
364 for (int i = 0; i < 3 * count; ++i) {
365 edges[i] = random->nextSScalar1();
366 }
367
joshualittb0a8a372014-09-23 09:50:21 -0700368 GrFragmentProcessor* fp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000369 do {
joshualittb0a8a372014-09-23 09:50:21 -0700370 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
371 random->nextULessThan(kGrProcessorEdgeTypeCnt));
372 fp = GrConvexPolyEffect::Create(edgeType, count, edges);
373 } while (NULL == fp);
374 return fp;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000375}