Commit ceacea9f authored by Mason Freed's avatar Mason Freed Committed by Commit Bot

Fix backdrop_filter_bounds location for clipped layers

Previous to this CL, the location of the backdrop filter bounds
rect was incorrect when the containing layer was clipped by the
viewport. In that case, the offset added to the backdrop filter
bounds transform did not account for the clip. It now does, which
should fix at least four bugs.

Bug: 618913, 927097, 932160, 940917
Change-Id: I0dc1e4c3dde61210d8f7aa78b2e20f13fc8a2471
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1602812
Commit-Queue: Mason Freed <masonfreed@chromium.org>
Reviewed-by: default avatarenne <enne@chromium.org>
Cr-Commit-Position: refs/heads/master@{#658920}
parent 74319f6e
......@@ -774,9 +774,8 @@ gfx::Rect GLRenderer::GetBackdropBoundingBoxForRenderPassQuad(
}
// |backdrop_filter_bounds| is a rounded rect in [-0.5,0.5] space that
// represents |params->backdrop_filter_bounds| as a fraction of the space
// defined by |quad->rect|, not including its offset.
if (!GetScaledRRectF(gfx::Rect(quad->rect.size()),
params->backdrop_filter_bounds,
// defined by |quad->rect|.
if (!GetScaledRRectF(quad->rect, params->backdrop_filter_bounds,
backdrop_filter_bounds)) {
*backdrop_filter_bounds = gfx::RRectF(SharedGeometryQuad().BoundingBox());
}
......@@ -828,9 +827,12 @@ gfx::Rect GLRenderer::GetBackdropBoundingBoxForRenderPassQuad(
// and it is included in |contents_device_transform| (through
// |projection_matrix|). Don't double-flip.
*backdrop_filter_bounds_transform = params->contents_device_transform;
float old_y = backdrop_filter_bounds_transform->To2dTranslation().y();
float new_y = 2 * backdrop_filter_bounds_transform->To2dTranslation().y() +
backdrop_rect.bottom() - unclipped_rect->bottom() +
backdrop_rect.y() - unclipped_rect->y();
backdrop_filter_bounds_transform->PostScale(1, -1);
backdrop_filter_bounds_transform->PostTranslate(0, 2 * old_y);
backdrop_filter_bounds_transform->PostTranslate(0, new_y);
// Shift to the space of the captured backdrop image.
backdrop_filter_bounds_transform->PostTranslate(-backdrop_rect.x(),
-backdrop_rect.y());
......
......@@ -2804,7 +2804,7 @@ TYPED_TEST(RendererPixelTest, RenderPassAndMaskForRoundedCornerMultiRadii) {
}
template <typename RendererType>
class RendererPixelTestWithBackgroundFilter
class RendererPixelTestWithBackdropFilter
: public RendererPixelTest<RendererType> {
protected:
void SetUpRenderPassList() {
......@@ -2911,23 +2911,18 @@ class RendererPixelTestWithBackgroundFilter
gfx::Rect filter_pass_layer_rect_;
};
// The software renderer does not support background filters yet.
using BackgroundFilterRendererTypes =
::testing::Types<GLRenderer, SkiaRenderer>;
// TODO(916318): The software renderer does not support background filters yet.
using BackdropFilterRendererTypes = ::testing::Types<GLRenderer, SkiaRenderer>;
TYPED_TEST_SUITE(RendererPixelTestWithBackgroundFilter,
BackgroundFilterRendererTypes);
TYPED_TEST_SUITE(RendererPixelTestWithBackdropFilter,
BackdropFilterRendererTypes);
TYPED_TEST(RendererPixelTestWithBackgroundFilter, InvertFilter) {
TYPED_TEST(RendererPixelTestWithBackdropFilter, InvertFilter) {
this->backdrop_filters_.Append(cc::FilterOperation::CreateInvertFilter(1.f));
this->filter_pass_layer_rect_ = gfx::Rect(this->device_viewport_size_);
this->filter_pass_layer_rect_.Inset(12, 14, 16, 18);
// The backdrop_filter_bounds will apply within the layer's coordinate space,
// so the clipping bounds should be 0,0 WxH, not
// this->filter_pass_layer_rect_.
this->backdrop_filter_bounds_ =
gfx::RRectF(0, 0, this->filter_pass_layer_rect_.width(),
this->filter_pass_layer_rect_.height(), 0);
gfx::RRectF(gfx::RectF(this->filter_pass_layer_rect_));
this->SetUpRenderPassList();
EXPECT_TRUE(this->RunPixelTest(
&this->pass_list_,
......
......@@ -1643,10 +1643,9 @@ SkiaRenderer::DrawRPDQParams SkiaRenderer::CalculateRPDQParams(
// Scale by the filter's scale, but don't apply filter origin
rpdq_params.backdrop_filter_bounds->Scale(quad->filters_scale.x(),
quad->filters_scale.y());
// Offset by the difference in origins between the quad->rect and the
// render pass' output rect.
// Offset by the render pass' output rect.
rpdq_params.backdrop_filter_bounds->Offset(
quad->rect.origin() -
gfx::Point() -
current_frame()->current_render_pass->output_rect.origin());
// If there are also regular image filters, they apply to the area of
......
......@@ -2471,7 +2471,6 @@ FloatRect PaintLayer::BackdropFilterReferenceBox() const {
float zoom = GetLayoutObject().StyleRef().EffectiveZoom();
if (zoom != 1)
reference_box.Scale(1 / zoom);
reference_box.Move(-ToFloatSize(FilterReferenceBox().Location()));
return reference_box;
}
......
......@@ -644,8 +644,7 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
PaintLayerResourceInfo& EnsureResourceInfo();
// Filter reference box is the area over which the filter is computed, in the
// coordinate system of the object with the filter. Filter bounds is the
// reference box, offset by the object's location in the graphics layer.
// local coordinate system of the effect node containing the filter.
FloatRect FilterReferenceBox() const;
FloatRect BackdropFilterReferenceBox() const;
gfx::RRectF BackdropFilterBounds(const FloatRect& reference_box) const;
......
......@@ -406,6 +406,8 @@ crbug.com/909749 fast/events/touch/touch-rect-crash-on-unpromote-layer.html [ Fa
crbug.com/923429 css3/filters/backdrop-filter-basic-blur.html [ Failure ]
crbug.com/923429 css3/filters/backdrop-filter-browser-zoom.html [ Failure ]
crbug.com/923429 css3/filters/backdrop-filter-border-radius.html [ Failure ]
crbug.com/923429 css3/filters/backdrop-filter-clip-rect-zoom.html [ Failure ]
crbug.com/923429 css3/filters/backdrop-filter-plus-filter.html [ Failure ]
crbug.com/923429 css3/filters/backdrop-filter-rendering.html [ Failure ]
crbug.com/923429 css3/filters/backdrop-filter-rendering-no-background.html [ Failure ]
crbug.com/923429 css3/filters/backdrop-filter-transform.html [ Failure ]
......@@ -414,6 +416,9 @@ crbug.com/923429 external/wpt/css/filter-effects/backdrop-filter-basic-opacity-2
crbug.com/923429 external/wpt/css/filter-effects/backdrop-filter-basic.html [ Failure ]
crbug.com/923429 external/wpt/css/filter-effects/backdrop-filter-fixed-clip.html [ Failure ]
crbug.com/923429 external/wpt/css/filter-effects/backdrop-filter-isolation.html [ Failure ]
crbug.com/923429 external/wpt/css/filter-effects/backdrop-filter-isolation-fixed.html [ Failure ]
crbug.com/923429 external/wpt/css/filter-effects/backdrop-filter-isolation-isolate.html [ Failure ]
crbug.com/940033 virtual/fractional_scrolling_threaded/fast/scrolling/wheel-scrolling-over-custom-scrollbar.html [ Failure ]
crbug.com/940033 virtual/threaded/fast/scrolling/wheel-scrolling-over-custom-scrollbar.html [ Failure ]
......
......@@ -1617,16 +1617,7 @@ crbug.com/538697 [ Win ] printing/webgl-oversized-printing.html [ Failure Crash
crbug.com/497522 css3/filters/backdrop-filter-boundary.html [ Failure ]
crbug.com/497522 css3/filters/backdrop-filter-bleeding.html [ Failure ]
crbug.com/497522 css3/filters/backdrop-filter-svg.html [ Failure ]
crbug.com/497522 external/wpt/css/filter-effects/backdrop-filter-clip-rect-zoom.html [ Failure ]
#crbug.com/497522 css3/filters/backdrop-filter-plus-filter.html [ Failure ]
# This fails, but only in CAP mode:
crbug.com/497522 external/wpt/css/filter-effects/backdrop-filter-isolation-isolate.html [ Failure ]
crbug.com/497522 external/wpt/css/filter-effects/backdrop-filter-paint-order.html [ Failure ]
crbug.com/497522 external/wpt/css/filter-effects/backdrop-filter-isolation-fixed.html [ Failure ]
crbug.com/497522 external/wpt/css/filter-effects/backdrop-filter-edge-pixels.html [ Pass Failure ]
# Flaky (timeout) tests:
crbug.com/912748 external/wpt/css/filter-effects/backdrop-filter-plus-filter.html [ Skip ]
crbug.com/913114 css3/filters/backdrop-filter-plus-filter.html [ Skip ]
# ====== Backdrop-filter related tests END ======
......
......@@ -6,12 +6,14 @@
<link rel="help" href="https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty">
<link rel="match" href="backdrop-filter-clip-rect-zoom-ref.html">
<div>
<p>Expected: A green box, color-inverted inside the short, wide box with a<br>
blue border and rounded corners, and not color-inverted anywhere else. In<br>
particular, there should be no color inversion inside the tall, narrow box,<br>
or anywhere outside that.</p>
</div>
<!-- See [1] for an implementation of this test in WPT format. It requires the
WPT Fuzzy Matching [2] feature to be implemented, due to AA on the border
radii.
[1] https://cs.chromium.org/chromium/src/third_party/blink/web_tests/external/wpt/css/filter-effects/backdrop-filter-clip-rect-zoom-ref.html?rcl=04f3fcde0d60b908e7c452b4956b693144cdfdd5&l=1
[2] https://github.com/web-platform-tests/wpt/blob/1f570a686843ca10f151a79956ee16110f4a4d42/docs/_writing-tests/reftests.md#fuzzy-matching
-->
<div class="box"></div>
<div class="navbar">
<div class="menu"></div>
......
<!DOCTYPE html>
<div class="container">
<div class="orangebox"></div>
<div class="bluebox blur-bd" style="background:transparent;"></div>
<div class="bluebox blur"></div>
</div>
<style>
div {
width: 100px;
height: 100px;
position :absolute;
}
.container {
width:200px;
height:200px;
position:absolute;
}
.blur {
-webkit-filter: blur(3px);
filter: blur(3px);
}
.blur-bd {
backdrop-filter: blur(15px);
}
.orangebox {
left: 10px;
top: 50px;
background: orange;
}
.bluebox {
left: 60px;
top: 110px;
background: #0000ff33;
}
</style>
<!DOCTYPE html>
<html style="zoom:5">
<meta charset="utf-8">
<title>backdrop-filter: Clip the filter at border box of element</title>
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<div>
<p>Expected: A green box, color-inverted inside the short, wide box with a<br>
blue border and rounded corners, and not color-inverted anywhere else. In<br>
particular, there should be no color inversion inside the tall, narrow box,<br>
or anywhere outside that.</p>
</div>
<div class="box"></div>
<div class="navbar"></div>
<div class="menu"></div>
<div class="menu2"></div>
<style>
div {
position: absolute;
}
.box {
width: 200px;
height: 200px;
top: 100px;
left: 100px;
background: green;
}
.navbar {
width: 300px;
height: 50px;
top: 150px;
left: 50px;
border: 2px solid blue;
backdrop-filter: invert(1);
border-radius: 10px 20px 30px 40px;
}
.menu {
width: 100px;
height: 150px;
top: 202px;
left: 147px;
border: 2px solid red;
}
.menu2 {
width: 100px;
height: 30px;
top: 118px;
left: 147px;
border: 2px solid red;
}
</style>
<script>
window.scrollTo(0,700);
</script>
<!DOCTYPE html>
<meta charset="utf-8">
<title>backdrop-filter: Should not filter outside parent stacking context.</title>
<title>backdrop-filter: fixed position should not cause a backdrop root.</title>
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel="help" href="https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty">
<link rel="match" href="backdrop-filter-isolation-ref.html">
<link rel="match" href="backdrop-filter-non-isolation-ref.html">
<div>
<p>Expected: Two green boxes overlapped by a yellow box. The overlapped region<br>
of the right-hand box ONLY should be inverted (pink).</p>
of BOTH green boxes should be inverted (pink).</p>
</div>
<div class="box outside">
<div class="box stacking-context">
......
<!DOCTYPE html>
<meta charset="utf-8">
<title>backdrop-filter: Should not filter outside parent stacking context.</title>
<title>backdrop-filter: isolation isolate should not cause a backdrop root.</title>
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel="help" href="https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty">
<link rel="match" href="backdrop-filter-isolation-ref.html">
<link rel="match" href="backdrop-filter-non-isolation-ref.html">
<div>
<p>Expected: Two green boxes overlapped by a yellow box. The overlapped region<br>
of the right-hand box ONLY should be inverted (pink).</p>
of BOTH green boxes should be inverted (pink).</p>
</div>
<div class="box outside">
<div class="box stacking-context">
......
<!DOCTYPE html>
<meta charset="utf-8">
<title>backdrop-filter: Isolation</title>
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<div>
<p>Expected: Two green boxes overlapped by a yellow box. The overlapped region<br>
of BOTH green boxes should be inverted (pink).</p>
</div>
<div class="box green"></div>
<div class="box green" style="left: 130px;"></div>
<div class="box yellow" style="width:160px;height:160px;top:140px;left:40px;"></div>
<div class="box orange" style="width:70px;height:70px;top:140px;left:40px;"></div>
<div class="box orange" style="width:70px;height:70px;top:140px;left:130px;"></div>
<style>
.box {
position: absolute;
width: 100px;
height: 100px;
top:110px;
left:10px;
}
.green { background: green; }
.yellow { background: #880; }
.orange { background: #ffc377; }
</style>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment