Fix two GPU image filters handling of subset inputs
Added a GM that demonstrates the bug. Should draw a blur with the center masked out, and a circular blurry shape that's roughly the inverse. On raster, this was already the result. On GPU, the blurred/eroded layer becomes a subset with an origin other than (0,0), and that layer was shifted. I *think* this is the correct fix - we are including 'offset' in the texture matrices, but that's just based on the crop rects and adjustments from each filter. We still need to adjust the texture coords for the subsets themselves. Bug: chromium:905548 Change-Id: I19c936adad90311aef243a9395a270d2e015df2f Reviewed-on: https://skia-review.googlesource.com/c/173321 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
7e000220c3
commit
c32aeb326e
38
gm/crbug_905548.cpp
Normal file
38
gm/crbug_905548.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gm.h"
|
||||
|
||||
#include "SkArithmeticImageFilter.h"
|
||||
#include "SkBlurImageFilter.h"
|
||||
#include "SkImageSource.h"
|
||||
#include "SkMorphologyImageFilter.h"
|
||||
#include "SkSurface.h"
|
||||
#include "SkXfermodeImageFilter.h"
|
||||
|
||||
DEF_SIMPLE_GM(crbug_905548, canvas, 100, 200) {
|
||||
auto surface = canvas->makeSurface(SkImageInfo::MakeN32Premul(100, 100));
|
||||
if (!surface) {
|
||||
surface = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(100, 100));
|
||||
}
|
||||
surface->getCanvas()->clear(0);
|
||||
surface->getCanvas()->drawCircle(50, 50, 45, SkPaint());
|
||||
auto imageSource = SkImageSource::Make(surface->makeImageSnapshot());
|
||||
|
||||
auto blurred = SkBlurImageFilter::Make(15, 15, imageSource);
|
||||
auto eroded = SkErodeImageFilter::Make(0, 0, blurred);
|
||||
auto blended = SkXfermodeImageFilter::Make(SkBlendMode::kDstOut, eroded, imageSource, nullptr);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setImageFilter(blended);
|
||||
canvas->drawRect(SkRect::MakeWH(100, 100), paint);
|
||||
|
||||
auto mult = SkArithmeticImageFilter::Make(1, 0, 0, 0, false, eroded, imageSource, nullptr);
|
||||
paint.setImageFilter(mult);
|
||||
canvas->translate(0, 100);
|
||||
canvas->drawRect(SkRect::MakeWH(100, 100), paint);
|
||||
}
|
@ -102,6 +102,7 @@ gm_sources = [
|
||||
"$_gm/crbug_887103.cpp",
|
||||
"$_gm/crbug_892988.cpp",
|
||||
"$_gm/crbug_899512.cpp",
|
||||
"$_gm/crbug_905548.cpp",
|
||||
"$_gm/croppedrects.cpp",
|
||||
"$_gm/crosscontextimage.cpp",
|
||||
"$_gm/cubicpaths.cpp",
|
||||
|
@ -308,11 +308,13 @@ sk_sp<SkSpecialImage> ArithmeticImageFilterImpl::filterImageGPU(
|
||||
std::unique_ptr<GrFragmentProcessor> bgFP;
|
||||
|
||||
if (backgroundProxy) {
|
||||
SkMatrix backgroundMatrix = SkMatrix::MakeTrans(-SkIntToScalar(backgroundOffset.fX),
|
||||
-SkIntToScalar(backgroundOffset.fY));
|
||||
SkIRect bgSubset = background->subset();
|
||||
SkMatrix backgroundMatrix = SkMatrix::MakeTrans(
|
||||
SkIntToScalar(bgSubset.left() - backgroundOffset.fX),
|
||||
SkIntToScalar(bgSubset.top() - backgroundOffset.fY));
|
||||
bgFP = GrTextureDomainEffect::Make(
|
||||
std::move(backgroundProxy), backgroundMatrix,
|
||||
GrTextureDomain::MakeTexelDomain(background->subset()),
|
||||
GrTextureDomain::MakeTexelDomain(bgSubset),
|
||||
GrTextureDomain::kDecal_Mode, GrSamplerState::Filter::kNearest);
|
||||
bgFP = GrColorSpaceXformEffect::Make(std::move(bgFP), background->getColorSpace(),
|
||||
background->alphaType(),
|
||||
@ -323,11 +325,13 @@ sk_sp<SkSpecialImage> ArithmeticImageFilterImpl::filterImageGPU(
|
||||
}
|
||||
|
||||
if (foregroundProxy) {
|
||||
SkMatrix foregroundMatrix = SkMatrix::MakeTrans(-SkIntToScalar(foregroundOffset.fX),
|
||||
-SkIntToScalar(foregroundOffset.fY));
|
||||
SkIRect fgSubset = foreground->subset();
|
||||
SkMatrix foregroundMatrix = SkMatrix::MakeTrans(
|
||||
SkIntToScalar(fgSubset.left() - foregroundOffset.fX),
|
||||
SkIntToScalar(fgSubset.top() - foregroundOffset.fY));
|
||||
auto foregroundFP = GrTextureDomainEffect::Make(
|
||||
std::move(foregroundProxy), foregroundMatrix,
|
||||
GrTextureDomain::MakeTexelDomain(foreground->subset()),
|
||||
GrTextureDomain::MakeTexelDomain(fgSubset),
|
||||
GrTextureDomain::kDecal_Mode, GrSamplerState::Filter::kNearest);
|
||||
foregroundFP = GrColorSpaceXformEffect::Make(std::move(foregroundFP),
|
||||
foreground->getColorSpace(),
|
||||
|
@ -276,10 +276,12 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::filterImageGPU(
|
||||
std::unique_ptr<GrFragmentProcessor> bgFP;
|
||||
|
||||
if (backgroundProxy) {
|
||||
SkMatrix bgMatrix = SkMatrix::MakeTrans(-SkIntToScalar(backgroundOffset.fX),
|
||||
-SkIntToScalar(backgroundOffset.fY));
|
||||
SkIRect bgSubset = background->subset();
|
||||
SkMatrix bgMatrix = SkMatrix::MakeTrans(
|
||||
SkIntToScalar(bgSubset.left() - backgroundOffset.fX),
|
||||
SkIntToScalar(bgSubset.top() - backgroundOffset.fY));
|
||||
bgFP = GrTextureDomainEffect::Make(std::move(backgroundProxy), bgMatrix,
|
||||
GrTextureDomain::MakeTexelDomain(background->subset()),
|
||||
GrTextureDomain::MakeTexelDomain(bgSubset),
|
||||
GrTextureDomain::kDecal_Mode,
|
||||
GrSamplerState::Filter::kNearest);
|
||||
bgFP = GrColorSpaceXformEffect::Make(std::move(bgFP), background->getColorSpace(),
|
||||
@ -291,11 +293,13 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::filterImageGPU(
|
||||
}
|
||||
|
||||
if (foregroundProxy) {
|
||||
SkMatrix fgMatrix = SkMatrix::MakeTrans(-SkIntToScalar(foregroundOffset.fX),
|
||||
-SkIntToScalar(foregroundOffset.fY));
|
||||
SkIRect fgSubset = foreground->subset();
|
||||
SkMatrix fgMatrix = SkMatrix::MakeTrans(
|
||||
SkIntToScalar(fgSubset.left() - foregroundOffset.fX),
|
||||
SkIntToScalar(fgSubset.top() - foregroundOffset.fY));
|
||||
auto foregroundFP = GrTextureDomainEffect::Make(
|
||||
std::move(foregroundProxy), fgMatrix,
|
||||
GrTextureDomain::MakeTexelDomain(foreground->subset()),
|
||||
GrTextureDomain::MakeTexelDomain(fgSubset),
|
||||
GrTextureDomain::kDecal_Mode, GrSamplerState::Filter::kNearest);
|
||||
foregroundFP = GrColorSpaceXformEffect::Make(std::move(foregroundFP),
|
||||
foreground->getColorSpace(),
|
||||
|
Loading…
Reference in New Issue
Block a user