diff options
author | ccameron <ccameron@chromium.org> | 2015-11-19 20:46:29 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-20 04:47:10 +0000 |
commit | 07e6ae2763489f4dd5bc1c01ca5d07acedfb8aef (patch) | |
tree | 9f9f6405cee026c3054a550ca8f6b5f3ac2e4fcc /cc/output | |
parent | f5bcadb3fe9f39fbb0fb0f9c3307420667e904a0 (diff) | |
download | chromium_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.cc | 17 | ||||
-rw-r--r-- | cc/output/gl_renderer.h | 2 | ||||
-rw-r--r-- | cc/output/overlay_unittest.cc | 132 | ||||
-rw-r--r-- | cc/output/renderer_settings.cc | 1 | ||||
-rw-r--r-- | cc/output/renderer_settings.h | 1 |
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; |