summaryrefslogtreecommitdiffstats
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
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}
-rw-r--r--cc/surfaces/display.cc11
-rw-r--r--cc/surfaces/surface_display_output_surface_unittest.cc15
-rw-r--r--cc/test/fake_output_surface.cc8
-rw-r--r--cc/test/fake_output_surface.h7
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_;