Commit f2185248 authored by Peter McNeeley's avatar Peter McNeeley Committed by Commit Bot

Damage entire candidate quad rect on underlay promotion

Certain overlay candidates forward damage rects that are smaller than
the quad itself. This works perfectly fine in the case of composition
as it simply corresponds to a partial update within a quad.

However, in the case of underlays, the primary plane must have the
overlay candidate rect be FULLY replaced by a black "window" quad.

Currently the code fails to do this on promotion and will make no
attempt to do this after promotion. This change damages the entire quad
rect so that the "window" quad is fully composed on the primary plane.

The reason why this bug remains unreported (till this time) is because
it only occurs for candidates that have damage as a subset of the quad
rect. Basically, only in the case of Lacros underlays.


Bug: 1130733
Change-Id: Ib4ecd77b105c5ad6e7b46d21e9edd5a8b802412f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2468678
Commit-Queue: Peter McNeeley <petermcneeley@chromium.org>
Reviewed-by: default avatarMaggie Chen <magchen@chromium.org>
Reviewed-by: default avatarRobert Kroeger <rjkroege@chromium.org>
Reviewed-by: default avatarKramer Ge <fangzhoug@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818046}
parent 4107e01f
......@@ -159,6 +159,15 @@ void OverlayProcessorUsingStrategy::UpdateDamageRect(
bool always_unoccluded =
overlay.is_unoccluded && previous_frame_underlay_was_unoccluded;
// We need to make sure that when we change the overlay we damage the
// region where the underlay will be positioned. This is because a
// black transparent hole is made for the underlay to show through
// but its possible that the damage for this quad is less than the
// complete size of the underlay. https://crbug.com/1130733
if (!same_underlay_rect) {
damage_rect->Union(this_frame_underlay_rect);
}
if (same_underlay_rect && !transition_from_occluded_to_unoccluded &&
(always_unoccluded || overlay.no_occluding_damage)) {
damage_rect->Subtract(this_frame_underlay_rect);
......
......@@ -2043,18 +2043,22 @@ TEST_F(UnderlayTest, UpdateDamageWhenChangingUnderlays) {
}
TEST_F(UnderlayTest, UpdateDamageRectWhenNoPromotion) {
// In the first pass there is an overlay promotion and the expected damage
// size should be unchanged.
// In the second pass there is no overlay promotion, but the damage should be
// the union of the damage_rect with CreateRenderPass's output_rect which is
// {0, 0, 256, 256}.
bool has_fullscreen_candidate[] = {true, false};
gfx::Rect damages[] = {gfx::Rect(0, 0, 32, 32), gfx::Rect(0, 0, 312, 16)};
gfx::Rect expected_damages[] = {gfx::Rect(0, 0, 32, 32),
// In the first pass there is an overlay promotion and the expected damage is
// a union of the hole made for the underlay and the incoming damage. In the
// second pass there is no occluding damage so the incoming damage is
// attributed to the overlay candidate and the final output damage is zero. In
// the third pass there is no overlay promotion, but the damage should be the
// union of the damage_rect with CreateRenderPass's output_rect which is {0,
// 0, 256, 256}. This is due to the demotion of the current overlay.
bool has_fullscreen_candidate[] = {true, true, false};
gfx::Rect damages[] = {gfx::Rect(0, 0, 32, 32), gfx::Rect(0, 0, 32, 32),
gfx::Rect(0, 0, 312, 16)};
gfx::Rect expected_damages[] = {gfx::Rect(0, 0, 256, 256),
gfx::Rect(0, 0, 0, 0),
gfx::Rect(0, 0, 312, 256)};
size_t expected_candidate_size[] = {1, 0};
size_t expected_candidate_size[] = {1, 1, 0};
for (int i = 0; i < 2; ++i) {
for (size_t i = 0; i < base::size(expected_damages); ++i) {
auto pass = CreateRenderPass();
if (has_fullscreen_candidate[i]) {
......
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