13eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org/*
23eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org * Copyright 2014 Google Inc.
33eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org *
43eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
53eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org * found in the LICENSE file.
63eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org */
73eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
83eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org#include "GrOvalEffect.h"
9eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
10eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "GrFragmentProcessor.h"
11605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h"
12eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "SkRect.h"
13b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h"
143eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org#include "gl/GrGLSL.h"
15eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "gl/builders/GrGLProgramBuilder.h"
163eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
173eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
183eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
19b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass CircleEffect : public GrFragmentProcessor {
203eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.orgpublic:
21b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrPrimitiveEdgeType, const SkPoint& center, SkScalar radius);
223eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
233eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    virtual ~CircleEffect() {};
24eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
2536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "Circle"; }
26eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
27cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    void getGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
28eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
2936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    GrGLFragmentProcessor* createGLInstance() const override;
303eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
313eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    const SkPoint& getCenter() const { return fCenter; }
323eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    SkScalar getRadius() const { return fRadius; }
333eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
34b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
353eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
363eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.orgprivate:
37b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    CircleEffect(GrPrimitiveEdgeType, const SkPoint& center, SkScalar radius);
383eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
3936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrFragmentProcessor&) const override;
403eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
4136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
421a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel
433eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    SkPoint             fCenter;
443eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    SkScalar            fRadius;
45b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrPrimitiveEdgeType    fEdgeType;
463eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
47b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
483eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
49b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrFragmentProcessor INHERITED;
503eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org};
513eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
52b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* CircleEffect::Create(GrPrimitiveEdgeType edgeType, const SkPoint& center,
53b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                          SkScalar radius) {
543eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    SkASSERT(radius >= 0);
5555fad7af61c21d502acb9891d631e8aa29e3628cbsalomon    return SkNEW_ARGS(CircleEffect, (edgeType, center, radius));
563eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org}
573eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
58605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdanielvoid CircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
5956995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt    inout->mulByUnknownSingleComponent();
603eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org}
613eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
62b0a8a377f832c59cee939ad721e1f87d378b7142joshualittCircleEffect::CircleEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar r)
633eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    : fCenter(c)
643eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    , fRadius(r)
653eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    , fEdgeType(edgeType) {
66eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    this->initClassID<CircleEffect>();
673eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    this->setWillReadFragmentPosition();
683eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org}
693eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
700e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool CircleEffect::onIsEqual(const GrFragmentProcessor& other) const {
7149586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const CircleEffect& ce = other.cast<CircleEffect>();
72d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    return fEdgeType == ce.fEdgeType && fCenter == ce.fCenter && fRadius == ce.fRadius;
733eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org}
743eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
753eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
763eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
77b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircleEffect);
783eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
79b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* CircleEffect::TestCreate(SkRandom* random,
80b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                              GrContext*,
81b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                              const GrDrawTargetCaps& caps,
82b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                              GrTexture*[]) {
833eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    SkPoint center;
843eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    center.fX = random->nextRangeScalar(0.f, 1000.f);
853eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    center.fY = random->nextRangeScalar(0.f, 1000.f);
863eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    SkScalar radius = random->nextRangeF(0.f, 1000.f);
87b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrPrimitiveEdgeType et;
883eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    do {
89b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        et = (GrPrimitiveEdgeType)random->nextULessThan(kGrProcessorEdgeTypeCnt);
90b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    } while (kHairlineAA_GrProcessorEdgeType == et);
913eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    return CircleEffect::Create(et, center, radius);
923eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org}
933eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
943eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
953eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
96b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GLCircleEffect : public GrGLFragmentProcessor {
973eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.orgpublic:
98eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLCircleEffect(const GrProcessor&);
993eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
1001598899975ecc85b003a59740b588d1ddbcedb09joshualitt    virtual void emitCode(GrGLFPBuilder* builder,
101b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrFragmentProcessor& fp,
1023eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org                          const char* outputColor,
1033eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org                          const char* inputColor,
1043eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org                          const TransformedCoordsArray&,
10536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                          const TextureSamplerArray&) override;
1063eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
107cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
1083eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
10936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
1103eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
1113eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.orgprivate:
1127510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    GrGLProgramDataManager::UniformHandle fCircleUniform;
1137510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    SkPoint                               fPrevCenter;
1147510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    SkScalar                              fPrevRadius;
1153eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
116b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrGLFragmentProcessor INHERITED;
1173eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org};
1183eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
119eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGLCircleEffect::GLCircleEffect(const GrProcessor&) {
1203eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    fPrevRadius = -1.f;
1213eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org}
1223eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
1231598899975ecc85b003a59740b588d1ddbcedb09joshualittvoid GLCircleEffect::emitCode(GrGLFPBuilder* builder,
124b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                              const GrFragmentProcessor& fp,
1253eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org                              const char* outputColor,
1263eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org                              const char* inputColor,
1273eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org                              const TransformedCoordsArray&,
1283eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org                              const TextureSamplerArray& samplers) {
129b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const CircleEffect& ce = fp.cast<CircleEffect>();
1303eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    const char *circleName;
131fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon    // The circle uniform is (center.x, center.y, radius + 0.5, 1 / (radius + 0.5)) for regular
132fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon    // fills and (..., radius - 0.5, 1 / (radius - 0.5)) for inverse fills.
13330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fCircleUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
134fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon                                         kVec4f_GrSLType, kDefault_GrSLPrecision,
1353eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org                                         "circle",
1363eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org                                         &circleName);
13730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
13829bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel    GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
13930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    const char* fragmentPos = fsBuilder->fragmentPosition();
1403eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
141b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    SkASSERT(kHairlineAA_GrProcessorEdgeType != ce.getEdgeType());
142fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon    // TODO: Right now the distance to circle caclulation is performed in a space normalized to the
143fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon    // radius and then denormalized. This is to prevent overflow on devices that have a "real"
144fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon    // mediump. It'd be nice to only to this on mediump devices but we currently don't have the
145fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon    // caps here.
146b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    if (GrProcessorEdgeTypeIsInverseFill(ce.getEdgeType())) {
147fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon        fsBuilder->codeAppendf("\t\tfloat d = (length((%s.xy - %s.xy) * %s.w) - 1.0) * %s.z;\n",
148fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon                                circleName, fragmentPos, circleName, circleName);
1493eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    } else {
150fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon        fsBuilder->codeAppendf("\t\tfloat d = (1.0 - length((%s.xy - %s.xy) *  %s.w)) * %s.z;\n",
151fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon                               circleName, fragmentPos, circleName, circleName);
1523eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    }
153b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    if (GrProcessorEdgeTypeIsAA(ce.getEdgeType())) {
15430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\t\td = clamp(d, 0.0, 1.0);\n");
1553eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    } else {
15630ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\t\td = d > 0.5 ? 1.0 : 0.0;\n");
1573eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    }
1583eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
15930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
1603eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org                           (GrGLSLExpr4(inputColor) * GrGLSLExpr1("d")).c_str());
1613eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org}
1623eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
163cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid GLCircleEffect::GenKey(const GrProcessor& processor, const GrGLSLCaps&,
164b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                            GrProcessorKeyBuilder* b) {
165b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const CircleEffect& ce = processor.cast<CircleEffect>();
16663e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    b->add32(ce.getEdgeType());
1673eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org}
1683eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
169b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLCircleEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
170b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const CircleEffect& ce = processor.cast<CircleEffect>();
1713eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    if (ce.getRadius() != fPrevRadius || ce.getCenter() != fPrevCenter) {
1720a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        SkScalar radius = ce.getRadius();
173b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        if (GrProcessorEdgeTypeIsInverseFill(ce.getEdgeType())) {
1740a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            radius -= 0.5f;
1750a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        } else {
1760a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            radius += 0.5f;
1770a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        }
178fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon        pdman.set4f(fCircleUniform, ce.getCenter().fX, ce.getCenter().fY, radius,
179fcabe429a4cd55d4b0b6c3e7b8b648fe8b35924dbsalomon                    SkScalarInvert(radius));
1803eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org        fPrevCenter = ce.getCenter();
1813eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org        fPrevRadius = ce.getRadius();
1823eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    }
1833eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org}
184d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
185eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt///////////////////////////////////////////////////////////////////////////////////////////////////
186eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
187cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid CircleEffect::getGLProcessorKey(const GrGLSLCaps& caps,
188eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt                                     GrProcessorKeyBuilder* b) const {
189eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLCircleEffect::GenKey(*this, caps, b);
190eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
191eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
192eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrGLFragmentProcessor* CircleEffect::createGLInstance() const  {
193eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    return SkNEW_ARGS(GLCircleEffect, (*this));
194eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
195d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
196eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt//////////////////////////////////////////////////////////////////////////////
197d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
198b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass EllipseEffect : public GrFragmentProcessor {
199d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.orgpublic:
200b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrPrimitiveEdgeType, const SkPoint& center, SkScalar rx,
201b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkScalar ry);
202d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
203d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    virtual ~EllipseEffect() {};
204eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
20536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "Ellipse"; }
206eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
207cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    void getGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
208eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
20936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    GrGLFragmentProcessor* createGLInstance() const override;
210d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
211d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    const SkPoint& getCenter() const { return fCenter; }
212d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    SkVector getRadii() const { return fRadii; }
213d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
214b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
215d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
216d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.orgprivate:
217b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    EllipseEffect(GrPrimitiveEdgeType, const SkPoint& center, SkScalar rx, SkScalar ry);
218d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
21936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrFragmentProcessor&) const override;
220d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
22136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
2221a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel
223d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    SkPoint             fCenter;
224d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    SkVector            fRadii;
225b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrPrimitiveEdgeType    fEdgeType;
226d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
227b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
228d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
229b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrFragmentProcessor INHERITED;
230d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org};
231d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
232b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* EllipseEffect::Create(GrPrimitiveEdgeType edgeType,
233b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                           const SkPoint& center,
234b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                           SkScalar rx,
235b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                           SkScalar ry) {
236d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    SkASSERT(rx >= 0 && ry >= 0);
23755fad7af61c21d502acb9891d631e8aa29e3628cbsalomon    return SkNEW_ARGS(EllipseEffect, (edgeType, center, rx, ry));
238d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org}
239d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
240605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdanielvoid EllipseEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
24156995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt    inout->mulByUnknownSingleComponent();
242d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org}
243d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
244b0a8a377f832c59cee939ad721e1f87d378b7142joshualittEllipseEffect::EllipseEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar rx, SkScalar ry)
245d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    : fCenter(c)
246d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    , fRadii(SkVector::Make(rx, ry))
247d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    , fEdgeType(edgeType) {
248eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    this->initClassID<EllipseEffect>();
249d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    this->setWillReadFragmentPosition();
250d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org}
251d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
2520e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool EllipseEffect::onIsEqual(const GrFragmentProcessor& other) const {
25349586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const EllipseEffect& ee = other.cast<EllipseEffect>();
254d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    return fEdgeType == ee.fEdgeType && fCenter == ee.fCenter && fRadii == ee.fRadii;
255d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org}
256d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
257d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
258d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
259b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(EllipseEffect);
260d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
261b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* EllipseEffect::TestCreate(SkRandom* random,
262b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                               GrContext*,
263b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                               const GrDrawTargetCaps& caps,
264b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                               GrTexture*[]) {
265d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    SkPoint center;
266d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    center.fX = random->nextRangeScalar(0.f, 1000.f);
267d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    center.fY = random->nextRangeScalar(0.f, 1000.f);
268d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    SkScalar rx = random->nextRangeF(0.f, 1000.f);
269d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    SkScalar ry = random->nextRangeF(0.f, 1000.f);
270b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrPrimitiveEdgeType et;
271d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    do {
272b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        et = (GrPrimitiveEdgeType)random->nextULessThan(kGrProcessorEdgeTypeCnt);
273b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    } while (kHairlineAA_GrProcessorEdgeType == et);
274d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    return EllipseEffect::Create(et, center, rx, ry);
275d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org}
276d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
277d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
278d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
279b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GLEllipseEffect : public GrGLFragmentProcessor {
280d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.orgpublic:
281eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLEllipseEffect(const GrProcessor&);
282d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
2831598899975ecc85b003a59740b588d1ddbcedb09joshualitt    virtual void emitCode(GrGLFPBuilder* builder,
284b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrFragmentProcessor& fp,
285d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org                          const char* outputColor,
286d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org                          const char* inputColor,
287d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org                          const TransformedCoordsArray&,
28836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                          const TextureSamplerArray&) override;
289d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
290cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
291d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
29236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
293d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
294d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.orgprivate:
2957510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    GrGLProgramDataManager::UniformHandle fEllipseUniform;
2967510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    SkPoint                               fPrevCenter;
2977510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    SkVector                              fPrevRadii;
298d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
299b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrGLFragmentProcessor INHERITED;
300d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org};
301d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
302eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGLEllipseEffect::GLEllipseEffect(const GrProcessor& effect) {
303d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    fPrevRadii.fX = -1.f;
304d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org}
305d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
3061598899975ecc85b003a59740b588d1ddbcedb09joshualittvoid GLEllipseEffect::emitCode(GrGLFPBuilder* builder,
307b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                               const GrFragmentProcessor& fp,
308d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org                               const char* outputColor,
309d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org                               const char* inputColor,
310d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org                               const TransformedCoordsArray&,
311d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org                               const TextureSamplerArray& samplers) {
312b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const EllipseEffect& ee = fp.cast<EllipseEffect>();
313d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    const char *ellipseName;
314d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    // The ellipse uniform is (center.x, center.y, 1 / rx^2, 1 / ry^2)
31530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fEllipseUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
316422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon                                         kVec4f_GrSLType, kDefault_GrSLPrecision,
317d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org                                         "ellipse",
318d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org                                         &ellipseName);
31930ba436f04e61d4505fb854d5fc56079636e0788joshualitt
32029bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel    GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
32130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    const char* fragmentPos = fsBuilder->fragmentPosition();
322d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
323d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    // d is the offset to the ellipse center
32430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\t\tvec2 d = %s.xy - %s.xy;\n", fragmentPos, ellipseName);
32530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\t\tvec2 Z = d * %s.zw;\n", ellipseName);
326d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1.
32730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, d) - 1.0;\n");
328d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    // grad_dot is the squared length of the gradient of the implicit.
32930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
3301b035d82d2b8b50ae334463edd06e4c5e0639311commit-bot@chromium.org    // avoid calling inversesqrt on zero.
33130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
33230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
333d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
334d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    switch (ee.getEdgeType()) {
335b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        case kFillAA_GrProcessorEdgeType:
33630ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
337d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org            break;
338b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        case kInverseFillAA_GrProcessorEdgeType:
33930ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
340d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org            break;
341b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        case kFillBW_GrProcessorEdgeType:
34230ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 0.0 : 1.0;\n");
343d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org            break;
344b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        case kInverseFillBW_GrProcessorEdgeType:
34530ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 1.0 : 0.0;\n");
346d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org            break;
347b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        case kHairlineAA_GrProcessorEdgeType:
34888cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org            SkFAIL("Hairline not expected here.");
349d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    }
350d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
35130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor,
352d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org                           (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
353d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org}
354d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
355cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid GLEllipseEffect::GenKey(const GrProcessor& effect, const GrGLSLCaps&,
356b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                             GrProcessorKeyBuilder* b) {
35749586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const EllipseEffect& ee = effect.cast<EllipseEffect>();
35863e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    b->add32(ee.getEdgeType());
359d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org}
360d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
361b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLEllipseEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& effect) {
36249586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const EllipseEffect& ee = effect.cast<EllipseEffect>();
363d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    if (ee.getRadii() != fPrevRadii || ee.getCenter() != fPrevCenter) {
364d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org        SkScalar invRXSqd = 1.f / (ee.getRadii().fX * ee.getRadii().fX);
365d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org        SkScalar invRYSqd = 1.f / (ee.getRadii().fY * ee.getRadii().fY);
3667510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set4f(fEllipseUniform, ee.getCenter().fX, ee.getCenter().fY, invRXSqd, invRYSqd);
367d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org        fPrevCenter = ee.getCenter();
368d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org        fPrevRadii = ee.getRadii();
369d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    }
370d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org}
371d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org
372eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt///////////////////////////////////////////////////////////////////////////////////////////////////
373eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
374cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid EllipseEffect::getGLProcessorKey(const GrGLSLCaps& caps,
375eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt                                     GrProcessorKeyBuilder* b) const {
376eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLEllipseEffect::GenKey(*this, caps, b);
377eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
378eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
379eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrGLFragmentProcessor* EllipseEffect::createGLInstance() const  {
380eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    return SkNEW_ARGS(GLEllipseEffect, (*this));
381eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
382eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
3833eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
3843eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
385b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrOvalEffect::Create(GrPrimitiveEdgeType edgeType, const SkRect& oval) {
386b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    if (kHairlineAA_GrProcessorEdgeType == edgeType) {
3873eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org        return NULL;
3883eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    }
3893eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    SkScalar w = oval.width();
3903eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    SkScalar h = oval.height();
3913eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    if (SkScalarNearlyEqual(w, h)) {
3923eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org        w /= 2;
3933eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org        return CircleEffect::Create(edgeType, SkPoint::Make(oval.fLeft + w, oval.fTop + w), w);
394d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org    } else {
395d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org        w /= 2;
396d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org        h /= 2;
397d0a502968c3fc7f03afbe07211e36d3eeaa83694commit-bot@chromium.org        return EllipseEffect::Create(edgeType, SkPoint::Make(oval.fLeft + w, oval.fTop + h), w, h);
3983eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    }
3993eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
4003eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    return NULL;
4013eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org}
402