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