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 | |
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}
-rw-r--r-- | cc/surfaces/display.cc | 11 | ||||
-rw-r--r-- | cc/surfaces/surface_display_output_surface_unittest.cc | 15 | ||||
-rw-r--r-- | cc/test/fake_output_surface.cc | 8 | ||||
-rw-r--r-- | cc/test/fake_output_surface.h | 7 |
4 files changed, 38 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(); diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc index dbb1d9d..4ba4971 100644 --- a/cc/test/fake_output_surface.cc +++ b/cc/test/fake_output_surface.cc @@ -22,6 +22,7 @@ FakeOutputSurface::FakeOutputSurface( client_(NULL), num_sent_frames_(0), has_external_stencil_test_(false), + suspended_for_recycle_(false), framebuffer_(0) { if (delegated_rendering) { capabilities_.delegated_rendering = true; @@ -36,6 +37,7 @@ FakeOutputSurface::FakeOutputSurface( client_(NULL), num_sent_frames_(0), has_external_stencil_test_(false), + suspended_for_recycle_(false), framebuffer_(0) { if (delegated_rendering) { capabilities_.delegated_rendering = true; @@ -50,6 +52,7 @@ FakeOutputSurface::FakeOutputSurface( client_(NULL), num_sent_frames_(0), has_external_stencil_test_(false), + suspended_for_recycle_(false), framebuffer_(0) { if (delegated_rendering) { capabilities_.delegated_rendering = true; @@ -65,6 +68,7 @@ FakeOutputSurface::FakeOutputSurface( client_(NULL), num_sent_frames_(0), has_external_stencil_test_(false), + suspended_for_recycle_(false), framebuffer_(0) { if (delegated_rendering) { capabilities_.delegated_rendering = true; @@ -139,6 +143,10 @@ bool FakeOutputSurface::HasExternalStencilTest() const { return has_external_stencil_test_; } +bool FakeOutputSurface::SurfaceIsSuspendForRecycle() const { + return suspended_for_recycle_; +} + void FakeOutputSurface::SetMemoryPolicyToSetAtBind( scoped_ptr<ManagedMemoryPolicy> memory_policy_to_set_at_bind) { memory_policy_to_set_at_bind_.swap(memory_policy_to_set_at_bind); diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index 7041a44..a682177 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h @@ -117,10 +117,16 @@ class FakeOutputSurface : public OutputSurface { bool HasExternalStencilTest() const override; + bool SurfaceIsSuspendForRecycle() const override; + void set_has_external_stencil_test(bool has_test) { has_external_stencil_test_ = has_test; } + void set_suspended_for_recycle(bool suspended) { + suspended_for_recycle_ = suspended; + } + void SetMemoryPolicyToSetAtBind( scoped_ptr<ManagedMemoryPolicy> memory_policy_to_set_at_bind); @@ -149,6 +155,7 @@ class FakeOutputSurface : public OutputSurface { CompositorFrame last_sent_frame_; size_t num_sent_frames_; bool has_external_stencil_test_; + bool suspended_for_recycle_; unsigned framebuffer_; TransferableResourceArray resources_held_by_parent_; scoped_ptr<ManagedMemoryPolicy> memory_policy_to_set_at_bind_; |