diff options
-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 | ||||
-rw-r--r-- | ui/compositor/compositor.cc | 2 |
6 files changed, 149 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; diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index 438d831..fbc801d 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc @@ -112,6 +112,8 @@ Compositor::Compositor(ui::ContextFactory* context_factory, !command_line->HasSwitch(switches::kUIDisablePartialSwap); #if defined(OS_WIN) settings.renderer_settings.finish_rendering_on_resize = true; +#elif defined(OS_MACOSX) + settings.renderer_settings.delay_releasing_overlay_resources = true; #endif // These flags should be mirrored by renderer versions in content/renderer/. |