use colorfilter instead of imagefilter when possible
big speed win w/ nanobench --match colorfilter_ BUG=skia: TBR= Will require rebaselining, so landing temporarily to trigger layouttests. Review URL: https://codereview.chromium.org/966233002
This commit is contained in:
parent
cedc36f18b
commit
f641bd076d
@ -8,6 +8,7 @@
|
||||
#include "SkCanvas.h"
|
||||
#include "SkCanvasPriv.h"
|
||||
#include "SkBitmapDevice.h"
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkDeviceImageFilterProxy.h"
|
||||
#include "SkDraw.h"
|
||||
#include "SkDrawable.h"
|
||||
@ -283,6 +284,36 @@ private:
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) {
|
||||
return lazy->isValid() ? lazy->get() : lazy->set(orig);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that
|
||||
* colorfilter, else return NULL.
|
||||
*/
|
||||
static SkColorFilter* image_to_color_filter(const SkPaint& paint) {
|
||||
SkImageFilter* imgf = paint.getImageFilter();
|
||||
if (!imgf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SkColorFilter* imgCF;
|
||||
if (!imgf->asAColorFilter(&imgCF)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SkColorFilter* paintCF = paint.getColorFilter();
|
||||
if (NULL == paintCF) {
|
||||
// there is no existing paint colorfilter, so we can just return the imagefilter's
|
||||
return imgCF;
|
||||
}
|
||||
|
||||
// The paint has both a colorfilter and an imagefilter.
|
||||
SkAutoTUnref<SkColorFilter> autoImgCF(imgCF);
|
||||
return SkColorFilter::CreateComposeFilter(imgCF, paintCF);
|
||||
}
|
||||
|
||||
class AutoDrawLooper {
|
||||
public:
|
||||
AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint,
|
||||
@ -295,9 +326,17 @@ public:
|
||||
fDoClearImageFilter = false;
|
||||
fDone = false;
|
||||
|
||||
if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) {
|
||||
SkColorFilter* simplifiedCF = image_to_color_filter(fOrigPaint);
|
||||
if (simplifiedCF) {
|
||||
SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint);
|
||||
paint->setColorFilter(simplifiedCF)->unref();
|
||||
paint->setImageFilter(NULL);
|
||||
fPaint = paint;
|
||||
}
|
||||
|
||||
if (!skipLayerForImageFilter && fPaint->getImageFilter()) {
|
||||
SkPaint tmp;
|
||||
tmp.setImageFilter(fOrigPaint.getImageFilter());
|
||||
tmp.setImageFilter(fPaint->getImageFilter());
|
||||
(void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag,
|
||||
true, SkCanvas::kFullLayer_SaveLayerStrategy);
|
||||
// we'll clear the imageFilter for the actual draws in next(), so
|
||||
@ -319,7 +358,7 @@ public:
|
||||
uint32_t oldFlags = paint.getFlags();
|
||||
fNewPaintFlags = filter_paint_flags(props, oldFlags);
|
||||
if (fIsSimple && (fNewPaintFlags != oldFlags)) {
|
||||
SkPaint* paint = fLazyPaint.set(fOrigPaint);
|
||||
SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint);
|
||||
paint->setFlags(fNewPaintFlags);
|
||||
fPaint = paint;
|
||||
// if we're not simple, doNext() will take care of calling setFlags()
|
||||
@ -350,7 +389,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
SkLazyPaint fLazyPaint;
|
||||
SkLazyPaint fLazyPaintInit, fLazyPaintPerNext;
|
||||
SkCanvas* fCanvas;
|
||||
const SkPaint& fOrigPaint;
|
||||
SkDrawFilter* fFilter;
|
||||
@ -371,7 +410,8 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) {
|
||||
SkASSERT(!fIsSimple);
|
||||
SkASSERT(fLooperContext || fFilter || fDoClearImageFilter);
|
||||
|
||||
SkPaint* paint = fLazyPaint.set(fOrigPaint);
|
||||
SkPaint* paint = fLazyPaintPerNext.set(fLazyPaintInit.isValid() ?
|
||||
*fLazyPaintInit.get() : fOrigPaint);
|
||||
paint->setFlags(fNewPaintFlags);
|
||||
|
||||
if (fDoClearImageFilter) {
|
||||
|
Loading…
Reference in New Issue
Block a user