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

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

Issue 249643002: Revert of Extract most of the mutable state of SkShader into a separate Context object. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 8 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
« no previous file with comments | « src/core/SkSmallAllocator.h ('k') | src/effects/SkTransparentShader.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 const SkISize* tileSize) 271 const SkISize* tileSize)
272 : fType(type) 272 : fType(type)
273 , fBaseFrequencyX(baseFrequencyX) 273 , fBaseFrequencyX(baseFrequencyX)
274 , fBaseFrequencyY(baseFrequencyY) 274 , fBaseFrequencyY(baseFrequencyY)
275 , fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/) 275 , fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/)
276 , fSeed(seed) 276 , fSeed(seed)
277 , fTileSize(NULL == tileSize ? SkISize::Make(0, 0) : *tileSize) 277 , fTileSize(NULL == tileSize ? SkISize::Make(0, 0) : *tileSize)
278 , fStitchTiles(!fTileSize.isEmpty()) 278 , fStitchTiles(!fTileSize.isEmpty())
279 { 279 {
280 SkASSERT(numOctaves >= 0 && numOctaves < 256); 280 SkASSERT(numOctaves >= 0 && numOctaves < 256);
281 fMatrix.reset();
281 fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY)); 282 fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY));
282 } 283 }
283 284
284 SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer) 285 SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer)
285 : INHERITED(buffer) 286 : INHERITED(buffer)
286 { 287 {
287 fType = (SkPerlinNoiseShader::Type) buffer.readInt(); 288 fType = (SkPerlinNoiseShader::Type) buffer.readInt();
288 fBaseFrequencyX = buffer.readScalar(); 289 fBaseFrequencyX = buffer.readScalar();
289 fBaseFrequencyY = buffer.readScalar(); 290 fBaseFrequencyY = buffer.readScalar();
290 fNumOctaves = buffer.readInt(); 291 fNumOctaves = buffer.readInt();
291 fSeed = buffer.readScalar(); 292 fSeed = buffer.readScalar();
292 fStitchTiles = buffer.readBool(); 293 fStitchTiles = buffer.readBool();
293 fTileSize.fWidth = buffer.readInt(); 294 fTileSize.fWidth = buffer.readInt();
294 fTileSize.fHeight = buffer.readInt(); 295 fTileSize.fHeight = buffer.readInt();
296 fMatrix.reset();
295 fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY)); 297 fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY));
296 buffer.validate(perlin_noise_type_is_valid(fType) && 298 buffer.validate(perlin_noise_type_is_valid(fType) &&
297 (fNumOctaves >= 0) && (fNumOctaves <= 255) && 299 (fNumOctaves >= 0) && (fNumOctaves <= 255) &&
298 (fStitchTiles != fTileSize.isEmpty())); 300 (fStitchTiles != fTileSize.isEmpty()));
299 } 301 }
300 302
301 SkPerlinNoiseShader::~SkPerlinNoiseShader() { 303 SkPerlinNoiseShader::~SkPerlinNoiseShader() {
302 // Safety, should have been done in endContext() 304 // Safety, should have been done in endContext()
303 SkDELETE(fPaintingData); 305 SkDELETE(fPaintingData);
304 } 306 }
305 307
306 void SkPerlinNoiseShader::flatten(SkWriteBuffer& buffer) const { 308 void SkPerlinNoiseShader::flatten(SkWriteBuffer& buffer) const {
307 this->INHERITED::flatten(buffer); 309 this->INHERITED::flatten(buffer);
308 buffer.writeInt((int) fType); 310 buffer.writeInt((int) fType);
309 buffer.writeScalar(fBaseFrequencyX); 311 buffer.writeScalar(fBaseFrequencyX);
310 buffer.writeScalar(fBaseFrequencyY); 312 buffer.writeScalar(fBaseFrequencyY);
311 buffer.writeInt(fNumOctaves); 313 buffer.writeInt(fNumOctaves);
312 buffer.writeScalar(fSeed); 314 buffer.writeScalar(fSeed);
313 buffer.writeBool(fStitchTiles); 315 buffer.writeBool(fStitchTiles);
314 buffer.writeInt(fTileSize.fWidth); 316 buffer.writeInt(fTileSize.fWidth);
315 buffer.writeInt(fTileSize.fHeight); 317 buffer.writeInt(fTileSize.fHeight);
316 } 318 }
317 319
318 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::noise2D( 320 SkScalar SkPerlinNoiseShader::noise2D(int channel, const PaintingData& paintingD ata,
319 int channel, const PaintingData& paintingData, 321 const StitchData& stitchData,
320 const StitchData& stitchData, const SkPoint& noiseVector) const { 322 const SkPoint& noiseVector) const {
321 struct Noise { 323 struct Noise {
322 int noisePositionIntegerValue; 324 int noisePositionIntegerValue;
323 SkScalar noisePositionFractionValue; 325 SkScalar noisePositionFractionValue;
324 Noise(SkScalar component) 326 Noise(SkScalar component)
325 { 327 {
326 SkScalar position = component + kPerlinNoise; 328 SkScalar position = component + kPerlinNoise;
327 noisePositionIntegerValue = SkScalarFloorToInt(position); 329 noisePositionIntegerValue = SkScalarFloorToInt(position);
328 noisePositionFractionValue = position - SkIntToScalar(noisePositionI ntegerValue); 330 noisePositionFractionValue = position - SkIntToScalar(noisePositionI ntegerValue);
329 } 331 }
330 }; 332 };
331 Noise noiseX(noiseVector.x()); 333 Noise noiseX(noiseVector.x());
332 Noise noiseY(noiseVector.y()); 334 Noise noiseY(noiseVector.y());
333 SkScalar u, v; 335 SkScalar u, v;
334 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi seShader&>(fShader);
335 // If stitching, adjust lattice points accordingly. 336 // If stitching, adjust lattice points accordingly.
336 if (perlinNoiseShader.fStitchTiles) { 337 if (fStitchTiles) {
337 noiseX.noisePositionIntegerValue = 338 noiseX.noisePositionIntegerValue =
338 checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stit chData.fWidth); 339 checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stit chData.fWidth);
339 noiseY.noisePositionIntegerValue = 340 noiseY.noisePositionIntegerValue =
340 checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stit chData.fHeight); 341 checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stit chData.fHeight);
341 } 342 }
342 noiseX.noisePositionIntegerValue &= kBlockMask; 343 noiseX.noisePositionIntegerValue &= kBlockMask;
343 noiseY.noisePositionIntegerValue &= kBlockMask; 344 noiseY.noisePositionIntegerValue &= kBlockMask;
344 int latticeIndex = 345 int latticeIndex =
345 paintingData.fLatticeSelector[noiseX.noisePositionIntegerValue] + 346 paintingData.fLatticeSelector[noiseX.noisePositionIntegerValue] +
346 noiseY.noisePositionIntegerValue; 347 noiseY.noisePositionIntegerValue;
(...skipping 10 matching lines...) Expand all
357 v = paintingData.fGradient[channel][nextLatticeIndex & kBlockMask].dot(fract ionValue); 358 v = paintingData.fGradient[channel][nextLatticeIndex & kBlockMask].dot(fract ionValue);
358 SkScalar a = SkScalarInterp(u, v, sx); 359 SkScalar a = SkScalarInterp(u, v, sx);
359 fractionValue.fY -= SK_Scalar1; // Offset (-1,-1) 360 fractionValue.fY -= SK_Scalar1; // Offset (-1,-1)
360 v = paintingData.fGradient[channel][(nextLatticeIndex + 1) & kBlockMask].dot (fractionValue); 361 v = paintingData.fGradient[channel][(nextLatticeIndex + 1) & kBlockMask].dot (fractionValue);
361 fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1) 362 fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1)
362 u = paintingData.fGradient[channel][(latticeIndex + 1) & kBlockMask].dot(fra ctionValue); 363 u = paintingData.fGradient[channel][(latticeIndex + 1) & kBlockMask].dot(fra ctionValue);
363 SkScalar b = SkScalarInterp(u, v, sx); 364 SkScalar b = SkScalarInterp(u, v, sx);
364 return SkScalarInterp(a, b, sy); 365 return SkScalarInterp(a, b, sy);
365 } 366 }
366 367
367 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::calculateTurbulenceValue ForPoint( 368 SkScalar SkPerlinNoiseShader::calculateTurbulenceValueForPoint(int channel,
368 int channel, const PaintingData& paintingData, 369 const PaintingDat a& paintingData,
369 StitchData& stitchData, const SkPoint& point) const { 370 StitchData& stitc hData,
370 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi seShader&>(fShader); 371 const SkPoint& po int) const {
371 if (perlinNoiseShader.fStitchTiles) { 372 if (fStitchTiles) {
372 // Set up TurbulenceInitial stitch values. 373 // Set up TurbulenceInitial stitch values.
373 stitchData = paintingData.fStitchDataInit; 374 stitchData = paintingData.fStitchDataInit;
374 } 375 }
375 SkScalar turbulenceFunctionResult = 0; 376 SkScalar turbulenceFunctionResult = 0;
376 SkPoint noiseVector(SkPoint::Make(SkScalarMul(point.x(), paintingData.fBaseF requency.fX), 377 SkPoint noiseVector(SkPoint::Make(SkScalarMul(point.x(), paintingData.fBaseF requency.fX),
377 SkScalarMul(point.y(), paintingData.fBaseF requency.fY))); 378 SkScalarMul(point.y(), paintingData.fBaseF requency.fY)));
378 SkScalar ratio = SK_Scalar1; 379 SkScalar ratio = SK_Scalar1;
379 for (int octave = 0; octave < perlinNoiseShader.fNumOctaves; ++octave) { 380 for (int octave = 0; octave < fNumOctaves; ++octave) {
380 SkScalar noise = noise2D(channel, paintingData, stitchData, noiseVector) ; 381 SkScalar noise = noise2D(channel, paintingData, stitchData, noiseVector) ;
381 turbulenceFunctionResult += SkScalarDiv( 382 turbulenceFunctionResult += SkScalarDiv(
382 (perlinNoiseShader.fType == kFractalNoise_Type) ? noise : SkScalarAb s(noise), ratio); 383 (fType == kFractalNoise_Type) ? noise : SkScalarAbs(noise), ratio);
383 noiseVector.fX *= 2; 384 noiseVector.fX *= 2;
384 noiseVector.fY *= 2; 385 noiseVector.fY *= 2;
385 ratio *= 2; 386 ratio *= 2;
386 if (perlinNoiseShader.fStitchTiles) { 387 if (fStitchTiles) {
387 // Update stitch values 388 // Update stitch values
388 stitchData.fWidth *= 2; 389 stitchData.fWidth *= 2;
389 stitchData.fWrapX = stitchData.fWidth + kPerlinNoise; 390 stitchData.fWrapX = stitchData.fWidth + kPerlinNoise;
390 stitchData.fHeight *= 2; 391 stitchData.fHeight *= 2;
391 stitchData.fWrapY = stitchData.fHeight + kPerlinNoise; 392 stitchData.fWrapY = stitchData.fHeight + kPerlinNoise;
392 } 393 }
393 } 394 }
394 395
395 // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResu lt) + 1) / 2 396 // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResu lt) + 1) / 2
396 // by fractalNoise and (turbulenceFunctionResult) by turbulence. 397 // by fractalNoise and (turbulenceFunctionResult) by turbulence.
397 if (perlinNoiseShader.fType == kFractalNoise_Type) { 398 if (fType == kFractalNoise_Type) {
398 turbulenceFunctionResult = 399 turbulenceFunctionResult =
399 SkScalarMul(turbulenceFunctionResult, SK_ScalarHalf) + SK_ScalarHalf ; 400 SkScalarMul(turbulenceFunctionResult, SK_ScalarHalf) + SK_ScalarHalf ;
400 } 401 }
401 402
402 if (channel == 3) { // Scale alpha by paint value 403 if (channel == 3) { // Scale alpha by paint value
403 turbulenceFunctionResult = SkScalarMul(turbulenceFunctionResult, 404 turbulenceFunctionResult = SkScalarMul(turbulenceFunctionResult,
404 SkScalarDiv(SkIntToScalar(getPaintAlpha()), SkIntToScalar(255))); 405 SkScalarDiv(SkIntToScalar(getPaintAlpha()), SkIntToScalar(255)));
405 } 406 }
406 407
407 // Clamp result 408 // Clamp result
408 return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1); 409 return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1);
409 } 410 }
410 411
411 SkPMColor SkPerlinNoiseShader::PerlinNoiseShaderContext::shade( 412 SkPMColor SkPerlinNoiseShader::shade(const SkPoint& point, StitchData& stitchDat a) const {
412 const SkPoint& point, StitchData& stitchData) const {
413 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi seShader&>(fShader);
414 SkPoint newPoint; 413 SkPoint newPoint;
415 fMatrix.mapPoints(&newPoint, &point, 1); 414 fMatrix.mapPoints(&newPoint, &point, 1);
416 newPoint.fX = SkScalarRoundToScalar(newPoint.fX); 415 newPoint.fX = SkScalarRoundToScalar(newPoint.fX);
417 newPoint.fY = SkScalarRoundToScalar(newPoint.fY); 416 newPoint.fY = SkScalarRoundToScalar(newPoint.fY);
418 417
419 U8CPU rgba[4]; 418 U8CPU rgba[4];
420 for (int channel = 3; channel >= 0; --channel) { 419 for (int channel = 3; channel >= 0; --channel) {
421 rgba[channel] = SkScalarFloorToInt(255 * 420 rgba[channel] = SkScalarFloorToInt(255 *
422 calculateTurbulenceValueForPoint(channel, *perlinNoiseShader.fPainti ngData, 421 calculateTurbulenceValueForPoint(channel, *fPaintingData, stitchData , newPoint));
423 stitchData, newPoint));
424 } 422 }
425 return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]); 423 return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
426 } 424 }
427 425
428 SkShader::Context* SkPerlinNoiseShader::createContext(const SkBitmap& device, co nst SkPaint& paint, 426 bool SkPerlinNoiseShader::setContext(const SkBitmap& device, const SkPaint& pain t,
429 const SkMatrix& matrix, vo id* storage) const { 427 const SkMatrix& matrix) {
430 if (!this->validContext(device, paint, matrix)) {
431 return NULL;
432 }
433
434 return SkNEW_PLACEMENT_ARGS(storage, PerlinNoiseShaderContext, (*this, devic e, paint, matrix));
435 }
436
437 size_t SkPerlinNoiseShader::contextSize() const {
438 return sizeof(PerlinNoiseShaderContext);
439 }
440
441 SkPerlinNoiseShader::PerlinNoiseShaderContext::PerlinNoiseShaderContext(
442 const SkPerlinNoiseShader& shader, const SkBitmap& device,
443 const SkPaint& paint, const SkMatrix& matrix)
444 : INHERITED(shader, device, paint, matrix)
445 {
446 SkMatrix newMatrix = matrix; 428 SkMatrix newMatrix = matrix;
447 newMatrix.postConcat(shader.getLocalMatrix()); 429 newMatrix.postConcat(getLocalMatrix());
448 SkMatrix invMatrix; 430 SkMatrix invMatrix;
449 if (!newMatrix.invert(&invMatrix)) { 431 if (!newMatrix.invert(&invMatrix)) {
450 invMatrix.reset(); 432 invMatrix.reset();
451 } 433 }
452 // This (1,1) translation is due to WebKit's 1 based coordinates for the noi se 434 // This (1,1) translation is due to WebKit's 1 based coordinates for the noi se
453 // (as opposed to 0 based, usually). The same adjustment is in the setData() function. 435 // (as opposed to 0 based, usually). The same adjustment is in the setData() function.
454 newMatrix.postTranslate(SK_Scalar1, SK_Scalar1); 436 newMatrix.postTranslate(SK_Scalar1, SK_Scalar1);
455 newMatrix.postConcat(invMatrix); 437 newMatrix.postConcat(invMatrix);
456 newMatrix.postConcat(invMatrix); 438 newMatrix.postConcat(invMatrix);
457 fMatrix = newMatrix; 439 fMatrix = newMatrix;
440 return INHERITED::setContext(device, paint, matrix);
458 } 441 }
459 442
460 void SkPerlinNoiseShader::PerlinNoiseShaderContext::shadeSpan( 443 void SkPerlinNoiseShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
461 int x, int y, SkPMColor result[], int count) {
462 SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y)); 444 SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
463 StitchData stitchData; 445 StitchData stitchData;
464 for (int i = 0; i < count; ++i) { 446 for (int i = 0; i < count; ++i) {
465 result[i] = shade(point, stitchData); 447 result[i] = shade(point, stitchData);
466 point.fX += SK_Scalar1; 448 point.fX += SK_Scalar1;
467 } 449 }
468 } 450 }
469 451
470 void SkPerlinNoiseShader::PerlinNoiseShaderContext::shadeSpan16( 452 void SkPerlinNoiseShader::shadeSpan16(int x, int y, uint16_t result[], int count ) {
471 int x, int y, uint16_t result[], int count) {
472 SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y)); 453 SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
473 StitchData stitchData; 454 StitchData stitchData;
474 DITHER_565_SCAN(y); 455 DITHER_565_SCAN(y);
475 for (int i = 0; i < count; ++i) { 456 for (int i = 0; i < count; ++i) {
476 unsigned dither = DITHER_VALUE(x); 457 unsigned dither = DITHER_VALUE(x);
477 result[i] = SkDitherRGB32To565(shade(point, stitchData), dither); 458 result[i] = SkDitherRGB32To565(shade(point, stitchData), dither);
478 DITHER_INC_X(x); 459 DITHER_INC_X(x);
479 point.fX += SK_Scalar1; 460 point.fX += SK_Scalar1;
480 } 461 }
481 } 462 }
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after
1365 str->append(" seed: "); 1346 str->append(" seed: ");
1366 str->appendScalar(fSeed); 1347 str->appendScalar(fSeed);
1367 str->append(" stitch tiles: "); 1348 str->append(" stitch tiles: ");
1368 str->append(fStitchTiles ? "true " : "false "); 1349 str->append(fStitchTiles ? "true " : "false ");
1369 1350
1370 this->INHERITED::toString(str); 1351 this->INHERITED::toString(str);
1371 1352
1372 str->append(")"); 1353 str->append(")");
1373 } 1354 }
1374 #endif 1355 #endif
OLDNEW
« no previous file with comments | « src/core/SkSmallAllocator.h ('k') | src/effects/SkTransparentShader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698