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