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