1/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkDither.h"
9#include "SkPerlinNoiseShader.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 "gl/GrGLEffect.h"
21#include "GrTBackendEffectFactory.h"
22#include "SkGr.h"
23#endif
24
25static const int kBlockSize = 256;
26static const int kBlockMask = kBlockSize - 1;
27static const int kPerlinNoise = 4096;
28static const int kRandMaximum = SK_MaxS32; // 2**31 - 1
29
30namespace {
31
32// noiseValue is the color component's value (or color)
33// limitValue is the maximum perlin noise array index value allowed
34// newValue is the current noise dimension (either width or height)
35inline int checkNoise(int noiseValue, int limitValue, int newValue) {
36    // If the noise value would bring us out of bounds of the current noise array while we are
37    // stiching noise tiles together, wrap the noise around the current dimension of the noise to
38    // stay within the array bounds in a continuous fashion (so that tiling lines are not visible)
39    if (noiseValue >= limitValue) {
40        noiseValue -= newValue;
41    }
42    return noiseValue;
43}
44
45inline SkScalar smoothCurve(SkScalar t) {
46    static const SkScalar SK_Scalar3 = 3.0f;
47
48    // returns t * t * (3 - 2 * t)
49    return SkScalarMul(SkScalarSquare(t), SK_Scalar3 - 2 * t);
50}
51
52bool perlin_noise_type_is_valid(SkPerlinNoiseShader::Type type) {
53    return (SkPerlinNoiseShader::kFractalNoise_Type == type) ||
54           (SkPerlinNoiseShader::kTurbulence_Type == type);
55}
56
57} // end namespace
58
59struct SkPerlinNoiseShader::StitchData {
60    StitchData()
61      : fWidth(0)
62      , fWrapX(0)
63      , fHeight(0)
64      , fWrapY(0)
65    {}
66
67    bool operator==(const StitchData& other) const {
68        return fWidth == other.fWidth &&
69               fWrapX == other.fWrapX &&
70               fHeight == other.fHeight &&
71               fWrapY == other.fWrapY;
72    }
73
74    int fWidth; // How much to subtract to wrap for stitching.
75    int fWrapX; // Minimum value to wrap.
76    int fHeight;
77    int fWrapY;
78};
79
80struct SkPerlinNoiseShader::PaintingData {
81    PaintingData(const SkISize& tileSize, SkScalar seed,
82                 SkScalar baseFrequencyX, SkScalar baseFrequencyY)
83      : fTileSize(tileSize)
84      , fBaseFrequency(SkPoint::Make(baseFrequencyX, baseFrequencyY))
85    {
86        this->init(seed);
87        if (!fTileSize.isEmpty()) {
88            this->stitch();
89        }
90
91#if SK_SUPPORT_GPU
92        fPermutationsBitmap.setInfo(SkImageInfo::MakeA8(kBlockSize, 1));
93        fPermutationsBitmap.setPixels(fLatticeSelector);
94
95        fNoiseBitmap.setInfo(SkImageInfo::MakeN32Premul(kBlockSize, 4));
96        fNoiseBitmap.setPixels(fNoise[0][0]);
97#endif
98    }
99
100    int         fSeed;
101    uint8_t     fLatticeSelector[kBlockSize];
102    uint16_t    fNoise[4][kBlockSize][2];
103    SkPoint     fGradient[4][kBlockSize];
104    SkISize     fTileSize;
105    SkVector    fBaseFrequency;
106    StitchData  fStitchDataInit;
107
108private:
109
110#if SK_SUPPORT_GPU
111    SkBitmap   fPermutationsBitmap;
112    SkBitmap   fNoiseBitmap;
113#endif
114
115    inline int random()  {
116        static const int gRandAmplitude = 16807; // 7**5; primitive root of m
117        static const int gRandQ = 127773; // m / a
118        static const int gRandR = 2836; // m % a
119
120        int result = gRandAmplitude * (fSeed % gRandQ) - gRandR * (fSeed / gRandQ);
121        if (result <= 0)
122            result += kRandMaximum;
123        fSeed = result;
124        return result;
125    }
126
127    // Only called once. Could be part of the constructor.
128    void init(SkScalar seed)
129    {
130        static const SkScalar gInvBlockSizef = SkScalarInvert(SkIntToScalar(kBlockSize));
131
132        // According to the SVG spec, we must truncate (not round) the seed value.
133        fSeed = SkScalarTruncToInt(seed);
134        // The seed value clamp to the range [1, kRandMaximum - 1].
135        if (fSeed <= 0) {
136            fSeed = -(fSeed % (kRandMaximum - 1)) + 1;
137        }
138        if (fSeed > kRandMaximum - 1) {
139            fSeed = kRandMaximum - 1;
140        }
141        for (int channel = 0; channel < 4; ++channel) {
142            for (int i = 0; i < kBlockSize; ++i) {
143                fLatticeSelector[i] = i;
144                fNoise[channel][i][0] = (random() % (2 * kBlockSize));
145                fNoise[channel][i][1] = (random() % (2 * kBlockSize));
146            }
147        }
148        for (int i = kBlockSize - 1; i > 0; --i) {
149            int k = fLatticeSelector[i];
150            int j = random() % kBlockSize;
151            SkASSERT(j >= 0);
152            SkASSERT(j < kBlockSize);
153            fLatticeSelector[i] = fLatticeSelector[j];
154            fLatticeSelector[j] = k;
155        }
156
157        // Perform the permutations now
158        {
159            // Copy noise data
160            uint16_t noise[4][kBlockSize][2];
161            for (int i = 0; i < kBlockSize; ++i) {
162                for (int channel = 0; channel < 4; ++channel) {
163                    for (int j = 0; j < 2; ++j) {
164                        noise[channel][i][j] = fNoise[channel][i][j];
165                    }
166                }
167            }
168            // Do permutations on noise data
169            for (int i = 0; i < kBlockSize; ++i) {
170                for (int channel = 0; channel < 4; ++channel) {
171                    for (int j = 0; j < 2; ++j) {
172                        fNoise[channel][i][j] = noise[channel][fLatticeSelector[i]][j];
173                    }
174                }
175            }
176        }
177
178        // Half of the largest possible value for 16 bit unsigned int
179        static const SkScalar gHalfMax16bits = 32767.5f;
180
181        // Compute gradients from permutated noise data
182        for (int channel = 0; channel < 4; ++channel) {
183            for (int i = 0; i < kBlockSize; ++i) {
184                fGradient[channel][i] = SkPoint::Make(
185                    SkScalarMul(SkIntToScalar(fNoise[channel][i][0] - kBlockSize),
186                                gInvBlockSizef),
187                    SkScalarMul(SkIntToScalar(fNoise[channel][i][1] - kBlockSize),
188                                gInvBlockSizef));
189                fGradient[channel][i].normalize();
190                // Put the normalized gradient back into the noise data
191                fNoise[channel][i][0] = SkScalarRoundToInt(SkScalarMul(
192                    fGradient[channel][i].fX + SK_Scalar1, gHalfMax16bits));
193                fNoise[channel][i][1] = SkScalarRoundToInt(SkScalarMul(
194                    fGradient[channel][i].fY + SK_Scalar1, gHalfMax16bits));
195            }
196        }
197    }
198
199    // Only called once. Could be part of the constructor.
200    void stitch() {
201        SkScalar tileWidth  = SkIntToScalar(fTileSize.width());
202        SkScalar tileHeight = SkIntToScalar(fTileSize.height());
203        SkASSERT(tileWidth > 0 && tileHeight > 0);
204        // When stitching tiled turbulence, the frequencies must be adjusted
205        // so that the tile borders will be continuous.
206        if (fBaseFrequency.fX) {
207            SkScalar lowFrequencx =
208                SkScalarFloorToScalar(tileWidth * fBaseFrequency.fX) / tileWidth;
209            SkScalar highFrequencx =
210                SkScalarCeilToScalar(tileWidth * fBaseFrequency.fX) / tileWidth;
211            // BaseFrequency should be non-negative according to the standard.
212            if (SkScalarDiv(fBaseFrequency.fX, lowFrequencx) <
213                SkScalarDiv(highFrequencx, fBaseFrequency.fX)) {
214                fBaseFrequency.fX = lowFrequencx;
215            } else {
216                fBaseFrequency.fX = highFrequencx;
217            }
218        }
219        if (fBaseFrequency.fY) {
220            SkScalar lowFrequency =
221                SkScalarFloorToScalar(tileHeight * fBaseFrequency.fY) / tileHeight;
222            SkScalar highFrequency =
223                SkScalarCeilToScalar(tileHeight * fBaseFrequency.fY) / tileHeight;
224            if (SkScalarDiv(fBaseFrequency.fY, lowFrequency) <
225                SkScalarDiv(highFrequency, fBaseFrequency.fY)) {
226                fBaseFrequency.fY = lowFrequency;
227            } else {
228                fBaseFrequency.fY = highFrequency;
229            }
230        }
231        // Set up TurbulenceInitial stitch values.
232        fStitchDataInit.fWidth  =
233            SkScalarRoundToInt(tileWidth * fBaseFrequency.fX);
234        fStitchDataInit.fWrapX  = kPerlinNoise + fStitchDataInit.fWidth;
235        fStitchDataInit.fHeight =
236            SkScalarRoundToInt(tileHeight * fBaseFrequency.fY);
237        fStitchDataInit.fWrapY  = kPerlinNoise + fStitchDataInit.fHeight;
238    }
239
240public:
241
242#if SK_SUPPORT_GPU
243    const SkBitmap& getPermutationsBitmap() const { return fPermutationsBitmap; }
244
245    const SkBitmap& getNoiseBitmap() const { return fNoiseBitmap; }
246#endif
247};
248
249SkShader* SkPerlinNoiseShader::CreateFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY,
250                                                  int numOctaves, SkScalar seed,
251                                                  const SkISize* tileSize) {
252    return SkNEW_ARGS(SkPerlinNoiseShader, (kFractalNoise_Type, baseFrequencyX, baseFrequencyY,
253                                            numOctaves, seed, tileSize));
254}
255
256SkShader* SkPerlinNoiseShader::CreateTurbulence(SkScalar baseFrequencyX, SkScalar baseFrequencyY,
257                                              int numOctaves, SkScalar seed,
258                                              const SkISize* tileSize) {
259    return SkNEW_ARGS(SkPerlinNoiseShader, (kTurbulence_Type, baseFrequencyX, baseFrequencyY,
260                                            numOctaves, seed, tileSize));
261}
262
263SkPerlinNoiseShader::SkPerlinNoiseShader(SkPerlinNoiseShader::Type type,
264                                         SkScalar baseFrequencyX,
265                                         SkScalar baseFrequencyY,
266                                         int numOctaves,
267                                         SkScalar seed,
268                                         const SkISize* tileSize)
269  : fType(type)
270  , fBaseFrequencyX(baseFrequencyX)
271  , fBaseFrequencyY(baseFrequencyY)
272  , fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/)
273  , fSeed(seed)
274  , fTileSize(NULL == tileSize ? SkISize::Make(0, 0) : *tileSize)
275  , fStitchTiles(!fTileSize.isEmpty())
276{
277    SkASSERT(numOctaves >= 0 && numOctaves < 256);
278    fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY));
279}
280
281SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer)
282    : INHERITED(buffer)
283{
284    fType           = (SkPerlinNoiseShader::Type) buffer.readInt();
285    fBaseFrequencyX = buffer.readScalar();
286    fBaseFrequencyY = buffer.readScalar();
287    fNumOctaves     = buffer.readInt();
288    fSeed           = buffer.readScalar();
289    fStitchTiles    = buffer.readBool();
290    fTileSize.fWidth  = buffer.readInt();
291    fTileSize.fHeight = buffer.readInt();
292    fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY));
293    buffer.validate(perlin_noise_type_is_valid(fType) &&
294                    (fNumOctaves >= 0) && (fNumOctaves <= 255) &&
295                    (fStitchTiles != fTileSize.isEmpty()));
296}
297
298SkPerlinNoiseShader::~SkPerlinNoiseShader() {
299    // Safety, should have been done in endContext()
300    SkDELETE(fPaintingData);
301}
302
303void SkPerlinNoiseShader::flatten(SkWriteBuffer& buffer) const {
304    this->INHERITED::flatten(buffer);
305    buffer.writeInt((int) fType);
306    buffer.writeScalar(fBaseFrequencyX);
307    buffer.writeScalar(fBaseFrequencyY);
308    buffer.writeInt(fNumOctaves);
309    buffer.writeScalar(fSeed);
310    buffer.writeBool(fStitchTiles);
311    buffer.writeInt(fTileSize.fWidth);
312    buffer.writeInt(fTileSize.fHeight);
313}
314
315SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::noise2D(
316        int channel, const PaintingData& paintingData,
317        const StitchData& stitchData, const SkPoint& noiseVector) const {
318    struct Noise {
319        int noisePositionIntegerValue;
320        int nextNoisePositionIntegerValue;
321        SkScalar noisePositionFractionValue;
322        Noise(SkScalar component)
323        {
324            SkScalar position = component + kPerlinNoise;
325            noisePositionIntegerValue = SkScalarFloorToInt(position);
326            noisePositionFractionValue = position - SkIntToScalar(noisePositionIntegerValue);
327            nextNoisePositionIntegerValue = noisePositionIntegerValue + 1;
328        }
329    };
330    Noise noiseX(noiseVector.x());
331    Noise noiseY(noiseVector.y());
332    SkScalar u, v;
333    const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoiseShader&>(fShader);
334    // If stitching, adjust lattice points accordingly.
335    if (perlinNoiseShader.fStitchTiles) {
336        noiseX.noisePositionIntegerValue =
337            checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth);
338        noiseY.noisePositionIntegerValue =
339            checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight);
340        noiseX.nextNoisePositionIntegerValue =
341            checkNoise(noiseX.nextNoisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth);
342        noiseY.nextNoisePositionIntegerValue =
343            checkNoise(noiseY.nextNoisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight);
344    }
345    noiseX.noisePositionIntegerValue &= kBlockMask;
346    noiseY.noisePositionIntegerValue &= kBlockMask;
347    noiseX.nextNoisePositionIntegerValue &= kBlockMask;
348    noiseY.nextNoisePositionIntegerValue &= kBlockMask;
349    int i =
350        paintingData.fLatticeSelector[noiseX.noisePositionIntegerValue];
351    int j =
352        paintingData.fLatticeSelector[noiseX.nextNoisePositionIntegerValue];
353    int b00 = (i + noiseY.noisePositionIntegerValue) & kBlockMask;
354    int b10 = (j + noiseY.noisePositionIntegerValue) & kBlockMask;
355    int b01 = (i + noiseY.nextNoisePositionIntegerValue) & kBlockMask;
356    int b11 = (j + noiseY.nextNoisePositionIntegerValue) & kBlockMask;
357    SkScalar sx = smoothCurve(noiseX.noisePositionFractionValue);
358    SkScalar sy = smoothCurve(noiseY.noisePositionFractionValue);
359    // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement
360    SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue,
361                                          noiseY.noisePositionFractionValue); // Offset (0,0)
362    u = paintingData.fGradient[channel][b00].dot(fractionValue);
363    fractionValue.fX -= SK_Scalar1; // Offset (-1,0)
364    v = paintingData.fGradient[channel][b10].dot(fractionValue);
365    SkScalar a = SkScalarInterp(u, v, sx);
366    fractionValue.fY -= SK_Scalar1; // Offset (-1,-1)
367    v = paintingData.fGradient[channel][b11].dot(fractionValue);
368    fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1)
369    u = paintingData.fGradient[channel][b01].dot(fractionValue);
370    SkScalar b = SkScalarInterp(u, v, sx);
371    return SkScalarInterp(a, b, sy);
372}
373
374SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::calculateTurbulenceValueForPoint(
375        int channel, const PaintingData& paintingData,
376        StitchData& stitchData, const SkPoint& point) const {
377    const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoiseShader&>(fShader);
378    if (perlinNoiseShader.fStitchTiles) {
379        // Set up TurbulenceInitial stitch values.
380        stitchData = paintingData.fStitchDataInit;
381    }
382    SkScalar turbulenceFunctionResult = 0;
383    SkPoint noiseVector(SkPoint::Make(SkScalarMul(point.x(), paintingData.fBaseFrequency.fX),
384                                      SkScalarMul(point.y(), paintingData.fBaseFrequency.fY)));
385    SkScalar ratio = SK_Scalar1;
386    for (int octave = 0; octave < perlinNoiseShader.fNumOctaves; ++octave) {
387        SkScalar noise = noise2D(channel, paintingData, stitchData, noiseVector);
388        turbulenceFunctionResult += SkScalarDiv(
389            (perlinNoiseShader.fType == kFractalNoise_Type) ? noise : SkScalarAbs(noise), ratio);
390        noiseVector.fX *= 2;
391        noiseVector.fY *= 2;
392        ratio *= 2;
393        if (perlinNoiseShader.fStitchTiles) {
394            // Update stitch values
395            stitchData.fWidth  *= 2;
396            stitchData.fWrapX   = stitchData.fWidth + kPerlinNoise;
397            stitchData.fHeight *= 2;
398            stitchData.fWrapY   = stitchData.fHeight + kPerlinNoise;
399        }
400    }
401
402    // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
403    // by fractalNoise and (turbulenceFunctionResult) by turbulence.
404    if (perlinNoiseShader.fType == kFractalNoise_Type) {
405        turbulenceFunctionResult =
406            SkScalarMul(turbulenceFunctionResult, SK_ScalarHalf) + SK_ScalarHalf;
407    }
408
409    if (channel == 3) { // Scale alpha by paint value
410        turbulenceFunctionResult = SkScalarMul(turbulenceFunctionResult,
411            SkScalarDiv(SkIntToScalar(getPaintAlpha()), SkIntToScalar(255)));
412    }
413
414    // Clamp result
415    return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1);
416}
417
418SkPMColor SkPerlinNoiseShader::PerlinNoiseShaderContext::shade(
419        const SkPoint& point, StitchData& stitchData) const {
420    const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoiseShader&>(fShader);
421    SkPoint newPoint;
422    fMatrix.mapPoints(&newPoint, &point, 1);
423    newPoint.fX = SkScalarRoundToScalar(newPoint.fX);
424    newPoint.fY = SkScalarRoundToScalar(newPoint.fY);
425
426    U8CPU rgba[4];
427    for (int channel = 3; channel >= 0; --channel) {
428        rgba[channel] = SkScalarFloorToInt(255 *
429            calculateTurbulenceValueForPoint(channel, *perlinNoiseShader.fPaintingData,
430                                             stitchData, newPoint));
431    }
432    return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
433}
434
435SkShader::Context* SkPerlinNoiseShader::onCreateContext(const ContextRec& rec,
436                                                        void* storage) const {
437    return SkNEW_PLACEMENT_ARGS(storage, PerlinNoiseShaderContext, (*this, rec));
438}
439
440size_t SkPerlinNoiseShader::contextSize() const {
441    return sizeof(PerlinNoiseShaderContext);
442}
443
444SkPerlinNoiseShader::PerlinNoiseShaderContext::PerlinNoiseShaderContext(
445        const SkPerlinNoiseShader& shader, const ContextRec& rec)
446    : INHERITED(shader, rec)
447{
448    SkMatrix newMatrix = *rec.fMatrix;
449    newMatrix.preConcat(shader.getLocalMatrix());
450    if (rec.fLocalMatrix) {
451        newMatrix.preConcat(*rec.fLocalMatrix);
452    }
453    SkMatrix invMatrix;
454    if (!newMatrix.invert(&invMatrix)) {
455        invMatrix.reset();
456    }
457    // This (1,1) translation is due to WebKit's 1 based coordinates for the noise
458    // (as opposed to 0 based, usually). The same adjustment is in the setData() function.
459    newMatrix.postTranslate(SK_Scalar1, SK_Scalar1);
460    newMatrix.postConcat(invMatrix);
461    newMatrix.postConcat(invMatrix);
462    fMatrix = newMatrix;
463}
464
465void SkPerlinNoiseShader::PerlinNoiseShaderContext::shadeSpan(
466        int x, int y, SkPMColor result[], int count) {
467    SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
468    StitchData stitchData;
469    for (int i = 0; i < count; ++i) {
470        result[i] = shade(point, stitchData);
471        point.fX += SK_Scalar1;
472    }
473}
474
475void SkPerlinNoiseShader::PerlinNoiseShaderContext::shadeSpan16(
476        int x, int y, uint16_t result[], int count) {
477    SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
478    StitchData stitchData;
479    DITHER_565_SCAN(y);
480    for (int i = 0; i < count; ++i) {
481        unsigned dither = DITHER_VALUE(x);
482        result[i] = SkDitherRGB32To565(shade(point, stitchData), dither);
483        DITHER_INC_X(x);
484        point.fX += SK_Scalar1;
485    }
486}
487
488/////////////////////////////////////////////////////////////////////
489
490#if SK_SUPPORT_GPU
491
492#include "GrTBackendEffectFactory.h"
493
494class GrGLPerlinNoise : public GrGLEffect {
495public:
496    GrGLPerlinNoise(const GrBackendEffectFactory& factory,
497                    const GrDrawEffect& drawEffect);
498    virtual ~GrGLPerlinNoise() {}
499
500    virtual void emitCode(GrGLShaderBuilder*,
501                          const GrDrawEffect&,
502                          EffectKey,
503                          const char* outputColor,
504                          const char* inputColor,
505                          const TransformedCoordsArray&,
506                          const TextureSamplerArray&) SK_OVERRIDE;
507
508    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
509
510    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
511
512private:
513
514    GrGLUniformManager::UniformHandle   fStitchDataUni;
515    SkPerlinNoiseShader::Type           fType;
516    bool                                fStitchTiles;
517    int                                 fNumOctaves;
518    GrGLUniformManager::UniformHandle   fBaseFrequencyUni;
519    GrGLUniformManager::UniformHandle   fAlphaUni;
520    GrGLUniformManager::UniformHandle   fInvMatrixUni;
521
522private:
523    typedef GrGLEffect INHERITED;
524};
525
526/////////////////////////////////////////////////////////////////////
527
528class GrPerlinNoiseEffect : public GrEffect {
529public:
530    static GrEffectRef* Create(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency,
531                               int numOctaves, bool stitchTiles,
532                               const SkPerlinNoiseShader::StitchData& stitchData,
533                               GrTexture* permutationsTexture, GrTexture* noiseTexture,
534                               const SkMatrix& matrix, uint8_t alpha) {
535        AutoEffectUnref effect(SkNEW_ARGS(GrPerlinNoiseEffect, (type, baseFrequency, numOctaves,
536            stitchTiles, stitchData, permutationsTexture, noiseTexture, matrix, alpha)));
537        return CreateEffectRef(effect);
538    }
539
540    virtual ~GrPerlinNoiseEffect() { }
541
542    static const char* Name() { return "PerlinNoise"; }
543    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
544        return GrTBackendEffectFactory<GrPerlinNoiseEffect>::getInstance();
545    }
546    const SkPerlinNoiseShader::StitchData& stitchData() const { return fStitchData; }
547
548    SkPerlinNoiseShader::Type type() const { return fType; }
549    bool stitchTiles() const { return fStitchTiles; }
550    const SkVector& baseFrequency() const { return fBaseFrequency; }
551    int numOctaves() const { return fNumOctaves; }
552    const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); }
553    uint8_t alpha() const { return fAlpha; }
554
555    typedef GrGLPerlinNoise GLEffect;
556
557private:
558    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
559        const GrPerlinNoiseEffect& s = CastEffect<GrPerlinNoiseEffect>(sBase);
560        return fType == s.fType &&
561               fBaseFrequency == s.fBaseFrequency &&
562               fNumOctaves == s.fNumOctaves &&
563               fStitchTiles == s.fStitchTiles &&
564               fCoordTransform.getMatrix() == s.fCoordTransform.getMatrix() &&
565               fAlpha == s.fAlpha &&
566               fPermutationsAccess.getTexture() == s.fPermutationsAccess.getTexture() &&
567               fNoiseAccess.getTexture() == s.fNoiseAccess.getTexture() &&
568               fStitchData == s.fStitchData;
569    }
570
571    GrPerlinNoiseEffect(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency,
572                        int numOctaves, bool stitchTiles,
573                        const SkPerlinNoiseShader::StitchData& stitchData,
574                        GrTexture* permutationsTexture, GrTexture* noiseTexture,
575                        const SkMatrix& matrix, uint8_t alpha)
576      : fType(type)
577      , fBaseFrequency(baseFrequency)
578      , fNumOctaves(numOctaves)
579      , fStitchTiles(stitchTiles)
580      , fAlpha(alpha)
581      , fPermutationsAccess(permutationsTexture)
582      , fNoiseAccess(noiseTexture)
583      , fStitchData(stitchData) {
584        this->addTextureAccess(&fPermutationsAccess);
585        this->addTextureAccess(&fNoiseAccess);
586        SkMatrix m = matrix;
587        m.postTranslate(SK_Scalar1, SK_Scalar1);
588        fCoordTransform.reset(kLocal_GrCoordSet, m);
589        this->addCoordTransform(&fCoordTransform);
590        this->setWillNotUseInputColor();
591    }
592
593    GR_DECLARE_EFFECT_TEST;
594
595    SkPerlinNoiseShader::Type       fType;
596    GrCoordTransform                fCoordTransform;
597    SkVector                        fBaseFrequency;
598    int                             fNumOctaves;
599    bool                            fStitchTiles;
600    uint8_t                         fAlpha;
601    GrTextureAccess                 fPermutationsAccess;
602    GrTextureAccess                 fNoiseAccess;
603    SkPerlinNoiseShader::StitchData fStitchData;
604
605    void getConstantColorComponents(GrColor*, uint32_t* validFlags) const SK_OVERRIDE {
606        *validFlags = 0; // This is noise. Nothing is constant.
607    }
608
609private:
610    typedef GrEffect INHERITED;
611};
612
613/////////////////////////////////////////////////////////////////////
614GR_DEFINE_EFFECT_TEST(GrPerlinNoiseEffect);
615
616GrEffectRef* GrPerlinNoiseEffect::TestCreate(SkRandom* random,
617                                             GrContext* context,
618                                             const GrDrawTargetCaps&,
619                                             GrTexture**) {
620    int      numOctaves = random->nextRangeU(2, 10);
621    bool     stitchTiles = random->nextBool();
622    SkScalar seed = SkIntToScalar(random->nextU());
623    SkISize  tileSize = SkISize::Make(random->nextRangeU(4, 4096), random->nextRangeU(4, 4096));
624    SkScalar baseFrequencyX = random->nextRangeScalar(0.01f,
625                                                      0.99f);
626    SkScalar baseFrequencyY = random->nextRangeScalar(0.01f,
627                                                      0.99f);
628
629    SkShader* shader = random->nextBool() ?
630        SkPerlinNoiseShader::CreateFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves, seed,
631                                                stitchTiles ? &tileSize : NULL) :
632        SkPerlinNoiseShader::CreateTurbulence(baseFrequencyX, baseFrequencyY, numOctaves, seed,
633                                             stitchTiles ? &tileSize : NULL);
634
635    SkPaint paint;
636    GrColor grColor;
637    GrEffectRef* effect;
638    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
639
640    SkDELETE(shader);
641
642    return effect;
643}
644
645GrGLPerlinNoise::GrGLPerlinNoise(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect)
646  : INHERITED (factory)
647  , fType(drawEffect.castEffect<GrPerlinNoiseEffect>().type())
648  , fStitchTiles(drawEffect.castEffect<GrPerlinNoiseEffect>().stitchTiles())
649  , fNumOctaves(drawEffect.castEffect<GrPerlinNoiseEffect>().numOctaves()) {
650}
651
652void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
653                               const GrDrawEffect&,
654                               EffectKey key,
655                               const char* outputColor,
656                               const char* inputColor,
657                               const TransformedCoordsArray& coords,
658                               const TextureSamplerArray& samplers) {
659    sk_ignore_unused_variable(inputColor);
660
661    SkString vCoords = builder->ensureFSCoords2D(coords, 0);
662
663    fInvMatrixUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
664                                        kMat33f_GrSLType, "invMatrix");
665    const char* invMatrixUni = builder->getUniformCStr(fInvMatrixUni);
666    fBaseFrequencyUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
667                                            kVec2f_GrSLType, "baseFrequency");
668    const char* baseFrequencyUni = builder->getUniformCStr(fBaseFrequencyUni);
669    fAlphaUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
670                                    kFloat_GrSLType, "alpha");
671    const char* alphaUni = builder->getUniformCStr(fAlphaUni);
672
673    const char* stitchDataUni = NULL;
674    if (fStitchTiles) {
675        fStitchDataUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
676                                             kVec2f_GrSLType, "stitchData");
677        stitchDataUni = builder->getUniformCStr(fStitchDataUni);
678    }
679
680    // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8
681    const char* chanCoordR  = "0.125";
682    const char* chanCoordG  = "0.375";
683    const char* chanCoordB  = "0.625";
684    const char* chanCoordA  = "0.875";
685    const char* chanCoord   = "chanCoord";
686    const char* stitchData  = "stitchData";
687    const char* ratio       = "ratio";
688    const char* noiseVec    = "noiseVec";
689    const char* noiseSmooth = "noiseSmooth";
690    const char* floorVal    = "floorVal";
691    const char* fractVal    = "fractVal";
692    const char* uv          = "uv";
693    const char* ab          = "ab";
694    const char* latticeIdx  = "latticeIdx";
695    const char* bcoords     = "bcoords";
696    const char* lattice     = "lattice";
697    const char* inc8bit     = "0.00390625";  // 1.0 / 256.0
698    // This is the math to convert the two 16bit integer packed into rgba 8 bit input into a
699    // [-1,1] vector and perform a dot product between that vector and the provided vector.
700    const char* dotLattice  = "dot(((%s.ga + %s.rb * vec2(%s)) * vec2(2.0) - vec2(1.0)), %s);";
701
702    // Add noise function
703    static const GrGLShaderVar gPerlinNoiseArgs[] =  {
704        GrGLShaderVar(chanCoord, kFloat_GrSLType),
705        GrGLShaderVar(noiseVec, kVec2f_GrSLType)
706    };
707
708    static const GrGLShaderVar gPerlinNoiseStitchArgs[] =  {
709        GrGLShaderVar(chanCoord, kFloat_GrSLType),
710        GrGLShaderVar(noiseVec, kVec2f_GrSLType),
711        GrGLShaderVar(stitchData, kVec2f_GrSLType)
712    };
713
714    SkString noiseCode;
715
716    noiseCode.appendf("\tvec4 %s;\n", floorVal);
717    noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec);
718    noiseCode.appendf("\t%s.zw = %s.xy + vec2(1.0);\n", floorVal, floorVal);
719    noiseCode.appendf("\tvec2 %s = fract(%s);\n", fractVal, noiseVec);
720
721    // smooth curve : t * t * (3 - 2 * t)
722    noiseCode.appendf("\n\tvec2 %s = %s * %s * (vec2(3.0) - vec2(2.0) * %s);",
723        noiseSmooth, fractVal, fractVal, fractVal);
724
725    // Adjust frequencies if we're stitching tiles
726    if (fStitchTiles) {
727        noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }",
728            floorVal, stitchData, floorVal, stitchData);
729        noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }",
730            floorVal, stitchData, floorVal, stitchData);
731        noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }",
732            floorVal, stitchData, floorVal, stitchData);
733        noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }",
734            floorVal, stitchData, floorVal, stitchData);
735    }
736
737    // Get texture coordinates and normalize
738    noiseCode.appendf("\n\t%s = fract(floor(mod(%s, 256.0)) / vec4(256.0));\n",
739        floorVal, floorVal);
740
741    // Get permutation for x
742    {
743        SkString xCoords("");
744        xCoords.appendf("vec2(%s.x, 0.5)", floorVal);
745
746        noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx);
747        builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
748        noiseCode.append(".r;");
749    }
750
751    // Get permutation for x + 1
752    {
753        SkString xCoords("");
754        xCoords.appendf("vec2(%s.z, 0.5)", floorVal);
755
756        noiseCode.appendf("\n\t%s.y = ", latticeIdx);
757        builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
758        noiseCode.append(".r;");
759    }
760
761#if defined(SK_BUILD_FOR_ANDROID)
762    // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Nexus 7 (Tegra 3).
763    // The issue is that colors aren't accurate enough on Tegra devices. For example, if an 8 bit
764    // value of 124 (or 0.486275 here) is entered, we can get a texture value of 123.513725
765    // (or 0.484368 here). The following rounding operation prevents these precision issues from
766    // affecting the result of the noise by making sure that we only have multiples of 1/255.
767    // (Note that 1/255 is about 0.003921569, which is the value used here).
768    noiseCode.appendf("\n\t%s = floor(%s * vec2(255.0) + vec2(0.5)) * vec2(0.003921569);",
769                      latticeIdx, latticeIdx);
770#endif
771
772    // Get (x,y) coordinates with the permutated x
773    noiseCode.appendf("\n\tvec4 %s = fract(%s.xyxy + %s.yyww);", bcoords, latticeIdx, floorVal);
774
775    noiseCode.appendf("\n\n\tvec2 %s;", uv);
776    // Compute u, at offset (0,0)
777    {
778        SkString latticeCoords("");
779        latticeCoords.appendf("vec2(%s.x, %s)", bcoords, chanCoord);
780        noiseCode.appendf("\n\tvec4 %s = ", lattice);
781        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
782            kVec2f_GrSLType);
783        noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
784        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
785    }
786
787    noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal);
788    // Compute v, at offset (-1,0)
789    {
790        SkString latticeCoords("");
791        latticeCoords.appendf("vec2(%s.y, %s)", bcoords, chanCoord);
792        noiseCode.append("\n\tlattice = ");
793        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
794            kVec2f_GrSLType);
795        noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
796        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
797    }
798
799    // Compute 'a' as a linear interpolation of 'u' and 'v'
800    noiseCode.appendf("\n\tvec2 %s;", ab);
801    noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth);
802
803    noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal);
804    // Compute v, at offset (-1,-1)
805    {
806        SkString latticeCoords("");
807        latticeCoords.appendf("vec2(%s.w, %s)", bcoords, chanCoord);
808        noiseCode.append("\n\tlattice = ");
809        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
810            kVec2f_GrSLType);
811        noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
812        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
813    }
814
815    noiseCode.appendf("\n\t%s.x += 1.0;", fractVal);
816    // Compute u, at offset (0,-1)
817    {
818        SkString latticeCoords("");
819        latticeCoords.appendf("vec2(%s.z, %s)", bcoords, chanCoord);
820        noiseCode.append("\n\tlattice = ");
821        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
822            kVec2f_GrSLType);
823        noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
824        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
825    }
826
827    // Compute 'b' as a linear interpolation of 'u' and 'v'
828    noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth);
829    // Compute the noise as a linear interpolation of 'a' and 'b'
830    noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth);
831
832    SkString noiseFuncName;
833    if (fStitchTiles) {
834        builder->fsEmitFunction(kFloat_GrSLType,
835                                "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitchArgs),
836                                gPerlinNoiseStitchArgs, noiseCode.c_str(), &noiseFuncName);
837    } else {
838        builder->fsEmitFunction(kFloat_GrSLType,
839                                "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs),
840                                gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncName);
841    }
842
843    // There are rounding errors if the floor operation is not performed here
844    builder->fsCodeAppendf("\n\t\tvec2 %s = floor((%s * vec3(%s, 1.0)).xy) * %s;",
845                           noiseVec, invMatrixUni, vCoords.c_str(), baseFrequencyUni);
846
847    // Clear the color accumulator
848    builder->fsCodeAppendf("\n\t\t%s = vec4(0.0);", outputColor);
849
850    if (fStitchTiles) {
851        // Set up TurbulenceInitial stitch values.
852        builder->fsCodeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni);
853    }
854
855    builder->fsCodeAppendf("\n\t\tfloat %s = 1.0;", ratio);
856
857    // Loop over all octaves
858    builder->fsCodeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {", fNumOctaves);
859
860    builder->fsCodeAppendf("\n\t\t\t%s += ", outputColor);
861    if (fType != SkPerlinNoiseShader::kFractalNoise_Type) {
862        builder->fsCodeAppend("abs(");
863    }
864    if (fStitchTiles) {
865        builder->fsCodeAppendf(
866            "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s),"
867                 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))",
868            noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData,
869            noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData,
870            noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData,
871            noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData);
872    } else {
873        builder->fsCodeAppendf(
874            "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s),"
875                 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))",
876            noiseFuncName.c_str(), chanCoordR, noiseVec,
877            noiseFuncName.c_str(), chanCoordG, noiseVec,
878            noiseFuncName.c_str(), chanCoordB, noiseVec,
879            noiseFuncName.c_str(), chanCoordA, noiseVec);
880    }
881    if (fType != SkPerlinNoiseShader::kFractalNoise_Type) {
882        builder->fsCodeAppendf(")"); // end of "abs("
883    }
884    builder->fsCodeAppendf(" * %s;", ratio);
885
886    builder->fsCodeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec);
887    builder->fsCodeAppendf("\n\t\t\t%s *= 0.5;", ratio);
888
889    if (fStitchTiles) {
890        builder->fsCodeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData);
891    }
892    builder->fsCodeAppend("\n\t\t}"); // end of the for loop on octaves
893
894    if (fType == SkPerlinNoiseShader::kFractalNoise_Type) {
895        // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
896        // by fractalNoise and (turbulenceFunctionResult) by turbulence.
897        builder->fsCodeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", outputColor, outputColor);
898    }
899
900    builder->fsCodeAppendf("\n\t\t%s.a *= %s;", outputColor, alphaUni);
901
902    // Clamp values
903    builder->fsCodeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", outputColor, outputColor);
904
905    // Pre-multiply the result
906    builder->fsCodeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
907                  outputColor, outputColor, outputColor, outputColor);
908}
909
910GrGLEffect::EffectKey GrGLPerlinNoise::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
911    const GrPerlinNoiseEffect& turbulence = drawEffect.castEffect<GrPerlinNoiseEffect>();
912
913    EffectKey key = turbulence.numOctaves();
914
915    key = key << 3; // Make room for next 3 bits
916
917    switch (turbulence.type()) {
918        case SkPerlinNoiseShader::kFractalNoise_Type:
919            key |= 0x1;
920            break;
921        case SkPerlinNoiseShader::kTurbulence_Type:
922            key |= 0x2;
923            break;
924        default:
925            // leave key at 0
926            break;
927    }
928
929    if (turbulence.stitchTiles()) {
930        key |= 0x4; // Flip the 3rd bit if tile stitching is on
931    }
932
933    return key;
934}
935
936void GrGLPerlinNoise::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
937    INHERITED::setData(uman, drawEffect);
938
939    const GrPerlinNoiseEffect& turbulence = drawEffect.castEffect<GrPerlinNoiseEffect>();
940
941    const SkVector& baseFrequency = turbulence.baseFrequency();
942    uman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY);
943    uman.set1f(fAlphaUni, SkScalarDiv(SkIntToScalar(turbulence.alpha()), SkIntToScalar(255)));
944
945    SkMatrix m = turbulence.matrix();
946    m.postTranslate(-SK_Scalar1, -SK_Scalar1);
947    SkMatrix invM;
948    if (!m.invert(&invM)) {
949        invM.reset();
950    } else {
951        invM.postConcat(invM); // Square the matrix
952    }
953    uman.setSkMatrix(fInvMatrixUni, invM);
954
955    if (turbulence.stitchTiles()) {
956        const SkPerlinNoiseShader::StitchData& stitchData = turbulence.stitchData();
957        uman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth),
958                                   SkIntToScalar(stitchData.fHeight));
959    }
960}
961
962/////////////////////////////////////////////////////////////////////
963
964bool SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& paint,
965                                      const SkMatrix* externalLocalMatrix, GrColor* grColor,
966                                      GrEffectRef** grEffect) const {
967    SkASSERT(NULL != context);
968
969    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
970
971    SkMatrix localMatrix = this->getLocalMatrix();
972    if (externalLocalMatrix) {
973        localMatrix.preConcat(*externalLocalMatrix);
974    }
975
976    if (0 == fNumOctaves) {
977        SkColor clearColor = 0;
978        if (kFractalNoise_Type == fType) {
979            clearColor = SkColorSetARGB(paint.getAlpha() / 2, 127, 127, 127);
980        }
981        SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(
982                                                clearColor, SkXfermode::kSrc_Mode));
983        *grEffect = cf->asNewEffect(context);
984        return true;
985    }
986
987    // Either we don't stitch tiles, either we have a valid tile size
988    SkASSERT(!fStitchTiles || !fTileSize.isEmpty());
989
990    GrTexture* permutationsTexture = GrLockAndRefCachedBitmapTexture(
991        context, fPaintingData->getPermutationsBitmap(), NULL);
992    GrTexture* noiseTexture = GrLockAndRefCachedBitmapTexture(
993        context, fPaintingData->getNoiseBitmap(), NULL);
994
995    *grEffect = (NULL != permutationsTexture) && (NULL != noiseTexture) ?
996        GrPerlinNoiseEffect::Create(fType, fPaintingData->fBaseFrequency,
997                                    fNumOctaves, fStitchTiles,
998                                    fPaintingData->fStitchDataInit,
999                                    permutationsTexture, noiseTexture,
1000                                    localMatrix, paint.getAlpha()) :
1001        NULL;
1002
1003    // Unlock immediately, this is not great, but we don't have a way of
1004    // knowing when else to unlock it currently. TODO: Remove this when
1005    // unref becomes the unlock replacement for all types of textures.
1006    if (NULL != permutationsTexture) {
1007        GrUnlockAndUnrefCachedBitmapTexture(permutationsTexture);
1008    }
1009    if (NULL != noiseTexture) {
1010        GrUnlockAndUnrefCachedBitmapTexture(noiseTexture);
1011    }
1012
1013    return true;
1014}
1015
1016#else
1017
1018bool SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& paint,
1019                                      const SkMatrix* externalLocalMatrix, GrColor* grColor,
1020                                      GrEffectRef** grEffect) const {
1021    SkDEBUGFAIL("Should not call in GPU-less build");
1022    return false;
1023}
1024
1025#endif
1026
1027#ifndef SK_IGNORE_TO_STRING
1028void SkPerlinNoiseShader::toString(SkString* str) const {
1029    str->append("SkPerlinNoiseShader: (");
1030
1031    str->append("type: ");
1032    switch (fType) {
1033        case kFractalNoise_Type:
1034            str->append("\"fractal noise\"");
1035            break;
1036        case kTurbulence_Type:
1037            str->append("\"turbulence\"");
1038            break;
1039        default:
1040            str->append("\"unknown\"");
1041            break;
1042    }
1043    str->append(" base frequency: (");
1044    str->appendScalar(fBaseFrequencyX);
1045    str->append(", ");
1046    str->appendScalar(fBaseFrequencyY);
1047    str->append(") number of octaves: ");
1048    str->appendS32(fNumOctaves);
1049    str->append(" seed: ");
1050    str->appendScalar(fSeed);
1051    str->append(" stitch tiles: ");
1052    str->append(fStitchTiles ? "true " : "false ");
1053
1054    this->INHERITED::toString(str);
1055
1056    str->append(")");
1057}
1058#endif
1059