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