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
diff --git a/gm/colorfilterimagefilter.cpp b/gm/colorfilterimagefilter.cpp
index 556e88a..60148b3 100644
--- a/gm/colorfilterimagefilter.cpp
+++ b/gm/colorfilterimagefilter.cpp
@@ -29,7 +29,7 @@
0, 0, 1, 0, amount255,
0, 0, 0, 1, 0 };
SkAutoTUnref<SkColorFilter> 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 @@
matrix[2] = matrix[7] = matrix[12] = SkFloatToScalar(0.0722f);
matrix[18] = SkFloatToScalar(1.0f);
SkAutoTUnref<SkColorFilter> filter(new SkColorMatrixFilter(matrix));
- return new SkColorFilterImageFilter(filter, input);
+ return SkColorFilterImageFilter::Create(filter, input);
}
static SkImageFilter* make_mode_blue(SkImageFilter* input = NULL) {
SkAutoTUnref<SkColorFilter> 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 bcceb58..7f8aeaf 100644
--- a/gm/imagefiltersbase.cpp
+++ b/gm/imagefiltersbase.cpp
@@ -176,12 +176,10 @@
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 a85aa6d..e61c85f 100644
--- a/gm/imagefiltersgraph.cpp
+++ b/gm/imagefiltersgraph.cpp
@@ -56,7 +56,7 @@
SkXfermode::kSrcIn_Mode));
SkAutoTUnref<SkImageFilter> blur(new SkBlurImageFilter(4.0f, 4.0f, bitmapSource));
SkAutoTUnref<SkImageFilter> erode(new SkErodeImageFilter(4, 4, blur));
- SkAutoTUnref<SkImageFilter> color(new SkColorFilterImageFilter(cf, erode));
+ SkAutoTUnref<SkImageFilter> color(SkColorFilterImageFilter::Create(cf, erode));
SkAutoTUnref<SkImageFilter> merge(new SkMergeImageFilter(blur, color));
SkPaint paint;
@@ -72,7 +72,7 @@
0, 0, 0, SkFloatToScalar(0.5f), 0 };
SkAutoTUnref<SkColorFilter> matrixFilter(new SkColorMatrixFilter(matrix));
- SkAutoTUnref<SkImageFilter> colorMorph(new SkColorFilterImageFilter(matrixFilter, morph));
+ SkAutoTUnref<SkImageFilter> colorMorph(SkColorFilterImageFilter::Create(matrixFilter, morph));
SkAutoTUnref<SkImageFilter> blendColor(new SkBlendImageFilter(SkBlendImageFilter::kNormal_Mode, colorMorph));
SkPaint paint;
diff --git a/gm/testimagefilters.cpp b/gm/testimagefilters.cpp
index 39b974b..e046416 100644
--- a/gm/testimagefilters.cpp
+++ b/gm/testimagefilters.cpp
@@ -24,7 +24,7 @@
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 @@
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 @@
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 e9124f9..bff9293 100755
--- a/include/effects/SkColorFilterImageFilter.h
+++ b/include/effects/SkColorFilterImageFilter.h
@@ -14,7 +14,7 @@
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 @@
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 22b5d12..369f782 100755
--- a/src/effects/SkColorFilterImageFilter.cpp
+++ b/src/effects/SkColorFilterImageFilter.cpp
@@ -56,6 +56,24 @@
};
+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<SkColorFilter> 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 @@
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<SkDevice> 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);