blob: 6f93fb5277fb878d35c98ad79f1d37c58ee36e7c [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"
joshualitteb2a6762014-12-04 11:35:33 -080010#include "SkPath.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"
joshualitteb2a6762014-12-04 11:35:33 -080013#include "gl/builders/GrGLProgramBuilder.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000014
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000015//////////////////////////////////////////////////////////////////////////////
joshualittb0a8a372014-09-23 09:50:21 -070016class AARectEffect : public GrFragmentProcessor {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000017public:
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000018 const SkRect& getRect() const { return fRect; }
19
joshualittb0a8a372014-09-23 09:50:21 -070020 static GrFragmentProcessor* Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) {
bsalomon55fad7a2014-07-08 07:34:20 -070021 return SkNEW_ARGS(AARectEffect, (edgeType, rect));
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000022 }
23
joshualittb0a8a372014-09-23 09:50:21 -070024 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +000025
joshualitteb2a6762014-12-04 11:35:33 -080026 virtual const char* name() const SK_OVERRIDE { return "AARect"; }
27
28 virtual void getGLProcessorKey(const GrGLCaps&, GrProcessorKeyBuilder*) const SK_OVERRIDE;
29
30 virtual GrGLFragmentProcessor* createGLInstance() const SK_OVERRIDE;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000031
32private:
joshualitteb2a6762014-12-04 11:35:33 -080033 AARectEffect(GrPrimitiveEdgeType edgeType, const SkRect& rect)
34 : fRect(rect), fEdgeType(edgeType) {
35 this->initClassID<AARectEffect>();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000036 this->setWillReadFragmentPosition();
37 }
38
bsalomon0e08fc12014-10-15 08:19:04 -070039 virtual bool onIsEqual(const GrFragmentProcessor& other) const SK_OVERRIDE {
joshualitt49586be2014-09-16 08:21:41 -070040 const AARectEffect& aare = other.cast<AARectEffect>();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000041 return fRect == aare.fRect;
42 }
43
egdaniel605dd0f2014-11-12 08:35:25 -080044 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
egdaniel1a8ecdf2014-10-03 06:24:12 -070045 if (fRect.isEmpty()) {
46 // An empty rect will have no coverage anywhere.
egdaniel9e4d6d12014-10-15 13:49:02 -070047 inout->mulByKnownAlpha(0);
egdaniel1a8ecdf2014-10-03 06:24:12 -070048 } else {
egdanielccb2e382014-10-13 12:53:46 -070049 inout->mulByUnknownAlpha();
egdaniel1a8ecdf2014-10-03 06:24:12 -070050 }
egdaniel1a8ecdf2014-10-03 06:24:12 -070051 }
52
joshualittb0a8a372014-09-23 09:50:21 -070053 SkRect fRect;
54 GrPrimitiveEdgeType fEdgeType;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +000055
joshualittb0a8a372014-09-23 09:50:21 -070056 typedef GrFragmentProcessor INHERITED;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000057
joshualittb0a8a372014-09-23 09:50:21 -070058 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000059
60};
61
joshualittb0a8a372014-09-23 09:50:21 -070062GR_DEFINE_FRAGMENT_PROCESSOR_TEST(AARectEffect);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000063
joshualittb0a8a372014-09-23 09:50:21 -070064GrFragmentProcessor* AARectEffect::TestCreate(SkRandom* random,
65 GrContext*,
66 const GrDrawTargetCaps& caps,
67 GrTexture*[]) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000068 SkRect rect = SkRect::MakeLTRB(random->nextSScalar1(),
69 random->nextSScalar1(),
70 random->nextSScalar1(),
71 random->nextSScalar1());
joshualittb0a8a372014-09-23 09:50:21 -070072 GrFragmentProcessor* fp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000073 do {
joshualittb0a8a372014-09-23 09:50:21 -070074 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->nextULessThan(
75 kGrProcessorEdgeTypeCnt));
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000076
joshualittb0a8a372014-09-23 09:50:21 -070077 fp = AARectEffect::Create(edgeType, rect);
78 } while (NULL == fp);
79 return fp;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000080}
81
82//////////////////////////////////////////////////////////////////////////////
83
joshualittb0a8a372014-09-23 09:50:21 -070084class GLAARectEffect : public GrGLFragmentProcessor {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000085public:
joshualitteb2a6762014-12-04 11:35:33 -080086 GLAARectEffect(const GrProcessor&);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000087
joshualitt15988992014-10-09 15:04:05 -070088 virtual void emitCode(GrGLFPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -070089 const GrFragmentProcessor& fp,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000090 const char* outputColor,
91 const char* inputColor,
92 const TransformedCoordsArray&,
93 const TextureSamplerArray&) SK_OVERRIDE;
94
joshualittb0a8a372014-09-23 09:50:21 -070095 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000096
joshualittb0a8a372014-09-23 09:50:21 -070097 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000098
99private:
kkinnunen7510b222014-07-30 00:04:16 -0700100 GrGLProgramDataManager::UniformHandle fRectUniform;
101 SkRect fPrevRect;
joshualittb0a8a372014-09-23 09:50:21 -0700102 typedef GrGLFragmentProcessor INHERITED;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000103};
104
joshualitteb2a6762014-12-04 11:35:33 -0800105GLAARectEffect::GLAARectEffect(const GrProcessor& effect) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000106 fPrevRect.fLeft = SK_ScalarNaN;
107}
108
joshualitt15988992014-10-09 15:04:05 -0700109void GLAARectEffect::emitCode(GrGLFPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -0700110 const GrFragmentProcessor& fp,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000111 const char* outputColor,
112 const char* inputColor,
113 const TransformedCoordsArray&,
114 const TextureSamplerArray& samplers) {
joshualittb0a8a372014-09-23 09:50:21 -0700115 const AARectEffect& aare = fp.cast<AARectEffect>();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000116 const char *rectName;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000117 // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5),
118 // respectively.
joshualitt30ba4362014-08-21 20:18:45 -0700119 fRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000120 kVec4f_GrSLType,
121 "rect",
122 &rectName);
joshualitt30ba4362014-08-21 20:18:45 -0700123
joshualitt15988992014-10-09 15:04:05 -0700124 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
joshualitt30ba4362014-08-21 20:18:45 -0700125 const char* fragmentPos = fsBuilder->fragmentPosition();
joshualittb0a8a372014-09-23 09:50:21 -0700126 if (GrProcessorEdgeTypeIsAA(aare.getEdgeType())) {
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000127 // The amount of coverage removed in x and y by the edges is computed as a pair of negative
128 // numbers, xSub and ySub.
joshualitt30ba4362014-08-21 20:18:45 -0700129 fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n");
130 fsBuilder->codeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName);
131 fsBuilder->codeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos);
132 fsBuilder->codeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName);
133 fsBuilder->codeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000134 // Now compute coverage in x and y and multiply them to get the fraction of the pixel
135 // covered.
joshualitt30ba4362014-08-21 20:18:45 -0700136 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 +0000137 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700138 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
139 fsBuilder->codeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
140 fsBuilder->codeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
141 fsBuilder->codeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
142 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 +0000143 }
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000144
joshualittb0a8a372014-09-23 09:50:21 -0700145 if (GrProcessorEdgeTypeIsInverseFill(aare.getEdgeType())) {
joshualitt30ba4362014-08-21 20:18:45 -0700146 fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n");
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000147 }
joshualitt30ba4362014-08-21 20:18:45 -0700148 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000149 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
150}
151
joshualittb0a8a372014-09-23 09:50:21 -0700152void GLAARectEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
153 const AARectEffect& aare = processor.cast<AARectEffect>();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000154 const SkRect& rect = aare.getRect();
155 if (rect != fPrevRect) {
kkinnunen7510b222014-07-30 00:04:16 -0700156 pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f,
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000157 rect.fRight - 0.5f, rect.fBottom - 0.5f);
158 fPrevRect = rect;
159 }
160}
161
joshualittb0a8a372014-09-23 09:50:21 -0700162void GLAARectEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
163 GrProcessorKeyBuilder* b) {
164 const AARectEffect& aare = processor.cast<AARectEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700165 b->add32(aare.getEdgeType());
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000166}
167
joshualitteb2a6762014-12-04 11:35:33 -0800168void AARectEffect::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const {
169 GLAARectEffect::GenKey(*this, caps, b);
170}
171
172GrGLFragmentProcessor* AARectEffect::createGLInstance() const {
173 return SkNEW_ARGS(GLAARectEffect, (*this));
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:
joshualitteb2a6762014-12-04 11:35:33 -0800180 GrGLConvexPolyEffect(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
joshualitteb2a6762014-12-04 11:35:33 -0800199GrGLConvexPolyEffect::GrGLConvexPolyEffect(const GrProcessor&) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000200 fPrevEdges[0] = SK_ScalarNaN;
201}
202
joshualitt15988992014-10-09 15:04:05 -0700203void GrGLConvexPolyEffect::emitCode(GrGLFPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -0700204 const GrFragmentProcessor& fp,
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000205 const char* outputColor,
206 const char* inputColor,
207 const TransformedCoordsArray&,
208 const TextureSamplerArray& samplers) {
joshualittb0a8a372014-09-23 09:50:21 -0700209 const GrConvexPolyEffect& cpe = fp.cast<GrConvexPolyEffect>();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000210
211 const char *edgeArrayName;
joshualitt30ba4362014-08-21 20:18:45 -0700212 fEdgeUniform = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000213 kVec3f_GrSLType,
214 "edges",
215 cpe.getEdgeCount(),
216 &edgeArrayName);
joshualitt15988992014-10-09 15:04:05 -0700217 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
joshualitt30ba4362014-08-21 20:18:45 -0700218 fsBuilder->codeAppend("\t\tfloat alpha = 1.0;\n");
219 fsBuilder->codeAppend("\t\tfloat edge;\n");
220 const char* fragmentPos = fsBuilder->fragmentPosition();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000221 for (int i = 0; i < cpe.getEdgeCount(); ++i) {
joshualitt30ba4362014-08-21 20:18:45 -0700222 fsBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n",
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000223 edgeArrayName, i, fragmentPos, fragmentPos);
joshualittb0a8a372014-09-23 09:50:21 -0700224 if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) {
joshualitt30ba4362014-08-21 20:18:45 -0700225 fsBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n");
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000226 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700227 fsBuilder->codeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n");
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000228 }
joshualitt30ba4362014-08-21 20:18:45 -0700229 fsBuilder->codeAppend("\t\talpha *= edge;\n");
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000230 }
231
commit-bot@chromium.org6dee8752014-02-07 22:39:01 +0000232 // Woe is me. See skbug.com/2149.
233 if (kTegra2_GrGLRenderer == builder->ctxInfo().renderer()) {
joshualitt30ba4362014-08-21 20:18:45 -0700234 fsBuilder->codeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n");
commit-bot@chromium.org6dee8752014-02-07 22:39:01 +0000235 }
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000236
joshualittb0a8a372014-09-23 09:50:21 -0700237 if (GrProcessorEdgeTypeIsInverseFill(cpe.getEdgeType())) {
joshualitt30ba4362014-08-21 20:18:45 -0700238 fsBuilder->codeAppend("\talpha = 1.0 - alpha;\n");
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000239 }
joshualitt30ba4362014-08-21 20:18:45 -0700240 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000241 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
242}
243
joshualittb0a8a372014-09-23 09:50:21 -0700244void GrGLConvexPolyEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& effect) {
joshualitt49586be2014-09-16 08:21:41 -0700245 const GrConvexPolyEffect& cpe = effect.cast<GrConvexPolyEffect>();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000246 size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar);
247 if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) {
kkinnunen7510b222014-07-30 00:04:16 -0700248 pdman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges());
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000249 memcpy(fPrevEdges, cpe.getEdges(), byteSize);
250 }
251}
252
joshualittb0a8a372014-09-23 09:50:21 -0700253void GrGLConvexPolyEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
254 GrProcessorKeyBuilder* b) {
255 const GrConvexPolyEffect& cpe = processor.cast<GrConvexPolyEffect>();
256 GR_STATIC_ASSERT(kGrProcessorEdgeTypeCnt <= 8);
bsalomon63e99f72014-07-21 08:03:14 -0700257 uint32_t key = (cpe.getEdgeCount() << 3) | cpe.getEdgeType();
258 b->add32(key);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000259}
260
261//////////////////////////////////////////////////////////////////////////////
262
joshualittb0a8a372014-09-23 09:50:21 -0700263GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType type, const SkPath& path,
264 const SkVector* offset) {
265 if (kHairlineAA_GrProcessorEdgeType == type) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000266 return NULL;
267 }
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000268 if (path.getSegmentMasks() != SkPath::kLine_SegmentMask ||
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000269 !path.isConvex()) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000270 return NULL;
271 }
272
273 if (path.countPoints() > kMaxEdges) {
274 return NULL;
275 }
276
277 SkPoint pts[kMaxEdges];
278 SkScalar edges[3 * kMaxEdges];
279
280 SkPath::Direction dir;
281 SkAssertResult(path.cheapComputeDirection(&dir));
282
commit-bot@chromium.orgb21fac12014-02-07 21:13:11 +0000283 SkVector t;
284 if (NULL == offset) {
285 t.set(0, 0);
286 } else {
287 t = *offset;
288 }
289
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000290 int count = path.getPoints(pts, kMaxEdges);
291 int n = 0;
292 for (int lastPt = count - 1, i = 0; i < count; lastPt = i++) {
293 if (pts[lastPt] != pts[i]) {
294 SkVector v = pts[i] - pts[lastPt];
295 v.normalize();
296 if (SkPath::kCCW_Direction == dir) {
297 edges[3 * n] = v.fY;
298 edges[3 * n + 1] = -v.fX;
299 } else {
300 edges[3 * n] = -v.fY;
301 edges[3 * n + 1] = v.fX;
302 }
commit-bot@chromium.orgb21fac12014-02-07 21:13:11 +0000303 SkPoint p = pts[i] + t;
304 edges[3 * n + 2] = -(edges[3 * n] * p.fX + edges[3 * n + 1] * p.fY);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000305 ++n;
306 }
307 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000308 if (path.isInverseFillType()) {
joshualittb0a8a372014-09-23 09:50:21 -0700309 type = GrInvertProcessorEdgeType(type);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000310 }
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000311 return Create(type, n, edges);
312}
313
joshualittb0a8a372014-09-23 09:50:21 -0700314GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) {
315 if (kHairlineAA_GrProcessorEdgeType == edgeType){
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000316 return NULL;
317 }
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000318 return AARectEffect::Create(edgeType, rect);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000319}
320
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000321GrConvexPolyEffect::~GrConvexPolyEffect() {}
322
egdaniel605dd0f2014-11-12 08:35:25 -0800323void GrConvexPolyEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
egdanielccb2e382014-10-13 12:53:46 -0700324 inout->mulByUnknownAlpha();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000325}
326
joshualitteb2a6762014-12-04 11:35:33 -0800327void GrConvexPolyEffect::getGLProcessorKey(const GrGLCaps& caps,
328 GrProcessorKeyBuilder* b) const {
329 GrGLConvexPolyEffect::GenKey(*this, caps, b);
330}
331
332GrGLFragmentProcessor* GrConvexPolyEffect::createGLInstance() const {
333 return SkNEW_ARGS(GrGLConvexPolyEffect, (*this));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000334}
335
joshualittb0a8a372014-09-23 09:50:21 -0700336GrConvexPolyEffect::GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, const SkScalar edges[])
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000337 : fEdgeType(edgeType)
338 , fEdgeCount(n) {
joshualitteb2a6762014-12-04 11:35:33 -0800339 this->initClassID<GrConvexPolyEffect>();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000340 // Factory function should have already ensured this.
341 SkASSERT(n <= kMaxEdges);
342 memcpy(fEdges, edges, 3 * n * sizeof(SkScalar));
343 // Outset the edges by 0.5 so that a pixel with center on an edge is 50% covered in the AA case
344 // and 100% covered in the non-AA case.
345 for (int i = 0; i < n; ++i) {
346 fEdges[3 * i + 2] += SK_ScalarHalf;
347 }
348 this->setWillReadFragmentPosition();
349}
350
bsalomon0e08fc12014-10-15 08:19:04 -0700351bool GrConvexPolyEffect::onIsEqual(const GrFragmentProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700352 const GrConvexPolyEffect& cpe = other.cast<GrConvexPolyEffect>();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000353 // ignore the fact that 0 == -0 and just use memcmp.
354 return (cpe.fEdgeType == fEdgeType && cpe.fEdgeCount == fEdgeCount &&
355 0 == memcmp(cpe.fEdges, fEdges, 3 * fEdgeCount * sizeof(SkScalar)));
356}
357
358//////////////////////////////////////////////////////////////////////////////
359
joshualittb0a8a372014-09-23 09:50:21 -0700360GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConvexPolyEffect);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000361
joshualittb0a8a372014-09-23 09:50:21 -0700362GrFragmentProcessor* GrConvexPolyEffect::TestCreate(SkRandom* random,
363 GrContext*,
364 const GrDrawTargetCaps& caps,
365 GrTexture*[]) {
commit-bot@chromium.org65ee5f42014-02-04 17:49:48 +0000366 int count = random->nextULessThan(kMaxEdges) + 1;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000367 SkScalar edges[kMaxEdges * 3];
368 for (int i = 0; i < 3 * count; ++i) {
369 edges[i] = random->nextSScalar1();
370 }
371
joshualittb0a8a372014-09-23 09:50:21 -0700372 GrFragmentProcessor* fp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000373 do {
joshualittb0a8a372014-09-23 09:50:21 -0700374 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
375 random->nextULessThan(kGrProcessorEdgeTypeCnt));
376 fp = GrConvexPolyEffect::Create(edgeType, count, edges);
377 } while (NULL == fp);
378 return fp;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000379}