Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 The Android Open Source Project |
| 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 "SkCanvas.h" | 8 #include "SkCanvas.h" |
| 9 #include "SkCanvasPriv.h" | 9 #include "SkCanvasPriv.h" |
| 10 #include "SkBitmapDevice.h" | 10 #include "SkBitmapDevice.h" |
| 11 #include "SkColorFilter.h" | |
| 11 #include "SkDeviceImageFilterProxy.h" | 12 #include "SkDeviceImageFilterProxy.h" |
| 12 #include "SkDraw.h" | 13 #include "SkDraw.h" |
| 13 #include "SkDrawable.h" | 14 #include "SkDrawable.h" |
| 14 #include "SkDrawFilter.h" | 15 #include "SkDrawFilter.h" |
| 15 #include "SkDrawLooper.h" | 16 #include "SkDrawLooper.h" |
| 16 #include "SkErrorInternals.h" | 17 #include "SkErrorInternals.h" |
| 17 #include "SkImage.h" | 18 #include "SkImage.h" |
| 18 #include "SkMetaData.h" | 19 #include "SkMetaData.h" |
| 19 #include "SkPathOps.h" | 20 #include "SkPathOps.h" |
| 20 #include "SkPatchUtils.h" | 21 #include "SkPatchUtils.h" |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 SkCanvas* fCanvas; | 293 SkCanvas* fCanvas; |
| 293 const DeviceCM* fCurrLayer; | 294 const DeviceCM* fCurrLayer; |
| 294 const SkPaint* fPaint; // May be null. | 295 const SkPaint* fPaint; // May be null. |
| 295 SkBool8 fSkipEmptyClips; | 296 SkBool8 fSkipEmptyClips; |
| 296 | 297 |
| 297 typedef SkDraw INHERITED; | 298 typedef SkDraw INHERITED; |
| 298 }; | 299 }; |
| 299 | 300 |
| 300 ///////////////////////////////////////////////////////////////////////////// | 301 ///////////////////////////////////////////////////////////////////////////// |
| 301 | 302 |
| 303 static SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { | |
| 304 return lazy->isValid() ? lazy->get() : lazy->set(orig); | |
| 305 } | |
| 306 | |
| 307 /** | |
| 308 * If the paint has an imagefilter, but it can be simplified to just a colorfil ter, return that | |
| 309 * colorfilter, else return NULL. | |
| 310 */ | |
| 311 static SkColorFilter* image_to_color_filter(const SkPaint& paint) { | |
| 312 #ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_TO_COLORFILTER | |
| 313 return NULL; | |
| 314 #else | |
| 315 SkImageFilter* imgf = paint.getImageFilter(); | |
| 316 if (!imgf) { | |
| 317 return NULL; | |
| 318 } | |
| 319 | |
| 320 SkColorFilter* imgCF; | |
| 321 if (!imgf->asAColorFilter(&imgCF)) { | |
| 322 return NULL; | |
| 323 } | |
| 324 | |
| 325 SkColorFilter* paintCF = paint.getColorFilter(); | |
| 326 if (NULL == paintCF) { | |
| 327 // there is no existing paint colorfilter, so we can just return the ima gefilter's | |
| 328 return imgCF; | |
| 329 } | |
| 330 | |
|
robertphillips
2015/04/29 18:50:05
imagefilter -> imagefilter that is a colorfilter ?
reed1
2015/04/29 19:05:37
Done.
| |
| 331 // The paint has both a colorfilter and an imagefilter. | |
| 332 SkAutoTUnref<SkColorFilter> autoImgCF(imgCF); | |
| 333 return SkColorFilter::CreateComposeFilter(imgCF, paintCF); | |
| 334 #endif | |
| 335 } | |
| 336 | |
| 302 class AutoDrawLooper { | 337 class AutoDrawLooper { |
| 303 public: | 338 public: |
| 304 AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, | 339 AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, |
| 305 bool skipLayerForImageFilter = false, | 340 bool skipLayerForImageFilter = false, |
| 306 const SkRect* bounds = NULL) : fOrigPaint(paint) { | 341 const SkRect* bounds = NULL) : fOrigPaint(paint) { |
| 307 fCanvas = canvas; | 342 fCanvas = canvas; |
| 308 fFilter = canvas->getDrawFilter(); | 343 fFilter = canvas->getDrawFilter(); |
| 309 fPaint = &fOrigPaint; | 344 fPaint = &fOrigPaint; |
| 310 fSaveCount = canvas->getSaveCount(); | 345 fSaveCount = canvas->getSaveCount(); |
| 311 fTempLayerForImageFilter = false; | 346 fTempLayerForImageFilter = false; |
| 312 fDone = false; | 347 fDone = false; |
| 313 | 348 |
| 314 if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { | 349 SkColorFilter* simplifiedCF = image_to_color_filter(fOrigPaint); |
| 350 if (simplifiedCF) { | |
| 351 SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); | |
| 352 paint->setColorFilter(simplifiedCF)->unref(); | |
| 353 paint->setImageFilter(NULL); | |
| 354 fPaint = paint; | |
| 355 } | |
| 356 | |
| 357 if (!skipLayerForImageFilter && fPaint->getImageFilter()) { | |
| 315 /** | 358 /** |
| 316 * We implement ImageFilters for a given draw by creating a layer, then applying the | 359 * We implement ImageFilters for a given draw by creating a layer, then applying the |
| 317 * imagefilter to the pixels of that layer (its backing surface/ima ge), and then | 360 * imagefilter to the pixels of that layer (its backing surface/ima ge), and then |
| 318 * we call restore() to xfer that layer to the main canvas. | 361 * we call restore() to xfer that layer to the main canvas. |
| 319 * | 362 * |
| 320 * 1. SaveLayer (with a paint containing the current imagefilter an d xfermode) | 363 * 1. SaveLayer (with a paint containing the current imagefilter an d xfermode) |
| 321 * 2. Generate the src pixels: | 364 * 2. Generate the src pixels: |
| 322 * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper) | 365 * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper) |
| 323 * return (fPaint). We then draw the primitive (using srcover) into a cleared | 366 * return (fPaint). We then draw the primitive (using srcover) into a cleared |
| 324 * buffer/surface. | 367 * buffer/surface. |
| 325 * 3. Restore the layer created in #1 | 368 * 3. Restore the layer created in #1 |
| 326 * The imagefilter is passed the buffer/surface from the layer (now filled with the | 369 * The imagefilter is passed the buffer/surface from the layer (now filled with the |
| 327 * src pixels of the primitive). It returns a new "filtered" bu ffer, which we | 370 * src pixels of the primitive). It returns a new "filtered" bu ffer, which we |
| 328 * draw onto the previous layer using the xfermode from the ori ginal paint. | 371 * draw onto the previous layer using the xfermode from the ori ginal paint. |
| 329 */ | 372 */ |
| 330 SkPaint tmp; | 373 SkPaint tmp; |
| 331 tmp.setImageFilter(fOrigPaint.getImageFilter()); | 374 tmp.setImageFilter(fPaint->getImageFilter()); |
| 332 tmp.setXfermode(fOrigPaint.getXfermode()); | 375 tmp.setXfermode(fPaint->getXfermode()); |
| 333 (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLa yer_SaveFlag, | 376 (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLa yer_SaveFlag, |
| 334 SkCanvas::kFullLayer_SaveLayerStrate gy); | 377 SkCanvas::kFullLayer_SaveLayerStrate gy); |
| 335 fTempLayerForImageFilter = true; | 378 fTempLayerForImageFilter = true; |
| 336 // we remove the imagefilter/xfermode inside doNext() | 379 // we remove the imagefilter/xfermode inside doNext() |
| 337 } | 380 } |
| 338 | 381 |
| 339 if (SkDrawLooper* looper = paint.getLooper()) { | 382 if (SkDrawLooper* looper = paint.getLooper()) { |
| 340 void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex t>( | 383 void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex t>( |
| 341 looper->contextSize()); | 384 looper->contextSize()); |
| 342 fLooperContext = looper->createContext(canvas, buffer); | 385 fLooperContext = looper->createContext(canvas, buffer); |
| 343 fIsSimple = false; | 386 fIsSimple = false; |
| 344 } else { | 387 } else { |
| 345 fLooperContext = NULL; | 388 fLooperContext = NULL; |
| 346 // can we be marked as simple? | 389 // can we be marked as simple? |
| 347 fIsSimple = !fFilter && !fTempLayerForImageFilter; | 390 fIsSimple = !fFilter && !fTempLayerForImageFilter; |
| 348 } | 391 } |
| 349 | 392 |
| 350 uint32_t oldFlags = paint.getFlags(); | 393 uint32_t oldFlags = paint.getFlags(); |
| 351 fNewPaintFlags = filter_paint_flags(props, oldFlags); | 394 fNewPaintFlags = filter_paint_flags(props, oldFlags); |
| 352 if (fIsSimple && (fNewPaintFlags != oldFlags)) { | 395 if (fIsSimple && (fNewPaintFlags != oldFlags)) { |
| 353 SkPaint* paint = fLazyPaint.set(fOrigPaint); | 396 SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); |
| 354 paint->setFlags(fNewPaintFlags); | 397 paint->setFlags(fNewPaintFlags); |
| 355 fPaint = paint; | 398 fPaint = paint; |
| 356 // if we're not simple, doNext() will take care of calling setFlags( ) | 399 // if we're not simple, doNext() will take care of calling setFlags( ) |
| 357 } | 400 } |
| 358 } | 401 } |
| 359 | 402 |
| 360 ~AutoDrawLooper() { | 403 ~AutoDrawLooper() { |
| 361 if (fTempLayerForImageFilter) { | 404 if (fTempLayerForImageFilter) { |
| 362 fCanvas->internalRestore(); | 405 fCanvas->internalRestore(); |
| 363 } | 406 } |
| 364 SkASSERT(fCanvas->getSaveCount() == fSaveCount); | 407 SkASSERT(fCanvas->getSaveCount() == fSaveCount); |
| 365 } | 408 } |
| 366 | 409 |
| 367 const SkPaint& paint() const { | 410 const SkPaint& paint() const { |
| 368 SkASSERT(fPaint); | 411 SkASSERT(fPaint); |
| 369 return *fPaint; | 412 return *fPaint; |
| 370 } | 413 } |
| 371 | 414 |
| 372 bool next(SkDrawFilter::Type drawType) { | 415 bool next(SkDrawFilter::Type drawType) { |
| 373 if (fDone) { | 416 if (fDone) { |
| 374 return false; | 417 return false; |
| 375 } else if (fIsSimple) { | 418 } else if (fIsSimple) { |
| 376 fDone = true; | 419 fDone = true; |
| 377 return !fPaint->nothingToDraw(); | 420 return !fPaint->nothingToDraw(); |
| 378 } else { | 421 } else { |
| 379 return this->doNext(drawType); | 422 return this->doNext(drawType); |
| 380 } | 423 } |
| 381 } | 424 } |
| 382 | 425 |
| 383 private: | 426 private: |
|
robertphillips
2015/04/29 18:50:05
fLazyPaintPerNext needs a better name (or a commen
reed1
2015/04/29 19:05:37
Done.
| |
| 384 SkLazyPaint fLazyPaint; | 427 SkLazyPaint fLazyPaintInit, fLazyPaintPerNext; |
| 385 SkCanvas* fCanvas; | 428 SkCanvas* fCanvas; |
| 386 const SkPaint& fOrigPaint; | 429 const SkPaint& fOrigPaint; |
| 387 SkDrawFilter* fFilter; | 430 SkDrawFilter* fFilter; |
| 388 const SkPaint* fPaint; | 431 const SkPaint* fPaint; |
| 389 int fSaveCount; | 432 int fSaveCount; |
| 390 uint32_t fNewPaintFlags; | 433 uint32_t fNewPaintFlags; |
| 391 bool fTempLayerForImageFilter; | 434 bool fTempLayerForImageFilter; |
| 392 bool fDone; | 435 bool fDone; |
| 393 bool fIsSimple; | 436 bool fIsSimple; |
| 394 SkDrawLooper::Context* fLooperContext; | 437 SkDrawLooper::Context* fLooperContext; |
| 395 SkSmallAllocator<1, 32> fLooperContextAllocator; | 438 SkSmallAllocator<1, 32> fLooperContextAllocator; |
| 396 | 439 |
| 397 bool doNext(SkDrawFilter::Type drawType); | 440 bool doNext(SkDrawFilter::Type drawType); |
| 398 }; | 441 }; |
| 399 | 442 |
| 400 bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { | 443 bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { |
| 401 fPaint = NULL; | 444 fPaint = NULL; |
| 402 SkASSERT(!fIsSimple); | 445 SkASSERT(!fIsSimple); |
| 403 SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); | 446 SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); |
| 404 | 447 |
| 405 SkPaint* paint = fLazyPaint.set(fOrigPaint); | 448 SkPaint* paint = fLazyPaintPerNext.set(fLazyPaintInit.isValid() ? |
| 449 *fLazyPaintInit.get() : fOrigPaint); | |
| 406 paint->setFlags(fNewPaintFlags); | 450 paint->setFlags(fNewPaintFlags); |
| 407 | 451 |
| 408 if (fTempLayerForImageFilter) { | 452 if (fTempLayerForImageFilter) { |
| 409 paint->setImageFilter(NULL); | 453 paint->setImageFilter(NULL); |
| 410 paint->setXfermode(NULL); | 454 paint->setXfermode(NULL); |
| 411 } | 455 } |
| 412 | 456 |
| 413 if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { | 457 if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { |
| 414 fDone = true; | 458 fDone = true; |
| 415 return false; | 459 return false; |
| (...skipping 2176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2592 } | 2636 } |
| 2593 | 2637 |
| 2594 if (matrix) { | 2638 if (matrix) { |
| 2595 canvas->concat(*matrix); | 2639 canvas->concat(*matrix); |
| 2596 } | 2640 } |
| 2597 } | 2641 } |
| 2598 | 2642 |
| 2599 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2643 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
| 2600 fCanvas->restoreToCount(fSaveCount); | 2644 fCanvas->restoreToCount(fSaveCount); |
| 2601 } | 2645 } |
| OLD | NEW |