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"
107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkFlattenableBuffers.h"
117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkShader.h"
127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkUnPreMultiply.h"
137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkString.h"
147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if SK_SUPPORT_GPU
167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "GrContext.h"
177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "gl/GrGLEffect.h"
187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "gl/GrGLEffectMatrix.h"
197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "GrTBackendEffectFactory.h"
207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkGr.h"
217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic const int kBlockSize = 256;
247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic const int kBlockMask = kBlockSize - 1;
257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic const int kPerlinNoise = 4096;
267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic const int kRandMaximum = SK_MaxS32; // 2**31 - 1
277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergernamespace {
297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// noiseValue is the color component's value (or color)
317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// limitValue is the maximum perlin noise array index value allowed
327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// newValue is the current noise dimension (either width or height)
337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerinline int checkNoise(int noiseValue, int limitValue, int newValue) {
347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // If the noise value would bring us out of bounds of the current noise array while we are
357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // stiching noise tiles together, wrap the noise around the current dimension of the noise to
367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // stay within the array bounds in a continuous fashion (so that tiling lines are not visible)
377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (noiseValue >= limitValue) {
387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseValue -= newValue;
397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (noiseValue >= limitValue - 1) {
417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseValue -= newValue - 1;
427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return noiseValue;
447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerinline SkScalar smoothCurve(SkScalar t) {
477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static const SkScalar SK_Scalar3 = SkFloatToScalar(3.0f);
487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // returns t * t * (3 - 2 * t)
507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkScalarMul(SkScalarSquare(t), SK_Scalar3 - 2 * t);
517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} // end namespace
547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstruct SkPerlinNoiseShader::StitchData {
567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    StitchData()
577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : fWidth(0)
587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fWrapX(0)
597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fHeight(0)
607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fWrapY(0)
617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {}
627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool operator==(const StitchData& other) const {
647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fWidth == other.fWidth &&
657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fWrapX == other.fWrapX &&
667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fHeight == other.fHeight &&
677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fWrapY == other.fWrapY;
687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int fWidth; // How much to subtract to wrap for stitching.
717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int fWrapX; // Minimum value to wrap.
727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int fHeight;
737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int fWrapY;
747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstruct SkPerlinNoiseShader::PaintingData {
777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    PaintingData(const SkISize& tileSize)
787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : fSeed(0)
797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fTileSize(tileSize)
807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fPermutationsBitmap(NULL)
817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fNoiseBitmap(NULL)
827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {}
837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    ~PaintingData()
857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkDELETE(fPermutationsBitmap);
877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkDELETE(fNoiseBitmap);
887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int         fSeed;
917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uint8_t     fLatticeSelector[kBlockSize];
927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uint16_t    fNoise[4][kBlockSize][2];
937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint     fGradient[4][kBlockSize];
947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkISize     fTileSize;
957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkVector    fBaseFrequency;
967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    StitchData  fStitchDataInit;
977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkBitmap*    fPermutationsBitmap;
1017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkBitmap*    fNoiseBitmap;
1027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
1047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    inline int random()  {
1067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        static const int gRandAmplitude = 16807; // 7**5; primitive root of m
1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        static const int gRandQ = 127773; // m / a
1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        static const int gRandR = 2836; // m % a
1097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int result = gRandAmplitude * (fSeed % gRandQ) - gRandR * (fSeed / gRandQ);
1117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (result <= 0)
1127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            result += kRandMaximum;
1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fSeed = result;
1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return result;
1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void init(SkScalar seed)
1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
1197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        static const SkScalar gInvBlockSizef = SkScalarInvert(SkIntToScalar(kBlockSize));
1207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // The seed value clamp to the range [1, kRandMaximum - 1].
1227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fSeed = SkScalarRoundToInt(seed);
1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (fSeed <= 0) {
1247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fSeed = -(fSeed % (kRandMaximum - 1)) + 1;
1257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (fSeed > kRandMaximum - 1) {
1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fSeed = kRandMaximum - 1;
1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int channel = 0; channel < 4; ++channel) {
1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            for (int i = 0; i < kBlockSize; ++i) {
1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fLatticeSelector[i] = i;
1327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fNoise[channel][i][0] = (random() % (2 * kBlockSize));
1337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fNoise[channel][i][1] = (random() % (2 * kBlockSize));
1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
1357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int i = kBlockSize - 1; i > 0; --i) {
1377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            int k = fLatticeSelector[i];
1387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            int j = random() % kBlockSize;
1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkASSERT(j >= 0);
1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkASSERT(j < kBlockSize);
1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fLatticeSelector[i] = fLatticeSelector[j];
1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fLatticeSelector[j] = k;
1437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Perform the permutations now
1467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        {
1477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // Copy noise data
1487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            uint16_t noise[4][kBlockSize][2];
1497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            for (int i = 0; i < kBlockSize; ++i) {
1507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                for (int channel = 0; channel < 4; ++channel) {
1517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    for (int j = 0; j < 2; ++j) {
1527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        noise[channel][i][j] = fNoise[channel][i][j];
1537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    }
1547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                }
1557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
1567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // Do permutations on noise data
1577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            for (int i = 0; i < kBlockSize; ++i) {
1587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                for (int channel = 0; channel < 4; ++channel) {
1597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    for (int j = 0; j < 2; ++j) {
1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        fNoise[channel][i][j] = noise[channel][fLatticeSelector[i]][j];
1617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    }
1627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                }
1637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
1647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Half of the largest possible value for 16 bit unsigned int
16758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        static const SkScalar gHalfMax16bits = SkFloatToScalar(32767.5f);
1687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Compute gradients from permutated noise data
1707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int channel = 0; channel < 4; ++channel) {
1717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            for (int i = 0; i < kBlockSize; ++i) {
1727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fGradient[channel][i] = SkPoint::Make(
1737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    SkScalarMul(SkIntToScalar(fNoise[channel][i][0] - kBlockSize),
1747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                gInvBlockSizef),
1757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    SkScalarMul(SkIntToScalar(fNoise[channel][i][1] - kBlockSize),
1767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                gInvBlockSizef));
1777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fGradient[channel][i].normalize();
1787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                // Put the normalized gradient back into the noise data
1797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fNoise[channel][i][0] = SkScalarRoundToInt(SkScalarMul(
18058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                    fGradient[channel][i].fX + SK_Scalar1, gHalfMax16bits));
1817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fNoise[channel][i][1] = SkScalarRoundToInt(SkScalarMul(
18258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                    fGradient[channel][i].fY + SK_Scalar1, gHalfMax16bits));
1837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
1847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Invalidate bitmaps
1877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkDELETE(fPermutationsBitmap);
1887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fPermutationsBitmap = NULL;
1897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkDELETE(fNoiseBitmap);
1907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fNoiseBitmap = NULL;
1917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void stitch() {
1947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkScalar tileWidth  = SkIntToScalar(fTileSize.width());
1957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkScalar tileHeight = SkIntToScalar(fTileSize.height());
1967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkASSERT(tileWidth > 0 && tileHeight > 0);
1977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // When stitching tiled turbulence, the frequencies must be adjusted
1987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // so that the tile borders will be continuous.
1997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (fBaseFrequency.fX) {
2007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalar lowFrequencx = SkScalarDiv(
2017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkScalarMulFloor(tileWidth, fBaseFrequency.fX), tileWidth);
2027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalar highFrequencx = SkScalarDiv(
2037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkScalarMulCeil(tileWidth, fBaseFrequency.fX), tileWidth);
2047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // BaseFrequency should be non-negative according to the standard.
2057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            if (SkScalarDiv(fBaseFrequency.fX, lowFrequencx) <
2067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkScalarDiv(highFrequencx, fBaseFrequency.fX)) {
2077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fBaseFrequency.fX = lowFrequencx;
2087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            } else {
2097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fBaseFrequency.fX = highFrequencx;
2107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
2117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (fBaseFrequency.fY) {
2137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalar lowFrequency = SkScalarDiv(
2147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkScalarMulFloor(tileHeight, fBaseFrequency.fY), tileHeight);
2157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalar highFrequency = SkScalarDiv(
2167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkScalarMulCeil(tileHeight, fBaseFrequency.fY), tileHeight);
2177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            if (SkScalarDiv(fBaseFrequency.fY, lowFrequency) <
2187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                SkScalarDiv(highFrequency, fBaseFrequency.fY)) {
2197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fBaseFrequency.fY = lowFrequency;
2207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            } else {
2217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                fBaseFrequency.fY = highFrequency;
2227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
2237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Set up TurbulenceInitial stitch values.
2257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fStitchDataInit.fWidth  =
2267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalarMulRound(tileWidth, fBaseFrequency.fX);
2277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fStitchDataInit.fWrapX  = kPerlinNoise + fStitchDataInit.fWidth;
2287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fStitchDataInit.fHeight =
2297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalarMulRound(tileHeight, fBaseFrequency.fY);
2307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fStitchDataInit.fWrapY  = kPerlinNoise + fStitchDataInit.fHeight;
2317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkBitmap* getPermutationsBitmap()
2347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
2357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (!fPermutationsBitmap) {
2367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fPermutationsBitmap = SkNEW(SkBitmap);
2377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fPermutationsBitmap->setConfig(SkBitmap::kA8_Config, kBlockSize, 1);
2387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fPermutationsBitmap->allocPixels();
2397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            uint8_t* bitmapPixels = fPermutationsBitmap->getAddr8(0, 0);
2407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            memcpy(bitmapPixels, fLatticeSelector, sizeof(uint8_t) * kBlockSize);
2417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fPermutationsBitmap;
2437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkBitmap* getNoiseBitmap()
2467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
2477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (!fNoiseBitmap) {
2487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fNoiseBitmap = SkNEW(SkBitmap);
2497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fNoiseBitmap->setConfig(SkBitmap::kARGB_8888_Config, kBlockSize, 4);
2507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fNoiseBitmap->allocPixels();
2517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            uint32_t* bitmapPixels = fNoiseBitmap->getAddr32(0, 0);
2527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            memcpy(bitmapPixels, fNoise[0][0], sizeof(uint16_t) * kBlockSize * 4 * 2);
2537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fNoiseBitmap;
2557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
2577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkShader* SkPerlinNoiseShader::CreateFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY,
2597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                  int numOctaves, SkScalar seed,
2607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                  const SkISize* tileSize) {
2617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkNEW_ARGS(SkPerlinNoiseShader, (kFractalNoise_Type, baseFrequencyX, baseFrequencyY,
2627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                            numOctaves, seed, tileSize));
2637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
2647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkShader* SkPerlinNoiseShader::CreateTubulence(SkScalar baseFrequencyX, SkScalar baseFrequencyY,
2667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                              int numOctaves, SkScalar seed,
2677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                              const SkISize* tileSize) {
2687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkNEW_ARGS(SkPerlinNoiseShader, (kTurbulence_Type, baseFrequencyX, baseFrequencyY,
2697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                            numOctaves, seed, tileSize));
2707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
2717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkPerlinNoiseShader::SkPerlinNoiseShader(SkPerlinNoiseShader::Type type,
2737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                         SkScalar baseFrequencyX,
2747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                         SkScalar baseFrequencyY,
2757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                         int numOctaves,
2767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                         SkScalar seed,
2777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                         const SkISize* tileSize)
2787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  : fType(type)
2797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fBaseFrequencyX(baseFrequencyX)
2807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fBaseFrequencyY(baseFrequencyY)
2817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fNumOctaves(numOctaves & 0xFF /*[0,255] octaves allowed*/)
2827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fSeed(seed)
2837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fStitchTiles((tileSize != NULL) && !tileSize->isEmpty())
2847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fPaintingData(NULL)
2857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger{
2867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(numOctaves >= 0 && numOctaves < 256);
2877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    setTileSize(fStitchTiles ? *tileSize : SkISize::Make(0,0));
2887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fMatrix.reset();
2897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
2907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkPerlinNoiseShader::SkPerlinNoiseShader(SkFlattenableReadBuffer& buffer) :
2927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        INHERITED(buffer), fPaintingData(NULL) {
2937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fType           = (SkPerlinNoiseShader::Type) buffer.readInt();
2947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fBaseFrequencyX = buffer.readScalar();
2957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fBaseFrequencyY = buffer.readScalar();
2967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fNumOctaves     = buffer.readInt();
2977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fSeed           = buffer.readScalar();
2987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fStitchTiles    = buffer.readBool();
2997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fTileSize.fWidth  = buffer.readInt();
3007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fTileSize.fHeight = buffer.readInt();
3017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    setTileSize(fTileSize);
3027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fMatrix.reset();
3037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkPerlinNoiseShader::~SkPerlinNoiseShader() {
3067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Safety, should have been done in endContext()
3077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkDELETE(fPaintingData);
3087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPerlinNoiseShader::flatten(SkFlattenableWriteBuffer& buffer) const {
3117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    this->INHERITED::flatten(buffer);
3127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeInt((int) fType);
3137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeScalar(fBaseFrequencyX);
3147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeScalar(fBaseFrequencyY);
3157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeInt(fNumOctaves);
3167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeScalar(fSeed);
3177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeBool(fStitchTiles);
3187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeInt(fTileSize.fWidth);
3197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    buffer.writeInt(fTileSize.fHeight);
3207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPerlinNoiseShader::initPaint(PaintingData& paintingData)
3237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger{
3247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    paintingData.init(fSeed);
3257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Set frequencies to original values
3277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    paintingData.fBaseFrequency.set(fBaseFrequencyX, fBaseFrequencyY);
3287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Adjust frequecies based on size if stitching is enabled
3297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fStitchTiles) {
3307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        paintingData.stitch();
3317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
3327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPerlinNoiseShader::setTileSize(const SkISize& tileSize) {
3357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fTileSize = tileSize;
3367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (NULL == fPaintingData) {
3387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize));
3397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        initPaint(*fPaintingData);
3407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    } else {
3417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Set Size
3427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fPaintingData->fTileSize = fTileSize;
3437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Set frequencies to original values
3447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fPaintingData->fBaseFrequency.set(fBaseFrequencyX, fBaseFrequencyY);
3457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Adjust frequecies based on size if stitching is enabled
3467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (fStitchTiles) {
3477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fPaintingData->stitch();
3487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
3497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
3507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkScalar SkPerlinNoiseShader::noise2D(int channel, const PaintingData& paintingData,
3537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                     const StitchData& stitchData, const SkPoint& noiseVector)
3547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger{
3557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    struct Noise {
3567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int noisePositionIntegerValue;
3577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkScalar noisePositionFractionValue;
3587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        Noise(SkScalar component)
3597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        {
3607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalar position = component + kPerlinNoise;
3617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            noisePositionIntegerValue = SkScalarFloorToInt(position);
3627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            noisePositionFractionValue = position - SkIntToScalar(noisePositionIntegerValue);
3637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
3647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
3657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    Noise noiseX(noiseVector.x());
3667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    Noise noiseY(noiseVector.y());
3677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar u, v;
3687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // If stitching, adjust lattice points accordingly.
3697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fStitchTiles) {
3707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseX.noisePositionIntegerValue =
3717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth);
3727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseY.noisePositionIntegerValue =
3737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight);
3747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
3757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    noiseX.noisePositionIntegerValue &= kBlockMask;
3767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    noiseY.noisePositionIntegerValue &= kBlockMask;
3777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int latticeIndex =
3787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        paintingData.fLatticeSelector[noiseX.noisePositionIntegerValue] +
3797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseY.noisePositionIntegerValue;
3807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int nextLatticeIndex =
3817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        paintingData.fLatticeSelector[(noiseX.noisePositionIntegerValue + 1) & kBlockMask] +
3827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseY.noisePositionIntegerValue;
3837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar sx = smoothCurve(noiseX.noisePositionFractionValue);
3847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar sy = smoothCurve(noiseY.noisePositionFractionValue);
3857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement
3867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue,
3877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                          noiseY.noisePositionFractionValue); // Offset (0,0)
3887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    u = paintingData.fGradient[channel][latticeIndex & kBlockMask].dot(fractionValue);
3897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fractionValue.fX -= SK_Scalar1; // Offset (-1,0)
3907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    v = paintingData.fGradient[channel][nextLatticeIndex & kBlockMask].dot(fractionValue);
3917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar a = SkScalarInterp(u, v, sx);
3927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fractionValue.fY -= SK_Scalar1; // Offset (-1,-1)
3937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    v = paintingData.fGradient[channel][(nextLatticeIndex + 1) & kBlockMask].dot(fractionValue);
3947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1)
3957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    u = paintingData.fGradient[channel][(latticeIndex + 1) & kBlockMask].dot(fractionValue);
3967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar b = SkScalarInterp(u, v, sx);
3977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkScalarInterp(a, b, sy);
3987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkScalar SkPerlinNoiseShader::calculateTurbulenceValueForPoint(
4017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int channel, const PaintingData& paintingData, StitchData& stitchData, const SkPoint& point)
4027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger{
4037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fStitchTiles) {
4047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Set up TurbulenceInitial stitch values.
4057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        stitchData = paintingData.fStitchDataInit;
4067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar turbulenceFunctionResult = 0;
4087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint noiseVector(SkPoint::Make(SkScalarMul(point.x(), paintingData.fBaseFrequency.fX),
4097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                      SkScalarMul(point.y(), paintingData.fBaseFrequency.fY)));
4107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar ratio = SK_Scalar1;
4117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int octave = 0; octave < fNumOctaves; ++octave) {
4127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkScalar noise = noise2D(channel, paintingData, stitchData, noiseVector);
4137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        turbulenceFunctionResult += SkScalarDiv(
4147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            (fType == kFractalNoise_Type) ? noise : SkScalarAbs(noise), ratio);
4157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseVector.fX *= 2;
4167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseVector.fY *= 2;
4177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        ratio *= 2;
4187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (fStitchTiles) {
4197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // Update stitch values
4207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            stitchData.fWidth  *= 2;
4217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            stitchData.fWrapX   = stitchData.fWidth + kPerlinNoise;
4227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            stitchData.fHeight *= 2;
4237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            stitchData.fWrapY   = stitchData.fHeight + kPerlinNoise;
4247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
4257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
4287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // by fractalNoise and (turbulenceFunctionResult) by turbulence.
4297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fType == kFractalNoise_Type) {
4307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        turbulenceFunctionResult =
4317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalarMul(turbulenceFunctionResult, SK_ScalarHalf) + SK_ScalarHalf;
4327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (channel == 3) { // Scale alpha by paint value
4357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        turbulenceFunctionResult = SkScalarMul(turbulenceFunctionResult,
4367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkScalarDiv(SkIntToScalar(getPaintAlpha()), SkIntToScalar(255)));
4377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Clamp result
4407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1);
4417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
4427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkPMColor SkPerlinNoiseShader::shade(const SkPoint& point, StitchData& stitchData) {
4447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkMatrix matrix = fMatrix;
4457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkMatrix invMatrix;
4467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (!matrix.invert(&invMatrix)) {
4477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        invMatrix.reset();
4487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    } else {
4497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        invMatrix.postConcat(invMatrix); // Square the matrix
4507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // This (1,1) translation is due to WebKit's 1 based coordinates for the noise
4527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // (as opposed to 0 based, usually). The same adjustment is in the setData() function.
4537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    matrix.postTranslate(SK_Scalar1, SK_Scalar1);
4547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint newPoint;
4557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    matrix.mapPoints(&newPoint, &point, 1);
4567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    invMatrix.mapPoints(&newPoint, &newPoint, 1);
4577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    newPoint.fX = SkScalarRoundToScalar(newPoint.fX);
4587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    newPoint.fY = SkScalarRoundToScalar(newPoint.fY);
4597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    U8CPU rgba[4];
4617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int channel = 3; channel >= 0; --channel) {
4627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        rgba[channel] = SkScalarFloorToInt(255 *
4637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            calculateTurbulenceValueForPoint(channel, *fPaintingData, stitchData, newPoint));
4647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
4667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
4677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerbool SkPerlinNoiseShader::setContext(const SkBitmap& device, const SkPaint& paint,
4697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                     const SkMatrix& matrix) {
4707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fMatrix = matrix;
4717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return INHERITED::setContext(device, paint, matrix);
4727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
4737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPerlinNoiseShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
4757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
4767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    StitchData stitchData;
4777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int i = 0; i < count; ++i) {
4787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        result[i] = shade(point, stitchData);
4797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        point.fX += SK_Scalar1;
4807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
4827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPerlinNoiseShader::shadeSpan16(int x, int y, uint16_t result[], int count) {
4847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
4857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    StitchData stitchData;
4867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    DITHER_565_SCAN(y);
4877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int i = 0; i < count; ++i) {
4887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        unsigned dither = DITHER_VALUE(x);
4897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        result[i] = SkDitherRGB32To565(shade(point, stitchData), dither);
4907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        DITHER_INC_X(x);
4917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        point.fX += SK_Scalar1;
4927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
4937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
4947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/////////////////////////////////////////////////////////////////////
4967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
49758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if SK_SUPPORT_GPU
4987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "GrTBackendEffectFactory.h"
5007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrGLNoise : public GrGLEffect {
5027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
5037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLNoise(const GrBackendEffectFactory& factory,
5047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger              const GrDrawEffect& drawEffect);
5057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual ~GrGLNoise() {}
5067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
5087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
5107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprotected:
5127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPerlinNoiseShader::Type           fType;
5137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool                                fStitchTiles;
5147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int                                 fNumOctaves;
5157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle   fBaseFrequencyUni;
5167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle   fAlphaUni;
5177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle   fInvMatrixUni;
5187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLEffectMatrix                    fEffectMatrix;
5197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
5217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrGLEffect INHERITED;
5227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
5237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrGLPerlinNoise : public GrGLNoise {
5257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
5267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLPerlinNoise(const GrBackendEffectFactory& factory,
5277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                    const GrDrawEffect& drawEffect)
5287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : GrGLNoise(factory, drawEffect) {}
5297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual ~GrGLPerlinNoise() {}
5307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual void emitCode(GrGLShaderBuilder*,
5327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const GrDrawEffect&,
5337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          EffectKey,
5347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const char* outputColor,
5357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const char* inputColor,
5367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const TextureSamplerArray&) SK_OVERRIDE;
5377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
5397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
5417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle fStitchDataUni;
5427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrGLNoise INHERITED;
5447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
5457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrGLSimplexNoise : public GrGLNoise {
5477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Note : This is for reference only. GrGLPerlinNoise is used for processing.
5487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
5497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLSimplexNoise(const GrBackendEffectFactory& factory,
5507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                     const GrDrawEffect& drawEffect)
5517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : GrGLNoise(factory, drawEffect) {}
5527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual ~GrGLSimplexNoise() {}
5547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual void emitCode(GrGLShaderBuilder*,
5567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const GrDrawEffect&,
5577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          EffectKey,
5587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const char* outputColor,
5597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const char* inputColor,
5607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          const TextureSamplerArray&) SK_OVERRIDE;
5617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
5637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
5657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLUniformManager::UniformHandle fSeedUni;
5667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrGLNoise INHERITED;
5687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
5697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/////////////////////////////////////////////////////////////////////
5717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrNoiseEffect : public GrEffect {
5737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
5747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual ~GrNoiseEffect() { }
5757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPerlinNoiseShader::Type type() const { return fType; }
5777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool stitchTiles() const { return fStitchTiles; }
5787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkVector& baseFrequency() const { return fBaseFrequency; }
5797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int numOctaves() const { return fNumOctaves; }
5807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkMatrix& matrix() const { return fMatrix; }
5817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uint8_t alpha() const { return fAlpha; }
5827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrGLEffectMatrix::CoordsType coordsType() const { return GrEffect::kLocal_CoordsType; }
5837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void getConstantColorComponents(GrColor*, uint32_t* validFlags) const SK_OVERRIDE {
5857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        *validFlags = 0; // This is noise. Nothing is constant.
5867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprotected:
5897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
5907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const GrNoiseEffect& s = CastEffect<GrNoiseEffect>(sBase);
5917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fType == s.fType &&
5927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fBaseFrequency == s.fBaseFrequency &&
5937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fNumOctaves == s.fNumOctaves &&
5947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fStitchTiles == s.fStitchTiles &&
5957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fMatrix == s.fMatrix &&
5967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fAlpha == s.fAlpha;
5977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
5987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
5997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrNoiseEffect(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency, int numOctaves,
6007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                  bool stitchTiles, const SkMatrix& matrix, uint8_t alpha)
6017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : fType(type)
6027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fBaseFrequency(baseFrequency)
6037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fNumOctaves(numOctaves)
6047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fStitchTiles(stitchTiles)
6057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fMatrix(matrix)
6067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fAlpha(alpha) {
6077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPerlinNoiseShader::Type       fType;
6107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkVector                        fBaseFrequency;
6117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int                             fNumOctaves;
6127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool                            fStitchTiles;
6137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkMatrix                        fMatrix;
6147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uint8_t                         fAlpha;
6157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
6177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrEffect INHERITED;
6187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
6197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrPerlinNoiseEffect : public GrNoiseEffect {
6217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
6227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static GrEffectRef* Create(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency,
6237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               int numOctaves, bool stitchTiles,
6247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const SkPerlinNoiseShader::StitchData& stitchData,
6257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               GrTexture* permutationsTexture, GrTexture* noiseTexture,
6267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const SkMatrix& matrix, uint8_t alpha) {
6277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        AutoEffectUnref effect(SkNEW_ARGS(GrPerlinNoiseEffect, (type, baseFrequency, numOctaves,
6287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            stitchTiles, stitchData, permutationsTexture, noiseTexture, matrix, alpha)));
6297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return CreateEffectRef(effect);
6307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual ~GrPerlinNoiseEffect() { }
6337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static const char* Name() { return "PerlinNoise"; }
6357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
6367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return GrTBackendEffectFactory<GrPerlinNoiseEffect>::getInstance();
6377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkPerlinNoiseShader::StitchData& stitchData() const { return fStitchData; }
6397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrGLPerlinNoise GLEffect;
6417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
6437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
6447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const GrPerlinNoiseEffect& s = CastEffect<GrPerlinNoiseEffect>(sBase);
6457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return INHERITED::onIsEqual(sBase) &&
6467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fPermutationsAccess.getTexture() == s.fPermutationsAccess.getTexture() &&
6477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fNoiseAccess.getTexture() == s.fNoiseAccess.getTexture() &&
6487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger               fStitchData == s.fStitchData;
6497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrPerlinNoiseEffect(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency,
6527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        int numOctaves, bool stitchTiles,
6537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        const SkPerlinNoiseShader::StitchData& stitchData,
6547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        GrTexture* permutationsTexture, GrTexture* noiseTexture,
6557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                        const SkMatrix& matrix, uint8_t alpha)
6567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : GrNoiseEffect(type, baseFrequency, numOctaves, stitchTiles, matrix, alpha)
6577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fPermutationsAccess(permutationsTexture)
6587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fNoiseAccess(noiseTexture)
6597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fStitchData(stitchData) {
6607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        this->addTextureAccess(&fPermutationsAccess);
6617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        this->addTextureAccess(&fNoiseAccess);
6627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GR_DECLARE_EFFECT_TEST;
6657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrTextureAccess                 fPermutationsAccess;
6677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrTextureAccess                 fNoiseAccess;
6687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPerlinNoiseShader::StitchData fStitchData;
6697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrNoiseEffect INHERITED;
6717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
6727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrSimplexNoiseEffect : public GrNoiseEffect {
6747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Note : This is for reference only. GrPerlinNoiseEffect is used for processing.
6757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
6767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static GrEffectRef* Create(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency,
6777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               int numOctaves, bool stitchTiles, const SkScalar seed,
6787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const SkMatrix& matrix, uint8_t alpha) {
6797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        AutoEffectUnref effect(SkNEW_ARGS(GrSimplexNoiseEffect, (type, baseFrequency, numOctaves,
6807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            stitchTiles, seed, matrix, alpha)));
6817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return CreateEffectRef(effect);
6827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual ~GrSimplexNoiseEffect() { }
6857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static const char* Name() { return "SimplexNoise"; }
6877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
6887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return GrTBackendEffectFactory<GrSimplexNoiseEffect>::getInstance();
6897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkScalar& seed() const { return fSeed; }
6917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrGLSimplexNoise GLEffect;
6937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
6957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual bool onIsEqual(const GrEffect& sBase) const SK_OVERRIDE {
6967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const GrSimplexNoiseEffect& s = CastEffect<GrSimplexNoiseEffect>(sBase);
6977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return INHERITED::onIsEqual(sBase) && fSeed == s.fSeed;
6987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrSimplexNoiseEffect(SkPerlinNoiseShader::Type type, const SkVector& baseFrequency,
7017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                         int numOctaves, bool stitchTiles, const SkScalar seed,
7027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                         const SkMatrix& matrix, uint8_t alpha)
7037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      : GrNoiseEffect(type, baseFrequency, numOctaves, stitchTiles, matrix, alpha)
7047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger      , fSeed(seed) {
7057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
7067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar fSeed;
7087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef GrNoiseEffect INHERITED;
7107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
7117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/////////////////////////////////////////////////////////////////////
7137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGR_DEFINE_EFFECT_TEST(GrPerlinNoiseEffect);
7147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGrEffectRef* GrPerlinNoiseEffect::TestCreate(SkMWCRandom* random,
7167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                             GrContext* context,
7177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                             const GrDrawTargetCaps&,
7187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                             GrTexture**) {
7197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int      numOctaves = random->nextRangeU(2, 10);
7207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool     stitchTiles = random->nextBool();
7217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar seed = SkIntToScalar(random->nextU());
7227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkISize  tileSize = SkISize::Make(random->nextRangeU(4, 4096), random->nextRangeU(4, 4096));
7237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar baseFrequencyX = random->nextRangeScalar(SkFloatToScalar(0.01f),
7247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                      SkFloatToScalar(0.99f));
7257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkScalar baseFrequencyY = random->nextRangeScalar(SkFloatToScalar(0.01f),
7267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                      SkFloatToScalar(0.99f));
7277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkShader* shader = random->nextBool() ?
7297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkPerlinNoiseShader::CreateFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves, seed,
7307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                stitchTiles ? &tileSize : NULL) :
7317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkPerlinNoiseShader::CreateTubulence(baseFrequencyX, baseFrequencyY, numOctaves, seed,
7327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                             stitchTiles ? &tileSize : NULL);
7337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPaint paint;
7357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrEffectRef* effect = shader->asNewEffect(context, paint);
7367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkDELETE(shader);
7387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return effect;
7407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
7417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/////////////////////////////////////////////////////////////////////
7437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrGLSimplexNoise::emitCode(GrGLShaderBuilder* builder,
7457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                const GrDrawEffect&,
7467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                EffectKey key,
7477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                const char* outputColor,
7487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                const char* inputColor,
7497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                const TextureSamplerArray&) {
7507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    sk_ignore_unused_variable(inputColor);
7517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* vCoords;
7537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &vCoords);
7547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fSeedUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
7567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                   kFloat_GrSLType, "seed");
7577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* seedUni = builder->getUniformCStr(fSeedUni);
7587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fInvMatrixUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
7597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                        kMat33f_GrSLType, "invMatrix");
7607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* invMatrixUni = builder->getUniformCStr(fInvMatrixUni);
7617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fBaseFrequencyUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
7627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                            kVec2f_GrSLType, "baseFrequency");
7637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* baseFrequencyUni = builder->getUniformCStr(fBaseFrequencyUni);
7647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fAlphaUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
7657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                    kFloat_GrSLType, "alpha");
7667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* alphaUni = builder->getUniformCStr(fAlphaUni);
7677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Add vec3 modulo 289 function
76958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    static const GrGLShaderVar gVec3Args[] =  {
7707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrGLShaderVar("x", kVec3f_GrSLType)
7717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
7727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkString mod289_3_funcName;
7747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->emitFunction(GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType,
77558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                          "mod289", SK_ARRAY_COUNT(gVec3Args), gVec3Args,
7767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          "const vec2 C = vec2(1.0 / 289.0, 289.0);\n"
7777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          "return x - floor(x * C.xxx) * C.yyy;", &mod289_3_funcName);
7787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Add vec4 modulo 289 function
78058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    static const GrGLShaderVar gVec4Args[] =  {
7817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrGLShaderVar("x", kVec4f_GrSLType)
7827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
7837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkString mod289_4_funcName;
7857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->emitFunction(GrGLShaderBuilder::kFragment_ShaderType, kVec4f_GrSLType,
78658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                          "mod289", SK_ARRAY_COUNT(gVec4Args), gVec4Args,
7877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          "const vec2 C = vec2(1.0 / 289.0, 289.0);\n"
7887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          "return x - floor(x * C.xxxx) * C.yyyy;", &mod289_4_funcName);
7897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Add vec4 permute function
79158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString permuteCode;
79258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    permuteCode.appendf("const vec2 C = vec2(34.0, 1.0);\n"
79358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                        "return %s(((x * C.xxxx) + C.yyyy) * x);", mod289_4_funcName.c_str());
79458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString permuteFuncName;
7957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->emitFunction(GrGLShaderBuilder::kFragment_ShaderType, kVec4f_GrSLType,
79658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                          "permute", SK_ARRAY_COUNT(gVec4Args), gVec4Args,
79758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                          permuteCode.c_str(), &permuteFuncName);
7987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
7997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Add vec4 taylorInvSqrt function
80058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString taylorInvSqrtFuncName;
8017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->emitFunction(GrGLShaderBuilder::kFragment_ShaderType, kVec4f_GrSLType,
80258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                          "taylorInvSqrt", SK_ARRAY_COUNT(gVec4Args), gVec4Args,
8037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                          "const vec2 C = vec2(-0.85373472095314, 1.79284291400159);\n"
80458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                          "return x * C.xxxx + C.yyyy;", &taylorInvSqrtFuncName);
8057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Add vec3 noise function
80758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    static const GrGLShaderVar gNoiseVec3Args[] =  {
8087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrGLShaderVar("v", kVec3f_GrSLType)
8097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
8107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
81158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString noiseCode;
81258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.append(
8137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "const vec2 C = vec2(1.0/6.0, 1.0/3.0);\n"
8147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n"
8157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // First corner
8177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 i = floor(v + dot(v, C.yyy));\n"
8187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 x0 = v - i + dot(i, C.xxx);\n"
8197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Other corners
8217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 g = step(x0.yzx, x0.xyz);\n"
8227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 l = 1.0 - g;\n"
8237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 i1 = min(g.xyz, l.zxy);\n"
8247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 i2 = max(g.xyz, l.zxy);\n"
8257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 x1 = x0 - i1 + C.xxx;\n"
8277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 x2 = x0 - i2 + C.yyy;\n" // 2.0*C.x = 1/3 = C.y
8287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 x3 = x0 - D.yyy;\n" // -1.0+3.0*C.x = -0.5 = -D.y
8297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    );
8307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
83158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf(
8327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Permutations
8337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "i = %s(i);\n"
8347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 p = %s(%s(%s(\n"
8357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "         i.z + vec4(0.0, i1.z, i2.z, 1.0)) +\n"
8367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "         i.y + vec4(0.0, i1.y, i2.y, 1.0)) +\n"
8377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "         i.x + vec4(0.0, i1.x, i2.x, 1.0));\n",
83858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        mod289_3_funcName.c_str(), permuteFuncName.c_str(), permuteFuncName.c_str(),
83958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        permuteFuncName.c_str());
8407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
84158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.append(
8427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Gradients: 7x7 points over a square, mapped onto an octahedron.
8437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
8447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "float n_ = 0.142857142857;\n" // 1.0/7.0
8457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3  ns = n_ * D.wyz - D.xzx;\n"
8467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 j = p - 49.0 * floor(p * ns.z * ns.z);\n" // mod(p,7*7)
8487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 x_ = floor(j * ns.z);\n"
8507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 y_ = floor(j - 7.0 * x_);" // mod(j,N)
8517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 x = x_ *ns.x + ns.yyyy;\n"
8537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 y = y_ *ns.x + ns.yyyy;\n"
8547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 h = 1.0 - abs(x) - abs(y);\n"
8557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 b0 = vec4(x.xy, y.xy);\n"
8577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 b1 = vec4(x.zw, y.zw);\n"
8587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    );
8597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
86058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.append(
8617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 s0 = floor(b0) * 2.0 + 1.0;\n"
8627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 s1 = floor(b1) * 2.0 + 1.0;\n"
8637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 sh = -step(h, vec4(0.0));\n"
8647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;\n"
8667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;\n"
8677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 p0 = vec3(a0.xy, h.x);\n"
8697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 p1 = vec3(a0.zw, h.y);\n"
8707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 p2 = vec3(a1.xy, h.z);\n"
8717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec3 p3 = vec3(a1.zw, h.w);\n"
8727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    );
8737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
87458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf(
8757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Normalise gradients
8767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 norm = %s(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n"
8777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "p0 *= norm.x;\n"
8787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "p1 *= norm.y;\n"
8797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "p2 *= norm.z;\n"
8807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "p3 *= norm.w;\n"
8817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Mix final noise value
8837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n"
8847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "m = m * m;\n"
8857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));",
88658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        taylorInvSqrtFuncName.c_str());
8877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
88858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString noiseFuncName;
8897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->emitFunction(GrGLShaderBuilder::kFragment_ShaderType, kFloat_GrSLType,
89058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                          "snoise", SK_ARRAY_COUNT(gNoiseVec3Args), gNoiseVec3Args,
89158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                          noiseCode.c_str(), &noiseFuncName);
8927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
8937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* noiseVecIni = "noiseVecIni";
8947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* factors     = "factors";
8957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* sum         = "sum";
8967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* xOffsets    = "xOffsets";
8977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* yOffsets    = "yOffsets";
8987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* channel     = "channel";
8997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Fill with some prime numbers
9017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\tconst vec4 %s = vec4(13.0, 53.0, 101.0, 151.0);\n", xOffsets);
9027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\tconst vec4 %s = vec4(109.0, 167.0, 23.0, 67.0);\n", yOffsets);
9037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // There are rounding errors if the floor operation is not performed here
9057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf(
9067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "\t\tvec3 %s = vec3(floor((%s*vec3(%s, 1.0)).xy) * vec2(0.66) * %s, 0.0);\n",
9077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        noiseVecIni, invMatrixUni, vCoords, baseFrequencyUni);
9087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Perturb the texcoords with three components of noise
9107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t%s += 0.1 * vec3(%s(%s + vec3(  0.0,   0.0, %s)),"
9117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                "%s(%s + vec3( 43.0,  17.0, %s)),"
9127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                "%s(%s + vec3(-17.0, -43.0, %s)));\n",
91358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                           noiseVecIni, noiseFuncName.c_str(), noiseVecIni, seedUni,
91458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                        noiseFuncName.c_str(), noiseVecIni, seedUni,
91558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                        noiseFuncName.c_str(), noiseVecIni, seedUni);
9167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t%s = vec4(0.0);\n", outputColor);
9187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\tvec3 %s = vec3(1.0);\n", factors);
9207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\tfloat %s = 0.0;\n", sum);
9217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Loop over all octaves
9237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\tfor (int octave = 0; octave < %d; ++octave) {\n", fNumOctaves);
9247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Loop over the 4 channels
9267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t\tfor (int %s = 3; %s >= 0; --%s) {\n", channel, channel, channel);
9277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf(
9297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        "\t\t\t\t%s[channel] += %s.x * %s(%s * %s.yyy - vec3(%s[%s], %s[%s], %s * %s.z));\n",
93058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        outputColor, factors, noiseFuncName.c_str(), noiseVecIni, factors, xOffsets, channel,
9317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        yOffsets, channel, seedUni, factors);
9327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppend("\t\t\t}\n"); // end of the for loop on channels
9347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t\t%s += %s.x;\n", sum, factors);
9367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t\t%s *= vec3(0.5, 2.0, 0.75);\n", factors);
9377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppend("\t\t}\n"); // end of the for loop on octaves
9397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fType == SkPerlinNoiseShader::kFractalNoise_Type) {
9417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
9427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // by fractalNoise and (turbulenceFunctionResult) by turbulence.
9437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        builder->fsCodeAppendf("\t\t%s = %s * vec4(0.5 / %s) + vec4(0.5);\n",
9447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               outputColor, outputColor, sum);
9457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    } else {
9467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        builder->fsCodeAppendf("\t\t%s = abs(%s / vec4(%s));\n",
9477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               outputColor, outputColor, sum);
9487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
9497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t%s.a *= %s;\n", outputColor, alphaUni);
9517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Clamp values
9537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
9547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Pre-multiply the result
9567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    builder->fsCodeAppendf("\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
9577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                           outputColor, outputColor, outputColor, outputColor);
9587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
9597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
9617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const GrDrawEffect&,
9627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               EffectKey key,
9637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const char* outputColor,
9647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const char* inputColor,
9657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               const TextureSamplerArray& samplers) {
9667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    sk_ignore_unused_variable(inputColor);
9677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* vCoords;
9697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &vCoords);
9707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fInvMatrixUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
9727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                        kMat33f_GrSLType, "invMatrix");
9737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* invMatrixUni = builder->getUniformCStr(fInvMatrixUni);
9747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fBaseFrequencyUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
9757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                            kVec2f_GrSLType, "baseFrequency");
9767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* baseFrequencyUni = builder->getUniformCStr(fBaseFrequencyUni);
9777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fAlphaUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
9787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                    kFloat_GrSLType, "alpha");
9797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* alphaUni = builder->getUniformCStr(fAlphaUni);
9807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* stitchDataUni = NULL;
9827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fStitchTiles) {
9837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fStitchDataUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
98458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                             kVec2f_GrSLType, "stitchData");
9857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        stitchDataUni = builder->getUniformCStr(fStitchDataUni);
9867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
9877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
98858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8
98958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const char* chanCoordR  = "0.125";
99058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const char* chanCoordG  = "0.375";
99158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const char* chanCoordB  = "0.625";
99258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const char* chanCoordA  = "0.875";
99358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const char* chanCoord   = "chanCoord";
9947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* stitchData  = "stitchData";
9957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* ratio       = "ratio";
9967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* noiseXY     = "noiseXY";
9977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* noiseVec    = "noiseVec";
9987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* noiseSmooth = "noiseSmooth";
9997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* fractVal    = "fractVal";
10007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* uv          = "uv";
10017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* ab          = "ab";
10027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* latticeIdx  = "latticeIdx";
10037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* lattice     = "lattice";
10047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* inc8bit     = "0.00390625";  // 1.0 / 256.0
10057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // This is the math to convert the two 16bit integer packed into rgba 8 bit input into a
10067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // [-1,1] vector and perform a dot product between that vector and the provided vector.
10077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const char* dotLattice  = "dot(((%s.ga + %s.rb * vec2(%s)) * vec2(2.0) - vec2(1.0)), %s);";
10087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
100958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // Add noise function
101058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    static const GrGLShaderVar gPerlinNoiseArgs[] =  {
101158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        GrGLShaderVar(chanCoord, kFloat_GrSLType),
101258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        GrGLShaderVar(noiseVec, kVec2f_GrSLType)
101358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    };
10147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
101558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    static const GrGLShaderVar gPerlinNoiseStitchArgs[] =  {
101658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        GrGLShaderVar(chanCoord, kFloat_GrSLType),
101758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        GrGLShaderVar(noiseVec, kVec2f_GrSLType),
101858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        GrGLShaderVar(stitchData, kVec2f_GrSLType)
101958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    };
10207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
102158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString noiseCode;
10227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
102358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\tvec4 %s = vec4(floor(%s), fract(%s));", noiseXY, noiseVec, noiseVec);
10247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
10257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // smooth curve : t * t * (3 - 2 * t)
102658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\tvec2 %s = %s.zw * %s.zw * (vec2(3.0) - vec2(2.0) * %s.zw);",
102758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseSmooth, noiseXY, noiseXY, noiseXY);
10287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
10297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Adjust frequencies if we're stitching tiles
10307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fStitchTiles) {
103158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }",
103258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseXY, stitchData, noiseXY, stitchData);
103358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\tif(%s.x >= (%s.x - 1.0)) { %s.x -= (%s.x - 1.0); }",
103458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseXY, stitchData, noiseXY, stitchData);
103558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }",
103658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseXY, stitchData, noiseXY, stitchData);
103758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\tif(%s.y >= (%s.y - 1.0)) { %s.y -= (%s.y - 1.0); }",
103858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseXY, stitchData, noiseXY, stitchData);
10397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
10407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
10417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Get texture coordinates and normalize
104258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s.xy = fract(floor(mod(%s.xy, 256.0)) / vec2(256.0));\n",
104358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseXY, noiseXY);
10447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
10457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Get permutation for x
10467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
10477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkString xCoords("");
10487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        xCoords.appendf("vec2(%s.x, 0.5)", noiseXY);
10497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
105058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx);
105158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
105258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.append(".r;");
10537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
10547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
10557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Get permutation for x + 1
10567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
10577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkString xCoords("");
10587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        xCoords.appendf("vec2(fract(%s.x + %s), 0.5)", noiseXY, inc8bit);
10597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
106058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\t%s.y = ", latticeIdx);
106158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), kVec2f_GrSLType);
106258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.append(".r;");
10637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
10647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
106558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if defined(SK_BUILD_FOR_ANDROID)
106658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Nexus 7 (Tegra 3).
106758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // The issue is that colors aren't accurate enough on Tegra devices. For example, if an 8 bit
106858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // value of 124 (or 0.486275 here) is entered, we can get a texture value of 123.513725
106958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // (or 0.484368 here). The following rounding operation prevents these precision issues from
107058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // affecting the result of the noise by making sure that we only have multiples of 1/255.
107158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // (Note that 1/255 is about 0.003921569, which is the value used here).
107258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s = floor(%s * vec2(255.0) + vec2(0.5)) * vec2(0.003921569);",
107358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                      latticeIdx, latticeIdx);
107458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif
107558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
10767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Get (x,y) coordinates with the permutated x
107758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s = fract(%s + %s.yy);", latticeIdx, latticeIdx, noiseXY);
10787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
107958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\tvec2 %s = %s.zw;", fractVal, noiseXY);
10807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
108158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\n\tvec2 %s;", uv);
10827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute u, at offset (0,0)
10837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
10847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkString latticeCoords("");
108558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        latticeCoords.appendf("vec2(%s.x, %s)", latticeIdx, chanCoord);
108658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf("\n\tvec4 %s = ", lattice);
108758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
108858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            kVec2f_GrSLType);
108958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
109058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
10917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
10927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
109358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal);
10947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute v, at offset (-1,0)
10957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
10967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkString latticeCoords("");
109758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        latticeCoords.appendf("vec2(%s.y, %s)", latticeIdx, chanCoord);
109858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.append("\n\tlattice = ");
109958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
110058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            kVec2f_GrSLType);
110158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
110258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
11037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
11047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
11057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute 'a' as a linear interpolation of 'u' and 'v'
110658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\tvec2 %s;", ab);
110758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth);
11087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
110958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal);
11107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute v, at offset (-1,-1)
11117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
11127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkString latticeCoords("");
111358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        latticeCoords.appendf("vec2(fract(%s.y + %s), %s)", latticeIdx, inc8bit, 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
112158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s.x += 1.0;", fractVal);
11227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute u, at offset (0,-1)
11237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    {
11247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkString latticeCoords("");
112558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        latticeCoords.appendf("vec2(fract(%s.x + %s), %s)", latticeIdx, inc8bit, chanCoord);
112658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.append("\n\tlattice = ");
112758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_str(),
112858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            kVec2f_GrSLType);
112958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
113058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
11317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
11327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
11337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute 'b' as a linear interpolation of 'u' and 'v'
113458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth);
11357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Compute the noise as a linear interpolation of 'a' and 'b'
113658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth);
113758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
113858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkString noiseFuncName;
113958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (fStitchTiles) {
114058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->emitFunction(GrGLShaderBuilder::kFragment_ShaderType, kFloat_GrSLType,
114158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                              "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitchArgs),
114258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                              gPerlinNoiseStitchArgs, noiseCode.c_str(), &noiseFuncName);
114358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    } else {
114458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->emitFunction(GrGLShaderBuilder::kFragment_ShaderType, kFloat_GrSLType,
114558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                              "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs),
114658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                              gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncName);
114758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
11487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
114958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // There are rounding errors if the floor operation is not performed here
115058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\tvec2 %s = floor((%s * vec3(%s, 1.0)).xy) * %s;",
115158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                           noiseVec, invMatrixUni, vCoords, baseFrequencyUni);
11527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
115358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // Clear the color accumulator
115458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t%s = vec4(0.0);", outputColor);
11557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
11567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fStitchTiles) {
115758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        // Set up TurbulenceInitial stitch values.
115858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni);
11597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
11607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
116158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\tfloat %s = 1.0;", ratio);
116258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
116358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // Loop over all octaves
116458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {", fNumOctaves);
116558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
116658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t\t%s += ", outputColor);
116758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (fType != SkPerlinNoiseShader::kFractalNoise_Type) {
116858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppend("abs(");
116958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
117058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (fStitchTiles) {
117158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppendf(
117258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s),"
117358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))",
117458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData,
117558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData,
117658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData,
117758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData);
117858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    } else {
117958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppendf(
118058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s),"
118158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))",
118258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordR, noiseVec,
118358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordG, noiseVec,
118458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordB, noiseVec,
118558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            noiseFuncName.c_str(), chanCoordA, noiseVec);
118658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
118758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (fType != SkPerlinNoiseShader::kFractalNoise_Type) {
118858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppendf(")"); // end of "abs("
118958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
119058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf(" * %s;", ratio);
119158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
119258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec);
119358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t\t%s *= 0.5;", ratio);
119458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
119558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (fStitchTiles) {
119658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData);
119758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
119858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppend("\n\t\t}"); // end of the for loop on octaves
11997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (fType == SkPerlinNoiseShader::kFractalNoise_Type) {
12017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
12027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // by fractalNoise and (turbulenceFunctionResult) by turbulence.
120358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        builder->fsCodeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", outputColor, outputColor);
12047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
12057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
120658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t%s.a *= %s;", outputColor, alphaUni);
12077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Clamp values
120958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", outputColor, outputColor);
12107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Pre-multiply the result
121258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    builder->fsCodeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
12137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                  outputColor, outputColor, outputColor, outputColor);
12147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
12157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGrGLNoise::GrGLNoise(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect)
12177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  : INHERITED (factory)
12187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fType(drawEffect.castEffect<GrPerlinNoiseEffect>().type())
12197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fStitchTiles(drawEffect.castEffect<GrPerlinNoiseEffect>().stitchTiles())
12207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fNumOctaves(drawEffect.castEffect<GrPerlinNoiseEffect>().numOctaves())
12217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger  , fEffectMatrix(drawEffect.castEffect<GrPerlinNoiseEffect>().coordsType()) {
12227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
12237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGrGLEffect::EffectKey GrGLNoise::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
12257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const GrPerlinNoiseEffect& turbulence = drawEffect.castEffect<GrPerlinNoiseEffect>();
12267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    EffectKey key = turbulence.numOctaves();
12287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    key = key << 3; // Make room for next 3 bits
12307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    switch (turbulence.type()) {
12327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case SkPerlinNoiseShader::kFractalNoise_Type:
12337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            key |= 0x1;
12347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
12357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case SkPerlinNoiseShader::kTurbulence_Type:
12367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            key |= 0x2;
12377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
12387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        default:
12397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            // leave key at 0
12407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
12417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
12427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (turbulence.stitchTiles()) {
12447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        key |= 0x4; // Flip the 3rd bit if tile stitching is on
12457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
12467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    key = key << GrGLEffectMatrix::kKeyBits;
12487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkMatrix m = turbulence.matrix();
12507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    m.postTranslate(SK_Scalar1, SK_Scalar1);
12517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return key | GrGLEffectMatrix::GenKey(m, drawEffect,
12527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                 drawEffect.castEffect<GrPerlinNoiseEffect>().coordsType(), NULL);
12537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
12547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrGLNoise::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
12567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const GrPerlinNoiseEffect& turbulence = drawEffect.castEffect<GrPerlinNoiseEffect>();
12577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkVector& baseFrequency = turbulence.baseFrequency();
12597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY);
12607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uman.set1f(fAlphaUni, SkScalarDiv(SkIntToScalar(turbulence.alpha()), SkIntToScalar(255)));
12617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkMatrix m = turbulence.matrix();
12637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkMatrix invM;
12647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (!m.invert(&invM)) {
12657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        invM.reset();
12667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    } else {
12677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        invM.postConcat(invM); // Square the matrix
12687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
12697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uman.setSkMatrix(fInvMatrixUni, invM);
12707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // This (1,1) translation is due to WebKit's 1 based coordinates for the noise
12727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // (as opposed to 0 based, usually). The same adjustment is in the shadeSpan() functions.
12737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    m.postTranslate(SK_Scalar1, SK_Scalar1);
12747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    fEffectMatrix.setData(uman, m, drawEffect, NULL);
12757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
12767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrGLPerlinNoise::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
12787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    INHERITED::setData(uman, drawEffect);
12797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const GrPerlinNoiseEffect& turbulence = drawEffect.castEffect<GrPerlinNoiseEffect>();
12817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (turbulence.stitchTiles()) {
12827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const SkPerlinNoiseShader::StitchData& stitchData = turbulence.stitchData();
128358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        uman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth),
128458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                   SkIntToScalar(stitchData.fHeight));
12857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
12867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
12877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrGLSimplexNoise::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
12897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    INHERITED::setData(uman, drawEffect);
12907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const GrSimplexNoiseEffect& turbulence = drawEffect.castEffect<GrSimplexNoiseEffect>();
12927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    uman.set1f(fSeedUni, turbulence.seed());
12937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
12947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/////////////////////////////////////////////////////////////////////
12967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
12977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& paint) const {
12987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(NULL != context);
12997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Either we don't stitch tiles, either we have a valid tile size
13017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(!fStitchTiles || !fTileSize.isEmpty());
13027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#ifdef SK_USE_SIMPLEX_NOISE
13047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Simplex noise is currently disabled but can be enabled by defining SK_USE_SIMPLEX_NOISE
13057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    sk_ignore_unused_variable(context);
13067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrEffectRef* effect =
13077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrSimplexNoiseEffect::Create(fType, fPaintingData->fBaseFrequency,
13087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                     fNumOctaves, fStitchTiles, fSeed,
13097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                     this->getLocalMatrix(), paint.getAlpha());
13107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#else
13117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrTexture* permutationsTexture = GrLockAndRefCachedBitmapTexture(
13127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        context, *fPaintingData->getPermutationsBitmap(), NULL);
13137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrTexture* noiseTexture = GrLockAndRefCachedBitmapTexture(
13147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        context, *fPaintingData->getNoiseBitmap(), NULL);
13157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    GrEffectRef* effect = (NULL != permutationsTexture) && (NULL != noiseTexture) ?
13177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrPerlinNoiseEffect::Create(fType, fPaintingData->fBaseFrequency,
13187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                    fNumOctaves, fStitchTiles,
13197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                    fPaintingData->fStitchDataInit,
13207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                    permutationsTexture, noiseTexture,
13217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                    this->getLocalMatrix(), paint.getAlpha()) :
13227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        NULL;
13237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // Unlock immediately, this is not great, but we don't have a way of
13257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // knowing when else to unlock it currently. TODO: Remove this when
13267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // unref becomes the unlock replacement for all types of textures.
13277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (NULL != permutationsTexture) {
13287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrUnlockAndUnrefCachedBitmapTexture(permutationsTexture);
13297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
13307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (NULL != noiseTexture) {
13317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrUnlockAndUnrefCachedBitmapTexture(noiseTexture);
13327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
13337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
13347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return effect;
13367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
13377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#else
13397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext*, const SkPaint&) const {
13417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkDEBUGFAIL("Should not call in GPU-less build");
13427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return NULL;
13437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
13447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
13467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#ifdef SK_DEVELOPER
13487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPerlinNoiseShader::toString(SkString* str) const {
13497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append("SkPerlinNoiseShader: (");
13507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append("type: ");
13527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    switch (fType) {
13537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case kFractalNoise_Type:
13547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            str->append("\"fractal noise\"");
13557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
13567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        case kTurbulence_Type:
13577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            str->append("\"turbulence\"");
13587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
13597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        default:
13607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            str->append("\"unknown\"");
13617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            break;
13627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
13637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(" base frequency: (");
13647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->appendScalar(fBaseFrequencyX);
13657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(", ");
13667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->appendScalar(fBaseFrequencyY);
13677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(") number of octaves: ");
13687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->appendS32(fNumOctaves);
13697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(" seed: ");
13707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->appendScalar(fSeed);
13717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(" stitch tiles: ");
13727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(fStitchTiles ? "true " : "false ");
13737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    this->INHERITED::toString(str);
13757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
13767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    str->append(")");
13777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
13787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
1379