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
This commit is contained in:
senorblanco@chromium.org 2012-10-26 19:37:00 +00:00
parent a76de72a60
commit cd9f55989e
6 changed files with 31 additions and 38 deletions

View File

@ -29,7 +29,7 @@ static SkImageFilter* make_brightness(float amount, SkImageFilter* input = NULL)
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 @@ static SkImageFilter* make_grayscale(SkImageFilter* input = NULL) {
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 {

View File

@ -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();

View File

@ -56,7 +56,7 @@ protected:
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 @@ protected:
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;

View File

@ -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);

View File

@ -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;

View File

@ -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<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 @@ 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<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);