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
14b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrTBackendProcessorFactory.h"
1530ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/builders/GrGLProgramBuilder.h"
16aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org// For brevity
177510b224e52b9518a8ddf7418db0e9c258f79539kkinnunentypedef GrGLProgramDataManager::UniformHandle UniformHandle;
18aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
1980894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.orgstatic const SkScalar kErrorTol = 0.00001f;
208405ef9854858b2527bf03b7e7abb1c0da59411degdanielstatic const SkScalar kEdgeErrorTol = 5.f * kErrorTol;
21c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
22c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org/**
23c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org * We have three general cases for 2pt conical gradients. First we always assume that
24c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org * the start radius <= end radius. Our first case (kInside_) is when the start circle
25c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org * is completely enclosed by the end circle. The second case (kOutside_) is the case
26c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org * when the start circle is either completely outside the end circle or the circles
27c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org * overlap. The final case (kEdge_) is when the start circle is inside the end one,
28c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org * but the two are just barely touching at 1 point along their edges.
29c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org */
30c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgenum ConicalType {
31c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    kInside_ConicalType,
32c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    kOutside_ConicalType,
33c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    kEdge_ConicalType,
34c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
35c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
362af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
372af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
38c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgstatic void set_matrix_edge_conical(const SkTwoPointConicalGradient& shader,
39c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                    SkMatrix* invLMatrix) {
402af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // Inverse of the current local matrix is passed in then,
412af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // translate to center1, rotate so center2 is on x axis.
422af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    const SkPoint& center1 = shader.getStartCenter();
432af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    const SkPoint& center2 = shader.getEndCenter();
442af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
452af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    invLMatrix->postTranslate(-center1.fX, -center1.fY);
462af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
472af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkPoint diff = center2 - center1;
482af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar diffLen = diff.length();
492af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    if (0 != diffLen) {
502af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        SkScalar invDiffLen = SkScalarInvert(diffLen);
512af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        SkMatrix rot;
522af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        rot.setSinCos(-SkScalarMul(invDiffLen, diff.fY),
532af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org                       SkScalarMul(invDiffLen, diff.fX));
542af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        invLMatrix->postConcat(rot);
552af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    }
562af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org}
572af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
58c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLEdge2PtConicalEffect;
592af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
60c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass Edge2PtConicalEffect : public GrGradientEffect {
61aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.orgpublic:
62aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
63b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrContext* ctx,
64b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkTwoPointConicalGradient& shader,
65b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkMatrix& matrix,
66b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkShader::TileMode tm) {
6755fad7af61c21d502acb9891d631e8aa29e3628cbsalomon        return SkNEW_ARGS(Edge2PtConicalEffect, (ctx, shader, matrix, tm));
682af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    }
692af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
70c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~Edge2PtConicalEffect() {}
712af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
72c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    static const char* Name() { return "Two-Point Conical Gradient Edge Touching"; }
73b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
742af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
752af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
762af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar center() const { return fCenterX1; }
772af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar diffRadius() const { return fDiffRadius; }
782af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar radius() const { return fRadius0; }
792af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
80b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GLEdge2PtConicalEffect GLProcessor;
812af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
822af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.orgprivate:
83b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual bool onIsEqual(const GrProcessor& sBase) const SK_OVERRIDE {
8449586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt        const Edge2PtConicalEffect& s = sBase.cast<Edge2PtConicalEffect>();
852af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        return (INHERITED::onIsEqual(sBase) &&
862af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org                this->fCenterX1 == s.fCenterX1 &&
872af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org                this->fRadius0 == s.fRadius0 &&
88c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fDiffRadius == s.fDiffRadius);
892af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    }
902af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
91c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    Edge2PtConicalEffect(GrContext* ctx,
92c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                         const SkTwoPointConicalGradient& shader,
93c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                         const SkMatrix& matrix,
94c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                         SkShader::TileMode tm)
952af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        : INHERITED(ctx, shader, matrix, tm),
962af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        fCenterX1(shader.getCenterX1()),
972af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        fRadius0(shader.getStartRadius()),
98c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fDiffRadius(shader.getDiffRadius()){
99c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // We should only be calling this shader if we are degenerate case with touching circles
1008405ef9854858b2527bf03b7e7abb1c0da59411degdaniel        // When deciding if we are in edge case, we scaled by the end radius for cases when the
1010125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt        // start radius was close to zero, otherwise we scaled by the start radius.  In addition
1020125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt        // Our test for the edge case in set_matrix_circle_conical has a higher tolerance so we
1030125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt        // need the sqrt value below
1040125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt        SkASSERT(SkScalarAbs(SkScalarAbs(fDiffRadius) - fCenterX1) <
1050125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt                 (fRadius0 < kErrorTol ? shader.getEndRadius() * kEdgeErrorTol :
1060125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt                                         fRadius0 * sqrt(kEdgeErrorTol)));
107c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1082af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        // We pass the linear part of the quadratic as a varying.
1092af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        //    float b = -2.0 * (fCenterX1 * x + fRadius0 * fDiffRadius * z)
1102af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        fBTransform = this->getCoordTransform();
1112af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        SkMatrix& bMatrix = *fBTransform.accessMatrix();
1122af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        SkScalar r0dr = SkScalarMul(fRadius0, fDiffRadius);
1132af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        bMatrix[SkMatrix::kMScaleX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::kMScaleX]) +
1142af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org                                            SkScalarMul(r0dr, bMatrix[SkMatrix::kMPersp0]));
1152af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        bMatrix[SkMatrix::kMSkewX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::kMSkewX]) +
1162af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org                                           SkScalarMul(r0dr, bMatrix[SkMatrix::kMPersp1]));
1172af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        bMatrix[SkMatrix::kMTransX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::kMTransX]) +
1182af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org                                            SkScalarMul(r0dr, bMatrix[SkMatrix::kMPersp2]));
1192af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org        this->addCoordTransform(&fBTransform);
1202af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    }
1212af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
122b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
1232af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
1242af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // @{
1252af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // Cache of values - these can change arbitrarily, EXCEPT
1262af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // we shouldn't change between degenerate and non-degenerate?!
1272af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
1282af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    GrCoordTransform fBTransform;
1292af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar         fCenterX1;
1302af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar         fRadius0;
1312af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    SkScalar         fDiffRadius;
1322af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
1332af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    // @}
1342af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
1352af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    typedef GrGradientEffect INHERITED;
1362af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org};
1372af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
138c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLEdge2PtConicalEffect : public GrGLGradientEffect {
1392af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.orgpublic:
140b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GLEdge2PtConicalEffect(const GrBackendProcessorFactory& factory, const GrProcessor&);
141c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~GLEdge2PtConicalEffect() { }
142aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
14330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    virtual void emitCode(GrGLProgramBuilder*,
144b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrFragmentProcessor&,
145b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrProcessorKey&,
146aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org                          const char* outputColor,
147aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org                          const char* inputColor,
148aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org                          const TransformedCoordsArray&,
149aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org                          const TextureSamplerArray&) SK_OVERRIDE;
150b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
151aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
152b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b);
153aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
154aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.orgprotected:
155aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    UniformHandle fParamUni;
156aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
157aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    const char* fVSVaryingName;
158aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    const char* fFSVaryingName;
159aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
160aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    // @{
161aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    /// Values last uploaded as uniforms
162aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
163aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkScalar fCachedRadius;
164aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkScalar fCachedDiffRadius;
165aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
166aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    // @}
167aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
168aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.orgprivate:
169aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    typedef GrGLGradientEffect INHERITED;
170aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
171aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org};
172aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
173b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendFragmentProcessorFactory& Edge2PtConicalEffect::getFactory() const {
174b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return GrTBackendFragmentProcessorFactory<Edge2PtConicalEffect>::getInstance();
175aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org}
176221b911f38cadfe6636bcc127c663fde548adc9askia.committer@gmail.com
177b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(Edge2PtConicalEffect);
178aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
1790125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt/*
1800125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt * All Two point conical gradient test create functions may occasionally create edge case shaders
1810125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt */
182b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* Edge2PtConicalEffect::TestCreate(SkRandom* random,
183b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                      GrContext* context,
184b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                      const GrDrawTargetCaps&,
185b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                      GrTexture**) {
186aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
187aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkScalar radius1 = random->nextUScalar1();
188aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkPoint center2;
189aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkScalar radius2;
190aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    do {
191aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org        center2.set(random->nextUScalar1(), random->nextUScalar1());
192aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org        // If the circles are identical the factory will give us an empty shader.
193c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // This will happen if we pick identical centers
194c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } while (center1 == center2);
195c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
196c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Below makes sure that circle one is contained within circle two
197c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // and both circles are touching on an edge
198c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint diff = center2 - center1;
199c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar diffLen = diff.length();
200c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    radius2 = radius1 + diffLen;
201aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
202aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkColor colors[kMaxRandomGradientColors];
203aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkScalar stopsArray[kMaxRandomGradientColors];
204aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkScalar* stops = stopsArray;
205aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkShader::TileMode tm;
206aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    int colorCount = RandomGradientParams(random, colors, &stops, &tm);
207aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1,
208aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org                                                                          center2, radius2,
209aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org                                                                          colors, stops, colorCount,
210aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org                                                                          tm));
211aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkPaint paint;
212b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrFragmentProcessor* fp;
21383d081ae1d731b5039e99823620f5e287542ee39bsalomon    GrColor paintColor;
214b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &fp));
215b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return fp;
216aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org}
217aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
218b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGLEdge2PtConicalEffect::GLEdge2PtConicalEffect(const GrBackendProcessorFactory& factory,
219b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                               const GrProcessor&)
220aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    : INHERITED(factory)
221aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    , fVSVaryingName(NULL)
222aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    , fFSVaryingName(NULL)
223aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    , fCachedRadius(-SK_ScalarMax)
224c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedDiffRadius(-SK_ScalarMax) {}
225c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
22630ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GLEdge2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
227b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                      const GrFragmentProcessor&,
228b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                      const GrProcessorKey& key,
229c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                      const char* outputColor,
230c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                      const char* inputColor,
231c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                      const TransformedCoordsArray& coords,
232c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                      const TextureSamplerArray& samplers) {
23363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    uint32_t baseKey = key.get32(0);
23463e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    this->emitUniforms(builder, baseKey);
23530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fParamUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
236c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                         kFloat_GrSLType, "Conical2FSParams", 3);
237aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
238aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkString cName("c");
239aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkString tName("t");
240c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString p0; // start radius
241c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString p1; // start radius squared
242c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString p2; // difference in radii (r1 - r0)
243aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
244aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    builder->getUniformVariable(fParamUni).appendArrayAccess(0, &p0);
245aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    builder->getUniformVariable(fParamUni).appendArrayAccess(1, &p1);
246aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    builder->getUniformVariable(fParamUni).appendArrayAccess(2, &p2);
247aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
248aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    // We interpolate the linear component in coords[1].
24923e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    SkASSERT(coords[0].getType() == coords[1].getType());
250aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    const char* coords2D;
251aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    SkString bVar;
25230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
25323e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    if (kVec3f_GrSLType == coords[0].getType()) {
25430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy / %s.z, %s.x / %s.z);\n",
25549586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt                               coords[0].c_str(), coords[0].c_str(), coords[1].c_str(),
25649586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt                               coords[1].c_str());
257aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org        coords2D = "interpolants.xy";
258aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org        bVar = "interpolants.z";
259aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    } else {
260aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org        coords2D = coords[0].c_str();
261aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org        bVar.printf("%s.x", coords[1].c_str());
262aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    }
263aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
264aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    // output will default to transparent black (we simply won't write anything
265aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    // else to it if invalid, instead of discarding or returning prematurely)
26630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
267aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
268c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // c = (x^2)+(y^2) - params[1]
26930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
270c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                           cName.c_str(), coords2D, coords2D, p1.c_str());
271c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
272c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // linear case: t = -c/b
27330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(),
274c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                           cName.c_str(), bVar.c_str());
275c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
276c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // if r(t) > 0, then t will be the x coordinate
27730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
278c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                           p2.c_str(), p0.c_str());
27930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppend("\t");
28063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
28130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppend("\t}\n");
282c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
283aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
2847510b224e52b9518a8ddf7418db0e9c258f79539kkinnunenvoid GLEdge2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
285b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                     const GrProcessor& processor) {
286b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    INHERITED::setData(pdman, processor);
287b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const Edge2PtConicalEffect& data = processor.cast<Edge2PtConicalEffect>();
288c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radius0 = data.radius();
289c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar diffRadius = data.diffRadius();
290aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
291c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (fCachedRadius != radius0 ||
292c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedDiffRadius != diffRadius) {
293aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
294c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        float values[3] = {
295c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            SkScalarToFloat(radius0),
296c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            SkScalarToFloat(SkScalarMul(radius0, radius0)),
297c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            SkScalarToFloat(diffRadius)
298c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        };
299c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
3007510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set1fv(fParamUni, 3, values);
301c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedRadius = radius0;
302c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedDiffRadius = diffRadius;
303c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
304c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
305c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
306b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLEdge2PtConicalEffect::GenKey(const GrProcessor& processor,
307b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                    const GrGLCaps&, GrProcessorKeyBuilder* b) {
308b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    b->add32(GenBaseGradientKey(processor));
309c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
310c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
311c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
312c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org// Focal Conical Gradients
313c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
314c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
315c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgstatic ConicalType set_matrix_focal_conical(const SkTwoPointConicalGradient& shader,
316c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                            SkMatrix* invLMatrix, SkScalar* focalX) {
317c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Inverse of the current local matrix is passed in then,
318c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // translate, scale, and rotate such that endCircle is unit circle on x-axis,
319c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // and focal point is at the origin.
320c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    ConicalType conicalType;
321c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const SkPoint& focal = shader.getStartCenter();
322c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const SkPoint& centerEnd = shader.getEndCenter();
323c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radius = shader.getEndRadius();
32480894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar invRadius = 1.f / radius;
325c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
326c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkMatrix matrix;
327aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
328c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.setTranslate(-centerEnd.fX, -centerEnd.fY);
329c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.postScale(invRadius, invRadius);
330aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
331c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint focalTrans;
332c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.mapPoints(&focalTrans, &focal, 1);
333c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    *focalX = focalTrans.length();
334aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
33580894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    if (0.f != *focalX) {
336c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkScalar invFocalX = SkScalarInvert(*focalX);
337c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkMatrix rot;
338c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        rot.setSinCos(-SkScalarMul(invFocalX, focalTrans.fY),
339c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                      SkScalarMul(invFocalX, focalTrans.fX));
340c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        matrix.postConcat(rot);
341c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
342c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
34380894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    matrix.postTranslate(-(*focalX), 0.f);
344c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
345c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // If the focal point is touching the edge of the circle it will
346c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // cause a degenerate case that must be handled separately
3478405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    // kEdgeErrorTol = 5 * kErrorTol was picked after manual testing the
3488405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    // stability trade off versus the linear approx used in the Edge Shader
3498405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    if (SkScalarAbs(1.f - (*focalX)) < kEdgeErrorTol) {
350c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return kEdge_ConicalType;
351c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
352c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
353c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Scale factor 1 / (1 - focalX * focalX)
35480894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar oneMinusF2 = 1.f - SkScalarMul(*focalX, *focalX);
35580894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar s = SkScalarDiv(1.f, oneMinusF2);
356c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
357c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
35880894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    if (s >= 0.f) {
359c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        conicalType = kInside_ConicalType;
360c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        matrix.postScale(s, s * SkScalarSqrt(oneMinusF2));
361aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    } else {
362c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        conicalType = kOutside_ConicalType;
363c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        matrix.postScale(s, s);
364c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
365c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
366c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    invLMatrix->postConcat(matrix);
367c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
368c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    return conicalType;
369c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
370c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
371c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
372c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
373c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLFocalOutside2PtConicalEffect;
374c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
375c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass FocalOutside2PtConicalEffect : public GrGradientEffect {
376c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
377c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
378b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrContext* ctx,
379b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkTwoPointConicalGradient& shader,
380b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkMatrix& matrix,
381b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkShader::TileMode tm,
382b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkScalar focalX) {
38355fad7af61c21d502acb9891d631e8aa29e3628cbsalomon        return SkNEW_ARGS(FocalOutside2PtConicalEffect, (ctx, shader, matrix, tm, focalX));
384c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
385c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
386c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~FocalOutside2PtConicalEffect() { }
387c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
388c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    static const char* Name() { return "Two-Point Conical Gradient Focal Outside"; }
389b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
390c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
391c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    bool isFlipped() const { return fIsFlipped; }
392c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar focal() const { return fFocalX; }
393c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
394b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GLFocalOutside2PtConicalEffect GLProcessor;
395c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
396c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
397b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual bool onIsEqual(const GrProcessor& sBase) const SK_OVERRIDE {
39849586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt        const FocalOutside2PtConicalEffect& s = sBase.cast<FocalOutside2PtConicalEffect>();
399c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return (INHERITED::onIsEqual(sBase) &&
400c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fFocalX == s.fFocalX &&
401c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fIsFlipped == s.fIsFlipped);
402c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
403c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
404c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    FocalOutside2PtConicalEffect(GrContext* ctx,
405c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 const SkTwoPointConicalGradient& shader,
406c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 const SkMatrix& matrix,
407c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 SkShader::TileMode tm,
408c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 SkScalar focalX)
409c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    : INHERITED(ctx, shader, matrix, tm), fFocalX(focalX), fIsFlipped(shader.isFlippedGrad()) {}
410c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
411b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
412c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
413c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar         fFocalX;
414c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    bool             fIsFlipped;
415c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
416c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGradientEffect INHERITED;
417c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
418c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
419c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLFocalOutside2PtConicalEffect : public GrGLGradientEffect {
420c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
421b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GLFocalOutside2PtConicalEffect(const GrBackendProcessorFactory& factory, const GrProcessor&);
422c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~GLFocalOutside2PtConicalEffect() { }
423c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
42430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    virtual void emitCode(GrGLProgramBuilder*,
425b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrFragmentProcessor&,
426b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrProcessorKey&,
427c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const char* outputColor,
428c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const char* inputColor,
429c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const TransformedCoordsArray&,
430c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const TextureSamplerArray&) SK_OVERRIDE;
431b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
432c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
433b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b);
434c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
435c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprotected:
436c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    UniformHandle fParamUni;
437c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
438c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fVSVaryingName;
439c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fFSVaryingName;
440c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
441c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    bool fIsFlipped;
442c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
443c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @{
444c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    /// Values last uploaded as uniforms
445c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
446c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedFocal;
447c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
448c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @}
449c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
450c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
451c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGLGradientEffect INHERITED;
452c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
453c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
454c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
455b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendFragmentProcessorFactory& FocalOutside2PtConicalEffect::getFactory() const {
456b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return GrTBackendFragmentProcessorFactory<FocalOutside2PtConicalEffect>::getInstance();
457c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
458c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
459b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(FocalOutside2PtConicalEffect);
460c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
4610125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt/*
4620125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt * All Two point conical gradient test create functions may occasionally create edge case shaders
4630125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt */
464b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* FocalOutside2PtConicalEffect::TestCreate(SkRandom* random,
465b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                              GrContext* context,
466b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                              const GrDrawTargetCaps&,
467b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                              GrTexture**) {
468c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
46980894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar radius1 = 0.f;
470c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint center2;
471c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radius2;
472c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    do {
473c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        center2.set(random->nextUScalar1(), random->nextUScalar1());
474ede0c5c7784ff4bd86e268d33df89c0ac432ca5bskia.committer@gmail.com        // Need to make sure the centers are not the same or else focal point will be inside
475c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } while (center1 == center2);
476c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkPoint diff = center2 - center1;
477c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkScalar diffLen = diff.length();
478c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // Below makes sure that the focal point is not contained within circle two
47980894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org        radius2 = random->nextRangeF(0.f, diffLen);
480c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
481c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkColor colors[kMaxRandomGradientColors];
482c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar stopsArray[kMaxRandomGradientColors];
483c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar* stops = stopsArray;
484c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkShader::TileMode tm;
485c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    int colorCount = RandomGradientParams(random, colors, &stops, &tm);
486c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1,
487c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          center2, radius2,
488c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          colors, stops, colorCount,
489c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          tm));
490c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPaint paint;
491b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrFragmentProcessor* effect;
49283d081ae1d731b5039e99823620f5e287542ee39bsalomon    GrColor paintColor;
493b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &effect));
4949de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    return effect;
495c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
496c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
497b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGLFocalOutside2PtConicalEffect::GLFocalOutside2PtConicalEffect(const GrBackendProcessorFactory& factory,
498b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                               const GrProcessor& processor)
499c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    : INHERITED(factory)
500c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fVSVaryingName(NULL)
501c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fFSVaryingName(NULL)
502c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedFocal(SK_ScalarMax) {
503b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const FocalOutside2PtConicalEffect& data = processor.cast<FocalOutside2PtConicalEffect>();
504c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    fIsFlipped = data.isFlipped();
505c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
506c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
50730ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GLFocalOutside2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
508b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                              const GrFragmentProcessor&,
509b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                              const GrProcessorKey& key,
510c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                              const char* outputColor,
511c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                              const char* inputColor,
512c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                              const TransformedCoordsArray& coords,
513c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                              const TextureSamplerArray& samplers) {
51463e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    uint32_t baseKey = key.get32(0);
51563e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    this->emitUniforms(builder, baseKey);
51630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fParamUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
517c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                         kFloat_GrSLType, "Conical2FSParams", 2);
518c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString tName("t");
519c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString p0; // focalX
520c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString p1; // 1 - focalX * focalX
521c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
522c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    builder->getUniformVariable(fParamUni).appendArrayAccess(0, &p0);
523c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    builder->getUniformVariable(fParamUni).appendArrayAccess(1, &p1);
524c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
525c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // if we have a vec3 from being in perspective, convert it to a vec2 first
52630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
52730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkString coords2DString = fsBuilder->ensureFSCoords2D(coords, 0);
528ede0c5c7784ff4bd86e268d33df89c0ac432ca5bskia.committer@gmail.com    const char* coords2D = coords2DString.c_str();
529c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
530c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // t = p.x * focal.x +/- sqrt(p.x^2 + (1 - focal.x^2) * p.y^2)
531aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
532c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // output will default to transparent black (we simply won't write anything
533c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // else to it if invalid, instead of discarding or returning prematurely)
53430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
535c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
53630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\tfloat xs = %s.x * %s.x;\n", coords2D, coords2D);
53730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\tfloat ys = %s.y * %s.y;\n", coords2D, coords2D);
53830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\tfloat d = xs + %s * ys;\n", p1.c_str());
539aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
540c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Must check to see if we flipped the circle order (to make sure start radius < end radius)
541c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // If so we must also flip sign on sqrt
542c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (!fIsFlipped) {
54330ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppendf("\tfloat %s = %s.x * %s  + sqrt(d);\n", tName.c_str(),
544c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                               coords2D, p0.c_str());
545c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } else {
54630ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppendf("\tfloat %s = %s.x * %s  - sqrt(d);\n", tName.c_str(),
547c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                               coords2D, p0.c_str());
548aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    }
549c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
55030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\tif (%s >= 0.0 && d >= 0.0) {\n", tName.c_str());
55130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppend("\t\t");
55263e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
55330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppend("\t}\n");
554aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org}
555aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
5567510b224e52b9518a8ddf7418db0e9c258f79539kkinnunenvoid GLFocalOutside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
557b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                             const GrProcessor& processor) {
558b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    INHERITED::setData(pdman, processor);
559b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const FocalOutside2PtConicalEffect& data = processor.cast<FocalOutside2PtConicalEffect>();
56044d83c1e81b0555efa94f78e2a53b862208cdd06commit-bot@chromium.org    SkASSERT(data.isFlipped() == fIsFlipped);
561c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar focal = data.focal();
562aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
563c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (fCachedFocal != focal) {
56480894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org        SkScalar oneMinus2F = 1.f - SkScalarMul(focal, focal);
565aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
566c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        float values[2] = {
567c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            SkScalarToFloat(focal),
568c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            SkScalarToFloat(oneMinus2F),
569aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org        };
570aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
5717510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set1fv(fParamUni, 2, values);
572c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedFocal = focal;
573aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org    }
574aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org}
575aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org
576b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLFocalOutside2PtConicalEffect::GenKey(const GrProcessor& processor,
577b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                            const GrGLCaps&, GrProcessorKeyBuilder* b) {
57863e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    uint32_t* key = b->add32n(2);
579b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    key[0] = GenBaseGradientKey(processor);
580b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    key[1] = processor.cast<FocalOutside2PtConicalEffect>().isFlipped();
581aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org}
5822af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
5832af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
5842af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
585c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLFocalInside2PtConicalEffect;
5862af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
587c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass FocalInside2PtConicalEffect : public GrGradientEffect {
588c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
589c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
590b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrContext* ctx,
591b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkTwoPointConicalGradient& shader,
592b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkMatrix& matrix,
593b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkShader::TileMode tm,
594b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkScalar focalX) {
59555fad7af61c21d502acb9891d631e8aa29e3628cbsalomon        return SkNEW_ARGS(FocalInside2PtConicalEffect, (ctx, shader, matrix, tm, focalX));
596c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
597c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
598c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~FocalInside2PtConicalEffect() {}
599c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
600c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    static const char* Name() { return "Two-Point Conical Gradient Focal Inside"; }
601b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
602c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
603c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar focal() const { return fFocalX; }
604c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
605b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GLFocalInside2PtConicalEffect GLProcessor;
606c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
607c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
608b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual bool onIsEqual(const GrProcessor& sBase) const SK_OVERRIDE {
60949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt        const FocalInside2PtConicalEffect& s = sBase.cast<FocalInside2PtConicalEffect>();
610c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return (INHERITED::onIsEqual(sBase) &&
611c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fFocalX == s.fFocalX);
6122af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org    }
6132af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
614c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    FocalInside2PtConicalEffect(GrContext* ctx,
615c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                const SkTwoPointConicalGradient& shader,
616c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                const SkMatrix& matrix,
617c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                SkShader::TileMode tm,
618c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                SkScalar focalX)
619c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        : INHERITED(ctx, shader, matrix, tm), fFocalX(focalX) {}
620c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
621b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
622c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
623c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar         fFocalX;
624c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
625c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGradientEffect INHERITED;
626c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
627c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
628c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLFocalInside2PtConicalEffect : public GrGLGradientEffect {
629c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
630b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GLFocalInside2PtConicalEffect(const GrBackendProcessorFactory& factory, const GrProcessor&);
631c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~GLFocalInside2PtConicalEffect() {}
632c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
63330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    virtual void emitCode(GrGLProgramBuilder*,
634b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrFragmentProcessor&,
635b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrProcessorKey&,
636c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const char* outputColor,
637c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const char* inputColor,
638c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const TransformedCoordsArray&,
639c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const TextureSamplerArray&) SK_OVERRIDE;
640b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
641c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
642b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b);
643c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
644c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprotected:
645c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    UniformHandle fFocalUni;
646c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
647c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fVSVaryingName;
648c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fFSVaryingName;
649c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
650c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @{
651c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    /// Values last uploaded as uniforms
652c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
653c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedFocal;
654c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
655c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @}
656c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
657c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
658c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGLGradientEffect INHERITED;
659c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
660c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
661c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
662b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendFragmentProcessorFactory& FocalInside2PtConicalEffect::getFactory() const {
663b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return GrTBackendFragmentProcessorFactory<FocalInside2PtConicalEffect>::getInstance();
664c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
665c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
666b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(FocalInside2PtConicalEffect);
667c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
6680125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt/*
6690125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt * All Two point conical gradient test create functions may occasionally create edge case shaders
6700125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt */
671b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* FocalInside2PtConicalEffect::TestCreate(SkRandom* random,
672b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                             GrContext* context,
673b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                             const GrDrawTargetCaps&,
674b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                             GrTexture**) {
675c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
67680894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar radius1 = 0.f;
677c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint center2;
678c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radius2;
679c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    do {
680c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        center2.set(random->nextUScalar1(), random->nextUScalar1());
681c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // Below makes sure radius2 is larger enouch such that the focal point
682c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // is inside the end circle
683c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkScalar increase = random->nextUScalar1();
684c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkPoint diff = center2 - center1;
685c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkScalar diffLen = diff.length();
686c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        radius2 = diffLen + increase;
687c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // If the circles are identical the factory will give us an empty shader.
688c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } while (radius1 == radius2 && center1 == center2);
689c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
690c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkColor colors[kMaxRandomGradientColors];
691c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar stopsArray[kMaxRandomGradientColors];
692c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar* stops = stopsArray;
693c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkShader::TileMode tm;
694c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    int colorCount = RandomGradientParams(random, colors, &stops, &tm);
695c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1,
696c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          center2, radius2,
697c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          colors, stops, colorCount,
698c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          tm));
699c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPaint paint;
70083d081ae1d731b5039e99823620f5e287542ee39bsalomon    GrColor paintColor;
701b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrFragmentProcessor* fp;
702b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &fp));
703b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return fp;
704c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
705c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
706b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGLFocalInside2PtConicalEffect::GLFocalInside2PtConicalEffect(const GrBackendProcessorFactory& factory,
707b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                             const GrProcessor&)
708c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    : INHERITED(factory)
709c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fVSVaryingName(NULL)
710c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fFSVaryingName(NULL)
711c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedFocal(SK_ScalarMax) {}
712c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
71330ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GLFocalInside2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
714b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                             const GrFragmentProcessor&,
715b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                             const GrProcessorKey& key,
716c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                             const char* outputColor,
717c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                             const char* inputColor,
718c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                             const TransformedCoordsArray& coords,
719c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                             const TextureSamplerArray& samplers) {
72063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    uint32_t baseKey = key.get32(0);
72163e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    this->emitUniforms(builder, baseKey);
72230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fFocalUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
723c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                    kFloat_GrSLType, "Conical2FSParams");
724c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString tName("t");
725c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
726c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // this is the distance along x-axis from the end center to focal point in
727c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // transformed coordinates
728c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    GrGLShaderVar focal = builder->getUniformVariable(fFocalUni);
729c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
730c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // if we have a vec3 from being in perspective, convert it to a vec2 first
73130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
73230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkString coords2DString = fsBuilder->ensureFSCoords2D(coords, 0);
733ede0c5c7784ff4bd86e268d33df89c0ac432ca5bskia.committer@gmail.com    const char* coords2D = coords2DString.c_str();
734c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
735c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // t = p.x * focalX + length(p)
73630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\tfloat %s = %s.x * %s  + length(%s);\n", tName.c_str(),
737c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                           coords2D, focal.c_str(), coords2D);
738c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
73963e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
740c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
741c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
7427510b224e52b9518a8ddf7418db0e9c258f79539kkinnunenvoid GLFocalInside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
743b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                            const GrProcessor& processor) {
744b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    INHERITED::setData(pdman, processor);
745b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const FocalInside2PtConicalEffect& data = processor.cast<FocalInside2PtConicalEffect>();
746c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar focal = data.focal();
747c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
748c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (fCachedFocal != focal) {
7497510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set1f(fFocalUni, SkScalarToFloat(focal));
750c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedFocal = focal;
751c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
752c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
753c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
754b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLFocalInside2PtConicalEffect::GenKey(const GrProcessor& processor,
755b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                           const GrGLCaps&, GrProcessorKeyBuilder* b) {
756b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    b->add32(GenBaseGradientKey(processor));
757c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
758c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
759c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
760c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org// Circle Conical Gradients
761c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
762c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
763c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgstruct CircleConicalInfo {
764c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint fCenterEnd;
765c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fA;
766c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fB;
767c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fC;
768c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
769c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
770c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org// Returns focal distance along x-axis in transformed coords
771c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgstatic ConicalType set_matrix_circle_conical(const SkTwoPointConicalGradient& shader,
772c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                             SkMatrix* invLMatrix, CircleConicalInfo* info) {
773c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Inverse of the current local matrix is passed in then,
774c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // translate and scale such that start circle is on the origin and has radius 1
775c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const SkPoint& centerStart = shader.getStartCenter();
776c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const SkPoint& centerEnd = shader.getEndCenter();
777c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radiusStart = shader.getStartRadius();
778c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radiusEnd = shader.getEndRadius();
779c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
780c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkMatrix matrix;
781c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
782c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.setTranslate(-centerStart.fX, -centerStart.fY);
783c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
78480894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar invStartRad = 1.f / radiusStart;
785c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.postScale(invStartRad, invStartRad);
786c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
787c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    radiusEnd /= radiusStart;
788c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
789c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint centerEndTrans;
790c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.mapPoints(&centerEndTrans, &centerEnd, 1);
791c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
792c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar A = centerEndTrans.fX * centerEndTrans.fX + centerEndTrans.fY * centerEndTrans.fY
793c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                 - radiusEnd * radiusEnd + 2 * radiusEnd - 1;
794c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
795c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Check to see if start circle is inside end circle with edges touching.
796c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // If touching we return that it is of kEdge_ConicalType, and leave the matrix setting
7978405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    // to the edge shader. kEdgeErrorTol = 5 * kErrorTol was picked after manual testing
7988405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    // so that C = 1 / A is stable, and the linear approximation used in the Edge shader is
7998405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    // still accurate.
8008405ef9854858b2527bf03b7e7abb1c0da59411degdaniel    if (SkScalarAbs(A) < kEdgeErrorTol) {
801c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return kEdge_ConicalType;
802c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
803c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
80480894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar C = 1.f / A;
80580894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar B = (radiusEnd - 1.f) * C;
806c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
807c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    matrix.postScale(C, C);
808c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
809c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    invLMatrix->postConcat(matrix);
810c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
811c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    info->fCenterEnd = centerEndTrans;
812c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    info->fA = A;
813c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    info->fB = B;
814c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    info->fC = C;
815c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
816c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // if A ends up being negative, the start circle is contained completely inside the end cirlce
81780894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    if (A < 0.f) {
818c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return kInside_ConicalType;
819c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
820c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    return kOutside_ConicalType;
821c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
822c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
823c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLCircleInside2PtConicalEffect;
824c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
825c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass CircleInside2PtConicalEffect : public GrGradientEffect {
826c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
827c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
828b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrContext* ctx,
829b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkTwoPointConicalGradient& shader,
830b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkMatrix& matrix,
831b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkShader::TileMode tm,
832b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const CircleConicalInfo& info) {
83355fad7af61c21d502acb9891d631e8aa29e3628cbsalomon        return SkNEW_ARGS(CircleInside2PtConicalEffect, (ctx, shader, matrix, tm, info));
834c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
835c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
836c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~CircleInside2PtConicalEffect() {}
837c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
838c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    static const char* Name() { return "Two-Point Conical Gradient Inside"; }
839b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
840c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
841c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerX() const { return fInfo.fCenterEnd.fX; }
842c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerY() const { return fInfo.fCenterEnd.fY; }
843c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar A() const { return fInfo.fA; }
844c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar B() const { return fInfo.fB; }
845c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar C() const { return fInfo.fC; }
846c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
847b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GLCircleInside2PtConicalEffect GLProcessor;
848c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
849c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
850b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual bool onIsEqual(const GrProcessor& sBase) const SK_OVERRIDE {
85149586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt        const CircleInside2PtConicalEffect& s = sBase.cast<CircleInside2PtConicalEffect>();
852c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return (INHERITED::onIsEqual(sBase) &&
853c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fCenterEnd == s.fInfo.fCenterEnd &&
854c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fA == s.fInfo.fA &&
855c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fB == s.fInfo.fB &&
856c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fC == s.fInfo.fC);
857c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
858c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
859c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    CircleInside2PtConicalEffect(GrContext* ctx,
860c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 const SkTwoPointConicalGradient& shader,
861c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 const SkMatrix& matrix,
862c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 SkShader::TileMode tm,
863c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                 const CircleConicalInfo& info)
864c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        : INHERITED(ctx, shader, matrix, tm), fInfo(info) {}
865c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
866b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
867c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
868c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const CircleConicalInfo fInfo;
869c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
870c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGradientEffect INHERITED;
871c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
872c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
873c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLCircleInside2PtConicalEffect : public GrGLGradientEffect {
874c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
875b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GLCircleInside2PtConicalEffect(const GrBackendProcessorFactory& factory, const GrProcessor&);
876c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~GLCircleInside2PtConicalEffect() {}
877c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
87830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    virtual void emitCode(GrGLProgramBuilder*,
879b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrFragmentProcessor&,
880b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrProcessorKey&,
881c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const char* outputColor,
882c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const char* inputColor,
883c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const TransformedCoordsArray&,
884c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const TextureSamplerArray&) SK_OVERRIDE;
885b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
886c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
887b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b);
888c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
889c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprotected:
890c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    UniformHandle fCenterUni;
891c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    UniformHandle fParamUni;
892c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
893c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fVSVaryingName;
894c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fFSVaryingName;
895c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
896c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @{
897c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    /// Values last uploaded as uniforms
898c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
899c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedCenterX;
900c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedCenterY;
901c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedA;
902c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedB;
903c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedC;
904c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
905c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @}
906c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
907c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
908c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGLGradientEffect INHERITED;
909c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
910c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
911c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
912b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendFragmentProcessorFactory& CircleInside2PtConicalEffect::getFactory() const {
913b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return GrTBackendFragmentProcessorFactory<CircleInside2PtConicalEffect>::getInstance();
914c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
915c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
916b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircleInside2PtConicalEffect);
917c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
9180125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt/*
9190125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt * All Two point conical gradient test create functions may occasionally create edge case shaders
9200125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt */
921b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* CircleInside2PtConicalEffect::TestCreate(SkRandom* random,
922b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                              GrContext* context,
923b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                              const GrDrawTargetCaps&,
924b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                              GrTexture**) {
925c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
92680894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar radius1 = random->nextUScalar1() + 0.0001f; // make sure radius1 != 0
927c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint center2;
928c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radius2;
929c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    do {
930c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        center2.set(random->nextUScalar1(), random->nextUScalar1());
931c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // Below makes sure that circle one is contained within circle two
932c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkScalar increase = random->nextUScalar1();
933c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkPoint diff = center2 - center1;
934c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkScalar diffLen = diff.length();
935c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        radius2 = radius1 + diffLen + increase;
936c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // If the circles are identical the factory will give us an empty shader.
937c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } while (radius1 == radius2 && center1 == center2);
938c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
939c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkColor colors[kMaxRandomGradientColors];
940c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar stopsArray[kMaxRandomGradientColors];
941c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar* stops = stopsArray;
942c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkShader::TileMode tm;
943c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    int colorCount = RandomGradientParams(random, colors, &stops, &tm);
944c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1,
945c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          center2, radius2,
946c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          colors, stops, colorCount,
947c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          tm));
948c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPaint paint;
94983d081ae1d731b5039e99823620f5e287542ee39bsalomon    GrColor paintColor;
950b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrFragmentProcessor* processor;
951b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &processor));
952b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return processor;
953c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
954c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
955b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGLCircleInside2PtConicalEffect::GLCircleInside2PtConicalEffect(const GrBackendProcessorFactory& factory,
956b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                               const GrProcessor& processor)
957c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    : INHERITED(factory)
958c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fVSVaryingName(NULL)
959c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fFSVaryingName(NULL)
960c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedCenterX(SK_ScalarMax)
961c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedCenterY(SK_ScalarMax)
962c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedA(SK_ScalarMax)
963c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedB(SK_ScalarMax)
964c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedC(SK_ScalarMax) {}
965c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
96630ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GLCircleInside2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
967b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                              const GrFragmentProcessor&,
968b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                              const GrProcessorKey& key,
969c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                              const char* outputColor,
970c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                              const char* inputColor,
971c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                              const TransformedCoordsArray& coords,
972c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                              const TextureSamplerArray& samplers) {
97363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    uint32_t baseKey = key.get32(0);
97463e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    this->emitUniforms(builder, baseKey);
97530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fCenterUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
976c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                     kVec2f_GrSLType, "Conical2FSCenter");
97730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fParamUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
978c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                    kVec3f_GrSLType, "Conical2FSParams");
979c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString tName("t");
980c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
981c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    GrGLShaderVar center = builder->getUniformVariable(fCenterUni);
982c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // params.x = A
983c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // params.y = B
984c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // params.z = C
985c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    GrGLShaderVar params = builder->getUniformVariable(fParamUni);
986c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
987c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // if we have a vec3 from being in perspective, convert it to a vec2 first
98830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
98930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkString coords2DString = fsBuilder->ensureFSCoords2D(coords, 0);
990ede0c5c7784ff4bd86e268d33df89c0ac432ca5bskia.committer@gmail.com    const char* coords2D = coords2DString.c_str();
991c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
992c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // p = coords2D
993c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // e = center end
994c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // r = radius end
995c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // A = dot(e, e) - r^2 + 2 * r - 1
996c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // B = (r -1) / A
997c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // C = 1 / A
998c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // d = dot(e, p) + B
999c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // t = d +/- sqrt(d^2 - A * dot(p, p) + C)
100030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\tfloat pDotp = dot(%s,  %s);\n", coords2D, coords2D);
100149586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    fsBuilder->codeAppendf("\tfloat d = dot(%s,  %s) + %s.y;\n", coords2D, center.c_str(),
100249586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt                           params.c_str());
100330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\tfloat %s = d + sqrt(d * d - %s.x * pDotp + %s.z);\n",
1004c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                           tName.c_str(), params.c_str(), params.c_str());
1005c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
100663e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
1007c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1008c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
10097510b224e52b9518a8ddf7418db0e9c258f79539kkinnunenvoid GLCircleInside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
1010b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                             const GrProcessor& processor) {
1011b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    INHERITED::setData(pdman, processor);
1012b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const CircleInside2PtConicalEffect& data = processor.cast<CircleInside2PtConicalEffect>();
1013c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerX = data.centerX();
1014c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerY = data.centerY();
1015c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar A = data.A();
1016c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar B = data.B();
1017c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar C = data.C();
1018c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1019c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (fCachedCenterX != centerX || fCachedCenterY != centerY ||
1020c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedA != A || fCachedB != B || fCachedC != C) {
1021c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
10227510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set2f(fCenterUni, SkScalarToFloat(centerX), SkScalarToFloat(centerY));
10237510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set3f(fParamUni, SkScalarToFloat(A), SkScalarToFloat(B), SkScalarToFloat(C));
1024c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1025c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedCenterX = centerX;
1026c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedCenterY = centerY;
1027c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedA = A;
1028c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedB = B;
1029c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedC = C;
1030c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1031c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1032c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1033b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLCircleInside2PtConicalEffect::GenKey(const GrProcessor& processor,
1034b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                            const GrGLCaps&, GrProcessorKeyBuilder* b) {
1035b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    b->add32(GenBaseGradientKey(processor));
1036c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1037c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1038c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
1039c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1040c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLCircleOutside2PtConicalEffect;
1041c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1042c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass CircleOutside2PtConicalEffect : public GrGradientEffect {
1043c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
1044c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1045b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrContext* ctx,
1046b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkTwoPointConicalGradient& shader,
1047b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkMatrix& matrix,
1048b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       SkShader::TileMode tm,
1049b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const CircleConicalInfo& info) {
105055fad7af61c21d502acb9891d631e8aa29e3628cbsalomon        return SkNEW_ARGS(CircleOutside2PtConicalEffect, (ctx, shader, matrix, tm, info));
1051c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1052c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1053c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~CircleOutside2PtConicalEffect() {}
1054c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1055c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    static const char* Name() { return "Two-Point Conical Gradient Outside"; }
1056b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
1057c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1058c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerX() const { return fInfo.fCenterEnd.fX; }
1059c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerY() const { return fInfo.fCenterEnd.fY; }
1060c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar A() const { return fInfo.fA; }
1061c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar B() const { return fInfo.fB; }
1062c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar C() const { return fInfo.fC; }
1063c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar tLimit() const { return fTLimit; }
1064c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    bool isFlipped() const { return fIsFlipped; }
1065c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1066b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GLCircleOutside2PtConicalEffect GLProcessor;
1067c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1068c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
1069b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual bool onIsEqual(const GrProcessor& sBase) const SK_OVERRIDE {
107049586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt        const CircleOutside2PtConicalEffect& s = sBase.cast<CircleOutside2PtConicalEffect>();
1071c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return (INHERITED::onIsEqual(sBase) &&
1072c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fCenterEnd == s.fInfo.fCenterEnd &&
1073c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fA == s.fInfo.fA &&
1074c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fB == s.fInfo.fB &&
1075c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fInfo.fC == s.fInfo.fC &&
1076c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fTLimit == s.fTLimit &&
1077c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                this->fIsFlipped == s.fIsFlipped);
1078c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1079c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1080c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    CircleOutside2PtConicalEffect(GrContext* ctx,
1081c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                  const SkTwoPointConicalGradient& shader,
1082c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                  const SkMatrix& matrix,
1083c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                  SkShader::TileMode tm,
1084c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                  const CircleConicalInfo& info)
1085c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        : INHERITED(ctx, shader, matrix, tm), fInfo(info) {
1086c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        if (shader.getStartRadius() != shader.getEndRadius()) {
108749586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt            fTLimit = SkScalarDiv(shader.getStartRadius(),
108849586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt                                  (shader.getStartRadius() - shader.getEndRadius()));
1089c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        } else {
1090c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            fTLimit = SK_ScalarMin;
1091c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        }
1092c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1093c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fIsFlipped = shader.isFlippedGrad();
1094c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1095c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1096b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
1097c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1098c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const CircleConicalInfo fInfo;
1099c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fTLimit;
1100c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    bool fIsFlipped;
1101c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1102c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGradientEffect INHERITED;
1103c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
1104c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1105c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgclass GLCircleOutside2PtConicalEffect : public GrGLGradientEffect {
1106c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgpublic:
1107b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GLCircleOutside2PtConicalEffect(const GrBackendProcessorFactory&, const GrProcessor&);
1108c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    virtual ~GLCircleOutside2PtConicalEffect() {}
1109c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
111030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    virtual void emitCode(GrGLProgramBuilder*,
1111b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrFragmentProcessor&,
1112b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrProcessorKey&,
1113c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const char* outputColor,
1114c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const char* inputColor,
1115c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const TransformedCoordsArray&,
1116c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                          const TextureSamplerArray&) SK_OVERRIDE;
1117b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE;
1118c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1119b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b);
1120c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1121c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprotected:
1122c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    UniformHandle fCenterUni;
1123c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    UniformHandle fParamUni;
1124c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1125c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fVSVaryingName;
1126c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    const char* fFSVaryingName;
1127c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1128c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    bool fIsFlipped;
1129c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1130c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @{
1131c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    /// Values last uploaded as uniforms
1132c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1133c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedCenterX;
1134c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedCenterY;
1135c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedA;
1136c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedB;
1137c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedC;
1138c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar fCachedTLimit;
1139c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1140c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // @}
1141c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1142c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.orgprivate:
1143c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    typedef GrGLGradientEffect INHERITED;
1144c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1145c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org};
1146c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1147b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendFragmentProcessorFactory& CircleOutside2PtConicalEffect::getFactory() const {
1148b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return GrTBackendFragmentProcessorFactory<CircleOutside2PtConicalEffect>::getInstance();
1149c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1150c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1151b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircleOutside2PtConicalEffect);
1152c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
11530125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt/*
11540125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt * All Two point conical gradient test create functions may occasionally create edge case shaders
11550125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt */
1156b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* CircleOutside2PtConicalEffect::TestCreate(SkRandom* random,
1157b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                               GrContext* context,
1158b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                               const GrDrawTargetCaps&,
1159b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                               GrTexture**) {
1160c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
116180894678ca7b54413ba50de4355b7816d5bc0e10commit-bot@chromium.org    SkScalar radius1 = random->nextUScalar1() + 0.0001f; // make sure radius1 != 0
1162c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPoint center2;
1163c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar radius2;
1164c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar diffLen;
1165c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    do {
1166c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        center2.set(random->nextUScalar1(), random->nextUScalar1());
1167c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        // If the circles share a center than we can't be in the outside case
1168c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } while (center1 == center2);
11690125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt    SkPoint diff = center2 - center1;
11700125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt    diffLen = diff.length();
11710125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt    // Below makes sure that circle one is not contained within circle two
11720125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt    // and have radius2 >= radius to match sorting on cpu side
11730125847c165d59c0efcbf9ab81e6b51715829afdjoshualitt    radius2 = radius1 + random->nextRangeF(0.f, diffLen);
1174c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1175c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkColor colors[kMaxRandomGradientColors];
1176c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar stopsArray[kMaxRandomGradientColors];
1177c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar* stops = stopsArray;
1178c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkShader::TileMode tm;
1179c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    int colorCount = RandomGradientParams(random, colors, &stops, &tm);
1180c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1,
1181c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          center2, radius2,
1182c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          colors, stops, colorCount,
1183c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                                                          tm));
1184c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkPaint paint;
118583d081ae1d731b5039e99823620f5e287542ee39bsalomon    GrColor paintColor;
1186b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GrFragmentProcessor* processor;
1187b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    SkAssertResult(shader->asFragmentProcessor(context, paint, NULL, &paintColor, &processor));
1188b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    return processor;
1189c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1190c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1191b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGLCircleOutside2PtConicalEffect::GLCircleOutside2PtConicalEffect(const GrBackendProcessorFactory& factory,
1192b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                                 const GrProcessor& processor)
1193c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    : INHERITED(factory)
1194c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fVSVaryingName(NULL)
1195c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fFSVaryingName(NULL)
1196c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedCenterX(SK_ScalarMax)
1197c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedCenterY(SK_ScalarMax)
1198c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedA(SK_ScalarMax)
1199c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedB(SK_ScalarMax)
1200c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedC(SK_ScalarMax)
1201c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    , fCachedTLimit(SK_ScalarMax) {
1202b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const CircleOutside2PtConicalEffect& data = processor.cast<CircleOutside2PtConicalEffect>();
1203c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    fIsFlipped = data.isFlipped();
1204c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1205c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
120630ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GLCircleOutside2PtConicalEffect::emitCode(GrGLProgramBuilder* builder,
1207b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                               const GrFragmentProcessor&,
1208b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                               const GrProcessorKey& key,
1209c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                               const char* outputColor,
1210c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                               const char* inputColor,
1211c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                               const TransformedCoordsArray& coords,
1212c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                               const TextureSamplerArray& samplers) {
121363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    uint32_t baseKey = key.get32(0);
121463e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    this->emitUniforms(builder, baseKey);
121530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fCenterUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
1216c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                     kVec2f_GrSLType, "Conical2FSCenter");
121730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fParamUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
1218c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                                    kVec4f_GrSLType, "Conical2FSParams");
1219c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkString tName("t");
1220c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1221c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    GrGLShaderVar center = builder->getUniformVariable(fCenterUni);
1222c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // params.x = A
1223c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // params.y = B
1224c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // params.z = C
1225c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    GrGLShaderVar params = builder->getUniformVariable(fParamUni);
1226c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1227c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // if we have a vec3 from being in perspective, convert it to a vec2 first
122830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
122930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkString coords2DString = fsBuilder->ensureFSCoords2D(coords, 0);
1230ede0c5c7784ff4bd86e268d33df89c0ac432ca5bskia.committer@gmail.com    const char* coords2D = coords2DString.c_str();
1231c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1232c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // output will default to transparent black (we simply won't write anything
1233c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // else to it if invalid, instead of discarding or returning prematurely)
123430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
1235c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1236c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // p = coords2D
1237c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // e = center end
1238c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // r = radius end
1239c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // A = dot(e, e) - r^2 + 2 * r - 1
1240c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // B = (r -1) / A
1241c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // C = 1 / A
1242c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // d = dot(e, p) + B
1243c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // t = d +/- sqrt(d^2 - A * dot(p, p) + C)
1244c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
124530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\tfloat pDotp = dot(%s,  %s);\n", coords2D, coords2D);
124649586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    fsBuilder->codeAppendf("\tfloat d = dot(%s,  %s) + %s.y;\n", coords2D, center.c_str(),
124749586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt                           params.c_str());
124849586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    fsBuilder->codeAppendf("\tfloat deter = d * d - %s.x * pDotp + %s.z;\n", params.c_str(),
124949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt                           params.c_str());
1250c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1251c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // Must check to see if we flipped the circle order (to make sure start radius < end radius)
1252c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    // If so we must also flip sign on sqrt
1253c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (!fIsFlipped) {
125430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppendf("\tfloat %s = d + sqrt(deter);\n", tName.c_str());
1255c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } else {
125630ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppendf("\tfloat %s = d - sqrt(deter);\n", tName.c_str());
1257c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1258c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
125930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\tif (%s >= %s.w && deter >= 0.0) {\n", tName.c_str(), params.c_str());
126030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppend("\t\t");
126163e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
126230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppend("\t}\n");
1263c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1264c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
12657510b224e52b9518a8ddf7418db0e9c258f79539kkinnunenvoid GLCircleOutside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
1266b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                              const GrProcessor& processor) {
1267b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    INHERITED::setData(pdman, processor);
1268b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const CircleOutside2PtConicalEffect& data = processor.cast<CircleOutside2PtConicalEffect>();
1269c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkASSERT(data.isFlipped() == fIsFlipped);
1270c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerX = data.centerX();
1271c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar centerY = data.centerY();
1272c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar A = data.A();
1273c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar B = data.B();
1274c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar C = data.C();
1275c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkScalar tLimit = data.tLimit();
1276c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1277c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (fCachedCenterX != centerX || fCachedCenterY != centerY ||
1278c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedA != A || fCachedB != B || fCachedC != C || fCachedTLimit != tLimit) {
1279c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
12807510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set2f(fCenterUni, SkScalarToFloat(centerX), SkScalarToFloat(centerY));
12817510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        pdman.set4f(fParamUni, SkScalarToFloat(A), SkScalarToFloat(B), SkScalarToFloat(C),
1282c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org                   SkScalarToFloat(tLimit));
1283c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1284c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedCenterX = centerX;
1285c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedCenterY = centerY;
1286c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedA = A;
1287c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedB = B;
1288c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedC = C;
1289c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        fCachedTLimit = tLimit;
1290c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1291c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1292c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1293b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLCircleOutside2PtConicalEffect::GenKey(const GrProcessor& processor,
1294b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                             const GrGLCaps&, GrProcessorKeyBuilder* b) {
129563e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    uint32_t* key = b->add32n(2);
1296b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    key[0] = GenBaseGradientKey(processor);
1297b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    key[1] = processor.cast<CircleOutside2PtConicalEffect>().isFlipped();
1298c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org}
1299c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1300c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
1301c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1302b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* Gr2PtConicalGradientEffect::Create(GrContext* ctx,
1303b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                        const SkTwoPointConicalGradient& shader,
1304b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                        SkShader::TileMode tm,
1305b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                        const SkMatrix* localMatrix) {
1306c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    SkMatrix matrix;
1307c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (!shader.getLocalMatrix().invert(&matrix)) {
1308c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return NULL;
1309c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
131096fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org    if (localMatrix) {
131196fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        SkMatrix inv;
131296fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        if (!localMatrix->invert(&inv)) {
131396fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org            return NULL;
131496fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        }
131596fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        matrix.postConcat(inv);
131696fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org    }
1317c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1318c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (shader.getStartRadius() < kErrorTol) {
1319c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        SkScalar focalX;
1320c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        ConicalType type = set_matrix_focal_conical(shader, &matrix, &focalX);
1321c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        if (type == kInside_ConicalType) {
1322c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            return FocalInside2PtConicalEffect::Create(ctx, shader, matrix, tm, focalX);
1323c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        } else if(type == kEdge_ConicalType) {
1324c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            set_matrix_edge_conical(shader, &matrix);
1325c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            return Edge2PtConicalEffect::Create(ctx, shader, matrix, tm);
1326c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        } else {
1327c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org            return FocalOutside2PtConicalEffect::Create(ctx, shader, matrix, tm, focalX);
1328c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        }
1329c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
1330c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1331c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    CircleConicalInfo info;
1332c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    ConicalType type = set_matrix_circle_conical(shader, &matrix, &info);
1333c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org
1334c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    if (type == kInside_ConicalType) {
1335c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return CircleInside2PtConicalEffect::Create(ctx, shader, matrix, tm, info);
1336c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } else if (type == kEdge_ConicalType) {
1337c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        set_matrix_edge_conical(shader, &matrix);
1338c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return Edge2PtConicalEffect::Create(ctx, shader, matrix, tm);
1339c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    } else {
1340c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org        return CircleOutside2PtConicalEffect::Create(ctx, shader, matrix, tm, info);
1341c8379d7f1b5ac9a53792cedf47e942262759d4a6commit-bot@chromium.org    }
13422af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org}
13432af1a2dbc46ea41e6208ad0c8681f98bd9b27bd8commit-bot@chromium.org
1344aa64fbfd349789f27b3cc35c1968d9dc0612cf8ecommit-bot@chromium.org#endif
1345