Commit 3a24b862 authored by tsunghung's avatar tsunghung Committed by Commit bot

Reset the state of the previous frame if hardware overlay processing is skipped.

If hardware overlay processing is skipped for a frame, there's no
way to be sure of the state of the previous frame. Reset
|previous_frame_underlay_rect_| for the next frame.

BUG=Internal b/37644269
CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel

Review-Url: https://codereview.chromium.org/2844483004
Cr-Commit-Position: refs/heads/master@{#467754}
parent 5928f440
...@@ -128,14 +128,16 @@ void OverlayProcessor::ProcessForOverlays( ...@@ -128,14 +128,16 @@ void OverlayProcessor::ProcessForOverlays(
SendPromotionHintsBeforeReturning notifier(resource_provider, candidates); SendPromotionHintsBeforeReturning notifier(resource_provider, candidates);
#endif #endif
// Reset |previous_frame_underlay_rect_| in case UpdateDamageRect() not being
// invoked.
const gfx::Rect previous_frame_underlay_rect = previous_frame_underlay_rect_;
previous_frame_underlay_rect_ = gfx::Rect();
// If we have any copy requests, we can't remove any quads for overlays or // If we have any copy requests, we can't remove any quads for overlays or
// CALayers because the framebuffer would be missing the removed quads' // CALayers because the framebuffer would be missing the removed quads'
// contents. // contents.
if (!render_pass->copy_requests.empty()) { if (!render_pass->copy_requests.empty()) {
dc_processor_.ClearOverlayState(); dc_processor_.ClearOverlayState();
// If overlay processing was skipped for a frame there's no way to be sure
// of the state of the previous frame, so reset.
previous_frame_underlay_rect_ = gfx::Rect();
return; return;
} }
...@@ -158,7 +160,7 @@ void OverlayProcessor::ProcessForOverlays( ...@@ -158,7 +160,7 @@ void OverlayProcessor::ProcessForOverlays(
content_bounds)) content_bounds))
continue; continue;
UpdateDamageRect(candidates, damage_rect); UpdateDamageRect(candidates, previous_frame_underlay_rect, damage_rect);
return; return;
} }
} }
...@@ -171,8 +173,10 @@ void OverlayProcessor::ProcessForOverlays( ...@@ -171,8 +173,10 @@ void OverlayProcessor::ProcessForOverlays(
// not to swap the framebuffer there will still be a transparent hole in the // not to swap the framebuffer there will still be a transparent hole in the
// previous frame. This only handles the common case of a single underlay quad // previous frame. This only handles the common case of a single underlay quad
// for fullscreen video. // for fullscreen video.
void OverlayProcessor::UpdateDamageRect(OverlayCandidateList* candidates, void OverlayProcessor::UpdateDamageRect(
gfx::Rect* damage_rect) { OverlayCandidateList* candidates,
const gfx::Rect& previous_frame_underlay_rect,
gfx::Rect* damage_rect) {
gfx::Rect output_surface_overlay_damage_rect; gfx::Rect output_surface_overlay_damage_rect;
gfx::Rect this_frame_underlay_rect; gfx::Rect this_frame_underlay_rect;
for (const OverlayCandidate& overlay : *candidates) { for (const OverlayCandidate& overlay : *candidates) {
...@@ -189,7 +193,7 @@ void OverlayProcessor::UpdateDamageRect(OverlayCandidateList* candidates, ...@@ -189,7 +193,7 @@ void OverlayProcessor::UpdateDamageRect(OverlayCandidateList* candidates,
} }
} }
if (this_frame_underlay_rect == previous_frame_underlay_rect_) if (this_frame_underlay_rect == previous_frame_underlay_rect)
damage_rect->Subtract(this_frame_underlay_rect); damage_rect->Subtract(this_frame_underlay_rect);
previous_frame_underlay_rect_ = this_frame_underlay_rect; previous_frame_underlay_rect_ = this_frame_underlay_rect;
......
...@@ -83,6 +83,7 @@ class CC_EXPORT OverlayProcessor { ...@@ -83,6 +83,7 @@ class CC_EXPORT OverlayProcessor {
gfx::Rect* damage_rect); gfx::Rect* damage_rect);
// Update |damage_rect| by removing damage casued by |candidates|. // Update |damage_rect| by removing damage casued by |candidates|.
void UpdateDamageRect(OverlayCandidateList* candidates, void UpdateDamageRect(OverlayCandidateList* candidates,
const gfx::Rect& previous_frame_underlay_rect,
gfx::Rect* damage_rect); gfx::Rect* damage_rect);
DCLayerOverlayProcessor dc_processor_; DCLayerOverlayProcessor dc_processor_;
......
...@@ -1400,6 +1400,38 @@ TEST_F(UnderlayTest, DamageNotSubtractedForNonIdenticalConsecutiveUnderlays) { ...@@ -1400,6 +1400,38 @@ TEST_F(UnderlayTest, DamageNotSubtractedForNonIdenticalConsecutiveUnderlays) {
} }
} }
// Underlay damage can only be subtracted if the previous frame's underlay
// exists.
TEST_F(UnderlayTest, DamageNotSubtractedForNonConsecutiveIdenticalUnderlays) {
bool has_fullscreen_candidate[] = {true, false, true};
for (int i = 0; i < 3; ++i) {
std::unique_ptr<RenderPass> pass = CreateRenderPass();
if (has_fullscreen_candidate[i]) {
CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(),
pass.get());
}
damage_rect_ = kOverlayRect;
// Add something behind it.
CreateFullscreenOpaqueQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass.get());
OverlayCandidateList candidate_list;
base::flat_map<int, FilterOperations*> render_pass_filters;
base::flat_map<int, FilterOperations*> render_pass_background_filters;
overlay_processor_->ProcessForOverlays(
resource_provider_.get(), pass.get(), render_pass_filters,
render_pass_background_filters, &candidate_list, nullptr, nullptr,
&damage_rect_, &content_bounds_);
}
EXPECT_EQ(kOverlayRect, damage_rect_);
}
TEST_F(UnderlayTest, DamageNotSubtractedWhenQuadsAboveOverlap) { TEST_F(UnderlayTest, DamageNotSubtractedWhenQuadsAboveOverlap) {
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
std::unique_ptr<RenderPass> pass = CreateRenderPass(); std::unique_ptr<RenderPass> pass = CreateRenderPass();
......
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