Protect filter_texture() against render target change.
Fix blend filters when input textures are "sloppy" (approx scratch texture match)
Add a new test case to gm/imagefiltersgraph, and reduce its size.
NOTE: this will require new baselines for the imagefiltersgraph GM.
BUG=950
Review URL: https://codereview.appspot.com/6769043
git-svn-id: http://skia.googlecode.com/svn/trunk@6073 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/imagefiltersgraph.cpp b/gm/imagefiltersgraph.cpp
index 816c88e..a85aa6d 100644
--- a/gm/imagefiltersgraph.cpp
+++ b/gm/imagefiltersgraph.cpp
@@ -8,8 +8,10 @@
#include "gm.h"
#include "SkBitmapSource.h"
+#include "SkBlendImageFilter.h"
#include "SkBlurImageFilter.h"
#include "SkColorFilter.h"
+#include "SkColorMatrixFilter.h"
#include "SkColorFilterImageFilter.h"
#include "SkMorphologyImageFilter.h"
@@ -40,7 +42,7 @@
canvas.drawText(str, strlen(str), SkIntToScalar(20), SkIntToScalar(70), paint);
}
- virtual SkISize onISize() { return SkISize::Make(500, 500); }
+ virtual SkISize onISize() { return SkISize::Make(200, 100); }
virtual void onDraw(SkCanvas* canvas) {
if (!fInitialized) {
@@ -48,19 +50,35 @@
fInitialized = true;
}
canvas->clear(0x00000000);
+ {
+ SkAutoTUnref<SkImageFilter> bitmapSource(new SkBitmapSource(fBitmap));
+ SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorRED,
+ 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> merge(new SkMergeImageFilter(blur, color));
- SkAutoTUnref<SkImageFilter> bitmapSource(new SkBitmapSource(fBitmap));
+ SkPaint paint;
+ paint.setImageFilter(merge);
+ canvas->drawPaint(paint);
+ }
+ {
+ SkAutoTUnref<SkImageFilter> morph(new SkDilateImageFilter(5, 5));
- SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorRED,
- 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> merge(new SkMergeImageFilter(blur, color));
+ SkScalar matrix[20] = { SK_Scalar1, 0, 0, 0, 0,
+ 0, SK_Scalar1, 0, 0, 0,
+ 0, 0, SK_Scalar1, 0, 0,
+ 0, 0, 0, SkFloatToScalar(0.5f), 0 };
- SkPaint paint;
- paint.setImageFilter(merge);
- canvas->drawPaint(paint);
+ SkAutoTUnref<SkColorFilter> matrixFilter(new SkColorMatrixFilter(matrix));
+ SkAutoTUnref<SkImageFilter> colorMorph(new SkColorFilterImageFilter(matrixFilter, morph));
+ SkAutoTUnref<SkImageFilter> blendColor(new SkBlendImageFilter(SkBlendImageFilter::kNormal_Mode, colorMorph));
+
+ SkPaint paint;
+ paint.setImageFilter(blendColor);
+ canvas->drawBitmap(fBitmap, 100, 0, &paint);
+ }
}
private:
diff --git a/src/effects/SkBlendImageFilter.cpp b/src/effects/SkBlendImageFilter.cpp
index 455ddcb..b93190f 100644
--- a/src/effects/SkBlendImageFilter.cpp
+++ b/src/effects/SkBlendImageFilter.cpp
@@ -203,11 +203,14 @@
GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
GrContext::AutoClip ac(context, rect);
- GrMatrix sampleM;
- sampleM.setIDiv(background->width(), background->height());
+ GrMatrix backgroundTexMatrix, foregroundTexMatrix;
+ backgroundTexMatrix.setIDiv(background->width(), background->height());
+ foregroundTexMatrix.setIDiv(foreground->width(), foreground->height());
GrPaint paint;
- paint.colorSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, (background.get())), sampleM)->unref();
- paint.colorSampler(1)->setCustomStage(SkNEW_ARGS(GrBlendEffect, (fMode, foreground.get())), sampleM)->unref();
+ paint.colorSampler(0)->setCustomStage(
+ SkNEW_ARGS(GrSingleTextureEffect, (background.get())), backgroundTexMatrix)->unref();
+ paint.colorSampler(1)->setCustomStage(
+ SkNEW_ARGS(GrBlendEffect, (fMode, foreground.get())), foregroundTexMatrix)->unref();
context->drawRect(paint, rect);
return dst;
}
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 52d26bb..fc1f86c 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1478,6 +1478,9 @@
GrCustomStage* stage;
if (filter->canFilterImageGPU()) {
+ // Save the render target and set it to NULL, so we don't accidentally draw to it in the
+ // filter. Also set the clip wide open and the matrix to identity.
+ GrContext::AutoWideOpenIdentityDraw awo(context, NULL);
texture = filter->onFilterImageGPU(&proxy, texture, rect);
} else if (filter->asNewCustomStage(&stage, texture)) {
GrAutoScratchTexture dst(context, desc);