From f4e57485631dc4c3beaa87de398975cab87fdc32 Mon Sep 17 00:00:00 2001 From: boliu Date: Tue, 22 Mar 2016 12:33:17 -0700 Subject: sync compositor: Add output_surface_id plumbing The output_surface_id is unique for a particular renderer compositor instance. It is used to avoid returning resources from lost context to compositor with new context. Plumb output_surface_id from SynchronousOutputSurface all the way to android_webview::HardwareRenderer. To avoid having to send down a map, a simpler guarantee is to assume the output_surface_id is increasing, so only need to return resources of with highest output surface id and drop resources other resources. BUG=592744 Review URL: https://codereview.chromium.org/1769913003 Cr-Commit-Position: refs/heads/master@{#382636} --- android_webview/browser/browser_view_renderer.cc | 23 ++--- .../browser/browser_view_renderer_unittest.cc | 99 +++++++++++++++++++++- android_webview/browser/child_frame.cc | 6 +- android_webview/browser/child_frame.h | 4 +- android_webview/browser/hardware_renderer.cc | 23 +++-- android_webview/browser/hardware_renderer.h | 7 +- android_webview/browser/shared_renderer_state.cc | 20 +++-- android_webview/browser/shared_renderer_state.h | 18 ++-- android_webview/browser/test/rendering_test.cc | 11 +-- android_webview/browser/test/rendering_test.h | 7 +- .../synchronous_compositor_factory_impl.cc | 3 +- .../synchronous_compositor_factory_impl.h | 1 + .../in_process/synchronous_compositor_impl.cc | 31 ++++--- .../in_process/synchronous_compositor_impl.h | 10 ++- .../browser/android/synchronous_compositor_host.cc | 30 +++++-- .../browser/android/synchronous_compositor_host.h | 6 +- content/common/android/sync_compositor_messages.cc | 1 + content/common/android/sync_compositor_messages.h | 5 +- content/content_browser.gypi | 1 + .../browser/android/synchronous_compositor.cc | 27 ++++++ .../browser/android/synchronous_compositor.h | 20 ++++- .../test/test_synchronous_compositor_android.cc | 25 +++++- .../test/test_synchronous_compositor_android.h | 24 +++++- .../android/synchronous_compositor_factory.h | 1 + .../synchronous_compositor_output_surface.cc | 8 +- .../synchronous_compositor_output_surface.h | 8 +- .../android/synchronous_compositor_proxy.cc | 30 +++---- .../android/synchronous_compositor_proxy.h | 6 +- content/renderer/render_widget.cc | 10 ++- 29 files changed, 365 insertions(+), 100 deletions(-) create mode 100644 content/public/browser/android/synchronous_compositor.cc diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc index 9cc3669..cf6b4b4 100644 --- a/android_webview/browser/browser_view_renderer.cc +++ b/android_webview/browser/browser_view_renderer.cc @@ -250,23 +250,24 @@ bool BrowserViewRenderer::OnDrawHardware() { viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_; } - scoped_ptr frame = + content::SynchronousCompositor::Frame frame = compositor_->DemandDrawHw(surface_size, gfx::Transform(), viewport, clip, viewport_rect_for_tile_priority, transform_for_tile_priority); - if (!frame.get()) { + if (!frame.frame.get()) { TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", TRACE_EVENT_SCOPE_THREAD); return shared_renderer_state_.HasFrameOnUI(); } scoped_ptr child_frame = make_scoped_ptr(new ChildFrame( - std::move(frame), GetCompositorID(compositor_), - viewport_rect_for_tile_priority.IsEmpty(), transform_for_tile_priority, - offscreen_pre_raster_, parent_draw_constraints.is_layer)); + frame.output_surface_id, std::move(frame.frame), + GetCompositorID(compositor_), viewport_rect_for_tile_priority.IsEmpty(), + transform_for_tile_priority, offscreen_pre_raster_, + parent_draw_constraints.is_layer)); ReturnUnusedResource(shared_renderer_state_.PassUncommittedFrameOnUI()); shared_renderer_state_.SetCompositorFrameOnUI(std::move(child_frame)); @@ -292,21 +293,23 @@ void BrowserViewRenderer::ReturnUnusedResource( content::SynchronousCompositor* compositor = compositor_map_[child_frame->compositor_id]; if (compositor && !frame_ack.resources.empty()) - compositor->ReturnResources(frame_ack); + compositor->ReturnResources(child_frame->output_surface_id, frame_ack); } void BrowserViewRenderer::ReturnResourceFromParent() { - std::map returned_resource_map; + SharedRendererState::ReturnedResourcesMap returned_resource_map; shared_renderer_state_.SwapReturnedResourcesOnUI(&returned_resource_map); for (auto iterator = returned_resource_map.begin(); iterator != returned_resource_map.end(); iterator++) { uint32_t compositor_id = iterator->first; content::SynchronousCompositor* compositor = compositor_map_[compositor_id]; cc::CompositorFrameAck frame_ack; - frame_ack.resources.swap(iterator->second); + frame_ack.resources.swap(iterator->second.resources); - if (compositor && !frame_ack.resources.empty()) - compositor->ReturnResources(frame_ack); + if (compositor && !frame_ack.resources.empty()) { + compositor->ReturnResources(iterator->second.output_surface_id, + frame_ack); + } } } diff --git a/android_webview/browser/browser_view_renderer_unittest.cc b/android_webview/browser/browser_view_renderer_unittest.cc index 5b2ec24..ffa5742 100644 --- a/android_webview/browser/browser_view_renderer_unittest.cc +++ b/android_webview/browser/browser_view_renderer_unittest.cc @@ -2,11 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include +#include +#include + #include "android_webview/browser/browser_view_renderer.h" #include "android_webview/browser/child_frame.h" #include "android_webview/browser/test/rendering_test.h" #include "base/location.h" #include "base/single_thread_task_runner.h" +#include "cc/output/compositor_frame.h" +#include "content/public/test/test_synchronous_compositor_android.h" namespace android_webview { @@ -156,7 +162,7 @@ class CompositorNoFrameTest : public RenderingTest { if (0 == on_draw_count_) { // No frame from compositor. } else if (1 == on_draw_count_) { - SetCompositorFrame(); + compositor_->SetHardwareFrame(0u, ConstructEmptyFrame()); } else if (2 == on_draw_count_) { // No frame from compositor. } @@ -186,4 +192,95 @@ class CompositorNoFrameTest : public RenderingTest { RENDERING_TEST_F(CompositorNoFrameTest); +class SwitchOutputSurfaceIdTest : public RenderingTest { + public: + struct FrameInfo { + uint32_t output_surface_id; + cc::ResourceId resource_id; // Each frame contains a single resource. + }; + + void StartTest() override { + last_output_surface_id_ = 0; + FrameInfo infos[] = { + // First output surface. + {0u, 1u}, {0u, 1u}, {0u, 2u}, {0u, 2u}, {0u, 3u}, {0u, 3u}, {0u, 4u}, + // Second output surface. + {1u, 1u}, {1u, 1u}, {1u, 2u}, {1u, 2u}, {1u, 3u}, {1u, 3u}, {1u, 4u}, + }; + for (const auto& info : infos) { + content::SynchronousCompositor::Frame frame; + frame.output_surface_id = info.output_surface_id; + frame.frame = ConstructEmptyFrame(); + cc::TransferableResource resource; + resource.id = info.resource_id; + frame.frame->delegated_frame_data->resource_list.push_back(resource); + frames_.push(std::move(frame)); + + // Keep a id -> count map for the last ouptut_surface_id. + if (last_output_surface_id_ != info.output_surface_id) { + expected_return_count_.clear(); + last_output_surface_id_ = info.output_surface_id; + } + if (expected_return_count_.count(info.resource_id)) { + expected_return_count_[info.resource_id]++; + } else { + expected_return_count_[info.resource_id] = 1; + } + } + + browser_view_renderer_->PostInvalidate(); + } + + void WillOnDraw() override { + if (!frames_.empty()) { + compositor_->SetHardwareFrame(frames_.front().output_surface_id, + std::move(frames_.front().frame)); + } + } + + void DidOnDraw(bool success) override { + EXPECT_TRUE(success); + if (frames_.empty()) { + ui_task_runner_->PostTask( + FROM_HERE, base::Bind(&SwitchOutputSurfaceIdTest::CheckResults, + base::Unretained(this))); + } else { + frames_.pop(); + browser_view_renderer_->PostInvalidate(); + } + } + + void CheckResults() { + window_->Detach(); + window_.reset(); + + // Make sure resources for the last output surface are returned. + content::TestSynchronousCompositor::FrameAckArray returned_resources_array; + compositor_->SwapReturnedResources(&returned_resources_array); + for (const auto& resources : returned_resources_array) { + if (resources.output_surface_id != last_output_surface_id_) + continue; + for (const auto& returned_resource : resources.resources) { + EXPECT_TRUE(!!expected_return_count_.count(returned_resource.id)); + EXPECT_GE(expected_return_count_[returned_resource.id], + returned_resource.count); + expected_return_count_[returned_resource.id] -= + returned_resource.count; + if (!expected_return_count_[returned_resource.id]) + expected_return_count_.erase(returned_resource.id); + } + } + EXPECT_TRUE(expected_return_count_.empty()); + + EndTest(); + } + + private: + std::queue frames_; + uint32_t last_output_surface_id_; + std::map expected_return_count_; +}; + +RENDERING_TEST_F(SwitchOutputSurfaceIdTest); + } // namespace android_webview diff --git a/android_webview/browser/child_frame.cc b/android_webview/browser/child_frame.cc index aa6130f..f51b745 100644 --- a/android_webview/browser/child_frame.cc +++ b/android_webview/browser/child_frame.cc @@ -10,13 +10,15 @@ namespace android_webview { -ChildFrame::ChildFrame(scoped_ptr frame, +ChildFrame::ChildFrame(uint32_t output_surface_id, + scoped_ptr frame, uint32_t compositor_id, bool viewport_rect_for_tile_priority_empty, const gfx::Transform& transform_for_tile_priority, bool offscreen_pre_raster, bool is_layer) - : frame(std::move(frame)), + : output_surface_id(output_surface_id), + frame(std::move(frame)), compositor_id(compositor_id), viewport_rect_for_tile_priority_empty( viewport_rect_for_tile_priority_empty), diff --git a/android_webview/browser/child_frame.h b/android_webview/browser/child_frame.h index b83e57e..ca42958 100644 --- a/android_webview/browser/child_frame.h +++ b/android_webview/browser/child_frame.h @@ -19,7 +19,8 @@ namespace android_webview { class ChildFrame { public: - ChildFrame(scoped_ptr frame, + ChildFrame(uint32_t output_surface_id, + scoped_ptr frame, uint32_t compositor_id, bool viewport_rect_for_tile_priority_empty, const gfx::Transform& transform_for_tile_priority, @@ -27,6 +28,7 @@ class ChildFrame { bool is_layer); ~ChildFrame(); + const uint32_t output_surface_id; scoped_ptr frame; // The id of the compositor this |frame| comes from. const uint32_t compositor_id; diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc index aab7f16..f0a4f85 100644 --- a/android_webview/browser/hardware_renderer.cc +++ b/android_webview/browser/hardware_renderer.cc @@ -38,7 +38,9 @@ HardwareRenderer::HardwareRenderer(SharedRendererState* state) : shared_renderer_state_(state), last_egl_context_(eglGetCurrentContext()), gl_surface_(new AwGLSurface), - compositor_id_(0), // Valid compositor id starts at 1. + compositor_id_(0u), // Valid compositor id starts at 1. + last_committed_output_surface_id_(0u), + last_submitted_output_surface_id_(0u), output_surface_(NULL) { DCHECK(last_egl_context_); @@ -86,6 +88,7 @@ void HardwareRenderer::CommitFrame() { if (!child_frame.get()) return; + last_committed_output_surface_id_ = child_frame->output_surface_id; ReturnResourcesInChildFrame(); child_frame_ = std::move(child_frame); DCHECK(child_frame_->frame.get()); @@ -110,7 +113,8 @@ void HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, // kModeProcess. Instead, submit the frame in "kModeDraw" stage to avoid // unnecessary kModeProcess. if (child_frame_.get() && child_frame_->frame.get()) { - if (compositor_id_ != child_frame_->compositor_id) { + if (compositor_id_ != child_frame_->compositor_id || + last_submitted_output_surface_id_ != child_frame_->output_surface_id) { if (!root_id_.is_null()) surface_factory_->Destroy(root_id_); if (!child_id_.is_null()) @@ -122,6 +126,7 @@ void HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, // This will return all the resources to the previous compositor. surface_factory_.reset(); compositor_id_ = child_frame_->compositor_id; + last_submitted_output_surface_id_ = child_frame_->output_surface_id; surface_factory_.reset( new cc::SurfaceFactory(surface_manager_.get(), this)); } @@ -223,7 +228,8 @@ void HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, void HardwareRenderer::ReturnResources( const cc::ReturnedResourceArray& resources) { - ReturnResourcesToCompositor(resources, compositor_id_); + ReturnResourcesToCompositor(resources, compositor_id_, + last_submitted_output_surface_id_); } void HardwareRenderer::SetBeginFrameSource( @@ -246,15 +252,20 @@ void HardwareRenderer::ReturnResourcesInChildFrame() { // The child frame's compositor id is not necessarily same as // compositor_id_. ReturnResourcesToCompositor(resources_to_return, - child_frame_->compositor_id); + child_frame_->compositor_id, + child_frame_->output_surface_id); } child_frame_.reset(); } void HardwareRenderer::ReturnResourcesToCompositor( const cc::ReturnedResourceArray& resources, - uint32_t compositor_id) { - shared_renderer_state_->InsertReturnedResourcesOnRT(resources, compositor_id); + uint32_t compositor_id, + uint32_t output_surface_id) { + if (output_surface_id != last_committed_output_surface_id_) + return; + shared_renderer_state_->InsertReturnedResourcesOnRT(resources, compositor_id, + output_surface_id); } } // namespace android_webview diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h index fe842f4..1b5127a 100644 --- a/android_webview/browser/hardware_renderer.h +++ b/android_webview/browser/hardware_renderer.h @@ -52,7 +52,8 @@ class HardwareRenderer : public cc::DisplayClient, void ReturnResourcesInChildFrame(); void ReturnResourcesToCompositor(const cc::ReturnedResourceArray& resources, - uint32_t compositor_routing_id); + uint32_t compositor_routing_id, + uint32_t output_surface_id); SharedRendererState* shared_renderer_state_; @@ -79,6 +80,10 @@ class HardwareRenderer : public cc::DisplayClient, cc::SurfaceId child_id_; cc::SurfaceId root_id_; uint32_t compositor_id_; + // HardwareRenderer guarantees resources are returned in the order of + // output_surface_id, and resources for old output surfaces are dropped. + uint32_t last_committed_output_surface_id_; + uint32_t last_submitted_output_surface_id_; // This is owned by |display_|. ParentOutputSurface* output_surface_; diff --git a/android_webview/browser/shared_renderer_state.cc b/android_webview/browser/shared_renderer_state.cc index e81ab126..488f915 100644 --- a/android_webview/browser/shared_renderer_state.cc +++ b/android_webview/browser/shared_renderer_state.cc @@ -213,18 +213,28 @@ bool SharedRendererState::IsInsideHardwareRelease() const { return inside_hardware_release_; } +SharedRendererState::ReturnedResources::ReturnedResources() + : output_surface_id(0u) {} + +SharedRendererState::ReturnedResources::~ReturnedResources() {} + void SharedRendererState::InsertReturnedResourcesOnRT( const cc::ReturnedResourceArray& resources, - uint32_t compositor_id) { + uint32_t compositor_id, + uint32_t output_surface_id) { base::AutoLock lock(lock_); - cc::ReturnedResourceArray& returned_resources = + ReturnedResources& returned_resources = returned_resources_map_[compositor_id]; - returned_resources.insert(returned_resources.end(), resources.begin(), - resources.end()); + if (returned_resources.output_surface_id != output_surface_id) { + returned_resources.resources.clear(); + } + returned_resources.resources.insert(returned_resources.resources.end(), + resources.begin(), resources.end()); + returned_resources.output_surface_id = output_surface_id; } void SharedRendererState::SwapReturnedResourcesOnUI( - std::map* returned_resource_map) { + ReturnedResourcesMap* returned_resource_map) { DCHECK(returned_resource_map->empty()); base::AutoLock lock(lock_); returned_resource_map->swap(returned_resources_map_); diff --git a/android_webview/browser/shared_renderer_state.h b/android_webview/browser/shared_renderer_state.h index a6f3e0b..a2313a5 100644 --- a/android_webview/browser/shared_renderer_state.h +++ b/android_webview/browser/shared_renderer_state.h @@ -34,6 +34,15 @@ class InsideHardwareReleaseReset; // This class is used to pass data between UI thread and RenderThread. class SharedRendererState { public: + struct ReturnedResources { + ReturnedResources(); + ~ReturnedResources(); + + uint32_t output_surface_id; + cc::ReturnedResourceArray resources; + }; + using ReturnedResourcesMap = std::map; + SharedRendererState( const scoped_refptr& ui_loop, BrowserViewRenderer* browser_view_renderer); @@ -48,8 +57,7 @@ class SharedRendererState { void InitializeHardwareDrawIfNeededOnUI(); void ReleaseHardwareDrawIfNeededOnUI(); ParentCompositorDrawConstraints GetParentDrawConstraintsOnUI() const; - void SwapReturnedResourcesOnUI( - std::map* returned_resource_map); + void SwapReturnedResourcesOnUI(ReturnedResourcesMap* returned_resource_map); bool ReturnedResourcesEmptyOnUI() const; scoped_ptr PassUncommittedFrameOnUI(); void DeleteHardwareRendererOnUI(); @@ -62,7 +70,8 @@ class SharedRendererState { void PostExternalDrawConstraintsToChildCompositorOnRT( const ParentCompositorDrawConstraints& parent_draw_constraints); void InsertReturnedResourcesOnRT(const cc::ReturnedResourceArray& resources, - uint32_t compositor_id); + uint32_t compositor_id, + uint32_t output_surface_id); private: friend class internal::RequestDrawGLTracker; @@ -106,8 +115,7 @@ class SharedRendererState { scoped_ptr child_frame_; bool inside_hardware_release_; ParentCompositorDrawConstraints parent_draw_constraints_; - // A map from compositor's ID to the resources that belong to the compositor. - std::map returned_resources_map_; + ReturnedResourcesMap returned_resources_map_; base::Closure request_draw_gl_closure_; base::WeakPtrFactory weak_factory_on_ui_thread_; diff --git a/android_webview/browser/test/rendering_test.cc b/android_webview/browser/test/rendering_test.cc index 4f00a20..e51f3aa 100644 --- a/android_webview/browser/test/rendering_test.cc +++ b/android_webview/browser/test/rendering_test.cc @@ -67,8 +67,7 @@ void RenderingTest::QuitMessageLoop() { message_loop_->QuitWhenIdle(); } -void RenderingTest::SetCompositorFrame() { - DCHECK(compositor_.get()); +scoped_ptr RenderingTest::ConstructEmptyFrame() { scoped_ptr compositor_frame(new cc::CompositorFrame); scoped_ptr frame(new cc::DelegatedFrameData); scoped_ptr root_pass(cc::RenderPass::Create()); @@ -77,11 +76,12 @@ void RenderingTest::SetCompositorFrame() { gfx::Transform()); frame->render_pass_list.push_back(std::move(root_pass)); compositor_frame->delegated_frame_data = std::move(frame); - compositor_->SetHardwareFrame(std::move(compositor_frame)); + return compositor_frame; } void RenderingTest::WillOnDraw() { - SetCompositorFrame(); + DCHECK(compositor_); + compositor_->SetHardwareFrame(0u, ConstructEmptyFrame()); } bool RenderingTest::RequestDrawGL(bool wait_for_completion) { @@ -103,7 +103,8 @@ void RenderingTest::OnNewPicture() { } void RenderingTest::PostInvalidate() { - window_->PostInvalidate(); + if (window_) + window_->PostInvalidate(); } void RenderingTest::DetachFunctorFromView() { diff --git a/android_webview/browser/test/rendering_test.h b/android_webview/browser/test/rendering_test.h index 0e6fcf1..8dd6cae 100644 --- a/android_webview/browser/test/rendering_test.h +++ b/android_webview/browser/test/rendering_test.h @@ -16,6 +16,10 @@ namespace base { class MessageLoop; } +namespace cc { +class CompositorFrame; +} + namespace content { class TestSynchronousCompositor; } @@ -58,6 +62,7 @@ class RenderingTest : public testing::Test, void DidDrawOnRT(SharedRendererState* functor) override {} protected: + RenderingTest(); ~RenderingTest() override; @@ -68,7 +73,7 @@ class RenderingTest : public testing::Test, void InitializeCompositor(); void Attach(); void EndTest(); - void SetCompositorFrame(); + scoped_ptr ConstructEmptyFrame(); scoped_refptr ui_task_runner_; scoped_ptr browser_view_renderer_; diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc index 4dba524b..6d9e64a 100644 --- a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc +++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc @@ -104,11 +104,12 @@ SynchronousCompositorFactoryImpl::GetCompositorTaskRunner() { scoped_ptr SynchronousCompositorFactoryImpl::CreateOutputSurface( int routing_id, + uint32_t output_surface_id, const scoped_refptr& frame_swap_message_queue, const scoped_refptr& onscreen_context, const scoped_refptr& worker_context) { return make_scoped_ptr(new SynchronousCompositorOutputSurface( - onscreen_context, worker_context, routing_id, + onscreen_context, worker_context, routing_id, output_surface_id, SynchronousCompositorRegistryInProc::GetInstance(), frame_swap_message_queue)); } diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.h b/content/browser/android/in_process/synchronous_compositor_factory_impl.h index 79b2625..4842e85 100644 --- a/content/browser/android/in_process/synchronous_compositor_factory_impl.h +++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.h @@ -41,6 +41,7 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { override; scoped_ptr CreateOutputSurface( int routing_id, + uint32_t output_surface_id, const scoped_refptr& frame_swap_message_queue, const scoped_refptr& onscreen_context, const scoped_refptr& worker_context) override; diff --git a/content/browser/android/in_process/synchronous_compositor_impl.cc b/content/browser/android/in_process/synchronous_compositor_impl.cc index ed99e093..1b06e51 100644 --- a/content/browser/android/in_process/synchronous_compositor_impl.cc +++ b/content/browser/android/in_process/synchronous_compositor_impl.cc @@ -150,7 +150,7 @@ void SynchronousCompositorImpl::DidDestroyRendererObjects() { need_animate_input_ = false; } -scoped_ptr SynchronousCompositorImpl::DemandDrawHw( +SynchronousCompositor::Frame SynchronousCompositorImpl::DemandDrawHw( const gfx::Size& surface_size, const gfx::Transform& transform, const gfx::Rect& viewport, @@ -160,45 +160,48 @@ scoped_ptr SynchronousCompositorImpl::DemandDrawHw( DCHECK(CalledOnValidThread()); DCHECK(output_surface_); DCHECK(begin_frame_source_); - DCHECK(!frame_holder_); + DCHECK(!frame_holder_.frame); output_surface_->DemandDrawHw(surface_size, transform, viewport, clip, viewport_rect_for_tile_priority, transform_for_tile_priority); - if (frame_holder_) - UpdateFrameMetaData(frame_holder_->metadata); + if (frame_holder_.frame) + UpdateFrameMetaData(frame_holder_.frame->metadata); return std::move(frame_holder_); } void SynchronousCompositorImpl::ReturnResources( + uint32_t output_surface_id, const cc::CompositorFrameAck& frame_ack) { DCHECK(CalledOnValidThread()); - output_surface_->ReturnResources(frame_ack); + output_surface_->ReturnResources(output_surface_id, frame_ack); } bool SynchronousCompositorImpl::DemandDrawSw(SkCanvas* canvas) { DCHECK(CalledOnValidThread()); DCHECK(output_surface_); DCHECK(begin_frame_source_); - DCHECK(!frame_holder_); + DCHECK(!frame_holder_.frame); output_surface_->DemandDrawSw(canvas); - bool success = !!frame_holder_; - if (frame_holder_) { - UpdateFrameMetaData(frame_holder_->metadata); - frame_holder_.reset(); + bool success = !!frame_holder_.frame; + if (frame_holder_.frame) { + UpdateFrameMetaData(frame_holder_.frame->metadata); + frame_holder_.frame.reset(); } return success; } -void SynchronousCompositorImpl::SwapBuffers(cc::CompositorFrame* frame) { - DCHECK(!frame_holder_); - frame_holder_.reset(new cc::CompositorFrame); - frame->AssignTo(frame_holder_.get()); +void SynchronousCompositorImpl::SwapBuffers(uint32_t output_surface_id, + cc::CompositorFrame* frame) { + DCHECK(!frame_holder_.frame); + frame_holder_.output_surface_id = output_surface_id; + frame_holder_.frame.reset(new cc::CompositorFrame); + frame->AssignTo(frame_holder_.frame.get()); } void SynchronousCompositorImpl::UpdateFrameMetaData( diff --git a/content/browser/android/in_process/synchronous_compositor_impl.h b/content/browser/android/in_process/synchronous_compositor_impl.h index 2c7e5b5..4f3155a 100644 --- a/content/browser/android/in_process/synchronous_compositor_impl.h +++ b/content/browser/android/in_process/synchronous_compositor_impl.h @@ -57,10 +57,11 @@ class SynchronousCompositorImpl // SynchronousCompositorOutputSurfaceClient overrides. void Invalidate() override; - void SwapBuffers(cc::CompositorFrame* frame) override; + void SwapBuffers(uint32_t output_surface_id, + cc::CompositorFrame* frame) override; // SynchronousCompositor overrides. - scoped_ptr DemandDrawHw( + SynchronousCompositor::Frame DemandDrawHw( const gfx::Size& surface_size, const gfx::Transform& transform, const gfx::Rect& viewport, @@ -68,7 +69,8 @@ class SynchronousCompositorImpl const gfx::Rect& viewport_rect_for_tile_priority, const gfx::Transform& transform_for_tile_priority) override; bool DemandDrawSw(SkCanvas* canvas) override; - void ReturnResources(const cc::CompositorFrameAck& frame_ack) override; + void ReturnResources(uint32_t output_surface_id, + const cc::CompositorFrameAck& frame_ack) override; void SetMemoryPolicy(size_t bytes_limit) override; void DidChangeRootLayerScrollOffset( const gfx::ScrollOffset& root_offset) override; @@ -116,7 +118,7 @@ class SynchronousCompositorImpl bool is_active_; bool renderer_needs_begin_frames_; bool need_animate_input_; - scoped_ptr frame_holder_; + SynchronousCompositor::Frame frame_holder_; base::WeakPtrFactory weak_ptr_factory_; diff --git a/content/browser/android/synchronous_compositor_host.cc b/content/browser/android/synchronous_compositor_host.cc index 6cb4907..2d937c5 100644 --- a/content/browser/android/synchronous_compositor_host.cc +++ b/content/browser/android/synchronous_compositor_host.cc @@ -42,6 +42,7 @@ SynchronousCompositorHost::SynchronousCompositorHost( use_in_process_zero_copy_software_draw_(use_in_proc_software_draw), is_active_(false), bytes_limit_(0u), + output_surface_id_from_last_draw_(0u), root_scroll_offset_updated_by_browser_(false), renderer_param_version_(0u), need_animate_scroll_(false), @@ -72,7 +73,7 @@ void SynchronousCompositorHost::DidBecomeCurrent() { client_->DidBecomeCurrent(this); } -scoped_ptr SynchronousCompositorHost::DemandDrawHw( +SynchronousCompositor::Frame SynchronousCompositorHost::DemandDrawHw( const gfx::Size& surface_size, const gfx::Transform& transform, const gfx::Rect& viewport, @@ -82,22 +83,27 @@ scoped_ptr SynchronousCompositorHost::DemandDrawHw( SyncCompositorDemandDrawHwParams params(surface_size, transform, viewport, clip, viewport_rect_for_tile_priority, transform_for_tile_priority); - scoped_ptr frame(new cc::CompositorFrame); + SynchronousCompositor::Frame frame; + frame.frame.reset(new cc::CompositorFrame); SyncCompositorCommonBrowserParams common_browser_params; PopulateCommonParams(&common_browser_params); SyncCompositorCommonRendererParams common_renderer_params; if (!sender_->Send(new SyncCompositorMsg_DemandDrawHw( routing_id_, common_browser_params, params, &common_renderer_params, - frame.get()))) { - return nullptr; + &frame.output_surface_id, frame.frame.get()))) { + return SynchronousCompositor::Frame(); } ProcessCommonParams(common_renderer_params); - if (!frame->delegated_frame_data) { + if (!frame.frame->delegated_frame_data) { // This can happen if compositor did not swap in this draw. - frame.reset(); + frame.frame.reset(); + } + if (frame.frame) { + UpdateFrameMetaData(frame.frame->metadata); + if (output_surface_id_from_last_draw_ != frame.output_surface_id) + returned_resources_.clear(); + output_surface_id_from_last_draw_ = frame.output_surface_id; } - if (frame) - UpdateFrameMetaData(frame->metadata); return frame; } @@ -269,7 +275,13 @@ void SynchronousCompositorHost::SendZeroMemory() { } void SynchronousCompositorHost::ReturnResources( + uint32_t output_surface_id, const cc::CompositorFrameAck& frame_ack) { + // If output_surface_id does not match, then renderer side has switched + // to a new OutputSurface, so dropping resources for old OutputSurface + // is allowed. + if (output_surface_id_from_last_draw_ != output_surface_id) + return; returned_resources_.insert(returned_resources_.end(), frame_ack.resources.begin(), frame_ack.resources.end()); @@ -389,6 +401,8 @@ void SynchronousCompositorHost::PopulateCommonParams( DCHECK(params); DCHECK(params->ack.resources.empty()); params->bytes_limit = bytes_limit_; + params->output_surface_id_for_returned_resources = + output_surface_id_from_last_draw_; params->ack.resources.swap(returned_resources_); if (root_scroll_offset_updated_by_browser_) { params->root_scroll_offset = root_scroll_offset_; diff --git a/content/browser/android/synchronous_compositor_host.h b/content/browser/android/synchronous_compositor_host.h index 90aafe5..6c0001b 100644 --- a/content/browser/android/synchronous_compositor_host.h +++ b/content/browser/android/synchronous_compositor_host.h @@ -33,7 +33,7 @@ class SynchronousCompositorHost : public SynchronousCompositorBase { ~SynchronousCompositorHost() override; // SynchronousCompositor overrides. - scoped_ptr DemandDrawHw( + SynchronousCompositor::Frame DemandDrawHw( const gfx::Size& surface_size, const gfx::Transform& transform, const gfx::Rect& viewport, @@ -41,7 +41,8 @@ class SynchronousCompositorHost : public SynchronousCompositorBase { const gfx::Rect& viewport_rect_for_tile_priority, const gfx::Transform& transform_for_tile_priority) override; bool DemandDrawSw(SkCanvas* canvas) override; - void ReturnResources(const cc::CompositorFrameAck& frame_ack) override; + void ReturnResources(uint32_t output_surface_id, + const cc::CompositorFrameAck& frame_ack) override; void SetMemoryPolicy(size_t bytes_limit) override; void DidChangeRootLayerScrollOffset( const gfx::ScrollOffset& root_offset) override; @@ -88,6 +89,7 @@ class SynchronousCompositorHost : public SynchronousCompositorBase { bool is_active_; size_t bytes_limit_; + uint32_t output_surface_id_from_last_draw_; cc::ReturnedResourceArray returned_resources_; scoped_ptr software_draw_shm_; diff --git a/content/common/android/sync_compositor_messages.cc b/content/common/android/sync_compositor_messages.cc index 638483e..1423091 100644 --- a/content/common/android/sync_compositor_messages.cc +++ b/content/common/android/sync_compositor_messages.cc @@ -8,6 +8,7 @@ namespace content { SyncCompositorCommonBrowserParams::SyncCompositorCommonBrowserParams() : bytes_limit(0u), + output_surface_id_for_returned_resources(0u), update_root_scroll_offset(false), begin_frame_source_paused(false) {} diff --git a/content/common/android/sync_compositor_messages.h b/content/common/android/sync_compositor_messages.h index 0ad1cf1..2e9af1a 100644 --- a/content/common/android/sync_compositor_messages.h +++ b/content/common/android/sync_compositor_messages.h @@ -26,6 +26,7 @@ struct SyncCompositorCommonBrowserParams { ~SyncCompositorCommonBrowserParams(); uint32_t bytes_limit; + uint32_t output_surface_id_for_returned_resources; cc::CompositorFrameAck ack; gfx::ScrollOffset root_scroll_offset; bool update_root_scroll_offset; @@ -96,6 +97,7 @@ struct SyncCompositorCommonRendererParams { IPC_STRUCT_TRAITS_BEGIN(content::SyncCompositorCommonBrowserParams) IPC_STRUCT_TRAITS_MEMBER(bytes_limit) + IPC_STRUCT_TRAITS_MEMBER(output_surface_id_for_returned_resources) IPC_STRUCT_TRAITS_MEMBER(ack) IPC_STRUCT_TRAITS_MEMBER(root_scroll_offset) IPC_STRUCT_TRAITS_MEMBER(update_root_scroll_offset) @@ -153,10 +155,11 @@ IPC_MESSAGE_ROUTED2(SyncCompositorMsg_ComputeScroll, content::SyncCompositorCommonBrowserParams, base::TimeTicks); -IPC_SYNC_MESSAGE_ROUTED2_2(SyncCompositorMsg_DemandDrawHw, +IPC_SYNC_MESSAGE_ROUTED2_3(SyncCompositorMsg_DemandDrawHw, content::SyncCompositorCommonBrowserParams, content::SyncCompositorDemandDrawHwParams, content::SyncCompositorCommonRendererParams, + uint32_t /* output_surface_id */, cc::CompositorFrame) IPC_SYNC_MESSAGE_ROUTED2_2(SyncCompositorMsg_SetSharedMemory, diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 945fe25..688b5ea 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -106,6 +106,7 @@ 'public/browser/android/download_controller_android.cc', 'public/browser/android/download_controller_android.h', 'public/browser/android/external_video_surface_container.h', + 'public/browser/android/synchronous_compositor.cc', 'public/browser/android/synchronous_compositor.h', 'public/browser/android/synchronous_compositor_client.h', 'public/browser/appcache_service.h', diff --git a/content/public/browser/android/synchronous_compositor.cc b/content/public/browser/android/synchronous_compositor.cc new file mode 100644 index 0000000..4e52b61 --- /dev/null +++ b/content/public/browser/android/synchronous_compositor.cc @@ -0,0 +1,27 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/public/browser/android/synchronous_compositor.h" + +#include + +#include "cc/output/compositor_frame.h" + +namespace content { + +SynchronousCompositor::Frame::Frame() : output_surface_id(0u) {} + +SynchronousCompositor::Frame::~Frame() {} + +SynchronousCompositor::Frame::Frame(Frame&& rhs) + : output_surface_id(rhs.output_surface_id), frame(std::move(rhs.frame)) {} + +SynchronousCompositor::Frame& SynchronousCompositor::Frame::operator=( + Frame&& rhs) { + output_surface_id = rhs.output_surface_id; + frame = std::move(rhs.frame); + return *this; +} + +} // namespace content diff --git a/content/public/browser/android/synchronous_compositor.h b/content/public/browser/android/synchronous_compositor.h index e0d09d8..431e1e1 100644 --- a/content/public/browser/android/synchronous_compositor.h +++ b/content/public/browser/android/synchronous_compositor.h @@ -47,9 +47,24 @@ class CONTENT_EXPORT SynchronousCompositor { static void SetGpuService( scoped_refptr service); + struct Frame { + Frame(); + ~Frame(); + + // Movable type. + Frame(Frame&& rhs); + Frame& operator=(Frame&& rhs); + + uint32_t output_surface_id; + scoped_ptr frame; + + private: + DISALLOW_COPY_AND_ASSIGN(Frame); + }; + // "On demand" hardware draw. The content is first clipped to |damage_area|, // then transformed through |transform|, and finally clipped to |view_size|. - virtual scoped_ptr DemandDrawHw( + virtual Frame DemandDrawHw( const gfx::Size& surface_size, const gfx::Transform& transform, const gfx::Rect& viewport, @@ -59,7 +74,8 @@ class CONTENT_EXPORT SynchronousCompositor { // For delegated rendering, return resources from parent compositor to this. // Note that all resources must be returned before ReleaseHwDraw. - virtual void ReturnResources(const cc::CompositorFrameAck& frame_ack) = 0; + virtual void ReturnResources(uint32_t output_surface_id, + const cc::CompositorFrameAck& frame_ack) = 0; // "On demand" SW draw, into the supplied canvas (observing the transform // and clip set there-in). diff --git a/content/public/test/test_synchronous_compositor_android.cc b/content/public/test/test_synchronous_compositor_android.cc index 9eff3ff..609cdf4 100644 --- a/content/public/test/test_synchronous_compositor_android.cc +++ b/content/public/test/test_synchronous_compositor_android.cc @@ -27,7 +27,7 @@ void TestSynchronousCompositor::SetClient(SynchronousCompositorClient* client) { } } -scoped_ptr TestSynchronousCompositor::DemandDrawHw( +SynchronousCompositor::Frame TestSynchronousCompositor::DemandDrawHw( const gfx::Size& surface_size, const gfx::Transform& transform, const gfx::Rect& viewport, @@ -37,14 +37,35 @@ scoped_ptr TestSynchronousCompositor::DemandDrawHw( return std::move(hardware_frame_); } +void TestSynchronousCompositor::ReturnResources( + uint32_t output_surface_id, + const cc::CompositorFrameAck& frame_ack) { + ReturnedResources returned_resources; + returned_resources.output_surface_id = output_surface_id; + returned_resources.resources = frame_ack.resources; + frame_ack_array_.push_back(returned_resources); +} + +void TestSynchronousCompositor::SwapReturnedResources(FrameAckArray* array) { + DCHECK(array); + frame_ack_array_.swap(*array); +} + bool TestSynchronousCompositor::DemandDrawSw(SkCanvas* canvas) { DCHECK(canvas); return true; } void TestSynchronousCompositor::SetHardwareFrame( + uint32_t output_surface_id, scoped_ptr frame) { - hardware_frame_ = std::move(frame); + hardware_frame_.output_surface_id = output_surface_id; + hardware_frame_.frame = std::move(frame); } +TestSynchronousCompositor::ReturnedResources::ReturnedResources() + : output_surface_id(0u) {} + +TestSynchronousCompositor::ReturnedResources::~ReturnedResources() {} + } // namespace content diff --git a/content/public/test/test_synchronous_compositor_android.h b/content/public/test/test_synchronous_compositor_android.h index b9f0c85..613eda6 100644 --- a/content/public/test/test_synchronous_compositor_android.h +++ b/content/public/test/test_synchronous_compositor_android.h @@ -7,8 +7,11 @@ #include +#include + #include "base/macros.h" #include "base/memory/scoped_ptr.h" +#include "cc/output/compositor_frame_ack.h" #include "content/public/browser/android/synchronous_compositor.h" #include "content/public/browser/android/synchronous_compositor_client.h" @@ -22,14 +25,15 @@ class CONTENT_EXPORT TestSynchronousCompositor : public SynchronousCompositor { void SetClient(SynchronousCompositorClient* client); // SynchronousCompositor overrides. - scoped_ptr DemandDrawHw( + SynchronousCompositor::Frame DemandDrawHw( const gfx::Size& surface_size, const gfx::Transform& transform, const gfx::Rect& viewport, const gfx::Rect& clip, const gfx::Rect& viewport_rect_for_tile_priority, const gfx::Transform& transform_for_tile_priority) override; - void ReturnResources(const cc::CompositorFrameAck& frame_ack) override {} + void ReturnResources(uint32_t output_surface_id, + const cc::CompositorFrameAck& frame_ack) override; bool DemandDrawSw(SkCanvas* canvas) override; void SetMemoryPolicy(size_t bytes_limit) override {} void DidChangeRootLayerScrollOffset( @@ -37,11 +41,23 @@ class CONTENT_EXPORT TestSynchronousCompositor : public SynchronousCompositor { void SetIsActive(bool is_active) override {} void OnComputeScroll(base::TimeTicks animate_time) override {} - void SetHardwareFrame(scoped_ptr frame); + void SetHardwareFrame(uint32_t output_surface_id, + scoped_ptr frame); + + struct ReturnedResources { + ReturnedResources(); + ~ReturnedResources(); + + uint32_t output_surface_id; + cc::ReturnedResourceArray resources; + }; + using FrameAckArray = std::vector; + void SwapReturnedResources(FrameAckArray* array); private: SynchronousCompositorClient* client_; - scoped_ptr hardware_frame_; + SynchronousCompositor::Frame hardware_frame_; + FrameAckArray frame_ack_array_; DISALLOW_COPY_AND_ASSIGN(TestSynchronousCompositor); }; diff --git a/content/renderer/android/synchronous_compositor_factory.h b/content/renderer/android/synchronous_compositor_factory.h index 18ada90..91185ffb 100644 --- a/content/renderer/android/synchronous_compositor_factory.h +++ b/content/renderer/android/synchronous_compositor_factory.h @@ -50,6 +50,7 @@ class SynchronousCompositorFactory { GetCompositorTaskRunner() = 0; virtual scoped_ptr CreateOutputSurface( int routing_id, + uint32_t output_surface_id, const scoped_refptr& frame_swap_message_queue, const scoped_refptr& onscreen_context, const scoped_refptr& worker_context) = 0; diff --git a/content/renderer/android/synchronous_compositor_output_surface.cc b/content/renderer/android/synchronous_compositor_output_surface.cc index 23f67d5..5609735 100644 --- a/content/renderer/android/synchronous_compositor_output_surface.cc +++ b/content/renderer/android/synchronous_compositor_output_surface.cc @@ -64,6 +64,7 @@ SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface( const scoped_refptr& context_provider, const scoped_refptr& worker_context_provider, int routing_id, + uint32_t output_surface_id, SynchronousCompositorRegistry* registry, scoped_refptr frame_swap_message_queue) : cc::OutputSurface( @@ -71,6 +72,7 @@ SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface( worker_context_provider, scoped_ptr(new SoftwareDevice(this))), routing_id_(routing_id), + output_surface_id_(output_surface_id), registry_(registry), registered_(false), sync_client_(nullptr), @@ -133,7 +135,7 @@ void SynchronousCompositorOutputSurface::SwapBuffers( DCHECK(CalledOnValidThread()); DCHECK(sync_client_); if (!fallback_tick_running_) - sync_client_->SwapBuffers(frame); + sync_client_->SwapBuffers(output_surface_id_, frame); client_->DidSwapBuffers(); did_swap_ = true; } @@ -227,8 +229,10 @@ void SynchronousCompositorOutputSurface::InvokeComposite( } void SynchronousCompositorOutputSurface::ReturnResources( + uint32_t output_surface_id, const cc::CompositorFrameAck& frame_ack) { - ReclaimResources(&frame_ack); + if (output_surface_id_ == output_surface_id) + ReclaimResources(&frame_ack); } void SynchronousCompositorOutputSurface::SetMemoryPolicy(size_t bytes_limit) { diff --git a/content/renderer/android/synchronous_compositor_output_surface.h b/content/renderer/android/synchronous_compositor_output_surface.h index 7fd8127..d373146 100644 --- a/content/renderer/android/synchronous_compositor_output_surface.h +++ b/content/renderer/android/synchronous_compositor_output_surface.h @@ -40,7 +40,8 @@ class WebGraphicsContext3DCommandBufferImpl; class SynchronousCompositorOutputSurfaceClient { public: virtual void Invalidate() = 0; - virtual void SwapBuffers(cc::CompositorFrame* frame) = 0; + virtual void SwapBuffers(uint32_t output_surface_id, + cc::CompositorFrame* frame) = 0; protected: virtual ~SynchronousCompositorOutputSurfaceClient() {} @@ -61,6 +62,7 @@ class SynchronousCompositorOutputSurface const scoped_refptr& context_provider, const scoped_refptr& worker_context_provider, int routing_id, + uint32_t output_surface_id, SynchronousCompositorRegistry* registry, scoped_refptr frame_swap_message_queue); ~SynchronousCompositorOutputSurface() override; @@ -84,7 +86,8 @@ class SynchronousCompositorOutputSurface const gfx::Rect& clip, const gfx::Rect& viewport_rect_for_tile_priority, const gfx::Transform& transform_for_tile_priority); - void ReturnResources(const cc::CompositorFrameAck& frame_ack); + void ReturnResources(uint32_t output_surface_id, + const cc::CompositorFrameAck& frame_ack); void DemandDrawSw(SkCanvas* canvas); void SetMemoryPolicy(size_t bytes_limit); void SetTreeActivationCallback(const base::Closure& callback); @@ -108,6 +111,7 @@ class SynchronousCompositorOutputSurface void FallbackTickFired(); const int routing_id_; + const uint32_t output_surface_id_; SynchronousCompositorRegistry* const registry_; // unowned bool registered_; diff --git a/content/renderer/android/synchronous_compositor_proxy.cc b/content/renderer/android/synchronous_compositor_proxy.cc index b985949..820b577 100644 --- a/content/renderer/android/synchronous_compositor_proxy.cc +++ b/content/renderer/android/synchronous_compositor_proxy.cc @@ -218,30 +218,30 @@ void SynchronousCompositorProxy::DemandDrawHw( if (inside_receive_) { // Did not swap. cc::CompositorFrame empty_frame; - SendDemandDrawHwReply(&empty_frame, reply_message); + SendDemandDrawHwReply(&empty_frame, 0u, reply_message); inside_receive_ = false; } else { DeliverMessages(); } } -void SynchronousCompositorProxy::SwapBuffersHw(cc::CompositorFrame* frame) { +void SynchronousCompositorProxy::SwapBuffersHw(uint32_t output_surface_id, + cc::CompositorFrame* frame) { DCHECK(inside_receive_); DCHECK(hardware_draw_reply_); DCHECK(frame); - SendDemandDrawHwReply(frame, hardware_draw_reply_); + SendDemandDrawHwReply(frame, output_surface_id, hardware_draw_reply_); inside_receive_ = false; } void SynchronousCompositorProxy::SendDemandDrawHwReply( cc::CompositorFrame* frame, + uint32_t output_surface_id, IPC::Message* reply_message) { SyncCompositorCommonRendererParams common_renderer_params; PopulateCommonParams(&common_renderer_params); - // Not using WriteParams because cc::CompositorFrame is not copy-able. - IPC::ParamTraits::Write( - reply_message, common_renderer_params); - IPC::ParamTraits::Write(reply_message, *frame); + SyncCompositorMsg_DemandDrawHw::WriteReplyParams( + reply_message, common_renderer_params, output_surface_id, *frame); Send(reply_message); } @@ -358,19 +358,17 @@ void SynchronousCompositorProxy::SendDemandDrawSwReply( IPC::Message* reply_message) { SyncCompositorCommonRendererParams common_renderer_params; PopulateCommonParams(&common_renderer_params); - // Not using WriteParams because cc::CompositorFrame is not copy-able. - IPC::ParamTraits::Write(reply_message, success); - IPC::ParamTraits::Write( - reply_message, common_renderer_params); - IPC::ParamTraits::Write(reply_message, *frame); + SyncCompositorMsg_DemandDrawSw::WriteReplyParams( + reply_message, success, common_renderer_params, *frame); Send(reply_message); } -void SynchronousCompositorProxy::SwapBuffers(cc::CompositorFrame* frame) { +void SynchronousCompositorProxy::SwapBuffers(uint32_t output_surface_id, + cc::CompositorFrame* frame) { DCHECK(hardware_draw_reply_ || software_draw_reply_); DCHECK(!(hardware_draw_reply_ && software_draw_reply_)); if (hardware_draw_reply_) { - SwapBuffersHw(frame); + SwapBuffersHw(output_surface_id, frame); } else if (software_draw_reply_) { SwapBuffersSw(frame); } @@ -409,7 +407,9 @@ void SynchronousCompositorProxy::ProcessCommonParams( begin_frame_source_->SetBeginFrameSourcePaused( common_params.begin_frame_source_paused); if (!common_params.ack.resources.empty()) { - output_surface_->ReturnResources(common_params.ack); + output_surface_->ReturnResources( + common_params.output_surface_id_for_returned_resources, + common_params.ack); } } diff --git a/content/renderer/android/synchronous_compositor_proxy.h b/content/renderer/android/synchronous_compositor_proxy.h index 534e7db..a07e7d8 100644 --- a/content/renderer/android/synchronous_compositor_proxy.h +++ b/content/renderer/android/synchronous_compositor_proxy.h @@ -72,7 +72,8 @@ class SynchronousCompositorProxy // SynchronousCompositorOutputSurfaceClient overrides. void Invalidate() override; - void SwapBuffers(cc::CompositorFrame* frame) override; + void SwapBuffers(uint32_t output_surface_id, + cc::CompositorFrame* frame) override; void OnMessageReceived(const IPC::Message& message); bool Send(IPC::Message* message); @@ -109,8 +110,9 @@ class SynchronousCompositorProxy const SyncCompositorDemandDrawSwParams& params, IPC::Message* reply_message); - void SwapBuffersHw(cc::CompositorFrame* frame); + void SwapBuffersHw(uint32_t output_surface_id, cc::CompositorFrame* frame); void SendDemandDrawHwReply(cc::CompositorFrame* frame, + uint32_t output_surface_id, IPC::Message* reply_message); void DoDemandDrawSw(const SyncCompositorDemandDrawSwParams& params); void SwapBuffersSw(cc::CompositorFrame* frame); diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index a4b9d63..b8337c6 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -752,14 +752,16 @@ scoped_ptr RenderWidget::CreateOutputSurface(bool fallback) { #if defined(OS_ANDROID) if (SynchronousCompositorFactory* factory = SynchronousCompositorFactory::GetInstance()) { + uint32_t output_surface_id = next_output_surface_id_++; return factory->CreateOutputSurface( - routing_id(), frame_swap_message_queue_, context_provider, - worker_context_provider); + routing_id(), output_surface_id, frame_swap_message_queue_, + context_provider, worker_context_provider); } else if (RenderThreadImpl::current()->sync_compositor_message_filter()) { + uint32_t output_surface_id = next_output_surface_id_++; return make_scoped_ptr(new SynchronousCompositorOutputSurface( context_provider, worker_context_provider, routing_id(), - content::RenderThreadImpl::current() - ->sync_compositor_message_filter(), + output_surface_id, content::RenderThreadImpl::current() + ->sync_compositor_message_filter(), frame_swap_message_queue_)); } #endif -- cgit v1.1