blob: a7750a8d856020158c351458c37072cb26eda3fc [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
606void SkPerlinNoiseShader2::PerlinNoiseShaderContext::shadeSpan16(
607 int x, int y, uint16_t result[], int count) {
608 SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
609 StitchData stitchData;
610 DITHER_565_SCAN(y);
611 for (int i = 0; i < count; ++i) {
612 unsigned dither = DITHER_VALUE(x);
613 result[i] = SkDitherRGB32To565(shade(point, stitchData), dither);
614 DITHER_INC_X(x);
615 point.fX += SK_Scalar1;
616 }
617}
618
619/////////////////////////////////////////////////////////////////////
620
621#if SK_SUPPORT_GPU
622
egdaniel64c47282015-11-13 06:54:19 -0800623class GrGLPerlinNoise2 : public GrGLSLFragmentProcessor {
ethannicholas417011c2015-11-09 06:35:12 -0800624public:
625 GrGLPerlinNoise2(const GrProcessor&);
626 virtual ~GrGLPerlinNoise2() {}
627
628 virtual void emitCode(EmitArgs&) override;
629
630 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder* b);
631
632protected:
633 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
634
635private:
636
637 GrGLSLProgramDataManager::UniformHandle fStitchDataUni;
638 SkPerlinNoiseShader2::Type fType;
639 bool fStitchTiles;
640 int fNumOctaves;
641 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni;
642
643private:
egdaniel64c47282015-11-13 06:54:19 -0800644 typedef GrGLSLFragmentProcessor INHERITED;
ethannicholas417011c2015-11-09 06:35:12 -0800645};
646
647/////////////////////////////////////////////////////////////////////
648
649class GrPerlinNoise2Effect : public GrFragmentProcessor {
650public:
651 static GrFragmentProcessor* Create(SkPerlinNoiseShader2::Type type,
652 int numOctaves, bool stitchTiles,
653 SkPerlinNoiseShader2::PaintingData* paintingData,
654 GrTexture* permutationsTexture, GrTexture* noiseTexture,
655 const SkMatrix& matrix) {
656 return new GrPerlinNoise2Effect(type, numOctaves, stitchTiles, paintingData,
657 permutationsTexture, noiseTexture, matrix);
658 }
659
660 virtual ~GrPerlinNoise2Effect() { delete fPaintingData; }
661
662 const char* name() const override { return "PerlinNoise"; }
663
664 const SkPerlinNoiseShader2::StitchData& stitchData() const { return fPaintingData->fStitchDataInit; }
665
666 SkPerlinNoiseShader2::Type type() const { return fType; }
667 bool stitchTiles() const { return fStitchTiles; }
668 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency; }
669 int numOctaves() const { return fNumOctaves; }
670 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); }
671
672private:
egdaniel57d3b032015-11-13 11:57:27 -0800673 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
ethannicholas417011c2015-11-09 06:35:12 -0800674 return new GrGLPerlinNoise2(*this);
675 }
676
egdaniel57d3b032015-11-13 11:57:27 -0800677 virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps,
678 GrProcessorKeyBuilder* b) const override {
ethannicholas417011c2015-11-09 06:35:12 -0800679 GrGLPerlinNoise2::GenKey(*this, caps, b);
680 }
681
682 bool onIsEqual(const GrFragmentProcessor& sBase) const override {
683 const GrPerlinNoise2Effect& s = sBase.cast<GrPerlinNoise2Effect>();
684 return fType == s.fType &&
685 fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency &&
686 fNumOctaves == s.fNumOctaves &&
687 fStitchTiles == s.fStitchTiles &&
688 fPaintingData->fStitchDataInit == s.fPaintingData->fStitchDataInit;
689 }
690
691 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
692 inout->setToUnknown(GrInvariantOutput::kWillNot_ReadInput);
693 }
694
695 GrPerlinNoise2Effect(SkPerlinNoiseShader2::Type type,
696 int numOctaves, bool stitchTiles,
697 SkPerlinNoiseShader2::PaintingData* paintingData,
698 GrTexture* permutationsTexture, GrTexture* noiseTexture,
699 const SkMatrix& matrix)
700 : fType(type)
701 , fNumOctaves(numOctaves)
702 , fStitchTiles(stitchTiles)
703 , fPermutationsAccess(permutationsTexture)
704 , fNoiseAccess(noiseTexture)
705 , fPaintingData(paintingData) {
706 this->initClassID<GrPerlinNoise2Effect>();
707 this->addTextureAccess(&fPermutationsAccess);
708 this->addTextureAccess(&fNoiseAccess);
709 fCoordTransform.reset(kLocal_GrCoordSet, matrix);
710 this->addCoordTransform(&fCoordTransform);
711 }
712
713 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
714
715 SkPerlinNoiseShader2::Type fType;
716 GrCoordTransform fCoordTransform;
717 int fNumOctaves;
718 bool fStitchTiles;
719 GrTextureAccess fPermutationsAccess;
720 GrTextureAccess fNoiseAccess;
721 SkPerlinNoiseShader2::PaintingData *fPaintingData;
722
723private:
724 typedef GrFragmentProcessor INHERITED;
725};
726
727/////////////////////////////////////////////////////////////////////
728GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrPerlinNoise2Effect);
729
730const GrFragmentProcessor* GrPerlinNoise2Effect::TestCreate(GrProcessorTestData* d) {
731 int numOctaves = d->fRandom->nextRangeU(2, 10);
732 bool stitchTiles = d->fRandom->nextBool();
733 SkScalar seed = SkIntToScalar(d->fRandom->nextU());
734 SkISize tileSize = SkISize::Make(d->fRandom->nextRangeU(4, 4096),
735 d->fRandom->nextRangeU(4, 4096));
736 SkScalar baseFrequencyX = d->fRandom->nextRangeScalar(0.01f,
737 0.99f);
738 SkScalar baseFrequencyY = d->fRandom->nextRangeScalar(0.01f,
739 0.99f);
740
741 SkAutoTUnref<SkShader> shader(d->fRandom->nextBool() ?
742 SkPerlinNoiseShader2::CreateFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves, seed,
743 stitchTiles ? &tileSize : nullptr) :
744 SkPerlinNoiseShader2::CreateTurbulence(baseFrequencyX, baseFrequencyY, numOctaves, seed,
745 stitchTiles ? &tileSize : nullptr));
746
747 GrPaint grPaint;
748 return shader->asFragmentProcessor(d->fContext,
749 GrTest::TestMatrix(d->fRandom), nullptr,
750 kNone_SkFilterQuality);
751}
752
753GrGLPerlinNoise2::GrGLPerlinNoise2(const GrProcessor& processor)
754 : fType(processor.cast<GrPerlinNoise2Effect>().type())
755 , fStitchTiles(processor.cast<GrPerlinNoise2Effect>().stitchTiles())
756 , fNumOctaves(processor.cast<GrPerlinNoise2Effect>().numOctaves()) {
757}
758
759void GrGLPerlinNoise2::emitCode(EmitArgs& args) {
egdaniel4ca2e602015-11-18 08:01:26 -0800760 GrGLSLFragmentBuilder* fsBuilder = args.fFragBuilder;
egdaniel7ea439b2015-12-03 09:20:44 -0800761 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
ethannicholas417011c2015-11-09 06:35:12 -0800762 SkString vCoords = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
763
egdaniel7ea439b2015-12-03 09:20:44 -0800764 fBaseFrequencyUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
765 kVec2f_GrSLType, kDefault_GrSLPrecision,
766 "baseFrequency");
767 const char* baseFrequencyUni = uniformHandler->getUniformCStr(fBaseFrequencyUni);
ethannicholas417011c2015-11-09 06:35:12 -0800768
769 const char* stitchDataUni = nullptr;
770 if (fStitchTiles) {
egdaniel7ea439b2015-12-03 09:20:44 -0800771 fStitchDataUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
772 kVec2f_GrSLType, kDefault_GrSLPrecision,
773 "stitchData");
774 stitchDataUni = uniformHandler->getUniformCStr(fStitchDataUni);
ethannicholas417011c2015-11-09 06:35:12 -0800775 }
776
777 // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8
778 const char* chanCoordR = "0.125";
779 const char* chanCoordG = "0.375";
780 const char* chanCoordB = "0.625";
781 const char* chanCoordA = "0.875";
782 const char* chanCoord = "chanCoord";
783 const char* stitchData = "stitchData";
784 const char* ratio = "ratio";
785 const char* noiseVec = "noiseVec";
786 const char* noiseSmooth = "noiseSmooth";
787 const char* floorVal = "floorVal";
788 const char* fractVal = "fractVal";
789 const char* uv = "uv";
790 const char* ab = "ab";
791 const char* latticeIdx = "latticeIdx";
792 const char* bcoords = "bcoords";
793 const char* lattice = "lattice";
794 const char* inc8bit = "0.00390625"; // 1.0 / 256.0
795 // This is the math to convert the two 16bit integer packed into rgba 8 bit input into a
796 // [-1,1] vector and perform a dot product between that vector and the provided vector.
797 const char* dotLattice = "dot(((%s.ga + %s.rb * vec2(%s)) * vec2(2.0) - vec2(1.0)), %s);";
798
799 // Add noise function
800 static const GrGLSLShaderVar gPerlinNoiseArgs[] = {
801 GrGLSLShaderVar(chanCoord, kFloat_GrSLType),
802 GrGLSLShaderVar(noiseVec, kVec2f_GrSLType)
803 };
804
805 static const GrGLSLShaderVar gPerlinNoiseStitchArgs[] = {
806 GrGLSLShaderVar(chanCoord, kFloat_GrSLType),
807 GrGLSLShaderVar(noiseVec, kVec2f_GrSLType),
808 GrGLSLShaderVar(stitchData, kVec2f_GrSLType)
809 };
810
811 SkString noiseCode;
812
813 noiseCode.appendf("\tvec4 %s;\n", floorVal);
814 noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec);
815 noiseCode.appendf("\t%s.zw = %s.xy + vec2(1.0);\n", floorVal, floorVal);
816 noiseCode.appendf("\tvec2 %s = fract(%s);\n", fractVal, noiseVec);
817
818 // smooth curve : t * t * (3 - 2 * t)
819 noiseCode.appendf("\n\tvec2 %s = %s * %s * (vec2(3.0) - vec2(2.0) * %s);",
820 noiseSmooth, fractVal, fractVal, fractVal);
821
822 // Adjust frequencies if we're stitching tiles
823 if (fStitchTiles) {
824 noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }",
825 floorVal, stitchData, floorVal, stitchData);
826 noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }",
827 floorVal, stitchData, floorVal, stitchData);
828 noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }",
829 floorVal, stitchData, floorVal, stitchData);
830 noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }",
831 floorVal, stitchData, floorVal, stitchData);
832 }
833
834 // Get texture coordinates and normalize
835 noiseCode.appendf("\n\t%s = fract(floor(mod(%s, 256.0)) / vec4(256.0));\n",
836 floorVal, floorVal);
837
838 // Get permutation for x
839 {
840 SkString xCoords("");
841 xCoords.appendf("vec2(%s.x, 0.5)", floorVal);
842
843 noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx);
844 fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[0], xCoords.c_str(),
845 kVec2f_GrSLType);
846 noiseCode.append(".r;");
847 }
848
849 // Get permutation for x + 1
850 {
851 SkString xCoords("");
852 xCoords.appendf("vec2(%s.z, 0.5)", floorVal);
853
854 noiseCode.appendf("\n\t%s.y = ", latticeIdx);
855 fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[0], xCoords.c_str(),
856 kVec2f_GrSLType);
857 noiseCode.append(".r;");
858 }
859
860#if defined(SK_BUILD_FOR_ANDROID)
861 // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Nexus 7 (Tegra 3).
862 // The issue is that colors aren't accurate enough on Tegra devices. For example, if an 8 bit
863 // value of 124 (or 0.486275 here) is entered, we can get a texture value of 123.513725
864 // (or 0.484368 here). The following rounding operation prevents these precision issues from
865 // affecting the result of the noise by making sure that we only have multiples of 1/255.
866 // (Note that 1/255 is about 0.003921569, which is the value used here).
867 noiseCode.appendf("\n\t%s = floor(%s * vec2(255.0) + vec2(0.5)) * vec2(0.003921569);",
868 latticeIdx, latticeIdx);
869#endif
870
871 // Get (x,y) coordinates with the permutated x
872 noiseCode.appendf("\n\tvec4 %s = fract(%s.xyxy + %s.yyww);", bcoords, latticeIdx, floorVal);
873
874 noiseCode.appendf("\n\n\tvec2 %s;", uv);
875 // Compute u, at offset (0,0)
876 {
877 SkString latticeCoords("");
878 latticeCoords.appendf("vec2(%s.x, %s)", bcoords, chanCoord);
879 noiseCode.appendf("\n\tvec4 %s = ", lattice);
880 fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
881 kVec2f_GrSLType);
882 noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
883 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
884 }
885
886 noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal);
887 // Compute v, at offset (-1,0)
888 {
889 SkString latticeCoords("");
890 latticeCoords.appendf("vec2(%s.y, %s)", bcoords, chanCoord);
891 noiseCode.append("\n\tlattice = ");
892 fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
893 kVec2f_GrSLType);
894 noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
895 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
896 }
897
898 // Compute 'a' as a linear interpolation of 'u' and 'v'
899 noiseCode.appendf("\n\tvec2 %s;", ab);
900 noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth);
901
902 noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal);
903 // Compute v, at offset (-1,-1)
904 {
905 SkString latticeCoords("");
906 latticeCoords.appendf("vec2(%s.w, %s)", bcoords, chanCoord);
907 noiseCode.append("\n\tlattice = ");
908 fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
909 kVec2f_GrSLType);
910 noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
911 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
912 }
913
914 noiseCode.appendf("\n\t%s.x += 1.0;", fractVal);
915 // Compute u, at offset (0,-1)
916 {
917 SkString latticeCoords("");
918 latticeCoords.appendf("vec2(%s.z, %s)", bcoords, chanCoord);
919 noiseCode.append("\n\tlattice = ");
920 fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
921 kVec2f_GrSLType);
922 noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
923 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
924 }
925
926 // Compute 'b' as a linear interpolation of 'u' and 'v'
927 noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth);
928 // Compute the noise as a linear interpolation of 'a' and 'b'
929 noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth);
930
931 SkString noiseFuncName;
932 if (fStitchTiles) {
933 fsBuilder->emitFunction(kFloat_GrSLType,
934 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitchArgs),
935 gPerlinNoiseStitchArgs, noiseCode.c_str(), &noiseFuncName);
936 } else {
937 fsBuilder->emitFunction(kFloat_GrSLType,
938 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs),
939 gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncName);
940 }
941
942 // There are rounding errors if the floor operation is not performed here
943 fsBuilder->codeAppendf("\n\t\tvec2 %s = floor(%s.xy) * %s;",
944 noiseVec, vCoords.c_str(), baseFrequencyUni);
945
946 // Clear the color accumulator
947 fsBuilder->codeAppendf("\n\t\t%s = vec4(0.0);", args.fOutputColor);
948
949 if (fStitchTiles) {
950 // Set up TurbulenceInitial stitch values.
951 fsBuilder->codeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni);
952 }
953
954 fsBuilder->codeAppendf("\n\t\tfloat %s = 1.0;", ratio);
955
956 // Loop over all octaves
957 fsBuilder->codeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {", fNumOctaves);
958
959 fsBuilder->codeAppendf("\n\t\t\t%s += ", args.fOutputColor);
960 if (fType != SkPerlinNoiseShader2::kFractalNoise_Type) {
961 fsBuilder->codeAppend("abs(");
962 }
963 if (fStitchTiles) {
964 fsBuilder->codeAppendf(
965 "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s),"
966 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))",
967 noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData,
968 noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData,
969 noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData,
970 noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData);
971 } else {
972 fsBuilder->codeAppendf(
973 "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s),"
974 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))",
975 noiseFuncName.c_str(), chanCoordR, noiseVec,
976 noiseFuncName.c_str(), chanCoordG, noiseVec,
977 noiseFuncName.c_str(), chanCoordB, noiseVec,
978 noiseFuncName.c_str(), chanCoordA, noiseVec);
979 }
980 if (fType != SkPerlinNoiseShader2::kFractalNoise_Type) {
981 fsBuilder->codeAppendf(")"); // end of "abs("
982 }
983 fsBuilder->codeAppendf(" * %s;", ratio);
984
985 fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec);
986 fsBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio);
987
988 if (fStitchTiles) {
989 fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData);
990 }
991 fsBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves
992
993 if (fType == SkPerlinNoiseShader2::kFractalNoise_Type) {
994 // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
995 // by fractalNoise and (turbulenceFunctionResult) by turbulence.
996 fsBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);",
997 args.fOutputColor,args.fOutputColor);
998 }
999
1000 // Clamp values
1001 fsBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColor, args.fOutputColor);
1002
1003 // Pre-multiply the result
1004 fsBuilder->codeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
1005 args.fOutputColor, args.fOutputColor,
1006 args.fOutputColor, args.fOutputColor);
1007}
1008
1009void GrGLPerlinNoise2::GenKey(const GrProcessor& processor, const GrGLSLCaps&,
egdaniel2d721d32015-11-11 13:06:05 -08001010 GrProcessorKeyBuilder* b) {
ethannicholas417011c2015-11-09 06:35:12 -08001011 const GrPerlinNoise2Effect& turbulence = processor.cast<GrPerlinNoise2Effect>();
1012
1013 uint32_t key = turbulence.numOctaves();
1014
1015 key = key << 3; // Make room for next 3 bits
1016
1017 switch (turbulence.type()) {
1018 case SkPerlinNoiseShader2::kFractalNoise_Type:
1019 key |= 0x1;
1020 break;
1021 case SkPerlinNoiseShader2::kTurbulence_Type:
1022 key |= 0x2;
1023 break;
1024 default:
1025 // leave key at 0
1026 break;
1027 }
1028
1029 if (turbulence.stitchTiles()) {
1030 key |= 0x4; // Flip the 3rd bit if tile stitching is on
1031 }
1032
1033 b->add32(key);
1034}
1035
1036void GrGLPerlinNoise2::onSetData(const GrGLSLProgramDataManager& pdman,
1037 const GrProcessor& processor) {
1038 INHERITED::onSetData(pdman, processor);
1039
1040 const GrPerlinNoise2Effect& turbulence = processor.cast<GrPerlinNoise2Effect>();
1041
1042 const SkVector& baseFrequency = turbulence.baseFrequency();
1043 pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY);
1044
1045 if (turbulence.stitchTiles()) {
1046 const SkPerlinNoiseShader2::StitchData& stitchData = turbulence.stitchData();
1047 pdman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth),
1048 SkIntToScalar(stitchData.fHeight));
1049 }
1050}
1051
1052/////////////////////////////////////////////////////////////////////
1053
egdaniel64c47282015-11-13 06:54:19 -08001054class GrGLImprovedPerlinNoise : public GrGLSLFragmentProcessor {
ethannicholas417011c2015-11-09 06:35:12 -08001055public:
1056 GrGLImprovedPerlinNoise(const GrProcessor&);
1057 virtual ~GrGLImprovedPerlinNoise() {}
1058
1059 virtual void emitCode(EmitArgs&) override;
1060
1061 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder* b);
1062
1063protected:
1064 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
1065
1066private:
1067
1068 SkScalar fZ;
1069 GrGLSLProgramDataManager::UniformHandle fZUni;
1070 GrGLSLProgramDataManager::UniformHandle fOctavesUni;
1071 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni;
1072
1073private:
egdaniel64c47282015-11-13 06:54:19 -08001074 typedef GrGLSLFragmentProcessor INHERITED;
ethannicholas417011c2015-11-09 06:35:12 -08001075};
1076
1077/////////////////////////////////////////////////////////////////////
1078
1079class GrImprovedPerlinNoiseEffect : public GrFragmentProcessor {
1080public:
egdaniel478c04e2015-11-09 07:40:49 -08001081 static GrFragmentProcessor* Create(int octaves, SkScalar z,
ethannicholas417011c2015-11-09 06:35:12 -08001082 SkPerlinNoiseShader2::PaintingData* paintingData,
1083 GrTexture* permutationsTexture, GrTexture* gradientTexture,
1084 const SkMatrix& matrix) {
1085 return new GrImprovedPerlinNoiseEffect(octaves, z, paintingData, permutationsTexture,
1086 gradientTexture, matrix);
1087 }
1088
1089 virtual ~GrImprovedPerlinNoiseEffect() { delete fPaintingData; }
1090
1091 const char* name() const override { return "ImprovedPerlinNoise"; }
1092
1093 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency; }
1094 SkScalar z() const { return fZ; }
1095 int octaves() const { return fOctaves; }
1096 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); }
1097
1098private:
egdaniel57d3b032015-11-13 11:57:27 -08001099 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
ethannicholas417011c2015-11-09 06:35:12 -08001100 return new GrGLImprovedPerlinNoise(*this);
1101 }
1102
egdaniel57d3b032015-11-13 11:57:27 -08001103 virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps,
1104 GrProcessorKeyBuilder* b) const override {
ethannicholas417011c2015-11-09 06:35:12 -08001105 GrGLImprovedPerlinNoise::GenKey(*this, caps, b);
1106 }
1107
1108 bool onIsEqual(const GrFragmentProcessor& sBase) const override {
1109 const GrImprovedPerlinNoiseEffect& s = sBase.cast<GrImprovedPerlinNoiseEffect>();
1110 return fZ == fZ &&
1111 fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency;
1112 }
1113
1114 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
1115 inout->setToUnknown(GrInvariantOutput::kWillNot_ReadInput);
1116 }
1117
1118 GrImprovedPerlinNoiseEffect(int octaves, SkScalar z,
1119 SkPerlinNoiseShader2::PaintingData* paintingData,
1120 GrTexture* permutationsTexture, GrTexture* gradientTexture,
1121 const SkMatrix& matrix)
1122 : fOctaves(octaves)
1123 , fZ(z)
1124 , fPermutationsAccess(permutationsTexture)
1125 , fGradientAccess(gradientTexture)
1126 , fPaintingData(paintingData) {
1127 this->initClassID<GrImprovedPerlinNoiseEffect>();
1128 this->addTextureAccess(&fPermutationsAccess);
1129 this->addTextureAccess(&fGradientAccess);
1130 fCoordTransform.reset(kLocal_GrCoordSet, matrix);
1131 this->addCoordTransform(&fCoordTransform);
1132 }
1133
1134 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
1135
1136 GrCoordTransform fCoordTransform;
1137 int fOctaves;
1138 SkScalar fZ;
1139 GrTextureAccess fPermutationsAccess;
1140 GrTextureAccess fGradientAccess;
1141 SkPerlinNoiseShader2::PaintingData *fPaintingData;
1142
1143private:
1144 typedef GrFragmentProcessor INHERITED;
1145};
1146
1147/////////////////////////////////////////////////////////////////////
1148GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrImprovedPerlinNoiseEffect);
1149
1150const GrFragmentProcessor* GrImprovedPerlinNoiseEffect::TestCreate(GrProcessorTestData* d) {
1151 SkScalar baseFrequencyX = d->fRandom->nextRangeScalar(0.01f,
1152 0.99f);
1153 SkScalar baseFrequencyY = d->fRandom->nextRangeScalar(0.01f,
1154 0.99f);
1155 int numOctaves = d->fRandom->nextRangeU(2, 10);
1156 SkScalar z = SkIntToScalar(d->fRandom->nextU());
1157
1158 SkAutoTUnref<SkShader> shader(SkPerlinNoiseShader2::CreateImprovedNoise(baseFrequencyX,
1159 baseFrequencyY,
1160 numOctaves,
1161 z));
1162
1163 GrPaint grPaint;
1164 return shader->asFragmentProcessor(d->fContext,
1165 GrTest::TestMatrix(d->fRandom), nullptr,
1166 kNone_SkFilterQuality);
1167}
1168
1169GrGLImprovedPerlinNoise::GrGLImprovedPerlinNoise(const GrProcessor& processor)
1170 : fZ(processor.cast<GrImprovedPerlinNoiseEffect>().z()) {
1171}
1172
1173void GrGLImprovedPerlinNoise::emitCode(EmitArgs& args) {
egdaniel4ca2e602015-11-18 08:01:26 -08001174 GrGLSLFragmentBuilder* fsBuilder = args.fFragBuilder;
egdaniel7ea439b2015-12-03 09:20:44 -08001175 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
ethannicholas417011c2015-11-09 06:35:12 -08001176 SkString vCoords = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
1177
egdaniel7ea439b2015-12-03 09:20:44 -08001178 fBaseFrequencyUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
1179 kVec2f_GrSLType, kDefault_GrSLPrecision,
1180 "baseFrequency");
1181 const char* baseFrequencyUni = uniformHandler->getUniformCStr(fBaseFrequencyUni);
ethannicholas417011c2015-11-09 06:35:12 -08001182
egdaniel7ea439b2015-12-03 09:20:44 -08001183 fOctavesUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
1184 kFloat_GrSLType, kDefault_GrSLPrecision,
1185 "octaves");
1186 const char* octavesUni = uniformHandler->getUniformCStr(fOctavesUni);
ethannicholas417011c2015-11-09 06:35:12 -08001187
egdaniel7ea439b2015-12-03 09:20:44 -08001188 fZUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
1189 kFloat_GrSLType, kDefault_GrSLPrecision,
1190 "z");
1191 const char* zUni = uniformHandler->getUniformCStr(fZUni);
ethannicholas417011c2015-11-09 06:35:12 -08001192
1193 // fade function
1194 static const GrGLSLShaderVar fadeArgs[] = {
1195 GrGLSLShaderVar("t", kVec3f_GrSLType)
1196 };
1197 SkString fadeFuncName;
1198 fsBuilder->emitFunction(kVec3f_GrSLType, "fade", SK_ARRAY_COUNT(fadeArgs),
1199 fadeArgs,
1200 "return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);",
1201 &fadeFuncName);
1202
1203 // perm function
1204 static const GrGLSLShaderVar permArgs[] = {
1205 GrGLSLShaderVar("x", kFloat_GrSLType)
1206 };
1207 SkString permFuncName;
1208 SkString permCode("return ");
1209 // FIXME even though I'm creating these textures with kRepeat_TileMode, they're clamped. Not
1210 // sure why. Using fract() (here and the next texture lookup) as a workaround.
1211 fsBuilder->appendTextureLookup(&permCode, args.fSamplers[0], "vec2(fract(x / 256.0), 0.0)",
1212 kVec2f_GrSLType);
1213 permCode.append(".r * 255.0;");
1214 fsBuilder->emitFunction(kFloat_GrSLType, "perm", SK_ARRAY_COUNT(permArgs), permArgs,
1215 permCode.c_str(), &permFuncName);
1216
1217 // grad function
1218 static const GrGLSLShaderVar gradArgs[] = {
1219 GrGLSLShaderVar("x", kFloat_GrSLType),
1220 GrGLSLShaderVar("p", kVec3f_GrSLType)
1221 };
1222 SkString gradFuncName;
1223 SkString gradCode("return dot(");
1224 fsBuilder->appendTextureLookup(&gradCode, args.fSamplers[1], "vec2(fract(x / 16.0), 0.0)",
1225 kVec2f_GrSLType);
1226 gradCode.append(".rgb * 255.0 - vec3(1.0), p);");
1227 fsBuilder->emitFunction(kFloat_GrSLType, "grad", SK_ARRAY_COUNT(gradArgs), gradArgs,
1228 gradCode.c_str(), &gradFuncName);
1229
1230 // lerp function
1231 static const GrGLSLShaderVar lerpArgs[] = {
1232 GrGLSLShaderVar("a", kFloat_GrSLType),
1233 GrGLSLShaderVar("b", kFloat_GrSLType),
1234 GrGLSLShaderVar("w", kFloat_GrSLType)
1235 };
1236 SkString lerpFuncName;
1237 fsBuilder->emitFunction(kFloat_GrSLType, "lerp", SK_ARRAY_COUNT(lerpArgs), lerpArgs,
1238 "return a + w * (b - a);", &lerpFuncName);
1239
1240 // noise function
1241 static const GrGLSLShaderVar noiseArgs[] = {
1242 GrGLSLShaderVar("p", kVec3f_GrSLType),
1243 };
1244 SkString noiseFuncName;
1245 SkString noiseCode;
1246 noiseCode.append("vec3 P = mod(floor(p), 256.0);");
1247 noiseCode.append("p -= floor(p);");
1248 noiseCode.appendf("vec3 f = %s(p);", fadeFuncName.c_str());
1249 noiseCode.appendf("float A = %s(P.x) + P.y;", permFuncName.c_str());
1250 noiseCode.appendf("float AA = %s(A) + P.z;", permFuncName.c_str());
1251 noiseCode.appendf("float AB = %s(A + 1.0) + P.z;", permFuncName.c_str());
1252 noiseCode.appendf("float B = %s(P.x + 1.0) + P.y;", permFuncName.c_str());
1253 noiseCode.appendf("float BA = %s(B) + P.z;", permFuncName.c_str());
1254 noiseCode.appendf("float BB = %s(B + 1.0) + P.z;", permFuncName.c_str());
1255 noiseCode.appendf("float result = %s(", lerpFuncName.c_str());
1256 noiseCode.appendf("%s(%s(%s(%s(AA), p),", lerpFuncName.c_str(), lerpFuncName.c_str(),
1257 gradFuncName.c_str(), permFuncName.c_str());
1258 noiseCode.appendf("%s(%s(BA), p + vec3(-1.0, 0.0, 0.0)), f.x),", gradFuncName.c_str(),
1259 permFuncName.c_str());
1260 noiseCode.appendf("%s(%s(%s(AB), p + vec3(0.0, -1.0, 0.0)),", lerpFuncName.c_str(),
1261 gradFuncName.c_str(), permFuncName.c_str());
1262 noiseCode.appendf("%s(%s(BB), p + vec3(-1.0, -1.0, 0.0)), f.x), f.y),",
1263 gradFuncName.c_str(), permFuncName.c_str());
1264 noiseCode.appendf("%s(%s(%s(%s(AA + 1.0), p + vec3(0.0, 0.0, -1.0)),",
1265 lerpFuncName.c_str(), lerpFuncName.c_str(), gradFuncName.c_str(),
1266 permFuncName.c_str());
1267 noiseCode.appendf("%s(%s(BA + 1.0), p + vec3(-1.0, 0.0, -1.0)), f.x),",
1268 gradFuncName.c_str(), permFuncName.c_str());
1269 noiseCode.appendf("%s(%s(%s(AB + 1.0), p + vec3(0.0, -1.0, -1.0)),",
1270 lerpFuncName.c_str(), gradFuncName.c_str(), permFuncName.c_str());
1271 noiseCode.appendf("%s(%s(BB + 1.0), p + vec3(-1.0, -1.0, -1.0)), f.x), f.y), f.z);",
1272 gradFuncName.c_str(), permFuncName.c_str());
1273 noiseCode.append("return result;");
1274 fsBuilder->emitFunction(kFloat_GrSLType, "noise", SK_ARRAY_COUNT(noiseArgs), noiseArgs,
1275 noiseCode.c_str(), &noiseFuncName);
1276
1277 // noiseOctaves function
1278 static const GrGLSLShaderVar noiseOctavesArgs[] = {
1279 GrGLSLShaderVar("p", kVec3f_GrSLType),
1280 GrGLSLShaderVar("octaves", kFloat_GrSLType),
1281 };
1282 SkString noiseOctavesFuncName;
1283 SkString noiseOctavesCode;
1284 noiseOctavesCode.append("float result = 0.0;");
1285 noiseOctavesCode.append("float ratio = 1.0;");
1286 noiseOctavesCode.append("for (float i = 0.0; i < octaves; i++) {");
1287 noiseOctavesCode.appendf("result += %s(p) / ratio;", noiseFuncName.c_str());
1288 noiseOctavesCode.append("p *= 2.0;");
1289 noiseOctavesCode.append("ratio *= 2.0;");
1290 noiseOctavesCode.append("}");
1291 noiseOctavesCode.append("return (result + 1.0) / 2.0;");
1292 fsBuilder->emitFunction(kFloat_GrSLType, "noiseOctaves", SK_ARRAY_COUNT(noiseOctavesArgs),
1293 noiseOctavesArgs, noiseOctavesCode.c_str(), &noiseOctavesFuncName);
1294
1295 fsBuilder->codeAppendf("vec2 coords = %s * %s;", vCoords.c_str(), baseFrequencyUni);
1296 fsBuilder->codeAppendf("float r = %s(vec3(coords, %s), %s);", noiseOctavesFuncName.c_str(),
1297 zUni, octavesUni);
egdaniel478c04e2015-11-09 07:40:49 -08001298 fsBuilder->codeAppendf("float g = %s(vec3(coords, %s + 0000.0), %s);",
ethannicholas417011c2015-11-09 06:35:12 -08001299 noiseOctavesFuncName.c_str(), zUni, octavesUni);
egdaniel478c04e2015-11-09 07:40:49 -08001300 fsBuilder->codeAppendf("float b = %s(vec3(coords, %s + 0000.0), %s);",
ethannicholas417011c2015-11-09 06:35:12 -08001301 noiseOctavesFuncName.c_str(), zUni, octavesUni);
egdaniel478c04e2015-11-09 07:40:49 -08001302 fsBuilder->codeAppendf("float a = %s(vec3(coords, %s + 0000.0), %s);",
ethannicholas417011c2015-11-09 06:35:12 -08001303 noiseOctavesFuncName.c_str(), zUni, octavesUni);
1304 fsBuilder->codeAppendf("%s = vec4(r, g, b, a);", args.fOutputColor);
1305
1306 // Clamp values
1307 fsBuilder->codeAppendf("%s = clamp(%s, 0.0, 1.0);", args.fOutputColor, args.fOutputColor);
1308
1309 // Pre-multiply the result
1310 fsBuilder->codeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
1311 args.fOutputColor, args.fOutputColor,
1312 args.fOutputColor, args.fOutputColor);
1313}
1314
1315void GrGLImprovedPerlinNoise::GenKey(const GrProcessor& processor, const GrGLSLCaps&,
1316 GrProcessorKeyBuilder* b) {
1317}
1318
1319void GrGLImprovedPerlinNoise::onSetData(const GrGLSLProgramDataManager& pdman,
1320 const GrProcessor& processor) {
1321 INHERITED::onSetData(pdman, processor);
1322
1323 const GrImprovedPerlinNoiseEffect& noise = processor.cast<GrImprovedPerlinNoiseEffect>();
1324
1325 const SkVector& baseFrequency = noise.baseFrequency();
1326 pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY);
1327
egdaniel478c04e2015-11-09 07:40:49 -08001328 pdman.set1f(fOctavesUni, SkIntToScalar(noise.octaves()));
ethannicholas417011c2015-11-09 06:35:12 -08001329
1330 pdman.set1f(fZUni, noise.z());
1331}
1332
1333/////////////////////////////////////////////////////////////////////
1334const GrFragmentProcessor* SkPerlinNoiseShader2::asFragmentProcessor(
1335 GrContext* context,
1336 const SkMatrix& viewM,
1337 const SkMatrix* externalLocalMatrix,
1338 SkFilterQuality) const {
1339 SkASSERT(context);
1340
1341 SkMatrix localMatrix = this->getLocalMatrix();
1342 if (externalLocalMatrix) {
1343 localMatrix.preConcat(*externalLocalMatrix);
1344 }
1345
1346 SkMatrix matrix = viewM;
1347 matrix.preConcat(localMatrix);
1348
1349 // Either we don't stitch tiles, either we have a valid tile size
1350 SkASSERT(!fStitchTiles || !fTileSize.isEmpty());
1351
1352 SkPerlinNoiseShader2::PaintingData* paintingData =
1353 new PaintingData(fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY, matrix);
1354
1355 SkMatrix m = viewM;
1356 m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1);
1357 m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1);
1358
1359 if (fType == kImprovedNoise_Type) {
1360 GrTextureParams textureParams(SkShader::TileMode::kRepeat_TileMode,
1361 GrTextureParams::FilterMode::kNone_FilterMode);
1362 SkAutoTUnref<GrTexture> permutationsTexture(
1363 GrRefCachedBitmapTexture(context, paintingData->getImprovedPermutationsBitmap(),
1364 textureParams));
1365 SkAutoTUnref<GrTexture> gradientTexture(
1366 GrRefCachedBitmapTexture(context, paintingData->getGradientBitmap(),
1367 textureParams));
1368 return GrImprovedPerlinNoiseEffect::Create(fNumOctaves, fSeed, paintingData,
1369 permutationsTexture, gradientTexture, m);
1370 }
1371
1372 if (0 == fNumOctaves) {
1373 if (kFractalNoise_Type == fType) {
1374 // Extract the incoming alpha and emit rgba = (a/4, a/4, a/4, a/2)
1375 SkAutoTUnref<const GrFragmentProcessor> inner(
1376 GrConstColorProcessor::Create(0x80404040,
1377 GrConstColorProcessor::kModulateRGBA_InputMode));
1378 return GrFragmentProcessor::MulOutputByInputAlpha(inner);
1379 }
1380 // Emit zero.
1381 return GrConstColorProcessor::Create(0x0, GrConstColorProcessor::kIgnore_InputMode);
1382 }
1383
1384 SkAutoTUnref<GrTexture> permutationsTexture(
1385 GrRefCachedBitmapTexture(context, paintingData->getPermutationsBitmap(),
1386 GrTextureParams::ClampNoFilter()));
1387 SkAutoTUnref<GrTexture> noiseTexture(
1388 GrRefCachedBitmapTexture(context, paintingData->getNoiseBitmap(),
1389 GrTextureParams::ClampNoFilter()));
1390
1391 if ((permutationsTexture) && (noiseTexture)) {
1392 SkAutoTUnref<GrFragmentProcessor> inner(
1393 GrPerlinNoise2Effect::Create(fType,
1394 fNumOctaves,
1395 fStitchTiles,
1396 paintingData,
1397 permutationsTexture, noiseTexture,
1398 m));
1399 return GrFragmentProcessor::MulOutputByInputAlpha(inner);
1400 }
1401 delete paintingData;
1402 return nullptr;
1403}
1404
1405#endif
1406
1407#ifndef SK_IGNORE_TO_STRING
1408void SkPerlinNoiseShader2::toString(SkString* str) const {
1409 str->append("SkPerlinNoiseShader2: (");
1410
1411 str->append("type: ");
1412 switch (fType) {
1413 case kFractalNoise_Type:
1414 str->append("\"fractal noise\"");
1415 break;
1416 case kTurbulence_Type:
1417 str->append("\"turbulence\"");
1418 break;
1419 default:
1420 str->append("\"unknown\"");
1421 break;
1422 }
1423 str->append(" base frequency: (");
1424 str->appendScalar(fBaseFrequencyX);
1425 str->append(", ");
1426 str->appendScalar(fBaseFrequencyY);
1427 str->append(") number of octaves: ");
1428 str->appendS32(fNumOctaves);
1429 str->append(" seed: ");
1430 str->appendScalar(fSeed);
1431 str->append(" stitch tiles: ");
1432 str->append(fStitchTiles ? "true " : "false ");
1433
1434 this->INHERITED::toString(str);
1435
1436 str->append(")");
1437}
1438#endif