Index: src/effects/SkPerlinNoiseShader.cpp |
diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp |
index 47de924b997e41b34bf902ee1174f7313e514cfe..e28227db09e7007036a65e0ce6553835995ce384 100644 |
--- a/src/effects/SkPerlinNoiseShader.cpp |
+++ b/src/effects/SkPerlinNoiseShader.cpp |
@@ -81,17 +81,23 @@ struct SkPerlinNoiseShader::StitchData { |
}; |
struct SkPerlinNoiseShader::PaintingData { |
- PaintingData(const SkISize& tileSize) |
- : fSeed(0) |
- , fTileSize(tileSize) |
- , fPermutationsBitmap(NULL) |
- , fNoiseBitmap(NULL) |
- {} |
- |
- ~PaintingData() |
+ PaintingData(const SkISize& tileSize, SkScalar seed, |
+ SkScalar baseFrequencyX, SkScalar baseFrequencyY) |
+ : fTileSize(tileSize) |
+ , fBaseFrequency(SkPoint::Make(baseFrequencyX, baseFrequencyY)) |
{ |
- SkDELETE(fPermutationsBitmap); |
- SkDELETE(fNoiseBitmap); |
+ this->init(seed); |
+ if (!fTileSize.isEmpty()) { |
+ this->stitch(); |
+ } |
+ |
+#if SK_SUPPORT_GPU && !defined(SK_USE_SIMPLEX_NOISE) |
+ fPermutationsBitmap.setConfig(SkImageInfo::MakeA8(kBlockSize, 1)); |
+ fPermutationsBitmap.setPixels(fLatticeSelector); |
+ |
+ fNoiseBitmap.setConfig(SkImageInfo::MakeN32Premul(kBlockSize, 4)); |
+ fNoiseBitmap.setPixels(fNoise[0][0]); |
+#endif |
} |
int fSeed; |
@@ -104,10 +110,10 @@ struct SkPerlinNoiseShader::PaintingData { |
private: |
- SkBitmap* fPermutationsBitmap; |
- SkBitmap* fNoiseBitmap; |
- |
-public: |
+#if SK_SUPPORT_GPU && !defined(SK_USE_SIMPLEX_NOISE) |
+ SkBitmap fPermutationsBitmap; |
+ SkBitmap fNoiseBitmap; |
+#endif |
inline int random() { |
static const int gRandAmplitude = 16807; // 7**5; primitive root of m |
@@ -121,6 +127,7 @@ public: |
return result; |
} |
+ // Only called once. Could be part of the constructor. |
void init(SkScalar seed) |
{ |
static const SkScalar gInvBlockSizef = SkScalarInvert(SkIntToScalar(kBlockSize)); |
@@ -190,14 +197,9 @@ public: |
fGradient[channel][i].fY + SK_Scalar1, gHalfMax16bits)); |
} |
} |
- |
- // Invalidate bitmaps |
- SkDELETE(fPermutationsBitmap); |
- fPermutationsBitmap = NULL; |
- SkDELETE(fNoiseBitmap); |
- fNoiseBitmap = NULL; |
} |
+ // Only called once. Could be part of the constructor. |
void stitch() { |
SkScalar tileWidth = SkIntToScalar(fTileSize.width()); |
SkScalar tileHeight = SkIntToScalar(fTileSize.height()); |
@@ -238,27 +240,13 @@ public: |
fStitchDataInit.fWrapY = kPerlinNoise + fStitchDataInit.fHeight; |
} |
- SkBitmap* getPermutationsBitmap() |
- { |
- if (!fPermutationsBitmap) { |
- fPermutationsBitmap = SkNEW(SkBitmap); |
- fPermutationsBitmap->allocPixels(SkImageInfo::MakeA8(kBlockSize, 1)); |
- uint8_t* bitmapPixels = fPermutationsBitmap->getAddr8(0, 0); |
- memcpy(bitmapPixels, fLatticeSelector, sizeof(uint8_t) * kBlockSize); |
- } |
- return fPermutationsBitmap; |
- } |
+public: |
- SkBitmap* getNoiseBitmap() |
- { |
- if (!fNoiseBitmap) { |
- fNoiseBitmap = SkNEW(SkBitmap); |
- fNoiseBitmap->allocPixels(SkImageInfo::MakeN32Premul(kBlockSize, 4)); |
- uint32_t* bitmapPixels = fNoiseBitmap->getAddr32(0, 0); |
- memcpy(bitmapPixels, fNoise[0][0], sizeof(uint16_t) * kBlockSize * 4 * 2); |
- } |
- return fNoiseBitmap; |
- } |
+#if SK_SUPPORT_GPU && !defined(SK_USE_SIMPLEX_NOISE) |
+ const SkBitmap& getPermutationsBitmap() const { return fPermutationsBitmap; } |
+ |
+ const SkBitmap& getNoiseBitmap() const { return fNoiseBitmap; } |
+#endif |
}; |
SkShader* SkPerlinNoiseShader::CreateFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY, |
@@ -286,16 +274,17 @@ SkPerlinNoiseShader::SkPerlinNoiseShader(SkPerlinNoiseShader::Type type, |
, fBaseFrequencyY(baseFrequencyY) |
, fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/) |
, fSeed(seed) |
- , fStitchTiles((tileSize != NULL) && !tileSize->isEmpty()) |
- , fPaintingData(NULL) |
+ , fTileSize(NULL == tileSize ? SkISize::Make(0, 0) : *tileSize) |
+ , fStitchTiles(!fTileSize.isEmpty()) |
{ |
SkASSERT(numOctaves >= 0 && numOctaves < 256); |
- setTileSize(fStitchTiles ? *tileSize : SkISize::Make(0,0)); |
fMatrix.reset(); |
+ fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY)); |
} |
-SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer) : |
- INHERITED(buffer), fPaintingData(NULL) { |
+SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer) |
+ : INHERITED(buffer) |
+{ |
fType = (SkPerlinNoiseShader::Type) buffer.readInt(); |
fBaseFrequencyX = buffer.readScalar(); |
fBaseFrequencyY = buffer.readScalar(); |
@@ -304,10 +293,11 @@ SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer) : |
fStitchTiles = buffer.readBool(); |
fTileSize.fWidth = buffer.readInt(); |
fTileSize.fHeight = buffer.readInt(); |
- setTileSize(fTileSize); |
fMatrix.reset(); |
+ fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY)); |
buffer.validate(perlin_noise_type_is_valid(fType) && |
- (fNumOctaves >= 0) && (fNumOctaves <= 255)); |
+ (fNumOctaves >= 0) && (fNumOctaves <= 255) && |
+ (fStitchTiles != fTileSize.isEmpty())); |
} |
SkPerlinNoiseShader::~SkPerlinNoiseShader() { |
@@ -327,39 +317,9 @@ void SkPerlinNoiseShader::flatten(SkWriteBuffer& buffer) const { |
buffer.writeInt(fTileSize.fHeight); |
} |
-void SkPerlinNoiseShader::initPaint(PaintingData& paintingData) |
-{ |
- paintingData.init(fSeed); |
- |
- // Set frequencies to original values |
- paintingData.fBaseFrequency.set(fBaseFrequencyX, fBaseFrequencyY); |
- // Adjust frequecies based on size if stitching is enabled |
- if (fStitchTiles) { |
- paintingData.stitch(); |
- } |
-} |
- |
-void SkPerlinNoiseShader::setTileSize(const SkISize& tileSize) { |
- fTileSize = tileSize; |
- |
- if (NULL == fPaintingData) { |
- fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize)); |
- initPaint(*fPaintingData); |
- } else { |
- // Set Size |
- fPaintingData->fTileSize = fTileSize; |
- // Set frequencies to original values |
- fPaintingData->fBaseFrequency.set(fBaseFrequencyX, fBaseFrequencyY); |
- // Adjust frequecies based on size if stitching is enabled |
- if (fStitchTiles) { |
- fPaintingData->stitch(); |
- } |
- } |
-} |
- |
SkScalar SkPerlinNoiseShader::noise2D(int channel, const PaintingData& paintingData, |
- const StitchData& stitchData, const SkPoint& noiseVector) |
-{ |
+ const StitchData& stitchData, |
+ const SkPoint& noiseVector) const { |
struct Noise { |
int noisePositionIntegerValue; |
SkScalar noisePositionFractionValue; |
@@ -405,9 +365,10 @@ SkScalar SkPerlinNoiseShader::noise2D(int channel, const PaintingData& paintingD |
return SkScalarInterp(a, b, sy); |
} |
-SkScalar SkPerlinNoiseShader::calculateTurbulenceValueForPoint( |
- int channel, const PaintingData& paintingData, StitchData& stitchData, const SkPoint& point) |
-{ |
+SkScalar SkPerlinNoiseShader::calculateTurbulenceValueForPoint(int channel, |
+ const PaintingData& paintingData, |
+ StitchData& stitchData, |
+ const SkPoint& point) const { |
if (fStitchTiles) { |
// Set up TurbulenceInitial stitch values. |
stitchData = paintingData.fStitchDataInit; |
@@ -448,7 +409,7 @@ SkScalar SkPerlinNoiseShader::calculateTurbulenceValueForPoint( |
return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1); |
} |
-SkPMColor SkPerlinNoiseShader::shade(const SkPoint& point, StitchData& stitchData) { |
+SkPMColor SkPerlinNoiseShader::shade(const SkPoint& point, StitchData& stitchData) const { |
SkMatrix matrix = fMatrix; |
matrix.postConcat(getLocalMatrix()); |
SkMatrix invMatrix; |
@@ -1326,9 +1287,9 @@ GrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& |
this->getLocalMatrix(), paint.getAlpha()); |
#else |
GrTexture* permutationsTexture = GrLockAndRefCachedBitmapTexture( |
- context, *fPaintingData->getPermutationsBitmap(), NULL); |
+ context, fPaintingData->getPermutationsBitmap(), NULL); |
GrTexture* noiseTexture = GrLockAndRefCachedBitmapTexture( |
- context, *fPaintingData->getNoiseBitmap(), NULL); |
+ context, fPaintingData->getNoiseBitmap(), NULL); |
GrEffectRef* effect = (NULL != permutationsTexture) && (NULL != noiseTexture) ? |
GrPerlinNoiseEffect::Create(fType, fPaintingData->fBaseFrequency, |