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