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