summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorboliu <boliu@chromium.org>2016-03-22 12:33:17 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-22 19:34:15 +0000
commitf4e57485631dc4c3beaa87de398975cab87fdc32 (patch)
treedafb5c772d42afba6404d85ece393a48d8eb9cdf
parentfc7f861f2ef3d880e88efbdab8366ff86d1dcf36 (diff)
downloadchromium_src-f4e57485631dc4c3beaa87de398975cab87fdc32.zip
chromium_src-f4e57485631dc4c3beaa87de398975cab87fdc32.tar.gz
chromium_src-f4e57485631dc4c3beaa87de398975cab87fdc32.tar.bz2
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<id, resource list>, 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}
-rw-r--r--android_webview/browser/browser_view_renderer.cc23
-rw-r--r--android_webview/browser/browser_view_renderer_unittest.cc99
-rw-r--r--android_webview/browser/child_frame.cc6
-rw-r--r--android_webview/browser/child_frame.h4
-rw-r--r--android_webview/browser/hardware_renderer.cc23
-rw-r--r--android_webview/browser/hardware_renderer.h7
-rw-r--r--android_webview/browser/shared_renderer_state.cc20
-rw-r--r--android_webview/browser/shared_renderer_state.h18
-rw-r--r--android_webview/browser/test/rendering_test.cc11
-rw-r--r--android_webview/browser/test/rendering_test.h7
-rw-r--r--content/browser/android/in_process/synchronous_compositor_factory_impl.cc3
-rw-r--r--content/browser/android/in_process/synchronous_compositor_factory_impl.h1
-rw-r--r--content/browser/android/in_process/synchronous_compositor_impl.cc31
-rw-r--r--content/browser/android/in_process/synchronous_compositor_impl.h10
-rw-r--r--content/browser/android/synchronous_compositor_host.cc30
-rw-r--r--content/browser/android/synchronous_compositor_host.h6
-rw-r--r--content/common/android/sync_compositor_messages.cc1
-rw-r--r--content/common/android/sync_compositor_messages.h5
-rw-r--r--content/content_browser.gypi1
-rw-r--r--content/public/browser/android/synchronous_compositor.cc27
-rw-r--r--content/public/browser/android/synchronous_compositor.h20
-rw-r--r--content/public/test/test_synchronous_compositor_android.cc25
-rw-r--r--content/public/test/test_synchronous_compositor_android.h24
-rw-r--r--content/renderer/android/synchronous_compositor_factory.h1
-rw-r--r--content/renderer/android/synchronous_compositor_output_surface.cc8
-rw-r--r--content/renderer/android/synchronous_compositor_output_surface.h8
-rw-r--r--content/renderer/android/synchronous_compositor_proxy.cc30
-rw-r--r--content/renderer/android/synchronous_compositor_proxy.h6
-rw-r--r--content/renderer/render_widget.cc10
29 files changed, 365 insertions, 100 deletions
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<cc::CompositorFrame> 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<ChildFrame> 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<uint32_t, cc::ReturnedResourceArray> 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 <map>
+#include <queue>
+#include <utility>
+
#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<content::SynchronousCompositor::Frame> frames_;
+ uint32_t last_output_surface_id_;
+ std::map<cc::ResourceId, int> 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<cc::CompositorFrame> frame,
+ChildFrame::ChildFrame(uint32_t output_surface_id,
+ scoped_ptr<cc::CompositorFrame> 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<cc::CompositorFrame> frame,
+ ChildFrame(uint32_t output_surface_id,
+ scoped_ptr<cc::CompositorFrame> 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<cc::CompositorFrame> 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<uint32_t, cc::ReturnedResourceArray>* 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<uint32_t, ReturnedResources>;
+
SharedRendererState(
const scoped_refptr<base::SingleThreadTaskRunner>& ui_loop,
BrowserViewRenderer* browser_view_renderer);
@@ -48,8 +57,7 @@ class SharedRendererState {
void InitializeHardwareDrawIfNeededOnUI();
void ReleaseHardwareDrawIfNeededOnUI();
ParentCompositorDrawConstraints GetParentDrawConstraintsOnUI() const;
- void SwapReturnedResourcesOnUI(
- std::map<uint32_t, cc::ReturnedResourceArray>* returned_resource_map);
+ void SwapReturnedResourcesOnUI(ReturnedResourcesMap* returned_resource_map);
bool ReturnedResourcesEmptyOnUI() const;
scoped_ptr<ChildFrame> 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<ChildFrame> 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<uint32_t, cc::ReturnedResourceArray> returned_resources_map_;
+ ReturnedResourcesMap returned_resources_map_;
base::Closure request_draw_gl_closure_;
base::WeakPtrFactory<SharedRendererState> 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<cc::CompositorFrame> RenderingTest::ConstructEmptyFrame() {
scoped_ptr<cc::CompositorFrame> compositor_frame(new cc::CompositorFrame);
scoped_ptr<cc::DelegatedFrameData> frame(new cc::DelegatedFrameData);
scoped_ptr<cc::RenderPass> 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<cc::CompositorFrame> ConstructEmptyFrame();
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
scoped_ptr<BrowserViewRenderer> 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<cc::OutputSurface>
SynchronousCompositorFactoryImpl::CreateOutputSurface(
int routing_id,
+ uint32_t output_surface_id,
const scoped_refptr<FrameSwapMessageQueue>& frame_swap_message_queue,
const scoped_refptr<cc::ContextProvider>& onscreen_context,
const scoped_refptr<cc::ContextProvider>& 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<cc::OutputSurface> CreateOutputSurface(
int routing_id,
+ uint32_t output_surface_id,
const scoped_refptr<FrameSwapMessageQueue>& frame_swap_message_queue,
const scoped_refptr<cc::ContextProvider>& onscreen_context,
const scoped_refptr<cc::ContextProvider>& 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<cc::CompositorFrame> 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<cc::CompositorFrame> 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<cc::CompositorFrame> 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<cc::CompositorFrame> frame_holder_;
+ SynchronousCompositor::Frame frame_holder_;
base::WeakPtrFactory<SynchronousCompositorImpl> 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<cc::CompositorFrame> 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<cc::CompositorFrame> SynchronousCompositorHost::DemandDrawHw(
SyncCompositorDemandDrawHwParams params(surface_size, transform, viewport,
clip, viewport_rect_for_tile_priority,
transform_for_tile_priority);
- scoped_ptr<cc::CompositorFrame> 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<cc::CompositorFrame> 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<SharedMemoryWithSize> 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 <utility>
+
+#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<gpu::InProcessCommandBuffer::Service> service);
+ struct Frame {
+ Frame();
+ ~Frame();
+
+ // Movable type.
+ Frame(Frame&& rhs);
+ Frame& operator=(Frame&& rhs);
+
+ uint32_t output_surface_id;
+ scoped_ptr<cc::CompositorFrame> 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<cc::CompositorFrame> 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<cc::CompositorFrame> 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<cc::CompositorFrame> 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<cc::CompositorFrame> 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 <stddef.h>
+#include <vector>
+
#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<cc::CompositorFrame> 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<cc::CompositorFrame> frame);
+ void SetHardwareFrame(uint32_t output_surface_id,
+ scoped_ptr<cc::CompositorFrame> frame);
+
+ struct ReturnedResources {
+ ReturnedResources();
+ ~ReturnedResources();
+
+ uint32_t output_surface_id;
+ cc::ReturnedResourceArray resources;
+ };
+ using FrameAckArray = std::vector<ReturnedResources>;
+ void SwapReturnedResources(FrameAckArray* array);
private:
SynchronousCompositorClient* client_;
- scoped_ptr<cc::CompositorFrame> 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<cc::OutputSurface> CreateOutputSurface(
int routing_id,
+ uint32_t output_surface_id,
const scoped_refptr<FrameSwapMessageQueue>& frame_swap_message_queue,
const scoped_refptr<cc::ContextProvider>& onscreen_context,
const scoped_refptr<cc::ContextProvider>& 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<cc::ContextProvider>& context_provider,
const scoped_refptr<cc::ContextProvider>& worker_context_provider,
int routing_id,
+ uint32_t output_surface_id,
SynchronousCompositorRegistry* registry,
scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue)
: cc::OutputSurface(
@@ -71,6 +72,7 @@ SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
worker_context_provider,
scoped_ptr<cc::SoftwareOutputDevice>(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<cc::ContextProvider>& context_provider,
const scoped_refptr<cc::ContextProvider>& worker_context_provider,
int routing_id,
+ uint32_t output_surface_id,
SynchronousCompositorRegistry* registry,
scoped_refptr<FrameSwapMessageQueue> 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<SyncCompositorCommonRendererParams>::Write(
- reply_message, common_renderer_params);
- IPC::ParamTraits<cc::CompositorFrame>::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<bool>::Write(reply_message, success);
- IPC::ParamTraits<SyncCompositorCommonRendererParams>::Write(
- reply_message, common_renderer_params);
- IPC::ParamTraits<cc::CompositorFrame>::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<cc::OutputSurface> 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