Add SkImageFilters::Blend rename for Xfermode filter

This better matches SkShaders::Blend and SkColorFilters::Blend factories.

Bug: skia:9310
Change-Id: I02a3fe488a446b803df96518caacff1fdf536e9f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/324623
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Michael Ludwig 2020-10-09 10:45:07 -04:00 committed by Skia Commit-Bot
parent 8dbdf23f31
commit 01b93eabe2
15 changed files with 72 additions and 53 deletions

View File

@ -9,6 +9,11 @@ Milestone 88
* <insert new release notes here>
* Add new SkImageFilters::Blend factory function, in place of the now deprecated
SkImageFilters::Xfermode factory function. Behavior is identical, but name better matches
conventions in SkShader and SkColorFilter.
https://review.skia.org/324623
* SkImageFilters::Foo() factory functions now accept SkIRect, SkRect, and optional SkIRect* or
SkRect*, instead of previously just the optional SkIRect*. Internally, the crop rects are stored
as floats to allow for fractional crops to be defined in the local coordinate system (before

View File

@ -149,7 +149,7 @@ protected:
auto offset1 = SkImageFilters::Offset(100.0f, 100.0f, blur);
auto offset2 = SkImageFilters::Offset(-100.0f, -100.0f, blur);
auto xfermode =
SkImageFilters::Xfermode(SkBlendMode::kSrcIn, offset1, offset2, nullptr);
SkImageFilters::Blend(SkBlendMode::kSrcIn, offset1, offset2, nullptr);
SkPaint paint;
paint.setImageFilter(xfermode);

View File

@ -785,8 +785,8 @@ static sk_sp<SkImageFilter> make_fuzz_imageFilter(Fuzz* fuzz, int depth) {
}
sk_sp<SkImageFilter> bg = make_fuzz_imageFilter(fuzz, depth - 1);
sk_sp<SkImageFilter> fg = make_fuzz_imageFilter(fuzz, depth - 1);
return SkImageFilters::Xfermode(blendMode, std::move(bg), std::move(fg),
useCropRect ? &cropRect : nullptr);
return SkImageFilters::Blend(blendMode, std::move(bg), std::move(fg),
useCropRect ? &cropRect : nullptr);
}
case 24: {
sk_sp<SkShader> shader = make_fuzz_shader(fuzz, depth - 1);

View File

@ -28,7 +28,7 @@ DEF_SIMPLE_GM(crbug_905548, canvas, 100, 200) {
auto blurred = SkImageFilters::Blur(15, 15, imageSource);
auto eroded = SkImageFilters::Erode(0, 0, blurred);
auto blended = SkImageFilters::Xfermode(SkBlendMode::kDstOut, eroded, imageSource, nullptr);
auto blended = SkImageFilters::Blend(SkBlendMode::kDstOut, eroded, imageSource, nullptr);
SkPaint paint;
paint.setImageFilter(blended);

View File

@ -257,7 +257,7 @@ DEF_SIMPLE_GM(imagefilters_effect_order, canvas, 512, 512) {
// If edge detector sees the mask filter, it'll have alpha and then blend with the original
// image; otherwise the mask filter will apply late (incorrectly) and none of the original
// image will be visible.
sk_sp<SkImageFilter> edgeBlend = SkImageFilters::Xfermode(SkBlendMode::kSrcOver,
sk_sp<SkImageFilter> edgeBlend = SkImageFilters::Blend(SkBlendMode::kSrcOver,
SkImageFilters::Image(image), edgeDetector);
SkPaint testMaskPaint;
@ -266,8 +266,8 @@ DEF_SIMPLE_GM(imagefilters_effect_order, canvas, 512, 512) {
SkPaint expectedMaskPaint;
expectedMaskPaint.setImageFilter(SkImageFilters::Compose(edgeBlend,
SkImageFilters::Xfermode(SkBlendMode::kSrcIn,
SkImageFilters::Shader(alphaMaskShader))));
SkImageFilters::Blend(SkBlendMode::kSrcIn,
SkImageFilters::Shader(alphaMaskShader))));
canvas->save();
canvas->translate(0, image->height());

View File

@ -71,8 +71,8 @@ protected:
sk_sp<SkImageFilter> colorMorph(SkImageFilters::ColorFilter(std::move(matrixFilter),
std::move(morph)));
SkPaint paint;
paint.setImageFilter(SkImageFilters::Xfermode(SkBlendMode::kSrcOver,
std::move(colorMorph)));
paint.setImageFilter(SkImageFilters::Blend(SkBlendMode::kSrcOver,
std::move(colorMorph)));
DrawClippedImage(canvas, fImage.get(), paint);
canvas->translate(SkIntToScalar(100), 0);
@ -100,7 +100,7 @@ protected:
SkIRect cropRect = SkIRect::MakeWH(95, 100);
SkPaint paint;
paint.setImageFilter(
SkImageFilters::Xfermode(SkBlendMode::kSrcIn, std::move(blur), nullptr, &cropRect));
SkImageFilters::Blend(SkBlendMode::kSrcIn, std::move(blur), nullptr, &cropRect));
DrawClippedImage(canvas, fImage.get(), paint);
canvas->translate(SkIntToScalar(100), 0);
}

View File

@ -135,7 +135,7 @@ DEF_SIMPLE_GM(rotate_imagefilter, canvas, 500, 500) {
sk_sp<SkImageFilter> filters[] = {
nullptr,
SkImageFilters::Blur(6, 0, nullptr),
SkImageFilters::Xfermode(SkBlendMode::kSrcOver, nullptr),
SkImageFilters::Blend(SkBlendMode::kSrcOver, nullptr),
};
for (auto& filter : filters) {

View File

@ -98,9 +98,9 @@ static sk_sp<SkImageFilter> arithmetic_factory(sk_sp<SkImage> auxImage, const Sk
nullptr, cropRect);
}
static sk_sp<SkImageFilter> xfermode_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
static sk_sp<SkImageFilter> blend_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
sk_sp<SkImageFilter> background = SkImageFilters::Image(std::move(auxImage));
return SkImageFilters::Xfermode(
return SkImageFilters::Blend(
SkBlendMode::kModulate, std::move(background), nullptr, cropRect);
}
@ -233,7 +233,7 @@ protected:
erode_factory,
displacement_factory,
arithmetic_factory,
xfermode_factory,
blend_factory,
convolution_factory,
matrix_factory,
alpha_threshold_factory,
@ -249,7 +249,7 @@ protected:
"Erode",
"Displacement",
"Arithmetic",
"Xfer Mode",
"Xfer Mode", // "blend"
"Convolution",
"Matrix Xform",
"Alpha Threshold",

View File

@ -92,7 +92,7 @@ protected:
int x = 0, y = 0;
sk_sp<SkImageFilter> background(SkImageFilters::Image(fCheckerboard));
for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
paint.setImageFilter(SkImageFilters::Xfermode(gModes[i], background));
paint.setImageFilter(SkImageFilters::Blend(gModes[i], background));
DrawClippedBitmap(canvas, fBitmap, paint, x, y);
x += fBitmap.width() + MARGIN;
if (x + fBitmap.width() > WIDTH) {
@ -109,7 +109,7 @@ protected:
y += fBitmap.height() + MARGIN;
}
// Test nullptr mode
paint.setImageFilter(SkImageFilters::Xfermode(SkBlendMode::kSrcOver, background));
paint.setImageFilter(SkImageFilters::Blend(SkBlendMode::kSrcOver, background));
DrawClippedBitmap(canvas, fBitmap, paint, x, y);
x += fBitmap.width() + MARGIN;
if (x + fBitmap.width() > WIDTH) {
@ -123,7 +123,7 @@ protected:
sk_sp<SkImageFilter> foreground(SkImageFilters::Image(std::move(bitmapImage)));
sk_sp<SkImageFilter> offsetForeground(SkImageFilters::Offset(4, -4, foreground));
sk_sp<SkImageFilter> offsetBackground(SkImageFilters::Offset(4, 4, background));
paint.setImageFilter(SkImageFilters::Xfermode(
paint.setImageFilter(SkImageFilters::Blend(
SkBlendMode::kSrcOver, offsetBackground, offsetForeground));
DrawClippedPaint(canvas, clipRect, paint, x, y);
x += fBitmap.width() + MARGIN;
@ -132,7 +132,7 @@ protected:
y += fBitmap.height() + MARGIN;
}
// Test offsets on Darken (uses shader blend)
paint.setImageFilter(SkImageFilters::Xfermode(
paint.setImageFilter(SkImageFilters::Blend(
SkBlendMode::kDarken, offsetBackground, offsetForeground));
DrawClippedPaint(canvas, clipRect, paint, x, y);
x += fBitmap.width() + MARGIN;
@ -153,8 +153,8 @@ protected:
offsets[i][1],
fBitmap.width() + offsets[i][2],
fBitmap.height() + offsets[i][3]);
paint.setImageFilter(SkImageFilters::Xfermode(sampledModes[i], offsetBackground,
offsetForeground, &cropRect));
paint.setImageFilter(SkImageFilters::Blend(sampledModes[i], offsetBackground,
offsetForeground, &cropRect));
DrawClippedPaint(canvas, clipRect, paint, x, y);
x += fBitmap.width() + MARGIN;
if (x + fBitmap.width() > WIDTH) {
@ -165,8 +165,7 @@ protected:
// Test small bg, large fg with Screen (uses shader blend)
SkIRect cropRect = SkIRect::MakeXYWH(10, 10, 60, 60);
sk_sp<SkImageFilter> cropped(SkImageFilters::Offset(0, 0, foreground, &cropRect));
paint.setImageFilter(SkImageFilters::Xfermode(SkBlendMode::kScreen, cropped, background,
nullptr));
paint.setImageFilter(SkImageFilters::Blend(SkBlendMode::kScreen, cropped, background));
DrawClippedPaint(canvas, clipRect, paint, x, y);
x += fBitmap.width() + MARGIN;
if (x + fBitmap.width() > WIDTH) {
@ -174,8 +173,7 @@ protected:
y += fBitmap.height() + MARGIN;
}
// Test small fg, large bg with Screen (uses shader blend)
paint.setImageFilter(SkImageFilters::Xfermode(SkBlendMode::kScreen, background, cropped,
nullptr));
paint.setImageFilter(SkImageFilters::Blend(SkBlendMode::kScreen, background, cropped));
DrawClippedPaint(canvas, clipRect, paint, x, y);
x += fBitmap.width() + MARGIN;
if (x + fBitmap.width() > WIDTH) {
@ -186,8 +184,8 @@ protected:
// This tests that SkXfermodeImageFilter correctly applies the compositing mode to
// the region outside the foreground.
SkIRect cropRectFull = SkIRect::MakeXYWH(0, 0, 80, 80);
paint.setImageFilter(SkImageFilters::Xfermode(SkBlendMode::kSrcIn, background, cropped,
&cropRectFull));
paint.setImageFilter(SkImageFilters::Blend(SkBlendMode::kSrcIn, background, cropped,
&cropRectFull));
DrawClippedPaint(canvas, clipRect, paint, x, y);
x += fBitmap.width() + MARGIN;
if (x + fBitmap.width() > WIDTH) {

View File

@ -81,6 +81,17 @@ public:
sk_sp<SkImageFilter> foreground,
const CropRect& cropRect = {});
/**
* This filter takes an SkBlendMode and uses it to composite the two filters together.
* @param mode The blend mode that defines the compositing operation
* @param background The Dst pixels used in blending, if null the source bitmap is used.
* @param foreground The Src pixels used in blending, if null the source bitmap is used.
* @cropRect Optional rectangle to crop input and output.
*/
static sk_sp<SkImageFilter> Blend(SkBlendMode mode, sk_sp<SkImageFilter> background,
sk_sp<SkImageFilter> foreground = nullptr,
const CropRect& cropRect = {});
/**
* Create a filter that blurs its input by the separate X and Y sigmas. The provided tile mode
* is used when the blur kernel goes outside the input image.
@ -316,13 +327,18 @@ public:
/**
* This filter takes an SkBlendMode and uses it to composite the two filters together.
* @param mode The blend mode that defines the compositing operation
* @param background The Dst pixels used in blending, if null the source bitmap is used.
* @param foreground The Src pixels used in blending, if null the source bitmap is used.
* @cropRect Optional rectangle to crop input and output.
*
* DEPRECATED: Prefer the more idiomatic Blend function
*/
static sk_sp<SkImageFilter> Xfermode(SkBlendMode, sk_sp<SkImageFilter> background,
static sk_sp<SkImageFilter> Xfermode(SkBlendMode mode, sk_sp<SkImageFilter> background,
sk_sp<SkImageFilter> foreground = nullptr,
const CropRect& cropRect = {});
const CropRect& cropRect = {}) {
return Blend(mode, std::move(background), std::move(foreground), cropRect);
}
// Morphology filter effects

View File

@ -113,7 +113,7 @@ private:
if (fType == Type::kInnerGlow) {
// Inner glows draw on top of, and are masked with, the source.
f = SkImageFilters::Xfermode(SkBlendMode::kDstIn, std::move(f));
f = SkImageFilters::Blend(SkBlendMode::kDstIn, std::move(f));
std::swap(source, f);
}

View File

@ -92,7 +92,7 @@ private:
if (fType == Type::kInnerShadow) {
// Inner shadows draw on top of, and are masked with, the source.
f = SkImageFilters::Xfermode(SkBlendMode::kDstIn, std::move(f));
f = SkImageFilters::Blend(SkBlendMode::kDstIn, std::move(f));
std::swap(source, f);
}

View File

@ -86,6 +86,13 @@ sk_sp<SkImageFilter> SkImageFilters::Arithmetic(
std::move(foreground), &r);
}
sk_sp<SkImageFilter> SkImageFilters::Blend(
SkBlendMode mode, sk_sp<SkImageFilter> background, sk_sp<SkImageFilter> foreground,
const CropRect& cropRect) {
SkImageFilter::CropRect r = to_legacy_crop_rect(cropRect);
return SkXfermodeImageFilter::Make(mode, std::move(background), std::move(foreground), &r);
}
sk_sp<SkImageFilter> SkImageFilters::Blur(
SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode, sk_sp<SkImageFilter> input,
const CropRect& cropRect) {
@ -195,13 +202,6 @@ sk_sp<SkImageFilter> SkImageFilters::Tile(
return SkTileImageFilter::Make(src, dst, std::move(input));
}
sk_sp<SkImageFilter> SkImageFilters::Xfermode(
SkBlendMode mode, sk_sp<SkImageFilter> background, sk_sp<SkImageFilter> foreground,
const CropRect& cropRect) {
SkImageFilter::CropRect r = to_legacy_crop_rect(cropRect);
return SkXfermodeImageFilter::Make(mode, std::move(background), std::move(foreground), &r);
}
// Morphology filter effects
sk_sp<SkImageFilter> SkImageFilters::Dilate(

View File

@ -215,7 +215,7 @@ public:
this->addFilter("paint and blur", SkImageFilters::Blur(
kBlurSigma, kBlurSigma, std::move(paintFilter), cropRect));
}
this->addFilter("xfermode", SkImageFilters::Xfermode(
this->addFilter("blend", SkImageFilters::Blend(
SkBlendMode::kSrc, input, input, cropRect));
}
int count() const { return fFilters.count(); }
@ -981,15 +981,15 @@ DEF_TEST(ImageFilterUnionBounds, reporter) {
// Regardless of which order they appear in, the image filter bounds should
// be combined correctly.
{
sk_sp<SkImageFilter> composite(SkImageFilters::Xfermode(SkBlendMode::kSrcOver, offset));
sk_sp<SkImageFilter> composite(SkImageFilters::Blend(SkBlendMode::kSrcOver, offset));
SkRect bounds = SkRect::MakeIWH(100, 100);
// Intentionally aliasing here, as that's what the real callers do.
bounds = composite->computeFastBounds(bounds);
REPORTER_ASSERT(reporter, bounds == SkRect::MakeIWH(150, 100));
}
{
sk_sp<SkImageFilter> composite(SkImageFilters::Xfermode(SkBlendMode::kSrcOver, nullptr,
offset, nullptr));
sk_sp<SkImageFilter> composite(SkImageFilters::Blend(SkBlendMode::kSrcOver, nullptr,
offset, nullptr));
SkRect bounds = SkRect::MakeIWH(100, 100);
// Intentionally aliasing here, as that's what the real callers do.
bounds = composite->computeFastBounds(bounds);
@ -1372,14 +1372,14 @@ static void test_xfermode_cropped_input(SkSurface* surf, skiatest::Reporter* rep
SkIRect cropRect = SkIRect::MakeEmpty();
sk_sp<SkImageFilter> croppedOut(SkImageFilters::ColorFilter(green, nullptr, &cropRect));
// Check that an xfermode image filter whose input has been cropped out still draws the other
// Check that an blend image filter whose input has been cropped out still draws the other
// input. Also check that drawing with both inputs cropped out doesn't cause a GPU warning.
SkBlendMode mode = SkBlendMode::kSrcOver;
sk_sp<SkImageFilter> xfermodeNoFg(SkImageFilters::Xfermode(
sk_sp<SkImageFilter> xfermodeNoFg(SkImageFilters::Blend(
mode, greenFilter, croppedOut, nullptr));
sk_sp<SkImageFilter> xfermodeNoBg(SkImageFilters::Xfermode(
sk_sp<SkImageFilter> xfermodeNoBg(SkImageFilters::Blend(
mode, croppedOut, greenFilter, nullptr));
sk_sp<SkImageFilter> xfermodeNoFgNoBg(SkImageFilters::Xfermode(
sk_sp<SkImageFilter> xfermodeNoFgNoBg(SkImageFilters::Blend(
mode, croppedOut, croppedOut, nullptr));
SkPaint paint;
@ -1728,7 +1728,7 @@ static void test_make_with_filter(skiatest::Reporter* reporter, GrRecordingConte
clipBounds.setXYWH(0, 0, 170, 100);
subset.setXYWH(0, 0, 160, 90);
filter = SkImageFilters::Xfermode(SkBlendMode::kSrc, nullptr);
filter = SkImageFilters::Blend(SkBlendMode::kSrc, nullptr);
result = sourceImage->makeWithFilter(rContext, filter.get(), subset, clipBounds,
&outSubset, &offset);
REPORTER_ASSERT(reporter, result);
@ -1831,8 +1831,8 @@ DEF_TEST(XfermodeImageFilterBounds, reporter) {
// The value of this variable doesn't matter because we use inputs with fixed bounds.
SkIRect src = SkIRect::MakeXYWH(11, 22, 33, 44);
for (int i = 0; i < kModeCount; ++i) {
sk_sp<SkImageFilter> xfermode(SkImageFilters::Xfermode(static_cast<SkBlendMode>(i),
background, foreground, nullptr));
sk_sp<SkImageFilter> xfermode(SkImageFilters::Blend(static_cast<SkBlendMode>(i),
background, foreground, nullptr));
auto bounds = xfermode->filterBounds(src, SkMatrix::I(),
SkImageFilter::kForward_MapDirection, nullptr);
REPORTER_ASSERT(reporter, bounds == expectedBounds[i]);
@ -1841,7 +1841,7 @@ DEF_TEST(XfermodeImageFilterBounds, reporter) {
// Test empty intersection.
sk_sp<SkImageFilter> background2(new FixedBoundsImageFilter(SkIRect::MakeXYWH(0, 0, 20, 20)));
sk_sp<SkImageFilter> foreground2(new FixedBoundsImageFilter(SkIRect::MakeXYWH(40, 40, 50, 50)));
sk_sp<SkImageFilter> xfermode(SkImageFilters::Xfermode(
sk_sp<SkImageFilter> xfermode(SkImageFilters::Blend(
SkBlendMode::kSrcIn, std::move(background2), std::move(foreground2), nullptr));
auto bounds = xfermode->filterBounds(src, SkMatrix::I(),
SkImageFilter::kForward_MapDirection, nullptr);

View File

@ -276,9 +276,9 @@ static void TestBitmapSerialization(const SkBitmap& validBitmap,
sk_sp<SkImage> invalidImage(SkImage::MakeFromBitmap(invalidBitmap));
sk_sp<SkImageFilter> invalidBitmapSource(SkImageFilters::Image(std::move(invalidImage)));
sk_sp<SkImageFilter> xfermodeImageFilter(
SkImageFilters::Xfermode(SkBlendMode::kSrcOver,
std::move(invalidBitmapSource),
std::move(validBitmapSource), nullptr));
SkImageFilters::Blend(SkBlendMode::kSrcOver,
std::move(invalidBitmapSource),
std::move(validBitmapSource), nullptr));
sk_sp<SkImageFilter> deserializedFilter(
TestFlattenableSerialization<SkImageFilter>(