diff options
author | ccameron <ccameron@chromium.org> | 2015-08-07 12:26:02 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-07 19:26:38 +0000 |
commit | d9fa78192b5286e0ab0ccf651ff5a8fb869ef7f2 (patch) | |
tree | d34a2500f973e029f038a03979be4fc54d7530ea /cc/surfaces | |
parent | 884b72bafb2dda816a09bbdb7a3b7ada2668eee0 (diff) | |
download | chromium_src-d9fa78192b5286e0ab0ccf651ff5a8fb869ef7f2.zip chromium_src-d9fa78192b5286e0ab0ccf651ff5a8fb869ef7f2.tar.gz chromium_src-d9fa78192b5286e0ab0ccf651ff5a8fb869ef7f2.tar.bz2 |
Mac: Fix white hangs
When the output surface has been suspended, skip the draw and swap, but
still return true from Display::DrawAndSwap.
The ui::Compositor remains suspended until a commit happens to it.
Returning false from Display::DrawAndSwap appears to sometimes block new
commits from happening, resulting in content never being drawn. This will
elide the SwapBuffers and immediately make the DidSwapBuffers and
DidSwapBuffersComplete calls, which will unblock the compositor.
Add some tests, too.
BUG=509917
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1275763003
Cr-Commit-Position: refs/heads/master@{#342408}
Diffstat (limited to 'cc/surfaces')
-rw-r--r-- | cc/surfaces/display.cc | 11 | ||||
-rw-r--r-- | cc/surfaces/surface_display_output_surface_unittest.cc | 15 |
2 files changed, 23 insertions, 3 deletions
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc index af24a97..5b69964 100644 --- a/cc/surfaces/display.cc +++ b/cc/surfaces/display.cc @@ -167,9 +167,6 @@ bool Display::DrawAndSwap() { return false; } - if (output_surface_->SurfaceIsSuspendForRecycle()) - return false; - scoped_ptr<CompositorFrame> frame = aggregator_->Aggregate(current_surface_id_); if (!frame) { @@ -211,6 +208,14 @@ bool Display::DrawAndSwap() { bool should_draw = !frame->metadata.latency_info.empty() || have_copy_requests || (have_damage && size_matches); + // If the surface is suspended then the resources to be used by the draw are + // likely destroyed. + if (output_surface_->SurfaceIsSuspendForRecycle()) { + TRACE_EVENT_INSTANT0("cc", "Surface is suspended for recycle.", + TRACE_EVENT_SCOPE_THREAD); + should_draw = false; + } + if (should_draw) { gfx::Rect device_viewport_rect = gfx::Rect(current_surface_size_); gfx::Rect device_clip_rect = diff --git a/cc/surfaces/surface_display_output_surface_unittest.cc b/cc/surfaces/surface_display_output_surface_unittest.cc index 9b67f1f..922dd9e 100644 --- a/cc/surfaces/surface_display_output_surface_unittest.cc +++ b/cc/surfaces/surface_display_output_surface_unittest.cc @@ -132,6 +132,21 @@ TEST_F(SurfaceDisplayOutputSurfaceTest, NoDamageDoesNotTriggerSwapBuffers) { EXPECT_EQ(1u, output_surface_->num_sent_frames()); } +TEST_F(SurfaceDisplayOutputSurfaceTest, SuspendedDoesNotTriggerSwapBuffers) { + SwapBuffersWithDamage(display_rect_); + EXPECT_EQ(1u, output_surface_->num_sent_frames()); + output_surface_->set_suspended_for_recycle(true); + task_runner_->RunUntilIdle(); + EXPECT_EQ(1u, output_surface_->num_sent_frames()); + SwapBuffersWithDamage(display_rect_); + task_runner_->RunUntilIdle(); + EXPECT_EQ(1u, output_surface_->num_sent_frames()); + output_surface_->set_suspended_for_recycle(false); + SwapBuffersWithDamage(display_rect_); + task_runner_->RunUntilIdle(); + EXPECT_EQ(2u, output_surface_->num_sent_frames()); +} + TEST_F(SurfaceDisplayOutputSurfaceTest, LockingResourcesDoesNotIndirectlyCauseDamage) { surface_display_output_surface_.ForceReclaimResources(); |