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

Unified Diff: src/core/SkCanvas.cpp

Issue 1091173003: apply xfermode after imagefilter when we create a tmp layer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkCanvas.cpp
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 68ced602f62da23dc3094de28326797c5502652b..0bd9eb357944bf4de88f101f68382cbf68ecab07 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -308,17 +308,32 @@ 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 xfer that layer to the main canvas.
+ *
+ * 1. SaveLayer (with a paint containing the current imagefilter and xfermode)
+ * 2. Generate the src pixels:
+ * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper)
+ * return (fPaint). We then draw the primitive (using srcover) into a cleared
Stephen White 2015/04/20 14:55:45 Out of curiosity, would it be equivalent to use Sr
+ * buffer/surface.
+ * 3. Restore the layer created in #1
+ * The imagefilter is passed the buffer/surface from the layer (now filled with the
+ * src pixels of the primitive). It returns a new "filtered" buffer, which we
+ * draw onto the previous layer using the xfermode from the original paint.
+ */
SkPaint tmp;
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;
+ // we remove the imagefilter/xfermode inside doNext()
}
if (SkDrawLooper* looper = paint.getLooper()) {
@@ -329,7 +344,7 @@ public:
} else {
fLooperContext = NULL;
// can we be marked as simple?
- fIsSimple = !fFilter && !fDoClearImageFilter;
+ fIsSimple = !fFilter && !fTempLayerForImageFilter;
}
uint32_t oldFlags = paint.getFlags();
@@ -343,7 +358,7 @@ public:
}
~AutoDrawLooper() {
- if (fDoClearImageFilter) {
+ if (fTempLayerForImageFilter) {
fCanvas->internalRestore();
}
SkASSERT(fCanvas->getSaveCount() == fSaveCount);
@@ -373,7 +388,7 @@ private:
const SkPaint* fPaint;
int fSaveCount;
uint32_t fNewPaintFlags;
- bool fDoClearImageFilter;
+ bool fTempLayerForImageFilter;
bool fDone;
bool fIsSimple;
SkDrawLooper::Context* fLooperContext;
@@ -385,13 +400,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)) {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698