17839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/*
27839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Copyright 2013 Google Inc.
37839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *
47839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be
57839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * found in the LICENSE file.
67839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */
77839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
87839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkDither.h"
97839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkPerlinNoiseShader.h"
10910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#include "SkColorFilter.h"
117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkFlattenableBuffers.h"
127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkShader.h"
137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkUnPreMultiply.h"
147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkString.h"
157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if SK_SUPPORT_GPU
177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "GrContext.h"
180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "GrCoordTransform.h"
197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "gl/GrGLEffect.h"
207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "GrTBackendEffectFactory.h"
217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkGr.h"
227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic const int kBlockSize = 256;
257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic const int kBlockMask = kBlockSize - 1;
267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic const int kPerlinNoise = 4096;
277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic const int kRandMaximum = SK_MaxS32; // 2**31 - 1
287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergernamespace {
307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// noiseValue is the color component's value (or color)
327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// limitValue is the maximum perlin noise array index value allowed
337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// newValue is the current noise dimension (either width or height)
347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerinline int checkNoise(int noiseValue, int limitValue, int newValue) {
357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // If the noise value would bring us out of bounds of the current noise array while we are
367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // stiching noise tiles together, wrap the noise around the current dimension of the noise to
377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // stay within the array bounds in a continuous fashion (so that tiling lines are not visible)
387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (noiseValue >= limitValue) {
397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseValue -= newValue;
407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (noiseValue >= limitValue - 1) {
427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseValue -= newValue - 1;
437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return noiseValue;
457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerinline SkScalar smoothCurve(SkScalar t) {
48910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    static const SkScalar SK_Scalar3 = 3.0f;
497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // returns t * t * (3 - 2 * t)
517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkScalarMul(SkScalarSquare(t), SK_Scalar3 - 2 * t);
527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
54910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergerbool perlin_noise_type_is_valid(SkPerlinNoiseShader::Type type) {
55910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    return (SkPerlinNoiseShader::kFractalNoise_Type == type) ||
56910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger           (SkPerlinNoiseShader::kTurbulence_Type == type);
57910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger}
58910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger
597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} // end namespace
607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstruct SkPerlinNoiseShader::StitchData {
627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    StitchData()
637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : fWidth(0)
647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fWrapX(0)
657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fHeight(0)
667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fWrapY(0)
677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {}
687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool operator==(const StitchData& other) const {
707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fWidth == other.fWidth &&
717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fWrapX == other.fWrapX &&
727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fHeight == other.fHeight &&
737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fWrapY == other.fWrapY;
747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int fWidth; // How much to subtract to wrap for stitching.
777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int fWrapX; // Minimum value to wrap.
787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int fHeight;
797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int fWrapY;
807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstruct SkPerlinNoiseShader::PaintingData {
837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    PaintingData(const SkISize& tileSize)
847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : fSeed(0)
857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fTileSize(tileSize)
867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fPermutationsBitmap(NULL)
877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fNoiseBitmap(NULL)
887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {}
897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    ~PaintingData()
917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkDELETE(fPermutationsBitmap);
937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkDELETE(fNoiseBitmap);
947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int         fSeed;
977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uint8_t     fLatticeSelector[kBlockSize];
987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uint16_t    fNoise[4][kBlockSize][2];
997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint     fGradient[4][kBlockSize];
1007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkISize     fTileSize;
1017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkVector    fBaseFrequency;
1027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    StitchData  fStitchDataInit;
1037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
1057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkBitmap*    fPermutationsBitmap;
1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkBitmap*    fNoiseBitmap;
1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
1107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    inline int random()  {
1127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        static const int gRandAmplitude = 16807; // 7**5; primitive root of m
1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        static const int gRandQ = 127773; // m / a
1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        static const int gRandR = 2836; // m % a
1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int result = gRandAmplitude * (fSeed % gRandQ) - gRandR * (fSeed / gRandQ);
1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (result <= 0)
1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            result += kRandMaximum;
1197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fSeed = result;
1207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return result;
1217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void init(SkScalar seed)
1247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
1257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        static const SkScalar gInvBlockSizef = SkScalarInvert(SkIntToScalar(kBlockSize));
1267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // The seed value clamp to the range [1, kRandMaximum - 1].
1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fSeed = SkScalarRoundToInt(seed);
1297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (fSeed <= 0) {
1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fSeed = -(fSeed % (kRandMaximum - 1)) + 1;
1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (fSeed > kRandMaximum - 1) {
1337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fSeed = kRandMaximum - 1;
1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int channel = 0; channel < 4; ++channel) {
1367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            for (int i = 0; i < kBlockSize; ++i) {
1377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fLatticeSelector[i] = i;
1387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fNoise[channel][i][0] = (random() % (2 * kBlockSize));
1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fNoise[channel][i][1] = (random() % (2 * kBlockSize));
1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int i = kBlockSize - 1; i > 0; --i) {
1437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            int k = fLatticeSelector[i];
1447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            int j = random() % kBlockSize;
1457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkASSERT(j >= 0);
1467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkASSERT(j < kBlockSize);
1477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fLatticeSelector[i] = fLatticeSelector[j];
1487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fLatticeSelector[j] = k;
1497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Perform the permutations now
1527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        {
1537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // Copy noise data
1547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            uint16_t noise[4][kBlockSize][2];
1557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            for (int i = 0; i < kBlockSize; ++i) {
1567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                for (int channel = 0; channel < 4; ++channel) {
1577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    for (int j = 0; j < 2; ++j) {
1587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        noise[channel][i][j] = fNoise[channel][i][j];
1597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    }
1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                }
1617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
1627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // Do permutations on noise data
1637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            for (int i = 0; i < kBlockSize; ++i) {
1647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                for (int channel = 0; channel < 4; ++channel) {
1657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    for (int j = 0; j < 2; ++j) {
1667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        fNoise[channel][i][j] = noise[channel][fLatticeSelector[i]][j];
1677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    }
1687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                }
1697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
1707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Half of the largest possible value for 16 bit unsigned int
173910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        static const SkScalar gHalfMax16bits = 32767.5f;
1747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Compute gradients from permutated noise data
1767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int channel = 0; channel < 4; ++channel) {
1777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            for (int i = 0; i < kBlockSize; ++i) {
1787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fGradient[channel][i] = SkPoint::Make(
1797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    SkScalarMul(SkIntToScalar(fNoise[channel][i][0] - kBlockSize),
1807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                gInvBlockSizef),
1817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    SkScalarMul(SkIntToScalar(fNoise[channel][i][1] - kBlockSize),
1827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                gInvBlockSizef));
1837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fGradient[channel][i].normalize();
1847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                // Put the normalized gradient back into the noise data
1857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fNoise[channel][i][0] = SkScalarRoundToInt(SkScalarMul(
18658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                    fGradient[channel][i].fX + SK_Scalar1, gHalfMax16bits));
1877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fNoise[channel][i][1] = SkScalarRoundToInt(SkScalarMul(
18858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                    fGradient[channel][i].fY + SK_Scalar1, gHalfMax16bits));
1897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
1907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Invalidate bitmaps
1937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkDELETE(fPermutationsBitmap);
1947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fPermutationsBitmap = NULL;
1957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkDELETE(fNoiseBitmap);
1967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fNoiseBitmap = NULL;
1977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void stitch() {
2007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkScalar tileWidth  = SkIntToScalar(fTileSize.width());
2017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkScalar tileHeight = SkIntToScalar(fTileSize.height());
2027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkASSERT(tileWidth > 0 && tileHeight > 0);
2037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // When stitching tiled turbulence, the frequencies must be adjusted
2047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // so that the tile borders will be continuous.
2057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (fBaseFrequency.fX) {
2067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalar lowFrequencx = SkScalarDiv(
2077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkScalarMulFloor(tileWidth, fBaseFrequency.fX), tileWidth);
2087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalar highFrequencx = SkScalarDiv(
2097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkScalarMulCeil(tileWidth, fBaseFrequency.fX), tileWidth);
2107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // BaseFrequency should be non-negative according to the standard.
2117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            if (SkScalarDiv(fBaseFrequency.fX, lowFrequencx) <
2127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkScalarDiv(highFrequencx, fBaseFrequency.fX)) {
2137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fBaseFrequency.fX = lowFrequencx;
2147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            } else {
2157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fBaseFrequency.fX = highFrequencx;
2167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
2177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (fBaseFrequency.fY) {
2197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalar lowFrequency = SkScalarDiv(
2207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkScalarMulFloor(tileHeight, fBaseFrequency.fY), tileHeight);
2217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalar highFrequency = SkScalarDiv(
2227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkScalarMulCeil(tileHeight, fBaseFrequency.fY), tileHeight);
2237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            if (SkScalarDiv(fBaseFrequency.fY, lowFrequency) <
2247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkScalarDiv(highFrequency, fBaseFrequency.fY)) {
2257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fBaseFrequency.fY = lowFrequency;
2267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            } else {
2277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fBaseFrequency.fY = highFrequency;
2287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
2297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Set up TurbulenceInitial stitch values.
2317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fStitchDataInit.fWidth  =
2327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalarMulRound(tileWidth, fBaseFrequency.fX);
2337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fStitchDataInit.fWrapX  = kPerlinNoise + fStitchDataInit.fWidth;
2347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fStitchDataInit.fHeight =
2357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalarMulRound(tileHeight, fBaseFrequency.fY);
2367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fStitchDataInit.fWrapY  = kPerlinNoise + fStitchDataInit.fHeight;
2377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkBitmap* getPermutationsBitmap()
2407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
2417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (!fPermutationsBitmap) {
2427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fPermutationsBitmap = SkNEW(SkBitmap);
2437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fPermutationsBitmap->setConfig(SkBitmap::kA8_Config, kBlockSize, 1);
2447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fPermutationsBitmap->allocPixels();
2457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            uint8_t* bitmapPixels = fPermutationsBitmap->getAddr8(0, 0);
2467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            memcpy(bitmapPixels, fLatticeSelector, sizeof(uint8_t) * kBlockSize);
2477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fPermutationsBitmap;
2497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkBitmap* getNoiseBitmap()
2527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
2537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (!fNoiseBitmap) {
2547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fNoiseBitmap = SkNEW(SkBitmap);
2557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fNoiseBitmap->setConfig(SkBitmap::kARGB_8888_Config, kBlockSize, 4);
2567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fNoiseBitmap->allocPixels();
2577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            uint32_t* bitmapPixels = fNoiseBitmap->getAddr32(0, 0);
2587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            memcpy(bitmapPixels, fNoise[0][0], sizeof(uint16_t) * kBlockSize * 4 * 2);
2597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fNoiseBitmap;
2617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
2637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkShader* SkPerlinNoiseShader::CreateFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY,
2657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                  int numOctaves, SkScalar seed,
2667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                  const SkISize* tileSize) {
2677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkNEW_ARGS(SkPerlinNoiseShader, (kFractalNoise_Type, baseFrequencyX, baseFrequencyY,
2687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                            numOctaves, seed, tileSize));
2697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
2707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkShader* SkPerlinNoiseShader::CreateTubulence(SkScalar baseFrequencyX, SkScalar baseFrequencyY,
2727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                              int numOctaves, SkScalar seed,
2737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                              const SkISize* tileSize) {
2747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkNEW_ARGS(SkPerlinNoiseShader, (kTurbulence_Type, baseFrequencyX, baseFrequencyY,
2757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                            numOctaves, seed, tileSize));
2767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
2777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkPerlinNoiseShader::SkPerlinNoiseShader(SkPerlinNoiseShader::Type type,
2797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                         SkScalar baseFrequencyX,
2807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                         SkScalar baseFrequencyY,
2817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                         int numOctaves,
2827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                         SkScalar seed,
2837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                         const SkISize* tileSize)
2847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  : fType(type)
2857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fBaseFrequencyX(baseFrequencyX)
2867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fBaseFrequencyY(baseFrequencyY)
287910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger  , fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/)
2887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fSeed(seed)
2897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fStitchTiles((tileSize != NULL) && !tileSize->isEmpty())
2907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fPaintingData(NULL)
2917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger{
2927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(numOctaves >= 0 && numOctaves < 256);
2937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    setTileSize(fStitchTiles ? *tileSize : SkISize::Make(0,0));
2947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fMatrix.reset();
2957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
2967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkPerlinNoiseShader::SkPerlinNoiseShader(SkFlattenableReadBuffer& buffer) :
2987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        INHERITED(buffer), fPaintingData(NULL) {
2997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fType           = (SkPerlinNoiseShader::Type) buffer.readInt();
3007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fBaseFrequencyX = buffer.readScalar();
3017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fBaseFrequencyY = buffer.readScalar();
3027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fNumOctaves     = buffer.readInt();
3037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fSeed           = buffer.readScalar();
3047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fStitchTiles    = buffer.readBool();
3057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fTileSize.fWidth  = buffer.readInt();
3067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fTileSize.fHeight = buffer.readInt();
3077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    setTileSize(fTileSize);
3087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fMatrix.reset();
309910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    buffer.validate(perlin_noise_type_is_valid(fType) &&
310910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                    (fNumOctaves >= 0) && (fNumOctaves <= 255));
3117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkPerlinNoiseShader::~SkPerlinNoiseShader() {
3147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Safety, should have been done in endContext()
3157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkDELETE(fPaintingData);
3167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPerlinNoiseShader::flatten(SkFlattenableWriteBuffer& buffer) const {
3197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    this->INHERITED::flatten(buffer);
3207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeInt((int) fType);
3217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeScalar(fBaseFrequencyX);
3227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeScalar(fBaseFrequencyY);
3237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeInt(fNumOctaves);
3247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeScalar(fSeed);
3257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeBool(fStitchTiles);
3267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeInt(fTileSize.fWidth);
3277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeInt(fTileSize.fHeight);
3287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPerlinNoiseShader::initPaint(PaintingData& paintingData)
3317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger{
3327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    paintingData.init(fSeed);
3337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Set frequencies to original values
3357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    paintingData.fBaseFrequency.set(fBaseFrequencyX, fBaseFrequencyY);
3367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Adjust frequecies based on size if stitching is enabled
3377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fStitchTiles) {
3387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        paintingData.stitch();
3397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
3407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPerlinNoiseShader::setTileSize(const SkISize& tileSize) {
3437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fTileSize = tileSize;
3447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (NULL == fPaintingData) {
3467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize));
3477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        initPaint(*fPaintingData);
3487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    } else {
3497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Set Size
3507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fPaintingData->fTileSize = fTileSize;
3517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Set frequencies to original values
3527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fPaintingData->fBaseFrequency.set(fBaseFrequencyX, fBaseFrequencyY);
3537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Adjust frequecies based on size if stitching is enabled
3547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (fStitchTiles) {
3557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fPaintingData->stitch();
3567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
3577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
3587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkScalar SkPerlinNoiseShader::noise2D(int channel, const PaintingData& paintingData,
3617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                     const StitchData& stitchData, const SkPoint& noiseVector)
3627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger{
3637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    struct Noise {
3647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int noisePositionIntegerValue;
3657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkScalar noisePositionFractionValue;
3667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        Noise(SkScalar component)
3677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        {
3687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalar position = component + kPerlinNoise;
3697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            noisePositionIntegerValue = SkScalarFloorToInt(position);
3707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            noisePositionFractionValue = position - SkIntToScalar(noisePositionIntegerValue);
3717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
3727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
3737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    Noise noiseX(noiseVector.x());
3747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    Noise noiseY(noiseVector.y());
3757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar u, v;
3767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // If stitching, adjust lattice points accordingly.
3777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fStitchTiles) {
3787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseX.noisePositionIntegerValue =
3797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth);
3807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseY.noisePositionIntegerValue =
3817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight);
3827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
3837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    noiseX.noisePositionIntegerValue &= kBlockMask;
3847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    noiseY.noisePositionIntegerValue &= kBlockMask;
3857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int latticeIndex =
3867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        paintingData.fLatticeSelector[noiseX.noisePositionIntegerValue] +
3877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseY.noisePositionIntegerValue;
3887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int nextLatticeIndex =
3897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        paintingData.fLatticeSelector[(noiseX.noisePositionIntegerValue + 1) & kBlockMask] +
3907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseY.noisePositionIntegerValue;
3917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar sx = smoothCurve(noiseX.noisePositionFractionValue);
3927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar sy = smoothCurve(noiseY.noisePositionFractionValue);
3937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement
3947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue,
3957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                          noiseY.noisePositionFractionValue); // Offset (0,0)
3967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    u = paintingData.fGradient[channel][latticeIndex & kBlockMask].dot(fractionValue);
3977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fractionValue.fX -= SK_Scalar1; // Offset (-1,0)
3987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    v = paintingData.fGradient[channel][nextLatticeIndex & kBlockMask].dot(fractionValue);
3997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar a = SkScalarInterp(u, v, sx);
4007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fractionValue.fY -= SK_Scalar1; // Offset (-1,-1)
4017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    v = paintingData.fGradient[channel][(nextLatticeIndex + 1) & kBlockMask].dot(fractionValue);
4027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1)
4037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    u = paintingData.fGradient[channel][(latticeIndex + 1) & kBlockMask].dot(fractionValue);
4047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar b = SkScalarInterp(u, v, sx);
4057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkScalarInterp(a, b, sy);
4067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
4077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkScalar SkPerlinNoiseShader::calculateTurbulenceValueForPoint(
4097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int channel, const PaintingData& paintingData, StitchData& stitchData, const SkPoint& point)
4107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger{
4117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fStitchTiles) {
4127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Set up TurbulenceInitial stitch values.
4137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        stitchData = paintingData.fStitchDataInit;
4147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar turbulenceFunctionResult = 0;
4167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint noiseVector(SkPoint::Make(SkScalarMul(point.x(), paintingData.fBaseFrequency.fX),
4177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                      SkScalarMul(point.y(), paintingData.fBaseFrequency.fY)));
4187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar ratio = SK_Scalar1;
4197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int octave = 0; octave < fNumOctaves; ++octave) {
4207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkScalar noise = noise2D(channel, paintingData, stitchData, noiseVector);
4217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        turbulenceFunctionResult += SkScalarDiv(
4227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            (fType == kFractalNoise_Type) ? noise : SkScalarAbs(noise), ratio);
4237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseVector.fX *= 2;
4247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseVector.fY *= 2;
4257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        ratio *= 2;
4267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (fStitchTiles) {
4277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // Update stitch values
4287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            stitchData.fWidth  *= 2;
4297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            stitchData.fWrapX   = stitchData.fWidth + kPerlinNoise;
4307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            stitchData.fHeight *= 2;
4317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            stitchData.fWrapY   = stitchData.fHeight + kPerlinNoise;
4327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
4337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
4367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // by fractalNoise and (turbulenceFunctionResult) by turbulence.
4377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fType == kFractalNoise_Type) {
4387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        turbulenceFunctionResult =
4397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalarMul(turbulenceFunctionResult, SK_ScalarHalf) + SK_ScalarHalf;
4407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (channel == 3) { // Scale alpha by paint value
4437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        turbulenceFunctionResult = SkScalarMul(turbulenceFunctionResult,
4447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalarDiv(SkIntToScalar(getPaintAlpha()), SkIntToScalar(255)));
4457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Clamp result
4487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1);
4497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
4507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkPMColor SkPerlinNoiseShader::shade(const SkPoint& point, StitchData& stitchData) {
4527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkMatrix matrix = fMatrix;
4537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkMatrix invMatrix;
4547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (!matrix.invert(&invMatrix)) {
4557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        invMatrix.reset();
4567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    } else {
4577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        invMatrix.postConcat(invMatrix); // Square the matrix
4587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // This (1,1) translation is due to WebKit's 1 based coordinates for the noise
4607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // (as opposed to 0 based, usually). The same adjustment is in the setData() function.
4617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    matrix.postTranslate(SK_Scalar1, SK_Scalar1);
4627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint newPoint;
4637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    matrix.mapPoints(&newPoint, &point, 1);
4647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    invMatrix.mapPoints(&newPoint, &newPoint, 1);
4657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    newPoint.fX = SkScalarRoundToScalar(newPoint.fX);
4667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    newPoint.fY = SkScalarRoundToScalar(newPoint.fY);
4677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    U8CPU rgba[4];
4697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int channel = 3; channel >= 0; --channel) {
4707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        rgba[channel] = SkScalarFloorToInt(255 *
4717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            calculateTurbulenceValueForPoint(channel, *fPaintingData, stitchData, newPoint));
4727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
4747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
4757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerbool SkPerlinNoiseShader::setContext(const SkBitmap& device, const SkPaint& paint,
4777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                     const SkMatrix& matrix) {
4787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fMatrix = matrix;
4797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return INHERITED::setContext(device, paint, matrix);
4807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
4817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPerlinNoiseShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
4837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
4847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    StitchData stitchData;
4857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int i = 0; i < count; ++i) {
4867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        result[i] = shade(point, stitchData);
4877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        point.fX += SK_Scalar1;
4887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
4907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPerlinNoiseShader::shadeSpan16(int x, int y, uint16_t result[], int count) {
4927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
4937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    StitchData stitchData;
4947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    DITHER_565_SCAN(y);
4957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int i = 0; i < count; ++i) {
4967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        unsigned dither = DITHER_VALUE(x);
4977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        result[i] = SkDitherRGB32To565(shade(point, stitchData), dither);
4987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        DITHER_INC_X(x);
4997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        point.fX += SK_Scalar1;
5007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
5027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/////////////////////////////////////////////////////////////////////
5047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
50558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if SK_SUPPORT_GPU
5067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "GrTBackendEffectFactory.h"
5087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrGLNoise : public GrGLEffect {
5107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
5117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLNoise(const GrBackendEffectFactory& factory,
5127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger              const GrDrawEffect& drawEffect);
5137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual ~GrGLNoise() {}
5147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
5167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
5187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprotected:
5207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPerlinNoiseShader::Type           fType;
5217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool                                fStitchTiles;
5227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int                                 fNumOctaves;
5237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle   fBaseFrequencyUni;
5247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle   fAlphaUni;
5257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle   fInvMatrixUni;
5267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
5287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrGLEffect INHERITED;
5297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
5307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrGLPerlinNoise : public GrGLNoise {
5327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
5337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLPerlinNoise(const GrBackendEffectFactory& factory,
5347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    const GrDrawEffect& drawEffect)
5357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : GrGLNoise(factory, drawEffect) {}
5367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual ~GrGLPerlinNoise() {}
5377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual void emitCode(GrGLShaderBuilder*,
5397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const GrDrawEffect&,
5407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          EffectKey,
5417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const char* outputColor,
5427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const char* inputColor,
5430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                          const TransformedCoordsArray&,
5447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const TextureSamplerArray&) SK_OVERRIDE;
5457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
5477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
5497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle fStitchDataUni;
5507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrGLNoise INHERITED;
5527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
5537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrGLSimplexNoise : public GrGLNoise {
5557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Note : This is for reference only. GrGLPerlinNoise is used for processing.
5567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
5577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLSimplexNoise(const GrBackendEffectFactory& factory,
5587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                     const GrDrawEffect& drawEffect)
5597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : GrGLNoise(factory, drawEffect) {}
5607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual ~GrGLSimplexNoise() {}
5627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual void emitCode(GrGLShaderBuilder*,
5647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const GrDrawEffect&,
5657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          EffectKey,
5667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const char* outputColor,
5677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const char* inputColor,
5680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                          const TransformedCoordsArray&,
5697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const TextureSamplerArray&) SK_OVERRIDE;
5707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
5727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
5747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle fSeedUni;
5757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrGLNoise INHERITED;
5777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
5787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/////////////////////////////////////////////////////////////////////
5807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrNoiseEffect : public GrEffect {
5827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
5837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual ~GrNoiseEffect() { }
5847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPerlinNoiseShader::Type type() const { return fType; }
5867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool stitchTiles() const { return fStitchTiles; }
5877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkVector& baseFrequency() const { return fBaseFrequency; }
5887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int numOctaves() const { return fNumOctaves; }
5890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); }
5907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uint8_t alpha() const { return fAlpha; }
5917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void getConstantColorComponents(GrColor*, uint32_t* validFlags) const SK_OVERRIDE {
5937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        *validFlags = 0; // This is noise. Nothing is constant.
5947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprotected:
5977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
5987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const GrNoiseEffect& s = CastEffect<GrNoiseEffect>(sBase);
5997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fType == s.fType &&
6007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fBaseFrequency == s.fBaseFrequency &&
6017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fNumOctaves == s.fNumOctaves &&
6027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fStitchTiles == s.fStitchTiles &&
6030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger               fCoordTransform.getMatrix() == s.fCoordTransform.getMatrix() &&
6047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fAlpha == s.fAlpha;
6057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrNoiseEffect(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency, int numOctaves,
6087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                  bool stitchTiles, const SkMatrix& matrix, uint8_t alpha)
6097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : fType(type)
6107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fBaseFrequency(baseFrequency)
6117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fNumOctaves(numOctaves)
6127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fStitchTiles(stitchTiles)
6137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fMatrix(matrix)
6147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fAlpha(alpha) {
6150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        // This (1,1) translation is due to WebKit's 1 based coordinates for the noise
6160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        // (as opposed to 0 based, usually). The same adjustment is in the shadeSpan() functions.
6170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkMatrix m = matrix;
6180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        m.postTranslate(SK_Scalar1, SK_Scalar1);
6190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fCoordTransform.reset(kLocal_GrCoordSet, m);
6200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        this->addCoordTransform(&fCoordTransform);
6210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        this->setWillNotUseInputColor();
6227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPerlinNoiseShader::Type       fType;
6250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GrCoordTransform                fCoordTransform;
6267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkVector                        fBaseFrequency;
6277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int                             fNumOctaves;
6287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool                            fStitchTiles;
6297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkMatrix                        fMatrix;
6307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uint8_t                         fAlpha;
6317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
6337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrEffect INHERITED;
6347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
6357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrPerlinNoiseEffect : public GrNoiseEffect {
6377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
6387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static GrEffectRef* Create(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency,
6397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               int numOctaves, bool stitchTiles,
6407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const SkPerlinNoiseShader::StitchData& stitchData,
6417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               GrTexture* permutationsTexture, GrTexture* noiseTexture,
6427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const SkMatrix& matrix, uint8_t alpha) {
6437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        AutoEffectUnref effect(SkNEW_ARGS(GrPerlinNoiseEffect, (type, baseFrequency, numOctaves,
6447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            stitchTiles, stitchData, permutationsTexture, noiseTexture, matrix, alpha)));
6457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return CreateEffectRef(effect);
6467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual ~GrPerlinNoiseEffect() { }
6497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static const char* Name() { return "PerlinNoise"; }
6517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
6527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return GrTBackendEffectFactory<GrPerlinNoiseEffect>::getInstance();
6537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkPerlinNoiseShader::StitchData& stitchData() const { return fStitchData; }
6557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrGLPerlinNoise GLEffect;
6577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
6597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
6607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const GrPerlinNoiseEffect& s = CastEffect<GrPerlinNoiseEffect>(sBase);
6617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return INHERITED::onIsEqual(sBase) &&
6627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fPermutationsAccess.getTexture() == s.fPermutationsAccess.getTexture() &&
6637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fNoiseAccess.getTexture() == s.fNoiseAccess.getTexture() &&
6647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fStitchData == s.fStitchData;
6657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrPerlinNoiseEffect(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency,
6687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        int numOctaves, bool stitchTiles,
6697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        const SkPerlinNoiseShader::StitchData& stitchData,
6707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        GrTexture* permutationsTexture, GrTexture* noiseTexture,
6717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        const SkMatrix& matrix, uint8_t alpha)
6727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : GrNoiseEffect(type, baseFrequency, numOctaves, stitchTiles, matrix, alpha)
6737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fPermutationsAccess(permutationsTexture)
6747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fNoiseAccess(noiseTexture)
6757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fStitchData(stitchData) {
6767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        this->addTextureAccess(&fPermutationsAccess);
6777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        this->addTextureAccess(&fNoiseAccess);
6787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GR_DECLARE_EFFECT_TEST;
6817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrTextureAccess                 fPermutationsAccess;
6837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrTextureAccess                 fNoiseAccess;
6847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPerlinNoiseShader::StitchData fStitchData;
6857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrNoiseEffect INHERITED;
6877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
6887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrSimplexNoiseEffect : public GrNoiseEffect {
6907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Note : This is for reference only. GrPerlinNoiseEffect is used for processing.
6917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
6927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static GrEffectRef* Create(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency,
6937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               int numOctaves, bool stitchTiles, const SkScalar seed,
6947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const SkMatrix& matrix, uint8_t alpha) {
6957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        AutoEffectUnref effect(SkNEW_ARGS(GrSimplexNoiseEffect, (type, baseFrequency, numOctaves,
6967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            stitchTiles, seed, matrix, alpha)));
6977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return CreateEffectRef(effect);
6987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual ~GrSimplexNoiseEffect() { }
7017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static const char* Name() { return "SimplexNoise"; }
7037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
7047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return GrTBackendEffectFactory<GrSimplexNoiseEffect>::getInstance();
7057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
7067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkScalar& seed() const { return fSeed; }
7077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrGLSimplexNoise GLEffect;
7097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
7117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
7127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const GrSimplexNoiseEffect& s = CastEffect<GrSimplexNoiseEffect>(sBase);
7137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return INHERITED::onIsEqual(sBase) && fSeed == s.fSeed;
7147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
7157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrSimplexNoiseEffect(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency,
7177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                         int numOctaves, bool stitchTiles, const SkScalar seed,
7187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                         const SkMatrix& matrix, uint8_t alpha)
7197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : GrNoiseEffect(type, baseFrequency, numOctaves, stitchTiles, matrix, alpha)
7207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fSeed(seed) {
7217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
7227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar fSeed;
7247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrNoiseEffect INHERITED;
7267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
7277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/////////////////////////////////////////////////////////////////////
7297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGR_DEFINE_EFFECT_TEST(GrPerlinNoiseEffect);
7307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7310a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerGrEffectRef* GrPerlinNoiseEffect::TestCreate(SkRandom* random,
7327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                             GrContext* context,
7337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                             const GrDrawTargetCaps&,
7347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                             GrTexture**) {
7357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int      numOctaves = random->nextRangeU(2, 10);
7367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool     stitchTiles = random->nextBool();
7377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar seed = SkIntToScalar(random->nextU());
7387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkISize  tileSize = SkISize::Make(random->nextRangeU(4, 4096), random->nextRangeU(4, 4096));
739910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    SkScalar baseFrequencyX = random->nextRangeScalar(0.01f,
740910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                                                      0.99f);
741910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    SkScalar baseFrequencyY = random->nextRangeScalar(0.01f,
742910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                                                      0.99f);
7437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkShader* shader = random->nextBool() ?
7457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkPerlinNoiseShader::CreateFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves, seed,
7467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                stitchTiles ? &tileSize : NULL) :
7477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkPerlinNoiseShader::CreateTubulence(baseFrequencyX, baseFrequencyY, numOctaves, seed,
7487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                             stitchTiles ? &tileSize : NULL);
7497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPaint paint;
7517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrEffectRef* effect = shader->asNewEffect(context, paint);
7527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkDELETE(shader);
7547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return effect;
7567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
7577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/////////////////////////////////////////////////////////////////////
7597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrGLSimplexNoise::emitCode(GrGLShaderBuilder* builder,
7617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                const GrDrawEffect&,
7627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                EffectKey key,
7637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                const char* outputColor,
7647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                const char* inputColor,
7650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                const TransformedCoordsArray& coords,
7667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                const TextureSamplerArray&) {
7677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    sk_ignore_unused_variable(inputColor);
7687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString vCoords = builder->ensureFSCoords2D(coords, 0);
7707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    fSeedUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
7727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                   kFloat_GrSLType, "seed");
7737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* seedUni = builder->getUniformCStr(fSeedUni);
7740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    fInvMatrixUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
7757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                        kMat33f_GrSLType, "invMatrix");
7767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* invMatrixUni = builder->getUniformCStr(fInvMatrixUni);
7770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    fBaseFrequencyUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
7787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                            kVec2f_GrSLType, "baseFrequency");
7797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* baseFrequencyUni = builder->getUniformCStr(fBaseFrequencyUni);
7800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    fAlphaUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
7817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                    kFloat_GrSLType, "alpha");
7827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* alphaUni = builder->getUniformCStr(fAlphaUni);
7837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Add vec3 modulo 289 function
78558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    static const GrGLShaderVar gVec3Args[] =  {
7867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrGLShaderVar("x", kVec3f_GrSLType)
7877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
7887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkString mod289_3_funcName;
7900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    builder->fsEmitFunction(kVec3f_GrSLType,
7910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            "mod289", SK_ARRAY_COUNT(gVec3Args), gVec3Args,
7920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            "const vec2 C = vec2(1.0 / 289.0, 289.0);\n"
7930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            "return x - floor(x * C.xxx) * C.yyy;", &mod289_3_funcName);
7947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Add vec4 modulo 289 function
79658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    static const GrGLShaderVar gVec4Args[] =  {
7977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrGLShaderVar("x", kVec4f_GrSLType)
7987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
7997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkString mod289_4_funcName;
8010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    builder->fsEmitFunction(kVec4f_GrSLType,
8020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            "mod289", SK_ARRAY_COUNT(gVec4Args), gVec4Args,
8030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            "const vec2 C = vec2(1.0 / 289.0, 289.0);\n"
8040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            "return x - floor(x * C.xxxx) * C.yyyy;", &mod289_4_funcName);
8057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Add vec4 permute function
80758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString permuteCode;
80858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    permuteCode.appendf("const vec2 C = vec2(34.0, 1.0);\n"
80958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                        "return %s(((x * C.xxxx) + C.yyyy) * x);", mod289_4_funcName.c_str());
81058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString permuteFuncName;
8110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    builder->fsEmitFunction(kVec4f_GrSLType,
8120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            "permute", SK_ARRAY_COUNT(gVec4Args), gVec4Args,
8130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            permuteCode.c_str(), &permuteFuncName);
8147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Add vec4 taylorInvSqrt function
81658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString taylorInvSqrtFuncName;
8170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    builder->fsEmitFunction(kVec4f_GrSLType,
8180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            "taylorInvSqrt", SK_ARRAY_COUNT(gVec4Args), gVec4Args,
8190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            "const vec2 C = vec2(-0.85373472095314, 1.79284291400159);\n"
8200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            "return x * C.xxxx + C.yyyy;", &taylorInvSqrtFuncName);
8217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Add vec3 noise function
82358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    static const GrGLShaderVar gNoiseVec3Args[] =  {
8247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrGLShaderVar("v", kVec3f_GrSLType)
8257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
8267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
82758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString noiseCode;
82858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.append(
8297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "const vec2 C = vec2(1.0/6.0, 1.0/3.0);\n"
8307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n"
8317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // First corner
8337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 i = floor(v + dot(v, C.yyy));\n"
8347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 x0 = v - i + dot(i, C.xxx);\n"
8357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Other corners
8377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 g = step(x0.yzx, x0.xyz);\n"
8387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 l = 1.0 - g;\n"
8397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 i1 = min(g.xyz, l.zxy);\n"
8407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 i2 = max(g.xyz, l.zxy);\n"
8417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 x1 = x0 - i1 + C.xxx;\n"
8437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 x2 = x0 - i2 + C.yyy;\n" // 2.0*C.x = 1/3 = C.y
8447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 x3 = x0 - D.yyy;\n" // -1.0+3.0*C.x = -0.5 = -D.y
8457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    );
8467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
84758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf(
8487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Permutations
8497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "i = %s(i);\n"
8507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 p = %s(%s(%s(\n"
8517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "         i.z + vec4(0.0, i1.z, i2.z, 1.0)) +\n"
8527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "         i.y + vec4(0.0, i1.y, i2.y, 1.0)) +\n"
8537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "         i.x + vec4(0.0, i1.x, i2.x, 1.0));\n",
85458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        mod289_3_funcName.c_str(), permuteFuncName.c_str(), permuteFuncName.c_str(),
85558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        permuteFuncName.c_str());
8567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
85758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.append(
8587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Gradients: 7x7 points over a square, mapped onto an octahedron.
8597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
8607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "float n_ = 0.142857142857;\n" // 1.0/7.0
8617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3  ns = n_ * D.wyz - D.xzx;\n"
8627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 j = p - 49.0 * floor(p * ns.z * ns.z);\n" // mod(p,7*7)
8647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 x_ = floor(j * ns.z);\n"
8667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 y_ = floor(j - 7.0 * x_);" // mod(j,N)
8677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 x = x_ *ns.x + ns.yyyy;\n"
8697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 y = y_ *ns.x + ns.yyyy;\n"
8707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 h = 1.0 - abs(x) - abs(y);\n"
8717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 b0 = vec4(x.xy, y.xy);\n"
8737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 b1 = vec4(x.zw, y.zw);\n"
8747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    );
8757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
87658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.append(
8777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 s0 = floor(b0) * 2.0 + 1.0;\n"
8787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 s1 = floor(b1) * 2.0 + 1.0;\n"
8797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 sh = -step(h, vec4(0.0));\n"
8807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;\n"
8827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;\n"
8837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 p0 = vec3(a0.xy, h.x);\n"
8857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 p1 = vec3(a0.zw, h.y);\n"
8867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 p2 = vec3(a1.xy, h.z);\n"
8877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 p3 = vec3(a1.zw, h.w);\n"
8887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    );
8897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
89058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf(
8917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Normalise gradients
8927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 norm = %s(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n"
8937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "p0 *= norm.x;\n"
8947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "p1 *= norm.y;\n"
8957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "p2 *= norm.z;\n"
8967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "p3 *= norm.w;\n"
8977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Mix final noise value
8997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n"
9007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "m = m * m;\n"
9017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));",
90258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        taylorInvSqrtFuncName.c_str());
9037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
90458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString noiseFuncName;
9050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    builder->fsEmitFunction(kFloat_GrSLType,
9060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            "snoise", SK_ARRAY_COUNT(gNoiseVec3Args), gNoiseVec3Args,
9070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                            noiseCode.c_str(), &noiseFuncName);
9087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* noiseVecIni = "noiseVecIni";
9107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* factors     = "factors";
9117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* sum         = "sum";
9127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* xOffsets    = "xOffsets";
9137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* yOffsets    = "yOffsets";
9147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* channel     = "channel";
9157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Fill with some prime numbers
9177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\tconst vec4 %s = vec4(13.0, 53.0, 101.0, 151.0);\n", xOffsets);
9187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\tconst vec4 %s = vec4(109.0, 167.0, 23.0, 67.0);\n", yOffsets);
9197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // There are rounding errors if the floor operation is not performed here
9217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf(
9227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "\t\tvec3 %s = vec3(floor((%s*vec3(%s, 1.0)).xy) * vec2(0.66) * %s, 0.0);\n",
9230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        noiseVecIni, invMatrixUni, vCoords.c_str(), baseFrequencyUni);
9247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Perturb the texcoords with three components of noise
9267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t%s += 0.1 * vec3(%s(%s + vec3(  0.0,   0.0, %s)),"
9277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                "%s(%s + vec3( 43.0,  17.0, %s)),"
9287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                "%s(%s + vec3(-17.0, -43.0, %s)));\n",
92958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                           noiseVecIni, noiseFuncName.c_str(), noiseVecIni, seedUni,
93058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                        noiseFuncName.c_str(), noiseVecIni, seedUni,
93158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                        noiseFuncName.c_str(), noiseVecIni, seedUni);
9327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t%s = vec4(0.0);\n", outputColor);
9347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\tvec3 %s = vec3(1.0);\n", factors);
9367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\tfloat %s = 0.0;\n", sum);
9377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Loop over all octaves
9397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\tfor (int octave = 0; octave < %d; ++octave) {\n", fNumOctaves);
9407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Loop over the 4 channels
9427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t\tfor (int %s = 3; %s >= 0; --%s) {\n", channel, channel, channel);
9437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf(
9457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "\t\t\t\t%s[channel] += %s.x * %s(%s * %s.yyy - vec3(%s[%s], %s[%s], %s * %s.z));\n",
94658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        outputColor, factors, noiseFuncName.c_str(), noiseVecIni, factors, xOffsets, channel,
9477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        yOffsets, channel, seedUni, factors);
9487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppend("\t\t\t}\n"); // end of the for loop on channels
9507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t\t%s += %s.x;\n", sum, factors);
9527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t\t%s *= vec3(0.5, 2.0, 0.75);\n", factors);
9537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppend("\t\t}\n"); // end of the for loop on octaves
9557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fType == SkPerlinNoiseShader::kFractalNoise_Type) {
9577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
9587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // by fractalNoise and (turbulenceFunctionResult) by turbulence.
9597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        builder->fsCodeAppendf("\t\t%s = %s * vec4(0.5 / %s) + vec4(0.5);\n",
9607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               outputColor, outputColor, sum);
9617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    } else {
9627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        builder->fsCodeAppendf("\t\t%s = abs(%s / vec4(%s));\n",
9637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               outputColor, outputColor, sum);
9647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
9657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t%s.a *= %s;\n", outputColor, alphaUni);
9677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Clamp values
9697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
9707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Pre-multiply the result
9727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
9737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                           outputColor, outputColor, outputColor, outputColor);
9747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
9757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
9777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const GrDrawEffect&,
9787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               EffectKey key,
9797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const char* outputColor,
9807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const char* inputColor,
9810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                               const TransformedCoordsArray& coords,
9827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const TextureSamplerArray& samplers) {
9837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    sk_ignore_unused_variable(inputColor);
9847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString vCoords = builder->ensureFSCoords2D(coords, 0);
9867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    fInvMatrixUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
9887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                        kMat33f_GrSLType, "invMatrix");
9897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* invMatrixUni = builder->getUniformCStr(fInvMatrixUni);
9900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    fBaseFrequencyUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
9917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                            kVec2f_GrSLType, "baseFrequency");
9927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* baseFrequencyUni = builder->getUniformCStr(fBaseFrequencyUni);
9930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    fAlphaUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
9947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                    kFloat_GrSLType, "alpha");
9957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* alphaUni = builder->getUniformCStr(fAlphaUni);
9967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* stitchDataUni = NULL;
9987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fStitchTiles) {
9990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fStitchDataUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
100058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                             kVec2f_GrSLType, "stitchData");
10017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        stitchDataUni = builder->getUniformCStr(fStitchDataUni);
10027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
10037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
100458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8
100558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const char* chanCoordR  = "0.125";
100658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const char* chanCoordG  = "0.375";
100758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const char* chanCoordB  = "0.625";
100858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const char* chanCoordA  = "0.875";
100958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const char* chanCoord   = "chanCoord";
10107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* stitchData  = "stitchData";
10117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* ratio       = "ratio";
10127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* noiseXY     = "noiseXY";
10137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* noiseVec    = "noiseVec";
10147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* noiseSmooth = "noiseSmooth";
10157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* fractVal    = "fractVal";
10167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* uv          = "uv";
10177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* ab          = "ab";
10187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* latticeIdx  = "latticeIdx";
10197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* lattice     = "lattice";
10207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* inc8bit     = "0.00390625";  // 1.0 / 256.0
10217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // This is the math to convert the two 16bit integer packed into rgba 8 bit input into a
10227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // [-1,1] vector and perform a dot product between that vector and the provided vector.
10237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* dotLattice  = "dot(((%s.ga + %s.rb * vec2(%s)) * vec2(2.0) - vec2(1.0)), %s);";
10247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
102558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // Add noise function
102658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    static const GrGLShaderVar gPerlinNoiseArgs[] =  {
102758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        GrGLShaderVar(chanCoord, kFloat_GrSLType),
102858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        GrGLShaderVar(noiseVec, kVec2f_GrSLType)
102958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    };
10307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
103158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    static const GrGLShaderVar gPerlinNoiseStitchArgs[] =  {
103258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        GrGLShaderVar(chanCoord, kFloat_GrSLType),
103358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        GrGLShaderVar(noiseVec, kVec2f_GrSLType),
103458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        GrGLShaderVar(stitchData, kVec2f_GrSLType)
103558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    };
10367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
103758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString noiseCode;
10387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
103958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\tvec4 %s = vec4(floor(%s), fract(%s));", noiseXY, noiseVec, noiseVec);
10407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
10417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // smooth curve : t * t * (3 - 2 * t)
104258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\tvec2 %s = %s.zw * %s.zw * (vec2(3.0) - vec2(2.0) * %s.zw);",
104358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseSmooth, noiseXY, noiseXY, noiseXY);
10447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
10457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Adjust frequencies if we're stitching tiles
10467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fStitchTiles) {
104758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }",
104858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseXY, stitchData, noiseXY, stitchData);
104958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\tif(%s.x >= (%s.x - 1.0)) { %s.x -= (%s.x - 1.0); }",
105058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseXY, stitchData, noiseXY, stitchData);
105158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }",
105258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseXY, stitchData, noiseXY, stitchData);
105358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\tif(%s.y >= (%s.y - 1.0)) { %s.y -= (%s.y - 1.0); }",
105458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseXY, stitchData, noiseXY, stitchData);
10557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
10567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
10577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Get texture coordinates and normalize
105858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s.xy = fract(floor(mod(%s.xy, 256.0)) / vec2(256.0));\n",
105958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseXY, noiseXY);
10607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
10617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Get permutation for x
10627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
10637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkString xCoords("");
10647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        xCoords.appendf("vec2(%s.x, 0.5)", noiseXY);
10657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
106658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx);
106758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
106858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.append(".r;");
10697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
10707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
10717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Get permutation for x + 1
10727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
10737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkString xCoords("");
10747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        xCoords.appendf("vec2(fract(%s.x + %s), 0.5)", noiseXY, inc8bit);
10757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
107658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\t%s.y = ", latticeIdx);
107758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
107858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.append(".r;");
10797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
10807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
108158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if defined(SK_BUILD_FOR_ANDROID)
108258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Nexus 7 (Tegra 3).
108358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // The issue is that colors aren't accurate enough on Tegra devices. For example, if an 8 bit
108458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // value of 124 (or 0.486275 here) is entered, we can get a texture value of 123.513725
108558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // (or 0.484368 here). The following rounding operation prevents these precision issues from
108658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // affecting the result of the noise by making sure that we only have multiples of 1/255.
108758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // (Note that 1/255 is about 0.003921569, which is the value used here).
108858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s = floor(%s * vec2(255.0) + vec2(0.5)) * vec2(0.003921569);",
108958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                      latticeIdx, latticeIdx);
109058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif
109158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
10927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Get (x,y) coordinates with the permutated x
109358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s = fract(%s + %s.yy);", latticeIdx, latticeIdx, noiseXY);
10947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
109558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\tvec2 %s = %s.zw;", fractVal, noiseXY);
10967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
109758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\n\tvec2 %s;", uv);
10987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute u, at offset (0,0)
10997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
11007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkString latticeCoords("");
110158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        latticeCoords.appendf("vec2(%s.x, %s)", latticeIdx, chanCoord);
110258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\tvec4 %s = ", lattice);
110358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
110458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            kVec2f_GrSLType);
110558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
110658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
11077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
11087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
110958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal);
11107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute v, at offset (-1,0)
11117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
11127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkString latticeCoords("");
111358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        latticeCoords.appendf("vec2(%s.y, %s)", latticeIdx, chanCoord);
111458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.append("\n\tlattice = ");
111558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
111658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            kVec2f_GrSLType);
111758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
111858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
11197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
11207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
11217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute 'a' as a linear interpolation of 'u' and 'v'
112258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\tvec2 %s;", ab);
112358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth);
11247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
112558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal);
11267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute v, at offset (-1,-1)
11277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
11287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkString latticeCoords("");
112958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        latticeCoords.appendf("vec2(fract(%s.y + %s), %s)", latticeIdx, inc8bit, chanCoord);
113058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.append("\n\tlattice = ");
113158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
113258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            kVec2f_GrSLType);
113358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
113458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
11357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
11367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
113758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s.x += 1.0;", fractVal);
11387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute u, at offset (0,-1)
11397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
11407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkString latticeCoords("");
114158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        latticeCoords.appendf("vec2(fract(%s.x + %s), %s)", latticeIdx, inc8bit, chanCoord);
114258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.append("\n\tlattice = ");
114358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
114458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            kVec2f_GrSLType);
114558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
114658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
11477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
11487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
11497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute 'b' as a linear interpolation of 'u' and 'v'
115058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth);
11517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute the noise as a linear interpolation of 'a' and 'b'
115258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth);
115358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
115458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString noiseFuncName;
115558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (fStitchTiles) {
11560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        builder->fsEmitFunction(kFloat_GrSLType,
11570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitchArgs),
11580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                gPerlinNoiseStitchArgs, noiseCode.c_str(), &noiseFuncName);
115958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    } else {
11600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        builder->fsEmitFunction(kFloat_GrSLType,
11610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs),
11620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncName);
116358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
11647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
116558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // There are rounding errors if the floor operation is not performed here
116658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\tvec2 %s = floor((%s * vec3(%s, 1.0)).xy) * %s;",
11670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                           noiseVec, invMatrixUni, vCoords.c_str(), baseFrequencyUni);
11687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
116958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // Clear the color accumulator
117058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t%s = vec4(0.0);", outputColor);
11717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
11727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fStitchTiles) {
117358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        // Set up TurbulenceInitial stitch values.
117458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni);
11757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
11767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
117758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\tfloat %s = 1.0;", ratio);
117858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
117958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // Loop over all octaves
118058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {", fNumOctaves);
118158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
118258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t\t%s += ", outputColor);
118358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (fType != SkPerlinNoiseShader::kFractalNoise_Type) {
118458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppend("abs(");
118558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
118658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (fStitchTiles) {
118758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppendf(
118858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s),"
118958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))",
119058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData,
119158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData,
119258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData,
119358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData);
119458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    } else {
119558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppendf(
119658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s),"
119758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))",
119858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordR, noiseVec,
119958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordG, noiseVec,
120058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordB, noiseVec,
120158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordA, noiseVec);
120258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
120358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (fType != SkPerlinNoiseShader::kFractalNoise_Type) {
120458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppendf(")"); // end of "abs("
120558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
120658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf(" * %s;", ratio);
120758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
120858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec);
120958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t\t%s *= 0.5;", ratio);
121058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
121158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (fStitchTiles) {
121258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData);
121358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
121458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppend("\n\t\t}"); // end of the for loop on octaves
12157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fType == SkPerlinNoiseShader::kFractalNoise_Type) {
12177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
12187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // by fractalNoise and (turbulenceFunctionResult) by turbulence.
121958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", outputColor, outputColor);
12207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
12217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
122258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t%s.a *= %s;", outputColor, alphaUni);
12237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Clamp values
122558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", outputColor, outputColor);
12267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Pre-multiply the result
122858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
12297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                  outputColor, outputColor, outputColor, outputColor);
12307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
12317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGrGLNoise::GrGLNoise(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect)
12337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  : INHERITED (factory)
12347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fType(drawEffect.castEffect<GrPerlinNoiseEffect>().type())
12357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fStitchTiles(drawEffect.castEffect<GrPerlinNoiseEffect>().stitchTiles())
12360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger  , fNumOctaves(drawEffect.castEffect<GrPerlinNoiseEffect>().numOctaves()) {
12377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
12387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGrGLEffect::EffectKey GrGLNoise::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
12407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const GrPerlinNoiseEffect& turbulence = drawEffect.castEffect<GrPerlinNoiseEffect>();
12417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    EffectKey key = turbulence.numOctaves();
12437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    key = key << 3; // Make room for next 3 bits
12457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    switch (turbulence.type()) {
12477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case SkPerlinNoiseShader::kFractalNoise_Type:
12487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            key |= 0x1;
12497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
12507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case SkPerlinNoiseShader::kTurbulence_Type:
12517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            key |= 0x2;
12527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
12537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        default:
12547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // leave key at 0
12557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
12567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
12577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (turbulence.stitchTiles()) {
12597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        key |= 0x4; // Flip the 3rd bit if tile stitching is on
12607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
12617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return key;
12637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
12647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrGLNoise::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
12667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const GrPerlinNoiseEffect& turbulence = drawEffect.castEffect<GrPerlinNoiseEffect>();
12677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkVector& baseFrequency = turbulence.baseFrequency();
12697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY);
12707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uman.set1f(fAlphaUni, SkScalarDiv(SkIntToScalar(turbulence.alpha()), SkIntToScalar(255)));
12717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkMatrix m = turbulence.matrix();
12730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    m.postTranslate(-SK_Scalar1, -SK_Scalar1);
12747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkMatrix invM;
12757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (!m.invert(&invM)) {
12767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        invM.reset();
12777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    } else {
12787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        invM.postConcat(invM); // Square the matrix
12797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
12807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uman.setSkMatrix(fInvMatrixUni, invM);
12817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
12827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrGLPerlinNoise::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
12847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    INHERITED::setData(uman, drawEffect);
12857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const GrPerlinNoiseEffect& turbulence = drawEffect.castEffect<GrPerlinNoiseEffect>();
12877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (turbulence.stitchTiles()) {
12887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const SkPerlinNoiseShader::StitchData& stitchData = turbulence.stitchData();
128958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        uman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth),
129058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                   SkIntToScalar(stitchData.fHeight));
12917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
12927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
12937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrGLSimplexNoise::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
12957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    INHERITED::setData(uman, drawEffect);
12967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const GrSimplexNoiseEffect& turbulence = drawEffect.castEffect<GrSimplexNoiseEffect>();
12987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uman.set1f(fSeedUni, turbulence.seed());
12997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
13007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/////////////////////////////////////////////////////////////////////
13027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& paint) const {
13047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(NULL != context);
13057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1306910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    if (0 == fNumOctaves) {
1307910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        SkColor clearColor = 0;
1308910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        if (kFractalNoise_Type == fType) {
1309910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger            clearColor = SkColorSetARGB(paint.getAlpha() / 2, 127, 127, 127);
1310910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        }
1311910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(
1312910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                                                clearColor, SkXfermode::kSrc_Mode));
1313910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        return cf->asNewEffect(context);
1314910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    }
1315910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger
13167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Either we don't stitch tiles, either we have a valid tile size
13177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(!fStitchTiles || !fTileSize.isEmpty());
13187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#ifdef SK_USE_SIMPLEX_NOISE
13207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Simplex noise is currently disabled but can be enabled by defining SK_USE_SIMPLEX_NOISE
13217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    sk_ignore_unused_variable(context);
13227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrEffectRef* effect =
13237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrSimplexNoiseEffect::Create(fType, fPaintingData->fBaseFrequency,
13247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                     fNumOctaves, fStitchTiles, fSeed,
13257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                     this->getLocalMatrix(), paint.getAlpha());
13267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#else
13277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrTexture* permutationsTexture = GrLockAndRefCachedBitmapTexture(
13287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        context, *fPaintingData->getPermutationsBitmap(), NULL);
13297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrTexture* noiseTexture = GrLockAndRefCachedBitmapTexture(
13307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        context, *fPaintingData->getNoiseBitmap(), NULL);
13317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrEffectRef* effect = (NULL != permutationsTexture) && (NULL != noiseTexture) ?
13337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrPerlinNoiseEffect::Create(fType, fPaintingData->fBaseFrequency,
13347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                    fNumOctaves, fStitchTiles,
13357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                    fPaintingData->fStitchDataInit,
13367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                    permutationsTexture, noiseTexture,
13377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                    this->getLocalMatrix(), paint.getAlpha()) :
13387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        NULL;
13397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Unlock immediately, this is not great, but we don't have a way of
13417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // knowing when else to unlock it currently. TODO: Remove this when
13427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // unref becomes the unlock replacement for all types of textures.
13437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (NULL != permutationsTexture) {
13447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrUnlockAndUnrefCachedBitmapTexture(permutationsTexture);
13457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
13467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (NULL != noiseTexture) {
13477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrUnlockAndUnrefCachedBitmapTexture(noiseTexture);
13487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
13497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
13507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return effect;
13527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
13537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#else
13557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext*, const SkPaint&) const {
13577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkDEBUGFAIL("Should not call in GPU-less build");
13587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return NULL;
13597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
13607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
13627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#ifdef SK_DEVELOPER
13647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPerlinNoiseShader::toString(SkString* str) const {
13657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append("SkPerlinNoiseShader: (");
13667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append("type: ");
13687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    switch (fType) {
13697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case kFractalNoise_Type:
13707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            str->append("\"fractal noise\"");
13717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
13727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case kTurbulence_Type:
13737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            str->append("\"turbulence\"");
13747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
13757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        default:
13767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            str->append("\"unknown\"");
13777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
13787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
13797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(" base frequency: (");
13807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->appendScalar(fBaseFrequencyX);
13817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(", ");
13827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->appendScalar(fBaseFrequencyY);
13837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(") number of octaves: ");
13847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->appendS32(fNumOctaves);
13857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(" seed: ");
13867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->appendScalar(fSeed);
13877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(" stitch tiles: ");
13887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(fStitchTiles ? "true " : "false ");
13897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    this->INHERITED::toString(str);
13917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(")");
13937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
13947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
1395