Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: src/effects/SkPerlinNoiseShader.cpp

Issue 169973002: Begin making SkPerlinNoiseShader const. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkDither.h" 8 #include "SkDither.h"
9 #include "SkPerlinNoiseShader.h" 9 #include "SkPerlinNoiseShader.h"
10 #include "SkColorFilter.h" 10 #include "SkColorFilter.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 fWrapY == other.fWrapY; 74 fWrapY == other.fWrapY;
75 } 75 }
76 76
77 int fWidth; // How much to subtract to wrap for stitching. 77 int fWidth; // How much to subtract to wrap for stitching.
78 int fWrapX; // Minimum value to wrap. 78 int fWrapX; // Minimum value to wrap.
79 int fHeight; 79 int fHeight;
80 int fWrapY; 80 int fWrapY;
81 }; 81 };
82 82
83 struct SkPerlinNoiseShader::PaintingData { 83 struct SkPerlinNoiseShader::PaintingData {
84 PaintingData(const SkISize& tileSize) 84 PaintingData(const SkISize& tileSize, SkScalar seed,
Stephen White 2014/02/18 14:58:56 Not new to this patch, but I think the PaintingDat
scroggo 2014/02/18 16:42:57 I believe so.
scroggo 2014/03/04 22:26:34 Done. This is a much more pervasive change, and re
85 : fSeed(0) 85 SkScalar baseFrequencyX, SkScalar baseFrequencyY)
86 , fTileSize(tileSize) 86 : fTileSize(tileSize)
87 , fBaseFrequency(SkPoint::Make(baseFrequencyX, baseFrequencyY))
87 , fPermutationsBitmap(NULL) 88 , fPermutationsBitmap(NULL)
88 , fNoiseBitmap(NULL) 89 , fNoiseBitmap(NULL)
89 {} 90 {
91 this->init(seed);
92 if (!fTileSize.isEmpty()) {
93 this->stitch();
94 }
95 }
90 96
91 ~PaintingData() 97 ~PaintingData()
92 { 98 {
93 SkDELETE(fPermutationsBitmap); 99 SkDELETE(fPermutationsBitmap);
94 SkDELETE(fNoiseBitmap); 100 SkDELETE(fNoiseBitmap);
95 } 101 }
96 102
97 int fSeed; 103 int fSeed;
98 uint8_t fLatticeSelector[kBlockSize]; 104 uint8_t fLatticeSelector[kBlockSize];
99 uint16_t fNoise[4][kBlockSize][2]; 105 uint16_t fNoise[4][kBlockSize][2];
100 SkPoint fGradient[4][kBlockSize]; 106 SkPoint fGradient[4][kBlockSize];
101 SkISize fTileSize; 107 SkISize fTileSize;
102 SkVector fBaseFrequency; 108 SkVector fBaseFrequency;
103 StitchData fStitchDataInit; 109 StitchData fStitchDataInit;
104 110
105 private: 111 private:
106 112
107 SkBitmap* fPermutationsBitmap; 113 SkBitmap* fPermutationsBitmap;
108 SkBitmap* fNoiseBitmap; 114 SkBitmap* fNoiseBitmap;
109 115
110 public:
111
112 inline int random() { 116 inline int random() {
113 static const int gRandAmplitude = 16807; // 7**5; primitive root of m 117 static const int gRandAmplitude = 16807; // 7**5; primitive root of m
114 static const int gRandQ = 127773; // m / a 118 static const int gRandQ = 127773; // m / a
115 static const int gRandR = 2836; // m % a 119 static const int gRandR = 2836; // m % a
116 120
117 int result = gRandAmplitude * (fSeed % gRandQ) - gRandR * (fSeed / gRand Q); 121 int result = gRandAmplitude * (fSeed % gRandQ) - gRandR * (fSeed / gRand Q);
118 if (result <= 0) 122 if (result <= 0)
119 result += kRandMaximum; 123 result += kRandMaximum;
120 fSeed = result; 124 fSeed = result;
121 return result; 125 return result;
122 } 126 }
123 127
128 // Only called once. Could be part of the constructor.
124 void init(SkScalar seed) 129 void init(SkScalar seed)
125 { 130 {
126 static const SkScalar gInvBlockSizef = SkScalarInvert(SkIntToScalar(kBlo ckSize)); 131 static const SkScalar gInvBlockSizef = SkScalarInvert(SkIntToScalar(kBlo ckSize));
127 132
128 // According to the SVG spec, we must truncate (not round) the seed valu e. 133 // According to the SVG spec, we must truncate (not round) the seed valu e.
129 fSeed = SkScalarTruncToInt(seed); 134 fSeed = SkScalarTruncToInt(seed);
130 // The seed value clamp to the range [1, kRandMaximum - 1]. 135 // The seed value clamp to the range [1, kRandMaximum - 1].
131 if (fSeed <= 0) { 136 if (fSeed <= 0) {
132 fSeed = -(fSeed % (kRandMaximum - 1)) + 1; 137 fSeed = -(fSeed % (kRandMaximum - 1)) + 1;
133 } 138 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 } 196 }
192 } 197 }
193 198
194 // Invalidate bitmaps 199 // Invalidate bitmaps
195 SkDELETE(fPermutationsBitmap); 200 SkDELETE(fPermutationsBitmap);
196 fPermutationsBitmap = NULL; 201 fPermutationsBitmap = NULL;
197 SkDELETE(fNoiseBitmap); 202 SkDELETE(fNoiseBitmap);
198 fNoiseBitmap = NULL; 203 fNoiseBitmap = NULL;
199 } 204 }
200 205
206 // Only called once. Could be part of the constructor.
201 void stitch() { 207 void stitch() {
202 SkScalar tileWidth = SkIntToScalar(fTileSize.width()); 208 SkScalar tileWidth = SkIntToScalar(fTileSize.width());
203 SkScalar tileHeight = SkIntToScalar(fTileSize.height()); 209 SkScalar tileHeight = SkIntToScalar(fTileSize.height());
204 SkASSERT(tileWidth > 0 && tileHeight > 0); 210 SkASSERT(tileWidth > 0 && tileHeight > 0);
205 // When stitching tiled turbulence, the frequencies must be adjusted 211 // When stitching tiled turbulence, the frequencies must be adjusted
206 // so that the tile borders will be continuous. 212 // so that the tile borders will be continuous.
207 if (fBaseFrequency.fX) { 213 if (fBaseFrequency.fX) {
208 SkScalar lowFrequencx = 214 SkScalar lowFrequencx =
209 SkScalarFloorToScalar(tileWidth * fBaseFrequency.fX) / tileWidth ; 215 SkScalarFloorToScalar(tileWidth * fBaseFrequency.fX) / tileWidth ;
210 SkScalar highFrequencx = 216 SkScalar highFrequencx =
(...skipping 20 matching lines...) Expand all
231 } 237 }
232 // Set up TurbulenceInitial stitch values. 238 // Set up TurbulenceInitial stitch values.
233 fStitchDataInit.fWidth = 239 fStitchDataInit.fWidth =
234 SkScalarRoundToInt(tileWidth * fBaseFrequency.fX); 240 SkScalarRoundToInt(tileWidth * fBaseFrequency.fX);
235 fStitchDataInit.fWrapX = kPerlinNoise + fStitchDataInit.fWidth; 241 fStitchDataInit.fWrapX = kPerlinNoise + fStitchDataInit.fWidth;
236 fStitchDataInit.fHeight = 242 fStitchDataInit.fHeight =
237 SkScalarRoundToInt(tileHeight * fBaseFrequency.fY); 243 SkScalarRoundToInt(tileHeight * fBaseFrequency.fY);
238 fStitchDataInit.fWrapY = kPerlinNoise + fStitchDataInit.fHeight; 244 fStitchDataInit.fWrapY = kPerlinNoise + fStitchDataInit.fHeight;
239 } 245 }
240 246
247 public:
248
241 SkBitmap* getPermutationsBitmap() 249 SkBitmap* getPermutationsBitmap()
242 { 250 {
243 if (!fPermutationsBitmap) { 251 if (!fPermutationsBitmap) {
244 fPermutationsBitmap = SkNEW(SkBitmap); 252 fPermutationsBitmap = SkNEW(SkBitmap);
245 fPermutationsBitmap->allocPixels(SkImageInfo::MakeA8(kBlockSize, 1)) ; 253 fPermutationsBitmap->allocPixels(SkImageInfo::MakeA8(kBlockSize, 1)) ;
246 uint8_t* bitmapPixels = fPermutationsBitmap->getAddr8(0, 0); 254 uint8_t* bitmapPixels = fPermutationsBitmap->getAddr8(0, 0);
247 memcpy(bitmapPixels, fLatticeSelector, sizeof(uint8_t) * kBlockSize) ; 255 memcpy(bitmapPixels, fLatticeSelector, sizeof(uint8_t) * kBlockSize) ;
248 } 256 }
249 return fPermutationsBitmap; 257 return fPermutationsBitmap;
250 } 258 }
(...skipping 28 matching lines...) Expand all
279 SkScalar baseFrequencyX, 287 SkScalar baseFrequencyX,
280 SkScalar baseFrequencyY, 288 SkScalar baseFrequencyY,
281 int numOctaves, 289 int numOctaves,
282 SkScalar seed, 290 SkScalar seed,
283 const SkISize* tileSize) 291 const SkISize* tileSize)
284 : fType(type) 292 : fType(type)
285 , fBaseFrequencyX(baseFrequencyX) 293 , fBaseFrequencyX(baseFrequencyX)
286 , fBaseFrequencyY(baseFrequencyY) 294 , fBaseFrequencyY(baseFrequencyY)
287 , fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/) 295 , fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/)
288 , fSeed(seed) 296 , fSeed(seed)
289 , fStitchTiles((tileSize != NULL) && !tileSize->isEmpty()) 297 , fTileSize(NULL == tileSize ? SkISize::Make(0, 0) : *tileSize)
290 , fPaintingData(NULL) 298 , fStitchTiles(!fTileSize.isEmpty())
291 { 299 {
292 SkASSERT(numOctaves >= 0 && numOctaves < 256); 300 SkASSERT(numOctaves >= 0 && numOctaves < 256);
293 setTileSize(fStitchTiles ? *tileSize : SkISize::Make(0,0));
294 fMatrix.reset(); 301 fMatrix.reset();
302 fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY));
295 } 303 }
296 304
297 SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer) : 305 SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer)
298 INHERITED(buffer), fPaintingData(NULL) { 306 : INHERITED(buffer)
307 {
299 fType = (SkPerlinNoiseShader::Type) buffer.readInt(); 308 fType = (SkPerlinNoiseShader::Type) buffer.readInt();
300 fBaseFrequencyX = buffer.readScalar(); 309 fBaseFrequencyX = buffer.readScalar();
301 fBaseFrequencyY = buffer.readScalar(); 310 fBaseFrequencyY = buffer.readScalar();
302 fNumOctaves = buffer.readInt(); 311 fNumOctaves = buffer.readInt();
303 fSeed = buffer.readScalar(); 312 fSeed = buffer.readScalar();
304 fStitchTiles = buffer.readBool(); 313 fStitchTiles = buffer.readBool();
305 fTileSize.fWidth = buffer.readInt(); 314 fTileSize.fWidth = buffer.readInt();
306 fTileSize.fHeight = buffer.readInt(); 315 fTileSize.fHeight = buffer.readInt();
307 setTileSize(fTileSize);
308 fMatrix.reset(); 316 fMatrix.reset();
317 fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY));
309 buffer.validate(perlin_noise_type_is_valid(fType) && 318 buffer.validate(perlin_noise_type_is_valid(fType) &&
310 (fNumOctaves >= 0) && (fNumOctaves <= 255)); 319 (fNumOctaves >= 0) && (fNumOctaves <= 255) &&
320 (fStitchTiles != fTileSize.isEmpty()));
311 } 321 }
312 322
313 SkPerlinNoiseShader::~SkPerlinNoiseShader() { 323 SkPerlinNoiseShader::~SkPerlinNoiseShader() {
314 // Safety, should have been done in endContext() 324 // Safety, should have been done in endContext()
315 SkDELETE(fPaintingData); 325 SkDELETE(fPaintingData);
316 } 326 }
317 327
318 void SkPerlinNoiseShader::flatten(SkWriteBuffer& buffer) const { 328 void SkPerlinNoiseShader::flatten(SkWriteBuffer& buffer) const {
319 this->INHERITED::flatten(buffer); 329 this->INHERITED::flatten(buffer);
320 buffer.writeInt((int) fType); 330 buffer.writeInt((int) fType);
321 buffer.writeScalar(fBaseFrequencyX); 331 buffer.writeScalar(fBaseFrequencyX);
322 buffer.writeScalar(fBaseFrequencyY); 332 buffer.writeScalar(fBaseFrequencyY);
323 buffer.writeInt(fNumOctaves); 333 buffer.writeInt(fNumOctaves);
324 buffer.writeScalar(fSeed); 334 buffer.writeScalar(fSeed);
325 buffer.writeBool(fStitchTiles); 335 buffer.writeBool(fStitchTiles);
326 buffer.writeInt(fTileSize.fWidth); 336 buffer.writeInt(fTileSize.fWidth);
327 buffer.writeInt(fTileSize.fHeight); 337 buffer.writeInt(fTileSize.fHeight);
328 } 338 }
329 339
330 void SkPerlinNoiseShader::initPaint(PaintingData& paintingData)
331 {
332 paintingData.init(fSeed);
333
334 // Set frequencies to original values
335 paintingData.fBaseFrequency.set(fBaseFrequencyX, fBaseFrequencyY);
336 // Adjust frequecies based on size if stitching is enabled
337 if (fStitchTiles) {
338 paintingData.stitch();
339 }
340 }
341
342 void SkPerlinNoiseShader::setTileSize(const SkISize& tileSize) {
343 fTileSize = tileSize;
344
345 if (NULL == fPaintingData) {
346 fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize));
347 initPaint(*fPaintingData);
348 } else {
349 // Set Size
350 fPaintingData->fTileSize = fTileSize;
351 // Set frequencies to original values
352 fPaintingData->fBaseFrequency.set(fBaseFrequencyX, fBaseFrequencyY);
353 // Adjust frequecies based on size if stitching is enabled
354 if (fStitchTiles) {
355 fPaintingData->stitch();
356 }
357 }
358 }
359
360 SkScalar SkPerlinNoiseShader::noise2D(int channel, const PaintingData& paintingD ata, 340 SkScalar SkPerlinNoiseShader::noise2D(int channel, const PaintingData& paintingD ata,
361 const StitchData& stitchData, const SkPoint & noiseVector) 341 const StitchData& stitchData, const SkPoint & noiseVector)
362 { 342 {
363 struct Noise { 343 struct Noise {
364 int noisePositionIntegerValue; 344 int noisePositionIntegerValue;
365 SkScalar noisePositionFractionValue; 345 SkScalar noisePositionFractionValue;
366 Noise(SkScalar component) 346 Noise(SkScalar component)
367 { 347 {
368 SkScalar position = component + kPerlinNoise; 348 SkScalar position = component + kPerlinNoise;
369 noisePositionIntegerValue = SkScalarFloorToInt(position); 349 noisePositionIntegerValue = SkScalarFloorToInt(position);
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 str->append(" seed: "); 1365 str->append(" seed: ");
1386 str->appendScalar(fSeed); 1366 str->appendScalar(fSeed);
1387 str->append(" stitch tiles: "); 1367 str->append(" stitch tiles: ");
1388 str->append(fStitchTiles ? "true " : "false "); 1368 str->append(fStitchTiles ? "true " : "false ");
1389 1369
1390 this->INHERITED::toString(str); 1370 this->INHERITED::toString(str);
1391 1371
1392 str->append(")"); 1372 str->append(")");
1393 } 1373 }
1394 #endif 1374 #endif
OLDNEW
« include/effects/SkPerlinNoiseShader.h ('K') | « include/effects/SkPerlinNoiseShader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698