| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1 |  | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 2 | /* | 
 | 3 |  * Copyright 2014 Google Inc. | 
 | 4 |  * | 
 | 5 |  * Use of this source code is governed by a BSD-style license that can be | 
 | 6 |  * found in the LICENSE file. | 
 | 7 |  */ | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 8 |  | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 9 | #include "SkTwoPointConicalGradient_gpu.h" | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 10 |  | 
 | 11 | #include "SkTwoPointConicalGradient.h" | 
 | 12 |  | 
| commit-bot@chromium.org | ef93d29 | 2014-04-10 15:37:52 +0000 | [diff] [blame] | 13 | #if SK_SUPPORT_GPU | 
| joshualitt | 8ca93e7 | 2015-07-08 06:51:43 -0700 | [diff] [blame] | 14 | #include "GrPaint.h" | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 15 | #include "gl/builders/GrGLProgramBuilder.h" | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 16 | // For brevity | 
| kkinnunen | 7510b22 | 2014-07-30 00:04:16 -0700 | [diff] [blame] | 17 | typedef GrGLProgramDataManager::UniformHandle UniformHandle; | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 18 |  | 
| commit-bot@chromium.org | 8089467 | 2014-04-22 21:24:22 +0000 | [diff] [blame] | 19 | static const SkScalar kErrorTol = 0.00001f; | 
| egdaniel | 8405ef9 | 2014-06-09 11:57:28 -0700 | [diff] [blame] | 20 | static const SkScalar kEdgeErrorTol = 5.f * kErrorTol; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 21 |  | 
 | 22 | /** | 
 | 23 |  * We have three general cases for 2pt conical gradients. First we always assume that | 
 | 24 |  * the start radius <= end radius. Our first case (kInside_) is when the start circle | 
 | 25 |  * is completely enclosed by the end circle. The second case (kOutside_) is the case | 
 | 26 |  * when the start circle is either completely outside the end circle or the circles | 
 | 27 |  * overlap. The final case (kEdge_) is when the start circle is inside the end one, | 
 | 28 |  * but the two are just barely touching at 1 point along their edges. | 
 | 29 |  */ | 
 | 30 | enum ConicalType { | 
 | 31 |     kInside_ConicalType, | 
 | 32 |     kOutside_ConicalType, | 
 | 33 |     kEdge_ConicalType, | 
 | 34 | }; | 
 | 35 |  | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 36 | ////////////////////////////////////////////////////////////////////////////// | 
 | 37 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 38 | static void set_matrix_edge_conical(const SkTwoPointConicalGradient& shader, | 
 | 39 |                                     SkMatrix* invLMatrix) { | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 40 |     // Inverse of the current local matrix is passed in then, | 
 | 41 |     // translate to center1, rotate so center2 is on x axis. | 
 | 42 |     const SkPoint& center1 = shader.getStartCenter(); | 
 | 43 |     const SkPoint& center2 = shader.getEndCenter(); | 
 | 44 |  | 
 | 45 |     invLMatrix->postTranslate(-center1.fX, -center1.fY); | 
 | 46 |  | 
 | 47 |     SkPoint diff = center2 - center1; | 
 | 48 |     SkScalar diffLen = diff.length(); | 
 | 49 |     if (0 != diffLen) { | 
 | 50 |         SkScalar invDiffLen = SkScalarInvert(diffLen); | 
 | 51 |         SkMatrix rot; | 
 | 52 |         rot.setSinCos(-SkScalarMul(invDiffLen, diff.fY), | 
 | 53 |                        SkScalarMul(invDiffLen, diff.fX)); | 
 | 54 |         invLMatrix->postConcat(rot); | 
 | 55 |     } | 
 | 56 | } | 
 | 57 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 58 | class Edge2PtConicalEffect : public GrGradientEffect { | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 59 | public: | 
 | 60 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 61 |     static GrFragmentProcessor* Create(GrContext* ctx, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 62 |                                        GrProcessorDataManager* procDataManager, | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 63 |                                        const SkTwoPointConicalGradient& shader, | 
 | 64 |                                        const SkMatrix& matrix, | 
 | 65 |                                        SkShader::TileMode tm) { | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 66 |         return SkNEW_ARGS(Edge2PtConicalEffect, (ctx, procDataManager, shader, matrix, tm)); | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 67 |     } | 
 | 68 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 69 |     virtual ~Edge2PtConicalEffect() {} | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 70 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 71 |     const char* name() const override { | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 72 |         return "Two-Point Conical Gradient Edge Touching"; | 
 | 73 |     } | 
 | 74 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 75 |     GrGLFragmentProcessor* createGLInstance() const override; | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 76 |  | 
 | 77 |     // The radial gradient parameters can collapse to a linear (instead of quadratic) equation. | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 78 |     SkScalar center() const { return fCenterX1; } | 
 | 79 |     SkScalar diffRadius() const { return fDiffRadius; } | 
 | 80 |     SkScalar radius() const { return fRadius0; } | 
 | 81 |  | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 82 | private: | 
| wangyix | 4b3050b | 2015-08-04 07:59:37 -0700 | [diff] [blame^] | 83 |     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override; | 
 | 84 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 85 |     bool onIsEqual(const GrFragmentProcessor& sBase) const override { | 
| joshualitt | 49586be | 2014-09-16 08:21:41 -0700 | [diff] [blame] | 86 |         const Edge2PtConicalEffect& s = sBase.cast<Edge2PtConicalEffect>(); | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 87 |         return (INHERITED::onIsEqual(sBase) && | 
 | 88 |                 this->fCenterX1 == s.fCenterX1 && | 
 | 89 |                 this->fRadius0 == s.fRadius0 && | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 90 |                 this->fDiffRadius == s.fDiffRadius); | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 91 |     } | 
 | 92 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 93 |     Edge2PtConicalEffect(GrContext* ctx, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 94 |                          GrProcessorDataManager* procDataManager, | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 95 |                          const SkTwoPointConicalGradient& shader, | 
 | 96 |                          const SkMatrix& matrix, | 
 | 97 |                          SkShader::TileMode tm) | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 98 |         : INHERITED(ctx, procDataManager, shader, matrix, tm), | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 99 |         fCenterX1(shader.getCenterX1()), | 
 | 100 |         fRadius0(shader.getStartRadius()), | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 101 |         fDiffRadius(shader.getDiffRadius()){ | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 102 |         this->initClassID<Edge2PtConicalEffect>(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 103 |         // We should only be calling this shader if we are degenerate case with touching circles | 
| egdaniel | 8405ef9 | 2014-06-09 11:57:28 -0700 | [diff] [blame] | 104 |         // When deciding if we are in edge case, we scaled by the end radius for cases when the | 
| joshualitt | 0125847 | 2014-09-22 10:29:30 -0700 | [diff] [blame] | 105 |         // start radius was close to zero, otherwise we scaled by the start radius.  In addition | 
 | 106 |         // Our test for the edge case in set_matrix_circle_conical has a higher tolerance so we | 
 | 107 |         // need the sqrt value below | 
 | 108 |         SkASSERT(SkScalarAbs(SkScalarAbs(fDiffRadius) - fCenterX1) < | 
 | 109 |                  (fRadius0 < kErrorTol ? shader.getEndRadius() * kEdgeErrorTol : | 
 | 110 |                                          fRadius0 * sqrt(kEdgeErrorTol))); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 111 |  | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 112 |         // We pass the linear part of the quadratic as a varying. | 
 | 113 |         //    float b = -2.0 * (fCenterX1 * x + fRadius0 * fDiffRadius * z) | 
 | 114 |         fBTransform = this->getCoordTransform(); | 
 | 115 |         SkMatrix& bMatrix = *fBTransform.accessMatrix(); | 
 | 116 |         SkScalar r0dr = SkScalarMul(fRadius0, fDiffRadius); | 
 | 117 |         bMatrix[SkMatrix::kMScaleX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::kMScaleX]) + | 
 | 118 |                                             SkScalarMul(r0dr, bMatrix[SkMatrix::kMPersp0])); | 
 | 119 |         bMatrix[SkMatrix::kMSkewX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::kMSkewX]) + | 
 | 120 |                                            SkScalarMul(r0dr, bMatrix[SkMatrix::kMPersp1])); | 
 | 121 |         bMatrix[SkMatrix::kMTransX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::kMTransX]) + | 
 | 122 |                                             SkScalarMul(r0dr, bMatrix[SkMatrix::kMPersp2])); | 
 | 123 |         this->addCoordTransform(&fBTransform); | 
 | 124 |     } | 
 | 125 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 126 |     GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 127 |  | 
 | 128 |     // @{ | 
 | 129 |     // Cache of values - these can change arbitrarily, EXCEPT | 
 | 130 |     // we shouldn't change between degenerate and non-degenerate?! | 
 | 131 |  | 
 | 132 |     GrCoordTransform fBTransform; | 
 | 133 |     SkScalar         fCenterX1; | 
 | 134 |     SkScalar         fRadius0; | 
 | 135 |     SkScalar         fDiffRadius; | 
 | 136 |  | 
 | 137 |     // @} | 
 | 138 |  | 
 | 139 |     typedef GrGradientEffect INHERITED; | 
 | 140 | }; | 
 | 141 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 142 | class GLEdge2PtConicalEffect : public GrGLGradientEffect { | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 143 | public: | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 144 |     GLEdge2PtConicalEffect(const GrProcessor&); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 145 |     virtual ~GLEdge2PtConicalEffect() { } | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 146 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 147 |     virtual void emitCode(EmitArgs&) override; | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 148 |     void setData(const GrGLProgramDataManager&, const GrProcessor&) override; | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 149 |  | 
| jvanverth | cfc1886 | 2015-04-28 08:48:20 -0700 | [diff] [blame] | 150 |     static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 151 |  | 
 | 152 | protected: | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 153 |     UniformHandle fParamUni; | 
 | 154 |  | 
 | 155 |     const char* fVSVaryingName; | 
 | 156 |     const char* fFSVaryingName; | 
 | 157 |  | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 158 |     // @{ | 
 | 159 |     /// Values last uploaded as uniforms | 
 | 160 |  | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 161 |     SkScalar fCachedRadius; | 
 | 162 |     SkScalar fCachedDiffRadius; | 
 | 163 |  | 
 | 164 |     // @} | 
 | 165 |  | 
 | 166 | private: | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 167 |     typedef GrGLGradientEffect INHERITED; | 
 | 168 |  | 
 | 169 | }; | 
 | 170 |  | 
| wangyix | 4b3050b | 2015-08-04 07:59:37 -0700 | [diff] [blame^] | 171 | void Edge2PtConicalEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 172 |                                              GrProcessorKeyBuilder* b) const { | 
 | 173 |     GLEdge2PtConicalEffect::GenKey(*this, caps, b); | 
 | 174 | } | 
 | 175 |  | 
 | 176 | GrGLFragmentProcessor* Edge2PtConicalEffect::createGLInstance() const { | 
 | 177 |     return SkNEW_ARGS(GLEdge2PtConicalEffect, (*this)); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 178 | } | 
| skia.committer@gmail.com | 221b911 | 2014-04-04 03:04:32 +0000 | [diff] [blame] | 179 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 180 | GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Edge2PtConicalEffect); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 181 |  | 
| joshualitt | 0125847 | 2014-09-22 10:29:30 -0700 | [diff] [blame] | 182 | /* | 
 | 183 |  * All Two point conical gradient test create functions may occasionally create edge case shaders | 
 | 184 |  */ | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 185 | GrFragmentProcessor* Edge2PtConicalEffect::TestCreate(GrProcessorTestData* d) { | 
 | 186 |     SkPoint center1 = {d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()}; | 
 | 187 |     SkScalar radius1 = d->fRandom->nextUScalar1(); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 188 |     SkPoint center2; | 
 | 189 |     SkScalar radius2; | 
 | 190 |     do { | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 191 |         center2.set(d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 192 |         // If the circles are identical the factory will give us an empty shader. | 
 | 193 |         // This will happen if we pick identical centers | 
 | 194 |     } while (center1 == center2); | 
 | 195 |  | 
 | 196 |     // Below makes sure that circle one is contained within circle two | 
 | 197 |     // and both circles are touching on an edge | 
 | 198 |     SkPoint diff = center2 - center1; | 
 | 199 |     SkScalar diffLen = diff.length(); | 
 | 200 |     radius2 = radius1 + diffLen; | 
 | 201 |  | 
 | 202 |     SkColor colors[kMaxRandomGradientColors]; | 
 | 203 |     SkScalar stopsArray[kMaxRandomGradientColors]; | 
 | 204 |     SkScalar* stops = stopsArray; | 
 | 205 |     SkShader::TileMode tm; | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 206 |     int colorCount = RandomGradientParams(d->fRandom, colors, &stops, &tm); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 207 |     SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1, | 
 | 208 |                                                                           center2, radius2, | 
 | 209 |                                                                           colors, stops, colorCount, | 
 | 210 |                                                                           tm)); | 
 | 211 |     SkPaint paint; | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 212 |     GrFragmentProcessor* fp; | 
| bsalomon | 83d081a | 2014-07-08 09:56:10 -0700 | [diff] [blame] | 213 |     GrColor paintColor; | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 214 |     SkAssertResult(shader->asFragmentProcessor(d->fContext, paint, | 
 | 215 |                                                GrTest::TestMatrix(d->fRandom), NULL, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 216 |                                                &paintColor, d->fProcDataManager, &fp)); | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 217 |     return fp; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 218 | } | 
 | 219 |  | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 220 | GLEdge2PtConicalEffect::GLEdge2PtConicalEffect(const GrProcessor&) | 
 | 221 |     : fVSVaryingName(NULL) | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 222 |     , fFSVaryingName(NULL) | 
 | 223 |     , fCachedRadius(-SK_ScalarMax) | 
 | 224 |     , fCachedDiffRadius(-SK_ScalarMax) {} | 
 | 225 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 226 | void GLEdge2PtConicalEffect::emitCode(EmitArgs& args) { | 
 | 227 |     const Edge2PtConicalEffect& ge = args.fFp.cast<Edge2PtConicalEffect>(); | 
 | 228 |     this->emitUniforms(args.fBuilder, ge); | 
 | 229 |     fParamUni = args.fBuilder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility, | 
| bsalomon | 422f56f | 2014-12-09 10:18:12 -0800 | [diff] [blame] | 230 |                                          kFloat_GrSLType, kDefault_GrSLPrecision, | 
 | 231 |                                          "Conical2FSParams", 3); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 232 |  | 
 | 233 |     SkString cName("c"); | 
 | 234 |     SkString tName("t"); | 
 | 235 |     SkString p0; // start radius | 
 | 236 |     SkString p1; // start radius squared | 
 | 237 |     SkString p2; // difference in radii (r1 - r0) | 
 | 238 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 239 |     args.fBuilder->getUniformVariable(fParamUni).appendArrayAccess(0, &p0); | 
 | 240 |     args.fBuilder->getUniformVariable(fParamUni).appendArrayAccess(1, &p1); | 
 | 241 |     args.fBuilder->getUniformVariable(fParamUni).appendArrayAccess(2, &p2); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 242 |  | 
 | 243 |     // We interpolate the linear component in coords[1]. | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 244 |     SkASSERT(args.fCoords[0].getType() == args.fCoords[1].getType()); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 245 |     const char* coords2D; | 
 | 246 |     SkString bVar; | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 247 |     GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); | 
 | 248 |     if (kVec3f_GrSLType == args.fCoords[0].getType()) { | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 249 |         fsBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy / %s.z, %s.x / %s.z);\n", | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 250 |                                args.fCoords[0].c_str(), args.fCoords[0].c_str(), | 
 | 251 |                                args.fCoords[1].c_str(), args.fCoords[1].c_str()); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 252 |         coords2D = "interpolants.xy"; | 
 | 253 |         bVar = "interpolants.z"; | 
 | 254 |     } else { | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 255 |         coords2D = args.fCoords[0].c_str(); | 
 | 256 |         bVar.printf("%s.x", args.fCoords[1].c_str()); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 257 |     } | 
 | 258 |  | 
 | 259 |     // output will default to transparent black (we simply won't write anything | 
 | 260 |     // else to it if invalid, instead of discarding or returning prematurely) | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 261 |     fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 262 |  | 
 | 263 |     // c = (x^2)+(y^2) - params[1] | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 264 |     fsBuilder->codeAppendf("\tfloat %s = dot(%s, %s) - %s;\n", | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 265 |                            cName.c_str(), coords2D, coords2D, p1.c_str()); | 
 | 266 |  | 
 | 267 |     // linear case: t = -c/b | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 268 |     fsBuilder->codeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(), | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 269 |                            cName.c_str(), bVar.c_str()); | 
 | 270 |  | 
 | 271 |     // if r(t) > 0, then t will be the x coordinate | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 272 |     fsBuilder->codeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(), | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 273 |                            p2.c_str(), p0.c_str()); | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 274 |     fsBuilder->codeAppend("\t"); | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 275 |     this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor, | 
 | 276 |                     args.fSamplers); | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 277 |     fsBuilder->codeAppend("\t}\n"); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 278 | } | 
 | 279 |  | 
| kkinnunen | 7510b22 | 2014-07-30 00:04:16 -0700 | [diff] [blame] | 280 | void GLEdge2PtConicalEffect::setData(const GrGLProgramDataManager& pdman, | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 281 |                                      const GrProcessor& processor) { | 
 | 282 |     INHERITED::setData(pdman, processor); | 
 | 283 |     const Edge2PtConicalEffect& data = processor.cast<Edge2PtConicalEffect>(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 284 |     SkScalar radius0 = data.radius(); | 
 | 285 |     SkScalar diffRadius = data.diffRadius(); | 
 | 286 |  | 
 | 287 |     if (fCachedRadius != radius0 || | 
 | 288 |         fCachedDiffRadius != diffRadius) { | 
 | 289 |  | 
 | 290 |         float values[3] = { | 
 | 291 |             SkScalarToFloat(radius0), | 
 | 292 |             SkScalarToFloat(SkScalarMul(radius0, radius0)), | 
 | 293 |             SkScalarToFloat(diffRadius) | 
 | 294 |         }; | 
 | 295 |  | 
| kkinnunen | 7510b22 | 2014-07-30 00:04:16 -0700 | [diff] [blame] | 296 |         pdman.set1fv(fParamUni, 3, values); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 297 |         fCachedRadius = radius0; | 
 | 298 |         fCachedDiffRadius = diffRadius; | 
 | 299 |     } | 
 | 300 | } | 
 | 301 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 302 | void GLEdge2PtConicalEffect::GenKey(const GrProcessor& processor, | 
| jvanverth | cfc1886 | 2015-04-28 08:48:20 -0700 | [diff] [blame] | 303 |                                     const GrGLSLCaps&, GrProcessorKeyBuilder* b) { | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 304 |     b->add32(GenBaseGradientKey(processor)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 305 | } | 
 | 306 |  | 
 | 307 | ////////////////////////////////////////////////////////////////////////////// | 
 | 308 | // Focal Conical Gradients | 
 | 309 | ////////////////////////////////////////////////////////////////////////////// | 
 | 310 |  | 
 | 311 | static ConicalType set_matrix_focal_conical(const SkTwoPointConicalGradient& shader, | 
 | 312 |                                             SkMatrix* invLMatrix, SkScalar* focalX) { | 
 | 313 |     // Inverse of the current local matrix is passed in then, | 
 | 314 |     // translate, scale, and rotate such that endCircle is unit circle on x-axis, | 
 | 315 |     // and focal point is at the origin. | 
 | 316 |     ConicalType conicalType; | 
 | 317 |     const SkPoint& focal = shader.getStartCenter(); | 
 | 318 |     const SkPoint& centerEnd = shader.getEndCenter(); | 
 | 319 |     SkScalar radius = shader.getEndRadius(); | 
| commit-bot@chromium.org | 8089467 | 2014-04-22 21:24:22 +0000 | [diff] [blame] | 320 |     SkScalar invRadius = 1.f / radius; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 321 |  | 
 | 322 |     SkMatrix matrix; | 
 | 323 |  | 
 | 324 |     matrix.setTranslate(-centerEnd.fX, -centerEnd.fY); | 
 | 325 |     matrix.postScale(invRadius, invRadius); | 
 | 326 |  | 
 | 327 |     SkPoint focalTrans; | 
 | 328 |     matrix.mapPoints(&focalTrans, &focal, 1); | 
 | 329 |     *focalX = focalTrans.length(); | 
 | 330 |  | 
| commit-bot@chromium.org | 8089467 | 2014-04-22 21:24:22 +0000 | [diff] [blame] | 331 |     if (0.f != *focalX) { | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 332 |         SkScalar invFocalX = SkScalarInvert(*focalX); | 
 | 333 |         SkMatrix rot; | 
 | 334 |         rot.setSinCos(-SkScalarMul(invFocalX, focalTrans.fY), | 
 | 335 |                       SkScalarMul(invFocalX, focalTrans.fX)); | 
 | 336 |         matrix.postConcat(rot); | 
 | 337 |     } | 
 | 338 |  | 
| commit-bot@chromium.org | 8089467 | 2014-04-22 21:24:22 +0000 | [diff] [blame] | 339 |     matrix.postTranslate(-(*focalX), 0.f); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 340 |  | 
 | 341 |     // If the focal point is touching the edge of the circle it will | 
 | 342 |     // cause a degenerate case that must be handled separately | 
| egdaniel | 8405ef9 | 2014-06-09 11:57:28 -0700 | [diff] [blame] | 343 |     // kEdgeErrorTol = 5 * kErrorTol was picked after manual testing the | 
 | 344 |     // stability trade off versus the linear approx used in the Edge Shader | 
 | 345 |     if (SkScalarAbs(1.f - (*focalX)) < kEdgeErrorTol) { | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 346 |         return kEdge_ConicalType; | 
 | 347 |     } | 
 | 348 |  | 
 | 349 |     // Scale factor 1 / (1 - focalX * focalX) | 
| commit-bot@chromium.org | 8089467 | 2014-04-22 21:24:22 +0000 | [diff] [blame] | 350 |     SkScalar oneMinusF2 = 1.f - SkScalarMul(*focalX, *focalX); | 
| reed | 80ea19c | 2015-05-12 10:37:34 -0700 | [diff] [blame] | 351 |     SkScalar s = SkScalarInvert(oneMinusF2); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 352 |  | 
 | 353 |  | 
| commit-bot@chromium.org | 8089467 | 2014-04-22 21:24:22 +0000 | [diff] [blame] | 354 |     if (s >= 0.f) { | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 355 |         conicalType = kInside_ConicalType; | 
 | 356 |         matrix.postScale(s, s * SkScalarSqrt(oneMinusF2)); | 
 | 357 |     } else { | 
 | 358 |         conicalType = kOutside_ConicalType; | 
 | 359 |         matrix.postScale(s, s); | 
 | 360 |     } | 
 | 361 |  | 
 | 362 |     invLMatrix->postConcat(matrix); | 
 | 363 |  | 
 | 364 |     return conicalType; | 
 | 365 | } | 
 | 366 |  | 
 | 367 | ////////////////////////////////////////////////////////////////////////////// | 
 | 368 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 369 | class FocalOutside2PtConicalEffect : public GrGradientEffect { | 
 | 370 | public: | 
 | 371 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 372 |     static GrFragmentProcessor* Create(GrContext* ctx, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 373 |                                        GrProcessorDataManager* procDataManager, | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 374 |                                        const SkTwoPointConicalGradient& shader, | 
 | 375 |                                        const SkMatrix& matrix, | 
 | 376 |                                        SkShader::TileMode tm, | 
 | 377 |                                        SkScalar focalX) { | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 378 |         return SkNEW_ARGS(FocalOutside2PtConicalEffect, (ctx, procDataManager, shader, matrix, tm, | 
| joshualitt | b245605 | 2015-07-08 09:36:59 -0700 | [diff] [blame] | 379 |                                                          focalX)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 380 |     } | 
 | 381 |  | 
 | 382 |     virtual ~FocalOutside2PtConicalEffect() { } | 
 | 383 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 384 |     const char* name() const override { | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 385 |         return "Two-Point Conical Gradient Focal Outside"; | 
 | 386 |     } | 
 | 387 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 388 |     GrGLFragmentProcessor* createGLInstance() const override; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 389 |  | 
 | 390 |     bool isFlipped() const { return fIsFlipped; } | 
 | 391 |     SkScalar focal() const { return fFocalX; } | 
 | 392 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 393 | private: | 
| wangyix | 4b3050b | 2015-08-04 07:59:37 -0700 | [diff] [blame^] | 394 |     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override; | 
 | 395 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 396 |     bool onIsEqual(const GrFragmentProcessor& sBase) const override { | 
| joshualitt | 49586be | 2014-09-16 08:21:41 -0700 | [diff] [blame] | 397 |         const FocalOutside2PtConicalEffect& s = sBase.cast<FocalOutside2PtConicalEffect>(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 398 |         return (INHERITED::onIsEqual(sBase) && | 
 | 399 |                 this->fFocalX == s.fFocalX && | 
 | 400 |                 this->fIsFlipped == s.fIsFlipped); | 
 | 401 |     } | 
 | 402 |  | 
 | 403 |     FocalOutside2PtConicalEffect(GrContext* ctx, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 404 |                                  GrProcessorDataManager* procDataManager, | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 405 |                                  const SkTwoPointConicalGradient& shader, | 
 | 406 |                                  const SkMatrix& matrix, | 
 | 407 |                                  SkShader::TileMode tm, | 
 | 408 |                                  SkScalar focalX) | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 409 |     : INHERITED(ctx, procDataManager, shader, matrix, tm) | 
| joshualitt | b245605 | 2015-07-08 09:36:59 -0700 | [diff] [blame] | 410 |     , fFocalX(focalX) | 
 | 411 |     , fIsFlipped(shader.isFlippedGrad()) { | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 412 |         this->initClassID<FocalOutside2PtConicalEffect>(); | 
 | 413 |     } | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 414 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 415 |     GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 416 |  | 
 | 417 |     SkScalar         fFocalX; | 
 | 418 |     bool             fIsFlipped; | 
 | 419 |  | 
 | 420 |     typedef GrGradientEffect INHERITED; | 
 | 421 | }; | 
 | 422 |  | 
 | 423 | class GLFocalOutside2PtConicalEffect : public GrGLGradientEffect { | 
 | 424 | public: | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 425 |     GLFocalOutside2PtConicalEffect(const GrProcessor&); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 426 |     virtual ~GLFocalOutside2PtConicalEffect() { } | 
 | 427 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 428 |     virtual void emitCode(EmitArgs&) override; | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 429 |     void setData(const GrGLProgramDataManager&, const GrProcessor&) override; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 430 |  | 
| jvanverth | cfc1886 | 2015-04-28 08:48:20 -0700 | [diff] [blame] | 431 |     static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 432 |  | 
 | 433 | protected: | 
 | 434 |     UniformHandle fParamUni; | 
 | 435 |  | 
 | 436 |     const char* fVSVaryingName; | 
 | 437 |     const char* fFSVaryingName; | 
 | 438 |  | 
 | 439 |     bool fIsFlipped; | 
 | 440 |  | 
 | 441 |     // @{ | 
 | 442 |     /// Values last uploaded as uniforms | 
 | 443 |  | 
 | 444 |     SkScalar fCachedFocal; | 
 | 445 |  | 
 | 446 |     // @} | 
 | 447 |  | 
 | 448 | private: | 
 | 449 |     typedef GrGLGradientEffect INHERITED; | 
 | 450 |  | 
 | 451 | }; | 
 | 452 |  | 
| wangyix | 4b3050b | 2015-08-04 07:59:37 -0700 | [diff] [blame^] | 453 | void FocalOutside2PtConicalEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 454 |                                                      GrProcessorKeyBuilder* b) const { | 
 | 455 |     GLFocalOutside2PtConicalEffect::GenKey(*this, caps, b); | 
 | 456 | } | 
 | 457 |  | 
 | 458 | GrGLFragmentProcessor* FocalOutside2PtConicalEffect::createGLInstance() const { | 
 | 459 |     return SkNEW_ARGS(GLFocalOutside2PtConicalEffect, (*this)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 460 | } | 
 | 461 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 462 | GR_DEFINE_FRAGMENT_PROCESSOR_TEST(FocalOutside2PtConicalEffect); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 463 |  | 
| joshualitt | 0125847 | 2014-09-22 10:29:30 -0700 | [diff] [blame] | 464 | /* | 
 | 465 |  * All Two point conical gradient test create functions may occasionally create edge case shaders | 
 | 466 |  */ | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 467 | GrFragmentProcessor* FocalOutside2PtConicalEffect::TestCreate(GrProcessorTestData* d) { | 
 | 468 |     SkPoint center1 = {d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()}; | 
| commit-bot@chromium.org | 8089467 | 2014-04-22 21:24:22 +0000 | [diff] [blame] | 469 |     SkScalar radius1 = 0.f; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 470 |     SkPoint center2; | 
 | 471 |     SkScalar radius2; | 
 | 472 |     do { | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 473 |         center2.set(d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()); | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 474 |         // Need to make sure the centers are not the same or else focal point will be inside | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 475 |     } while (center1 == center2); | 
 | 476 |         SkPoint diff = center2 - center1; | 
 | 477 |         SkScalar diffLen = diff.length(); | 
 | 478 |         // Below makes sure that the focal point is not contained within circle two | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 479 |         radius2 = d->fRandom->nextRangeF(0.f, diffLen); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 480 |  | 
 | 481 |     SkColor colors[kMaxRandomGradientColors]; | 
 | 482 |     SkScalar stopsArray[kMaxRandomGradientColors]; | 
 | 483 |     SkScalar* stops = stopsArray; | 
 | 484 |     SkShader::TileMode tm; | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 485 |     int colorCount = RandomGradientParams(d->fRandom, colors, &stops, &tm); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 486 |     SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1, | 
 | 487 |                                                                           center2, radius2, | 
 | 488 |                                                                           colors, stops, colorCount, | 
 | 489 |                                                                           tm)); | 
 | 490 |     SkPaint paint; | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 491 |     GrFragmentProcessor* effect; | 
| bsalomon | 83d081a | 2014-07-08 09:56:10 -0700 | [diff] [blame] | 492 |     GrColor paintColor; | 
| joshualitt | 8ca93e7 | 2015-07-08 06:51:43 -0700 | [diff] [blame] | 493 |     GrPaint grPaint; | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 494 |     SkAssertResult(shader->asFragmentProcessor(d->fContext, paint, | 
 | 495 |                                                GrTest::TestMatrix(d->fRandom), NULL, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 496 |                                                &paintColor, d->fProcDataManager, | 
| joshualitt | 8ca93e7 | 2015-07-08 06:51:43 -0700 | [diff] [blame] | 497 |                                                &effect)); | 
| dandov | 9de5b51 | 2014-06-10 14:38:28 -0700 | [diff] [blame] | 498 |     return effect; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 499 | } | 
 | 500 |  | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 501 | GLFocalOutside2PtConicalEffect::GLFocalOutside2PtConicalEffect(const GrProcessor& processor) | 
 | 502 |     : fVSVaryingName(NULL) | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 503 |     , fFSVaryingName(NULL) | 
 | 504 |     , fCachedFocal(SK_ScalarMax) { | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 505 |     const FocalOutside2PtConicalEffect& data = processor.cast<FocalOutside2PtConicalEffect>(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 506 |     fIsFlipped = data.isFlipped(); | 
 | 507 | } | 
 | 508 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 509 | void GLFocalOutside2PtConicalEffect::emitCode(EmitArgs& args) { | 
 | 510 |     const FocalOutside2PtConicalEffect& ge = args.fFp.cast<FocalOutside2PtConicalEffect>(); | 
 | 511 |     this->emitUniforms(args.fBuilder, ge); | 
 | 512 |     fParamUni = args.fBuilder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility, | 
| bsalomon | 422f56f | 2014-12-09 10:18:12 -0800 | [diff] [blame] | 513 |                                          kFloat_GrSLType, kDefault_GrSLPrecision, | 
 | 514 |                                          "Conical2FSParams", 2); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 515 |     SkString tName("t"); | 
 | 516 |     SkString p0; // focalX | 
 | 517 |     SkString p1; // 1 - focalX * focalX | 
 | 518 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 519 |     args.fBuilder->getUniformVariable(fParamUni).appendArrayAccess(0, &p0); | 
 | 520 |     args.fBuilder->getUniformVariable(fParamUni).appendArrayAccess(1, &p1); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 521 |  | 
 | 522 |     // if we have a vec3 from being in perspective, convert it to a vec2 first | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 523 |     GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); | 
 | 524 |     SkString coords2DString = fsBuilder->ensureFSCoords2D(args.fCoords, 0); | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 525 |     const char* coords2D = coords2DString.c_str(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 526 |  | 
 | 527 |     // t = p.x * focal.x +/- sqrt(p.x^2 + (1 - focal.x^2) * p.y^2) | 
 | 528 |  | 
 | 529 |     // output will default to transparent black (we simply won't write anything | 
 | 530 |     // else to it if invalid, instead of discarding or returning prematurely) | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 531 |     fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 532 |  | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 533 |     fsBuilder->codeAppendf("\tfloat xs = %s.x * %s.x;\n", coords2D, coords2D); | 
 | 534 |     fsBuilder->codeAppendf("\tfloat ys = %s.y * %s.y;\n", coords2D, coords2D); | 
 | 535 |     fsBuilder->codeAppendf("\tfloat d = xs + %s * ys;\n", p1.c_str()); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 536 |  | 
 | 537 |     // Must check to see if we flipped the circle order (to make sure start radius < end radius) | 
 | 538 |     // If so we must also flip sign on sqrt | 
 | 539 |     if (!fIsFlipped) { | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 540 |         fsBuilder->codeAppendf("\tfloat %s = %s.x * %s  + sqrt(d);\n", tName.c_str(), | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 541 |                                coords2D, p0.c_str()); | 
 | 542 |     } else { | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 543 |         fsBuilder->codeAppendf("\tfloat %s = %s.x * %s  - sqrt(d);\n", tName.c_str(), | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 544 |                                coords2D, p0.c_str()); | 
 | 545 |     } | 
 | 546 |  | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 547 |     fsBuilder->codeAppendf("\tif (%s >= 0.0 && d >= 0.0) {\n", tName.c_str()); | 
 | 548 |     fsBuilder->codeAppend("\t\t"); | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 549 |     this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor, | 
 | 550 |                     args.fSamplers); | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 551 |     fsBuilder->codeAppend("\t}\n"); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 552 | } | 
 | 553 |  | 
| kkinnunen | 7510b22 | 2014-07-30 00:04:16 -0700 | [diff] [blame] | 554 | void GLFocalOutside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman, | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 555 |                                              const GrProcessor& processor) { | 
 | 556 |     INHERITED::setData(pdman, processor); | 
 | 557 |     const FocalOutside2PtConicalEffect& data = processor.cast<FocalOutside2PtConicalEffect>(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 558 |     SkASSERT(data.isFlipped() == fIsFlipped); | 
 | 559 |     SkScalar focal = data.focal(); | 
 | 560 |  | 
 | 561 |     if (fCachedFocal != focal) { | 
| commit-bot@chromium.org | 8089467 | 2014-04-22 21:24:22 +0000 | [diff] [blame] | 562 |         SkScalar oneMinus2F = 1.f - SkScalarMul(focal, focal); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 563 |  | 
 | 564 |         float values[2] = { | 
 | 565 |             SkScalarToFloat(focal), | 
 | 566 |             SkScalarToFloat(oneMinus2F), | 
 | 567 |         }; | 
 | 568 |  | 
| kkinnunen | 7510b22 | 2014-07-30 00:04:16 -0700 | [diff] [blame] | 569 |         pdman.set1fv(fParamUni, 2, values); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 570 |         fCachedFocal = focal; | 
 | 571 |     } | 
 | 572 | } | 
 | 573 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 574 | void GLFocalOutside2PtConicalEffect::GenKey(const GrProcessor& processor, | 
| jvanverth | cfc1886 | 2015-04-28 08:48:20 -0700 | [diff] [blame] | 575 |                                             const GrGLSLCaps&, GrProcessorKeyBuilder* b) { | 
| bsalomon | 63e99f7 | 2014-07-21 08:03:14 -0700 | [diff] [blame] | 576 |     uint32_t* key = b->add32n(2); | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 577 |     key[0] = GenBaseGradientKey(processor); | 
 | 578 |     key[1] = processor.cast<FocalOutside2PtConicalEffect>().isFlipped(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 579 | } | 
 | 580 |  | 
 | 581 | ////////////////////////////////////////////////////////////////////////////// | 
 | 582 |  | 
 | 583 | class GLFocalInside2PtConicalEffect; | 
 | 584 |  | 
 | 585 | class FocalInside2PtConicalEffect : public GrGradientEffect { | 
 | 586 | public: | 
 | 587 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 588 |     static GrFragmentProcessor* Create(GrContext* ctx, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 589 |                                        GrProcessorDataManager* procDataManager, | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 590 |                                        const SkTwoPointConicalGradient& shader, | 
 | 591 |                                        const SkMatrix& matrix, | 
 | 592 |                                        SkShader::TileMode tm, | 
 | 593 |                                        SkScalar focalX) { | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 594 |         return SkNEW_ARGS(FocalInside2PtConicalEffect, (ctx, procDataManager, shader, matrix, tm, | 
| joshualitt | b245605 | 2015-07-08 09:36:59 -0700 | [diff] [blame] | 595 |                                                         focalX)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 596 |     } | 
 | 597 |  | 
 | 598 |     virtual ~FocalInside2PtConicalEffect() {} | 
 | 599 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 600 |     const char* name() const override { | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 601 |         return "Two-Point Conical Gradient Focal Inside"; | 
 | 602 |     } | 
 | 603 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 604 |     GrGLFragmentProcessor* createGLInstance() const override; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 605 |  | 
 | 606 |     SkScalar focal() const { return fFocalX; } | 
 | 607 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 608 |     typedef GLFocalInside2PtConicalEffect GLProcessor; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 609 |  | 
 | 610 | private: | 
| wangyix | 4b3050b | 2015-08-04 07:59:37 -0700 | [diff] [blame^] | 611 |     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override; | 
 | 612 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 613 |     bool onIsEqual(const GrFragmentProcessor& sBase) const override { | 
| joshualitt | 49586be | 2014-09-16 08:21:41 -0700 | [diff] [blame] | 614 |         const FocalInside2PtConicalEffect& s = sBase.cast<FocalInside2PtConicalEffect>(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 615 |         return (INHERITED::onIsEqual(sBase) && | 
 | 616 |                 this->fFocalX == s.fFocalX); | 
 | 617 |     } | 
 | 618 |  | 
 | 619 |     FocalInside2PtConicalEffect(GrContext* ctx, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 620 |                                 GrProcessorDataManager* procDataManager, | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 621 |                                 const SkTwoPointConicalGradient& shader, | 
 | 622 |                                 const SkMatrix& matrix, | 
 | 623 |                                 SkShader::TileMode tm, | 
 | 624 |                                 SkScalar focalX) | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 625 |         : INHERITED(ctx, procDataManager, shader, matrix, tm), fFocalX(focalX) { | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 626 |         this->initClassID<FocalInside2PtConicalEffect>(); | 
 | 627 |     } | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 628 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 629 |     GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 630 |  | 
 | 631 |     SkScalar         fFocalX; | 
 | 632 |  | 
 | 633 |     typedef GrGradientEffect INHERITED; | 
 | 634 | }; | 
 | 635 |  | 
 | 636 | class GLFocalInside2PtConicalEffect : public GrGLGradientEffect { | 
 | 637 | public: | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 638 |     GLFocalInside2PtConicalEffect(const GrProcessor&); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 639 |     virtual ~GLFocalInside2PtConicalEffect() {} | 
 | 640 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 641 |     virtual void emitCode(EmitArgs&) override; | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 642 |     void setData(const GrGLProgramDataManager&, const GrProcessor&) override; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 643 |  | 
| jvanverth | cfc1886 | 2015-04-28 08:48:20 -0700 | [diff] [blame] | 644 |     static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 645 |  | 
 | 646 | protected: | 
 | 647 |     UniformHandle fFocalUni; | 
 | 648 |  | 
 | 649 |     const char* fVSVaryingName; | 
 | 650 |     const char* fFSVaryingName; | 
 | 651 |  | 
 | 652 |     // @{ | 
 | 653 |     /// Values last uploaded as uniforms | 
 | 654 |  | 
 | 655 |     SkScalar fCachedFocal; | 
 | 656 |  | 
 | 657 |     // @} | 
 | 658 |  | 
 | 659 | private: | 
 | 660 |     typedef GrGLGradientEffect INHERITED; | 
 | 661 |  | 
 | 662 | }; | 
 | 663 |  | 
| wangyix | 4b3050b | 2015-08-04 07:59:37 -0700 | [diff] [blame^] | 664 | void FocalInside2PtConicalEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 665 |                                GrProcessorKeyBuilder* b) const { | 
 | 666 |     GLFocalInside2PtConicalEffect::GenKey(*this, caps, b); | 
 | 667 | } | 
 | 668 |  | 
 | 669 | GrGLFragmentProcessor* FocalInside2PtConicalEffect::createGLInstance() const { | 
 | 670 |     return SkNEW_ARGS(GLFocalInside2PtConicalEffect, (*this)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 671 | } | 
 | 672 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 673 | GR_DEFINE_FRAGMENT_PROCESSOR_TEST(FocalInside2PtConicalEffect); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 674 |  | 
| joshualitt | 0125847 | 2014-09-22 10:29:30 -0700 | [diff] [blame] | 675 | /* | 
 | 676 |  * All Two point conical gradient test create functions may occasionally create edge case shaders | 
 | 677 |  */ | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 678 | GrFragmentProcessor* FocalInside2PtConicalEffect::TestCreate(GrProcessorTestData* d) { | 
 | 679 |     SkPoint center1 = {d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()}; | 
| commit-bot@chromium.org | 8089467 | 2014-04-22 21:24:22 +0000 | [diff] [blame] | 680 |     SkScalar radius1 = 0.f; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 681 |     SkPoint center2; | 
 | 682 |     SkScalar radius2; | 
 | 683 |     do { | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 684 |         center2.set(d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 685 |         // Below makes sure radius2 is larger enouch such that the focal point | 
 | 686 |         // is inside the end circle | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 687 |         SkScalar increase = d->fRandom->nextUScalar1(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 688 |         SkPoint diff = center2 - center1; | 
 | 689 |         SkScalar diffLen = diff.length(); | 
 | 690 |         radius2 = diffLen + increase; | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 691 |         // If the circles are identical the factory will give us an empty shader. | 
 | 692 |     } while (radius1 == radius2 && center1 == center2); | 
 | 693 |  | 
 | 694 |     SkColor colors[kMaxRandomGradientColors]; | 
 | 695 |     SkScalar stopsArray[kMaxRandomGradientColors]; | 
 | 696 |     SkScalar* stops = stopsArray; | 
 | 697 |     SkShader::TileMode tm; | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 698 |     int colorCount = RandomGradientParams(d->fRandom, colors, &stops, &tm); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 699 |     SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1, | 
 | 700 |                                                                           center2, radius2, | 
 | 701 |                                                                           colors, stops, colorCount, | 
 | 702 |                                                                           tm)); | 
 | 703 |     SkPaint paint; | 
| bsalomon | 83d081a | 2014-07-08 09:56:10 -0700 | [diff] [blame] | 704 |     GrColor paintColor; | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 705 |     GrFragmentProcessor* fp; | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 706 |     SkAssertResult(shader->asFragmentProcessor(d->fContext, paint, | 
 | 707 |                                                GrTest::TestMatrix(d->fRandom), NULL, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 708 |                                                &paintColor, d->fProcDataManager, &fp)); | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 709 |     return fp; | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 710 | } | 
 | 711 |  | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 712 | GLFocalInside2PtConicalEffect::GLFocalInside2PtConicalEffect(const GrProcessor&) | 
 | 713 |     : fVSVaryingName(NULL) | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 714 |     , fFSVaryingName(NULL) | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 715 |     , fCachedFocal(SK_ScalarMax) {} | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 716 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 717 | void GLFocalInside2PtConicalEffect::emitCode(EmitArgs& args) { | 
 | 718 |     const FocalInside2PtConicalEffect& ge = args.fFp.cast<FocalInside2PtConicalEffect>(); | 
 | 719 |     this->emitUniforms(args.fBuilder, ge); | 
 | 720 |     fFocalUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, | 
| bsalomon | 422f56f | 2014-12-09 10:18:12 -0800 | [diff] [blame] | 721 |                                     kFloat_GrSLType, kDefault_GrSLPrecision, | 
 | 722 |                                     "Conical2FSParams"); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 723 |     SkString tName("t"); | 
 | 724 |  | 
 | 725 |     // this is the distance along x-axis from the end center to focal point in | 
 | 726 |     // transformed coordinates | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 727 |     GrGLShaderVar focal = args.fBuilder->getUniformVariable(fFocalUni); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 728 |  | 
 | 729 |     // if we have a vec3 from being in perspective, convert it to a vec2 first | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 730 |     GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); | 
 | 731 |     SkString coords2DString = fsBuilder->ensureFSCoords2D(args.fCoords, 0); | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 732 |     const char* coords2D = coords2DString.c_str(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 733 |  | 
 | 734 |     // t = p.x * focalX + length(p) | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 735 |     fsBuilder->codeAppendf("\tfloat %s = %s.x * %s  + length(%s);\n", tName.c_str(), | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 736 |                            coords2D, focal.c_str(), coords2D); | 
 | 737 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 738 |     this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor, | 
 | 739 |                     args.fSamplers); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 740 | } | 
 | 741 |  | 
| kkinnunen | 7510b22 | 2014-07-30 00:04:16 -0700 | [diff] [blame] | 742 | void GLFocalInside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman, | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 743 |                                             const GrProcessor& processor) { | 
 | 744 |     INHERITED::setData(pdman, processor); | 
 | 745 |     const FocalInside2PtConicalEffect& data = processor.cast<FocalInside2PtConicalEffect>(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 746 |     SkScalar focal = data.focal(); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 747 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 748 |     if (fCachedFocal != focal) { | 
| kkinnunen | 7510b22 | 2014-07-30 00:04:16 -0700 | [diff] [blame] | 749 |         pdman.set1f(fFocalUni, SkScalarToFloat(focal)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 750 |         fCachedFocal = focal; | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 751 |     } | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 752 | } | 
 | 753 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 754 | void GLFocalInside2PtConicalEffect::GenKey(const GrProcessor& processor, | 
| jvanverth | cfc1886 | 2015-04-28 08:48:20 -0700 | [diff] [blame] | 755 |                                            const GrGLSLCaps&, GrProcessorKeyBuilder* b) { | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 756 |     b->add32(GenBaseGradientKey(processor)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 757 | } | 
 | 758 |  | 
 | 759 | ////////////////////////////////////////////////////////////////////////////// | 
 | 760 | // Circle Conical Gradients | 
 | 761 | ////////////////////////////////////////////////////////////////////////////// | 
 | 762 |  | 
 | 763 | struct CircleConicalInfo { | 
 | 764 |     SkPoint fCenterEnd; | 
 | 765 |     SkScalar fA; | 
 | 766 |     SkScalar fB; | 
 | 767 |     SkScalar fC; | 
 | 768 | }; | 
 | 769 |  | 
 | 770 | // Returns focal distance along x-axis in transformed coords | 
 | 771 | static ConicalType set_matrix_circle_conical(const SkTwoPointConicalGradient& shader, | 
 | 772 |                                              SkMatrix* invLMatrix, CircleConicalInfo* info) { | 
 | 773 |     // Inverse of the current local matrix is passed in then, | 
 | 774 |     // translate and scale such that start circle is on the origin and has radius 1 | 
 | 775 |     const SkPoint& centerStart = shader.getStartCenter(); | 
 | 776 |     const SkPoint& centerEnd = shader.getEndCenter(); | 
 | 777 |     SkScalar radiusStart = shader.getStartRadius(); | 
 | 778 |     SkScalar radiusEnd = shader.getEndRadius(); | 
 | 779 |  | 
 | 780 |     SkMatrix matrix; | 
 | 781 |  | 
 | 782 |     matrix.setTranslate(-centerStart.fX, -centerStart.fY); | 
 | 783 |  | 
| commit-bot@chromium.org | 8089467 | 2014-04-22 21:24:22 +0000 | [diff] [blame] | 784 |     SkScalar invStartRad = 1.f / radiusStart; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 785 |     matrix.postScale(invStartRad, invStartRad); | 
 | 786 |  | 
 | 787 |     radiusEnd /= radiusStart; | 
 | 788 |  | 
 | 789 |     SkPoint centerEndTrans; | 
 | 790 |     matrix.mapPoints(¢erEndTrans, ¢erEnd, 1); | 
 | 791 |  | 
 | 792 |     SkScalar A = centerEndTrans.fX * centerEndTrans.fX + centerEndTrans.fY * centerEndTrans.fY | 
 | 793 |                  - radiusEnd * radiusEnd + 2 * radiusEnd - 1; | 
 | 794 |  | 
 | 795 |     // Check to see if start circle is inside end circle with edges touching. | 
 | 796 |     // If touching we return that it is of kEdge_ConicalType, and leave the matrix setting | 
| egdaniel | 8405ef9 | 2014-06-09 11:57:28 -0700 | [diff] [blame] | 797 |     // to the edge shader. kEdgeErrorTol = 5 * kErrorTol was picked after manual testing | 
 | 798 |     // so that C = 1 / A is stable, and the linear approximation used in the Edge shader is | 
 | 799 |     // still accurate. | 
 | 800 |     if (SkScalarAbs(A) < kEdgeErrorTol) { | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 801 |         return kEdge_ConicalType; | 
 | 802 |     } | 
 | 803 |  | 
| commit-bot@chromium.org | 8089467 | 2014-04-22 21:24:22 +0000 | [diff] [blame] | 804 |     SkScalar C = 1.f / A; | 
 | 805 |     SkScalar B = (radiusEnd - 1.f) * C; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 806 |  | 
 | 807 |     matrix.postScale(C, C); | 
 | 808 |  | 
 | 809 |     invLMatrix->postConcat(matrix); | 
 | 810 |  | 
 | 811 |     info->fCenterEnd = centerEndTrans; | 
 | 812 |     info->fA = A; | 
 | 813 |     info->fB = B; | 
 | 814 |     info->fC = C; | 
 | 815 |  | 
 | 816 |     // if A ends up being negative, the start circle is contained completely inside the end cirlce | 
| commit-bot@chromium.org | 8089467 | 2014-04-22 21:24:22 +0000 | [diff] [blame] | 817 |     if (A < 0.f) { | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 818 |         return kInside_ConicalType; | 
 | 819 |     } | 
 | 820 |     return kOutside_ConicalType; | 
 | 821 | } | 
 | 822 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 823 | class CircleInside2PtConicalEffect : public GrGradientEffect { | 
 | 824 | public: | 
 | 825 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 826 |     static GrFragmentProcessor* Create(GrContext* ctx, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 827 |                                        GrProcessorDataManager* procDataManager, | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 828 |                                        const SkTwoPointConicalGradient& shader, | 
 | 829 |                                        const SkMatrix& matrix, | 
 | 830 |                                        SkShader::TileMode tm, | 
 | 831 |                                        const CircleConicalInfo& info) { | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 832 |         return SkNEW_ARGS(CircleInside2PtConicalEffect, (ctx, procDataManager, shader, matrix, tm, | 
| joshualitt | b245605 | 2015-07-08 09:36:59 -0700 | [diff] [blame] | 833 |                                                          info)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 834 |     } | 
 | 835 |  | 
 | 836 |     virtual ~CircleInside2PtConicalEffect() {} | 
 | 837 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 838 |     const char* name() const override { return "Two-Point Conical Gradient Inside"; } | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 839 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 840 |     GrGLFragmentProcessor* createGLInstance() const override; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 841 |  | 
 | 842 |     SkScalar centerX() const { return fInfo.fCenterEnd.fX; } | 
 | 843 |     SkScalar centerY() const { return fInfo.fCenterEnd.fY; } | 
 | 844 |     SkScalar A() const { return fInfo.fA; } | 
 | 845 |     SkScalar B() const { return fInfo.fB; } | 
 | 846 |     SkScalar C() const { return fInfo.fC; } | 
 | 847 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 848 | private: | 
| wangyix | 4b3050b | 2015-08-04 07:59:37 -0700 | [diff] [blame^] | 849 |     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps, | 
 | 850 |                                      GrProcessorKeyBuilder* b) const override; | 
 | 851 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 852 |     bool onIsEqual(const GrFragmentProcessor& sBase) const override { | 
| joshualitt | 49586be | 2014-09-16 08:21:41 -0700 | [diff] [blame] | 853 |         const CircleInside2PtConicalEffect& s = sBase.cast<CircleInside2PtConicalEffect>(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 854 |         return (INHERITED::onIsEqual(sBase) && | 
 | 855 |                 this->fInfo.fCenterEnd == s.fInfo.fCenterEnd && | 
 | 856 |                 this->fInfo.fA == s.fInfo.fA && | 
 | 857 |                 this->fInfo.fB == s.fInfo.fB && | 
 | 858 |                 this->fInfo.fC == s.fInfo.fC); | 
 | 859 |     } | 
 | 860 |  | 
 | 861 |     CircleInside2PtConicalEffect(GrContext* ctx, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 862 |                                  GrProcessorDataManager* procDataManager, | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 863 |                                  const SkTwoPointConicalGradient& shader, | 
 | 864 |                                  const SkMatrix& matrix, | 
 | 865 |                                  SkShader::TileMode tm, | 
 | 866 |                                  const CircleConicalInfo& info) | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 867 |         : INHERITED(ctx, procDataManager, shader, matrix, tm), fInfo(info) { | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 868 |         this->initClassID<CircleInside2PtConicalEffect>(); | 
 | 869 |     } | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 870 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 871 |     GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 872 |  | 
 | 873 |     const CircleConicalInfo fInfo; | 
 | 874 |  | 
 | 875 |     typedef GrGradientEffect INHERITED; | 
 | 876 | }; | 
 | 877 |  | 
 | 878 | class GLCircleInside2PtConicalEffect : public GrGLGradientEffect { | 
 | 879 | public: | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 880 |     GLCircleInside2PtConicalEffect(const GrProcessor&); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 881 |     virtual ~GLCircleInside2PtConicalEffect() {} | 
 | 882 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 883 |     virtual void emitCode(EmitArgs&) override; | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 884 |     void setData(const GrGLProgramDataManager&, const GrProcessor&) override; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 885 |  | 
| jvanverth | cfc1886 | 2015-04-28 08:48:20 -0700 | [diff] [blame] | 886 |     static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 887 |  | 
 | 888 | protected: | 
 | 889 |     UniformHandle fCenterUni; | 
 | 890 |     UniformHandle fParamUni; | 
 | 891 |  | 
 | 892 |     const char* fVSVaryingName; | 
 | 893 |     const char* fFSVaryingName; | 
 | 894 |  | 
 | 895 |     // @{ | 
 | 896 |     /// Values last uploaded as uniforms | 
 | 897 |  | 
 | 898 |     SkScalar fCachedCenterX; | 
 | 899 |     SkScalar fCachedCenterY; | 
 | 900 |     SkScalar fCachedA; | 
 | 901 |     SkScalar fCachedB; | 
 | 902 |     SkScalar fCachedC; | 
 | 903 |  | 
 | 904 |     // @} | 
 | 905 |  | 
 | 906 | private: | 
 | 907 |     typedef GrGLGradientEffect INHERITED; | 
 | 908 |  | 
 | 909 | }; | 
 | 910 |  | 
| wangyix | 4b3050b | 2015-08-04 07:59:37 -0700 | [diff] [blame^] | 911 | void CircleInside2PtConicalEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 912 |                                                      GrProcessorKeyBuilder* b) const { | 
 | 913 |     GLCircleInside2PtConicalEffect::GenKey(*this, caps, b); | 
 | 914 | } | 
 | 915 |  | 
 | 916 | GrGLFragmentProcessor* CircleInside2PtConicalEffect::createGLInstance() const { | 
 | 917 |     return SkNEW_ARGS(GLCircleInside2PtConicalEffect, (*this)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 918 | } | 
 | 919 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 920 | GR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircleInside2PtConicalEffect); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 921 |  | 
| joshualitt | 0125847 | 2014-09-22 10:29:30 -0700 | [diff] [blame] | 922 | /* | 
 | 923 |  * All Two point conical gradient test create functions may occasionally create edge case shaders | 
 | 924 |  */ | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 925 | GrFragmentProcessor* | 
 | 926 | CircleInside2PtConicalEffect::TestCreate(GrProcessorTestData* d) { | 
 | 927 |     SkPoint center1 = {d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()}; | 
 | 928 |     SkScalar radius1 = d->fRandom->nextUScalar1() + 0.0001f; // make sure radius1 != 0 | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 929 |     SkPoint center2; | 
 | 930 |     SkScalar radius2; | 
 | 931 |     do { | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 932 |         center2.set(d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 933 |         // Below makes sure that circle one is contained within circle two | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 934 |         SkScalar increase = d->fRandom->nextUScalar1(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 935 |         SkPoint diff = center2 - center1; | 
 | 936 |         SkScalar diffLen = diff.length(); | 
 | 937 |         radius2 = radius1 + diffLen + increase; | 
 | 938 |         // If the circles are identical the factory will give us an empty shader. | 
 | 939 |     } while (radius1 == radius2 && center1 == center2); | 
 | 940 |  | 
 | 941 |     SkColor colors[kMaxRandomGradientColors]; | 
 | 942 |     SkScalar stopsArray[kMaxRandomGradientColors]; | 
 | 943 |     SkScalar* stops = stopsArray; | 
 | 944 |     SkShader::TileMode tm; | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 945 |     int colorCount = RandomGradientParams(d->fRandom, colors, &stops, &tm); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 946 |     SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1, | 
 | 947 |                                                                           center2, radius2, | 
 | 948 |                                                                           colors, stops, colorCount, | 
 | 949 |                                                                           tm)); | 
 | 950 |     SkPaint paint; | 
| bsalomon | 83d081a | 2014-07-08 09:56:10 -0700 | [diff] [blame] | 951 |     GrColor paintColor; | 
| joshualitt | 8ca93e7 | 2015-07-08 06:51:43 -0700 | [diff] [blame] | 952 |     GrFragmentProcessor* fp; | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 953 |     SkAssertResult(shader->asFragmentProcessor(d->fContext, paint, | 
 | 954 |                                                GrTest::TestMatrix(d->fRandom), NULL, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 955 |                                                &paintColor, d->fProcDataManager, &fp)); | 
| joshualitt | 8ca93e7 | 2015-07-08 06:51:43 -0700 | [diff] [blame] | 956 |     return fp; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 957 | } | 
 | 958 |  | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 959 | GLCircleInside2PtConicalEffect::GLCircleInside2PtConicalEffect(const GrProcessor& processor) | 
 | 960 |     : fVSVaryingName(NULL) | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 961 |     , fFSVaryingName(NULL) | 
 | 962 |     , fCachedCenterX(SK_ScalarMax) | 
 | 963 |     , fCachedCenterY(SK_ScalarMax) | 
 | 964 |     , fCachedA(SK_ScalarMax) | 
 | 965 |     , fCachedB(SK_ScalarMax) | 
 | 966 |     , fCachedC(SK_ScalarMax) {} | 
 | 967 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 968 | void GLCircleInside2PtConicalEffect::emitCode(EmitArgs& args) { | 
 | 969 |     const CircleInside2PtConicalEffect& ge = args.fFp.cast<CircleInside2PtConicalEffect>(); | 
 | 970 |     this->emitUniforms(args.fBuilder, ge); | 
 | 971 |     fCenterUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, | 
| bsalomon | 422f56f | 2014-12-09 10:18:12 -0800 | [diff] [blame] | 972 |                                      kVec2f_GrSLType, kDefault_GrSLPrecision, | 
 | 973 |                                      "Conical2FSCenter"); | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 974 |     fParamUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, | 
| bsalomon | 422f56f | 2014-12-09 10:18:12 -0800 | [diff] [blame] | 975 |                                     kVec3f_GrSLType, kDefault_GrSLPrecision, | 
 | 976 |                                     "Conical2FSParams"); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 977 |     SkString tName("t"); | 
 | 978 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 979 |     GrGLShaderVar center = args.fBuilder->getUniformVariable(fCenterUni); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 980 |     // params.x = A | 
 | 981 |     // params.y = B | 
 | 982 |     // params.z = C | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 983 |     GrGLShaderVar params = args.fBuilder->getUniformVariable(fParamUni); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 984 |  | 
 | 985 |     // if we have a vec3 from being in perspective, convert it to a vec2 first | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 986 |     GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); | 
 | 987 |     SkString coords2DString = fsBuilder->ensureFSCoords2D(args.fCoords, 0); | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 988 |     const char* coords2D = coords2DString.c_str(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 989 |  | 
 | 990 |     // p = coords2D | 
 | 991 |     // e = center end | 
 | 992 |     // r = radius end | 
 | 993 |     // A = dot(e, e) - r^2 + 2 * r - 1 | 
 | 994 |     // B = (r -1) / A | 
 | 995 |     // C = 1 / A | 
 | 996 |     // d = dot(e, p) + B | 
 | 997 |     // t = d +/- sqrt(d^2 - A * dot(p, p) + C) | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 998 |     fsBuilder->codeAppendf("\tfloat pDotp = dot(%s,  %s);\n", coords2D, coords2D); | 
| joshualitt | 49586be | 2014-09-16 08:21:41 -0700 | [diff] [blame] | 999 |     fsBuilder->codeAppendf("\tfloat d = dot(%s,  %s) + %s.y;\n", coords2D, center.c_str(), | 
 | 1000 |                            params.c_str()); | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 1001 |     fsBuilder->codeAppendf("\tfloat %s = d + sqrt(d * d - %s.x * pDotp + %s.z);\n", | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1002 |                            tName.c_str(), params.c_str(), params.c_str()); | 
 | 1003 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 1004 |     this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor, | 
 | 1005 |                     args.fSamplers); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1006 | } | 
 | 1007 |  | 
| kkinnunen | 7510b22 | 2014-07-30 00:04:16 -0700 | [diff] [blame] | 1008 | void GLCircleInside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman, | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1009 |                                              const GrProcessor& processor) { | 
 | 1010 |     INHERITED::setData(pdman, processor); | 
 | 1011 |     const CircleInside2PtConicalEffect& data = processor.cast<CircleInside2PtConicalEffect>(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1012 |     SkScalar centerX = data.centerX(); | 
 | 1013 |     SkScalar centerY = data.centerY(); | 
 | 1014 |     SkScalar A = data.A(); | 
 | 1015 |     SkScalar B = data.B(); | 
 | 1016 |     SkScalar C = data.C(); | 
 | 1017 |  | 
 | 1018 |     if (fCachedCenterX != centerX || fCachedCenterY != centerY || | 
 | 1019 |         fCachedA != A || fCachedB != B || fCachedC != C) { | 
 | 1020 |  | 
| kkinnunen | 7510b22 | 2014-07-30 00:04:16 -0700 | [diff] [blame] | 1021 |         pdman.set2f(fCenterUni, SkScalarToFloat(centerX), SkScalarToFloat(centerY)); | 
 | 1022 |         pdman.set3f(fParamUni, SkScalarToFloat(A), SkScalarToFloat(B), SkScalarToFloat(C)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1023 |  | 
 | 1024 |         fCachedCenterX = centerX; | 
 | 1025 |         fCachedCenterY = centerY; | 
 | 1026 |         fCachedA = A; | 
 | 1027 |         fCachedB = B; | 
 | 1028 |         fCachedC = C; | 
 | 1029 |     } | 
 | 1030 | } | 
 | 1031 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1032 | void GLCircleInside2PtConicalEffect::GenKey(const GrProcessor& processor, | 
| jvanverth | cfc1886 | 2015-04-28 08:48:20 -0700 | [diff] [blame] | 1033 |                                             const GrGLSLCaps&, GrProcessorKeyBuilder* b) { | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1034 |     b->add32(GenBaseGradientKey(processor)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1035 | } | 
 | 1036 |  | 
 | 1037 | ////////////////////////////////////////////////////////////////////////////// | 
 | 1038 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1039 | class CircleOutside2PtConicalEffect : public GrGradientEffect { | 
 | 1040 | public: | 
 | 1041 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1042 |     static GrFragmentProcessor* Create(GrContext* ctx, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 1043 |                                        GrProcessorDataManager* procDataManager, | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1044 |                                        const SkTwoPointConicalGradient& shader, | 
 | 1045 |                                        const SkMatrix& matrix, | 
 | 1046 |                                        SkShader::TileMode tm, | 
 | 1047 |                                        const CircleConicalInfo& info) { | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 1048 |         return SkNEW_ARGS(CircleOutside2PtConicalEffect, (ctx, procDataManager, shader, matrix, | 
| joshualitt | b245605 | 2015-07-08 09:36:59 -0700 | [diff] [blame] | 1049 |                                                           tm, info)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1050 |     } | 
 | 1051 |  | 
 | 1052 |     virtual ~CircleOutside2PtConicalEffect() {} | 
 | 1053 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 1054 |     const char* name() const override { return "Two-Point Conical Gradient Outside"; } | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 1055 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 1056 |     GrGLFragmentProcessor* createGLInstance() const override; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1057 |  | 
 | 1058 |     SkScalar centerX() const { return fInfo.fCenterEnd.fX; } | 
 | 1059 |     SkScalar centerY() const { return fInfo.fCenterEnd.fY; } | 
 | 1060 |     SkScalar A() const { return fInfo.fA; } | 
 | 1061 |     SkScalar B() const { return fInfo.fB; } | 
 | 1062 |     SkScalar C() const { return fInfo.fC; } | 
 | 1063 |     SkScalar tLimit() const { return fTLimit; } | 
 | 1064 |     bool isFlipped() const { return fIsFlipped; } | 
 | 1065 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1066 | private: | 
| wangyix | 4b3050b | 2015-08-04 07:59:37 -0700 | [diff] [blame^] | 1067 |     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override; | 
 | 1068 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 1069 |     bool onIsEqual(const GrFragmentProcessor& sBase) const override { | 
| joshualitt | 49586be | 2014-09-16 08:21:41 -0700 | [diff] [blame] | 1070 |         const CircleOutside2PtConicalEffect& s = sBase.cast<CircleOutside2PtConicalEffect>(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1071 |         return (INHERITED::onIsEqual(sBase) && | 
 | 1072 |                 this->fInfo.fCenterEnd == s.fInfo.fCenterEnd && | 
 | 1073 |                 this->fInfo.fA == s.fInfo.fA && | 
 | 1074 |                 this->fInfo.fB == s.fInfo.fB && | 
 | 1075 |                 this->fInfo.fC == s.fInfo.fC && | 
 | 1076 |                 this->fTLimit == s.fTLimit && | 
 | 1077 |                 this->fIsFlipped == s.fIsFlipped); | 
 | 1078 |     } | 
 | 1079 |  | 
 | 1080 |     CircleOutside2PtConicalEffect(GrContext* ctx, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 1081 |                                   GrProcessorDataManager* procDataManager, | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1082 |                                   const SkTwoPointConicalGradient& shader, | 
 | 1083 |                                   const SkMatrix& matrix, | 
 | 1084 |                                   SkShader::TileMode tm, | 
 | 1085 |                                   const CircleConicalInfo& info) | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 1086 |         : INHERITED(ctx, procDataManager, shader, matrix, tm), fInfo(info) { | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 1087 |         this->initClassID<CircleOutside2PtConicalEffect>(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1088 |         if (shader.getStartRadius() != shader.getEndRadius()) { | 
| reed | 80ea19c | 2015-05-12 10:37:34 -0700 | [diff] [blame] | 1089 |             fTLimit = shader.getStartRadius() / (shader.getStartRadius() - shader.getEndRadius()); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1090 |         } else { | 
 | 1091 |             fTLimit = SK_ScalarMin; | 
 | 1092 |         } | 
 | 1093 |  | 
 | 1094 |         fIsFlipped = shader.isFlippedGrad(); | 
 | 1095 |     } | 
 | 1096 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1097 |     GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1098 |  | 
 | 1099 |     const CircleConicalInfo fInfo; | 
 | 1100 |     SkScalar fTLimit; | 
 | 1101 |     bool fIsFlipped; | 
 | 1102 |  | 
 | 1103 |     typedef GrGradientEffect INHERITED; | 
 | 1104 | }; | 
 | 1105 |  | 
 | 1106 | class GLCircleOutside2PtConicalEffect : public GrGLGradientEffect { | 
 | 1107 | public: | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 1108 |     GLCircleOutside2PtConicalEffect(const GrProcessor&); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1109 |     virtual ~GLCircleOutside2PtConicalEffect() {} | 
 | 1110 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 1111 |     virtual void emitCode(EmitArgs&) override; | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 1112 |     void setData(const GrGLProgramDataManager&, const GrProcessor&) override; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1113 |  | 
| jvanverth | cfc1886 | 2015-04-28 08:48:20 -0700 | [diff] [blame] | 1114 |     static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1115 |  | 
 | 1116 | protected: | 
 | 1117 |     UniformHandle fCenterUni; | 
 | 1118 |     UniformHandle fParamUni; | 
 | 1119 |  | 
 | 1120 |     const char* fVSVaryingName; | 
 | 1121 |     const char* fFSVaryingName; | 
 | 1122 |  | 
 | 1123 |     bool fIsFlipped; | 
 | 1124 |  | 
 | 1125 |     // @{ | 
 | 1126 |     /// Values last uploaded as uniforms | 
 | 1127 |  | 
 | 1128 |     SkScalar fCachedCenterX; | 
 | 1129 |     SkScalar fCachedCenterY; | 
 | 1130 |     SkScalar fCachedA; | 
 | 1131 |     SkScalar fCachedB; | 
 | 1132 |     SkScalar fCachedC; | 
 | 1133 |     SkScalar fCachedTLimit; | 
 | 1134 |  | 
 | 1135 |     // @} | 
 | 1136 |  | 
 | 1137 | private: | 
 | 1138 |     typedef GrGLGradientEffect INHERITED; | 
 | 1139 |  | 
 | 1140 | }; | 
 | 1141 |  | 
| wangyix | 4b3050b | 2015-08-04 07:59:37 -0700 | [diff] [blame^] | 1142 | void CircleOutside2PtConicalEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 1143 |                                                       GrProcessorKeyBuilder* b) const { | 
 | 1144 |     GLCircleOutside2PtConicalEffect::GenKey(*this, caps, b); | 
 | 1145 | } | 
 | 1146 |  | 
 | 1147 | GrGLFragmentProcessor* CircleOutside2PtConicalEffect::createGLInstance() const { | 
 | 1148 |     return SkNEW_ARGS(GLCircleOutside2PtConicalEffect, (*this)); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1149 | } | 
 | 1150 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1151 | GR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircleOutside2PtConicalEffect); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1152 |  | 
| joshualitt | 0125847 | 2014-09-22 10:29:30 -0700 | [diff] [blame] | 1153 | /* | 
 | 1154 |  * All Two point conical gradient test create functions may occasionally create edge case shaders | 
 | 1155 |  */ | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 1156 | GrFragmentProcessor* CircleOutside2PtConicalEffect::TestCreate(GrProcessorTestData* d) { | 
 | 1157 |     SkPoint center1 = {d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()}; | 
 | 1158 |     SkScalar radius1 = d->fRandom->nextUScalar1() + 0.0001f; // make sure radius1 != 0 | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1159 |     SkPoint center2; | 
 | 1160 |     SkScalar radius2; | 
 | 1161 |     SkScalar diffLen; | 
 | 1162 |     do { | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 1163 |         center2.set(d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1164 |         // If the circles share a center than we can't be in the outside case | 
 | 1165 |     } while (center1 == center2); | 
| joshualitt | 0125847 | 2014-09-22 10:29:30 -0700 | [diff] [blame] | 1166 |     SkPoint diff = center2 - center1; | 
 | 1167 |     diffLen = diff.length(); | 
 | 1168 |     // Below makes sure that circle one is not contained within circle two | 
 | 1169 |     // and have radius2 >= radius to match sorting on cpu side | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 1170 |     radius2 = radius1 + d->fRandom->nextRangeF(0.f, diffLen); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1171 |  | 
 | 1172 |     SkColor colors[kMaxRandomGradientColors]; | 
 | 1173 |     SkScalar stopsArray[kMaxRandomGradientColors]; | 
 | 1174 |     SkScalar* stops = stopsArray; | 
 | 1175 |     SkShader::TileMode tm; | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 1176 |     int colorCount = RandomGradientParams(d->fRandom, colors, &stops, &tm); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1177 |     SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointConical(center1, radius1, | 
 | 1178 |                                                                           center2, radius2, | 
 | 1179 |                                                                           colors, stops, colorCount, | 
 | 1180 |                                                                           tm)); | 
 | 1181 |     SkPaint paint; | 
| bsalomon | 83d081a | 2014-07-08 09:56:10 -0700 | [diff] [blame] | 1182 |     GrColor paintColor; | 
| joshualitt | 8ca93e7 | 2015-07-08 06:51:43 -0700 | [diff] [blame] | 1183 |     GrFragmentProcessor* fp; | 
| joshualitt | 0067ff5 | 2015-07-08 14:26:19 -0700 | [diff] [blame] | 1184 |     SkAssertResult(shader->asFragmentProcessor(d->fContext, paint, | 
 | 1185 |                                                GrTest::TestMatrix(d->fRandom), NULL, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 1186 |                                                &paintColor, d->fProcDataManager, &fp)); | 
| joshualitt | 8ca93e7 | 2015-07-08 06:51:43 -0700 | [diff] [blame] | 1187 |     return fp; | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1188 | } | 
 | 1189 |  | 
| joshualitt | eb2a676 | 2014-12-04 11:35:33 -0800 | [diff] [blame] | 1190 | GLCircleOutside2PtConicalEffect::GLCircleOutside2PtConicalEffect(const GrProcessor& processor) | 
 | 1191 |     : fVSVaryingName(NULL) | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1192 |     , fFSVaryingName(NULL) | 
 | 1193 |     , fCachedCenterX(SK_ScalarMax) | 
 | 1194 |     , fCachedCenterY(SK_ScalarMax) | 
 | 1195 |     , fCachedA(SK_ScalarMax) | 
 | 1196 |     , fCachedB(SK_ScalarMax) | 
 | 1197 |     , fCachedC(SK_ScalarMax) | 
 | 1198 |     , fCachedTLimit(SK_ScalarMax) { | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1199 |     const CircleOutside2PtConicalEffect& data = processor.cast<CircleOutside2PtConicalEffect>(); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1200 |     fIsFlipped = data.isFlipped(); | 
 | 1201 |     } | 
 | 1202 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 1203 | void GLCircleOutside2PtConicalEffect::emitCode(EmitArgs& args) { | 
 | 1204 |     const CircleOutside2PtConicalEffect& ge = args.fFp.cast<CircleOutside2PtConicalEffect>(); | 
 | 1205 |     this->emitUniforms(args.fBuilder, ge); | 
 | 1206 |     fCenterUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, | 
| bsalomon | 422f56f | 2014-12-09 10:18:12 -0800 | [diff] [blame] | 1207 |                                      kVec2f_GrSLType, kDefault_GrSLPrecision, | 
 | 1208 |                                      "Conical2FSCenter"); | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 1209 |     fParamUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, | 
| bsalomon | 422f56f | 2014-12-09 10:18:12 -0800 | [diff] [blame] | 1210 |                                     kVec4f_GrSLType, kDefault_GrSLPrecision, | 
 | 1211 |                                     "Conical2FSParams"); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1212 |     SkString tName("t"); | 
 | 1213 |  | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 1214 |     GrGLShaderVar center = args.fBuilder->getUniformVariable(fCenterUni); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1215 |     // params.x = A | 
 | 1216 |     // params.y = B | 
 | 1217 |     // params.z = C | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 1218 |     GrGLShaderVar params = args.fBuilder->getUniformVariable(fParamUni); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1219 |  | 
 | 1220 |     // if we have a vec3 from being in perspective, convert it to a vec2 first | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 1221 |     GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); | 
 | 1222 |     SkString coords2DString = fsBuilder->ensureFSCoords2D(args.fCoords, 0); | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 1223 |     const char* coords2D = coords2DString.c_str(); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1224 |  | 
 | 1225 |     // output will default to transparent black (we simply won't write anything | 
 | 1226 |     // else to it if invalid, instead of discarding or returning prematurely) | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 1227 |     fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1228 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1229 |     // p = coords2D | 
 | 1230 |     // e = center end | 
 | 1231 |     // r = radius end | 
 | 1232 |     // A = dot(e, e) - r^2 + 2 * r - 1 | 
 | 1233 |     // B = (r -1) / A | 
 | 1234 |     // C = 1 / A | 
 | 1235 |     // d = dot(e, p) + B | 
 | 1236 |     // t = d +/- sqrt(d^2 - A * dot(p, p) + C) | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1237 |  | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 1238 |     fsBuilder->codeAppendf("\tfloat pDotp = dot(%s,  %s);\n", coords2D, coords2D); | 
| joshualitt | 49586be | 2014-09-16 08:21:41 -0700 | [diff] [blame] | 1239 |     fsBuilder->codeAppendf("\tfloat d = dot(%s,  %s) + %s.y;\n", coords2D, center.c_str(), | 
 | 1240 |                            params.c_str()); | 
 | 1241 |     fsBuilder->codeAppendf("\tfloat deter = d * d - %s.x * pDotp + %s.z;\n", params.c_str(), | 
 | 1242 |                            params.c_str()); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1243 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1244 |     // Must check to see if we flipped the circle order (to make sure start radius < end radius) | 
 | 1245 |     // If so we must also flip sign on sqrt | 
 | 1246 |     if (!fIsFlipped) { | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 1247 |         fsBuilder->codeAppendf("\tfloat %s = d + sqrt(deter);\n", tName.c_str()); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1248 |     } else { | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 1249 |         fsBuilder->codeAppendf("\tfloat %s = d - sqrt(deter);\n", tName.c_str()); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1250 |     } | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1251 |  | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 1252 |     fsBuilder->codeAppendf("\tif (%s >= %s.w && deter >= 0.0) {\n", tName.c_str(), params.c_str()); | 
 | 1253 |     fsBuilder->codeAppend("\t\t"); | 
| wangyix | 7c157a9 | 2015-07-22 15:08:53 -0700 | [diff] [blame] | 1254 |     this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor, | 
 | 1255 |                     args.fSamplers); | 
| joshualitt | 30ba436 | 2014-08-21 20:18:45 -0700 | [diff] [blame] | 1256 |     fsBuilder->codeAppend("\t}\n"); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1257 | } | 
 | 1258 |  | 
| kkinnunen | 7510b22 | 2014-07-30 00:04:16 -0700 | [diff] [blame] | 1259 | void GLCircleOutside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman, | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1260 |                                               const GrProcessor& processor) { | 
 | 1261 |     INHERITED::setData(pdman, processor); | 
 | 1262 |     const CircleOutside2PtConicalEffect& data = processor.cast<CircleOutside2PtConicalEffect>(); | 
| commit-bot@chromium.org | 44d83c1 | 2014-04-21 13:10:25 +0000 | [diff] [blame] | 1263 |     SkASSERT(data.isFlipped() == fIsFlipped); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1264 |     SkScalar centerX = data.centerX(); | 
 | 1265 |     SkScalar centerY = data.centerY(); | 
 | 1266 |     SkScalar A = data.A(); | 
 | 1267 |     SkScalar B = data.B(); | 
 | 1268 |     SkScalar C = data.C(); | 
 | 1269 |     SkScalar tLimit = data.tLimit(); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1270 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1271 |     if (fCachedCenterX != centerX || fCachedCenterY != centerY || | 
 | 1272 |         fCachedA != A || fCachedB != B || fCachedC != C || fCachedTLimit != tLimit) { | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1273 |  | 
| kkinnunen | 7510b22 | 2014-07-30 00:04:16 -0700 | [diff] [blame] | 1274 |         pdman.set2f(fCenterUni, SkScalarToFloat(centerX), SkScalarToFloat(centerY)); | 
 | 1275 |         pdman.set4f(fParamUni, SkScalarToFloat(A), SkScalarToFloat(B), SkScalarToFloat(C), | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1276 |                    SkScalarToFloat(tLimit)); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1277 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1278 |         fCachedCenterX = centerX; | 
 | 1279 |         fCachedCenterY = centerY; | 
 | 1280 |         fCachedA = A; | 
 | 1281 |         fCachedB = B; | 
 | 1282 |         fCachedC = C; | 
 | 1283 |         fCachedTLimit = tLimit; | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1284 |     } | 
 | 1285 | } | 
 | 1286 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1287 | void GLCircleOutside2PtConicalEffect::GenKey(const GrProcessor& processor, | 
| jvanverth | cfc1886 | 2015-04-28 08:48:20 -0700 | [diff] [blame] | 1288 |                                              const GrGLSLCaps&, GrProcessorKeyBuilder* b) { | 
| bsalomon | 63e99f7 | 2014-07-21 08:03:14 -0700 | [diff] [blame] | 1289 |     uint32_t* key = b->add32n(2); | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1290 |     key[0] = GenBaseGradientKey(processor); | 
 | 1291 |     key[1] = processor.cast<CircleOutside2PtConicalEffect>().isFlipped(); | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1292 | } | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 1293 |  | 
 | 1294 | ////////////////////////////////////////////////////////////////////////////// | 
 | 1295 |  | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1296 | GrFragmentProcessor* Gr2PtConicalGradientEffect::Create(GrContext* ctx, | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 1297 |                                                         GrProcessorDataManager* procDataManager, | 
| joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 1298 |                                                         const SkTwoPointConicalGradient& shader, | 
 | 1299 |                                                         SkShader::TileMode tm, | 
 | 1300 |                                                         const SkMatrix* localMatrix) { | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 1301 |     SkMatrix matrix; | 
 | 1302 |     if (!shader.getLocalMatrix().invert(&matrix)) { | 
 | 1303 |         return NULL; | 
 | 1304 |     } | 
| commit-bot@chromium.org | 96fb748 | 2014-05-09 20:28:11 +0000 | [diff] [blame] | 1305 |     if (localMatrix) { | 
 | 1306 |         SkMatrix inv; | 
 | 1307 |         if (!localMatrix->invert(&inv)) { | 
 | 1308 |             return NULL; | 
 | 1309 |         } | 
 | 1310 |         matrix.postConcat(inv); | 
 | 1311 |     } | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 1312 |  | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1313 |     if (shader.getStartRadius() < kErrorTol) { | 
 | 1314 |         SkScalar focalX; | 
 | 1315 |         ConicalType type = set_matrix_focal_conical(shader, &matrix, &focalX); | 
 | 1316 |         if (type == kInside_ConicalType) { | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 1317 |             return FocalInside2PtConicalEffect::Create(ctx, procDataManager, shader, matrix, tm, | 
| joshualitt | b245605 | 2015-07-08 09:36:59 -0700 | [diff] [blame] | 1318 |                                                        focalX); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1319 |         } else if(type == kEdge_ConicalType) { | 
 | 1320 |             set_matrix_edge_conical(shader, &matrix); | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 1321 |             return Edge2PtConicalEffect::Create(ctx, procDataManager, shader, matrix, tm); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1322 |         } else { | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 1323 |             return FocalOutside2PtConicalEffect::Create(ctx, procDataManager, shader, matrix, tm, | 
| joshualitt | b245605 | 2015-07-08 09:36:59 -0700 | [diff] [blame] | 1324 |                                                         focalX); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1325 |         } | 
 | 1326 |     } | 
 | 1327 |  | 
 | 1328 |     CircleConicalInfo info; | 
 | 1329 |     ConicalType type = set_matrix_circle_conical(shader, &matrix, &info); | 
 | 1330 |  | 
 | 1331 |     if (type == kInside_ConicalType) { | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 1332 |         return CircleInside2PtConicalEffect::Create(ctx, procDataManager,  shader, matrix, tm, | 
| joshualitt | b245605 | 2015-07-08 09:36:59 -0700 | [diff] [blame] | 1333 |                                                     info); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1334 |     } else if (type == kEdge_ConicalType) { | 
 | 1335 |         set_matrix_edge_conical(shader, &matrix); | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 1336 |         return Edge2PtConicalEffect::Create(ctx, procDataManager, shader, matrix, tm); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1337 |     } else { | 
| joshualitt | 9cc1775 | 2015-07-09 06:28:14 -0700 | [diff] [blame] | 1338 |         return CircleOutside2PtConicalEffect::Create(ctx, procDataManager, shader, matrix, tm, | 
| joshualitt | b245605 | 2015-07-08 09:36:59 -0700 | [diff] [blame] | 1339 |                                                      info); | 
| commit-bot@chromium.org | c8379d7 | 2014-04-22 20:56:37 +0000 | [diff] [blame] | 1340 |     } | 
| commit-bot@chromium.org | 2af1a2d | 2014-04-04 13:50:50 +0000 | [diff] [blame] | 1341 | } | 
 | 1342 |  | 
| commit-bot@chromium.org | aa64fbf | 2014-04-03 14:59:19 +0000 | [diff] [blame] | 1343 | #endif |