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