1e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com/* 2e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com * Copyright 2013 Google Inc. 3e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com * 4e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com * Use of this source code is governed by a BSD-style license that can be 5e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com * found in the LICENSE file. 6e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com */ 7e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 8e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com#include "SkPerlinNoiseShader.h" 9c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org#include "SkColorFilter.h" 108b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 12e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com#include "SkShader.h" 13e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com#include "SkUnPreMultiply.h" 14e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com#include "SkString.h" 15e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 16e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com#if SK_SUPPORT_GPU 17e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com#include "GrContext.h" 1877af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com#include "GrCoordTransform.h" 19605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h" 20eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "SkGr.h" 21c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon#include "effects/GrConstColorProcessor.h" 2264c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLFragmentProcessor.h" 232d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h" 24018fb62d12d1febf121fe265da5b6117b86a6541egdaniel#include "glsl/GrGLSLProgramDataManager.h" 257ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLUniformHandler.h" 26e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com#endif 27e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 28e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comstatic const int kBlockSize = 256; 29e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comstatic const int kBlockMask = kBlockSize - 1; 30e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comstatic const int kPerlinNoise = 4096; 31e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comstatic const int kRandMaximum = SK_MaxS32; // 2**31 - 1 32e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 33e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comnamespace { 34e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 35e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com// noiseValue is the color component's value (or color) 36e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com// limitValue is the maximum perlin noise array index value allowed 37e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com// newValue is the current noise dimension (either width or height) 38e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.cominline int checkNoise(int noiseValue, int limitValue, int newValue) { 39e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // If the noise value would bring us out of bounds of the current noise array while we are 40e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // stiching noise tiles together, wrap the noise around the current dimension of the noise to 41e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // stay within the array bounds in a continuous fashion (so that tiling lines are not visible) 42e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com if (noiseValue >= limitValue) { 43e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com noiseValue -= newValue; 44e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 45e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com return noiseValue; 46e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 47e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 48e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.cominline SkScalar smoothCurve(SkScalar t) { 494b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org static const SkScalar SK_Scalar3 = 3.0f; 50e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 51e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // returns t * t * (3 - 2 * t) 52e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com return SkScalarMul(SkScalarSquare(t), SK_Scalar3 - 2 * t); 53e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 54e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 55e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} // end namespace 56e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 57e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comstruct SkPerlinNoiseShader::StitchData { 58e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com StitchData() 59e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com : fWidth(0) 60e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com , fWrapX(0) 61e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com , fHeight(0) 62e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com , fWrapY(0) 63e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com {} 64e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 65e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com bool operator==(const StitchData& other) const { 66e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com return fWidth == other.fWidth && 67e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fWrapX == other.fWrapX && 68e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fHeight == other.fHeight && 69e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fWrapY == other.fWrapY; 70e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 71e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 72e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int fWidth; // How much to subtract to wrap for stitching. 73e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int fWrapX; // Minimum value to wrap. 74e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int fHeight; 75e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int fWrapY; 76e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com}; 77e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 78e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comstruct SkPerlinNoiseShader::PaintingData { 79fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org PaintingData(const SkISize& tileSize, SkScalar seed, 80ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco SkScalar baseFrequencyX, SkScalar baseFrequencyY, 81ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco const SkMatrix& matrix) 82e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com { 8311fa2247b747eb75e2f158dc7571d458ed6c0115reed SkVector vec[2] = { 8411fa2247b747eb75e2f158dc7571d458ed6c0115reed { SkScalarInvert(baseFrequencyX), SkScalarInvert(baseFrequencyY) }, 8511fa2247b747eb75e2f158dc7571d458ed6c0115reed { SkIntToScalar(tileSize.fWidth), SkIntToScalar(tileSize.fHeight) }, 8611fa2247b747eb75e2f158dc7571d458ed6c0115reed }; 8711fa2247b747eb75e2f158dc7571d458ed6c0115reed matrix.mapVectors(vec, 2); 8811fa2247b747eb75e2f158dc7571d458ed6c0115reed 8911fa2247b747eb75e2f158dc7571d458ed6c0115reed fBaseFrequency.set(SkScalarInvert(vec[0].fX), SkScalarInvert(vec[0].fY)); 9011fa2247b747eb75e2f158dc7571d458ed6c0115reed fTileSize.set(SkScalarRoundToInt(vec[1].fX), SkScalarRoundToInt(vec[1].fY)); 91fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org this->init(seed); 92fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org if (!fTileSize.isEmpty()) { 93fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org this->stitch(); 94fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org } 95fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org 96f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco#if SK_SUPPORT_GPU 97a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org fPermutationsBitmap.setInfo(SkImageInfo::MakeA8(kBlockSize, 1)); 98fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org fPermutationsBitmap.setPixels(fLatticeSelector); 99fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org 100a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org fNoiseBitmap.setInfo(SkImageInfo::MakeN32Premul(kBlockSize, 4)); 101fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org fNoiseBitmap.setPixels(fNoise[0][0]); 102fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org#endif 103e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 104e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 105e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int fSeed; 106e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com uint8_t fLatticeSelector[kBlockSize]; 107e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com uint16_t fNoise[4][kBlockSize][2]; 108e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkPoint fGradient[4][kBlockSize]; 109e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkISize fTileSize; 110e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkVector fBaseFrequency; 111e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com StitchData fStitchDataInit; 112e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 113e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comprivate: 114e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 115f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco#if SK_SUPPORT_GPU 116fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org SkBitmap fPermutationsBitmap; 117fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org SkBitmap fNoiseBitmap; 118fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org#endif 119e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 120e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com inline int random() { 121e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com static const int gRandAmplitude = 16807; // 7**5; primitive root of m 122e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com static const int gRandQ = 127773; // m / a 123e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com static const int gRandR = 2836; // m % a 124e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 125e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int result = gRandAmplitude * (fSeed % gRandQ) - gRandR * (fSeed / gRandQ); 126e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com if (result <= 0) 127e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com result += kRandMaximum; 128e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fSeed = result; 129e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com return result; 130e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 131e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 132fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org // Only called once. Could be part of the constructor. 133e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com void init(SkScalar seed) 134e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com { 135e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com static const SkScalar gInvBlockSizef = SkScalarInvert(SkIntToScalar(kBlockSize)); 136e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 137857e320300372dab938c0dbffadc3c2c8a893b92senorblanco@chromium.org // According to the SVG spec, we must truncate (not round) the seed value. 138857e320300372dab938c0dbffadc3c2c8a893b92senorblanco@chromium.org fSeed = SkScalarTruncToInt(seed); 139e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // The seed value clamp to the range [1, kRandMaximum - 1]. 140e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com if (fSeed <= 0) { 141e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fSeed = -(fSeed % (kRandMaximum - 1)) + 1; 142e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 143e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com if (fSeed > kRandMaximum - 1) { 144e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fSeed = kRandMaximum - 1; 145e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 146e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int channel = 0; channel < 4; ++channel) { 147e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int i = 0; i < kBlockSize; ++i) { 148e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fLatticeSelector[i] = i; 149e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fNoise[channel][i][0] = (random() % (2 * kBlockSize)); 150e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fNoise[channel][i][1] = (random() % (2 * kBlockSize)); 151e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 152e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 153e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int i = kBlockSize - 1; i > 0; --i) { 154e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int k = fLatticeSelector[i]; 155e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int j = random() % kBlockSize; 156e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkASSERT(j >= 0); 157e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkASSERT(j < kBlockSize); 158e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fLatticeSelector[i] = fLatticeSelector[j]; 159e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fLatticeSelector[j] = k; 160e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 161e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 162e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Perform the permutations now 163e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com { 164e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Copy noise data 165e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com uint16_t noise[4][kBlockSize][2]; 166e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int i = 0; i < kBlockSize; ++i) { 167e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int channel = 0; channel < 4; ++channel) { 168e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int j = 0; j < 2; ++j) { 169e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com noise[channel][i][j] = fNoise[channel][i][j]; 170e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 171e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 172e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 173e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Do permutations on noise data 174e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int i = 0; i < kBlockSize; ++i) { 175e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int channel = 0; channel < 4; ++channel) { 176e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int j = 0; j < 2; ++j) { 177e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fNoise[channel][i][j] = noise[channel][fLatticeSelector[i]][j]; 178e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 179e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 180e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 181e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 182e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 183e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Half of the largest possible value for 16 bit unsigned int 1844b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org static const SkScalar gHalfMax16bits = 32767.5f; 185e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 186e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Compute gradients from permutated noise data 187e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int channel = 0; channel < 4; ++channel) { 188e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int i = 0; i < kBlockSize; ++i) { 189e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fGradient[channel][i] = SkPoint::Make( 190e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalarMul(SkIntToScalar(fNoise[channel][i][0] - kBlockSize), 191e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com gInvBlockSizef), 192cff0243b0ff1de25b3d99e2bf15a30c0e0a31261skia.committer@gmail.com SkScalarMul(SkIntToScalar(fNoise[channel][i][1] - kBlockSize), 193e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com gInvBlockSizef)); 194e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fGradient[channel][i].normalize(); 195e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Put the normalized gradient back into the noise data 196e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fNoise[channel][i][0] = SkScalarRoundToInt(SkScalarMul( 197d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com fGradient[channel][i].fX + SK_Scalar1, gHalfMax16bits)); 198e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fNoise[channel][i][1] = SkScalarRoundToInt(SkScalarMul( 199d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com fGradient[channel][i].fY + SK_Scalar1, gHalfMax16bits)); 200e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 201e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 202e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 203e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 204fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org // Only called once. Could be part of the constructor. 205e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com void stitch() { 206e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar tileWidth = SkIntToScalar(fTileSize.width()); 207e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar tileHeight = SkIntToScalar(fTileSize.height()); 208e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkASSERT(tileWidth > 0 && tileHeight > 0); 209e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // When stitching tiled turbulence, the frequencies must be adjusted 210e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // so that the tile borders will be continuous. 211e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com if (fBaseFrequency.fX) { 2128015cdd8fa5694e52b70e728bcdc6b35d739b819reed@google.com SkScalar lowFrequencx = 2138015cdd8fa5694e52b70e728bcdc6b35d739b819reed@google.com SkScalarFloorToScalar(tileWidth * fBaseFrequency.fX) / tileWidth; 2148015cdd8fa5694e52b70e728bcdc6b35d739b819reed@google.com SkScalar highFrequencx = 2158015cdd8fa5694e52b70e728bcdc6b35d739b819reed@google.com SkScalarCeilToScalar(tileWidth * fBaseFrequency.fX) / tileWidth; 216e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // BaseFrequency should be non-negative according to the standard. 21780ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed if (fBaseFrequency.fX / lowFrequencx < highFrequencx / fBaseFrequency.fX) { 218e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fBaseFrequency.fX = lowFrequencx; 219e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } else { 220e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fBaseFrequency.fX = highFrequencx; 221e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 222e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 223e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com if (fBaseFrequency.fY) { 2248015cdd8fa5694e52b70e728bcdc6b35d739b819reed@google.com SkScalar lowFrequency = 2258015cdd8fa5694e52b70e728bcdc6b35d739b819reed@google.com SkScalarFloorToScalar(tileHeight * fBaseFrequency.fY) / tileHeight; 2268015cdd8fa5694e52b70e728bcdc6b35d739b819reed@google.com SkScalar highFrequency = 2278015cdd8fa5694e52b70e728bcdc6b35d739b819reed@google.com SkScalarCeilToScalar(tileHeight * fBaseFrequency.fY) / tileHeight; 22880ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed if (fBaseFrequency.fY / lowFrequency < highFrequency / fBaseFrequency.fY) { 229e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fBaseFrequency.fY = lowFrequency; 230e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } else { 231e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fBaseFrequency.fY = highFrequency; 232e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 233e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 234e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Set up TurbulenceInitial stitch values. 235e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fStitchDataInit.fWidth = 2368015cdd8fa5694e52b70e728bcdc6b35d739b819reed@google.com SkScalarRoundToInt(tileWidth * fBaseFrequency.fX); 237e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fStitchDataInit.fWrapX = kPerlinNoise + fStitchDataInit.fWidth; 238e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fStitchDataInit.fHeight = 2398015cdd8fa5694e52b70e728bcdc6b35d739b819reed@google.com SkScalarRoundToInt(tileHeight * fBaseFrequency.fY); 240e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fStitchDataInit.fWrapY = kPerlinNoise + fStitchDataInit.fHeight; 241e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 242e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 243fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.orgpublic: 244e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 245f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco#if SK_SUPPORT_GPU 246fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org const SkBitmap& getPermutationsBitmap() const { return fPermutationsBitmap; } 247fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org 248fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org const SkBitmap& getNoiseBitmap() const { return fNoiseBitmap; } 249fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org#endif 250e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com}; 251e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 252e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comSkShader* SkPerlinNoiseShader::CreateFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY, 253e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int numOctaves, SkScalar seed, 254e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const SkISize* tileSize) { 255385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkPerlinNoiseShader(kFractalNoise_Type, baseFrequencyX, baseFrequencyY, numOctaves, 256385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary seed, tileSize); 257e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 258e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 2599fbbcca1c958e6df2cff24d3ccdb7ebd89b8486bcommit-bot@chromium.orgSkShader* SkPerlinNoiseShader::CreateTurbulence(SkScalar baseFrequencyX, SkScalar baseFrequencyY, 260e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int numOctaves, SkScalar seed, 261e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const SkISize* tileSize) { 262385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkPerlinNoiseShader(kTurbulence_Type, baseFrequencyX, baseFrequencyY, numOctaves, 263385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary seed, tileSize); 264e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 265e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 266e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comSkPerlinNoiseShader::SkPerlinNoiseShader(SkPerlinNoiseShader::Type type, 267e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar baseFrequencyX, 268e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar baseFrequencyY, 269e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int numOctaves, 270e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar seed, 271e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const SkISize* tileSize) 272e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com : fType(type) 273e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com , fBaseFrequencyX(baseFrequencyX) 274e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com , fBaseFrequencyY(baseFrequencyY) 275ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org , fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/) 276e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com , fSeed(seed) 27796fcdcc219d2a0d3579719b84b28bede76efba64halcanary , fTileSize(nullptr == tileSize ? SkISize::Make(0, 0) : *tileSize) 278fd5c9a6e04ba31a82670d281b03b9c4a3f9b6e3ccommit-bot@chromium.org , fStitchTiles(!fTileSize.isEmpty()) 279e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com{ 280e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkASSERT(numOctaves >= 0 && numOctaves < 256); 281e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 282e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 283e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comSkPerlinNoiseShader::~SkPerlinNoiseShader() { 284e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 285e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 2869fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkPerlinNoiseShader::CreateProc(SkReadBuffer& buffer) { 2879fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed Type type = (Type)buffer.readInt(); 2889fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkScalar freqX = buffer.readScalar(); 2899fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkScalar freqY = buffer.readScalar(); 2909fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed int octaves = buffer.readInt(); 2919fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkScalar seed = buffer.readScalar(); 2929fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkISize tileSize; 2939fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed tileSize.fWidth = buffer.readInt(); 2949fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed tileSize.fHeight = buffer.readInt(); 2959fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 2969fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed switch (type) { 2979fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed case kFractalNoise_Type: 2989fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return SkPerlinNoiseShader::CreateFractalNoise(freqX, freqY, octaves, seed, &tileSize); 2999fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed case kTurbulence_Type: 3009fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return SkPerlinNoiseShader::CreateTubulence(freqX, freqY, octaves, seed, &tileSize); 3019fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed default: 30296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 3039fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 3049fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 3059fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 3068b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkPerlinNoiseShader::flatten(SkWriteBuffer& buffer) const { 307e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com buffer.writeInt((int) fType); 308e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com buffer.writeScalar(fBaseFrequencyX); 309e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com buffer.writeScalar(fBaseFrequencyY); 310e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com buffer.writeInt(fNumOctaves); 311e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com buffer.writeScalar(fSeed); 312e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com buffer.writeInt(fTileSize.fWidth); 313e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com buffer.writeInt(fTileSize.fHeight); 314e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 315e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 31687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::noise2D( 317ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco int channel, const StitchData& stitchData, const SkPoint& noiseVector) const { 318e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com struct Noise { 319e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int noisePositionIntegerValue; 320ce6a354e121915c2925e545e7df2929492d69d50senorblanco int nextNoisePositionIntegerValue; 321e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar noisePositionFractionValue; 322e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com Noise(SkScalar component) 323e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com { 324e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar position = component + kPerlinNoise; 325e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com noisePositionIntegerValue = SkScalarFloorToInt(position); 326e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com noisePositionFractionValue = position - SkIntToScalar(noisePositionIntegerValue); 327ce6a354e121915c2925e545e7df2929492d69d50senorblanco nextNoisePositionIntegerValue = noisePositionIntegerValue + 1; 328e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 329e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com }; 330e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com Noise noiseX(noiseVector.x()); 331e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com Noise noiseY(noiseVector.y()); 332e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar u, v; 33387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoiseShader&>(fShader); 334e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // If stitching, adjust lattice points accordingly. 33587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (perlinNoiseShader.fStitchTiles) { 336e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com noiseX.noisePositionIntegerValue = 337e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth); 338e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com noiseY.noisePositionIntegerValue = 339e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight); 340ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseX.nextNoisePositionIntegerValue = 341ce6a354e121915c2925e545e7df2929492d69d50senorblanco checkNoise(noiseX.nextNoisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth); 342ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseY.nextNoisePositionIntegerValue = 343ce6a354e121915c2925e545e7df2929492d69d50senorblanco checkNoise(noiseY.nextNoisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight); 344e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 345e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com noiseX.noisePositionIntegerValue &= kBlockMask; 346e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com noiseY.noisePositionIntegerValue &= kBlockMask; 347ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseX.nextNoisePositionIntegerValue &= kBlockMask; 348ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseY.nextNoisePositionIntegerValue &= kBlockMask; 349ce6a354e121915c2925e545e7df2929492d69d50senorblanco int i = 350ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco fPaintingData->fLatticeSelector[noiseX.noisePositionIntegerValue]; 351ce6a354e121915c2925e545e7df2929492d69d50senorblanco int j = 352ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco fPaintingData->fLatticeSelector[noiseX.nextNoisePositionIntegerValue]; 353ce6a354e121915c2925e545e7df2929492d69d50senorblanco int b00 = (i + noiseY.noisePositionIntegerValue) & kBlockMask; 354ce6a354e121915c2925e545e7df2929492d69d50senorblanco int b10 = (j + noiseY.noisePositionIntegerValue) & kBlockMask; 355ce6a354e121915c2925e545e7df2929492d69d50senorblanco int b01 = (i + noiseY.nextNoisePositionIntegerValue) & kBlockMask; 356ce6a354e121915c2925e545e7df2929492d69d50senorblanco int b11 = (j + noiseY.nextNoisePositionIntegerValue) & kBlockMask; 357e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar sx = smoothCurve(noiseX.noisePositionFractionValue); 358e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar sy = smoothCurve(noiseY.noisePositionFractionValue); 359e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement 360e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue, 361e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com noiseY.noisePositionFractionValue); // Offset (0,0) 362ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco u = fPaintingData->fGradient[channel][b00].dot(fractionValue); 363e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fractionValue.fX -= SK_Scalar1; // Offset (-1,0) 364ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco v = fPaintingData->fGradient[channel][b10].dot(fractionValue); 365e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar a = SkScalarInterp(u, v, sx); 366e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fractionValue.fY -= SK_Scalar1; // Offset (-1,-1) 367ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco v = fPaintingData->fGradient[channel][b11].dot(fractionValue); 368e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1) 369ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco u = fPaintingData->fGradient[channel][b01].dot(fractionValue); 370e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar b = SkScalarInterp(u, v, sx); 371e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com return SkScalarInterp(a, b, sy); 372e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 373e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 37487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::calculateTurbulenceValueForPoint( 375ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco int channel, StitchData& stitchData, const SkPoint& point) const { 37687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoiseShader&>(fShader); 37787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (perlinNoiseShader.fStitchTiles) { 378e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Set up TurbulenceInitial stitch values. 379ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco stitchData = fPaintingData->fStitchDataInit; 380e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 381e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar turbulenceFunctionResult = 0; 382ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco SkPoint noiseVector(SkPoint::Make(SkScalarMul(point.x(), fPaintingData->fBaseFrequency.fX), 383ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco SkScalarMul(point.y(), fPaintingData->fBaseFrequency.fY))); 384e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalar ratio = SK_Scalar1; 38587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org for (int octave = 0; octave < perlinNoiseShader.fNumOctaves; ++octave) { 386ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco SkScalar noise = noise2D(channel, stitchData, noiseVector); 38780ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed SkScalar numer = (perlinNoiseShader.fType == kFractalNoise_Type) ? 38880ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed noise : SkScalarAbs(noise); 38980ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed turbulenceFunctionResult += numer / ratio; 390e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com noiseVector.fX *= 2; 391e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com noiseVector.fY *= 2; 392e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com ratio *= 2; 39387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (perlinNoiseShader.fStitchTiles) { 394e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Update stitch values 395e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com stitchData.fWidth *= 2; 396e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com stitchData.fWrapX = stitchData.fWidth + kPerlinNoise; 397e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com stitchData.fHeight *= 2; 398e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com stitchData.fWrapY = stitchData.fHeight + kPerlinNoise; 399e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 400e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 401e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 402e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2 403e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // by fractalNoise and (turbulenceFunctionResult) by turbulence. 40487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org if (perlinNoiseShader.fType == kFractalNoise_Type) { 405e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com turbulenceFunctionResult = 406e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkScalarMul(turbulenceFunctionResult, SK_ScalarHalf) + SK_ScalarHalf; 407e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 408e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 409e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com if (channel == 3) { // Scale alpha by paint value 41080ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed turbulenceFunctionResult *= SkIntToScalar(getPaintAlpha()) / 255; 411e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 412e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 413e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Clamp result 414e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1); 415e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 416e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 41787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkPMColor SkPerlinNoiseShader::PerlinNoiseShaderContext::shade( 41887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkPoint& point, StitchData& stitchData) const { 419e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkPoint newPoint; 420a8d95f899bf3fe404d3cd5c357531ff852c15b29senorblanco@chromium.org fMatrix.mapPoints(&newPoint, &point, 1); 421e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com newPoint.fX = SkScalarRoundToScalar(newPoint.fX); 422e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com newPoint.fY = SkScalarRoundToScalar(newPoint.fY); 423e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 424e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com U8CPU rgba[4]; 425e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int channel = 3; channel >= 0; --channel) { 426e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com rgba[channel] = SkScalarFloorToInt(255 * 427ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco calculateTurbulenceValueForPoint(channel, stitchData, newPoint)); 428e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 429e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]); 430e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 431e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 432ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgSkShader::Context* SkPerlinNoiseShader::onCreateContext(const ContextRec& rec, 433ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org void* storage) const { 434385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new (storage) PerlinNoiseShaderContext(*this, rec); 43587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org} 43687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 4378d9f2e474ac9d175c28079357b022d31408e2fe4fmalitasize_t SkPerlinNoiseShader::contextSize(const ContextRec&) const { 43887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org return sizeof(PerlinNoiseShaderContext); 43987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org} 44087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 44187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkPerlinNoiseShader::PerlinNoiseShaderContext::PerlinNoiseShaderContext( 442e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org const SkPerlinNoiseShader& shader, const ContextRec& rec) 443e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org : INHERITED(shader, rec) 44487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org{ 445e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org SkMatrix newMatrix = *rec.fMatrix; 446b67b8e6052bf5567eb3f9726dda99a6b260dfb05reed@google.com newMatrix.preConcat(shader.getLocalMatrix()); 447b67b8e6052bf5567eb3f9726dda99a6b260dfb05reed@google.com if (rec.fLocalMatrix) { 448b67b8e6052bf5567eb3f9726dda99a6b260dfb05reed@google.com newMatrix.preConcat(*rec.fLocalMatrix); 449b67b8e6052bf5567eb3f9726dda99a6b260dfb05reed@google.com } 450a8d95f899bf3fe404d3cd5c357531ff852c15b29senorblanco@chromium.org // This (1,1) translation is due to WebKit's 1 based coordinates for the noise 451a8d95f899bf3fe404d3cd5c357531ff852c15b29senorblanco@chromium.org // (as opposed to 0 based, usually). The same adjustment is in the setData() function. 452ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco fMatrix.setTranslate(-newMatrix.getTranslateX() + SK_Scalar1, -newMatrix.getTranslateY() + SK_Scalar1); 453385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary fPaintingData = new PaintingData(shader.fTileSize, shader.fSeed, shader.fBaseFrequencyX, 454385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary shader.fBaseFrequencyY, newMatrix); 455ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco} 456ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco 457385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanarySkPerlinNoiseShader::PerlinNoiseShaderContext::~PerlinNoiseShaderContext() { delete fPaintingData; } 458e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 45987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkPerlinNoiseShader::PerlinNoiseShaderContext::shadeSpan( 46087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org int x, int y, SkPMColor result[], int count) { 461e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y)); 462e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com StitchData stitchData; 463e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com for (int i = 0; i < count; ++i) { 464e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com result[i] = shade(point, stitchData); 465e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com point.fX += SK_Scalar1; 466e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 467e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 468e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 469e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com///////////////////////////////////////////////////////////////////// 470e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 471344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org#if SK_SUPPORT_GPU 472e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 47364c4728c70001ed074fecf5c4e083781987b12e9egdanielclass GrGLPerlinNoise : public GrGLSLFragmentProcessor { 4744775cba7b37e24e8480bd2d96e297fd0828fb5c3sugoi@google.compublic: 4759cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips void emitCode(EmitArgs&) override; 476e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 477bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*); 4784775cba7b37e24e8480bd2d96e297fd0828fb5c3sugoi@google.com 479b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyixprotected: 480018fb62d12d1febf121fe265da5b6117b86a6541egdaniel void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override; 481b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix 482f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblancoprivate: 483018fb62d12d1febf121fe265da5b6117b86a6541egdaniel GrGLSLProgramDataManager::UniformHandle fStitchDataUni; 484018fb62d12d1febf121fe265da5b6117b86a6541egdaniel GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni; 485e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 48664c4728c70001ed074fecf5c4e083781987b12e9egdaniel typedef GrGLSLFragmentProcessor INHERITED; 487e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com}; 488e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 489e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com///////////////////////////////////////////////////////////////////// 490e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 491b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrPerlinNoiseEffect : public GrFragmentProcessor { 492e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.compublic: 4934a339529612a43871d021877e58698e067d6c4cdbsalomon static GrFragmentProcessor* Create(SkPerlinNoiseShader::Type type, 494b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int numOctaves, bool stitchTiles, 495b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkPerlinNoiseShader::PaintingData* paintingData, 496b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* permutationsTexture, GrTexture* noiseTexture, 497c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon const SkMatrix& matrix) { 4984a339529612a43871d021877e58698e067d6c4cdbsalomon return new GrPerlinNoiseEffect(type, numOctaves, stitchTiles, paintingData, 499c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon permutationsTexture, noiseTexture, matrix); 500e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 501e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 502385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary virtual ~GrPerlinNoiseEffect() { delete fPaintingData; } 503e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 50436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "PerlinNoise"; } 505eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 506ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco const SkPerlinNoiseShader::StitchData& stitchData() const { return fPaintingData->fStitchDataInit; } 507e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 508f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco SkPerlinNoiseShader::Type type() const { return fType; } 509f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco bool stitchTiles() const { return fStitchTiles; } 510ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency; } 511f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco int numOctaves() const { return fNumOctaves; } 512f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); } 513f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco 514e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comprivate: 51557d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 516bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips return new GrGLPerlinNoise; 517b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix } 518b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix 51957d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps, 52057d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrProcessorKeyBuilder* b) const override { 5214b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix GrGLPerlinNoise::GenKey(*this, caps, b); 5224b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix } 5234b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix 52436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onIsEqual(const GrFragmentProcessor& sBase) const override { 52549586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrPerlinNoiseEffect& s = sBase.cast<GrPerlinNoiseEffect>(); 526f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco return fType == s.fType && 527ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency && 528f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco fNumOctaves == s.fNumOctaves && 529f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco fStitchTiles == s.fStitchTiles && 530ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco fPaintingData->fStitchDataInit == s.fPaintingData->fStitchDataInit; 531e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 532e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 53336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 534605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel inout->setToUnknown(GrInvariantOutput::kWillNot_ReadInput); 5351a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel } 5361a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel 5374a339529612a43871d021877e58698e067d6c4cdbsalomon GrPerlinNoiseEffect(SkPerlinNoiseShader::Type type, 538e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com int numOctaves, bool stitchTiles, 539ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco SkPerlinNoiseShader::PaintingData* paintingData, 540e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com GrTexture* permutationsTexture, GrTexture* noiseTexture, 541c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon const SkMatrix& matrix) 542f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco : fType(type) 543f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco , fNumOctaves(numOctaves) 544f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco , fStitchTiles(stitchTiles) 5454775cba7b37e24e8480bd2d96e297fd0828fb5c3sugoi@google.com , fPermutationsAccess(permutationsTexture) 546e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com , fNoiseAccess(noiseTexture) 547ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco , fPaintingData(paintingData) { 548eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt this->initClassID<GrPerlinNoiseEffect>(); 549e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com this->addTextureAccess(&fPermutationsAccess); 550e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com this->addTextureAccess(&fNoiseAccess); 551ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco fCoordTransform.reset(kLocal_GrCoordSet, matrix); 552f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco this->addCoordTransform(&fCoordTransform); 553e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 554e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 555b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 556e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 557f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco SkPerlinNoiseShader::Type fType; 558f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco GrCoordTransform fCoordTransform; 559f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco int fNumOctaves; 560f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco bool fStitchTiles; 561e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com GrTextureAccess fPermutationsAccess; 562e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com GrTextureAccess fNoiseAccess; 563ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco SkPerlinNoiseShader::PaintingData *fPaintingData; 564e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 5654775cba7b37e24e8480bd2d96e297fd0828fb5c3sugoi@google.comprivate: 566b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrFragmentProcessor INHERITED; 567e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com}; 568e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 569e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com///////////////////////////////////////////////////////////////////// 570b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrPerlinNoiseEffect); 571e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 572c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonconst GrFragmentProcessor* GrPerlinNoiseEffect::TestCreate(GrProcessorTestData* d) { 5730067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt int numOctaves = d->fRandom->nextRangeU(2, 10); 5740067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt bool stitchTiles = d->fRandom->nextBool(); 5750067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt SkScalar seed = SkIntToScalar(d->fRandom->nextU()); 5760067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt SkISize tileSize = SkISize::Make(d->fRandom->nextRangeU(4, 4096), 5770067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt d->fRandom->nextRangeU(4, 4096)); 5780067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt SkScalar baseFrequencyX = d->fRandom->nextRangeScalar(0.01f, 5790067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt 0.99f); 5800067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt SkScalar baseFrequencyY = d->fRandom->nextRangeScalar(0.01f, 5810067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt 0.99f); 5820067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt 5836d2a203117015b4da13dbc5f627646df69d92653bsalomon SkAutoTUnref<SkShader> shader(d->fRandom->nextBool() ? 584e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkPerlinNoiseShader::CreateFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves, seed, 58596fcdcc219d2a0d3579719b84b28bede76efba64halcanary stitchTiles ? &tileSize : nullptr) : 5869fbbcca1c958e6df2cff24d3ccdb7ebd89b8486bcommit-bot@chromium.org SkPerlinNoiseShader::CreateTurbulence(baseFrequencyX, baseFrequencyY, numOctaves, seed, 5876d2a203117015b4da13dbc5f627646df69d92653bsalomon stitchTiles ? &tileSize : nullptr)); 588e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 589c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon return shader->asFragmentProcessor(d->fContext, 590c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon GrTest::TestMatrix(d->fRandom), nullptr, 5914a339529612a43871d021877e58698e067d6c4cdbsalomon kNone_SkFilterQuality); 592e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 5934775cba7b37e24e8480bd2d96e297fd0828fb5c3sugoi@google.com 5947c157a988845fb00f9024d6db6dda142c3458033wangyixvoid GrGLPerlinNoise::emitCode(EmitArgs& args) { 595bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips const GrPerlinNoiseEffect& pne = args.fFp.cast<GrPerlinNoiseEffect>(); 596bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips 5978528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 5987ea439b2203855db97330b25945b87dd4b170b8begdaniel GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 5994ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel SkString vCoords = fragBuilder->ensureFSCoords2D(args.fCoords, 0); 600e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 6015e58ceea8569f0d90ff7e3daf5de2def50407212cdalton fBaseFrequencyUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 6027ea439b2203855db97330b25945b87dd4b170b8begdaniel kVec2f_GrSLType, kDefault_GrSLPrecision, 6037ea439b2203855db97330b25945b87dd4b170b8begdaniel "baseFrequency"); 6047ea439b2203855db97330b25945b87dd4b170b8begdaniel const char* baseFrequencyUni = uniformHandler->getUniformCStr(fBaseFrequencyUni); 605e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 60696fcdcc219d2a0d3579719b84b28bede76efba64halcanary const char* stitchDataUni = nullptr; 607bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips if (pne.stitchTiles()) { 6085e58ceea8569f0d90ff7e3daf5de2def50407212cdalton fStitchDataUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 6097ea439b2203855db97330b25945b87dd4b170b8begdaniel kVec2f_GrSLType, kDefault_GrSLPrecision, 6107ea439b2203855db97330b25945b87dd4b170b8begdaniel "stitchData"); 6117ea439b2203855db97330b25945b87dd4b170b8begdaniel stitchDataUni = uniformHandler->getUniformCStr(fStitchDataUni); 612e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 613e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 614d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8 615d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com const char* chanCoordR = "0.125"; 616d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com const char* chanCoordG = "0.375"; 617d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com const char* chanCoordB = "0.625"; 618d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com const char* chanCoordA = "0.875"; 619d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com const char* chanCoord = "chanCoord"; 620e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const char* stitchData = "stitchData"; 621e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const char* ratio = "ratio"; 622e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const char* noiseVec = "noiseVec"; 623e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const char* noiseSmooth = "noiseSmooth"; 624ce6a354e121915c2925e545e7df2929492d69d50senorblanco const char* floorVal = "floorVal"; 625e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const char* fractVal = "fractVal"; 626e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const char* uv = "uv"; 627e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const char* ab = "ab"; 628e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const char* latticeIdx = "latticeIdx"; 629ce6a354e121915c2925e545e7df2929492d69d50senorblanco const char* bcoords = "bcoords"; 630e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const char* lattice = "lattice"; 631e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const char* inc8bit = "0.00390625"; // 1.0 / 256.0 632e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // This is the math to convert the two 16bit integer packed into rgba 8 bit input into a 633e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // [-1,1] vector and perform a dot product between that vector and the provided vector. 634e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const char* dotLattice = "dot(((%s.ga + %s.rb * vec2(%s)) * vec2(2.0) - vec2(1.0)), %s);"; 635e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 636d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com // Add noise function 6370d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel static const GrGLSLShaderVar gPerlinNoiseArgs[] = { 6380d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel GrGLSLShaderVar(chanCoord, kFloat_GrSLType), 6390d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel GrGLSLShaderVar(noiseVec, kVec2f_GrSLType) 640d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com }; 641e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 6420d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel static const GrGLSLShaderVar gPerlinNoiseStitchArgs[] = { 6430d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel GrGLSLShaderVar(chanCoord, kFloat_GrSLType), 6440d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel GrGLSLShaderVar(noiseVec, kVec2f_GrSLType), 6450d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel GrGLSLShaderVar(stitchData, kVec2f_GrSLType) 646d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com }; 647e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 648d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com SkString noiseCode; 649e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 650ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseCode.appendf("\tvec4 %s;\n", floorVal); 651ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec); 652ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseCode.appendf("\t%s.zw = %s.xy + vec2(1.0);\n", floorVal, floorVal); 653ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseCode.appendf("\tvec2 %s = fract(%s);\n", fractVal, noiseVec); 654e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 655e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // smooth curve : t * t * (3 - 2 * t) 656ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseCode.appendf("\n\tvec2 %s = %s * %s * (vec2(3.0) - vec2(2.0) * %s);", 657ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseSmooth, fractVal, fractVal, fractVal); 658e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 659e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Adjust frequencies if we're stitching tiles 660bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips if (pne.stitchTiles()) { 6619839320ae17ab1c2182dc144db5ba94caa1bde56commit-bot@chromium.org noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }", 6624ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel floorVal, stitchData, floorVal, stitchData); 6639839320ae17ab1c2182dc144db5ba94caa1bde56commit-bot@chromium.org noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }", 6644ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel floorVal, stitchData, floorVal, stitchData); 665ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }", 6664ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel floorVal, stitchData, floorVal, stitchData); 667ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }", 6684ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel floorVal, stitchData, floorVal, stitchData); 669e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 670e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 671e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Get texture coordinates and normalize 672ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseCode.appendf("\n\t%s = fract(floor(mod(%s, 256.0)) / vec4(256.0));\n", 6734ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel floorVal, floorVal); 674e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 675e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Get permutation for x 676e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com { 677e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkString xCoords(""); 678ce6a354e121915c2925e545e7df2929492d69d50senorblanco xCoords.appendf("vec2(%s.x, 0.5)", floorVal); 679e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 680d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx); 6814ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->appendTextureLookup(&noiseCode, args.fSamplers[0], xCoords.c_str(), 6824ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel kVec2f_GrSLType); 683d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.append(".r;"); 684e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 685e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 686e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Get permutation for x + 1 687e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com { 688e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkString xCoords(""); 689ce6a354e121915c2925e545e7df2929492d69d50senorblanco xCoords.appendf("vec2(%s.z, 0.5)", floorVal); 690e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 691d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf("\n\t%s.y = ", latticeIdx); 6924ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->appendTextureLookup(&noiseCode, args.fSamplers[0], xCoords.c_str(), 6934ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel kVec2f_GrSLType); 694d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.append(".r;"); 695e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 696e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 697344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org#if defined(SK_BUILD_FOR_ANDROID) 698344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Nexus 7 (Tegra 3). 699344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org // The issue is that colors aren't accurate enough on Tegra devices. For example, if an 8 bit 700344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org // value of 124 (or 0.486275 here) is entered, we can get a texture value of 123.513725 701344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org // (or 0.484368 here). The following rounding operation prevents these precision issues from 702344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org // affecting the result of the noise by making sure that we only have multiples of 1/255. 703344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org // (Note that 1/255 is about 0.003921569, which is the value used here). 704344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org noiseCode.appendf("\n\t%s = floor(%s * vec2(255.0) + vec2(0.5)) * vec2(0.003921569);", 705344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org latticeIdx, latticeIdx); 706344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org#endif 707344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org 708e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Get (x,y) coordinates with the permutated x 709ce6a354e121915c2925e545e7df2929492d69d50senorblanco noiseCode.appendf("\n\tvec4 %s = fract(%s.xyxy + %s.yyww);", bcoords, latticeIdx, floorVal); 710e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 711d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf("\n\n\tvec2 %s;", uv); 712e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Compute u, at offset (0,0) 713e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com { 714e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkString latticeCoords(""); 715ce6a354e121915c2925e545e7df2929492d69d50senorblanco latticeCoords.appendf("vec2(%s.x, %s)", bcoords, chanCoord); 716d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf("\n\tvec4 %s = ", lattice); 7174ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(), 7184ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel kVec2f_GrSLType); 719d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf(".bgra;\n\t%s.x = ", uv); 720d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); 721e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 722e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 723d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal); 724e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Compute v, at offset (-1,0) 725e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com { 726e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkString latticeCoords(""); 727ce6a354e121915c2925e545e7df2929492d69d50senorblanco latticeCoords.appendf("vec2(%s.y, %s)", bcoords, chanCoord); 728344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org noiseCode.append("\n\tlattice = "); 7294ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(), 7304ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel kVec2f_GrSLType); 731d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf(".bgra;\n\t%s.y = ", uv); 732d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); 733e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 734e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 735e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Compute 'a' as a linear interpolation of 'u' and 'v' 736d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf("\n\tvec2 %s;", ab); 737d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth); 738e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 739d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal); 740e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Compute v, at offset (-1,-1) 741e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com { 742e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkString latticeCoords(""); 743ce6a354e121915c2925e545e7df2929492d69d50senorblanco latticeCoords.appendf("vec2(%s.w, %s)", bcoords, chanCoord); 744344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org noiseCode.append("\n\tlattice = "); 7454ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(), 7464ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel kVec2f_GrSLType); 747d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf(".bgra;\n\t%s.y = ", uv); 748d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); 749e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 750e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 751d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf("\n\t%s.x += 1.0;", fractVal); 752e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Compute u, at offset (0,-1) 753e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com { 754e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkString latticeCoords(""); 755ce6a354e121915c2925e545e7df2929492d69d50senorblanco latticeCoords.appendf("vec2(%s.z, %s)", bcoords, chanCoord); 756344cf45a40c7de3c4664f8a048d4017af88adfeecommit-bot@chromium.org noiseCode.append("\n\tlattice = "); 7574ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(), 7584ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel kVec2f_GrSLType); 759d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf(".bgra;\n\t%s.x = ", uv); 760d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); 761e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 762e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 763e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Compute 'b' as a linear interpolation of 'u' and 'v' 764d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth); 765e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Compute the noise as a linear interpolation of 'a' and 'b' 766d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth); 767d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com 768d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com SkString noiseFuncName; 769bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips if (pne.stitchTiles()) { 7704ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->emitFunction(kFloat_GrSLType, 7714ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitchArgs), 7724ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel gPerlinNoiseStitchArgs, noiseCode.c_str(), &noiseFuncName); 773d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com } else { 7744ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->emitFunction(kFloat_GrSLType, 7754ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs), 7764ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncName); 777d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com } 778e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 779d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com // There are rounding errors if the floor operation is not performed here 7804ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("\n\t\tvec2 %s = floor(%s.xy) * %s;", 7814ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel noiseVec, vCoords.c_str(), baseFrequencyUni); 782e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 783d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com // Clear the color accumulator 7844ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("\n\t\t%s = vec4(0.0);", args.fOutputColor); 785e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 786bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips if (pne.stitchTiles()) { 787d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com // Set up TurbulenceInitial stitch values. 788bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips fragBuilder->codeAppendf("vec2 %s = %s;", stitchData, stitchDataUni); 789e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 790e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 791bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips fragBuilder->codeAppendf("float %s = 1.0;", ratio); 792d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com 793d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com // Loop over all octaves 794bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips fragBuilder->codeAppendf("for (int octave = 0; octave < %d; ++octave) {", pne.numOctaves()); 795d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com 796bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips fragBuilder->codeAppendf("%s += ", args.fOutputColor); 797bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips if (pne.type() != SkPerlinNoiseShader::kFractalNoise_Type) { 7984ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("abs("); 799d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com } 800bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips if (pne.stitchTiles()) { 8014ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf( 802d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s)," 803d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))", 804d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData, 805d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData, 806d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData, 807d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData); 808d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com } else { 8094ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf( 810d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s)," 811d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))", 812d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseFuncName.c_str(), chanCoordR, noiseVec, 813d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseFuncName.c_str(), chanCoordG, noiseVec, 814d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseFuncName.c_str(), chanCoordB, noiseVec, 815d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com noiseFuncName.c_str(), chanCoordA, noiseVec); 816d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com } 817bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips if (pne.type() != SkPerlinNoiseShader::kFractalNoise_Type) { 8184ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf(")"); // end of "abs(" 819d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com } 8204ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf(" * %s;", ratio); 821d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com 8224ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec); 8234ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio); 824d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com 825bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips if (pne.stitchTiles()) { 8264ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData); 827d537af50fcd013aa69fddc24afb1b997408ec762sugoi@google.com } 8284ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves 829e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 830bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips if (pne.type() == SkPerlinNoiseShader::kFractalNoise_Type) { 831e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2 832e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // by fractalNoise and (turbulenceFunctionResult) by turbulence. 8334ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", 8344ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel args.fOutputColor,args.fOutputColor); 835e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 836e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 837e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Clamp values 8384ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColor, args.fOutputColor); 839e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 840e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Pre-multiply the result 8414ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n", 8424ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel args.fOutputColor, args.fOutputColor, 8434ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel args.fOutputColor, args.fOutputColor); 844e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 845e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 846cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid GrGLPerlinNoise::GenKey(const GrProcessor& processor, const GrGLSLCaps&, 847b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 848b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrPerlinNoiseEffect& turbulence = processor.cast<GrPerlinNoiseEffect>(); 849e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 85063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon uint32_t key = turbulence.numOctaves(); 851e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 852e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com key = key << 3; // Make room for next 3 bits 853e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 854e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com switch (turbulence.type()) { 855e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com case SkPerlinNoiseShader::kFractalNoise_Type: 856e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com key |= 0x1; 857e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com break; 858e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com case SkPerlinNoiseShader::kTurbulence_Type: 859e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com key |= 0x2; 860e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com break; 861e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com default: 862e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // leave key at 0 863e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com break; 864e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 865e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 866e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com if (turbulence.stitchTiles()) { 867e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com key |= 0x4; // Flip the 3rd bit if tile stitching is on 868e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 869e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 87063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon b->add32(key); 871e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 872e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 873018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GrGLPerlinNoise::onSetData(const GrGLSLProgramDataManager& pdman, 874018fb62d12d1febf121fe265da5b6117b86a6541egdaniel const GrProcessor& processor) { 875b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix INHERITED::onSetData(pdman, processor); 876f3b50276a4ad71c9e8ba13d752a5db0c073cae2csenorblanco 877b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrPerlinNoiseEffect& turbulence = processor.cast<GrPerlinNoiseEffect>(); 878e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 879e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com const SkVector& baseFrequency = turbulence.baseFrequency(); 8807510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY); 881e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 8824775cba7b37e24e8480bd2d96e297fd0828fb5c3sugoi@google.com if (turbulence.stitchTiles()) { 8834775cba7b37e24e8480bd2d96e297fd0828fb5c3sugoi@google.com const SkPerlinNoiseShader::StitchData& stitchData = turbulence.stitchData(); 8847510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth), 8859839320ae17ab1c2182dc144db5ba94caa1bde56commit-bot@chromium.org SkIntToScalar(stitchData.fHeight)); 8864775cba7b37e24e8480bd2d96e297fd0828fb5c3sugoi@google.com } 8874775cba7b37e24e8480bd2d96e297fd0828fb5c3sugoi@google.com} 8884775cba7b37e24e8480bd2d96e297fd0828fb5c3sugoi@google.com 889e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com///////////////////////////////////////////////////////////////////// 890c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonconst GrFragmentProcessor* SkPerlinNoiseShader::asFragmentProcessor( 891c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon GrContext* context, 892c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon const SkMatrix& viewM, 893c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon const SkMatrix* externalLocalMatrix, 8944a339529612a43871d021877e58698e067d6c4cdbsalomon SkFilterQuality) const { 89549f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(context); 8963f3b3d003527861dc0bd89733857576408906431mtklein 89796fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org SkMatrix localMatrix = this->getLocalMatrix(); 89896fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org if (externalLocalMatrix) { 89996fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org localMatrix.preConcat(*externalLocalMatrix); 90096fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org } 90196fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org 9025531d51ce7426bdae7563547326fcf0bf926a083joshualitt SkMatrix matrix = viewM; 903ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco matrix.preConcat(localMatrix); 904ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco 905c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org if (0 == fNumOctaves) { 906c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org if (kFractalNoise_Type == fType) { 907c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon // Extract the incoming alpha and emit rgba = (a/4, a/4, a/4, a/2) 908c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon SkAutoTUnref<const GrFragmentProcessor> inner( 909c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon GrConstColorProcessor::Create(0x80404040, 910c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon GrConstColorProcessor::kModulateRGBA_InputMode)); 911f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return GrFragmentProcessor::MulOutputByInputAlpha(inner); 912cff10b21a9934afc540d121b493b204335829589reed } 913c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon // Emit zero. 914c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon return GrConstColorProcessor::Create(0x0, GrConstColorProcessor::kIgnore_InputMode); 915c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org } 916c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org 917e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com // Either we don't stitch tiles, either we have a valid tile size 918e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com SkASSERT(!fStitchTiles || !fTileSize.isEmpty()); 919e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 920b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkPerlinNoiseShader::PaintingData* paintingData = 921385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary new PaintingData(fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY, matrix); 922bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon SkAutoTUnref<GrTexture> permutationsTexture( 923afa95e270c64c9777647b6c58b796750ced57c39bsalomon GrRefCachedBitmapTexture(context, paintingData->getPermutationsBitmap(), 924afa95e270c64c9777647b6c58b796750ced57c39bsalomon GrTextureParams::ClampNoFilter())); 925bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon SkAutoTUnref<GrTexture> noiseTexture( 926afa95e270c64c9777647b6c58b796750ced57c39bsalomon GrRefCachedBitmapTexture(context, paintingData->getNoiseBitmap(), 927afa95e270c64c9777647b6c58b796750ced57c39bsalomon GrTextureParams::ClampNoFilter())); 928ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco 9295531d51ce7426bdae7563547326fcf0bf926a083joshualitt SkMatrix m = viewM; 930ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1); 931ca6a7c29452e13cf63bb4e225972065cbfe6e265senorblanco m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1); 93249f085dddff10473b6ebf832a974288300224e60bsalomon if ((permutationsTexture) && (noiseTexture)) { 933c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon SkAutoTUnref<GrFragmentProcessor> inner( 9344a339529612a43871d021877e58698e067d6c4cdbsalomon GrPerlinNoiseEffect::Create(fType, 935c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon fNumOctaves, 936c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon fStitchTiles, 937c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon paintingData, 938c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon permutationsTexture, noiseTexture, 939c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon m)); 940f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return GrFragmentProcessor::MulOutputByInputAlpha(inner); 941c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon } 942c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon delete paintingData; 943c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon return nullptr; 944e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 945e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 946e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com#endif 947e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 9480f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 949e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comvoid SkPerlinNoiseShader::toString(SkString* str) const { 950e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->append("SkPerlinNoiseShader: ("); 951e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 952e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->append("type: "); 953e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com switch (fType) { 954e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com case kFractalNoise_Type: 955e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->append("\"fractal noise\""); 956e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com break; 957e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com case kTurbulence_Type: 958e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->append("\"turbulence\""); 959e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com break; 960e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com default: 961e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->append("\"unknown\""); 962e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com break; 963e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com } 964e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->append(" base frequency: ("); 965e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->appendScalar(fBaseFrequencyX); 966e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->append(", "); 967e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->appendScalar(fBaseFrequencyY); 968e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->append(") number of octaves: "); 969e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->appendS32(fNumOctaves); 970e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->append(" seed: "); 971e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->appendScalar(fSeed); 972e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->append(" stitch tiles: "); 973e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->append(fStitchTiles ? "true " : "false "); 974e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 975e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com this->INHERITED::toString(str); 976e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com 977e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com str->append(")"); 978e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com} 979e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com#endif 980