blob: a3d032f4a0f106ff7bc59e4dbf5aa0a39b330481 [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
8#include "GrConvexPolyEffect.h"
egdaniel605dd0f2014-11-12 08:35:25 -08009#include "GrInvariantOutput.h"
reed026beb52015-06-10 14:23:15 -070010#include "SkPathPriv.h"
joshualittb0a8a372014-09-23 09:50:21 -070011#include "gl/GrGLProcessor.h"
joshualitteb2a6762014-12-04 11:35:33 -080012#include "gl/builders/GrGLProgramBuilder.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000013
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000014//////////////////////////////////////////////////////////////////////////////
joshualittb0a8a372014-09-23 09:50:21 -070015class AARectEffect : public GrFragmentProcessor {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000016public:
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000017 const SkRect& getRect() const { return fRect; }
18
joshualittb0a8a372014-09-23 09:50:21 -070019 static GrFragmentProcessor* Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) {
bsalomon55fad7a2014-07-08 07:34:20 -070020 return SkNEW_ARGS(AARectEffect, (edgeType, rect));
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000021 }
22
joshualittb0a8a372014-09-23 09:50:21 -070023 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +000024
mtklein36352bf2015-03-25 18:17:31 -070025 const char* name() const override { return "AARect"; }
joshualitteb2a6762014-12-04 11:35:33 -080026
jvanverthcfc18862015-04-28 08:48:20 -070027 void getGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
joshualitteb2a6762014-12-04 11:35:33 -080028
mtklein36352bf2015-03-25 18:17:31 -070029 GrGLFragmentProcessor* createGLInstance() const override;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000030
31private:
joshualitteb2a6762014-12-04 11:35:33 -080032 AARectEffect(GrPrimitiveEdgeType edgeType, const SkRect& rect)
33 : fRect(rect), fEdgeType(edgeType) {
34 this->initClassID<AARectEffect>();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000035 this->setWillReadFragmentPosition();
36 }
37
mtklein36352bf2015-03-25 18:17:31 -070038 bool onIsEqual(const GrFragmentProcessor& other) const override {
joshualitt49586be2014-09-16 08:21:41 -070039 const AARectEffect& aare = other.cast<AARectEffect>();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000040 return fRect == aare.fRect;
41 }
42
mtklein36352bf2015-03-25 18:17:31 -070043 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
egdaniel1a8ecdf2014-10-03 06:24:12 -070044 if (fRect.isEmpty()) {
45 // An empty rect will have no coverage anywhere.
joshualitt56995b52014-12-11 15:44:02 -080046 inout->mulByKnownSingleComponent(0);
egdaniel1a8ecdf2014-10-03 06:24:12 -070047 } else {
joshualitt56995b52014-12-11 15:44:02 -080048 inout->mulByUnknownSingleComponent();
egdaniel1a8ecdf2014-10-03 06:24:12 -070049 }
egdaniel1a8ecdf2014-10-03 06:24:12 -070050 }
51
joshualittb0a8a372014-09-23 09:50:21 -070052 SkRect fRect;
53 GrPrimitiveEdgeType fEdgeType;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +000054
joshualittb0a8a372014-09-23 09:50:21 -070055 typedef GrFragmentProcessor INHERITED;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000056
joshualittb0a8a372014-09-23 09:50:21 -070057 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000058
59};
60
joshualittb0a8a372014-09-23 09:50:21 -070061GR_DEFINE_FRAGMENT_PROCESSOR_TEST(AARectEffect);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000062
joshualitt0067ff52015-07-08 14:26:19 -070063GrFragmentProcessor* AARectEffect::TestCreate(GrProcessorTestData* d) {
64 SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(),
65 d->fRandom->nextSScalar1(),
66 d->fRandom->nextSScalar1(),
67 d->fRandom->nextSScalar1());
joshualittb0a8a372014-09-23 09:50:21 -070068 GrFragmentProcessor* fp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000069 do {
joshualitt0067ff52015-07-08 14:26:19 -070070 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
71 d->fRandom->nextULessThan(kGrProcessorEdgeTypeCnt));
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000072
joshualittb0a8a372014-09-23 09:50:21 -070073 fp = AARectEffect::Create(edgeType, rect);
74 } while (NULL == fp);
75 return fp;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000076}
77
78//////////////////////////////////////////////////////////////////////////////
79
joshualittb0a8a372014-09-23 09:50:21 -070080class GLAARectEffect : public GrGLFragmentProcessor {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000081public:
joshualitteb2a6762014-12-04 11:35:33 -080082 GLAARectEffect(const GrProcessor&);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000083
joshualitt15988992014-10-09 15:04:05 -070084 virtual void emitCode(GrGLFPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -070085 const GrFragmentProcessor& fp,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000086 const char* outputColor,
87 const char* inputColor,
88 const TransformedCoordsArray&,
mtklein36352bf2015-03-25 18:17:31 -070089 const TextureSamplerArray&) override;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000090
jvanverthcfc18862015-04-28 08:48:20 -070091 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000092
mtklein36352bf2015-03-25 18:17:31 -070093 void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000094
95private:
kkinnunen7510b222014-07-30 00:04:16 -070096 GrGLProgramDataManager::UniformHandle fRectUniform;
97 SkRect fPrevRect;
joshualittb0a8a372014-09-23 09:50:21 -070098 typedef GrGLFragmentProcessor INHERITED;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000099};
100
joshualitteb2a6762014-12-04 11:35:33 -0800101GLAARectEffect::GLAARectEffect(const GrProcessor& effect) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000102 fPrevRect.fLeft = SK_ScalarNaN;
103}
104
joshualitt15988992014-10-09 15:04:05 -0700105void GLAARectEffect::emitCode(GrGLFPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -0700106 const GrFragmentProcessor& fp,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000107 const char* outputColor,
108 const char* inputColor,
109 const TransformedCoordsArray&,
110 const TextureSamplerArray& samplers) {
joshualittb0a8a372014-09-23 09:50:21 -0700111 const AARectEffect& aare = fp.cast<AARectEffect>();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000112 const char *rectName;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000113 // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5),
114 // respectively.
joshualitt30ba4362014-08-21 20:18:45 -0700115 fRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000116 kVec4f_GrSLType,
bsalomon422f56f2014-12-09 10:18:12 -0800117 kDefault_GrSLPrecision,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000118 "rect",
119 &rectName);
joshualitt30ba4362014-08-21 20:18:45 -0700120
egdaniel29bee0f2015-04-29 11:54:42 -0700121 GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
joshualitt30ba4362014-08-21 20:18:45 -0700122 const char* fragmentPos = fsBuilder->fragmentPosition();
joshualittb0a8a372014-09-23 09:50:21 -0700123 if (GrProcessorEdgeTypeIsAA(aare.getEdgeType())) {
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000124 // The amount of coverage removed in x and y by the edges is computed as a pair of negative
125 // numbers, xSub and ySub.
joshualitt30ba4362014-08-21 20:18:45 -0700126 fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n");
127 fsBuilder->codeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName);
128 fsBuilder->codeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos);
129 fsBuilder->codeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName);
130 fsBuilder->codeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000131 // Now compute coverage in x and y and multiply them to get the fraction of the pixel
132 // covered.
joshualitt30ba4362014-08-21 20:18:45 -0700133 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 +0000134 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700135 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
robertphillips7f14c9b2015-01-30 14:44:22 -0800136 fsBuilder->codeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
137 fsBuilder->codeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
138 fsBuilder->codeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
139 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 +0000140 }
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000141
joshualittb0a8a372014-09-23 09:50:21 -0700142 if (GrProcessorEdgeTypeIsInverseFill(aare.getEdgeType())) {
joshualitt30ba4362014-08-21 20:18:45 -0700143 fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n");
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000144 }
joshualitt30ba4362014-08-21 20:18:45 -0700145 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000146 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
147}
148
joshualittb0a8a372014-09-23 09:50:21 -0700149void GLAARectEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
150 const AARectEffect& aare = processor.cast<AARectEffect>();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000151 const SkRect& rect = aare.getRect();
152 if (rect != fPrevRect) {
robertphillips7f14c9b2015-01-30 14:44:22 -0800153 pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f,
154 rect.fRight - 0.5f, rect.fBottom - 0.5f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000155 fPrevRect = rect;
156 }
157}
158
jvanverthcfc18862015-04-28 08:48:20 -0700159void GLAARectEffect::GenKey(const GrProcessor& processor, const GrGLSLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700160 GrProcessorKeyBuilder* b) {
161 const AARectEffect& aare = processor.cast<AARectEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700162 b->add32(aare.getEdgeType());
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000163}
164
jvanverthcfc18862015-04-28 08:48:20 -0700165void AARectEffect::getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
joshualitteb2a6762014-12-04 11:35:33 -0800166 GLAARectEffect::GenKey(*this, caps, b);
167}
168
169GrGLFragmentProcessor* AARectEffect::createGLInstance() const {
170 return SkNEW_ARGS(GLAARectEffect, (*this));
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000171}
172
173//////////////////////////////////////////////////////////////////////////////
174
joshualittb0a8a372014-09-23 09:50:21 -0700175class GrGLConvexPolyEffect : public GrGLFragmentProcessor {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000176public:
joshualitteb2a6762014-12-04 11:35:33 -0800177 GrGLConvexPolyEffect(const GrProcessor&);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000178
joshualitt15988992014-10-09 15:04:05 -0700179 virtual void emitCode(GrGLFPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -0700180 const GrFragmentProcessor& fp,
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000181 const char* outputColor,
182 const char* inputColor,
183 const TransformedCoordsArray&,
mtklein36352bf2015-03-25 18:17:31 -0700184 const TextureSamplerArray&) override;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000185
jvanverthcfc18862015-04-28 08:48:20 -0700186 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000187
mtklein36352bf2015-03-25 18:17:31 -0700188 void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000189
190private:
kkinnunen7510b222014-07-30 00:04:16 -0700191 GrGLProgramDataManager::UniformHandle fEdgeUniform;
192 SkScalar fPrevEdges[3 * GrConvexPolyEffect::kMaxEdges];
joshualittb0a8a372014-09-23 09:50:21 -0700193 typedef GrGLFragmentProcessor INHERITED;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000194};
195
joshualitteb2a6762014-12-04 11:35:33 -0800196GrGLConvexPolyEffect::GrGLConvexPolyEffect(const GrProcessor&) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000197 fPrevEdges[0] = SK_ScalarNaN;
198}
199
joshualitt15988992014-10-09 15:04:05 -0700200void GrGLConvexPolyEffect::emitCode(GrGLFPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -0700201 const GrFragmentProcessor& fp,
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000202 const char* outputColor,
203 const char* inputColor,
204 const TransformedCoordsArray&,
205 const TextureSamplerArray& samplers) {
joshualittb0a8a372014-09-23 09:50:21 -0700206 const GrConvexPolyEffect& cpe = fp.cast<GrConvexPolyEffect>();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000207
208 const char *edgeArrayName;
joshualitt30ba4362014-08-21 20:18:45 -0700209 fEdgeUniform = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000210 kVec3f_GrSLType,
bsalomon422f56f2014-12-09 10:18:12 -0800211 kDefault_GrSLPrecision,
212 "edges",
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000213 cpe.getEdgeCount(),
214 &edgeArrayName);
egdaniel29bee0f2015-04-29 11:54:42 -0700215 GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
joshualitt30ba4362014-08-21 20:18:45 -0700216 fsBuilder->codeAppend("\t\tfloat alpha = 1.0;\n");
217 fsBuilder->codeAppend("\t\tfloat edge;\n");
218 const char* fragmentPos = fsBuilder->fragmentPosition();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000219 for (int i = 0; i < cpe.getEdgeCount(); ++i) {
robertphillips7f14c9b2015-01-30 14:44:22 -0800220 fsBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n",
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000221 edgeArrayName, i, fragmentPos, fragmentPos);
joshualittb0a8a372014-09-23 09:50:21 -0700222 if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) {
joshualitt30ba4362014-08-21 20:18:45 -0700223 fsBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n");
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000224 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700225 fsBuilder->codeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n");
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000226 }
joshualitt30ba4362014-08-21 20:18:45 -0700227 fsBuilder->codeAppend("\t\talpha *= edge;\n");
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000228 }
229
commit-bot@chromium.org6dee8752014-02-07 22:39:01 +0000230 // Woe is me. See skbug.com/2149.
231 if (kTegra2_GrGLRenderer == builder->ctxInfo().renderer()) {
joshualitt30ba4362014-08-21 20:18:45 -0700232 fsBuilder->codeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n");
commit-bot@chromium.org6dee8752014-02-07 22:39:01 +0000233 }
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000234
joshualittb0a8a372014-09-23 09:50:21 -0700235 if (GrProcessorEdgeTypeIsInverseFill(cpe.getEdgeType())) {
joshualitt30ba4362014-08-21 20:18:45 -0700236 fsBuilder->codeAppend("\talpha = 1.0 - alpha;\n");
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000237 }
joshualitt30ba4362014-08-21 20:18:45 -0700238 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000239 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
240}
241
joshualittb0a8a372014-09-23 09:50:21 -0700242void GrGLConvexPolyEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& effect) {
joshualitt49586be2014-09-16 08:21:41 -0700243 const GrConvexPolyEffect& cpe = effect.cast<GrConvexPolyEffect>();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000244 size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar);
245 if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) {
kkinnunen7510b222014-07-30 00:04:16 -0700246 pdman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges());
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000247 memcpy(fPrevEdges, cpe.getEdges(), byteSize);
248 }
249}
250
jvanverthcfc18862015-04-28 08:48:20 -0700251void GrGLConvexPolyEffect::GenKey(const GrProcessor& processor, const GrGLSLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700252 GrProcessorKeyBuilder* b) {
253 const GrConvexPolyEffect& cpe = processor.cast<GrConvexPolyEffect>();
254 GR_STATIC_ASSERT(kGrProcessorEdgeTypeCnt <= 8);
bsalomon63e99f72014-07-21 08:03:14 -0700255 uint32_t key = (cpe.getEdgeCount() << 3) | cpe.getEdgeType();
256 b->add32(key);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000257}
258
259//////////////////////////////////////////////////////////////////////////////
260
joshualittb0a8a372014-09-23 09:50:21 -0700261GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType type, const SkPath& path,
262 const SkVector* offset) {
263 if (kHairlineAA_GrProcessorEdgeType == type) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000264 return NULL;
265 }
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000266 if (path.getSegmentMasks() != SkPath::kLine_SegmentMask ||
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000267 !path.isConvex()) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000268 return NULL;
269 }
270
271 if (path.countPoints() > kMaxEdges) {
272 return NULL;
273 }
274
275 SkPoint pts[kMaxEdges];
276 SkScalar edges[3 * kMaxEdges];
277
reed026beb52015-06-10 14:23:15 -0700278 SkPathPriv::FirstDirection dir;
279 SkAssertResult(SkPathPriv::CheapComputeFirstDirection(path, &dir));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000280
commit-bot@chromium.orgb21fac12014-02-07 21:13:11 +0000281 SkVector t;
282 if (NULL == offset) {
283 t.set(0, 0);
284 } else {
285 t = *offset;
286 }
287
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000288 int count = path.getPoints(pts, kMaxEdges);
289 int n = 0;
290 for (int lastPt = count - 1, i = 0; i < count; lastPt = i++) {
291 if (pts[lastPt] != pts[i]) {
292 SkVector v = pts[i] - pts[lastPt];
293 v.normalize();
reed026beb52015-06-10 14:23:15 -0700294 if (SkPathPriv::kCCW_FirstDirection == dir) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000295 edges[3 * n] = v.fY;
296 edges[3 * n + 1] = -v.fX;
297 } else {
298 edges[3 * n] = -v.fY;
299 edges[3 * n + 1] = v.fX;
300 }
commit-bot@chromium.orgb21fac12014-02-07 21:13:11 +0000301 SkPoint p = pts[i] + t;
302 edges[3 * n + 2] = -(edges[3 * n] * p.fX + edges[3 * n + 1] * p.fY);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000303 ++n;
304 }
305 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000306 if (path.isInverseFillType()) {
joshualittb0a8a372014-09-23 09:50:21 -0700307 type = GrInvertProcessorEdgeType(type);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000308 }
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000309 return Create(type, n, edges);
310}
311
joshualittb0a8a372014-09-23 09:50:21 -0700312GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) {
313 if (kHairlineAA_GrProcessorEdgeType == edgeType){
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000314 return NULL;
315 }
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000316 return AARectEffect::Create(edgeType, rect);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000317}
318
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000319GrConvexPolyEffect::~GrConvexPolyEffect() {}
320
egdaniel605dd0f2014-11-12 08:35:25 -0800321void GrConvexPolyEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
joshualitt56995b52014-12-11 15:44:02 -0800322 inout->mulByUnknownSingleComponent();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000323}
324
jvanverthcfc18862015-04-28 08:48:20 -0700325void GrConvexPolyEffect::getGLProcessorKey(const GrGLSLCaps& caps,
joshualitteb2a6762014-12-04 11:35:33 -0800326 GrProcessorKeyBuilder* b) const {
327 GrGLConvexPolyEffect::GenKey(*this, caps, b);
328}
329
330GrGLFragmentProcessor* GrConvexPolyEffect::createGLInstance() const {
331 return SkNEW_ARGS(GrGLConvexPolyEffect, (*this));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000332}
333
joshualittb0a8a372014-09-23 09:50:21 -0700334GrConvexPolyEffect::GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, const SkScalar edges[])
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000335 : fEdgeType(edgeType)
336 , fEdgeCount(n) {
joshualitteb2a6762014-12-04 11:35:33 -0800337 this->initClassID<GrConvexPolyEffect>();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000338 // Factory function should have already ensured this.
339 SkASSERT(n <= kMaxEdges);
340 memcpy(fEdges, edges, 3 * n * sizeof(SkScalar));
341 // Outset the edges by 0.5 so that a pixel with center on an edge is 50% covered in the AA case
342 // and 100% covered in the non-AA case.
343 for (int i = 0; i < n; ++i) {
344 fEdges[3 * i + 2] += SK_ScalarHalf;
345 }
346 this->setWillReadFragmentPosition();
347}
348
bsalomon0e08fc12014-10-15 08:19:04 -0700349bool GrConvexPolyEffect::onIsEqual(const GrFragmentProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700350 const GrConvexPolyEffect& cpe = other.cast<GrConvexPolyEffect>();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000351 // ignore the fact that 0 == -0 and just use memcmp.
352 return (cpe.fEdgeType == fEdgeType && cpe.fEdgeCount == fEdgeCount &&
353 0 == memcmp(cpe.fEdges, fEdges, 3 * fEdgeCount * sizeof(SkScalar)));
354}
355
356//////////////////////////////////////////////////////////////////////////////
357
joshualittb0a8a372014-09-23 09:50:21 -0700358GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConvexPolyEffect);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000359
joshualitt0067ff52015-07-08 14:26:19 -0700360GrFragmentProcessor* GrConvexPolyEffect::TestCreate(GrProcessorTestData* d) {
361 int count = d->fRandom->nextULessThan(kMaxEdges) + 1;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000362 SkScalar edges[kMaxEdges * 3];
363 for (int i = 0; i < 3 * count; ++i) {
joshualitt0067ff52015-07-08 14:26:19 -0700364 edges[i] = d->fRandom->nextSScalar1();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000365 }
366
joshualittb0a8a372014-09-23 09:50:21 -0700367 GrFragmentProcessor* fp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000368 do {
joshualittb0a8a372014-09-23 09:50:21 -0700369 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
joshualitt0067ff52015-07-08 14:26:19 -0700370 d->fRandom->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualittb0a8a372014-09-23 09:50:21 -0700371 fp = GrConvexPolyEffect::Create(edgeType, count, edges);
372 } while (NULL == fp);
373 return fp;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000374}