Chromium Code Reviews| Index: src/core/SkCanvas.cpp |
| diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp |
| index 68ced602f62da23dc3094de28326797c5502652b..2434fc360e726e84ee0d118b8469d53da351d4a7 100644 |
| --- a/src/core/SkCanvas.cpp |
| +++ b/src/core/SkCanvas.cpp |
| @@ -308,17 +308,29 @@ public: |
| fFilter = canvas->getDrawFilter(); |
| fPaint = &fOrigPaint; |
| fSaveCount = canvas->getSaveCount(); |
| - fDoClearImageFilter = false; |
| + fTempLayerForImageFilter = false; |
| fDone = false; |
| if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { |
| + /** |
| + * We implement ImageFilters for a given draw by creating a layer, then applying the |
| + * imagefilter to the pixels of that layer (its backing surface/image), and then |
| + * we call restore() to apply that layer to the main canvas. |
| + * |
| + * To generate the src pixels for the filter, we remove the imagefilter and the |
| + * xfermode from the paint that we (AutoDrawLooper) return (fPaint). The imagefilter |
| + * is applied right before the restore, and the xfermode is applied during the restore. |
|
Stephen White
2015/04/20 14:36:46
Nit: this might be slightly misleading: the imagef
reed1
2015/04/20 14:49:19
Done.
|
| + * |
| + * We strip the imagefilter/xfermode inside doNext(). |
| + */ |
| SkPaint tmp; |
| + // store the imagefilter/xfermode on the layer's paint, so they can be applied in |
| + // restore. |
| tmp.setImageFilter(fOrigPaint.getImageFilter()); |
| + tmp.setXfermode(fOrigPaint.getXfermode()); |
| (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag, |
| SkCanvas::kFullLayer_SaveLayerStrategy); |
| - // we'll clear the imageFilter for the actual draws in next(), so |
| - // it will only be applied during the restore(). |
| - fDoClearImageFilter = true; |
| + fTempLayerForImageFilter = true; |
|
Stephen White
2015/04/20 14:36:46
This name is much clearer to me; thanks for that!
|
| } |
| if (SkDrawLooper* looper = paint.getLooper()) { |
| @@ -329,7 +341,7 @@ public: |
| } else { |
| fLooperContext = NULL; |
| // can we be marked as simple? |
| - fIsSimple = !fFilter && !fDoClearImageFilter; |
| + fIsSimple = !fFilter && !fTempLayerForImageFilter; |
| } |
| uint32_t oldFlags = paint.getFlags(); |
| @@ -343,7 +355,7 @@ public: |
| } |
| ~AutoDrawLooper() { |
| - if (fDoClearImageFilter) { |
| + if (fTempLayerForImageFilter) { |
| fCanvas->internalRestore(); |
| } |
| SkASSERT(fCanvas->getSaveCount() == fSaveCount); |
| @@ -373,7 +385,7 @@ private: |
| const SkPaint* fPaint; |
| int fSaveCount; |
| uint32_t fNewPaintFlags; |
| - bool fDoClearImageFilter; |
| + bool fTempLayerForImageFilter; |
| bool fDone; |
| bool fIsSimple; |
| SkDrawLooper::Context* fLooperContext; |
| @@ -385,13 +397,14 @@ private: |
| bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { |
| fPaint = NULL; |
| SkASSERT(!fIsSimple); |
| - SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); |
| + SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); |
| SkPaint* paint = fLazyPaint.set(fOrigPaint); |
| paint->setFlags(fNewPaintFlags); |
| - if (fDoClearImageFilter) { |
| + if (fTempLayerForImageFilter) { |
| paint->setImageFilter(NULL); |
| + paint->setXfermode(NULL); |
| } |
| if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { |