From cd9f55989e680b7f52fa21766dde0ac67ac9911f Mon Sep 17 00:00:00 2001 From: "senorblanco@chromium.org" Date: Fri, 26 Oct 2012 19:37:00 +0000 Subject: [PATCH] Add a factory Create function for SkColorFilterImageFilter, and move the matrix optimization there. This will allow the Chrome compositor to extract the optimized matrix, and potentially apply the color matrix itself, saving a buffer allocation & draw. Review URL: https://codereview.appspot.com/6739057 git-svn-id: http://skia.googlecode.com/svn/trunk@6152 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gm/colorfilterimagefilter.cpp | 6 +-- gm/imagefiltersbase.cpp | 4 +- gm/imagefiltersgraph.cpp | 4 +- gm/testimagefilters.cpp | 6 +-- include/effects/SkColorFilterImageFilter.h | 3 +- src/effects/SkColorFilterImageFilter.cpp | 46 ++++++++++------------ 6 files changed, 31 insertions(+), 38 deletions(-) diff --git a/gm/colorfilterimagefilter.cpp b/gm/colorfilterimagefilter.cpp index 556e88a186..60148b36f9 100644 --- a/gm/colorfilterimagefilter.cpp +++ b/gm/colorfilterimagefilter.cpp @@ -29,7 +29,7 @@ static SkImageFilter* make_brightness(float amount, SkImageFilter* input = NULL) 0, 0, 1, 0, amount255, 0, 0, 0, 1, 0 }; SkAutoTUnref filter(new SkColorMatrixFilter(matrix)); - return new SkColorFilterImageFilter(filter, input); + return SkColorFilterImageFilter::Create(filter, input); } static SkImageFilter* make_grayscale(SkImageFilter* input = NULL) { @@ -40,13 +40,13 @@ static SkImageFilter* make_grayscale(SkImageFilter* input = NULL) { matrix[2] = matrix[7] = matrix[12] = SkFloatToScalar(0.0722f); matrix[18] = SkFloatToScalar(1.0f); SkAutoTUnref filter(new SkColorMatrixFilter(matrix)); - return new SkColorFilterImageFilter(filter, input); + return SkColorFilterImageFilter::Create(filter, input); } static SkImageFilter* make_mode_blue(SkImageFilter* input = NULL) { SkAutoTUnref filter( SkColorFilter::CreateModeFilter(SK_ColorBLUE, SkXfermode::kSrcIn_Mode)); - return new SkColorFilterImageFilter(filter, input); + return SkColorFilterImageFilter::Create(filter, input); } class ColorFilterImageFilterGM : public skiagm::GM { diff --git a/gm/imagefiltersbase.cpp b/gm/imagefiltersbase.cpp index bcceb5895f..7f8aeaf231 100644 --- a/gm/imagefiltersbase.cpp +++ b/gm/imagefiltersbase.cpp @@ -176,12 +176,10 @@ protected: SkColorFilter* cf = SkColorFilter::CreateModeFilter(SK_ColorRED, SkXfermode::kSrcIn_Mode); SkImageFilter* filters[] = { -#if 1 NULL, new IdentityImageFilter, new FailImageFilter, - new SkColorFilterImageFilter(cf), -#endif + SkColorFilterImageFilter::Create(cf), new SkBlurImageFilter(12.0f, 0.0f), }; cf->unref(); diff --git a/gm/imagefiltersgraph.cpp b/gm/imagefiltersgraph.cpp index a85aa6d161..e61c85f937 100644 --- a/gm/imagefiltersgraph.cpp +++ b/gm/imagefiltersgraph.cpp @@ -56,7 +56,7 @@ protected: SkXfermode::kSrcIn_Mode)); SkAutoTUnref blur(new SkBlurImageFilter(4.0f, 4.0f, bitmapSource)); SkAutoTUnref erode(new SkErodeImageFilter(4, 4, blur)); - SkAutoTUnref color(new SkColorFilterImageFilter(cf, erode)); + SkAutoTUnref color(SkColorFilterImageFilter::Create(cf, erode)); SkAutoTUnref merge(new SkMergeImageFilter(blur, color)); SkPaint paint; @@ -72,7 +72,7 @@ protected: 0, 0, 0, SkFloatToScalar(0.5f), 0 }; SkAutoTUnref matrixFilter(new SkColorMatrixFilter(matrix)); - SkAutoTUnref colorMorph(new SkColorFilterImageFilter(matrixFilter, morph)); + SkAutoTUnref colorMorph(SkColorFilterImageFilter::Create(matrixFilter, morph)); SkAutoTUnref blendColor(new SkBlendImageFilter(SkBlendImageFilter::kNormal_Mode, colorMorph)); SkPaint paint; diff --git a/gm/testimagefilters.cpp b/gm/testimagefilters.cpp index 39b974b296..e046416b0f 100644 --- a/gm/testimagefilters.cpp +++ b/gm/testimagefilters.cpp @@ -24,7 +24,7 @@ static SkImageFilter* make2() { SkColorFilter* cf = SkColorFilter::CreateModeFilter(SK_ColorBLUE, SkXfermode::kSrcIn_Mode); SkAutoUnref aur(cf); - return new SkColorFilterImageFilter(cf); + return SkColorFilterImageFilter::Create(cf); } static SkImageFilter* make3() { return new SkBlurImageFilter(8, 0); @@ -56,7 +56,7 @@ static SkImageFilter* make6() { SkColorFilter* cf = SkColorFilter::CreateModeFilter(0x880000FF, SkXfermode::kSrcIn_Mode); SkAutoUnref aur3(cf); - SkImageFilter* blue = new SkColorFilterImageFilter(cf); + SkImageFilter* blue = SkColorFilterImageFilter::Create(cf); SkAutoUnref aur4(blue); return new SkMergeImageFilter(compose, blue); @@ -73,7 +73,7 @@ static SkImageFilter* make7() { SkColorFilter* cf = SkColorFilter::CreateModeFilter(0x880000FF, SkXfermode::kSrcIn_Mode); SkAutoUnref aur3(cf); - SkImageFilter* blue = new SkColorFilterImageFilter(cf); + SkImageFilter* blue = SkColorFilterImageFilter::Create(cf); SkAutoUnref aur4(blue); return new SkMergeImageFilter(compose, blue); diff --git a/include/effects/SkColorFilterImageFilter.h b/include/effects/SkColorFilterImageFilter.h index e9124f9123..bff9293816 100755 --- a/include/effects/SkColorFilterImageFilter.h +++ b/include/effects/SkColorFilterImageFilter.h @@ -14,7 +14,7 @@ class SkColorFilter; class SK_API SkColorFilterImageFilter : public SkSingleInputImageFilter { public: - SkColorFilterImageFilter(SkColorFilter* cf, SkImageFilter* input = NULL); + static SkColorFilterImageFilter* Create(SkColorFilter* cf, SkImageFilter* input = NULL); virtual ~SkColorFilterImageFilter(); SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorFilterImageFilter) @@ -29,6 +29,7 @@ protected: virtual SkColorFilter* asColorFilter() const SK_OVERRIDE; private: + SkColorFilterImageFilter(SkColorFilter* cf, SkImageFilter* input); SkColorFilter* fColorFilter; typedef SkSingleInputImageFilter INHERITED; diff --git a/src/effects/SkColorFilterImageFilter.cpp b/src/effects/SkColorFilterImageFilter.cpp index 22b5d12c9c..369f782d18 100755 --- a/src/effects/SkColorFilterImageFilter.cpp +++ b/src/effects/SkColorFilterImageFilter.cpp @@ -56,6 +56,24 @@ bool matrix_needs_clamping(SkScalar matrix[20]) { }; +SkColorFilterImageFilter* SkColorFilterImageFilter::Create(SkColorFilter* cf, + SkImageFilter* input) { + SkASSERT(cf); + SkScalar colorMatrix[20], inputMatrix[20]; + SkColorFilter* inputColorFilter; + if (input && cf->asColorMatrix(colorMatrix) + && (inputColorFilter = input->asColorFilter()) + && inputColorFilter->asColorMatrix(inputMatrix) + && !matrix_needs_clamping(inputMatrix)) { + SkScalar combinedMatrix[20]; + mult_color_matrix(inputMatrix, colorMatrix, combinedMatrix); + SkAutoTUnref newCF(SkNEW_ARGS(SkColorMatrixFilter, (combinedMatrix))); + return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0))); + } else { + return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input)); + } +} + SkColorFilterImageFilter::SkColorFilterImageFilter(SkColorFilter* cf, SkImageFilter* input) : INHERITED(input), fColorFilter(cf) { SkASSERT(cf); SkSafeRef(cf); @@ -79,37 +97,13 @@ bool SkColorFilterImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& sourc const SkMatrix& matrix, SkBitmap* result, SkIPoint* loc) { - SkImageFilter* parent = getInput(0); - SkScalar colorMatrix[20]; - SkBitmap src; - SkColorFilter* cf; - if (parent && fColorFilter->asColorMatrix(colorMatrix)) { - SkColorFilter* parentColorFilter; - SkScalar parentMatrix[20]; - while (parent && (parentColorFilter = parent->asColorFilter()) - && parentColorFilter->asColorMatrix(parentMatrix) - && !matrix_needs_clamping(parentMatrix)) { - SkScalar combinedMatrix[20]; - mult_color_matrix(parentMatrix, colorMatrix, combinedMatrix); - memcpy(colorMatrix, combinedMatrix, 20 * sizeof(SkScalar)); - parent = parent->getInput(0); - } - if (!parent || !parent->filterImage(proxy, source, matrix, &src, loc)) { - src = source; - } - cf = SkNEW_ARGS(SkColorMatrixFilter, (colorMatrix)); - } else { - src = this->getInputResult(proxy, source, matrix, loc); - cf = fColorFilter; - cf->ref(); - } - + SkBitmap src = this->getInputResult(proxy, source, matrix, loc); SkAutoTUnref device(proxy->createDevice(src.width(), src.height())); SkCanvas canvas(device.get()); SkPaint paint; paint.setXfermodeMode(SkXfermode::kSrc_Mode); - paint.setColorFilter(cf)->unref(); + paint.setColorFilter(fColorFilter); canvas.drawSprite(src, 0, 0, &paint); *result = device.get()->accessBitmap(false);