1/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkPerlinNoiseShader.h"
9
10#include "SkArenaAlloc.h"
11#include "SkDither.h"
12#include "SkColorFilter.h"
13#include "SkMakeUnique.h"
14#include "SkReadBuffer.h"
15#include "SkWriteBuffer.h"
16#include "SkShader.h"
17#include "SkUnPreMultiply.h"
18#include "SkString.h"
19
20#if SK_SUPPORT_GPU
21#include "GrContext.h"
22#include "GrContextPriv.h"
23#include "GrCoordTransform.h"
24#include "SkGr.h"
25#include "effects/GrConstColorProcessor.h"
26#include "glsl/GrGLSLFragmentProcessor.h"
27#include "glsl/GrGLSLFragmentShaderBuilder.h"
28#include "glsl/GrGLSLProgramDataManager.h"
29#include "glsl/GrGLSLUniformHandler.h"
30#endif
31
32static const int kBlockSize = 256;
33static const int kBlockMask = kBlockSize - 1;
34static const int kPerlinNoise = 4096;
35static const int kRandMaximum = SK_MaxS32; // 2**31 - 1
36
37static uint8_t improved_noise_permutations[] = {
38    151, 160, 137,  91,  90,  15, 131,  13, 201,  95,  96,  53, 194, 233,   7, 225, 140,  36, 103,
39     30,  69, 142,   8,  99,  37, 240,  21,  10,  23, 190,   6, 148, 247, 120, 234,  75,   0,  26,
40    197,  62,  94, 252, 219, 203, 117,  35,  11,  32,  57, 177,  33,  88, 237, 149,  56,  87, 174,
41     20, 125, 136, 171, 168,  68, 175,  74, 165,  71, 134, 139,  48,  27, 166,  77, 146, 158, 231,
42     83, 111, 229, 122,  60, 211, 133, 230, 220, 105,  92,  41,  55,  46, 245,  40, 244, 102, 143,
43     54,  65,  25,  63, 161,   1, 216,  80,  73, 209,  76, 132, 187, 208,  89,  18, 169, 200, 196,
44    135, 130, 116, 188, 159,  86, 164, 100, 109, 198, 173, 186,   3,  64,  52, 217, 226, 250, 124,
45    123,   5, 202,  38, 147, 118, 126, 255,  82,  85, 212, 207, 206,  59, 227,  47,  16,  58,  17,
46    182, 189,  28,  42, 223, 183, 170, 213, 119, 248, 152,   2,  44, 154, 163,  70, 221, 153, 101,
47    155, 167,  43, 172,   9, 129,  22,  39, 253,  19,  98, 108, 110,  79, 113, 224, 232, 178, 185,
48    112, 104, 218, 246,  97, 228, 251,  34, 242, 193, 238, 210, 144,  12, 191, 179, 162, 241,  81,
49     51, 145, 235, 249,  14, 239, 107,  49, 192, 214,  31, 181, 199, 106, 157, 184,  84, 204, 176,
50    115, 121,  50,  45, 127,   4, 150, 254, 138, 236, 205,  93, 222, 114,  67,  29,  24,  72, 243,
51    141, 128, 195,  78,  66, 215,  61, 156, 180,
52    151, 160, 137,  91,  90,  15, 131,  13, 201,  95,  96,  53, 194, 233,   7, 225, 140,  36, 103,
53     30,  69, 142,   8,  99,  37, 240,  21,  10,  23, 190,   6, 148, 247, 120, 234,  75,   0,  26,
54    197,  62,  94, 252, 219, 203, 117,  35,  11,  32,  57, 177,  33,  88, 237, 149,  56,  87, 174,
55     20, 125, 136, 171, 168,  68, 175,  74, 165,  71, 134, 139,  48,  27, 166,  77, 146, 158, 231,
56     83, 111, 229, 122,  60, 211, 133, 230, 220, 105,  92,  41,  55,  46, 245,  40, 244, 102, 143,
57     54,  65,  25,  63, 161,   1, 216,  80,  73, 209,  76, 132, 187, 208,  89,  18, 169, 200, 196,
58    135, 130, 116, 188, 159,  86, 164, 100, 109, 198, 173, 186,   3,  64,  52, 217, 226, 250, 124,
59    123,   5, 202,  38, 147, 118, 126, 255,  82,  85, 212, 207, 206,  59, 227,  47,  16,  58,  17,
60    182, 189,  28,  42, 223, 183, 170, 213, 119, 248, 152,   2,  44, 154, 163,  70, 221, 153, 101,
61    155, 167,  43, 172,   9, 129,  22,  39, 253,  19,  98, 108, 110,  79, 113, 224, 232, 178, 185,
62    112, 104, 218, 246,  97, 228, 251,  34, 242, 193, 238, 210, 144,  12, 191, 179, 162, 241,  81,
63     51, 145, 235, 249,  14, 239, 107,  49, 192, 214,  31, 181, 199, 106, 157, 184,  84, 204, 176,
64    115, 121,  50,  45, 127,   4, 150, 254, 138, 236, 205,  93, 222, 114,  67,  29,  24,  72, 243,
65    141, 128, 195,  78,  66, 215,  61, 156, 180
66};
67
68class SkPerlinNoiseShaderImpl : public SkShaderBase {
69public:
70    struct StitchData {
71        StitchData()
72          : fWidth(0)
73          , fWrapX(0)
74          , fHeight(0)
75          , fWrapY(0)
76        {}
77
78        bool operator==(const StitchData& other) const {
79            return fWidth == other.fWidth &&
80                   fWrapX == other.fWrapX &&
81                   fHeight == other.fHeight &&
82                   fWrapY == other.fWrapY;
83        }
84
85        int fWidth; // How much to subtract to wrap for stitching.
86        int fWrapX; // Minimum value to wrap.
87        int fHeight;
88        int fWrapY;
89    };
90
91    struct PaintingData {
92        PaintingData(const SkISize& tileSize, SkScalar seed,
93                     SkScalar baseFrequencyX, SkScalar baseFrequencyY,
94                     const SkMatrix& matrix)
95        {
96            SkVector vec[2] = {
97                { SkScalarInvert(baseFrequencyX),   SkScalarInvert(baseFrequencyY)  },
98                { SkIntToScalar(tileSize.fWidth),   SkIntToScalar(tileSize.fHeight) },
99            };
100            matrix.mapVectors(vec, 2);
101
102            fBaseFrequency.set(SkScalarInvert(vec[0].fX), SkScalarInvert(vec[0].fY));
103            fTileSize.set(SkScalarRoundToInt(vec[1].fX), SkScalarRoundToInt(vec[1].fY));
104            this->init(seed);
105            if (!fTileSize.isEmpty()) {
106                this->stitch();
107            }
108
109    #if SK_SUPPORT_GPU
110            fPermutationsBitmap.setInfo(SkImageInfo::MakeA8(kBlockSize, 1));
111            fPermutationsBitmap.setPixels(fLatticeSelector);
112
113            fNoiseBitmap.setInfo(SkImageInfo::MakeN32Premul(kBlockSize, 4));
114            fNoiseBitmap.setPixels(fNoise[0][0]);
115
116            fImprovedPermutationsBitmap.setInfo(SkImageInfo::MakeA8(256, 1));
117            fImprovedPermutationsBitmap.setPixels(improved_noise_permutations);
118
119            fGradientBitmap.setInfo(SkImageInfo::MakeN32Premul(16, 1));
120            static uint8_t gradients[] = { 2, 2, 1, 0,
121                                           0, 2, 1, 0,
122                                           2, 0, 1, 0,
123                                           0, 0, 1, 0,
124                                           2, 1, 2, 0,
125                                           0, 1, 2, 0,
126                                           2, 1, 0, 0,
127                                           0, 1, 0, 0,
128                                           1, 2, 2, 0,
129                                           1, 0, 2, 0,
130                                           1, 2, 0, 0,
131                                           1, 0, 0, 0,
132                                           2, 2, 1, 0,
133                                           1, 0, 2, 0,
134                                           0, 2, 1, 0,
135                                           1, 0, 0, 0 };
136            fGradientBitmap.setPixels(gradients);
137    #endif
138        }
139
140    #if SK_SUPPORT_GPU
141        PaintingData(const PaintingData& that)
142                : fSeed(that.fSeed)
143                , fTileSize(that.fTileSize)
144                , fBaseFrequency(that.fBaseFrequency)
145                , fStitchDataInit(that.fStitchDataInit)
146                , fPermutationsBitmap(that.fPermutationsBitmap)
147                , fNoiseBitmap(that.fNoiseBitmap)
148                , fImprovedPermutationsBitmap(that.fImprovedPermutationsBitmap)
149                , fGradientBitmap(that.fGradientBitmap) {
150            memcpy(fLatticeSelector, that.fLatticeSelector, sizeof(fLatticeSelector));
151            memcpy(fNoise, that.fNoise, sizeof(fNoise));
152            memcpy(fGradient, that.fGradient, sizeof(fGradient));
153        }
154    #endif
155
156        int         fSeed;
157        uint8_t     fLatticeSelector[kBlockSize];
158        uint16_t    fNoise[4][kBlockSize][2];
159        SkPoint     fGradient[4][kBlockSize];
160        SkISize     fTileSize;
161        SkVector    fBaseFrequency;
162        StitchData  fStitchDataInit;
163
164    private:
165
166    #if SK_SUPPORT_GPU
167        SkBitmap   fPermutationsBitmap;
168        SkBitmap   fNoiseBitmap;
169        SkBitmap   fImprovedPermutationsBitmap;
170        SkBitmap   fGradientBitmap;
171    #endif
172
173        inline int random()  {
174            static const int gRandAmplitude = 16807; // 7**5; primitive root of m
175            static const int gRandQ = 127773; // m / a
176            static const int gRandR = 2836; // m % a
177
178            int result = gRandAmplitude * (fSeed % gRandQ) - gRandR * (fSeed / gRandQ);
179            if (result <= 0)
180                result += kRandMaximum;
181            fSeed = result;
182            return result;
183        }
184
185        // Only called once. Could be part of the constructor.
186        void init(SkScalar seed)
187        {
188            static const SkScalar gInvBlockSizef = SkScalarInvert(SkIntToScalar(kBlockSize));
189
190            // According to the SVG spec, we must truncate (not round) the seed value.
191            fSeed = SkScalarTruncToInt(seed);
192            // The seed value clamp to the range [1, kRandMaximum - 1].
193            if (fSeed <= 0) {
194                fSeed = -(fSeed % (kRandMaximum - 1)) + 1;
195            }
196            if (fSeed > kRandMaximum - 1) {
197                fSeed = kRandMaximum - 1;
198            }
199            for (int channel = 0; channel < 4; ++channel) {
200                for (int i = 0; i < kBlockSize; ++i) {
201                    fLatticeSelector[i] = i;
202                    fNoise[channel][i][0] = (random() % (2 * kBlockSize));
203                    fNoise[channel][i][1] = (random() % (2 * kBlockSize));
204                }
205            }
206            for (int i = kBlockSize - 1; i > 0; --i) {
207                int k = fLatticeSelector[i];
208                int j = random() % kBlockSize;
209                SkASSERT(j >= 0);
210                SkASSERT(j < kBlockSize);
211                fLatticeSelector[i] = fLatticeSelector[j];
212                fLatticeSelector[j] = k;
213            }
214
215            // Perform the permutations now
216            {
217                // Copy noise data
218                uint16_t noise[4][kBlockSize][2];
219                for (int i = 0; i < kBlockSize; ++i) {
220                    for (int channel = 0; channel < 4; ++channel) {
221                        for (int j = 0; j < 2; ++j) {
222                            noise[channel][i][j] = fNoise[channel][i][j];
223                        }
224                    }
225                }
226                // Do permutations on noise data
227                for (int i = 0; i < kBlockSize; ++i) {
228                    for (int channel = 0; channel < 4; ++channel) {
229                        for (int j = 0; j < 2; ++j) {
230                            fNoise[channel][i][j] = noise[channel][fLatticeSelector[i]][j];
231                        }
232                    }
233                }
234            }
235
236            // Half of the largest possible value for 16 bit unsigned int
237            static const SkScalar gHalfMax16bits = 32767.5f;
238
239            // Compute gradients from permutated noise data
240            for (int channel = 0; channel < 4; ++channel) {
241                for (int i = 0; i < kBlockSize; ++i) {
242                    fGradient[channel][i] = SkPoint::Make(
243                        (fNoise[channel][i][0] - kBlockSize) * gInvBlockSizef,
244                        (fNoise[channel][i][1] - kBlockSize) * gInvBlockSizef);
245                    fGradient[channel][i].normalize();
246                    // Put the normalized gradient back into the noise data
247                    fNoise[channel][i][0] = SkScalarRoundToInt(
248                                                   (fGradient[channel][i].fX + 1) * gHalfMax16bits);
249                    fNoise[channel][i][1] = SkScalarRoundToInt(
250                                                   (fGradient[channel][i].fY + 1) * gHalfMax16bits);
251                }
252            }
253        }
254
255        // Only called once. Could be part of the constructor.
256        void stitch() {
257            SkScalar tileWidth  = SkIntToScalar(fTileSize.width());
258            SkScalar tileHeight = SkIntToScalar(fTileSize.height());
259            SkASSERT(tileWidth > 0 && tileHeight > 0);
260            // When stitching tiled turbulence, the frequencies must be adjusted
261            // so that the tile borders will be continuous.
262            if (fBaseFrequency.fX) {
263                SkScalar lowFrequencx =
264                    SkScalarFloorToScalar(tileWidth * fBaseFrequency.fX) / tileWidth;
265                SkScalar highFrequencx =
266                    SkScalarCeilToScalar(tileWidth * fBaseFrequency.fX) / tileWidth;
267                // BaseFrequency should be non-negative according to the standard.
268                if (fBaseFrequency.fX / lowFrequencx < highFrequencx / fBaseFrequency.fX) {
269                    fBaseFrequency.fX = lowFrequencx;
270                } else {
271                    fBaseFrequency.fX = highFrequencx;
272                }
273            }
274            if (fBaseFrequency.fY) {
275                SkScalar lowFrequency =
276                    SkScalarFloorToScalar(tileHeight * fBaseFrequency.fY) / tileHeight;
277                SkScalar highFrequency =
278                    SkScalarCeilToScalar(tileHeight * fBaseFrequency.fY) / tileHeight;
279                if (fBaseFrequency.fY / lowFrequency < highFrequency / fBaseFrequency.fY) {
280                    fBaseFrequency.fY = lowFrequency;
281                } else {
282                    fBaseFrequency.fY = highFrequency;
283                }
284            }
285            // Set up TurbulenceInitial stitch values.
286            fStitchDataInit.fWidth  =
287                SkScalarRoundToInt(tileWidth * fBaseFrequency.fX);
288            fStitchDataInit.fWrapX  = kPerlinNoise + fStitchDataInit.fWidth;
289            fStitchDataInit.fHeight =
290                SkScalarRoundToInt(tileHeight * fBaseFrequency.fY);
291            fStitchDataInit.fWrapY  = kPerlinNoise + fStitchDataInit.fHeight;
292        }
293
294    public:
295
296#if SK_SUPPORT_GPU
297        const SkBitmap& getPermutationsBitmap() const { return fPermutationsBitmap; }
298
299        const SkBitmap& getNoiseBitmap() const { return fNoiseBitmap; }
300
301        const SkBitmap& getImprovedPermutationsBitmap() const { return fImprovedPermutationsBitmap; }
302
303        const SkBitmap& getGradientBitmap() const { return fGradientBitmap; }
304#endif
305    };
306
307    /**
308     *  About the noise types : the difference between the first 2 is just minor tweaks to the
309     *  algorithm, they're not 2 entirely different noises. The output looks different, but once the
310     *  noise is generated in the [1, -1] range, the output is brought back in the [0, 1] range by
311     *  doing :
312     *  kFractalNoise_Type : noise * 0.5 + 0.5
313     *  kTurbulence_Type   : abs(noise)
314     *  Very little differences between the 2 types, although you can tell the difference visually.
315     *  "Improved" is based on the Improved Perlin Noise algorithm described at
316     *  http://mrl.nyu.edu/~perlin/noise/. It is quite distinct from the other two, and the noise is
317     *  a 2D slice of a 3D noise texture. Minor changes to the Z coordinate will result in minor
318     *  changes to the noise, making it suitable for animated noise.
319     */
320    enum Type {
321        kFractalNoise_Type,
322        kTurbulence_Type,
323        kImprovedNoise_Type,
324        kLast_Type = kImprovedNoise_Type
325    };
326
327    static const int kMaxOctaves = 255; // numOctaves must be <= 0 and <= kMaxOctaves
328
329    SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::Type type, SkScalar baseFrequencyX,
330                      SkScalar baseFrequencyY, int numOctaves, SkScalar seed,
331                      const SkISize* tileSize);
332
333    class PerlinNoiseShaderContext : public Context {
334    public:
335        PerlinNoiseShaderContext(const SkPerlinNoiseShaderImpl& shader, const ContextRec&);
336
337        void shadeSpan(int x, int y, SkPMColor[], int count) override;
338
339    private:
340        SkPMColor shade(const SkPoint& point, StitchData& stitchData) const;
341        SkScalar calculateTurbulenceValueForPoint(
342                                                  int channel,
343                                                  StitchData& stitchData, const SkPoint& point) const;
344        SkScalar calculateImprovedNoiseValueForPoint(int channel, const SkPoint& point) const;
345        SkScalar noise2D(int channel,
346                         const StitchData& stitchData, const SkPoint& noiseVector) const;
347
348        SkMatrix     fMatrix;
349        PaintingData fPaintingData;
350
351        typedef Context INHERITED;
352    };
353
354#if SK_SUPPORT_GPU
355    std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override;
356#endif
357
358    SK_TO_STRING_OVERRIDE()
359    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPerlinNoiseShaderImpl)
360
361protected:
362    void flatten(SkWriteBuffer&) const override;
363    Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
364
365private:
366    const SkPerlinNoiseShaderImpl::Type fType;
367    const SkScalar                  fBaseFrequencyX;
368    const SkScalar                  fBaseFrequencyY;
369    const int                       fNumOctaves;
370    const SkScalar                  fSeed;
371    const SkISize                   fTileSize;
372    const bool                      fStitchTiles;
373
374    friend class ::SkPerlinNoiseShader;
375
376    typedef SkShaderBase INHERITED;
377};
378
379namespace {
380
381// noiseValue is the color component's value (or color)
382// limitValue is the maximum perlin noise array index value allowed
383// newValue is the current noise dimension (either width or height)
384inline int checkNoise(int noiseValue, int limitValue, int newValue) {
385    // If the noise value would bring us out of bounds of the current noise array while we are
386    // stiching noise tiles together, wrap the noise around the current dimension of the noise to
387    // stay within the array bounds in a continuous fashion (so that tiling lines are not visible)
388    if (noiseValue >= limitValue) {
389        noiseValue -= newValue;
390    }
391    return noiseValue;
392}
393
394inline SkScalar smoothCurve(SkScalar t) {
395    return t * t * (3 - 2 * t);
396}
397
398} // end namespace
399
400SkPerlinNoiseShaderImpl::SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::Type type,
401                                                 SkScalar baseFrequencyX,
402                                                 SkScalar baseFrequencyY,
403                                                 int numOctaves,
404                                                 SkScalar seed,
405                                                 const SkISize* tileSize)
406  : fType(type)
407  , fBaseFrequencyX(baseFrequencyX)
408  , fBaseFrequencyY(baseFrequencyY)
409  , fNumOctaves(numOctaves > kMaxOctaves ? kMaxOctaves : numOctaves/*[0,255] octaves allowed*/)
410  , fSeed(seed)
411  , fTileSize(nullptr == tileSize ? SkISize::Make(0, 0) : *tileSize)
412  , fStitchTiles(!fTileSize.isEmpty())
413{
414    SkASSERT(numOctaves >= 0 && numOctaves <= kMaxOctaves);
415}
416
417sk_sp<SkFlattenable> SkPerlinNoiseShaderImpl::CreateProc(SkReadBuffer& buffer) {
418    Type type = buffer.read32LE(kLast_Type);
419
420    SkScalar freqX = buffer.readScalar();
421    SkScalar freqY = buffer.readScalar();
422
423    int octaves = buffer.read32LE<int>(kMaxOctaves);
424
425    SkScalar seed = buffer.readScalar();
426    SkISize tileSize;
427    tileSize.fWidth = buffer.readInt();
428    tileSize.fHeight = buffer.readInt();
429
430    switch (type) {
431        case kFractalNoise_Type:
432            return SkPerlinNoiseShader::MakeFractalNoise(freqX, freqY, octaves, seed, &tileSize);
433        case kTurbulence_Type:
434            return SkPerlinNoiseShader::MakeTurbulence(freqX, freqY, octaves, seed, &tileSize);
435        case kImprovedNoise_Type:
436            return SkPerlinNoiseShader::MakeImprovedNoise(freqX, freqY, octaves, seed);
437        default:
438            // Really shouldn't get here b.c. of earlier check on type
439            buffer.validate(false);
440            return nullptr;
441    }
442}
443
444void SkPerlinNoiseShaderImpl::flatten(SkWriteBuffer& buffer) const {
445    buffer.writeInt((int) fType);
446    buffer.writeScalar(fBaseFrequencyX);
447    buffer.writeScalar(fBaseFrequencyY);
448    buffer.writeInt(fNumOctaves);
449    buffer.writeScalar(fSeed);
450    buffer.writeInt(fTileSize.fWidth);
451    buffer.writeInt(fTileSize.fHeight);
452}
453
454SkScalar SkPerlinNoiseShaderImpl::PerlinNoiseShaderContext::noise2D(
455        int channel, const StitchData& stitchData, const SkPoint& noiseVector) const {
456    struct Noise {
457        int noisePositionIntegerValue;
458        int nextNoisePositionIntegerValue;
459        SkScalar noisePositionFractionValue;
460        Noise(SkScalar component)
461        {
462            SkScalar position = component + kPerlinNoise;
463            noisePositionIntegerValue = SkScalarFloorToInt(position);
464            noisePositionFractionValue = position - SkIntToScalar(noisePositionIntegerValue);
465            nextNoisePositionIntegerValue = noisePositionIntegerValue + 1;
466        }
467    };
468    Noise noiseX(noiseVector.x());
469    Noise noiseY(noiseVector.y());
470    SkScalar u, v;
471    const SkPerlinNoiseShaderImpl& perlinNoiseShader = static_cast<const SkPerlinNoiseShaderImpl&>(fShader);
472    // If stitching, adjust lattice points accordingly.
473    if (perlinNoiseShader.fStitchTiles) {
474        noiseX.noisePositionIntegerValue =
475            checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth);
476        noiseY.noisePositionIntegerValue =
477            checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight);
478        noiseX.nextNoisePositionIntegerValue =
479            checkNoise(noiseX.nextNoisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth);
480        noiseY.nextNoisePositionIntegerValue =
481            checkNoise(noiseY.nextNoisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight);
482    }
483    noiseX.noisePositionIntegerValue &= kBlockMask;
484    noiseY.noisePositionIntegerValue &= kBlockMask;
485    noiseX.nextNoisePositionIntegerValue &= kBlockMask;
486    noiseY.nextNoisePositionIntegerValue &= kBlockMask;
487    int i = fPaintingData.fLatticeSelector[noiseX.noisePositionIntegerValue];
488    int j = fPaintingData.fLatticeSelector[noiseX.nextNoisePositionIntegerValue];
489    int b00 = (i + noiseY.noisePositionIntegerValue) & kBlockMask;
490    int b10 = (j + noiseY.noisePositionIntegerValue) & kBlockMask;
491    int b01 = (i + noiseY.nextNoisePositionIntegerValue) & kBlockMask;
492    int b11 = (j + noiseY.nextNoisePositionIntegerValue) & kBlockMask;
493    SkScalar sx = smoothCurve(noiseX.noisePositionFractionValue);
494    SkScalar sy = smoothCurve(noiseY.noisePositionFractionValue);
495
496    if (sx < 0 || sy < 0 || sx > 1 || sy > 1) {
497        return 0;  // Check for pathological inputs.
498    }
499
500    // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement
501    SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue,
502                                          noiseY.noisePositionFractionValue); // Offset (0,0)
503    u = fPaintingData.fGradient[channel][b00].dot(fractionValue);
504    fractionValue.fX -= SK_Scalar1; // Offset (-1,0)
505    v = fPaintingData.fGradient[channel][b10].dot(fractionValue);
506    SkScalar a = SkScalarInterp(u, v, sx);
507    fractionValue.fY -= SK_Scalar1; // Offset (-1,-1)
508    v = fPaintingData.fGradient[channel][b11].dot(fractionValue);
509    fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1)
510    u = fPaintingData.fGradient[channel][b01].dot(fractionValue);
511    SkScalar b = SkScalarInterp(u, v, sx);
512    return SkScalarInterp(a, b, sy);
513}
514
515SkScalar SkPerlinNoiseShaderImpl::PerlinNoiseShaderContext::calculateTurbulenceValueForPoint(
516        int channel, StitchData& stitchData, const SkPoint& point) const {
517    const SkPerlinNoiseShaderImpl& perlinNoiseShader = static_cast<const SkPerlinNoiseShaderImpl&>(fShader);
518    if (perlinNoiseShader.fStitchTiles) {
519        // Set up TurbulenceInitial stitch values.
520        stitchData = fPaintingData.fStitchDataInit;
521    }
522    SkScalar turbulenceFunctionResult = 0;
523    SkPoint noiseVector(SkPoint::Make(point.x() * fPaintingData.fBaseFrequency.fX,
524                                      point.y() * fPaintingData.fBaseFrequency.fY));
525    SkScalar ratio = SK_Scalar1;
526    for (int octave = 0; octave < perlinNoiseShader.fNumOctaves; ++octave) {
527        SkScalar noise = noise2D(channel, stitchData, noiseVector);
528        SkScalar numer = (perlinNoiseShader.fType == kFractalNoise_Type) ?
529                            noise : SkScalarAbs(noise);
530        turbulenceFunctionResult += numer / ratio;
531        noiseVector.fX *= 2;
532        noiseVector.fY *= 2;
533        ratio *= 2;
534        if (perlinNoiseShader.fStitchTiles) {
535            // Update stitch values
536            stitchData.fWidth  *= 2;
537            stitchData.fWrapX   = stitchData.fWidth + kPerlinNoise;
538            stitchData.fHeight *= 2;
539            stitchData.fWrapY   = stitchData.fHeight + kPerlinNoise;
540        }
541    }
542
543    // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
544    // by fractalNoise and (turbulenceFunctionResult) by turbulence.
545    if (perlinNoiseShader.fType == kFractalNoise_Type) {
546        turbulenceFunctionResult = SkScalarHalf(turbulenceFunctionResult + 1);
547    }
548
549    if (channel == 3) { // Scale alpha by paint value
550        turbulenceFunctionResult *= SkIntToScalar(getPaintAlpha()) / 255;
551    }
552
553    // Clamp result
554    return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1);
555}
556
557////////////////////////////////////////////////////////////////////////////////////////////////////
558// Improved Perlin Noise based on Java implementation found at http://mrl.nyu.edu/~perlin/noise/
559static SkScalar fade(SkScalar t) {
560    return t * t * t * (t * (t * 6 - 15) + 10);
561}
562
563static SkScalar lerp(SkScalar t, SkScalar a, SkScalar b) {
564    return a + t * (b - a);
565}
566
567static SkScalar grad(int hash, SkScalar x, SkScalar y, SkScalar z) {
568    int h = hash & 15;
569    SkScalar u = h < 8 ? x : y;
570    SkScalar v = h < 4 ? y : h == 12 || h == 14 ? x : z;
571    return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
572}
573
574SkScalar SkPerlinNoiseShaderImpl::PerlinNoiseShaderContext::calculateImprovedNoiseValueForPoint(
575        int channel, const SkPoint& point) const {
576    const SkPerlinNoiseShaderImpl& perlinNoiseShader = static_cast<const SkPerlinNoiseShaderImpl&>(fShader);
577    SkScalar x = point.fX * perlinNoiseShader.fBaseFrequencyX;
578    SkScalar y = point.fY * perlinNoiseShader.fBaseFrequencyY;
579    // z offset between different channels, chosen arbitrarily
580    static const SkScalar CHANNEL_DELTA = 1000.0f;
581    SkScalar z = channel * CHANNEL_DELTA + perlinNoiseShader.fSeed;
582    SkScalar result = 0;
583    SkScalar ratio = SK_Scalar1;
584    for (int i = 0; i < perlinNoiseShader.fNumOctaves; i++) {
585        int X = SkScalarFloorToInt(x) & 255;
586        int Y = SkScalarFloorToInt(y) & 255;
587        int Z = SkScalarFloorToInt(z) & 255;
588        SkScalar px = x - SkScalarFloorToScalar(x);
589        SkScalar py = y - SkScalarFloorToScalar(y);
590        SkScalar pz = z - SkScalarFloorToScalar(z);
591        SkScalar u = fade(px);
592        SkScalar v = fade(py);
593        SkScalar w = fade(pz);
594        uint8_t* permutations = improved_noise_permutations;
595        int A  = permutations[X] + Y;
596        int AA = permutations[A] + Z;
597        int AB = permutations[A + 1] + Z;
598        int B  = permutations[X + 1] + Y;
599        int BA = permutations[B] + Z;
600        int BB = permutations[B + 1] + Z;
601        result += lerp(w, lerp(v, lerp(u, grad(permutations[AA    ], px    , py    , pz    ),
602                                          grad(permutations[BA    ], px - 1, py    , pz    )),
603                                  lerp(u, grad(permutations[AB    ], px    , py - 1, pz    ),
604                                          grad(permutations[BB    ], px - 1, py - 1, pz    ))),
605                          lerp(v, lerp(u, grad(permutations[AA + 1], px    , py    , pz - 1),
606                                          grad(permutations[BA + 1], px - 1, py    , pz - 1)),
607                                  lerp(u, grad(permutations[AB + 1], px    , py - 1, pz - 1),
608                                          grad(permutations[BB + 1], px - 1, py - 1, pz - 1)))) /
609                   ratio;
610        x *= 2;
611        y *= 2;
612        ratio *= 2;
613    }
614    result = SkScalarClampMax((result + 1.0f) / 2.0f, 1.0f);
615    return result;
616}
617////////////////////////////////////////////////////////////////////////////////////////////////////
618
619SkPMColor SkPerlinNoiseShaderImpl::PerlinNoiseShaderContext::shade(
620        const SkPoint& point, StitchData& stitchData) const {
621    const SkPerlinNoiseShaderImpl& perlinNoiseShader = static_cast<const SkPerlinNoiseShaderImpl&>(fShader);
622    SkPoint newPoint;
623    fMatrix.mapPoints(&newPoint, &point, 1);
624    newPoint.fX = SkScalarRoundToScalar(newPoint.fX);
625    newPoint.fY = SkScalarRoundToScalar(newPoint.fY);
626
627    U8CPU rgba[4];
628    for (int channel = 3; channel >= 0; --channel) {
629        SkScalar value;
630        if (perlinNoiseShader.fType == kImprovedNoise_Type) {
631            value = calculateImprovedNoiseValueForPoint(channel, newPoint);
632        }
633        else {
634            value = calculateTurbulenceValueForPoint(channel, stitchData, newPoint);
635        }
636        rgba[channel] = SkScalarFloorToInt(255 * value);
637    }
638    return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
639}
640
641SkShaderBase::Context* SkPerlinNoiseShaderImpl::onMakeContext(const ContextRec& rec,
642                                                           SkArenaAlloc* alloc) const {
643    return alloc->make<PerlinNoiseShaderContext>(*this, rec);
644}
645
646static inline SkMatrix total_matrix(const SkShaderBase::ContextRec& rec,
647                                    const SkShaderBase& shader) {
648    SkMatrix matrix = SkMatrix::Concat(*rec.fMatrix, shader.getLocalMatrix());
649    if (rec.fLocalMatrix) {
650        matrix.preConcat(*rec.fLocalMatrix);
651    }
652
653    return matrix;
654}
655
656SkPerlinNoiseShaderImpl::PerlinNoiseShaderContext::PerlinNoiseShaderContext(
657        const SkPerlinNoiseShaderImpl& shader, const ContextRec& rec)
658    : INHERITED(shader, rec)
659    , fMatrix(total_matrix(rec, shader)) // used for temp storage, adjusted below
660    , fPaintingData(shader.fTileSize, shader.fSeed, shader.fBaseFrequencyX,
661                    shader.fBaseFrequencyY, fMatrix)
662{
663    // This (1,1) translation is due to WebKit's 1 based coordinates for the noise
664    // (as opposed to 0 based, usually). The same adjustment is in the setData() function.
665    fMatrix.setTranslate(-fMatrix.getTranslateX() + SK_Scalar1,
666                         -fMatrix.getTranslateY() + SK_Scalar1);
667}
668
669void SkPerlinNoiseShaderImpl::PerlinNoiseShaderContext::shadeSpan(
670        int x, int y, SkPMColor result[], int count) {
671    SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
672    StitchData stitchData;
673    for (int i = 0; i < count; ++i) {
674        result[i] = shade(point, stitchData);
675        point.fX += SK_Scalar1;
676    }
677}
678
679/////////////////////////////////////////////////////////////////////
680
681#if SK_SUPPORT_GPU
682
683class GrGLPerlinNoise : public GrGLSLFragmentProcessor {
684public:
685    void emitCode(EmitArgs&) override;
686
687    static inline void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder* b);
688
689protected:
690    void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override;
691
692private:
693    GrGLSLProgramDataManager::UniformHandle fStitchDataUni;
694    GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni;
695
696    typedef GrGLSLFragmentProcessor INHERITED;
697};
698
699/////////////////////////////////////////////////////////////////////
700
701class GrPerlinNoise2Effect : public GrFragmentProcessor {
702public:
703    static std::unique_ptr<GrFragmentProcessor> Make(
704            SkPerlinNoiseShaderImpl::Type type, int numOctaves, bool stitchTiles,
705            std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData,
706            sk_sp<GrTextureProxy> permutationsProxy, sk_sp<GrTextureProxy> noiseProxy,
707            const SkMatrix& matrix) {
708        return std::unique_ptr<GrFragmentProcessor>(new GrPerlinNoise2Effect(
709                type, numOctaves, stitchTiles, std::move(paintingData),
710                std::move(permutationsProxy), std::move(noiseProxy), matrix));
711    }
712
713    const char* name() const override { return "PerlinNoise"; }
714
715    std::unique_ptr<GrFragmentProcessor> clone() const override {
716        return std::unique_ptr<GrFragmentProcessor>(new GrPerlinNoise2Effect(*this));
717    }
718
719    const SkPerlinNoiseShaderImpl::StitchData& stitchData() const { return fPaintingData->fStitchDataInit; }
720
721    SkPerlinNoiseShaderImpl::Type type() const { return fType; }
722    bool stitchTiles() const { return fStitchTiles; }
723    const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency; }
724    int numOctaves() const { return fNumOctaves; }
725    const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); }
726
727private:
728    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
729        return new GrGLPerlinNoise;
730    }
731
732    virtual void onGetGLSLProcessorKey(const GrShaderCaps& caps,
733                                       GrProcessorKeyBuilder* b) const override {
734        GrGLPerlinNoise::GenKey(*this, caps, b);
735    }
736
737    bool onIsEqual(const GrFragmentProcessor& sBase) const override {
738        const GrPerlinNoise2Effect& s = sBase.cast<GrPerlinNoise2Effect>();
739        return fType == s.fType &&
740               fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency &&
741               fNumOctaves == s.fNumOctaves &&
742               fStitchTiles == s.fStitchTiles &&
743               fPaintingData->fStitchDataInit == s.fPaintingData->fStitchDataInit;
744    }
745
746    GrPerlinNoise2Effect(SkPerlinNoiseShaderImpl::Type type, int numOctaves, bool stitchTiles,
747                         std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData,
748                         sk_sp<GrTextureProxy> permutationsProxy,
749                         sk_sp<GrTextureProxy> noiseProxy,
750                         const SkMatrix& matrix)
751            : INHERITED(kGrPerlinNoise2Effect_ClassID, kNone_OptimizationFlags)
752            , fType(type)
753            , fNumOctaves(numOctaves)
754            , fStitchTiles(stitchTiles)
755            , fPermutationsSampler(std::move(permutationsProxy))
756            , fNoiseSampler(std::move(noiseProxy))
757            , fPaintingData(std::move(paintingData)) {
758        this->addTextureSampler(&fPermutationsSampler);
759        this->addTextureSampler(&fNoiseSampler);
760        fCoordTransform.reset(matrix);
761        this->addCoordTransform(&fCoordTransform);
762    }
763
764    GrPerlinNoise2Effect(const GrPerlinNoise2Effect& that)
765            : INHERITED(kGrPerlinNoise2Effect_ClassID, kNone_OptimizationFlags)
766            , fType(that.fType)
767            , fCoordTransform(that.fCoordTransform)
768            , fNumOctaves(that.fNumOctaves)
769            , fStitchTiles(that.fStitchTiles)
770            , fPermutationsSampler(that.fPermutationsSampler)
771            , fNoiseSampler(that.fNoiseSampler)
772            , fPaintingData(new SkPerlinNoiseShaderImpl::PaintingData(*that.fPaintingData)) {
773        this->addTextureSampler(&fPermutationsSampler);
774        this->addTextureSampler(&fNoiseSampler);
775        this->addCoordTransform(&fCoordTransform);
776    }
777
778    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
779
780    SkPerlinNoiseShaderImpl::Type       fType;
781    GrCoordTransform                    fCoordTransform;
782    int                                 fNumOctaves;
783    bool                                fStitchTiles;
784    TextureSampler                      fPermutationsSampler;
785    TextureSampler                      fNoiseSampler;
786    std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> fPaintingData;
787
788    typedef GrFragmentProcessor INHERITED;
789};
790
791/////////////////////////////////////////////////////////////////////
792GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrPerlinNoise2Effect);
793
794#if GR_TEST_UTILS
795std::unique_ptr<GrFragmentProcessor> GrPerlinNoise2Effect::TestCreate(GrProcessorTestData* d) {
796    int      numOctaves = d->fRandom->nextRangeU(2, 10);
797    bool     stitchTiles = d->fRandom->nextBool();
798    SkScalar seed = SkIntToScalar(d->fRandom->nextU());
799    SkISize  tileSize = SkISize::Make(d->fRandom->nextRangeU(4, 4096),
800                                      d->fRandom->nextRangeU(4, 4096));
801    SkScalar baseFrequencyX = d->fRandom->nextRangeScalar(0.01f,
802                                                          0.99f);
803    SkScalar baseFrequencyY = d->fRandom->nextRangeScalar(0.01f,
804                                                          0.99f);
805
806    sk_sp<SkShader> shader(d->fRandom->nextBool() ?
807        SkPerlinNoiseShader::MakeFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves, seed,
808                                               stitchTiles ? &tileSize : nullptr) :
809        SkPerlinNoiseShader::MakeTurbulence(baseFrequencyX, baseFrequencyY, numOctaves, seed,
810                                             stitchTiles ? &tileSize : nullptr));
811
812    GrTest::TestAsFPArgs asFPArgs(d);
813    return as_SB(shader)->asFragmentProcessor(asFPArgs.args());
814}
815#endif
816
817void GrGLPerlinNoise::emitCode(EmitArgs& args) {
818    const GrPerlinNoise2Effect& pne = args.fFp.cast<GrPerlinNoise2Effect>();
819
820    GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
821    GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
822    SkString vCoords = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
823
824    fBaseFrequencyUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType,
825                                                   "baseFrequency");
826    const char* baseFrequencyUni = uniformHandler->getUniformCStr(fBaseFrequencyUni);
827
828    const char* stitchDataUni = nullptr;
829    if (pne.stitchTiles()) {
830        fStitchDataUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType,
831                                                    "stitchData");
832        stitchDataUni = uniformHandler->getUniformCStr(fStitchDataUni);
833    }
834
835    // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8
836    const char* chanCoordR  = "0.125";
837    const char* chanCoordG  = "0.375";
838    const char* chanCoordB  = "0.625";
839    const char* chanCoordA  = "0.875";
840    const char* chanCoord   = "chanCoord";
841    const char* stitchData  = "stitchData";
842    const char* ratio       = "ratio";
843    const char* noiseVec    = "noiseVec";
844    const char* noiseSmooth = "noiseSmooth";
845    const char* floorVal    = "floorVal";
846    const char* fractVal    = "fractVal";
847    const char* uv          = "uv";
848    const char* ab          = "ab";
849    const char* latticeIdx  = "latticeIdx";
850    const char* bcoords     = "bcoords";
851    const char* lattice     = "lattice";
852    const char* inc8bit     = "0.00390625";  // 1.0 / 256.0
853    // This is the math to convert the two 16bit integer packed into rgba 8 bit input into a
854    // [-1,1] vector and perform a dot product between that vector and the provided vector.
855    const char* dotLattice  = "dot(((%s.ga + %s.rb * half2(%s)) * half2(2.0) - half2(1.0)), %s);";
856
857    // Add noise function
858    static const GrShaderVar gPerlinNoiseArgs[] =  {
859        GrShaderVar(chanCoord, kHalf_GrSLType),
860        GrShaderVar(noiseVec, kHalf2_GrSLType)
861    };
862
863    static const GrShaderVar gPerlinNoiseStitchArgs[] =  {
864        GrShaderVar(chanCoord, kHalf_GrSLType),
865        GrShaderVar(noiseVec, kHalf2_GrSLType),
866        GrShaderVar(stitchData, kHalf2_GrSLType)
867    };
868
869    SkString noiseCode;
870
871    noiseCode.appendf("\thalf4 %s;\n", floorVal);
872    noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec);
873    noiseCode.appendf("\t%s.zw = %s.xy + half2(1.0);\n", floorVal, floorVal);
874    noiseCode.appendf("\thalf2 %s = fract(%s);\n", fractVal, noiseVec);
875
876    // smooth curve : t * t * (3 - 2 * t)
877    noiseCode.appendf("\n\thalf2 %s = %s * %s * (half2(3.0) - half2(2.0) * %s);",
878        noiseSmooth, fractVal, fractVal, fractVal);
879
880    // Adjust frequencies if we're stitching tiles
881    if (pne.stitchTiles()) {
882        noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }",
883            floorVal, stitchData, floorVal, stitchData);
884        noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }",
885            floorVal, stitchData, floorVal, stitchData);
886        noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }",
887            floorVal, stitchData, floorVal, stitchData);
888        noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }",
889            floorVal, stitchData, floorVal, stitchData);
890    }
891
892    // Get texture coordinates and normalize
893    noiseCode.appendf("\n\t%s = fract(floor(mod(%s, 256.0)) / half4(256.0));\n",
894        floorVal, floorVal);
895
896    // Get permutation for x
897    {
898        SkString xCoords("");
899        xCoords.appendf("half2(%s.x, 0.5)", floorVal);
900
901        noiseCode.appendf("\n\thalf2 %s;\n\t%s.x = ", latticeIdx, latticeIdx);
902        fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[0], xCoords.c_str(),
903                                         kHalf2_GrSLType);
904        noiseCode.append(".r;");
905    }
906
907    // Get permutation for x + 1
908    {
909        SkString xCoords("");
910        xCoords.appendf("half2(%s.z, 0.5)", floorVal);
911
912        noiseCode.appendf("\n\t%s.y = ", latticeIdx);
913        fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[0], xCoords.c_str(),
914                                         kHalf2_GrSLType);
915        noiseCode.append(".r;");
916    }
917
918#if defined(SK_BUILD_FOR_ANDROID)
919    // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Nexus 7 (Tegra 3).
920    // The issue is that colors aren't accurate enough on Tegra devices. For example, if an 8 bit
921    // value of 124 (or 0.486275 here) is entered, we can get a texture value of 123.513725
922    // (or 0.484368 here). The following rounding operation prevents these precision issues from
923    // affecting the result of the noise by making sure that we only have multiples of 1/255.
924    // (Note that 1/255 is about 0.003921569, which is the value used here).
925    noiseCode.appendf("\n\t%s = floor(%s * half2(255.0) + half2(0.5)) * half2(0.003921569);",
926                      latticeIdx, latticeIdx);
927#endif
928
929    // Get (x,y) coordinates with the permutated x
930    noiseCode.appendf("\n\thalf4 %s = fract(%s.xyxy + %s.yyww);", bcoords, latticeIdx, floorVal);
931
932    noiseCode.appendf("\n\n\thalf2 %s;", uv);
933    // Compute u, at offset (0,0)
934    {
935        SkString latticeCoords("");
936        latticeCoords.appendf("half2(%s.x, %s)", bcoords, chanCoord);
937        noiseCode.appendf("\n\thalf4 %s = ", lattice);
938        fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[1], latticeCoords.c_str(),
939                                         kHalf2_GrSLType);
940        noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
941        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
942    }
943
944    noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal);
945    // Compute v, at offset (-1,0)
946    {
947        SkString latticeCoords("");
948        latticeCoords.appendf("half2(%s.y, %s)", bcoords, chanCoord);
949        noiseCode.append("\n\tlattice = ");
950        fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[1], latticeCoords.c_str(),
951                                         kHalf2_GrSLType);
952        noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
953        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
954    }
955
956    // Compute 'a' as a linear interpolation of 'u' and 'v'
957    noiseCode.appendf("\n\thalf2 %s;", ab);
958    noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth);
959
960    noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal);
961    // Compute v, at offset (-1,-1)
962    {
963        SkString latticeCoords("");
964        latticeCoords.appendf("half2(%s.w, %s)", bcoords, chanCoord);
965        noiseCode.append("\n\tlattice = ");
966        fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[1], latticeCoords.c_str(),
967                                         kHalf2_GrSLType);
968        noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
969        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
970    }
971
972    noiseCode.appendf("\n\t%s.x += 1.0;", fractVal);
973    // Compute u, at offset (0,-1)
974    {
975        SkString latticeCoords("");
976        latticeCoords.appendf("half2(%s.z, %s)", bcoords, chanCoord);
977        noiseCode.append("\n\tlattice = ");
978        fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[1], latticeCoords.c_str(),
979                                         kHalf2_GrSLType);
980        noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
981        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
982    }
983
984    // Compute 'b' as a linear interpolation of 'u' and 'v'
985    noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth);
986    // Compute the noise as a linear interpolation of 'a' and 'b'
987    noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth);
988
989    SkString noiseFuncName;
990    if (pne.stitchTiles()) {
991        fragBuilder->emitFunction(kHalf_GrSLType,
992                                  "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitchArgs),
993                                  gPerlinNoiseStitchArgs, noiseCode.c_str(), &noiseFuncName);
994    } else {
995        fragBuilder->emitFunction(kHalf_GrSLType,
996                                  "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs),
997                                  gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncName);
998    }
999
1000    // There are rounding errors if the floor operation is not performed here
1001    fragBuilder->codeAppendf("\n\t\thalf2 %s = floor(%s.xy) * %s;",
1002                             noiseVec, vCoords.c_str(), baseFrequencyUni);
1003
1004    // Clear the color accumulator
1005    fragBuilder->codeAppendf("\n\t\t%s = half4(0.0);", args.fOutputColor);
1006
1007    if (pne.stitchTiles()) {
1008        // Set up TurbulenceInitial stitch values.
1009        fragBuilder->codeAppendf("\n\t\thalf2 %s = %s;", stitchData, stitchDataUni);
1010    }
1011
1012    fragBuilder->codeAppendf("\n\t\thalf %s = 1.0;", ratio);
1013
1014    // Loop over all octaves
1015    fragBuilder->codeAppendf("for (int octave = 0; octave < %d; ++octave) {", pne.numOctaves());
1016
1017    fragBuilder->codeAppendf("\n\t\t\t%s += ", args.fOutputColor);
1018    if (pne.type() != SkPerlinNoiseShaderImpl::kFractalNoise_Type) {
1019        fragBuilder->codeAppend("abs(");
1020    }
1021    if (pne.stitchTiles()) {
1022        fragBuilder->codeAppendf(
1023            "half4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s),"
1024                 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))",
1025            noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData,
1026            noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData,
1027            noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData,
1028            noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData);
1029    } else {
1030        fragBuilder->codeAppendf(
1031            "half4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s),"
1032                 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))",
1033            noiseFuncName.c_str(), chanCoordR, noiseVec,
1034            noiseFuncName.c_str(), chanCoordG, noiseVec,
1035            noiseFuncName.c_str(), chanCoordB, noiseVec,
1036            noiseFuncName.c_str(), chanCoordA, noiseVec);
1037    }
1038    if (pne.type() != SkPerlinNoiseShaderImpl::kFractalNoise_Type) {
1039        fragBuilder->codeAppendf(")"); // end of "abs("
1040    }
1041    fragBuilder->codeAppendf(" * %s;", ratio);
1042
1043    fragBuilder->codeAppendf("\n\t\t\t%s *= half2(2.0);", noiseVec);
1044    fragBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio);
1045
1046    if (pne.stitchTiles()) {
1047        fragBuilder->codeAppendf("\n\t\t\t%s *= half2(2.0);", stitchData);
1048    }
1049    fragBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves
1050
1051    if (pne.type() == SkPerlinNoiseShaderImpl::kFractalNoise_Type) {
1052        // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
1053        // by fractalNoise and (turbulenceFunctionResult) by turbulence.
1054        fragBuilder->codeAppendf("\n\t\t%s = %s * half4(0.5) + half4(0.5);",
1055                               args.fOutputColor,args.fOutputColor);
1056    }
1057
1058    // Clamp values
1059    fragBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColor, args.fOutputColor);
1060
1061    // Pre-multiply the result
1062    fragBuilder->codeAppendf("\n\t\t%s = half4(%s.rgb * %s.aaa, %s.a);\n",
1063                             args.fOutputColor, args.fOutputColor,
1064                             args.fOutputColor, args.fOutputColor);
1065}
1066
1067void GrGLPerlinNoise::GenKey(const GrProcessor& processor, const GrShaderCaps&,
1068                             GrProcessorKeyBuilder* b) {
1069    const GrPerlinNoise2Effect& turbulence = processor.cast<GrPerlinNoise2Effect>();
1070
1071    uint32_t key = turbulence.numOctaves();
1072
1073    key = key << 3; // Make room for next 3 bits
1074
1075    switch (turbulence.type()) {
1076        case SkPerlinNoiseShaderImpl::kFractalNoise_Type:
1077            key |= 0x1;
1078            break;
1079        case SkPerlinNoiseShaderImpl::kTurbulence_Type:
1080            key |= 0x2;
1081            break;
1082        default:
1083            // leave key at 0
1084            break;
1085    }
1086
1087    if (turbulence.stitchTiles()) {
1088        key |= 0x4; // Flip the 3rd bit if tile stitching is on
1089    }
1090
1091    b->add32(key);
1092}
1093
1094void GrGLPerlinNoise::onSetData(const GrGLSLProgramDataManager& pdman,
1095                                const GrFragmentProcessor& processor) {
1096    INHERITED::onSetData(pdman, processor);
1097
1098    const GrPerlinNoise2Effect& turbulence = processor.cast<GrPerlinNoise2Effect>();
1099
1100    const SkVector& baseFrequency = turbulence.baseFrequency();
1101    pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY);
1102
1103    if (turbulence.stitchTiles()) {
1104        const SkPerlinNoiseShaderImpl::StitchData& stitchData = turbulence.stitchData();
1105        pdman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth),
1106                                   SkIntToScalar(stitchData.fHeight));
1107    }
1108}
1109
1110/////////////////////////////////////////////////////////////////////
1111
1112class GrGLImprovedPerlinNoise : public GrGLSLFragmentProcessor {
1113public:
1114    void emitCode(EmitArgs&) override;
1115
1116    static inline void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*);
1117
1118protected:
1119    void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override;
1120
1121private:
1122    GrGLSLProgramDataManager::UniformHandle fZUni;
1123    GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni;
1124
1125    typedef GrGLSLFragmentProcessor INHERITED;
1126};
1127
1128/////////////////////////////////////////////////////////////////////
1129
1130class GrImprovedPerlinNoiseEffect : public GrFragmentProcessor {
1131public:
1132    static std::unique_ptr<GrFragmentProcessor> Make(
1133            int octaves, SkScalar z,
1134            std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData,
1135            sk_sp<GrTextureProxy> permutationsProxy, sk_sp<GrTextureProxy> gradientProxy,
1136            const SkMatrix& matrix) {
1137        return std::unique_ptr<GrFragmentProcessor>(new GrImprovedPerlinNoiseEffect(
1138                octaves, z, std::move(paintingData), std::move(permutationsProxy),
1139                std::move(gradientProxy), matrix));
1140    }
1141
1142    const char* name() const override { return "ImprovedPerlinNoise"; }
1143
1144    std::unique_ptr<GrFragmentProcessor> clone() const override {
1145        return std::unique_ptr<GrFragmentProcessor>(new GrImprovedPerlinNoiseEffect(*this));
1146    }
1147
1148    const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency; }
1149    SkScalar z() const { return fZ; }
1150    int octaves() const { return fOctaves; }
1151    const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); }
1152
1153private:
1154    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
1155        return new GrGLImprovedPerlinNoise;
1156    }
1157
1158    void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
1159        GrGLImprovedPerlinNoise::GenKey(*this, caps, b);
1160    }
1161
1162    bool onIsEqual(const GrFragmentProcessor& sBase) const override {
1163        const GrImprovedPerlinNoiseEffect& s = sBase.cast<GrImprovedPerlinNoiseEffect>();
1164        return fZ == fZ &&
1165               fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency;
1166    }
1167
1168    GrImprovedPerlinNoiseEffect(int octaves, SkScalar z,
1169                                std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData,
1170                                sk_sp<GrTextureProxy> permutationsProxy,
1171                                sk_sp<GrTextureProxy> gradientProxy,
1172                                const SkMatrix& matrix)
1173            : INHERITED(kGrImprovedPerlinNoiseEffect_ClassID, kNone_OptimizationFlags)
1174            , fOctaves(octaves)
1175            , fZ(z)
1176            , fPermutationsSampler(std::move(permutationsProxy))
1177            , fGradientSampler(std::move(gradientProxy))
1178            , fPaintingData(std::move(paintingData)) {
1179        this->addTextureSampler(&fPermutationsSampler);
1180        this->addTextureSampler(&fGradientSampler);
1181        fCoordTransform.reset(matrix);
1182        this->addCoordTransform(&fCoordTransform);
1183    }
1184
1185    GrImprovedPerlinNoiseEffect(const GrImprovedPerlinNoiseEffect& that)
1186            : INHERITED(kGrImprovedPerlinNoiseEffect_ClassID, kNone_OptimizationFlags)
1187            , fCoordTransform(that.fCoordTransform)
1188            , fOctaves(that.fOctaves)
1189            , fZ(that.fZ)
1190            , fPermutationsSampler(that.fPermutationsSampler)
1191            , fGradientSampler(that.fGradientSampler)
1192            , fPaintingData(new SkPerlinNoiseShaderImpl::PaintingData(*that.fPaintingData)) {
1193        this->addTextureSampler(&fPermutationsSampler);
1194        this->addTextureSampler(&fGradientSampler);
1195        this->addCoordTransform(&fCoordTransform);
1196    }
1197
1198    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
1199
1200    GrCoordTransform                    fCoordTransform;
1201    int                                 fOctaves;
1202    SkScalar                            fZ;
1203    TextureSampler                      fPermutationsSampler;
1204    TextureSampler                      fGradientSampler;
1205    std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> fPaintingData;
1206
1207    typedef GrFragmentProcessor INHERITED;
1208};
1209
1210/////////////////////////////////////////////////////////////////////
1211GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrImprovedPerlinNoiseEffect);
1212
1213#if GR_TEST_UTILS
1214std::unique_ptr<GrFragmentProcessor> GrImprovedPerlinNoiseEffect::TestCreate(
1215        GrProcessorTestData* d) {
1216    SkScalar baseFrequencyX = d->fRandom->nextRangeScalar(0.01f,
1217                                                          0.99f);
1218    SkScalar baseFrequencyY = d->fRandom->nextRangeScalar(0.01f,
1219                                                          0.99f);
1220    int numOctaves = d->fRandom->nextRangeU(2, 10);
1221    SkScalar z = SkIntToScalar(d->fRandom->nextU());
1222
1223    sk_sp<SkShader> shader(SkPerlinNoiseShader::MakeImprovedNoise(baseFrequencyX,
1224                                                                   baseFrequencyY,
1225                                                                   numOctaves,
1226                                                                   z));
1227
1228    GrTest::TestAsFPArgs asFPArgs(d);
1229    return as_SB(shader)->asFragmentProcessor(asFPArgs.args());
1230}
1231#endif
1232
1233void GrGLImprovedPerlinNoise::emitCode(EmitArgs& args) {
1234    const GrImprovedPerlinNoiseEffect& pne = args.fFp.cast<GrImprovedPerlinNoiseEffect>();
1235    GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
1236    GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
1237    SkString vCoords = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
1238
1239    fBaseFrequencyUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType,
1240                                                   "baseFrequency");
1241    const char* baseFrequencyUni = uniformHandler->getUniformCStr(fBaseFrequencyUni);
1242
1243    fZUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "z");
1244    const char* zUni = uniformHandler->getUniformCStr(fZUni);
1245
1246    // fade function
1247    static const GrShaderVar fadeArgs[] =  {
1248        GrShaderVar("t", kHalf3_GrSLType)
1249    };
1250    SkString fadeFuncName;
1251    fragBuilder->emitFunction(kHalf3_GrSLType, "fade", SK_ARRAY_COUNT(fadeArgs),
1252                              fadeArgs,
1253                              "return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);",
1254                              &fadeFuncName);
1255
1256    // perm function
1257    static const GrShaderVar permArgs[] =  {
1258        GrShaderVar("x", kHalf_GrSLType)
1259    };
1260    SkString permFuncName;
1261    SkString permCode("return ");
1262    // FIXME even though I'm creating these textures with kRepeat_TileMode, they're clamped. Not
1263    // sure why. Using fract() (here and the next texture lookup) as a workaround.
1264    fragBuilder->appendTextureLookup(&permCode, args.fTexSamplers[0], "float2(fract(x / 256.0), 0.0)",
1265                                     kHalf2_GrSLType);
1266    permCode.append(".r * 255.0;");
1267    fragBuilder->emitFunction(kHalf_GrSLType, "perm", SK_ARRAY_COUNT(permArgs), permArgs,
1268                              permCode.c_str(), &permFuncName);
1269
1270    // grad function
1271    static const GrShaderVar gradArgs[] =  {
1272        GrShaderVar("x", kHalf_GrSLType),
1273        GrShaderVar("p", kHalf3_GrSLType)
1274    };
1275    SkString gradFuncName;
1276    SkString gradCode("return dot(");
1277    fragBuilder->appendTextureLookup(&gradCode, args.fTexSamplers[1], "float2(fract(x / 16.0), 0.0)",
1278                                     kHalf2_GrSLType);
1279    gradCode.append(".rgb * 255.0 - float3(1.0), p);");
1280    fragBuilder->emitFunction(kHalf_GrSLType, "grad", SK_ARRAY_COUNT(gradArgs), gradArgs,
1281                              gradCode.c_str(), &gradFuncName);
1282
1283    // lerp function
1284    static const GrShaderVar lerpArgs[] =  {
1285        GrShaderVar("a", kHalf_GrSLType),
1286        GrShaderVar("b", kHalf_GrSLType),
1287        GrShaderVar("w", kHalf_GrSLType)
1288    };
1289    SkString lerpFuncName;
1290    fragBuilder->emitFunction(kHalf_GrSLType, "lerp", SK_ARRAY_COUNT(lerpArgs), lerpArgs,
1291                              "return a + w * (b - a);", &lerpFuncName);
1292
1293    // noise function
1294    static const GrShaderVar noiseArgs[] =  {
1295        GrShaderVar("p", kHalf3_GrSLType),
1296    };
1297    SkString noiseFuncName;
1298    SkString noiseCode;
1299    noiseCode.append("half3 P = mod(floor(p), 256.0);");
1300    noiseCode.append("p -= floor(p);");
1301    noiseCode.appendf("half3 f = %s(p);", fadeFuncName.c_str());
1302    noiseCode.appendf("half A = %s(P.x) + P.y;", permFuncName.c_str());
1303    noiseCode.appendf("half AA = %s(A) + P.z;", permFuncName.c_str());
1304    noiseCode.appendf("half AB = %s(A + 1.0) + P.z;", permFuncName.c_str());
1305    noiseCode.appendf("half B =  %s(P.x + 1.0) + P.y;", permFuncName.c_str());
1306    noiseCode.appendf("half BA = %s(B) + P.z;", permFuncName.c_str());
1307    noiseCode.appendf("half BB = %s(B + 1.0) + P.z;", permFuncName.c_str());
1308    noiseCode.appendf("half result = %s(", lerpFuncName.c_str());
1309    noiseCode.appendf("%s(%s(%s(%s(AA), p),", lerpFuncName.c_str(), lerpFuncName.c_str(),
1310                      gradFuncName.c_str(), permFuncName.c_str());
1311    noiseCode.appendf("%s(%s(BA), p + half3(-1.0, 0.0, 0.0)), f.x),", gradFuncName.c_str(),
1312                      permFuncName.c_str());
1313    noiseCode.appendf("%s(%s(%s(AB), p + half3(0.0, -1.0, 0.0)),", lerpFuncName.c_str(),
1314                      gradFuncName.c_str(), permFuncName.c_str());
1315    noiseCode.appendf("%s(%s(BB), p + half3(-1.0, -1.0, 0.0)), f.x), f.y),",
1316                      gradFuncName.c_str(), permFuncName.c_str());
1317    noiseCode.appendf("%s(%s(%s(%s(AA + 1.0), p + half3(0.0, 0.0, -1.0)),",
1318                      lerpFuncName.c_str(), lerpFuncName.c_str(), gradFuncName.c_str(),
1319                      permFuncName.c_str());
1320    noiseCode.appendf("%s(%s(BA + 1.0), p + half3(-1.0, 0.0, -1.0)), f.x),",
1321                      gradFuncName.c_str(), permFuncName.c_str());
1322    noiseCode.appendf("%s(%s(%s(AB + 1.0), p + half3(0.0, -1.0, -1.0)),",
1323                      lerpFuncName.c_str(), gradFuncName.c_str(), permFuncName.c_str());
1324    noiseCode.appendf("%s(%s(BB + 1.0), p + half3(-1.0, -1.0, -1.0)), f.x), f.y), f.z);",
1325                      gradFuncName.c_str(), permFuncName.c_str());
1326    noiseCode.append("return result;");
1327    fragBuilder->emitFunction(kHalf_GrSLType, "noise", SK_ARRAY_COUNT(noiseArgs), noiseArgs,
1328                              noiseCode.c_str(), &noiseFuncName);
1329
1330    // noiseOctaves function
1331    static const GrShaderVar noiseOctavesArgs[] =  {
1332        GrShaderVar("p", kHalf3_GrSLType)
1333    };
1334    SkString noiseOctavesFuncName;
1335    SkString noiseOctavesCode;
1336    noiseOctavesCode.append("half result = 0.0;");
1337    noiseOctavesCode.append("half ratio = 1.0;");
1338    noiseOctavesCode.appendf("for (half i = 0.0; i < %d; i++) {", pne.octaves());
1339    noiseOctavesCode.appendf("result += %s(p) / ratio;", noiseFuncName.c_str());
1340    noiseOctavesCode.append("p *= 2.0;");
1341    noiseOctavesCode.append("ratio *= 2.0;");
1342    noiseOctavesCode.append("}");
1343    noiseOctavesCode.append("return (result + 1.0) / 2.0;");
1344    fragBuilder->emitFunction(kHalf_GrSLType, "noiseOctaves", SK_ARRAY_COUNT(noiseOctavesArgs),
1345                              noiseOctavesArgs, noiseOctavesCode.c_str(), &noiseOctavesFuncName);
1346
1347    fragBuilder->codeAppendf("half2 coords = %s * %s;", vCoords.c_str(), baseFrequencyUni);
1348    fragBuilder->codeAppendf("half r = %s(half3(coords, %s));", noiseOctavesFuncName.c_str(),
1349                             zUni);
1350    fragBuilder->codeAppendf("half g = %s(half3(coords, %s + 0000.0));",
1351                             noiseOctavesFuncName.c_str(), zUni);
1352    fragBuilder->codeAppendf("half b = %s(half3(coords, %s + 0000.0));",
1353                             noiseOctavesFuncName.c_str(), zUni);
1354    fragBuilder->codeAppendf("half a = %s(half3(coords, %s + 0000.0));",
1355                             noiseOctavesFuncName.c_str(), zUni);
1356    fragBuilder->codeAppendf("%s = half4(r, g, b, a);", args.fOutputColor);
1357
1358    // Clamp values
1359    fragBuilder->codeAppendf("%s = clamp(%s, 0.0, 1.0);", args.fOutputColor, args.fOutputColor);
1360
1361    // Pre-multiply the result
1362    fragBuilder->codeAppendf("\n\t\t%s = half4(%s.rgb * %s.aaa, %s.a);\n",
1363                             args.fOutputColor, args.fOutputColor,
1364                             args.fOutputColor, args.fOutputColor);
1365}
1366
1367void GrGLImprovedPerlinNoise::GenKey(const GrProcessor& processor, const GrShaderCaps&,
1368                                     GrProcessorKeyBuilder* b) {
1369    const GrImprovedPerlinNoiseEffect& pne = processor.cast<GrImprovedPerlinNoiseEffect>();
1370    b->add32(pne.octaves());
1371}
1372
1373void GrGLImprovedPerlinNoise::onSetData(const GrGLSLProgramDataManager& pdman,
1374                                        const GrFragmentProcessor& processor) {
1375    INHERITED::onSetData(pdman, processor);
1376
1377    const GrImprovedPerlinNoiseEffect& noise = processor.cast<GrImprovedPerlinNoiseEffect>();
1378
1379    const SkVector& baseFrequency = noise.baseFrequency();
1380    pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY);
1381
1382    pdman.set1f(fZUni, noise.z());
1383}
1384
1385/////////////////////////////////////////////////////////////////////
1386std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcessor(
1387        const GrFPArgs& args) const {
1388    SkASSERT(args.fContext);
1389
1390    SkMatrix localMatrix = this->getLocalMatrix();
1391    if (args.fLocalMatrix) {
1392        localMatrix.preConcat(*args.fLocalMatrix);
1393    }
1394
1395    SkMatrix matrix = *args.fViewMatrix;
1396    matrix.preConcat(localMatrix);
1397
1398    // Either we don't stitch tiles, either we have a valid tile size
1399    SkASSERT(!fStitchTiles || !fTileSize.isEmpty());
1400
1401    std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData =
1402        skstd::make_unique<SkPerlinNoiseShaderImpl::PaintingData>(fTileSize,
1403                                                                  fSeed,
1404                                                                  fBaseFrequencyX,
1405                                                                  fBaseFrequencyY,
1406                                                                  matrix);
1407
1408    SkMatrix m = *args.fViewMatrix;
1409    m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1);
1410    m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1);
1411
1412    if (fType == kImprovedNoise_Type) {
1413        GrSamplerState textureParams(GrSamplerState::WrapMode::kRepeat,
1414                                     GrSamplerState::Filter::kNearest);
1415        sk_sp<GrTextureProxy> permutationsTexture(
1416            GrRefCachedBitmapTextureProxy(args.fContext,
1417                                          paintingData->getImprovedPermutationsBitmap(),
1418                                          textureParams, nullptr));
1419        sk_sp<GrTextureProxy> gradientTexture(
1420            GrRefCachedBitmapTextureProxy(args.fContext,
1421                                          paintingData->getGradientBitmap(),
1422                                          textureParams, nullptr));
1423        return GrImprovedPerlinNoiseEffect::Make(fNumOctaves, fSeed, std::move(paintingData),
1424                                                 std::move(permutationsTexture),
1425                                                 std::move(gradientTexture), m);
1426    }
1427
1428    if (0 == fNumOctaves) {
1429        if (kFractalNoise_Type == fType) {
1430            // Extract the incoming alpha and emit rgba = (a/4, a/4, a/4, a/2)
1431            // TODO: Either treat the output of this shader as sRGB or allow client to specify a
1432            // color space of the noise. Either way, this case (and the GLSL) need to convert to
1433            // the destination.
1434            auto inner =
1435                    GrConstColorProcessor::Make(GrColor4f::FromGrColor(0x80404040),
1436                                                GrConstColorProcessor::InputMode::kModulateRGBA);
1437            return GrFragmentProcessor::MulChildByInputAlpha(std::move(inner));
1438        }
1439        // Emit zero.
1440        return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(),
1441                                           GrConstColorProcessor::InputMode::kIgnore);
1442    }
1443
1444    sk_sp<GrTextureProxy> permutationsProxy = GrMakeCachedBitmapProxy(
1445                                                    args.fContext->contextPriv().proxyProvider(),
1446                                                    paintingData->getPermutationsBitmap());
1447    sk_sp<GrTextureProxy> noiseProxy = GrMakeCachedBitmapProxy(
1448                                                    args.fContext->contextPriv().proxyProvider(),
1449                                                    paintingData->getNoiseBitmap());
1450
1451    if (permutationsProxy && noiseProxy) {
1452        auto inner = GrPerlinNoise2Effect::Make(fType,
1453                                                fNumOctaves,
1454                                                fStitchTiles,
1455                                                std::move(paintingData),
1456                                                std::move(permutationsProxy),
1457                                                std::move(noiseProxy),
1458                                                m);
1459        return GrFragmentProcessor::MulChildByInputAlpha(std::move(inner));
1460    }
1461    return nullptr;
1462}
1463
1464#endif
1465
1466#ifndef SK_IGNORE_TO_STRING
1467void SkPerlinNoiseShaderImpl::toString(SkString* str) const {
1468    str->append("SkPerlinNoiseShaderImpl: (");
1469
1470    str->append("type: ");
1471    switch (fType) {
1472        case kFractalNoise_Type:
1473            str->append("\"fractal noise\"");
1474            break;
1475        case kTurbulence_Type:
1476            str->append("\"turbulence\"");
1477            break;
1478        default:
1479            str->append("\"unknown\"");
1480            break;
1481    }
1482    str->append(" base frequency: (");
1483    str->appendScalar(fBaseFrequencyX);
1484    str->append(", ");
1485    str->appendScalar(fBaseFrequencyY);
1486    str->append(") number of octaves: ");
1487    str->appendS32(fNumOctaves);
1488    str->append(" seed: ");
1489    str->appendScalar(fSeed);
1490    str->append(" stitch tiles: ");
1491    str->append(fStitchTiles ? "true " : "false ");
1492
1493    this->INHERITED::toString(str);
1494
1495    str->append(")");
1496}
1497#endif
1498
1499///////////////////////////////////////////////////////////////////////////////////////////////////
1500
1501sk_sp<SkShader> SkPerlinNoiseShader::MakeFractalNoise(SkScalar baseFrequencyX,
1502                                                      SkScalar baseFrequencyY,
1503                                                      int numOctaves, SkScalar seed,
1504                                                      const SkISize* tileSize) {
1505    return sk_sp<SkShader>(new SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::kFractalNoise_Type,
1506                                                 baseFrequencyX, baseFrequencyY, numOctaves, seed,
1507                                                 tileSize));
1508}
1509
1510sk_sp<SkShader> SkPerlinNoiseShader::MakeTurbulence(SkScalar baseFrequencyX,
1511                                                    SkScalar baseFrequencyY,
1512                                                    int numOctaves, SkScalar seed,
1513                                                    const SkISize* tileSize) {
1514    return sk_sp<SkShader>(new SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::kTurbulence_Type,
1515                                                 baseFrequencyX, baseFrequencyY, numOctaves, seed,
1516                                                 tileSize));
1517}
1518
1519sk_sp<SkShader> SkPerlinNoiseShader::MakeImprovedNoise(SkScalar baseFrequencyX,
1520                                                       SkScalar baseFrequencyY,
1521                                                       int numOctaves, SkScalar z) {
1522    return sk_sp<SkShader>(new SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::kImprovedNoise_Type,
1523                                                 baseFrequencyX, baseFrequencyY, numOctaves, z,
1524                                                 nullptr));
1525}
1526
1527SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkPerlinNoiseShader)
1528    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShaderImpl)
1529SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
1530