1c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org/*
2c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org * Copyright 2014 Google Inc.
3c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org *
4c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
5c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org * found in the LICENSE file.
6c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org */
7c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
8c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org#include "GrRRectEffect.h"
9c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
102a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org#include "GrConvexPolyEffect.h"
11eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "GrFragmentProcessor.h"
123eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org#include "GrOvalEffect.h"
1394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon#include "GrShaderCaps.h"
14e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org#include "SkRRect.h"
157ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "SkTLazy.h"
1664c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLFragmentProcessor.h"
172d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h"
18018fb62d12d1febf121fe265da5b6117b86a6541egdaniel#include "glsl/GrGLSLProgramDataManager.h"
197ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLUniformHandler.h"
20c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
212a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org// The effects defined here only handle rrect radii >= kRadiusMin.
222a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.orgstatic const SkScalar kRadiusMin = SK_ScalarHalf;
232a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org
242a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
252a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org
26b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass CircularRRectEffect : public GrFragmentProcessor {
27e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.orgpublic:
28f1f66c0c8623805fdb88f09c0d87cbdd1745e12bskia.committer@gmail.com
29dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org    enum CornerFlags {
30dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org        kTopLeft_CornerFlag     = (1 << SkRRect::kUpperLeft_Corner),
31dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org        kTopRight_CornerFlag    = (1 << SkRRect::kUpperRight_Corner),
32dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org        kBottomRight_CornerFlag = (1 << SkRRect::kLowerRight_Corner),
33dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org        kBottomLeft_CornerFlag  = (1 << SkRRect::kLowerLeft_Corner),
34dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org
35dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org        kLeft_CornerFlags   = kTopLeft_CornerFlag    | kBottomLeft_CornerFlag,
36dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org        kTop_CornerFlags    = kTopLeft_CornerFlag    | kTopRight_CornerFlag,
37dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org        kRight_CornerFlags  = kTopRight_CornerFlag   | kBottomRight_CornerFlag,
38dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org        kBottom_CornerFlags = kBottomLeft_CornerFlag | kBottomRight_CornerFlag,
39dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org
40dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org        kAll_CornerFlags = kTopLeft_CornerFlag    | kTopRight_CornerFlag |
41dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org                           kBottomLeft_CornerFlag | kBottomRight_CornerFlag,
42dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org
432a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org        kNone_CornerFlags = 0
44cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org    };
45cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org
46dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org    // The flags are used to indicate which corners are circluar (unflagged corners are assumed to
47dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org    // be square).
4806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    static sk_sp<GrFragmentProcessor> Make(GrPrimitiveEdgeType, uint32_t circularCornerFlags,
4906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                           const SkRRect&);
50e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
51d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon    ~CircularRRectEffect() override {}
52eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
5336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "CircularRRect"; }
54eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
55e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org    const SkRRect& getRRect() const { return fRRect; }
56e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
57dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org    uint32_t getCircularCornerFlags() const { return fCircularCornerFlags; }
5806acb58074778d8eb40f14ae72b000d5120a8111skia.committer@gmail.com
59b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
60cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org
61e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.orgprivate:
62b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    CircularRRectEffect(GrPrimitiveEdgeType, uint32_t circularCornerFlags, const SkRRect&);
63e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
6457d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
65b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
6694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
674b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix
6836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrFragmentProcessor& other) const override;
69e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
70b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    SkRRect                fRRect;
71b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrPrimitiveEdgeType    fEdgeType;
72b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    uint32_t               fCircularCornerFlags;
73e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
74b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
75e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
76b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrFragmentProcessor INHERITED;
77e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org};
78e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
7906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrFragmentProcessor> CircularRRectEffect::Make(GrPrimitiveEdgeType edgeType,
8006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                                     uint32_t circularCornerFlags,
8106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                                     const SkRRect& rrect) {
82b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    if (kFillAA_GrProcessorEdgeType != edgeType && kInverseFillAA_GrProcessorEdgeType != edgeType) {
8396fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
843eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    }
8506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    return sk_sp<GrFragmentProcessor>(
8606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        new CircularRRectEffect(edgeType, circularCornerFlags, rrect));
87e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org}
88e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
89b0a8a377f832c59cee939ad721e1f87d378b7142joshualittCircularRRectEffect::CircularRRectEffect(GrPrimitiveEdgeType edgeType, uint32_t circularCornerFlags,
90b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                         const SkRRect& rrect)
91f3b995b628ef76bff28b9721dd1e182336156086Brian Salomon        : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
92587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon        , fRRect(rrect)
93587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon        , fEdgeType(edgeType)
94587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon        , fCircularCornerFlags(circularCornerFlags) {
95eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    this->initClassID<CircularRRectEffect>();
96e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org}
97e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
980e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool CircularRRectEffect::onIsEqual(const GrFragmentProcessor& other) const {
9949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const CircularRRectEffect& crre = other.cast<CircularRRectEffect>();
1004355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // The corner flags are derived from fRRect, so no need to check them.
1014355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    return fEdgeType == crre.fEdgeType && fRRect == crre.fRRect;
102e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org}
103e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
104e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
105e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
106b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircularRRectEffect);
107e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
1086f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#if GR_TEST_UTILS
10906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrFragmentProcessor> CircularRRectEffect::TestCreate(GrProcessorTestData* d) {
1100067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkScalar w = d->fRandom->nextRangeScalar(20.f, 1000.f);
1110067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkScalar h = d->fRandom->nextRangeScalar(20.f, 1000.f);
1120067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkScalar r = d->fRandom->nextRangeF(kRadiusMin, 9.f);
113e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org    SkRRect rrect;
114e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org    rrect.setRectXY(SkRect::MakeWH(w, h), r, r);
11506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    sk_sp<GrFragmentProcessor> fp;
116cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org    do {
117b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        GrPrimitiveEdgeType et =
1180067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                (GrPrimitiveEdgeType)d->fRandom->nextULessThan(kGrProcessorEdgeTypeCnt);
11906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        fp = GrRRectEffect::Make(et, rrect);
12096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    } while (nullptr == fp);
121b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return fp;
122e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org}
1236f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#endif
124c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
125c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
126e5280893f8f9f6b6149572a4c8fe513f9c2b3888commit-bot@chromium.org
12764c4728c70001ed074fecf5c4e083781987b12e9egdanielclass GLCircularRRectEffect : public GrGLSLFragmentProcessor {
128c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.orgpublic:
1299cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips    GLCircularRRectEffect() {
1309cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips        fPrevRRect.setEmpty();
1319cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips    }
132c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
1337c157a988845fb00f9024d6db6dda142c3458033wangyix    virtual void emitCode(EmitArgs&) override;
134c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
13594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    static inline void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*);
136c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
137b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyixprotected:
138018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
139c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
140c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.orgprivate:
141018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    GrGLSLProgramDataManager::UniformHandle fInnerRectUniform;
142018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    GrGLSLProgramDataManager::UniformHandle fRadiusPlusHalfUniform;
143bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips    SkRRect                                 fPrevRRect;
14464c4728c70001ed074fecf5c4e083781987b12e9egdaniel    typedef GrGLSLFragmentProcessor INHERITED;
145c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org};
146c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
1477c157a988845fb00f9024d6db6dda142c3458033wangyixvoid GLCircularRRectEffect::emitCode(EmitArgs& args) {
1487c157a988845fb00f9024d6db6dda142c3458033wangyix    const CircularRRectEffect& crre = args.fFp.cast<CircularRRectEffect>();
1497ea439b2203855db97330b25945b87dd4b170b8begdaniel    GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
150c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    const char *rectName;
151c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    const char *radiusPlusHalfName;
152c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org    // The inner rect is the rrect bounds inset by the radius. Its left, top, right, and bottom
153c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org    // edges correspond to components x, y, z, and w, respectively. When a side of the rrect has
154c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org    // only rectangular corners, that side's value corresponds to the rect edge's value outset by
155c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org    // half a pixel.
1565e58ceea8569f0d90ff7e3daf5de2def50407212cdalton    fInnerRectUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
1577ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                   kVec4f_GrSLType, kDefault_GrSLPrecision,
1587ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                   "innerRect",
1597ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                   &rectName);
160cd0749144383d78a10a5df00e2e96e76456b412bbsalomon    // x is (r + .5) and y is 1/(r + .5)
1615e58ceea8569f0d90ff7e3daf5de2def50407212cdalton    fRadiusPlusHalfUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
162cd0749144383d78a10a5df00e2e96e76456b412bbsalomon                                                        kVec2f_GrSLType, kDefault_GrSLPrecision,
1637ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                        "radiusPlusHalf",
1647ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                        &radiusPlusHalfName);
1652d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel
166cd0749144383d78a10a5df00e2e96e76456b412bbsalomon    // If we're on a device with a "real" mediump then the length calculation could overflow.
167cd0749144383d78a10a5df00e2e96e76456b412bbsalomon    SkString clampedCircleDistance;
1681edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    if (args.fShaderCaps->floatPrecisionVaries()) {
169cd0749144383d78a10a5df00e2e96e76456b412bbsalomon        clampedCircleDistance.printf("clamp(%s.x * (1.0 - length(dxy * %s.y)), 0.0, 1.0);",
170cd0749144383d78a10a5df00e2e96e76456b412bbsalomon                                     radiusPlusHalfName, radiusPlusHalfName);
171cd0749144383d78a10a5df00e2e96e76456b412bbsalomon    } else {
172cd0749144383d78a10a5df00e2e96e76456b412bbsalomon        clampedCircleDistance.printf("clamp(%s.x - length(dxy), 0.0, 1.0);", radiusPlusHalfName);
173cd0749144383d78a10a5df00e2e96e76456b412bbsalomon    }
174cd0749144383d78a10a5df00e2e96e76456b412bbsalomon
1758528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
176c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    // At each quarter-circle corner we compute a vector that is the offset of the fragment position
177c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    // from the circle center. The vector is pinned in x and y to be in the quarter-plane relevant
178c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    // to that corner. This means that points near the interior near the rrect top edge will have
179c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    // a vector that points straight up for both the TL left and TR corners. Computing an
180c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    // alpha from this vector at either the TR or TL corner will give the correct result. Similarly,
181c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    // fragments near the other three edges will get the correct AA. Fragments in the interior of
182c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    // the rrect will have a (0,0) vector at all four corners. So long as the radius > 0.5 they will
183c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    // correctly produce an alpha value of 1 at all four corners. We take the min of all the alphas.
184c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    // The code below is a simplified version of the above that performs maxs on the vector
185c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    // components before computing distances and alpha values so that only one distance computation
186c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    // need be computed to determine the min alpha.
187cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org    //
188cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org    // For the cases where one half of the rrect is rectangular we drop one of the x or y
189cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org    // computations, compute a separate rect edge alpha for the rect side, and mul the two computed
190cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org    // alphas together.
1914355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    switch (crre.getCircularCornerFlags()) {
1924355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        case CircularRRectEffect::kAll_CornerFlags:
1933865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
1943865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("vec2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
195cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppend("vec2 dxy = max(max(dxy0, dxy1), 0.0);");
196cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppendf("float alpha = %s;", clampedCircleDistance.c_str());
197cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org            break;
1984355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        case CircularRRectEffect::kTopLeft_CornerFlag:
1993865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("vec2 dxy = max(%s.xy - sk_FragCoord.xy, 0.0);",
2003865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
2013865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
2023865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
2033865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
2043865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
205cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppendf("float alpha = bottomAlpha * rightAlpha * %s;",
206cd0749144383d78a10a5df00e2e96e76456b412bbsalomon                                     clampedCircleDistance.c_str());
207c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org            break;
2084355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        case CircularRRectEffect::kTopRight_CornerFlag:
2093865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("vec2 dxy = max(vec2(sk_FragCoord.x - %s.z, "
2103865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                                         "%s.y - sk_FragCoord.y), 0.0);",
2113865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName, rectName);
2123865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
2133865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
2143865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
2153865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
216cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppendf("float alpha = bottomAlpha * leftAlpha * %s;",
217cd0749144383d78a10a5df00e2e96e76456b412bbsalomon                                     clampedCircleDistance.c_str());
218c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org            break;
2194355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        case CircularRRectEffect::kBottomRight_CornerFlag:
2203865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("vec2 dxy = max(sk_FragCoord.xy - %s.zw, 0.0);",
2213865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
2223865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
2233865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
2243865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
2253865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
226cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppendf("float alpha = topAlpha * leftAlpha * %s;",
227cd0749144383d78a10a5df00e2e96e76456b412bbsalomon                                     clampedCircleDistance.c_str());
228c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org            break;
2294355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        case CircularRRectEffect::kBottomLeft_CornerFlag:
2303865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("vec2 dxy = max(vec2(%s.x - sk_FragCoord.x, sk_FragCoord.y - "
2313865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     "%s.w), 0.0);",
2323865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName, rectName);
2333865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
2343865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
2353865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
2363865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
237cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppendf("float alpha = topAlpha * rightAlpha * %s;",
238cd0749144383d78a10a5df00e2e96e76456b412bbsalomon                                     clampedCircleDistance.c_str());
239c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org            break;
2404355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        case CircularRRectEffect::kLeft_CornerFlags:
2413865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
2423865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float dy1 = sk_FragCoord.y - %s.w;", rectName);
243cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppend("vec2 dxy = max(vec2(dxy0.x, max(dxy0.y, dy1)), 0.0);");
2443865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
2453865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
246cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppendf("float alpha = rightAlpha * %s;",
247cd0749144383d78a10a5df00e2e96e76456b412bbsalomon                                     clampedCircleDistance.c_str());
248cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org            break;
2494355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        case CircularRRectEffect::kTop_CornerFlags:
2503865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
2513865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float dx1 = sk_FragCoord.x - %s.z;", rectName);
252cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppend("vec2 dxy = max(vec2(max(dxy0.x, dx1), dxy0.y), 0.0);");
2533865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
2543865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
255cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppendf("float alpha = bottomAlpha * %s;",
256cd0749144383d78a10a5df00e2e96e76456b412bbsalomon                                     clampedCircleDistance.c_str());
257cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org            break;
2584355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        case CircularRRectEffect::kRight_CornerFlags:
2593865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float dy0 = %s.y - sk_FragCoord.y;", rectName);
2603865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("vec2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
261cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppend("vec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1.y)), 0.0);");
2623865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
2633865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
264cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppendf("float alpha = leftAlpha * %s;",
265cd0749144383d78a10a5df00e2e96e76456b412bbsalomon                                     clampedCircleDistance.c_str());
266cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org            break;
2674355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        case CircularRRectEffect::kBottom_CornerFlags:
2683865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float dx0 = %s.x - sk_FragCoord.x;", rectName);
2693865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("vec2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
270cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppend("vec2 dxy = max(vec2(max(dx0, dxy1.x), dxy1.y), 0.0);");
2713865711259e25a90a1d72480f848863ada202067Ethan Nicholas            fragBuilder->codeAppendf("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
2723865711259e25a90a1d72480f848863ada202067Ethan Nicholas                                     rectName);
273cd0749144383d78a10a5df00e2e96e76456b412bbsalomon            fragBuilder->codeAppendf("float alpha = topAlpha * %s;",
274cd0749144383d78a10a5df00e2e96e76456b412bbsalomon                                     clampedCircleDistance.c_str());
275cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org            break;
276cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org    }
27706acb58074778d8eb40f14ae72b000d5120a8111skia.committer@gmail.com
278b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    if (kInverseFillAA_GrProcessorEdgeType == crre.getEdgeType()) {
279cd0749144383d78a10a5df00e2e96e76456b412bbsalomon        fragBuilder->codeAppend("alpha = 1.0 - alpha;");
280fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org    }
281c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
282cd0749144383d78a10a5df00e2e96e76456b412bbsalomon    fragBuilder->codeAppendf("%s = %s;", args.fOutputColor,
2834ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                             (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
284c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org}
285c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
28694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomonvoid GLCircularRRectEffect::GenKey(const GrProcessor& processor, const GrShaderCaps&,
287b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                   GrProcessorKeyBuilder* b) {
288b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const CircularRRectEffect& crre = processor.cast<CircularRRectEffect>();
289b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_STATIC_ASSERT(kGrProcessorEdgeTypeCnt <= 8);
29063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType());
291cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org}
292cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org
293018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GLCircularRRectEffect::onSetData(const GrGLSLProgramDataManager& pdman,
294018fb62d12d1febf121fe265da5b6117b86a6541egdaniel                                      const GrProcessor& processor) {
295b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const CircularRRectEffect& crre = processor.cast<CircularRRectEffect>();
2964355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    const SkRRect& rrect = crre.getRRect();
297c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    if (rrect != fPrevRRect) {
298c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org        SkRect rect = rrect.getBounds();
299cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org        SkScalar radius = 0;
3004355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        switch (crre.getCircularCornerFlags()) {
3014355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kAll_CornerFlags:
302cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                SkASSERT(rrect.isSimpleCircular());
303cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                radius = rrect.getSimpleRadii().fX;
3042a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                SkASSERT(radius >= kRadiusMin);
305cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.inset(radius, radius);
306cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                break;
3074355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kTopLeft_CornerFlag:
308c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX;
309c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                rect.fLeft += radius;
310c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                rect.fTop += radius;
311c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                rect.fRight += 0.5f;
312c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                rect.fBottom += 0.5f;
313c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                break;
3144355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kTopRight_CornerFlag:
315c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                radius = rrect.radii(SkRRect::kUpperRight_Corner).fX;
316de9f251427ccb35fa4d55b5efc97c1b31721cf78bsalomon@google.com                rect.fLeft -= 0.5f;
317c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                rect.fTop += radius;
318c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                rect.fRight -= radius;
319c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                rect.fBottom += 0.5f;
320c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                break;
3214355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kBottomRight_CornerFlag:
322c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                radius = rrect.radii(SkRRect::kLowerRight_Corner).fX;
323de9f251427ccb35fa4d55b5efc97c1b31721cf78bsalomon@google.com                rect.fLeft -= 0.5f;
324de9f251427ccb35fa4d55b5efc97c1b31721cf78bsalomon@google.com                rect.fTop -= 0.5f;
325c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                rect.fRight -= radius;
326c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                rect.fBottom -= radius;
327c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                break;
3284355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kBottomLeft_CornerFlag:
329c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                radius = rrect.radii(SkRRect::kLowerLeft_Corner).fX;
330c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                rect.fLeft += radius;
331de9f251427ccb35fa4d55b5efc97c1b31721cf78bsalomon@google.com                rect.fTop -= 0.5f;
332de9f251427ccb35fa4d55b5efc97c1b31721cf78bsalomon@google.com                rect.fRight += 0.5f;
333c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                rect.fBottom -= radius;
334c5c748c14797ae49ba73999a63e3b07315c888e1commit-bot@chromium.org                break;
3354355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kLeft_CornerFlags:
336cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX;
337cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fLeft += radius;
338cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fTop += radius;
339cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fRight += 0.5f;
340cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fBottom -= radius;
341cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                break;
3424355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kTop_CornerFlags:
343cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX;
344cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fLeft += radius;
345cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fTop += radius;
346cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fRight -= radius;
347cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fBottom += 0.5f;
348cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                break;
3494355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kRight_CornerFlags:
350cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                radius = rrect.radii(SkRRect::kUpperRight_Corner).fX;
351cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fLeft -= 0.5f;
352cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fTop += radius;
353cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fRight -= radius;
354cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fBottom -= radius;
355cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                break;
3564355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kBottom_CornerFlags:
357cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                radius = rrect.radii(SkRRect::kLowerLeft_Corner).fX;
358cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fLeft += radius;
359cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fTop -= 0.5f;
360cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fRight -= radius;
361cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                rect.fBottom -= radius;
362cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                break;
363dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org            default:
36488cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org                SkFAIL("Should have been one of the above cases.");
365cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org        }
3667510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
367cd0749144383d78a10a5df00e2e96e76456b412bbsalomon        radius += 0.5f;
368cd0749144383d78a10a5df00e2e96e76456b412bbsalomon        pdman.set2f(fRadiusPlusHalfUniform, radius, 1.f / radius);
369c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org        fPrevRRect = rrect;
370c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    }
371c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org}
372c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
373eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt////////////////////////////////////////////////////////////////////////////////////////////////////
374c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org
37594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomonvoid CircularRRectEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
37657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel                                                GrProcessorKeyBuilder* b) const {
377eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLCircularRRectEffect::GenKey(*this, caps, b);
378eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
379eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
38057d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* CircularRRectEffect::onCreateGLSLInstance() const  {
3819cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips    return new GLCircularRRectEffect;
382eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
383eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
384eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt//////////////////////////////////////////////////////////////////////////////
3854355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
386b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass EllipticalRRectEffect : public GrFragmentProcessor {
3874355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.orgpublic:
38806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    static sk_sp<GrFragmentProcessor> Make(GrPrimitiveEdgeType, const SkRRect&);
3894355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
390d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon    ~EllipticalRRectEffect() override {}
3914355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
39236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "EllipticalRRect"; }
3934355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
394eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    const SkRRect& getRRect() const { return fRRect; }
3954355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
396eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
3974355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
3984355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.orgprivate:
399b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    EllipticalRRectEffect(GrPrimitiveEdgeType, const SkRRect&);
4004355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
40157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
402b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
40394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
4044b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix
40536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrFragmentProcessor& other) const override;
4064355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
407587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon    SkRRect fRRect;
408587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon    GrPrimitiveEdgeType fEdgeType;
4094355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
410b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
4114355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
412b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrFragmentProcessor INHERITED;
4134355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org};
4144355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
41506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrFragmentProcessor>
41606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemanEllipticalRRectEffect::Make(GrPrimitiveEdgeType edgeType, const SkRRect& rrect) {
417b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    if (kFillAA_GrProcessorEdgeType != edgeType && kInverseFillAA_GrProcessorEdgeType != edgeType) {
41896fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
4193eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    }
42006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    return sk_sp<GrFragmentProcessor>(new EllipticalRRectEffect(edgeType, rrect));
4214355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org}
4224355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
423b0a8a377f832c59cee939ad721e1f87d378b7142joshualittEllipticalRRectEffect::EllipticalRRectEffect(GrPrimitiveEdgeType edgeType, const SkRRect& rrect)
424f3b995b628ef76bff28b9721dd1e182336156086Brian Salomon        : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
425f3b995b628ef76bff28b9721dd1e182336156086Brian Salomon        , fRRect(rrect)
426f3b995b628ef76bff28b9721dd1e182336156086Brian Salomon        , fEdgeType(edgeType) {
427eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    this->initClassID<EllipticalRRectEffect>();
4284355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org}
4294355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
4300e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool EllipticalRRectEffect::onIsEqual(const GrFragmentProcessor& other) const {
43149586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const EllipticalRRectEffect& erre = other.cast<EllipticalRRectEffect>();
4324355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    return fEdgeType == erre.fEdgeType && fRRect == erre.fRRect;
4334355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org}
4344355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
4354355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
4364355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
437b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(EllipticalRRectEffect);
4384355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
4396f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#if GR_TEST_UTILS
44006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrFragmentProcessor> EllipticalRRectEffect::TestCreate(GrProcessorTestData* d) {
4410067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkScalar w = d->fRandom->nextRangeScalar(20.f, 1000.f);
4420067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkScalar h = d->fRandom->nextRangeScalar(20.f, 1000.f);
443fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org    SkVector r[4];
4440067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    r[SkRRect::kUpperLeft_Corner].fX = d->fRandom->nextRangeF(kRadiusMin, 9.f);
445fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org    // ensure at least one corner really is elliptical
446fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org    do {
4470067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        r[SkRRect::kUpperLeft_Corner].fY = d->fRandom->nextRangeF(kRadiusMin, 9.f);
448fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org    } while (r[SkRRect::kUpperLeft_Corner].fY == r[SkRRect::kUpperLeft_Corner].fX);
449fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org
4504355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    SkRRect rrect;
4510067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    if (d->fRandom->nextBool()) {
452fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org        // half the time create a four-radii rrect.
4530067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        r[SkRRect::kLowerRight_Corner].fX = d->fRandom->nextRangeF(kRadiusMin, 9.f);
4540067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        r[SkRRect::kLowerRight_Corner].fY = d->fRandom->nextRangeF(kRadiusMin, 9.f);
455fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org
456fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org        r[SkRRect::kUpperRight_Corner].fX = r[SkRRect::kLowerRight_Corner].fX;
457fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org        r[SkRRect::kUpperRight_Corner].fY = r[SkRRect::kUpperLeft_Corner].fY;
458fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org
459fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org        r[SkRRect::kLowerLeft_Corner].fX = r[SkRRect::kUpperLeft_Corner].fX;
460fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org        r[SkRRect::kLowerLeft_Corner].fY = r[SkRRect::kLowerRight_Corner].fY;
461fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org
462fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org        rrect.setRectRadii(SkRect::MakeWH(w, h), r);
463fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org    } else {
464fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org        rrect.setRectXY(SkRect::MakeWH(w, h), r[SkRRect::kUpperLeft_Corner].fX,
465fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                                              r[SkRRect::kUpperLeft_Corner].fY);
466fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org    }
46706ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    sk_sp<GrFragmentProcessor> fp;
4684355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    do {
4690067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        GrPrimitiveEdgeType et =
4700067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                (GrPrimitiveEdgeType)d->fRandom->nextULessThan(kGrProcessorEdgeTypeCnt);
47106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        fp = GrRRectEffect::Make(et, rrect);
47296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    } while (nullptr == fp);
473b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return fp;
4744355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org}
4756f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#endif
4764355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
4774355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
4784355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
47964c4728c70001ed074fecf5c4e083781987b12e9egdanielclass GLEllipticalRRectEffect : public GrGLSLFragmentProcessor {
4804355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.orgpublic:
4819cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips    GLEllipticalRRectEffect() {
4829cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips        fPrevRRect.setEmpty();
4839cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips    }
4844355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
4859cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips    void emitCode(EmitArgs&) override;
4864355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
48794efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    static inline void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*);
4884355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
489b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyixprotected:
490018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
4914355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
4924355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.orgprivate:
493018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    GrGLSLProgramDataManager::UniformHandle fInnerRectUniform;
494018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    GrGLSLProgramDataManager::UniformHandle fInvRadiiSqdUniform;
495e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    GrGLSLProgramDataManager::UniformHandle fScaleUniform;
496e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    SkRRect                                 fPrevRRect;
49764c4728c70001ed074fecf5c4e083781987b12e9egdaniel    typedef GrGLSLFragmentProcessor INHERITED;
4984355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org};
4994355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
5007c157a988845fb00f9024d6db6dda142c3458033wangyixvoid GLEllipticalRRectEffect::emitCode(EmitArgs& args) {
5017c157a988845fb00f9024d6db6dda142c3458033wangyix    const EllipticalRRectEffect& erre = args.fFp.cast<EllipticalRRectEffect>();
5027ea439b2203855db97330b25945b87dd4b170b8begdaniel    GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
5034355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    const char *rectName;
5044355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // The inner rect is the rrect bounds inset by the x/y radii
5055e58ceea8569f0d90ff7e3daf5de2def50407212cdalton    fInnerRectUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
5067ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                   kVec4f_GrSLType, kDefault_GrSLPrecision,
5077ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                   "innerRect",
5087ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                   &rectName);
50930ba436f04e61d4505fb854d5fc56079636e0788joshualitt
5108528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
5114355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // At each quarter-ellipse corner we compute a vector that is the offset of the fragment pos
5124355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // to the ellipse center. The vector is pinned in x and y to be in the quarter-plane relevant
5134355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // to that corner. This means that points near the interior near the rrect top edge will have
5144355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // a vector that points straight up for both the TL left and TR corners. Computing an
5154355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // alpha from this vector at either the TR or TL corner will give the correct result. Similarly,
5164355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // fragments near the other three edges will get the correct AA. Fragments in the interior of
5174355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // the rrect will have a (0,0) vector at all four corners. So long as the radii > 0.5 they will
5184355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // correctly produce an alpha value of 1 at all four corners. We take the min of all the alphas.
519c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon    //
5204355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // The code below is a simplified version of the above that performs maxs on the vector
5214355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // components before computing distances and alpha values so that only one distance computation
5224355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // need be computed to determine the min alpha.
5233865711259e25a90a1d72480f848863ada202067Ethan Nicholas    fragBuilder->codeAppendf("vec2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
5243865711259e25a90a1d72480f848863ada202067Ethan Nicholas    fragBuilder->codeAppendf("vec2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
525e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon
526e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    // If we're on a device with a "real" mediump then we'll do the distance computation in a space
527e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    // that is normalized by the largest radius. The scale uniform will be scale, 1/scale. The
528e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    // radii uniform values are already in this normalized space.
529e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    const char* scaleName = nullptr;
5301edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon    if (args.fShaderCaps->floatPrecisionVaries()) {
5315e58ceea8569f0d90ff7e3daf5de2def50407212cdalton        fScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
532e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                                                   kVec2f_GrSLType, kDefault_GrSLPrecision,
533e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                                                   "scale", &scaleName);
534e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    }
535e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon
536c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon    // The uniforms with the inv squared radii are highp to prevent underflow.
5379615d5fc040e7302ce870639ab221233f56fff7ccommit-bot@chromium.org    switch (erre.getRRect().getType()) {
5389615d5fc040e7302ce870639ab221233f56fff7ccommit-bot@chromium.org        case SkRRect::kSimple_Type: {
539fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org            const char *invRadiiXYSqdName;
5405e58ceea8569f0d90ff7e3daf5de2def50407212cdalton            fInvRadiiSqdUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
5415e58ceea8569f0d90ff7e3daf5de2def50407212cdalton                                                             kVec2f_GrSLType,
5425e58ceea8569f0d90ff7e3daf5de2def50407212cdalton                                                             kDefault_GrSLPrecision,
5435e58ceea8569f0d90ff7e3daf5de2def50407212cdalton                                                             "invRadiiXY",
5445e58ceea8569f0d90ff7e3daf5de2def50407212cdalton                                                             &invRadiiXYSqdName);
545e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon            fragBuilder->codeAppend("vec2 dxy = max(max(dxy0, dxy1), 0.0);");
546e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon            if (scaleName) {
547e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                fragBuilder->codeAppendf("dxy *= %s.y;", scaleName);
548e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon            }
549fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org            // Z is the x/y offsets divided by squared radii.
550e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon            fragBuilder->codeAppendf("vec2 Z = dxy * %s.xy;", invRadiiXYSqdName);
551fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org            break;
552fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org        }
5539615d5fc040e7302ce870639ab221233f56fff7ccommit-bot@chromium.org        case SkRRect::kNinePatch_Type: {
554fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org            const char *invRadiiLTRBSqdName;
5555e58ceea8569f0d90ff7e3daf5de2def50407212cdalton            fInvRadiiSqdUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
5565e58ceea8569f0d90ff7e3daf5de2def50407212cdalton                                                             kVec4f_GrSLType,
5575e58ceea8569f0d90ff7e3daf5de2def50407212cdalton                                                             kDefault_GrSLPrecision,
5585e58ceea8569f0d90ff7e3daf5de2def50407212cdalton                                                             "invRadiiLTRB",
5595e58ceea8569f0d90ff7e3daf5de2def50407212cdalton                                                             &invRadiiLTRBSqdName);
560e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon            if (scaleName) {
561e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                fragBuilder->codeAppendf("dxy0 *= %s.y;", scaleName);
562e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                fragBuilder->codeAppendf("dxy1 *= %s.y;", scaleName);
563e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon            }
564e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon            fragBuilder->codeAppend("vec2 dxy = max(max(dxy0, dxy1), 0.0);");
565fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org            // Z is the x/y offsets divided by squared radii. We only care about the (at most) one
566fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org            // corner where both the x and y offsets are positive, hence the maxes. (The inverse
567fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org            // squared radii will always be positive.)
568e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon            fragBuilder->codeAppendf("vec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);",
5694ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     invRadiiLTRBSqdName, invRadiiLTRBSqdName);
570e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon
571fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org            break;
5729615d5fc040e7302ce870639ab221233f56fff7ccommit-bot@chromium.org        }
5739615d5fc040e7302ce870639ab221233f56fff7ccommit-bot@chromium.org        default:
57488cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org            SkFAIL("RRect should always be simple or nine-patch.");
575fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org    }
5764355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1.
577e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    fragBuilder->codeAppend("float implicit = dot(Z, dxy) - 1.0;");
5784355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    // grad_dot is the squared length of the gradient of the implicit.
579e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    fragBuilder->codeAppend("float grad_dot = 4.0 * dot(Z, Z);");
5801b035d82d2b8b50ae334463edd06e4c5e0639311commit-bot@chromium.org    // avoid calling inversesqrt on zero.
581e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
582e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    fragBuilder->codeAppend("float approx_dist = implicit * inversesqrt(grad_dot);");
583e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    if (scaleName) {
584e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon        fragBuilder->codeAppendf("approx_dist *= %s.x;", scaleName);
585e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    }
5864355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
587b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    if (kFillAA_GrProcessorEdgeType == erre.getEdgeType()) {
588e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon        fragBuilder->codeAppend("float alpha = clamp(0.5 - approx_dist, 0.0, 1.0);");
5894355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    } else {
590e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon        fragBuilder->codeAppend("float alpha = clamp(0.5 + approx_dist, 0.0, 1.0);");
5914355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    }
5924355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
593e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    fragBuilder->codeAppendf("%s = %s;", args.fOutputColor,
5944ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                             (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
5954355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org}
5964355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
59794efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomonvoid GLEllipticalRRectEffect::GenKey(const GrProcessor& effect, const GrShaderCaps&,
598b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                     GrProcessorKeyBuilder* b) {
59949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>();
600b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_STATIC_ASSERT(kLast_GrProcessorEdgeType < (1 << 3));
60163e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3);
6024355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org}
6034355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
604018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GLEllipticalRRectEffect::onSetData(const GrGLSLProgramDataManager& pdman,
605018fb62d12d1febf121fe265da5b6117b86a6541egdaniel                                        const GrProcessor& effect) {
60649586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>();
6074355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    const SkRRect& rrect = erre.getRRect();
608e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    // If we're using a scale factor to work around precision issues, choose the largest radius
609e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon    // as the scale factor. The inv radii need to be pre-adjusted by the scale factor.
6104355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    if (rrect != fPrevRRect) {
6114355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        SkRect rect = rrect.getBounds();
612fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org        const SkVector& r0 = rrect.radii(SkRRect::kUpperLeft_Corner);
6132a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org        SkASSERT(r0.fX >= kRadiusMin);
6142a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org        SkASSERT(r0.fY >= kRadiusMin);
6159615d5fc040e7302ce870639ab221233f56fff7ccommit-bot@chromium.org        switch (erre.getRRect().getType()) {
6169615d5fc040e7302ce870639ab221233f56fff7ccommit-bot@chromium.org            case SkRRect::kSimple_Type:
617fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                rect.inset(r0.fX, r0.fY);
618e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                if (fScaleUniform.isValid()) {
619e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                    if (r0.fX > r0.fY) {
620e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                        pdman.set2f(fInvRadiiSqdUniform, 1.f, (r0.fX * r0.fX) / (r0.fY * r0.fY));
621e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                        pdman.set2f(fScaleUniform, r0.fX, 1.f / r0.fX);
622e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                    } else {
623e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                        pdman.set2f(fInvRadiiSqdUniform, (r0.fY * r0.fY) / (r0.fX * r0.fX), 1.f);
624e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                        pdman.set2f(fScaleUniform, r0.fY, 1.f / r0.fY);
625e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                    }
626e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                } else {
627e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                    pdman.set2f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX),
628e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                                                     1.f / (r0.fY * r0.fY));
629e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                }
630fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                break;
6319615d5fc040e7302ce870639ab221233f56fff7ccommit-bot@chromium.org            case SkRRect::kNinePatch_Type: {
632fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                const SkVector& r1 = rrect.radii(SkRRect::kLowerRight_Corner);
6332a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                SkASSERT(r1.fX >= kRadiusMin);
6342a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                SkASSERT(r1.fY >= kRadiusMin);
635fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                rect.fLeft += r0.fX;
636fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                rect.fTop += r0.fY;
637fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                rect.fRight -= r1.fX;
638fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                rect.fBottom -= r1.fY;
639e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                if (fScaleUniform.isValid()) {
640e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                    float scale = SkTMax(SkTMax(r0.fX, r0.fY), SkTMax(r1.fX, r1.fY));
641e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                    float scaleSqd = scale * scale;
642e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                    pdman.set4f(fInvRadiiSqdUniform, scaleSqd / (r0.fX * r0.fX),
643e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                                                     scaleSqd / (r0.fY * r0.fY),
644e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                                                     scaleSqd / (r1.fX * r1.fX),
645e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                                                     scaleSqd / (r1.fY * r1.fY));
646e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                    pdman.set2f(fScaleUniform, scale, 1.f / scale);
647e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                } else {
648e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                    pdman.set4f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX),
649e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                                                     1.f / (r0.fY * r0.fY),
650e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                                                     1.f / (r1.fX * r1.fX),
651e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                                                     1.f / (r1.fY * r1.fY));
652e87256c46291f7ce10f1d9a1d691d01ecf4eb3ccbsalomon                }
653fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                break;
654fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org            }
6559615d5fc040e7302ce870639ab221233f56fff7ccommit-bot@chromium.org        default:
65688cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org            SkFAIL("RRect should always be simple or nine-patch.");
657fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org        }
6587510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
6594355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        fPrevRRect = rrect;
6604355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    }
6614355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org}
6624355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
663eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt////////////////////////////////////////////////////////////////////////////////////////////////////
664eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
66594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomonvoid EllipticalRRectEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
66657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel                                                  GrProcessorKeyBuilder* b) const {
667eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLEllipticalRRectEffect::GenKey(*this, caps, b);
668eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
669eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
67057d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* EllipticalRRectEffect::onCreateGLSLInstance() const  {
6719cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips    return new GLEllipticalRRectEffect;
672eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
673eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
6744355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
6754355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org
67606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrFragmentProcessor> GrRRectEffect::Make(GrPrimitiveEdgeType edgeType, const SkRRect& rrect) {
6772a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org    if (rrect.isRect()) {
67806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
6792a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org    }
6802a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org
6813eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    if (rrect.isOval()) {
68206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        return GrOvalEffect::Make(edgeType, rrect.getBounds());
6833eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org    }
6843eedb801e35001df4b7e154edf4fd8da942296a0commit-bot@chromium.org
6854355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org    if (rrect.isSimple()) {
6862a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org        if (rrect.getSimpleRadii().fX < kRadiusMin || rrect.getSimpleRadii().fY < kRadiusMin) {
6872a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            // In this case the corners are extremely close to rectangular and we collapse the
6882a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            // clip to a rectangular clip.
68906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
6902a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org        }
6914355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        if (rrect.getSimpleRadii().fX == rrect.getSimpleRadii().fY) {
69206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            return CircularRRectEffect::Make(edgeType, CircularRRectEffect::kAll_CornerFlags,
6932a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                                               rrect);
6944355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org        } else {
69506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            return EllipticalRRectEffect::Make(edgeType, rrect);
696cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org        }
6972a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org    }
6982a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org
6992a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org    if (rrect.isComplex() || rrect.isNinePatch()) {
700cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org        // Check for the "tab" cases - two adjacent circular corners and two square corners.
7012a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org        SkScalar circularRadius = 0;
7022a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org        uint32_t cornerFlags  = 0;
7032a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org
7042a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org        SkVector radii[4];
7052a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org        bool squashedRadii = false;
706cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org        for (int c = 0; c < 4; ++c) {
7072a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            radii[c] = rrect.radii((SkRRect::Corner)c);
7082a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            SkASSERT((0 == radii[c].fX) == (0 == radii[c].fY));
7092a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            if (0 == radii[c].fX) {
7102a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                // The corner is square, so no need to squash or flag as circular.
7112a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                continue;
7122a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            }
7132a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            if (radii[c].fX < kRadiusMin || radii[c].fY < kRadiusMin) {
7142a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                radii[c].set(0, 0);
7152a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                squashedRadii = true;
716cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                continue;
717cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org            }
7182a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            if (radii[c].fX != radii[c].fY) {
71944a435bc1ac84748d5bec420c7c5fe09171fd971bsalomon@google.com                cornerFlags = ~0U;
720fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                break;
721cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org            }
722dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org            if (!cornerFlags) {
7232a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                circularRadius = radii[c].fX;
724dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org                cornerFlags = 1 << c;
725cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org            } else {
7262a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                if (radii[c].fX != circularRadius) {
72744a435bc1ac84748d5bec420c7c5fe09171fd971bsalomon@google.com                   cornerFlags = ~0U;
728fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                   break;
729cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org                }
730dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org                cornerFlags |= 1 << c;
731cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org            }
732cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org        }
733cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org
734dd58422b4b2bffb0f7b5bdc047d0f93bd93813b4commit-bot@chromium.org        switch (cornerFlags) {
7352a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            case CircularRRectEffect::kAll_CornerFlags:
7362a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                // This rrect should have been caught in the simple case above. Though, it would
7372a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                // be correctly handled in the fallthrough code.
7382a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                SkASSERT(false);
7394355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kTopLeft_CornerFlag:
7404355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kTopRight_CornerFlag:
7414355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kBottomRight_CornerFlag:
7424355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kBottomLeft_CornerFlag:
7434355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kLeft_CornerFlags:
7444355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kTop_CornerFlags:
7454355f21dbc29bcb479a3806444dd22916e22771ecommit-bot@chromium.org            case CircularRRectEffect::kRight_CornerFlags:
7462a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            case CircularRRectEffect::kBottom_CornerFlags: {
7472a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                SkTCopyOnFirstWrite<SkRRect> rr(rrect);
7482a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                if (squashedRadii) {
7492a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                    rr.writable()->setRectRadii(rrect.getBounds(), radii);
7502a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                }
75106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                return CircularRRectEffect::Make(edgeType, cornerFlags, *rr);
7522a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            }
7532a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            case CircularRRectEffect::kNone_CornerFlags:
75406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
7552a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            default: {
7562a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                if (squashedRadii) {
7572a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                    // If we got here then we squashed some but not all the radii to zero. (If all
7582a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                    // had been squashed cornerFlags would be 0.) The elliptical effect doesn't
7592a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                    // support some rounded and some square corners.
76096fcdcc219d2a0d3579719b84b28bede76efba64halcanary                    return nullptr;
7612a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org                }
762fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                if (rrect.isNinePatch()) {
76306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                    return EllipticalRRectEffect::Make(edgeType, rrect);
764fa5edbe5750632b4590ed951c594dd2766ccc4cfcommit-bot@chromium.org                }
76596fcdcc219d2a0d3579719b84b28bede76efba64halcanary                return nullptr;
7662a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org            }
767cb3672ed7fb9a5d54849e3265e8399bc5224bacecommit-bot@chromium.org        }
768c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org    }
7692a8be900db664bb26dca1adcb3a524a1bb1f45e6commit-bot@chromium.org
77096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    return nullptr;
771c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org}
772