Reland "skif:LayerSpace<SkRect>::roundOut/In have epsilon tolerance."
This is a reland of commit acb8770918
Original change's description:
> skif:LayerSpace<SkRect>::roundOut/In have epsilon tolerance.
>
> Adds a little tolerance so that e.g. left=30.999994 with roundOut
> will still round to 31 not 30. Helps avoid cases where imprecision
> leads to including an entire unwanted row/column of an input image
> to an image filter.
>
> This Chrome change must land first:
> https://chromium-review.googlesource.com/c/chromium/src/+/3577185/
>
> Bug: chromium:1313579
> Change-Id: I143c8f99b90413a6b610f2b3a5e54e648777ca68
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/528652
> Reviewed-by: Michael Ludwig <michaelludwig@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>
Bug: chromium:1313579
Change-Id: Ia827c6fc01542fa3d56f560cde517570b8f0021d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/529744
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
28c9c8b9f5
commit
de301c8d70
@ -9673,3 +9673,16 @@ generated_cc_atom(
|
||||
"//tools:ToolUtils_hdr",
|
||||
],
|
||||
)
|
||||
|
||||
generated_cc_atom(
|
||||
name = "crbug_1313579_src",
|
||||
srcs = ["crbug_1313579.cpp"],
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
":gm_hdr",
|
||||
"//include/core:SkCanvas_hdr",
|
||||
"//include/core:SkMatrix_hdr",
|
||||
"//include/core:SkRect_hdr",
|
||||
"//include/effects:SkImageFilters_hdr",
|
||||
],
|
||||
)
|
||||
|
41
gm/crbug_1313579.cpp
Normal file
41
gm/crbug_1313579.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gm/gm.h"
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkMatrix.h"
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/effects/SkImageFilters.h"
|
||||
|
||||
// SkiaRenderer can wind up specifying near-integer scale-and-translate matrices on SkCanvas before
|
||||
// applying a backdrop blur image filter via saveLayer() with an integer clip, crop rect, and
|
||||
// SaveLayerRec bounds. Round-out is used to determine the bounds of the input image needed in IFs.
|
||||
// This could cause an extra row/column of pixels to be included in the blur. When that row/column
|
||||
// is significantly different in color than the intended blur content and the radius is large then
|
||||
// clamp mode blur creates a very noticeable color bleed artifact.
|
||||
DEF_SIMPLE_GM(crbug_1313579, canvas, 110, 110) {
|
||||
static constexpr auto kBGRect = SkIRect{0, 0, 100, 100};
|
||||
|
||||
sk_sp<SkImageFilter> backdrop_filter =
|
||||
SkImageFilters::Blur(50.f, 50.f, SkTileMode::kClamp, nullptr);
|
||||
sk_sp<SkImageFilter> crop = SkImageFilters::Offset(0, 0, nullptr, &kBGRect);
|
||||
backdrop_filter = SkImageFilters::Compose(
|
||||
crop, SkImageFilters::Compose(std::move(backdrop_filter), crop));
|
||||
|
||||
SkMatrix m;
|
||||
|
||||
canvas->clear(SK_ColorGREEN);
|
||||
|
||||
m.setAll(0.999999f, 0, 4.99999f,
|
||||
0, 0.999999f, 4.99999f,
|
||||
0, 0, 1);
|
||||
canvas->concat(m);
|
||||
canvas->clipIRect(kBGRect);
|
||||
canvas->clear(SK_ColorWHITE);
|
||||
canvas->saveLayer(SkCanvas::SaveLayerRec(nullptr, nullptr, backdrop_filter.get(), 0));
|
||||
canvas->restore();
|
||||
}
|
@ -119,6 +119,7 @@ gm_sources = [
|
||||
"$_gm/crbug_1174354.cpp",
|
||||
"$_gm/crbug_1177833.cpp",
|
||||
"$_gm/crbug_1257515.cpp",
|
||||
"$_gm/crbug_1313579.cpp",
|
||||
"$_gm/crbug_224618.cpp",
|
||||
"$_gm/crbug_691386.cpp",
|
||||
"$_gm/crbug_788500.cpp",
|
||||
|
@ -402,8 +402,12 @@ public:
|
||||
}
|
||||
|
||||
LayerSpace<SkIRect> round() const { return LayerSpace<SkIRect>(fData.round()); }
|
||||
LayerSpace<SkIRect> roundIn() const { return LayerSpace<SkIRect>(fData.roundIn()); }
|
||||
LayerSpace<SkIRect> roundOut() const { return LayerSpace<SkIRect>(fData.roundOut()); }
|
||||
LayerSpace<SkIRect> roundIn() const {
|
||||
return LayerSpace<SkIRect>(fData.makeOutset(kRoundEpsilon, kRoundEpsilon).roundIn());
|
||||
}
|
||||
LayerSpace<SkIRect> roundOut() const {
|
||||
return LayerSpace<SkIRect>(fData.makeInset(kRoundEpsilon, kRoundEpsilon).roundOut());
|
||||
}
|
||||
|
||||
bool intersect(const LayerSpace<SkRect>& r) { return fData.intersect(r.fData); }
|
||||
void join(const LayerSpace<SkRect>& r) { fData.join(r.fData); }
|
||||
@ -411,6 +415,17 @@ public:
|
||||
void outset(const LayerSpace<SkSize>& delta) { fData.outset(delta.width(), delta.height()); }
|
||||
|
||||
private:
|
||||
// This exists to cover up issues where infinite precision would produce integers but float
|
||||
// math produces values just larger/smaller than an int and roundOut/In on bounds would produce
|
||||
// nearly a full pixel error. One such case is crbug.com/1313579 where the caller has produced
|
||||
// near integer CTM and uses integer crop rects that would grab an extra row/column of the
|
||||
// input image when using a strict roundOut.
|
||||
#if defined(SK_DISABLE_SKIF_TOLERANCE_ROUND)
|
||||
static constexpr float kRoundEpsilon = 0;
|
||||
#else
|
||||
static constexpr float kRoundEpsilon = 1e-3f;
|
||||
#endif
|
||||
|
||||
SkRect fData;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user