cc: Introduce LayerContext
This introduces new LayerContext and LayerContextClient abstractions in
cc as well as their corresponding mojom interfaces in Viz. These types
sit between a client-side LayerTreeHost and a corresponding
LayerTreeHostImpl which may reside in another process. They will be used
to experiment with GPU-side layer trees.
This CL only introduces minimal boilerplate and plumbing for a client to
construct a new client-side VizLayerContext over an established
CompositorFrameSink endpoint, to control a GPU-side LayerTreeHost owned
by that sink within Viz.
Test coverage and actual frame production from a LayerContext are done
in a follow-up CL.
Bug: 1431762
Change-Id: I86e9150aa034fe77300036816c8e2c5ae3999c55
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4418567
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
Auto-Submit: Ken Rockot <rockot@google.com>
Reviewed-by: Jonathan Ross <jonross@chromium.org>
Reviewed-by: Will Harris <wfh@chromium.org>
Code-Coverage: Findit <findit-for-me@appspot.gserviceaccount.com>
Commit-Queue: Alexander Cooper <alcooper@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1130132}
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 05e11fe..d59e047 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -366,6 +366,8 @@
"trees/latency_info_swap_promise.h",
"trees/latency_info_swap_promise_monitor.cc",
"trees/latency_info_swap_promise_monitor.h",
+ "trees/layer_context.h",
+ "trees/layer_context_client.h",
"trees/layer_tree_frame_sink.cc",
"trees/layer_tree_frame_sink.h",
"trees/layer_tree_frame_sink_client.h",
@@ -381,6 +383,8 @@
"trees/layer_tree_mutator.h",
"trees/layer_tree_settings.cc",
"trees/layer_tree_settings.h",
+ "trees/local_layer_context.cc",
+ "trees/local_layer_context.h",
"trees/managed_memory_policy.cc",
"trees/managed_memory_policy.h",
"trees/mobile_optimized_viewport_util.cc",
diff --git a/cc/mojo_embedder/BUILD.gn b/cc/mojo_embedder/BUILD.gn
index 32c65d2..152c647 100644
--- a/cc/mojo_embedder/BUILD.gn
+++ b/cc/mojo_embedder/BUILD.gn
@@ -9,6 +9,8 @@
sources = [
"async_layer_tree_frame_sink.cc",
"async_layer_tree_frame_sink.h",
+ "viz_layer_context.cc",
+ "viz_layer_context.h",
]
defines = [ "CC_MOJO_EMBEDDER_IMPLEMENTATION" ]
diff --git a/cc/mojo_embedder/viz_layer_context.cc b/cc/mojo_embedder/viz_layer_context.cc
new file mode 100644
index 0000000..8b74d2cab
--- /dev/null
+++ b/cc/mojo_embedder/viz_layer_context.cc
@@ -0,0 +1,49 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/mojo_embedder/viz_layer_context.h"
+
+#include <utility>
+
+#include "base/check.h"
+#include "cc/trees/layer_context_client.h"
+#include "services/viz/public/mojom/compositing/layer_context.mojom.h"
+
+namespace cc::mojo_embedder {
+
+VizLayerContext::VizLayerContext(viz::mojom::CompositorFrameSink& frame_sink,
+ cc::LayerContextClient* client)
+ : client_(client) {
+ CHECK(client_);
+ auto context = viz::mojom::PendingLayerContext::New();
+ context->receiver = service_.BindNewEndpointAndPassReceiver();
+ context->client = client_receiver_.BindNewEndpointAndPassRemote();
+ frame_sink.BindLayerContext(std::move(context));
+}
+
+VizLayerContext::~VizLayerContext() = default;
+
+void VizLayerContext::SetTargetLocalSurfaceId(const viz::LocalSurfaceId& id) {
+ service_->SetTargetLocalSurfaceId(id);
+}
+
+void VizLayerContext::SetVisible(bool visible) {
+ service_->SetVisible(visible);
+}
+
+void VizLayerContext::Commit(const CommitState& state) {
+ // TODO(https://crbug.com/1431762): Push actual commit data. For now we only
+ // update basic parameters required for any LayerTreeHost drawing.
+ auto update = viz::mojom::LayerTreeUpdate::New();
+ update->device_viewport = state.device_viewport_rect;
+ update->device_scale_factor = state.device_scale_factor;
+ update->local_surface_id_from_parent = state.local_surface_id_from_parent;
+ service_->Commit(std::move(update));
+}
+
+void VizLayerContext::OnRequestCommitForFrame(const viz::BeginFrameArgs& args) {
+ client_->OnRequestCommitForFrame(args);
+}
+
+} // namespace cc::mojo_embedder
diff --git a/cc/mojo_embedder/viz_layer_context.h b/cc/mojo_embedder/viz_layer_context.h
new file mode 100644
index 0000000..dd24603
--- /dev/null
+++ b/cc/mojo_embedder/viz_layer_context.h
@@ -0,0 +1,51 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_MOJO_EMBEDDER_VIZ_LAYER_CONTEXT_H_
+#define CC_MOJO_EMBEDDER_VIZ_LAYER_CONTEXT_H_
+
+#include "base/memory/raw_ptr.h"
+#include "cc/mojo_embedder/mojo_embedder_export.h"
+#include "cc/trees/layer_context.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h"
+#include "services/viz/public/mojom/compositing/layer_context.mojom.h"
+
+namespace cc {
+class LayerContextClient;
+} // namespace cc
+
+namespace cc::mojo_embedder {
+
+// A client-side implementation of LayerContext which runs over a Mojo
+// connection to a GPU-side LayerContext backend within Viz.
+class CC_MOJO_EMBEDDER_EXPORT VizLayerContext
+ : public LayerContext,
+ public viz::mojom::LayerContextClient {
+ public:
+ // Constructs a VizLayerContext which submits content on behalf of
+ // `frame_sink`. `client` must outlive this object.
+ VizLayerContext(viz::mojom::CompositorFrameSink& frame_sink,
+ cc::LayerContextClient* client);
+ ~VizLayerContext() override;
+
+ // LayerContext:
+ void SetTargetLocalSurfaceId(const viz::LocalSurfaceId& id) override;
+ void SetVisible(bool visible) override;
+ void Commit(const CommitState& state) override;
+
+ // viz::mojom::LayerContextClient:
+ void OnRequestCommitForFrame(const viz::BeginFrameArgs& args) override;
+
+ private:
+ raw_ptr<cc::LayerContextClient> client_;
+ mojo::AssociatedReceiver<viz::mojom::LayerContextClient> client_receiver_{
+ this};
+ mojo::AssociatedRemote<viz::mojom::LayerContext> service_;
+};
+
+} // namespace cc::mojo_embedder
+
+#endif // CC_MOJO_EMBEDDER_VIZ_LAYER_CONTEXT_H_
diff --git a/cc/slim/test_frame_sink_impl.cc b/cc/slim/test_frame_sink_impl.cc
index 84f9e7a7..af27c9d 100644
--- a/cc/slim/test_frame_sink_impl.cc
+++ b/cc/slim/test_frame_sink_impl.cc
@@ -17,6 +17,7 @@
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h"
+#include "services/viz/public/mojom/compositing/layer_context.mojom.h"
namespace cc::slim {
@@ -49,6 +50,7 @@
void DidDeleteSharedBitmap(const gpu::Mailbox& id) override {}
void InitializeCompositorFrameSinkType(
viz::mojom::CompositorFrameSinkType type) override {}
+ void BindLayerContext(viz::mojom::PendingLayerContextPtr context) override {}
#if BUILDFLAG(IS_ANDROID)
void SetThreadIds(const std::vector<int32_t>& thread_ids) override {}
#endif
diff --git a/cc/trees/layer_context.h b/cc/trees/layer_context.h
new file mode 100644
index 0000000..95726a1
--- /dev/null
+++ b/cc/trees/layer_context.h
@@ -0,0 +1,35 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_TREES_LAYER_CONTEXT_H_
+#define CC_TREES_LAYER_CONTEXT_H_
+
+#include "cc/cc_export.h"
+#include "cc/trees/commit_state.h"
+#include "components/viz/common/surfaces/local_surface_id.h"
+
+namespace cc {
+
+// LayerContext provides an opaque interface through which a LayerTreeHost can
+// control a backing LayerTreeHostImpl, potentially on another thread or in
+// another process.
+class CC_EXPORT LayerContext {
+ public:
+ virtual ~LayerContext() = default;
+
+ // Indicates that a new LocalSurfaceId has been set for the frame sink hosting
+ // this tree.
+ virtual void SetTargetLocalSurfaceId(const viz::LocalSurfaceId& id) = 0;
+
+ // Globally controls the visibility of layers within the tree.
+ virtual void SetVisible(bool visible) = 0;
+
+ // Flushes pending updates to the backing LayerTreeHostImpl. `state`
+ // represents the pending CommitState for the client-side LayerTreeHost.
+ virtual void Commit(const CommitState& state) = 0;
+};
+
+} // namespace cc
+
+#endif // CC_TREES_LAYER_CONTEXT_H_
diff --git a/cc/trees/layer_context_client.h b/cc/trees/layer_context_client.h
new file mode 100644
index 0000000..2514c245
--- /dev/null
+++ b/cc/trees/layer_context_client.h
@@ -0,0 +1,27 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_TREES_LAYER_CONTEXT_CLIENT_H_
+#define CC_TREES_LAYER_CONTEXT_CLIENT_H_
+
+#include "cc/cc_export.h"
+#include "components/viz/common/frame_sinks/begin_frame_args.h"
+
+namespace cc {
+
+// Interface used by LayerContext to push requests to its corresponding
+// client-side LayerTreeHost.
+class CC_EXPORT LayerContextClient {
+ public:
+ virtual ~LayerContextClient() = default;
+
+ // Indicates that the compositor will produce a new display frame soon and
+ // that the client should commit a new layer tree ASAP. `args` correspond to
+ // the impending display frame that the compositor wants to produce.
+ virtual void OnRequestCommitForFrame(const viz::BeginFrameArgs& args) = 0;
+};
+
+} // namespace cc
+
+#endif // CC_TREES_LAYER_CONTEXT_CLIENT_H_
diff --git a/cc/trees/local_layer_context.cc b/cc/trees/local_layer_context.cc
new file mode 100644
index 0000000..0238c079
--- /dev/null
+++ b/cc/trees/local_layer_context.cc
@@ -0,0 +1,151 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/local_layer_context.h"
+
+#include <memory>
+
+#include "base/task/single_thread_task_runner.h"
+#include "cc/raster/categorized_worker_pool.h"
+#include "cc/trees/commit_state.h"
+#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/layer_tree_settings.h"
+
+namespace cc {
+
+namespace {
+
+LayerListSettings CreateSettings() {
+ LayerListSettings settings;
+ settings.commit_to_active_tree = true;
+ return settings;
+}
+
+LayerTreeHost::InitParams CreateInitParams(LocalLayerContext& context,
+ const LayerListSettings& settings,
+ MutatorHost* mutator_host) {
+ LayerTreeHost::InitParams params;
+ params.client = &context;
+ params.settings = &settings;
+ params.task_graph_runner = CategorizedWorkerPool::GetOrCreate();
+ params.main_task_runner = base::SingleThreadTaskRunner::GetCurrentDefault();
+ params.mutator_host = mutator_host;
+ return params;
+}
+
+} // namespace
+
+LocalLayerContext::LocalLayerContext(MutatorHost* mutator_host)
+ : mutator_host_(mutator_host),
+ layer_list_settings_(CreateSettings()),
+ host_(LayerTreeHost::CreateSingleThreaded(
+ this,
+ CreateInitParams(*this, layer_list_settings_, mutator_host_))) {}
+
+LocalLayerContext::~LocalLayerContext() = default;
+
+void LocalLayerContext::SetTargetLocalSurfaceId(const viz::LocalSurfaceId& id) {
+ host_->SetTargetLocalSurfaceId(id);
+}
+
+void LocalLayerContext::SetVisible(bool visible) {
+ host_->SetVisible(visible);
+}
+
+void LocalLayerContext::Commit(const CommitState& state) {
+ // TODO(https://crbug.com/1431762): Actually update the tree contents.
+ host_->SetViewportRectAndScale(state.device_viewport_rect,
+ state.device_scale_factor,
+ state.local_surface_id_from_parent);
+}
+
+void LocalLayerContext::WillBeginMainFrame() {}
+
+void LocalLayerContext::DidBeginMainFrame() {}
+
+void LocalLayerContext::WillUpdateLayers() {}
+
+void LocalLayerContext::DidUpdateLayers() {}
+
+void LocalLayerContext::BeginMainFrame(const viz::BeginFrameArgs& args) {}
+
+void LocalLayerContext::OnDeferMainFrameUpdatesChanged(bool) {}
+
+void LocalLayerContext::OnDeferCommitsChanged(
+ bool defer_status,
+ PaintHoldingReason reason,
+ absl::optional<PaintHoldingCommitTrigger> trigger) {}
+
+void LocalLayerContext::OnCommitRequested() {}
+
+void LocalLayerContext::BeginMainFrameNotExpectedSoon() {}
+
+void LocalLayerContext::BeginMainFrameNotExpectedUntil(base::TimeTicks time) {}
+
+void LocalLayerContext::UpdateLayerTreeHost() {}
+
+void LocalLayerContext::ApplyViewportChanges(
+ const ApplyViewportChangesArgs& args) {}
+
+void LocalLayerContext::UpdateCompositorScrollState(
+ const CompositorCommitData& commit_data) {}
+
+void LocalLayerContext::RequestNewLayerTreeFrameSink() {}
+
+void LocalLayerContext::DidInitializeLayerTreeFrameSink() {}
+
+void LocalLayerContext::DidFailToInitializeLayerTreeFrameSink() {}
+
+void LocalLayerContext::WillCommit(const CommitState&) {}
+
+void LocalLayerContext::DidCommit(base::TimeTicks commit_start_time,
+ base::TimeTicks commit_finish_time) {}
+
+void LocalLayerContext::DidCommitAndDrawFrame() {}
+
+void LocalLayerContext::DidReceiveCompositorFrameAck() {}
+
+void LocalLayerContext::DidCompletePageScaleAnimation() {}
+
+void LocalLayerContext::DidPresentCompositorFrame(
+ uint32_t frame_token,
+ const gfx::PresentationFeedback& feedback) {}
+
+void LocalLayerContext::RecordStartOfFrameMetrics() {}
+
+void LocalLayerContext::RecordEndOfFrameMetrics(
+ base::TimeTicks frame_begin_time,
+ ActiveFrameSequenceTrackers trackers) {}
+
+std::unique_ptr<BeginMainFrameMetrics>
+LocalLayerContext::GetBeginMainFrameMetrics() {
+ return nullptr;
+}
+
+std::unique_ptr<WebVitalMetrics> LocalLayerContext::GetWebVitalMetrics() {
+ return nullptr;
+}
+
+void LocalLayerContext::NotifyThroughputTrackerResults(
+ CustomTrackerResults results) {}
+
+void LocalLayerContext::DidObserveFirstScrollDelay(
+ base::TimeDelta first_scroll_delay,
+ base::TimeTicks first_scroll_timestamp) {}
+
+void LocalLayerContext::RunPaintBenchmark(int repeat_count,
+ PaintBenchmarkResult& result) {}
+
+void LocalLayerContext::ScheduleAnimationForWebTests() {}
+
+void LocalLayerContext::FrameIntervalUpdated(base::TimeDelta interval) {}
+
+void LocalLayerContext::DidSubmitCompositorFrame() {}
+
+void LocalLayerContext::DidLoseLayerTreeFrameSink() {}
+
+void LocalLayerContext::FrameSinksToThrottleUpdated(
+ const base::flat_set<viz::FrameSinkId>& ids) {}
+
+} // namespace cc
diff --git a/cc/trees/local_layer_context.h b/cc/trees/local_layer_context.h
new file mode 100644
index 0000000..106a711
--- /dev/null
+++ b/cc/trees/local_layer_context.h
@@ -0,0 +1,98 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_TREES_LOCAL_LAYER_CONTEXT_H_
+#define CC_TREES_LOCAL_LAYER_CONTEXT_H_
+
+#include <memory>
+
+#include "base/memory/raw_ptr.h"
+#include "cc/cc_export.h"
+#include "cc/trees/layer_context.h"
+#include "cc/trees/layer_tree_host_client.h"
+#include "cc/trees/layer_tree_host_single_thread_client.h"
+#include "cc/trees/layer_tree_settings.h"
+
+namespace cc {
+
+class LayerTreeHost;
+class MutatorHost;
+
+// LocalLayerContext owns and manages a LayerTreeHostImpl to be controlled
+// indirectly by a client's corresponding LayerTreeHost.
+class CC_EXPORT LocalLayerContext : public LayerContext,
+ public LayerTreeHostClient,
+ public LayerTreeHostSingleThreadClient {
+ public:
+ explicit LocalLayerContext(MutatorHost* mutator_host);
+ ~LocalLayerContext() override;
+
+ // LayerContext:
+ void SetTargetLocalSurfaceId(const viz::LocalSurfaceId& id) override;
+ void SetVisible(bool visible) override;
+ void Commit(const CommitState& state) override;
+
+ // LayerTreeHostClient:
+ void WillBeginMainFrame() override;
+ void DidBeginMainFrame() override;
+ void WillUpdateLayers() override;
+ void DidUpdateLayers() override;
+ void BeginMainFrame(const viz::BeginFrameArgs& args) override;
+ void OnDeferMainFrameUpdatesChanged(bool) override;
+ void OnDeferCommitsChanged(
+ bool defer_status,
+ PaintHoldingReason reason,
+ absl::optional<PaintHoldingCommitTrigger> trigger) override;
+ void OnCommitRequested() override;
+ void BeginMainFrameNotExpectedSoon() override;
+ void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override;
+ void UpdateLayerTreeHost() override;
+ void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override;
+ void UpdateCompositorScrollState(
+ const CompositorCommitData& commit_data) override;
+ void RequestNewLayerTreeFrameSink() override;
+ void DidInitializeLayerTreeFrameSink() override;
+ void DidFailToInitializeLayerTreeFrameSink() override;
+ void WillCommit(const CommitState&) override;
+ void DidCommit(base::TimeTicks commit_start_time,
+ base::TimeTicks commit_finish_time) override;
+ void DidCommitAndDrawFrame() override;
+ void DidReceiveCompositorFrameAck() override;
+ void DidCompletePageScaleAnimation() override;
+ void DidPresentCompositorFrame(
+ uint32_t frame_token,
+ const gfx::PresentationFeedback& feedback) override;
+ void RecordStartOfFrameMetrics() override;
+ void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time,
+ ActiveFrameSequenceTrackers trackers) override;
+ std::unique_ptr<BeginMainFrameMetrics> GetBeginMainFrameMetrics() override;
+ std::unique_ptr<WebVitalMetrics> GetWebVitalMetrics() override;
+ void NotifyThroughputTrackerResults(CustomTrackerResults results) override;
+ void DidObserveFirstScrollDelay(
+ base::TimeDelta first_scroll_delay,
+ base::TimeTicks first_scroll_timestamp) override;
+ void RunPaintBenchmark(int repeat_count,
+ PaintBenchmarkResult& result) override;
+
+ // LayerTreeHostSingleThreadClient:
+ void ScheduleAnimationForWebTests() override;
+ void FrameIntervalUpdated(base::TimeDelta interval) override;
+ void DidSubmitCompositorFrame() override;
+ void DidLoseLayerTreeFrameSink() override;
+ void FrameSinksToThrottleUpdated(
+ const base::flat_set<viz::FrameSinkId>& ids) override;
+
+ private:
+ const raw_ptr<MutatorHost> mutator_host_;
+
+ // The concrete LayerTreeHost which the client is controlling.
+ // TODO(https://crbug.com/1431762): Own and manage a LayerTreeHostImpl
+ // directly instead of proxying through a single-threaded LayerTreeHost.
+ const LayerListSettings layer_list_settings_;
+ std::unique_ptr<LayerTreeHost> host_;
+};
+
+} // namespace cc
+
+#endif // CC_TREES_LOCAL_LAYER_CONTEXT_H_
diff --git a/chrome/browser/android/vr/arcore_device/arcore_device_unittest.cc b/chrome/browser/android/vr/arcore_device/arcore_device_unittest.cc
index f26edd6..43a93ea 100644
--- a/chrome/browser/android/vr/arcore_device/arcore_device_unittest.cc
+++ b/chrome/browser/android/vr/arcore_device/arcore_device_unittest.cc
@@ -27,6 +27,7 @@
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "services/viz/public/mojom/compositing/layer_context.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -232,6 +233,7 @@
SubmitCompositorFrameSyncCallback callback) override {}
void InitializeCompositorFrameSinkType(
viz::mojom::CompositorFrameSinkType type) override {}
+ void BindLayerContext(viz::mojom::PendingLayerContextPtr context) override {}
void SetThreadIds(const std::vector<int32_t>& thread_ids) override {}
// mojom::ExternalBeginFrameController implementation.
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index 395917c..96fe556 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -189,6 +189,8 @@
"hit_test/hit_test_aggregator_delegate.h",
"hit_test/hit_test_manager.cc",
"hit_test/hit_test_manager.h",
+ "layers/layer_context_impl.cc",
+ "layers/layer_context_impl.h",
"performance_hint/hint_session.cc",
"performance_hint/hint_session.h",
"performance_hint/utils.cc",
@@ -246,6 +248,7 @@
"//media",
"//media/capture:capture_lib",
"//media/mojo/services",
+ "//services/metrics/public/mojom",
"//services/tracing/public/cpp:cpp",
"//services/viz/privileged/mojom",
"//skia",
@@ -257,6 +260,8 @@
public_deps = [
"//base",
+ "//cc",
+ "//cc/animation",
"//cc/debug",
"//components/viz/common",
"//gpu/command_buffer/service:gles2",
@@ -264,6 +269,7 @@
"//gpu/vulkan:buildflags",
"//media/gpu/ipc/service",
"//media/mojo/services",
+ "//services/metrics/public/cpp:metrics_cpp",
"//services/viz/privileged/mojom/compositing",
"//services/viz/privileged/mojom/gl",
"//services/viz/public/mojom",
diff --git a/components/viz/service/frame_sinks/DEPS b/components/viz/service/frame_sinks/DEPS
index b62ceac..163224a 100644
--- a/components/viz/service/frame_sinks/DEPS
+++ b/components/viz/service/frame_sinks/DEPS
@@ -6,6 +6,7 @@
"+components/viz/service/display",
"+components/viz/service/display_embedder",
"+components/viz/service/hit_test",
+ "+components/viz/service/layers",
"+components/viz/service/performance_hint",
"+components/viz/service/surfaces",
"+components/viz/service/transitions",
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc
index a9c7bb4..eeec1ba 100644
--- a/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc
@@ -16,6 +16,7 @@
#include "build/build_config.h"
#include "components/viz/service/frame_sinks/frame_sink_bundle_impl.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
+#include "services/viz/public/mojom/compositing/layer_context.mojom.h"
#include "ui/gfx/overlay_transform.h"
namespace viz {
@@ -199,6 +200,11 @@
support_->InitializeCompositorFrameSinkType(type);
}
+void CompositorFrameSinkImpl::BindLayerContext(
+ mojom::PendingLayerContextPtr context) {
+ support_->BindLayerContext(*context);
+}
+
#if BUILDFLAG(IS_ANDROID)
void CompositorFrameSinkImpl::SetThreadIds(
const std::vector<int32_t>& thread_ids) {
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_impl.h b/components/viz/service/frame_sinks/compositor_frame_sink_impl.h
index 90af1827..3df7c43 100644
--- a/components/viz/service/frame_sinks/compositor_frame_sink_impl.h
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_impl.h
@@ -61,6 +61,7 @@
void DidDeleteSharedBitmap(const SharedBitmapId& id) override;
void InitializeCompositorFrameSinkType(
mojom::CompositorFrameSinkType type) override;
+ void BindLayerContext(mojom::PendingLayerContextPtr context) override;
#if BUILDFLAG(IS_ANDROID)
void SetThreadIds(const std::vector<int32_t>& thread_ids) override;
#endif
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
index 966f54b..e55a674 100644
--- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -459,6 +459,11 @@
}
}
+void CompositorFrameSinkSupport::BindLayerContext(
+ mojom::PendingLayerContext& context) {
+ layer_context_impl_ = std::make_unique<LayerContextImpl>(context);
+}
+
void CompositorFrameSinkSupport::SetThreadIds(
bool from_untrusted_client,
base::flat_set<base::PlatformThreadId> unverified_thread_ids) {
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.h b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
index c8350efc..b55a8d8 100644
--- a/components/viz/service/frame_sinks/compositor_frame_sink_support.h
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
@@ -29,11 +29,13 @@
#include "components/viz/service/frame_sinks/surface_resource_holder_client.h"
#include "components/viz/service/frame_sinks/video_capture/capturable_frame_sink.h"
#include "components/viz/service/hit_test/hit_test_aggregator.h"
+#include "components/viz/service/layers/layer_context_impl.h"
#include "components/viz/service/surfaces/frame_index_constants.h"
#include "components/viz/service/surfaces/surface_client.h"
#include "components/viz/service/transitions/surface_animation_manager.h"
#include "components/viz/service/viz_service_export.h"
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h"
+#include "services/viz/public/mojom/compositing/layer_context.mojom.h"
#include "services/viz/public/mojom/hit_test/hit_test_region_list.mojom.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
@@ -41,6 +43,7 @@
class FrameSinkManagerImpl;
class LatestLocalSurfaceIdLookupDelegate;
+class LayerContextImpl;
class Surface;
class SurfaceManager;
@@ -132,6 +135,7 @@
base::TimeDelta GetPreferredFrameInterval(
mojom::CompositorFrameSinkType* type) const;
void InitializeCompositorFrameSinkType(mojom::CompositorFrameSinkType type);
+ void BindLayerContext(mojom::PendingLayerContext& context);
void SetThreadIds(
bool from_untrusted_client,
base::flat_set<base::PlatformThreadId> unverified_thread_ids);
@@ -455,6 +459,10 @@
// Region capture bounds associated with the last surface that was aggregated.
RegionCaptureBounds current_capture_bounds_;
+ // In LayerContext mode only, this is the Viz LayerContext implementation
+ // which owns the backend layer tree for this frame sink.
+ std::unique_ptr<LayerContextImpl> layer_context_impl_;
+
base::WeakPtrFactory<CompositorFrameSinkSupport> weak_factory_{this};
};
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
index b2dec27..0110919 100644
--- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
+++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -25,6 +25,7 @@
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "components/viz/service/frame_sinks/gpu_vsync_begin_frame_source.h"
#include "components/viz/service/hit_test/hit_test_aggregator.h"
+#include "services/viz/public/mojom/compositing/layer_context.mojom.h"
#include "ui/gfx/geometry/skia_conversions.h"
#if BUILDFLAG(IS_ANDROID)
@@ -493,6 +494,11 @@
support_->InitializeCompositorFrameSinkType(type);
}
+void RootCompositorFrameSinkImpl::BindLayerContext(
+ mojom::PendingLayerContextPtr context) {
+ support_->BindLayerContext(*context);
+}
+
#if BUILDFLAG(IS_ANDROID)
void RootCompositorFrameSinkImpl::SetThreadIds(
const std::vector<int32_t>& thread_ids) {
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
index 559a8cc..c3c15f9c 100644
--- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
+++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
@@ -121,6 +121,7 @@
SubmitCompositorFrameSyncCallback callback) override;
void InitializeCompositorFrameSinkType(
mojom::CompositorFrameSinkType type) override;
+ void BindLayerContext(mojom::PendingLayerContextPtr context) override;
#if BUILDFLAG(IS_ANDROID)
void SetThreadIds(const std::vector<int32_t>& thread_ids) override;
#endif
diff --git a/components/viz/service/layers/DEPS b/components/viz/service/layers/DEPS
new file mode 100644
index 0000000..27a6d9ae
--- /dev/null
+++ b/components/viz/service/layers/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+components/viz/service/frame_sinks",
+ "+mojo/public",
+]
diff --git a/components/viz/service/layers/layer_context_impl.cc b/components/viz/service/layers/layer_context_impl.cc
new file mode 100644
index 0000000..5992805
--- /dev/null
+++ b/components/viz/service/layers/layer_context_impl.cc
@@ -0,0 +1,37 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/layers/layer_context_impl.h"
+
+#include <utility>
+
+#include "cc/trees/commit_state.h"
+#include "cc/trees/layer_tree_host.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+
+namespace viz {
+
+LayerContextImpl::LayerContextImpl(mojom::PendingLayerContext& context)
+ : receiver_(this, std::move(context.receiver)),
+ client_(std::move(context.client)) {}
+
+LayerContextImpl::~LayerContextImpl() = default;
+
+void LayerContextImpl::SetTargetLocalSurfaceId(const LocalSurfaceId& id) {
+ context_.SetTargetLocalSurfaceId(id);
+}
+
+void LayerContextImpl::SetVisible(bool visible) {
+ context_.SetVisible(visible);
+}
+
+void LayerContextImpl::Commit(mojom::LayerTreeUpdatePtr update) {
+ cc::CommitState state;
+ state.device_viewport_rect = update->device_viewport;
+ state.device_scale_factor = update->device_scale_factor;
+ state.local_surface_id_from_parent = update->local_surface_id_from_parent;
+ context_.Commit(state);
+}
+
+} // namespace viz
diff --git a/components/viz/service/layers/layer_context_impl.h b/components/viz/service/layers/layer_context_impl.h
new file mode 100644
index 0000000..31b6cd4
--- /dev/null
+++ b/components/viz/service/layers/layer_context_impl.h
@@ -0,0 +1,43 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_LAYERS_LAYER_CONTEXT_IMPL_H_
+#define COMPONENTS_VIZ_SERVICE_LAYERS_LAYER_CONTEXT_IMPL_H_
+
+#include <memory>
+
+#include "cc/animation/animation_host.h"
+#include "cc/trees/local_layer_context.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "services/viz/public/mojom/compositing/layer_context.mojom.h"
+
+namespace viz {
+
+// Implements the Viz LayerContext API backed by a LocalLayerContext. This
+// provides the service backend for a client-side VizLayerContext.
+class LayerContextImpl : public mojom::LayerContext {
+ public:
+ // Constructs a new LayerContextImpl with client connection details given by
+ // `context`.
+ explicit LayerContextImpl(mojom::PendingLayerContext& context);
+ ~LayerContextImpl() override;
+
+ private:
+ // mojom::LayerContext:
+ void SetTargetLocalSurfaceId(const LocalSurfaceId& id) override;
+ void SetVisible(bool visible) override;
+ void Commit(mojom::LayerTreeUpdatePtr update) override;
+
+ const std::unique_ptr<cc::AnimationHost> animation_host_{
+ cc::AnimationHost::CreateMainInstance()};
+ cc::LocalLayerContext context_{animation_host_.get()};
+
+ mojo::AssociatedReceiver<mojom::LayerContext> receiver_;
+ mojo::AssociatedRemote<mojom::LayerContextClient> client_;
+};
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_SERVICE_LAYERS_LAYER_CONTEXT_IMPL_H_
diff --git a/services/viz/public/mojom/BUILD.gn b/services/viz/public/mojom/BUILD.gn
index a4bc44b..17f0b9ab 100644
--- a/services/viz/public/mojom/BUILD.gn
+++ b/services/viz/public/mojom/BUILD.gn
@@ -24,6 +24,7 @@
"compositing/frame_sink_bundle_id.mojom",
"compositing/frame_sink_id.mojom",
"compositing/frame_timing_details.mojom",
+ "compositing/layer_context.mojom",
"compositing/local_surface_id.mojom",
"compositing/paint_filter.mojom",
"compositing/quads.mojom",
diff --git a/services/viz/public/mojom/compositing/compositor_frame_sink.mojom b/services/viz/public/mojom/compositing/compositor_frame_sink.mojom
index f7fd878..f0515087 100644
--- a/services/viz/public/mojom/compositing/compositor_frame_sink.mojom
+++ b/services/viz/public/mojom/compositing/compositor_frame_sink.mojom
@@ -8,6 +8,7 @@
import "mojo/public/mojom/base/shared_memory.mojom";
import "services/viz/public/mojom/compositing/begin_frame_args.mojom";
import "services/viz/public/mojom/compositing/compositor_frame.mojom";
+import "services/viz/public/mojom/compositing/layer_context.mojom";
import "services/viz/public/mojom/compositing/local_surface_id.mojom";
import "services/viz/public/mojom/compositing/frame_timing_details.mojom";
import "services/viz/public/mojom/compositing/returned_resource.mojom";
@@ -93,6 +94,13 @@
// are silently ignored.
InitializeCompositorFrameSinkType(CompositorFrameSinkType type);
+ // Binds to the LayerContext interface for this frame sink. Once this is bound
+ // the frame sink is permanently in LayerContext mode and the client should no
+ // longer submit frames through the CompositorFrameSink interface. Instead
+ // frames will automtaically be submitted by Viz based on the state of a
+ // GPU-side layer tree which can be manipulated through this LayerContext.
+ BindLayerContext(PendingLayerContext context);
+
// Informs the display compositor the IDs of the thread involved in frame
// production. This is used on Android PerformanceHint API to dynamically
// adjust performance to allow power saving.
diff --git a/services/viz/public/mojom/compositing/layer_context.mojom b/services/viz/public/mojom/compositing/layer_context.mojom
new file mode 100644
index 0000000..84b8e1b
--- /dev/null
+++ b/services/viz/public/mojom/compositing/layer_context.mojom
@@ -0,0 +1,47 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module viz.mojom;
+
+import "ui/gfx/geometry/mojom/geometry.mojom";
+import "services/viz/public/mojom/compositing/begin_frame_args.mojom";
+import "services/viz/public/mojom/compositing/local_surface_id.mojom";
+
+// Metadata about a layer tree to be updated with each LayerContext commit.
+struct LayerTreeUpdate {
+ gfx.mojom.Rect device_viewport;
+ float device_scale_factor;
+ LocalSurfaceId local_surface_id_from_parent;
+};
+
+// Drives updates to a GPU-side LayerTreeHostImpl from its corresponding
+// client-side (e.g. renderer- or browser-side) LayerTreeHost.
+interface LayerContext {
+ // Updates the LocalSurfaceId associated with the tree.
+ SetTargetLocalSurfaceId(LocalSurfaceId id);
+
+ // Globally controls whether the tree contents are visible.
+ SetVisible(bool visible);
+
+ // Flushes pending updates from the client to the LayerTreeHostImpl.
+ Commit(LayerTreeUpdate update);
+};
+
+// Provides feedback from a GPU-side LayerTreeHostImpl to its corresponding
+// client-side (e.g. renderer- or browser-side) LayerTreeHost.
+interface LayerContextClient {
+ // Sent by the LayerTreeHostImpl when it needs to produce a new frame soon and
+ // the client had previously indicated that it wants an opporunity to make
+ // changes to the tree before that frame is drawn.
+ OnRequestCommitForFrame(BeginFrameArgs args);
+};
+
+// Parameters needed to bind a LayerContext endpoint via a CompositorFrameSink.
+struct PendingLayerContext {
+ // TODO(https://crbug.com/1431762): De-associate these interfaces from
+ // CompositorFrameSink.
+ pending_associated_receiver<LayerContext> receiver;
+ pending_associated_remote<LayerContextClient> client;
+};
+
diff --git a/third_party/blink/renderer/platform/graphics/test/mock_compositor_frame_sink.h b/third_party/blink/renderer/platform/graphics/test/mock_compositor_frame_sink.h
index 6b9e14c..3e59679 100644
--- a/third_party/blink/renderer/platform/graphics/test/mock_compositor_frame_sink.h
+++ b/third_party/blink/renderer/platform/graphics/test/mock_compositor_frame_sink.h
@@ -13,6 +13,7 @@
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom-blink.h"
+#include "services/viz/public/mojom/compositing/layer_context.mojom-blink.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/mojom/frame_sinks/embedded_frame_sink.mojom-blink-forward.h"
@@ -64,6 +65,8 @@
MOCK_METHOD1(SetPreferredFrameInterval, void(base::TimeDelta));
MOCK_METHOD1(InitializeCompositorFrameSinkType,
void(viz::mojom::CompositorFrameSinkType));
+ MOCK_METHOD1(BindLayerContext,
+ void(viz::mojom::blink::PendingLayerContextPtr));
MOCK_METHOD1(SetThreadIds, void(const WTF::Vector<int32_t>&));
private:
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
index d5260d8..c0a5ea7 100644
--- a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
+++ b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
@@ -30,6 +30,7 @@
#include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom-blink.h"
#include "services/viz/public/mojom/compositing/frame_sink_bundle.mojom-blink.h"
+#include "services/viz/public/mojom/compositing/layer_context.mojom-blink.h"
#include "services/viz/public/mojom/hit_test/hit_test_region_list.mojom-blink.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
@@ -152,6 +153,9 @@
bundle_->InitializeCompositorFrameSinkType(frame_sink_id_.sink_id(), type);
}
+ void BindLayerContext(
+ viz::mojom::blink::PendingLayerContextPtr context) override {}
+
#if BUILDFLAG(IS_ANDROID)
void SetThreadIds(const WTF::Vector<int32_t>& thread_ids) override {
bundle_->SetThreadIds(frame_sink_id_.sink_id(), thread_ids);
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc b/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc
index 6ef6725f..5887c8e 100644
--- a/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc
+++ b/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc
@@ -31,6 +31,7 @@
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom-blink.h"
+#include "services/viz/public/mojom/compositing/layer_context.mojom-blink.h"
#include "services/viz/public/mojom/hit_test/hit_test_region_list.mojom-blink.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -116,6 +117,8 @@
MOCK_METHOD1(DidDeleteSharedBitmap, void(const gpu::Mailbox& id));
MOCK_METHOD1(InitializeCompositorFrameSinkType,
void(viz::mojom::CompositorFrameSinkType));
+ MOCK_METHOD1(BindLayerContext,
+ void(viz::mojom::blink::PendingLayerContextPtr));
MOCK_METHOD1(SetThreadIds, void(const WTF::Vector<int32_t>&));
private: