summaryrefslogtreecommitdiffstats
path: root/cc/surfaces
diff options
context:
space:
mode:
authorccameron <ccameron@chromium.org>2015-08-07 12:26:02 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-07 19:26:38 +0000
commitd9fa78192b5286e0ab0ccf651ff5a8fb869ef7f2 (patch)
treed34a2500f973e029f038a03979be4fc54d7530ea /cc/surfaces
parent884b72bafb2dda816a09bbdb7a3b7ada2668eee0 (diff)
downloadchromium_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.cc11
-rw-r--r--cc/surfaces/surface_display_output_surface_unittest.cc15
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();