summaryrefslogtreecommitdiffstats
path: root/cc/output
diff options
context:
space:
mode:
authorccameron <ccameron@chromium.org>2015-11-19 20:46:29 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-20 04:47:10 +0000
commit07e6ae2763489f4dd5bc1c01ca5d07acedfb8aef (patch)
tree9f9f6405cee026c3054a550ca8f6b5f3ac2e4fcc /cc/output
parentf5bcadb3fe9f39fbb0fb0f9c3307420667e904a0 (diff)
downloadchromium_src-07e6ae2763489f4dd5bc1c01ca5d07acedfb8aef.zip
chromium_src-07e6ae2763489f4dd5bc1c01ca5d07acedfb8aef.tar.gz
chromium_src-07e6ae2763489f4dd5bc1c01ca5d07acedfb8aef.tar.bz2
cc: Allow holding on to overlay resources for another extra frame
We don't get a clear picture of when CoreAnimation is done using resources, so, when we hand a resource to CoreAnimation as an overlay, hold on to that resource for an extra frame, to ensure that we don't access it while the system is still accessing it. Add a RendererSettings flag to control this. BUG=558701 TEST=Open 2 windows, 1 with poster circle and the other NTP, hover mouse around the NTP thumbnails CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1463653002 Cr-Commit-Position: refs/heads/master@{#360747}
Diffstat (limited to 'cc/output')
-rw-r--r--cc/output/gl_renderer.cc17
-rw-r--r--cc/output/gl_renderer.h2
-rw-r--r--cc/output/overlay_unittest.cc132
-rw-r--r--cc/output/renderer_settings.cc1
-rw-r--r--cc/output/renderer_settings.h1
5 files changed, 147 insertions, 6 deletions
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index 280b554..546446d 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -383,7 +383,8 @@ GLRenderer::~GLRenderer() {
pending_async_read_pixels_.pop_back();
}
- previous_swap_overlay_resources_.clear();
+ previous_swap_overlay_resources_[1].clear();
+ previous_swap_overlay_resources_[0].clear();
in_use_overlay_resources_.clear();
CleanupSharedObjects();
@@ -2628,10 +2629,16 @@ void GLRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) {
output_surface_->SwapBuffers(&compositor_frame);
// We always hold onto resources for an extra frame, to make sure we don't
- // update the buffer while it's being scanned out.
- previous_swap_overlay_resources_.clear();
- previous_swap_overlay_resources_.swap(in_use_overlay_resources_);
-
+ // update the buffer while it's being scanned out. On some platforms, hold
+ // on to resources for an extra frame.
+ if (settings_->delay_releasing_overlay_resources) {
+ previous_swap_overlay_resources_[1].clear();
+ previous_swap_overlay_resources_[1].swap(
+ previous_swap_overlay_resources_[0]);
+ } else {
+ previous_swap_overlay_resources_[0].clear();
+ }
+ previous_swap_overlay_resources_[0].swap(in_use_overlay_resources_);
in_use_overlay_resources_.swap(pending_overlay_resources_);
swap_buffer_rect_ = gfx::Rect();
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h
index 93b65b4..233fd3b 100644
--- a/cc/output/gl_renderer.h
+++ b/cc/output/gl_renderer.h
@@ -264,7 +264,7 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
std::vector<scoped_ptr<ResourceProvider::ScopedReadLockGL>>;
OverlayResourceLockList pending_overlay_resources_;
OverlayResourceLockList in_use_overlay_resources_;
- OverlayResourceLockList previous_swap_overlay_resources_;
+ OverlayResourceLockList previous_swap_overlay_resources_[2];
RendererCapabilitiesImpl capabilities_;
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc
index 1fbcff0..6ee0ac5 100644
--- a/cc/output/overlay_unittest.cc
+++ b/cc/output/overlay_unittest.cc
@@ -1895,5 +1895,137 @@ TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturnedWithDelay) {
Mock::VerifyAndClearExpectations(&scheduler_);
}
+TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturnedWithExtraDelay) {
+ bool use_validator = true;
+ settings_.delay_releasing_overlay_resources = true;
+ Init(use_validator);
+ renderer_->set_expect_overlays(true);
+
+ ResourceId resource1 =
+ CreateResource(resource_provider_.get(), gfx::Size(32, 32), true);
+ ResourceId resource2 =
+ CreateResource(resource_provider_.get(), gfx::Size(32, 32), true);
+ ResourceId resource3 =
+ CreateResource(resource_provider_.get(), gfx::Size(32, 32), true);
+
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ DirectRenderer::DrawingFrame frame1;
+ frame1.render_passes_in_draw_order = &pass_list;
+ frame1.overlay_list.resize(2);
+ frame1.overlay_list.front().use_output_surface_for_resource = true;
+ OverlayCandidate& overlay1 = frame1.overlay_list.back();
+ overlay1.resource_id = resource1;
+ overlay1.plane_z_order = 1;
+
+ DirectRenderer::DrawingFrame frame2;
+ frame2.render_passes_in_draw_order = &pass_list;
+ frame2.overlay_list.resize(2);
+ frame2.overlay_list.front().use_output_surface_for_resource = true;
+ OverlayCandidate& overlay2 = frame2.overlay_list.back();
+ overlay2.resource_id = resource2;
+ overlay2.plane_z_order = 1;
+
+ DirectRenderer::DrawingFrame frame3;
+ frame3.render_passes_in_draw_order = &pass_list;
+ frame3.overlay_list.resize(2);
+ frame3.overlay_list.front().use_output_surface_for_resource = true;
+ OverlayCandidate& overlay3 = frame3.overlay_list.back();
+ overlay3.resource_id = resource3;
+ overlay3.plane_z_order = 1;
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(2);
+ renderer_->BeginDrawingFrame(&frame1);
+ renderer_->FinishDrawingFrame(&frame1);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+ SwapBuffers();
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(2);
+ renderer_->BeginDrawingFrame(&frame2);
+ renderer_->FinishDrawingFrame(&frame2);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
+ SwapBuffers();
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(2);
+ renderer_->BeginDrawingFrame(&frame3);
+ renderer_->FinishDrawingFrame(&frame3);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource3));
+ SwapBuffers();
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource3));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ // No overlays, release the resource.
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
+ DirectRenderer::DrawingFrame frame_no_overlays;
+ frame_no_overlays.render_passes_in_draw_order = &pass_list;
+ renderer_->set_expect_overlays(false);
+ renderer_->BeginDrawingFrame(&frame_no_overlays);
+ renderer_->FinishDrawingFrame(&frame_no_overlays);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource3));
+ SwapBuffers();
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource3));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ // Use the same buffer twice.
+ renderer_->set_expect_overlays(true);
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(2);
+ renderer_->BeginDrawingFrame(&frame1);
+ renderer_->FinishDrawingFrame(&frame1);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ SwapBuffers();
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(2);
+ renderer_->BeginDrawingFrame(&frame1);
+ renderer_->FinishDrawingFrame(&frame1);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ SwapBuffers();
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
+ renderer_->set_expect_overlays(false);
+ renderer_->BeginDrawingFrame(&frame_no_overlays);
+ renderer_->FinishDrawingFrame(&frame_no_overlays);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ SwapBuffers();
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
+ renderer_->set_expect_overlays(false);
+ renderer_->BeginDrawingFrame(&frame_no_overlays);
+ renderer_->FinishDrawingFrame(&frame_no_overlays);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ SwapBuffers();
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
+ renderer_->set_expect_overlays(false);
+ renderer_->BeginDrawingFrame(&frame_no_overlays);
+ renderer_->FinishDrawingFrame(&frame_no_overlays);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ SwapBuffers();
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+}
+
} // namespace
} // namespace cc
diff --git a/cc/output/renderer_settings.cc b/cc/output/renderer_settings.cc
index dce7e24..7b18278 100644
--- a/cc/output/renderer_settings.cc
+++ b/cc/output/renderer_settings.cc
@@ -18,6 +18,7 @@ RendererSettings::RendererSettings()
finish_rendering_on_resize(false),
should_clear_root_render_pass(true),
disable_display_vsync(false),
+ delay_releasing_overlay_resources(false),
refresh_rate(60.0),
highp_threshold_min(0),
use_rgba_4444_textures(false),
diff --git a/cc/output/renderer_settings.h b/cc/output/renderer_settings.h
index 8022800..3934139 100644
--- a/cc/output/renderer_settings.h
+++ b/cc/output/renderer_settings.h
@@ -22,6 +22,7 @@ class CC_EXPORT RendererSettings {
bool finish_rendering_on_resize;
bool should_clear_root_render_pass;
bool disable_display_vsync;
+ bool delay_releasing_overlay_resources;
double refresh_rate;
int highp_threshold_min;
bool use_rgba_4444_textures;