1c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
2aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org/*
3aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org * Copyright 2014 Google Inc.
4aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org *
5aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
6aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org * found in the LICENSE file.
7aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org */
82af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
9aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org#include "SkTwoPointConicalGradient_gpu.h"
10aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
11aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org#include "SkTwoPointConicalGradient.h"
12aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
13ef93d294ef545c91028262478e4f1c7c2ed456b8commit-bot@chromium.org#if SK_SUPPORT_GPU
147ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "GrCoordTransform.h"
157ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "GrInvariantOutput.h"
168ca93e7c733ab064c8a9e03715ac405ae739cf51joshualitt#include "GrPaint.h"
172d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h"
18018fb62d12d1febf121fe265da5b6117b86a6541egdaniel#include "glsl/GrGLSLProgramDataManager.h"
197ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLUniformHandler.h"
20aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org// For brevity
21018fb62d12d1febf121fe265da5b6117b86a6541egdanieltypedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
22aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
2380894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.orgstatic const SkScalar kErrorTol = 0.00001f;
248405ef9854858b2527bf03b7e7abb1c0da59411degdanielstatic const SkScalar kEdgeErrorTol = 5.f * kErrorTol;
25c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
26c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org/**
27c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org * We have three general cases for 2pt conical gradients. First we always assume that
28c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org * the start radius <= end radius. Our first case (kInside_) is when the start circle
29c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org * is completely enclosed by the end circle. The second case (kOutside_) is the case
30c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org * when the start circle is either completely outside the end circle or the circles
31c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org * overlap. The final case (kEdge_) is when the start circle is inside the end one,
32c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org * but the two are just barely touching at 1 point along their edges.
33c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org */
34c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgenum ConicalType {
35c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    kInside_ConicalType,
36c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    kOutside_ConicalType,
37c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    kEdge_ConicalType,
38c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
39c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
402af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
412af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
42c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgstatic void set_matrix_edge_conical(const SkTwoPointConicalGradient& shader,
43c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                    SkMatrix* invLMatrix) {
442af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // Inverse of the current local matrix is passed in then,
452af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // translate to center1, rotate so center2 is on x axis.
462af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    const SkPoint& center1 = shader.getStartCenter();
472af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    const SkPoint& center2 = shader.getEndCenter();
482af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
492af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    invLMatrix->postTranslate(-center1.fX, -center1.fY);
502af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
512af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkPoint diff = center2 - center1;
522af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar diffLen = diff.length();
532af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    if (0 != diffLen) {
542af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        SkScalar invDiffLen = SkScalarInvert(diffLen);
552af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        SkMatrix rot;
562af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        rot.setSinCos(-SkScalarMul(invDiffLen, diff.fY),
572af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org                       SkScalarMul(invDiffLen, diff.fX));
582af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        invLMatrix->postConcat(rot);
592af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    }
602af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org}
612af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
62c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass Edge2PtConicalEffect : public GrGradientEffect {
63aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.orgpublic:
64aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
65b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrContext* ctx,
66b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkTwoPointConicalGradient& shader,
67b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkMatrix& matrix,
68b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkShader::TileMode tm) {
694a339529612a43871d021877e58698e067d6c4cdbsalomon        return new Edge2PtConicalEffect(ctx, shader, matrix, tm);
702af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    }
712af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
72c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~Edge2PtConicalEffect() {}
732af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
7436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override {
75eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt        return "Two-Point Conical Gradient Edge Touching";
76eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    }
77eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
782af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
792af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar center() const { return fCenterX1; }
802af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar diffRadius() const { return fDiffRadius; }
812af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar radius() const { return fRadius0; }
822af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
832af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.orgprivate:
8457d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
85b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
8657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
874b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix
8836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrFragmentProcessor& sBase) const override {
8949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt        const Edge2PtConicalEffect& s = sBase.cast<Edge2PtConicalEffect>();
902af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        return (INHERITED::onIsEqual(sBase) &&
912af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org                this->fCenterX1 == s.fCenterX1 &&
922af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org                this->fRadius0 == s.fRadius0 &&
93c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fDiffRadius == s.fDiffRadius);
942af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    }
952af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
96c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    Edge2PtConicalEffect(GrContext* ctx,
97c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                         const SkTwoPointConicalGradient& shader,
98c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                         const SkMatrix& matrix,
99c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                         SkShader::TileMode tm)
1004a339529612a43871d021877e58698e067d6c4cdbsalomon        : INHERITED(ctx, shader, matrix, tm),
1012af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        fCenterX1(shader.getCenterX1()),
1022af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        fRadius0(shader.getStartRadius()),
103c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fDiffRadius(shader.getDiffRadius()){
104eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt        this->initClassID<Edge2PtConicalEffect>();
105c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // We should only be calling this shader if we are degenerate case with touching circles
1068405ef9854858b2527bf03b7e7abb1c0da59411degdaniel        // When deciding if we are in edge case, we scaled by the end radius for cases when the
1070125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt        // start radius was close to zero, otherwise we scaled by the start radius.  In addition
1080125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt        // Our test for the edge case in set_matrix_circle_conical has a higher tolerance so we
1090125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt        // need the sqrt value below
1100125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt        SkASSERT(SkScalarAbs(SkScalarAbs(fDiffRadius) - fCenterX1) <
1110125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt                 (fRadius0 < kErrorTol ? shader.getEndRadius() * kEdgeErrorTol :
1120125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt                                         fRadius0 * sqrt(kEdgeErrorTol)));
113c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1142af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        // We pass the linear part of the quadratic as a varying.
1152af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        //    float b = -2.0 * (fCenterX1 * x + fRadius0 * fDiffRadius * z)
1162af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        fBTransform = this->getCoordTransform();
1172af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        SkMatrix& bMatrix = *fBTransform.accessMatrix();
1182af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        SkScalar r0dr = SkScalarMul(fRadius0, fDiffRadius);
1192af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        bMatrix[SkMatrix::kMScaleX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::kMScaleX]) +
1202af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org                                            SkScalarMul(r0dr, bMatrix[SkMatrix::kMPersp0]));
1212af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        bMatrix[SkMatrix::kMSkewX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::kMSkewX]) +
1222af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org                                           SkScalarMul(r0dr, bMatrix[SkMatrix::kMPersp1]));
1232af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        bMatrix[SkMatrix::kMTransX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::kMTransX]) +
1242af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org                                            SkScalarMul(r0dr, bMatrix[SkMatrix::kMPersp2]));
1252af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        this->addCoordTransform(&fBTransform);
1262af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    }
1272af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
128b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
1292af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
1302af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // @{
1312af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // Cache of values - these can change arbitrarily, EXCEPT
1322af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // we shouldn't change between degenerate and non-degenerate?!
1332af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
1342af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    GrCoordTransform fBTransform;
1352af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar         fCenterX1;
1362af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar         fRadius0;
1372af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar         fDiffRadius;
1382af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
1392af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // @}
1402af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
1412af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    typedef GrGradientEffect INHERITED;
1422af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org};
1432af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
144c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLEdge2PtConicalEffect : public GrGLGradientEffect {
1452af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.orgpublic:
146eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLEdge2PtConicalEffect(const GrProcessor&);
147c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~GLEdge2PtConicalEffect() { }
148aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
1497c157a988845fb00f9024d6db6dda142c3458033wangyix    virtual void emitCode(EmitArgs&) override;
150aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
151cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b);
152aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
153aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.orgprotected:
154018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
155b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
156aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    UniformHandle fParamUni;
157aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
158aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    const char* fVSVaryingName;
159aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    const char* fFSVaryingName;
160aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
161aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    // @{
162aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    /// Values last uploaded as uniforms
163aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
164aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkScalar fCachedRadius;
165aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkScalar fCachedDiffRadius;
166aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
167aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    // @}
168aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
169aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.orgprivate:
170aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    typedef GrGLGradientEffect INHERITED;
171aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
172aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org};
173aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
17457d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielvoid Edge2PtConicalEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
17557d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel                                                 GrProcessorKeyBuilder* b) const {
176eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLEdge2PtConicalEffect::GenKey(*this, caps, b);
177eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
178eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
17957d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* Edge2PtConicalEffect::onCreateGLSLInstance() const {
180385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return new GLEdge2PtConicalEffect(*this);
181aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org}
182221b911f38cadfe6636bcc127c663fde548adc9askia.committer@gmail.com
183b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(Edge2PtConicalEffect);
184aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
1850125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt/*
1860125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt * All Two point conical gradient test create functions may occasionally create edge case shaders
1870125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt */
188c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonconst GrFragmentProcessor* Edge2PtConicalEffect::TestCreate(GrProcessorTestData* d) {
1890067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkPoint center1 = {d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()};
1900067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkScalar radius1 = d->fRandom->nextUScalar1();
191aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkPoint center2;
192aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkScalar radius2;
193aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    do {
1940067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        center2.set(d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1());
195aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org        // If the circles are identical the factory will give us an empty shader.
196c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // This will happen if we pick identical centers
197c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } while (center1 == center2);
198c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
199c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Below makes sure that circle one is contained within circle two
200c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // and both circles are touching on an edge
201c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint diff = center2 - center1;
202c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar diffLen = diff.length();
203c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    radius2 = radius1 + diffLen;
204aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
205aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkColor colors[kMaxRandomGradientColors];
206aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkScalar stopsArray[kMaxRandomGradientColors];
207aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkScalar* stops = stopsArray;
208aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkShader::TileMode tm;
2090067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    int colorCount = RandomGradientParams(d->fRandom, colors, &stops, &tm);
210aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1,
211aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org                                                                          center2, radius2,
212aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org                                                                          colors, stops, colorCount,
213aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org                                                                          tm));
214c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    const GrFragmentProcessor* fp = shader->asFragmentProcessor(d->fContext,
2154a339529612a43871d021877e58698e067d6c4cdbsalomon        GrTest::TestMatrix(d->fRandom), NULL, kNone_SkFilterQuality);
216c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    GrAlwaysAssert(fp);
217b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return fp;
218aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org}
219aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
220eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGLEdge2PtConicalEffect::GLEdge2PtConicalEffect(const GrProcessor&)
22196fcdcc219d2a0d3579719b84b28bede76efba64halcanary    : fVSVaryingName(nullptr)
22296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    , fFSVaryingName(nullptr)
223aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    , fCachedRadius(-SK_ScalarMax)
224c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedDiffRadius(-SK_ScalarMax) {}
225c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
2267c157a988845fb00f9024d6db6dda142c3458033wangyixvoid GLEdge2PtConicalEffect::emitCode(EmitArgs& args) {
2277c157a988845fb00f9024d6db6dda142c3458033wangyix    const Edge2PtConicalEffect& ge = args.fFp.cast<Edge2PtConicalEffect>();
2287ea439b2203855db97330b25945b87dd4b170b8begdaniel    GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
2297ea439b2203855db97330b25945b87dd4b170b8begdaniel    this->emitUniforms(uniformHandler, ge);
2305e58ceea8569f0d90ff7e3daf5de2def50407212cdalton    fParamUni = uniformHandler->addUniformArray(kFragment_GrShaderFlag,
2317ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                kFloat_GrSLType, kDefault_GrSLPrecision,
2327ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                "Conical2FSParams", 3);
233aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
234aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkString cName("c");
235aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkString tName("t");
236c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString p0; // start radius
237c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString p1; // start radius squared
238c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString p2; // difference in radii (r1 - r0)
239aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
2407ea439b2203855db97330b25945b87dd4b170b8begdaniel    uniformHandler->getUniformVariable(fParamUni).appendArrayAccess(0, &p0);
2417ea439b2203855db97330b25945b87dd4b170b8begdaniel    uniformHandler->getUniformVariable(fParamUni).appendArrayAccess(1, &p1);
2427ea439b2203855db97330b25945b87dd4b170b8begdaniel    uniformHandler->getUniformVariable(fParamUni).appendArrayAccess(2, &p2);
243aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
244aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    // We interpolate the linear component in coords[1].
2457c157a988845fb00f9024d6db6dda142c3458033wangyix    SkASSERT(args.fCoords[0].getType() == args.fCoords[1].getType());
246aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    const char* coords2D;
247aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkString bVar;
2488528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
2497c157a988845fb00f9024d6db6dda142c3458033wangyix    if (kVec3f_GrSLType == args.fCoords[0].getType()) {
2504ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel        fragBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy / %s.z, %s.x / %s.z);\n",
2517c157a988845fb00f9024d6db6dda142c3458033wangyix                               args.fCoords[0].c_str(), args.fCoords[0].c_str(),
2527c157a988845fb00f9024d6db6dda142c3458033wangyix                               args.fCoords[1].c_str(), args.fCoords[1].c_str());
253aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org        coords2D = "interpolants.xy";
254aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org        bVar = "interpolants.z";
255aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    } else {
2567c157a988845fb00f9024d6db6dda142c3458033wangyix        coords2D = args.fCoords[0].c_str();
2577c157a988845fb00f9024d6db6dda142c3458033wangyix        bVar.printf("%s.x", args.fCoords[1].c_str());
258aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    }
259aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
260aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    // output will default to transparent black (we simply won't write anything
261aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    // else to it if invalid, instead of discarding or returning prematurely)
2624ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor);
263aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
264c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // c = (x^2)+(y^2) - params[1]
2654ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
266c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                           cName.c_str(), coords2D, coords2D, p1.c_str());
267c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
268c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // linear case: t = -c/b
2694ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(),
270c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                           cName.c_str(), bVar.c_str());
271c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
272c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // if r(t) > 0, then t will be the x coordinate
2734ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
274c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                           p2.c_str(), p0.c_str());
2754ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppend("\t");
2767ea439b2203855db97330b25945b87dd4b170b8begdaniel    this->emitColor(fragBuilder,
2777ea439b2203855db97330b25945b87dd4b170b8begdaniel                    uniformHandler,
278a2e3e0f7f8ceed2ab152428d7ee2812ad8c842c3egdaniel                    args.fGLSLCaps,
2794ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    ge,
2804ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    tName.c_str(),
2814ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    args.fOutputColor,
2824ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    args.fInputColor,
2837c157a988845fb00f9024d6db6dda142c3458033wangyix                    args.fSamplers);
2844ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppend("\t}\n");
285c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
286aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
287018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GLEdge2PtConicalEffect::onSetData(const GrGLSLProgramDataManager& pdman,
288018fb62d12d1febf121fe265da5b6117b86a6541egdaniel                                       const GrProcessor& processor) {
289b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix    INHERITED::onSetData(pdman, processor);
290b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const Edge2PtConicalEffect& data = processor.cast<Edge2PtConicalEffect>();
291c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radius0 = data.radius();
292c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar diffRadius = data.diffRadius();
293aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
294c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (fCachedRadius != radius0 ||
295c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedDiffRadius != diffRadius) {
296aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
297c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        float values[3] = {
298c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            SkScalarToFloat(radius0),
299c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            SkScalarToFloat(SkScalarMul(radius0, radius0)),
300c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            SkScalarToFloat(diffRadius)
301c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        };
302c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
3037510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set1fv(fParamUni, 3, values);
304c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedRadius = radius0;
305c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedDiffRadius = diffRadius;
306c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
307c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
308c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
309b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLEdge2PtConicalEffect::GenKey(const GrProcessor& processor,
310cfc18867d982119d9dc2888bf09f1093012daaddjvanverth                                    const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
311b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    b->add32(GenBaseGradientKey(processor));
312c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
313c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
314c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
315c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org// Focal Conical Gradients
316c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
317c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
318c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgstatic ConicalType set_matrix_focal_conical(const SkTwoPointConicalGradient& shader,
319c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                            SkMatrix* invLMatrix, SkScalar* focalX) {
320c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Inverse of the current local matrix is passed in then,
321c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // translate, scale, and rotate such that endCircle is unit circle on x-axis,
322c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // and focal point is at the origin.
323c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    ConicalType conicalType;
324c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const SkPoint& focal = shader.getStartCenter();
325c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const SkPoint& centerEnd = shader.getEndCenter();
326c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radius = shader.getEndRadius();
32780894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar invRadius = 1.f / radius;
328c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
329c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkMatrix matrix;
330aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
331c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.setTranslate(-centerEnd.fX, -centerEnd.fY);
332c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.postScale(invRadius, invRadius);
333aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
334c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint focalTrans;
335c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.mapPoints(&focalTrans, &focal, 1);
336c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    *focalX = focalTrans.length();
337aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
33880894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    if (0.f != *focalX) {
339c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkScalar invFocalX = SkScalarInvert(*focalX);
340c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkMatrix rot;
341c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        rot.setSinCos(-SkScalarMul(invFocalX, focalTrans.fY),
342c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                      SkScalarMul(invFocalX, focalTrans.fX));
343c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        matrix.postConcat(rot);
344c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
345c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
34680894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    matrix.postTranslate(-(*focalX), 0.f);
347c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
348c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // If the focal point is touching the edge of the circle it will
349c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // cause a degenerate case that must be handled separately
3508405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    // kEdgeErrorTol = 5 * kErrorTol was picked after manual testing the
3518405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    // stability trade off versus the linear approx used in the Edge Shader
3528405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    if (SkScalarAbs(1.f - (*focalX)) < kEdgeErrorTol) {
353c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return kEdge_ConicalType;
354c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
355c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
356c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Scale factor 1 / (1 - focalX * focalX)
35780894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar oneMinusF2 = 1.f - SkScalarMul(*focalX, *focalX);
35880ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed    SkScalar s = SkScalarInvert(oneMinusF2);
359c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
360c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
36180894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    if (s >= 0.f) {
362c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        conicalType = kInside_ConicalType;
363c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        matrix.postScale(s, s * SkScalarSqrt(oneMinusF2));
364aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    } else {
365c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        conicalType = kOutside_ConicalType;
366c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        matrix.postScale(s, s);
367c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
368c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
369c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    invLMatrix->postConcat(matrix);
370c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
371c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    return conicalType;
372c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
373c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
374c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
375c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
376c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass FocalOutside2PtConicalEffect : public GrGradientEffect {
377c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
378c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
379b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrContext* ctx,
380b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkTwoPointConicalGradient& shader,
381b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkMatrix& matrix,
382b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkShader::TileMode tm,
383b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkScalar focalX) {
3844a339529612a43871d021877e58698e067d6c4cdbsalomon        return new FocalOutside2PtConicalEffect(ctx, shader, matrix, tm, focalX);
385c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
386c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
387c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~FocalOutside2PtConicalEffect() { }
388c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
38936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override {
390eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt        return "Two-Point Conical Gradient Focal Outside";
391eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    }
392eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
393c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    bool isFlipped() const { return fIsFlipped; }
394c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar focal() const { return fFocalX; }
395c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
396c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
39757d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
398b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
39957d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
4004b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix
40136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrFragmentProcessor& sBase) const override {
40249586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt        const FocalOutside2PtConicalEffect& s = sBase.cast<FocalOutside2PtConicalEffect>();
403c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return (INHERITED::onIsEqual(sBase) &&
404c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fFocalX == s.fFocalX &&
405c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fIsFlipped == s.fIsFlipped);
406c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
407c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
408c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    FocalOutside2PtConicalEffect(GrContext* ctx,
409c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 const SkTwoPointConicalGradient& shader,
410c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 const SkMatrix& matrix,
411c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 SkShader::TileMode tm,
412c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 SkScalar focalX)
4134a339529612a43871d021877e58698e067d6c4cdbsalomon    : INHERITED(ctx, shader, matrix, tm)
414b2456053c7e20e5439915cd2954c71f73bc85375joshualitt    , fFocalX(focalX)
415b2456053c7e20e5439915cd2954c71f73bc85375joshualitt    , fIsFlipped(shader.isFlippedGrad()) {
416eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt        this->initClassID<FocalOutside2PtConicalEffect>();
417eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    }
418c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
419b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
420c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
421c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar         fFocalX;
422c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    bool             fIsFlipped;
423c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
424c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGradientEffect INHERITED;
425c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
426c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
427c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLFocalOutside2PtConicalEffect : public GrGLGradientEffect {
428c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
429eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLFocalOutside2PtConicalEffect(const GrProcessor&);
430c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~GLFocalOutside2PtConicalEffect() { }
431c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
4327c157a988845fb00f9024d6db6dda142c3458033wangyix    virtual void emitCode(EmitArgs&) override;
433c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
434cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b);
435c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
436c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprotected:
437018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
438b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
439c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    UniformHandle fParamUni;
440c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
441c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fVSVaryingName;
442c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fFSVaryingName;
443c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
444c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    bool fIsFlipped;
445c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
446c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @{
447c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    /// Values last uploaded as uniforms
448c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
449c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedFocal;
450c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
451c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @}
452c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
453c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
454c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGLGradientEffect INHERITED;
455c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
456c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
457c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
45857d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielvoid FocalOutside2PtConicalEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
45957d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel                                                         GrProcessorKeyBuilder* b) const {
460eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLFocalOutside2PtConicalEffect::GenKey(*this, caps, b);
461eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
462eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
46357d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* FocalOutside2PtConicalEffect::onCreateGLSLInstance() const {
464385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return new GLFocalOutside2PtConicalEffect(*this);
465c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
466c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
467b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(FocalOutside2PtConicalEffect);
468c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
4690125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt/*
4700125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt * All Two point conical gradient test create functions may occasionally create edge case shaders
4710125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt */
472c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonconst GrFragmentProcessor* FocalOutside2PtConicalEffect::TestCreate(GrProcessorTestData* d) {
4730067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkPoint center1 = {d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()};
47480894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar radius1 = 0.f;
475c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint center2;
476c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radius2;
477c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    do {
4780067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        center2.set(d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1());
479ede0c5c7784ff4bd86e268d33df89c0ac432ca5bskia.committer@gmail.com        // Need to make sure the centers are not the same or else focal point will be inside
480c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } while (center1 == center2);
481c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkPoint diff = center2 - center1;
482c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkScalar diffLen = diff.length();
483c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // Below makes sure that the focal point is not contained within circle two
4840067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        radius2 = d->fRandom->nextRangeF(0.f, diffLen);
485c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
486c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkColor colors[kMaxRandomGradientColors];
487c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar stopsArray[kMaxRandomGradientColors];
488c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar* stops = stopsArray;
489c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkShader::TileMode tm;
4900067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    int colorCount = RandomGradientParams(d->fRandom, colors, &stops, &tm);
491c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1,
492c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          center2, radius2,
493c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          colors, stops, colorCount,
494c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          tm));
495c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    const GrFragmentProcessor* fp = shader->asFragmentProcessor(d->fContext,
4964a339529612a43871d021877e58698e067d6c4cdbsalomon        GrTest::TestMatrix(d->fRandom), NULL, kNone_SkFilterQuality);
497c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    GrAlwaysAssert(fp);
498c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    return fp;
499c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
500c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
501eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGLFocalOutside2PtConicalEffect::GLFocalOutside2PtConicalEffect(const GrProcessor& processor)
50296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    : fVSVaryingName(nullptr)
50396fcdcc219d2a0d3579719b84b28bede76efba64halcanary    , fFSVaryingName(nullptr)
504c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedFocal(SK_ScalarMax) {
505b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const FocalOutside2PtConicalEffect& data = processor.cast<FocalOutside2PtConicalEffect>();
506c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    fIsFlipped = data.isFlipped();
507c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
508c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
5097c157a988845fb00f9024d6db6dda142c3458033wangyixvoid GLFocalOutside2PtConicalEffect::emitCode(EmitArgs& args) {
5107c157a988845fb00f9024d6db6dda142c3458033wangyix    const FocalOutside2PtConicalEffect& ge = args.fFp.cast<FocalOutside2PtConicalEffect>();
5117ea439b2203855db97330b25945b87dd4b170b8begdaniel    GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
5127ea439b2203855db97330b25945b87dd4b170b8begdaniel    this->emitUniforms(uniformHandler, ge);
5135e58ceea8569f0d90ff7e3daf5de2def50407212cdalton    fParamUni = uniformHandler->addUniformArray(kFragment_GrShaderFlag,
5147ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                kFloat_GrSLType, kDefault_GrSLPrecision,
5157ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                "Conical2FSParams", 2);
516c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString tName("t");
517c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString p0; // focalX
518c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString p1; // 1 - focalX * focalX
519c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
5207ea439b2203855db97330b25945b87dd4b170b8begdaniel    uniformHandler->getUniformVariable(fParamUni).appendArrayAccess(0, &p0);
5217ea439b2203855db97330b25945b87dd4b170b8begdaniel    uniformHandler->getUniformVariable(fParamUni).appendArrayAccess(1, &p1);
522c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
523c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // if we have a vec3 from being in perspective, convert it to a vec2 first
5248528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
5254ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    SkString coords2DString = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
526ede0c5c7784ff4bd86e268d33df89c0ac432ca5bskia.committer@gmail.com    const char* coords2D = coords2DString.c_str();
527c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
528c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // t = p.x * focal.x +/- sqrt(p.x^2 + (1 - focal.x^2) * p.y^2)
529aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
530c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // output will default to transparent black (we simply won't write anything
531c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // else to it if invalid, instead of discarding or returning prematurely)
5324ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor);
533c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
5344ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tfloat xs = %s.x * %s.x;\n", coords2D, coords2D);
5354ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tfloat ys = %s.y * %s.y;\n", coords2D, coords2D);
5364ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tfloat d = xs + %s * ys;\n", p1.c_str());
537aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
538c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Must check to see if we flipped the circle order (to make sure start radius < end radius)
539c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // If so we must also flip sign on sqrt
540c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (!fIsFlipped) {
5414ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel        fragBuilder->codeAppendf("\tfloat %s = %s.x * %s  + sqrt(d);\n", tName.c_str(),
5424ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                 coords2D, p0.c_str());
543c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } else {
5444ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel        fragBuilder->codeAppendf("\tfloat %s = %s.x * %s  - sqrt(d);\n", tName.c_str(),
5454ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                 coords2D, p0.c_str());
546aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    }
547c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
5484ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tif (%s >= 0.0 && d >= 0.0) {\n", tName.c_str());
5494ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppend("\t\t");
5507ea439b2203855db97330b25945b87dd4b170b8begdaniel    this->emitColor(fragBuilder,
5517ea439b2203855db97330b25945b87dd4b170b8begdaniel                    uniformHandler,
552a2e3e0f7f8ceed2ab152428d7ee2812ad8c842c3egdaniel                    args.fGLSLCaps,
5534ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    ge,
5544ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    tName.c_str(),
5554ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    args.fOutputColor,
5564ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    args.fInputColor,
5577c157a988845fb00f9024d6db6dda142c3458033wangyix                    args.fSamplers);
5584ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppend("\t}\n");
559aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org}
560aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
561018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GLFocalOutside2PtConicalEffect::onSetData(const GrGLSLProgramDataManager& pdman,
562018fb62d12d1febf121fe265da5b6117b86a6541egdaniel                                               const GrProcessor& processor) {
563b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix    INHERITED::onSetData(pdman, processor);
564b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const FocalOutside2PtConicalEffect& data = processor.cast<FocalOutside2PtConicalEffect>();
56544d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org    SkASSERT(data.isFlipped() == fIsFlipped);
566c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar focal = data.focal();
567aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
568c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (fCachedFocal != focal) {
56980894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org        SkScalar oneMinus2F = 1.f - SkScalarMul(focal, focal);
570aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
571c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        float values[2] = {
572c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            SkScalarToFloat(focal),
573c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            SkScalarToFloat(oneMinus2F),
574aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org        };
575aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
5767510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set1fv(fParamUni, 2, values);
577c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedFocal = focal;
578aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    }
579aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org}
580aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
581b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLFocalOutside2PtConicalEffect::GenKey(const GrProcessor& processor,
582cfc18867d982119d9dc2888bf09f1093012daaddjvanverth                                            const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
58363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    uint32_t* key = b->add32n(2);
584b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    key[0] = GenBaseGradientKey(processor);
585b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    key[1] = processor.cast<FocalOutside2PtConicalEffect>().isFlipped();
586aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org}
5872af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
5882af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
5892af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
590c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLFocalInside2PtConicalEffect;
5912af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
592c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass FocalInside2PtConicalEffect : public GrGradientEffect {
593c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
594c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
595b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrContext* ctx,
596b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkTwoPointConicalGradient& shader,
597b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkMatrix& matrix,
598b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkShader::TileMode tm,
599b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkScalar focalX) {
6004a339529612a43871d021877e58698e067d6c4cdbsalomon        return new FocalInside2PtConicalEffect(ctx, shader, matrix, tm, focalX);
601c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
602c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
603c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~FocalInside2PtConicalEffect() {}
604c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
60536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override {
606eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt        return "Two-Point Conical Gradient Focal Inside";
607eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    }
608eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
609c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar focal() const { return fFocalX; }
610c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
61157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    typedef GLFocalInside2PtConicalEffect GLSLProcessor;
612c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
613c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
61457d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
615b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
61657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
6174b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix
61836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrFragmentProcessor& sBase) const override {
61949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt        const FocalInside2PtConicalEffect& s = sBase.cast<FocalInside2PtConicalEffect>();
620c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return (INHERITED::onIsEqual(sBase) &&
621c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fFocalX == s.fFocalX);
6222af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    }
6232af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
624c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    FocalInside2PtConicalEffect(GrContext* ctx,
625c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                const SkTwoPointConicalGradient& shader,
626c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                const SkMatrix& matrix,
627c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                SkShader::TileMode tm,
628c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                SkScalar focalX)
6294a339529612a43871d021877e58698e067d6c4cdbsalomon        : INHERITED(ctx, shader, matrix, tm), fFocalX(focalX) {
630eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt        this->initClassID<FocalInside2PtConicalEffect>();
631eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    }
632c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
633b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
634c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
635c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar         fFocalX;
636c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
637c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGradientEffect INHERITED;
638c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
639c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
640c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLFocalInside2PtConicalEffect : public GrGLGradientEffect {
641c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
642eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLFocalInside2PtConicalEffect(const GrProcessor&);
643c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~GLFocalInside2PtConicalEffect() {}
644c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
6457c157a988845fb00f9024d6db6dda142c3458033wangyix    virtual void emitCode(EmitArgs&) override;
646c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
647cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b);
648c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
649c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprotected:
650018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
651b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
652c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    UniformHandle fFocalUni;
653c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
654c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fVSVaryingName;
655c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fFSVaryingName;
656c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
657c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @{
658c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    /// Values last uploaded as uniforms
659c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
660c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedFocal;
661c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
662c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @}
663c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
664c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
665c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGLGradientEffect INHERITED;
666c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
667c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
668c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
66957d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielvoid FocalInside2PtConicalEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
67057d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel                                                        GrProcessorKeyBuilder* b) const {
671eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLFocalInside2PtConicalEffect::GenKey(*this, caps, b);
672eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
673eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
67457d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* FocalInside2PtConicalEffect::onCreateGLSLInstance() const {
675385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return new GLFocalInside2PtConicalEffect(*this);
676c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
677c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
678b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(FocalInside2PtConicalEffect);
679c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
6800125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt/*
6810125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt * All Two point conical gradient test create functions may occasionally create edge case shaders
6820125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt */
683c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonconst GrFragmentProcessor* FocalInside2PtConicalEffect::TestCreate(GrProcessorTestData* d) {
6840067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkPoint center1 = {d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()};
68580894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar radius1 = 0.f;
686c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint center2;
687c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radius2;
688c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    do {
6890067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        center2.set(d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1());
690c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // Below makes sure radius2 is larger enouch such that the focal point
691c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // is inside the end circle
6920067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        SkScalar increase = d->fRandom->nextUScalar1();
693c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkPoint diff = center2 - center1;
694c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkScalar diffLen = diff.length();
695c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        radius2 = diffLen + increase;
696c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // If the circles are identical the factory will give us an empty shader.
697c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } while (radius1 == radius2 && center1 == center2);
698c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
699c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkColor colors[kMaxRandomGradientColors];
700c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar stopsArray[kMaxRandomGradientColors];
701c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar* stops = stopsArray;
702c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkShader::TileMode tm;
7030067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    int colorCount = RandomGradientParams(d->fRandom, colors, &stops, &tm);
704c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1,
705c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          center2, radius2,
706c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          colors, stops, colorCount,
707c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          tm));
708c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    const GrFragmentProcessor* fp = shader->asFragmentProcessor(d->fContext,
7094a339529612a43871d021877e58698e067d6c4cdbsalomon        GrTest::TestMatrix(d->fRandom), NULL, kNone_SkFilterQuality);
710c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    GrAlwaysAssert(fp);
711b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return fp;
712c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
713c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
714eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGLFocalInside2PtConicalEffect::GLFocalInside2PtConicalEffect(const GrProcessor&)
71596fcdcc219d2a0d3579719b84b28bede76efba64halcanary    : fVSVaryingName(nullptr)
71696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    , fFSVaryingName(nullptr)
717c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedFocal(SK_ScalarMax) {}
718c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
7197c157a988845fb00f9024d6db6dda142c3458033wangyixvoid GLFocalInside2PtConicalEffect::emitCode(EmitArgs& args) {
7207c157a988845fb00f9024d6db6dda142c3458033wangyix    const FocalInside2PtConicalEffect& ge = args.fFp.cast<FocalInside2PtConicalEffect>();
7217ea439b2203855db97330b25945b87dd4b170b8begdaniel    GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
7227ea439b2203855db97330b25945b87dd4b170b8begdaniel    this->emitUniforms(uniformHandler, ge);
7235e58ceea8569f0d90ff7e3daf5de2def50407212cdalton    fFocalUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
7247ea439b2203855db97330b25945b87dd4b170b8begdaniel                                           kFloat_GrSLType, kDefault_GrSLPrecision,
7257ea439b2203855db97330b25945b87dd4b170b8begdaniel                                           "Conical2FSParams");
726c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString tName("t");
727c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
728c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // this is the distance along x-axis from the end center to focal point in
729c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // transformed coordinates
7307ea439b2203855db97330b25945b87dd4b170b8begdaniel    GrGLSLShaderVar focal = uniformHandler->getUniformVariable(fFocalUni);
731c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
732c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // if we have a vec3 from being in perspective, convert it to a vec2 first
7338528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
7344ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    SkString coords2DString = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
735ede0c5c7784ff4bd86e268d33df89c0ac432ca5bskia.committer@gmail.com    const char* coords2D = coords2DString.c_str();
736c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
737c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // t = p.x * focalX + length(p)
7384ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tfloat %s = %s.x * %s  + length(%s);\n", tName.c_str(),
7397ea439b2203855db97330b25945b87dd4b170b8begdaniel                             coords2D, focal.c_str(), coords2D);
740c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
7417ea439b2203855db97330b25945b87dd4b170b8begdaniel    this->emitColor(fragBuilder,
7427ea439b2203855db97330b25945b87dd4b170b8begdaniel                    uniformHandler,
743a2e3e0f7f8ceed2ab152428d7ee2812ad8c842c3egdaniel                    args.fGLSLCaps,
7444ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    ge,
7454ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    tName.c_str(),
7464ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    args.fOutputColor,
7474ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    args.fInputColor,
7487c157a988845fb00f9024d6db6dda142c3458033wangyix                    args.fSamplers);
749c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
750c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
751018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GLFocalInside2PtConicalEffect::onSetData(const GrGLSLProgramDataManager& pdman,
752018fb62d12d1febf121fe265da5b6117b86a6541egdaniel                                              const GrProcessor& processor) {
753b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix    INHERITED::onSetData(pdman, processor);
754b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const FocalInside2PtConicalEffect& data = processor.cast<FocalInside2PtConicalEffect>();
755c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar focal = data.focal();
756c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
757c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (fCachedFocal != focal) {
7587510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set1f(fFocalUni, SkScalarToFloat(focal));
759c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedFocal = focal;
760c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
761c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
762c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
763b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLFocalInside2PtConicalEffect::GenKey(const GrProcessor& processor,
764cfc18867d982119d9dc2888bf09f1093012daaddjvanverth                                           const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
765b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    b->add32(GenBaseGradientKey(processor));
766c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
767c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
768c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
769c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org// Circle Conical Gradients
770c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
771c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
772c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgstruct CircleConicalInfo {
773c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint fCenterEnd;
774c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fA;
775c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fB;
776c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fC;
777c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
778c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
779c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org// Returns focal distance along x-axis in transformed coords
780c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgstatic ConicalType set_matrix_circle_conical(const SkTwoPointConicalGradient& shader,
781c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                             SkMatrix* invLMatrix, CircleConicalInfo* info) {
782c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Inverse of the current local matrix is passed in then,
783c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // translate and scale such that start circle is on the origin and has radius 1
784c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const SkPoint& centerStart = shader.getStartCenter();
785c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const SkPoint& centerEnd = shader.getEndCenter();
786c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radiusStart = shader.getStartRadius();
787c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radiusEnd = shader.getEndRadius();
788c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
789c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkMatrix matrix;
790c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
791c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.setTranslate(-centerStart.fX, -centerStart.fY);
792c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
79380894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar invStartRad = 1.f / radiusStart;
794c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.postScale(invStartRad, invStartRad);
795c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
796c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    radiusEnd /= radiusStart;
797c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
798c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint centerEndTrans;
799c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.mapPoints(&centerEndTrans, &centerEnd, 1);
800c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
801c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar A = centerEndTrans.fX * centerEndTrans.fX + centerEndTrans.fY * centerEndTrans.fY
802c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                 - radiusEnd * radiusEnd + 2 * radiusEnd - 1;
803c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
804c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Check to see if start circle is inside end circle with edges touching.
805c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // If touching we return that it is of kEdge_ConicalType, and leave the matrix setting
8068405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    // to the edge shader. kEdgeErrorTol = 5 * kErrorTol was picked after manual testing
8078405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    // so that C = 1 / A is stable, and the linear approximation used in the Edge shader is
8088405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    // still accurate.
8098405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    if (SkScalarAbs(A) < kEdgeErrorTol) {
810c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return kEdge_ConicalType;
811c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
812c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
81380894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar C = 1.f / A;
81480894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar B = (radiusEnd - 1.f) * C;
815c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
816c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.postScale(C, C);
817c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
818c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    invLMatrix->postConcat(matrix);
819c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
820c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    info->fCenterEnd = centerEndTrans;
821c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    info->fA = A;
822c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    info->fB = B;
823c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    info->fC = C;
824c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
825c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // if A ends up being negative, the start circle is contained completely inside the end cirlce
82680894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    if (A < 0.f) {
827c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return kInside_ConicalType;
828c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
829c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    return kOutside_ConicalType;
830c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
831c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
832c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass CircleInside2PtConicalEffect : public GrGradientEffect {
833c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
834c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
835b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrContext* ctx,
836b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkTwoPointConicalGradient& shader,
837b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkMatrix& matrix,
838b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkShader::TileMode tm,
839b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const CircleConicalInfo& info) {
8404a339529612a43871d021877e58698e067d6c4cdbsalomon        return new CircleInside2PtConicalEffect(ctx, shader, matrix, tm, info);
841c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
842c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
843c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~CircleInside2PtConicalEffect() {}
844c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
84536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "Two-Point Conical Gradient Inside"; }
846eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
847c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerX() const { return fInfo.fCenterEnd.fX; }
848c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerY() const { return fInfo.fCenterEnd.fY; }
849c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar A() const { return fInfo.fA; }
850c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar B() const { return fInfo.fB; }
851c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar C() const { return fInfo.fC; }
852c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
853c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
85457d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
855b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
85657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps,
85757d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel                                       GrProcessorKeyBuilder* b) const override;
8584b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix
85936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrFragmentProcessor& sBase) const override {
86049586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt        const CircleInside2PtConicalEffect& s = sBase.cast<CircleInside2PtConicalEffect>();
861c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return (INHERITED::onIsEqual(sBase) &&
862c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fCenterEnd == s.fInfo.fCenterEnd &&
863c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fA == s.fInfo.fA &&
864c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fB == s.fInfo.fB &&
865c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fC == s.fInfo.fC);
866c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
867c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
868c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    CircleInside2PtConicalEffect(GrContext* ctx,
869c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 const SkTwoPointConicalGradient& shader,
870c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 const SkMatrix& matrix,
871c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 SkShader::TileMode tm,
872c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 const CircleConicalInfo& info)
8734a339529612a43871d021877e58698e067d6c4cdbsalomon        : INHERITED(ctx, shader, matrix, tm), fInfo(info) {
874eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt        this->initClassID<CircleInside2PtConicalEffect>();
875eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    }
876c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
877b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
878c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
879c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const CircleConicalInfo fInfo;
880c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
881c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGradientEffect INHERITED;
882c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
883c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
884c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLCircleInside2PtConicalEffect : public GrGLGradientEffect {
885c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
886eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLCircleInside2PtConicalEffect(const GrProcessor&);
887c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~GLCircleInside2PtConicalEffect() {}
888c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
8897c157a988845fb00f9024d6db6dda142c3458033wangyix    virtual void emitCode(EmitArgs&) override;
890c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
891cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b);
892c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
893c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprotected:
894018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
895b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
896c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    UniformHandle fCenterUni;
897c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    UniformHandle fParamUni;
898c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
899c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fVSVaryingName;
900c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fFSVaryingName;
901c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
902c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @{
903c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    /// Values last uploaded as uniforms
904c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
905c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedCenterX;
906c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedCenterY;
907c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedA;
908c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedB;
909c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedC;
910c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
911c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @}
912c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
913c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
914c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGLGradientEffect INHERITED;
915c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
916c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
917c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
91857d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielvoid CircleInside2PtConicalEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
91957d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel                                                         GrProcessorKeyBuilder* b) const {
920eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLCircleInside2PtConicalEffect::GenKey(*this, caps, b);
921eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
922eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
92357d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* CircleInside2PtConicalEffect::onCreateGLSLInstance() const {
924385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return new GLCircleInside2PtConicalEffect(*this);
925c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
926c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
927b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircleInside2PtConicalEffect);
928c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
9290125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt/*
9300125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt * All Two point conical gradient test create functions may occasionally create edge case shaders
9310125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt */
932c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonconst GrFragmentProcessor* CircleInside2PtConicalEffect::TestCreate(GrProcessorTestData* d) {
9330067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkPoint center1 = {d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()};
9340067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkScalar radius1 = d->fRandom->nextUScalar1() + 0.0001f; // make sure radius1 != 0
935c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint center2;
936c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radius2;
937c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    do {
9380067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        center2.set(d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1());
939c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // Below makes sure that circle one is contained within circle two
9400067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        SkScalar increase = d->fRandom->nextUScalar1();
941c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkPoint diff = center2 - center1;
942c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkScalar diffLen = diff.length();
943c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        radius2 = radius1 + diffLen + increase;
944c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // If the circles are identical the factory will give us an empty shader.
945c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } while (radius1 == radius2 && center1 == center2);
946c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
947c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkColor colors[kMaxRandomGradientColors];
948c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar stopsArray[kMaxRandomGradientColors];
949c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar* stops = stopsArray;
950c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkShader::TileMode tm;
9510067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    int colorCount = RandomGradientParams(d->fRandom, colors, &stops, &tm);
952c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1,
953c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          center2, radius2,
954c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          colors, stops, colorCount,
955c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          tm));
956c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    const GrFragmentProcessor* fp = shader->asFragmentProcessor(d->fContext,
9574a339529612a43871d021877e58698e067d6c4cdbsalomon        GrTest::TestMatrix(d->fRandom), NULL, kNone_SkFilterQuality);
958c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    GrAlwaysAssert(fp);
9598ca93e7c733ab064c8a9e03715ac405ae739cf51joshualitt    return fp;
960c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
961c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
962eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGLCircleInside2PtConicalEffect::GLCircleInside2PtConicalEffect(const GrProcessor& processor)
96396fcdcc219d2a0d3579719b84b28bede76efba64halcanary    : fVSVaryingName(nullptr)
96496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    , fFSVaryingName(nullptr)
965c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedCenterX(SK_ScalarMax)
966c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedCenterY(SK_ScalarMax)
967c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedA(SK_ScalarMax)
968c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedB(SK_ScalarMax)
969c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedC(SK_ScalarMax) {}
970c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
9717c157a988845fb00f9024d6db6dda142c3458033wangyixvoid GLCircleInside2PtConicalEffect::emitCode(EmitArgs& args) {
9727c157a988845fb00f9024d6db6dda142c3458033wangyix    const CircleInside2PtConicalEffect& ge = args.fFp.cast<CircleInside2PtConicalEffect>();
9737ea439b2203855db97330b25945b87dd4b170b8begdaniel    GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
9747ea439b2203855db97330b25945b87dd4b170b8begdaniel    this->emitUniforms(uniformHandler, ge);
9755e58ceea8569f0d90ff7e3daf5de2def50407212cdalton    fCenterUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
9767ea439b2203855db97330b25945b87dd4b170b8begdaniel                                            kVec2f_GrSLType, kDefault_GrSLPrecision,
9777ea439b2203855db97330b25945b87dd4b170b8begdaniel                                            "Conical2FSCenter");
9785e58ceea8569f0d90ff7e3daf5de2def50407212cdalton    fParamUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
9797ea439b2203855db97330b25945b87dd4b170b8begdaniel                                           kVec3f_GrSLType, kDefault_GrSLPrecision,
9807ea439b2203855db97330b25945b87dd4b170b8begdaniel                                           "Conical2FSParams");
981c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString tName("t");
982c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
9837ea439b2203855db97330b25945b87dd4b170b8begdaniel    GrGLSLShaderVar center = uniformHandler->getUniformVariable(fCenterUni);
984c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // params.x = A
985c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // params.y = B
986c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // params.z = C
9877ea439b2203855db97330b25945b87dd4b170b8begdaniel    GrGLSLShaderVar params = uniformHandler->getUniformVariable(fParamUni);
988c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
989c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // if we have a vec3 from being in perspective, convert it to a vec2 first
9908528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
9914ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    SkString coords2DString = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
992ede0c5c7784ff4bd86e268d33df89c0ac432ca5bskia.committer@gmail.com    const char* coords2D = coords2DString.c_str();
993c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
994c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // p = coords2D
995c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // e = center end
996c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // r = radius end
997c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // A = dot(e, e) - r^2 + 2 * r - 1
998c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // B = (r -1) / A
999c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // C = 1 / A
1000c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // d = dot(e, p) + B
1001c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // t = d +/- sqrt(d^2 - A * dot(p, p) + C)
10024ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tfloat pDotp = dot(%s,  %s);\n", coords2D, coords2D);
10034ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tfloat d = dot(%s,  %s) + %s.y;\n", coords2D, center.c_str(),
10044ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                             params.c_str());
10054ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tfloat %s = d + sqrt(d * d - %s.x * pDotp + %s.z);\n",
10064ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                             tName.c_str(), params.c_str(), params.c_str());
10074ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel
10087ea439b2203855db97330b25945b87dd4b170b8begdaniel    this->emitColor(fragBuilder,
10097ea439b2203855db97330b25945b87dd4b170b8begdaniel                    uniformHandler,
1010a2e3e0f7f8ceed2ab152428d7ee2812ad8c842c3egdaniel                    args.fGLSLCaps,
10114ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    ge,
10124ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    tName.c_str(),
10134ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    args.fOutputColor,
10144ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    args.fInputColor,
10157c157a988845fb00f9024d6db6dda142c3458033wangyix                    args.fSamplers);
1016c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1017c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1018018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GLCircleInside2PtConicalEffect::onSetData(const GrGLSLProgramDataManager& pdman,
1019018fb62d12d1febf121fe265da5b6117b86a6541egdaniel                                               const GrProcessor& processor) {
1020b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix    INHERITED::onSetData(pdman, processor);
1021b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const CircleInside2PtConicalEffect& data = processor.cast<CircleInside2PtConicalEffect>();
1022c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerX = data.centerX();
1023c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerY = data.centerY();
1024c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar A = data.A();
1025c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar B = data.B();
1026c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar C = data.C();
1027c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1028c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (fCachedCenterX != centerX || fCachedCenterY != centerY ||
1029c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedA != A || fCachedB != B || fCachedC != C) {
1030c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
10317510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set2f(fCenterUni, SkScalarToFloat(centerX), SkScalarToFloat(centerY));
10327510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set3f(fParamUni, SkScalarToFloat(A), SkScalarToFloat(B), SkScalarToFloat(C));
1033c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1034c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedCenterX = centerX;
1035c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedCenterY = centerY;
1036c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedA = A;
1037c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedB = B;
1038c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedC = C;
1039c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1040c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1041c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1042b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLCircleInside2PtConicalEffect::GenKey(const GrProcessor& processor,
1043cfc18867d982119d9dc2888bf09f1093012daaddjvanverth                                            const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
1044b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    b->add32(GenBaseGradientKey(processor));
1045c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1046c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1047c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
1048c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1049c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass CircleOutside2PtConicalEffect : public GrGradientEffect {
1050c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
1051c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1052b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrContext* ctx,
1053b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkTwoPointConicalGradient& shader,
1054b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkMatrix& matrix,
1055b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkShader::TileMode tm,
1056b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const CircleConicalInfo& info) {
10574a339529612a43871d021877e58698e067d6c4cdbsalomon        return new CircleOutside2PtConicalEffect(ctx, shader, matrix, tm, info);
1058c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1059c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1060c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~CircleOutside2PtConicalEffect() {}
1061c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
106236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "Two-Point Conical Gradient Outside"; }
1063eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
1064c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerX() const { return fInfo.fCenterEnd.fX; }
1065c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerY() const { return fInfo.fCenterEnd.fY; }
1066c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar A() const { return fInfo.fA; }
1067c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar B() const { return fInfo.fB; }
1068c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar C() const { return fInfo.fC; }
1069c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar tLimit() const { return fTLimit; }
1070c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    bool isFlipped() const { return fIsFlipped; }
1071c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1072c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
107357d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
1074b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
107557d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
10764b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix
107736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrFragmentProcessor& sBase) const override {
107849586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt        const CircleOutside2PtConicalEffect& s = sBase.cast<CircleOutside2PtConicalEffect>();
1079c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return (INHERITED::onIsEqual(sBase) &&
1080c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fCenterEnd == s.fInfo.fCenterEnd &&
1081c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fA == s.fInfo.fA &&
1082c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fB == s.fInfo.fB &&
1083c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fC == s.fInfo.fC &&
1084c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fTLimit == s.fTLimit &&
1085c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fIsFlipped == s.fIsFlipped);
1086c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1087c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1088c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    CircleOutside2PtConicalEffect(GrContext* ctx,
1089c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                  const SkTwoPointConicalGradient& shader,
1090c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                  const SkMatrix& matrix,
1091c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                  SkShader::TileMode tm,
1092c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                  const CircleConicalInfo& info)
10934a339529612a43871d021877e58698e067d6c4cdbsalomon        : INHERITED(ctx, shader, matrix, tm), fInfo(info) {
1094eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt        this->initClassID<CircleOutside2PtConicalEffect>();
1095c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        if (shader.getStartRadius() != shader.getEndRadius()) {
109680ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed            fTLimit = shader.getStartRadius() / (shader.getStartRadius() - shader.getEndRadius());
1097c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        } else {
1098c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            fTLimit = SK_ScalarMin;
1099c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        }
1100c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1101c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fIsFlipped = shader.isFlippedGrad();
1102c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1103c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1104b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
1105c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1106c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const CircleConicalInfo fInfo;
1107c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fTLimit;
1108c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    bool fIsFlipped;
1109c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1110c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGradientEffect INHERITED;
1111c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
1112c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1113c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLCircleOutside2PtConicalEffect : public GrGLGradientEffect {
1114c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
1115eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLCircleOutside2PtConicalEffect(const GrProcessor&);
1116c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~GLCircleOutside2PtConicalEffect() {}
1117c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
11187c157a988845fb00f9024d6db6dda142c3458033wangyix    virtual void emitCode(EmitArgs&) override;
1119c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1120cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b);
1121c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1122c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprotected:
1123018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
1124b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
1125c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    UniformHandle fCenterUni;
1126c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    UniformHandle fParamUni;
1127c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1128c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fVSVaryingName;
1129c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fFSVaryingName;
1130c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1131c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    bool fIsFlipped;
1132c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1133c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @{
1134c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    /// Values last uploaded as uniforms
1135c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1136c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedCenterX;
1137c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedCenterY;
1138c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedA;
1139c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedB;
1140c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedC;
1141c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedTLimit;
1142c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1143c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @}
1144c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1145c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
1146c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGLGradientEffect INHERITED;
1147c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1148c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
1149c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
115057d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielvoid CircleOutside2PtConicalEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
115157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel                                                          GrProcessorKeyBuilder* b) const {
1152eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GLCircleOutside2PtConicalEffect::GenKey(*this, caps, b);
1153eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
1154eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
115557d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* CircleOutside2PtConicalEffect::onCreateGLSLInstance() const {
1156385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return new GLCircleOutside2PtConicalEffect(*this);
1157c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1158c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1159b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircleOutside2PtConicalEffect);
1160c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
11610125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt/*
11620125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt * All Two point conical gradient test create functions may occasionally create edge case shaders
11630125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt */
1164c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonconst GrFragmentProcessor* CircleOutside2PtConicalEffect::TestCreate(GrProcessorTestData* d) {
11650067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkPoint center1 = {d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()};
11660067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    SkScalar radius1 = d->fRandom->nextUScalar1() + 0.0001f; // make sure radius1 != 0
1167c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint center2;
1168c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radius2;
1169c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar diffLen;
1170c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    do {
11710067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        center2.set(d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1());
1172c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // If the circles share a center than we can't be in the outside case
1173c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } while (center1 == center2);
11740125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt    SkPoint diff = center2 - center1;
11750125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt    diffLen = diff.length();
11760125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt    // Below makes sure that circle one is not contained within circle two
11770125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt    // and have radius2 >= radius to match sorting on cpu side
11780067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    radius2 = radius1 + d->fRandom->nextRangeF(0.f, diffLen);
1179c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1180c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkColor colors[kMaxRandomGradientColors];
1181c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar stopsArray[kMaxRandomGradientColors];
1182c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar* stops = stopsArray;
1183c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkShader::TileMode tm;
11840067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    int colorCount = RandomGradientParams(d->fRandom, colors, &stops, &tm);
1185c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1,
1186c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          center2, radius2,
1187c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          colors, stops, colorCount,
1188c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          tm));
1189c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    const GrFragmentProcessor* fp = shader->asFragmentProcessor(
11904a339529612a43871d021877e58698e067d6c4cdbsalomon        d->fContext,GrTest::TestMatrix(d->fRandom), NULL, kNone_SkFilterQuality);
1191c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    GrAlwaysAssert(fp);
11928ca93e7c733ab064c8a9e03715ac405ae739cf51joshualitt    return fp;
1193c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1194c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1195eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGLCircleOutside2PtConicalEffect::GLCircleOutside2PtConicalEffect(const GrProcessor& processor)
119696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    : fVSVaryingName(nullptr)
119796fcdcc219d2a0d3579719b84b28bede76efba64halcanary    , fFSVaryingName(nullptr)
1198c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedCenterX(SK_ScalarMax)
1199c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedCenterY(SK_ScalarMax)
1200c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedA(SK_ScalarMax)
1201c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedB(SK_ScalarMax)
1202c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedC(SK_ScalarMax)
1203c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedTLimit(SK_ScalarMax) {
1204b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const CircleOutside2PtConicalEffect& data = processor.cast<CircleOutside2PtConicalEffect>();
1205c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    fIsFlipped = data.isFlipped();
1206c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1207c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
12087c157a988845fb00f9024d6db6dda142c3458033wangyixvoid GLCircleOutside2PtConicalEffect::emitCode(EmitArgs& args) {
12097c157a988845fb00f9024d6db6dda142c3458033wangyix    const CircleOutside2PtConicalEffect& ge = args.fFp.cast<CircleOutside2PtConicalEffect>();
12107ea439b2203855db97330b25945b87dd4b170b8begdaniel    GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
12117ea439b2203855db97330b25945b87dd4b170b8begdaniel    this->emitUniforms(uniformHandler, ge);
12125e58ceea8569f0d90ff7e3daf5de2def50407212cdalton    fCenterUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
12137ea439b2203855db97330b25945b87dd4b170b8begdaniel                                            kVec2f_GrSLType, kDefault_GrSLPrecision,
12147ea439b2203855db97330b25945b87dd4b170b8begdaniel                                            "Conical2FSCenter");
12155e58ceea8569f0d90ff7e3daf5de2def50407212cdalton    fParamUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
12167ea439b2203855db97330b25945b87dd4b170b8begdaniel                                           kVec4f_GrSLType, kDefault_GrSLPrecision,
12177ea439b2203855db97330b25945b87dd4b170b8begdaniel                                           "Conical2FSParams");
1218c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString tName("t");
1219c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
12207ea439b2203855db97330b25945b87dd4b170b8begdaniel    GrGLSLShaderVar center = uniformHandler->getUniformVariable(fCenterUni);
1221c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // params.x = A
1222c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // params.y = B
1223c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // params.z = C
12247ea439b2203855db97330b25945b87dd4b170b8begdaniel    GrGLSLShaderVar params = uniformHandler->getUniformVariable(fParamUni);
1225c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1226c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // if we have a vec3 from being in perspective, convert it to a vec2 first
12278528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
12284ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    SkString coords2DString = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
1229ede0c5c7784ff4bd86e268d33df89c0ac432ca5bskia.committer@gmail.com    const char* coords2D = coords2DString.c_str();
1230c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1231c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // output will default to transparent black (we simply won't write anything
1232c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // else to it if invalid, instead of discarding or returning prematurely)
12334ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor);
1234c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1235c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // p = coords2D
1236c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // e = center end
1237c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // r = radius end
1238c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // A = dot(e, e) - r^2 + 2 * r - 1
1239c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // B = (r -1) / A
1240c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // C = 1 / A
1241c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // d = dot(e, p) + B
1242c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // t = d +/- sqrt(d^2 - A * dot(p, p) + C)
1243c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
12444ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tfloat pDotp = dot(%s,  %s);\n", coords2D, coords2D);
12454ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tfloat d = dot(%s,  %s) + %s.y;\n", coords2D, center.c_str(),
12464ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                             params.c_str());
12474ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("\tfloat deter = d * d - %s.x * pDotp + %s.z;\n", params.c_str(),
12484ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                             params.c_str());
1249c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1250c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Must check to see if we flipped the circle order (to make sure start radius < end radius)
1251c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // If so we must also flip sign on sqrt
1252c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (!fIsFlipped) {
12534ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel        fragBuilder->codeAppendf("\tfloat %s = d + sqrt(deter);\n", tName.c_str());
1254c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } else {
12554ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel        fragBuilder->codeAppendf("\tfloat %s = d - sqrt(deter);\n", tName.c_str());
1256c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1257c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
12587ea439b2203855db97330b25945b87dd4b170b8begdaniel    fragBuilder->codeAppendf("\tif (%s >= %s.w && deter >= 0.0) {\n",
12597ea439b2203855db97330b25945b87dd4b170b8begdaniel                             tName.c_str(), params.c_str());
12604ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppend("\t\t");
12617ea439b2203855db97330b25945b87dd4b170b8begdaniel    this->emitColor(fragBuilder,
12627ea439b2203855db97330b25945b87dd4b170b8begdaniel                    uniformHandler,
1263a2e3e0f7f8ceed2ab152428d7ee2812ad8c842c3egdaniel                    args.fGLSLCaps,
12644ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    ge,
12654ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    tName.c_str(),
12664ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    args.fOutputColor,
12674ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                    args.fInputColor,
12687c157a988845fb00f9024d6db6dda142c3458033wangyix                    args.fSamplers);
12694ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppend("\t}\n");
1270c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1271c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1272018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GLCircleOutside2PtConicalEffect::onSetData(const GrGLSLProgramDataManager& pdman,
1273018fb62d12d1febf121fe265da5b6117b86a6541egdaniel                                                const GrProcessor& processor) {
1274b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix    INHERITED::onSetData(pdman, processor);
1275b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const CircleOutside2PtConicalEffect& data = processor.cast<CircleOutside2PtConicalEffect>();
1276c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkASSERT(data.isFlipped() == fIsFlipped);
1277c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerX = data.centerX();
1278c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerY = data.centerY();
1279c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar A = data.A();
1280c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar B = data.B();
1281c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar C = data.C();
1282c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar tLimit = data.tLimit();
1283c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1284c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (fCachedCenterX != centerX || fCachedCenterY != centerY ||
1285c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedA != A || fCachedB != B || fCachedC != C || fCachedTLimit != tLimit) {
1286c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
12877510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set2f(fCenterUni, SkScalarToFloat(centerX), SkScalarToFloat(centerY));
12887510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set4f(fParamUni, SkScalarToFloat(A), SkScalarToFloat(B), SkScalarToFloat(C),
1289c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                   SkScalarToFloat(tLimit));
1290c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1291c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedCenterX = centerX;
1292c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedCenterY = centerY;
1293c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedA = A;
1294c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedB = B;
1295c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedC = C;
1296c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedTLimit = tLimit;
1297c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1298c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1299c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1300b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLCircleOutside2PtConicalEffect::GenKey(const GrProcessor& processor,
1301cfc18867d982119d9dc2888bf09f1093012daaddjvanverth                                             const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
130263e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    uint32_t* key = b->add32n(2);
1303b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    key[0] = GenBaseGradientKey(processor);
1304b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    key[1] = processor.cast<CircleOutside2PtConicalEffect>().isFlipped();
1305c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1306c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1307c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
1308c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1309b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* Gr2PtConicalGradientEffect::Create(GrContext* ctx,
1310b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                        const SkTwoPointConicalGradient& shader,
1311b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                        SkShader::TileMode tm,
1312b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                        const SkMatrix* localMatrix) {
1313c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkMatrix matrix;
1314c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (!shader.getLocalMatrix().invert(&matrix)) {
131596fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
1316c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
131796fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org    if (localMatrix) {
131896fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        SkMatrix inv;
131996fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        if (!localMatrix->invert(&inv)) {
132096fcdcc219d2a0d3579719b84b28bede76efba64halcanary            return nullptr;
132196fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        }
132296fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        matrix.postConcat(inv);
132396fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org    }
1324c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1325c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (shader.getStartRadius() < kErrorTol) {
1326c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkScalar focalX;
1327c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        ConicalType type = set_matrix_focal_conical(shader, &matrix, &focalX);
1328c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        if (type == kInside_ConicalType) {
13294a339529612a43871d021877e58698e067d6c4cdbsalomon            return FocalInside2PtConicalEffect::Create(ctx, shader, matrix, tm, focalX);
1330c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        } else if(type == kEdge_ConicalType) {
1331c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            set_matrix_edge_conical(shader, &matrix);
13324a339529612a43871d021877e58698e067d6c4cdbsalomon            return Edge2PtConicalEffect::Create(ctx, shader, matrix, tm);
1333c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        } else {
13344a339529612a43871d021877e58698e067d6c4cdbsalomon            return FocalOutside2PtConicalEffect::Create(ctx, shader, matrix, tm, focalX);
1335c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        }
1336c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1337c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1338c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    CircleConicalInfo info;
1339c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    ConicalType type = set_matrix_circle_conical(shader, &matrix, &info);
1340c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1341c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (type == kInside_ConicalType) {
13424a339529612a43871d021877e58698e067d6c4cdbsalomon        return CircleInside2PtConicalEffect::Create(ctx, shader, matrix, tm, info);
1343c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } else if (type == kEdge_ConicalType) {
1344c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        set_matrix_edge_conical(shader, &matrix);
13454a339529612a43871d021877e58698e067d6c4cdbsalomon        return Edge2PtConicalEffect::Create(ctx, shader, matrix, tm);
1346c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } else {
13474a339529612a43871d021877e58698e067d6c4cdbsalomon        return CircleOutside2PtConicalEffect::Create(ctx, shader, matrix, tm, info);
1348c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
13492af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org}
13502af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
1351aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org#endif
1352