Commit d2f538cf authored by Saman Sami's avatar Saman Sami Committed by Commit Bot

Stop sending OnFirstSurfaceActivation to SurfaceLayerBridge

Establish a direct connection from the child (CanvasResourceDispatcher/
VideoFrameSubmitter) to the embedder (SuraceLayerBridge) so the child
can notify the embedder of its allocated SurfaceIds directly instead of
three process hops (renderer->viz->browser->renderer), hence reducing
latency and eliminating any IPC messages involved in this process.

Bug: 893850,883927
Change-Id: Ide595e3c6aa995c77678d6413d5ad6421e2d35e5
Reviewed-on: https://chromium-review.googlesource.com/c/1338411
Commit-Queue: Saman Sami <samans@chromium.org>
Reviewed-by: default avatarRobert Flack <flackr@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarFady Samuel <fsamuel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609469}
parent 1d8d4654
......@@ -26,7 +26,10 @@ EmbeddedFrameSinkImpl::EmbeddedFrameSinkImpl(
frame_sink_id_(frame_sink_id) {
client_.set_connection_error_handler(std::move(destroy_callback));
host_frame_sink_manager_->RegisterFrameSinkId(
frame_sink_id_, this, viz::ReportFirstSurfaceActivation::kYes);
frame_sink_id_, this,
features::IsSurfaceSynchronizationEnabled()
? viz::ReportFirstSurfaceActivation::kNo
: viz::ReportFirstSurfaceActivation::kYes);
host_frame_sink_manager_->SetFrameSinkDebugLabel(frame_sink_id_,
"EmbeddedFrameSinkImpl");
}
......@@ -41,7 +44,8 @@ EmbeddedFrameSinkImpl::~EmbeddedFrameSinkImpl() {
void EmbeddedFrameSinkImpl::CreateCompositorFrameSink(
viz::mojom::CompositorFrameSinkClientPtr client,
viz::mojom::CompositorFrameSinkRequest request) {
viz::mojom::CompositorFrameSinkRequest request,
blink::mojom::SurfaceEmbedderRequest surface_embedder_request) {
// We might recreate the CompositorFrameSink on context loss or GPU crash.
// Only register frame sink hierarchy the first time.
if (!has_created_compositor_frame_sink_) {
......@@ -58,6 +62,8 @@ void EmbeddedFrameSinkImpl::CreateCompositorFrameSink(
host_frame_sink_manager_->CreateCompositorFrameSink(
frame_sink_id_, std::move(request), std::move(client));
client_->BindSurfaceEmbedder(std::move(surface_embedder_request));
has_created_compositor_frame_sink_ = true;
}
......
......@@ -44,7 +44,8 @@ class CONTENT_EXPORT EmbeddedFrameSinkImpl : public viz::HostFrameSinkClient {
// should only ever be called once.
void CreateCompositorFrameSink(
viz::mojom::CompositorFrameSinkClientPtr client,
viz::mojom::CompositorFrameSinkRequest request);
viz::mojom::CompositorFrameSinkRequest request,
blink::mojom::SurfaceEmbedderRequest surface_embedder_request);
// viz::HostFrameSinkClient implementation.
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
......
......@@ -51,7 +51,8 @@ void EmbeddedFrameSinkProviderImpl::RegisterEmbeddedFrameSink(
void EmbeddedFrameSinkProviderImpl::CreateCompositorFrameSink(
const viz::FrameSinkId& frame_sink_id,
viz::mojom::CompositorFrameSinkClientPtr client,
viz::mojom::CompositorFrameSinkRequest request) {
viz::mojom::CompositorFrameSinkRequest request,
blink::mojom::SurfaceEmbedderRequest surface_embedder_request) {
// TODO(kylechar): Kill the renderer too.
if (frame_sink_id.client_id() != renderer_client_id_) {
DLOG(ERROR) << "Invalid client id " << frame_sink_id;
......@@ -64,8 +65,8 @@ void EmbeddedFrameSinkProviderImpl::CreateCompositorFrameSink(
return;
}
iter->second->CreateCompositorFrameSink(std::move(client),
std::move(request));
iter->second->CreateCompositorFrameSink(std::move(client), std::move(request),
std::move(surface_embedder_request));
}
void EmbeddedFrameSinkProviderImpl::CreateSimpleCompositorFrameSink(
......@@ -76,9 +77,10 @@ void EmbeddedFrameSinkProviderImpl::CreateSimpleCompositorFrameSink(
viz::mojom::CompositorFrameSinkRequest compositor_frame_sink_request) {
RegisterEmbeddedFrameSink(parent_frame_sink_id, frame_sink_id,
std::move(embedded_frame_sink_client));
CreateCompositorFrameSink(frame_sink_id,
std::move(compositor_frame_sink_client),
std::move(compositor_frame_sink_request));
blink::mojom::SurfaceEmbedderPtr doomed;
CreateCompositorFrameSink(
frame_sink_id, std::move(compositor_frame_sink_client),
std::move(compositor_frame_sink_request), mojo::MakeRequest(&doomed));
}
void EmbeddedFrameSinkProviderImpl::DestroyEmbeddedFrameSink(
......
......@@ -39,8 +39,9 @@ class CONTENT_EXPORT EmbeddedFrameSinkProviderImpl
blink::mojom::EmbeddedFrameSinkClientPtr client) override;
void CreateCompositorFrameSink(
const viz::FrameSinkId& frame_sink_id,
viz::mojom::CompositorFrameSinkClientPtr client,
viz::mojom::CompositorFrameSinkRequest request) override;
viz::mojom::CompositorFrameSinkClientPtr sink_client,
viz::mojom::CompositorFrameSinkRequest sink_request,
blink::mojom::SurfaceEmbedderRequest surface_embedder_request) override;
void CreateSimpleCompositorFrameSink(
const viz::FrameSinkId& parent_frame_sink_id,
const viz::FrameSinkId& frame_sink_id,
......
......@@ -11,6 +11,7 @@
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "components/viz/common/features.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
......@@ -51,9 +52,11 @@ void WaitForConnectionError(T* endpoint) {
// Stub EmbeddedFrameSinkClient that stores the latest SurfaceInfo.
class StubEmbeddedFrameSinkClient
: public blink::mojom::EmbeddedFrameSinkClient {
: public blink::mojom::EmbeddedFrameSinkClient,
public blink::mojom::SurfaceEmbedder {
public:
StubEmbeddedFrameSinkClient() : binding_(this) {}
StubEmbeddedFrameSinkClient()
: surface_embedder_binding_(this), binding_(this) {}
~StubEmbeddedFrameSinkClient() override {}
blink::mojom::EmbeddedFrameSinkClientPtr GetInterfacePtr() {
......@@ -71,6 +74,10 @@ class StubEmbeddedFrameSinkClient
return last_surface_info_;
}
const viz::LocalSurfaceId& last_received_local_surface_id() const {
return last_received_local_surface_id_;
}
bool connection_error() const { return connection_error_; }
private:
......@@ -78,9 +85,20 @@ class StubEmbeddedFrameSinkClient
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override {
last_surface_info_ = surface_info;
}
void BindSurfaceEmbedder(
blink::mojom::SurfaceEmbedderRequest request) override {
surface_embedder_binding_.Bind(std::move(request));
}
// blink::mojom::SurfaceEmbedder implementation:
void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id) override {
last_received_local_surface_id_ = local_surface_id;
}
mojo::Binding<blink::mojom::SurfaceEmbedder> surface_embedder_binding_;
mojo::Binding<blink::mojom::EmbeddedFrameSinkClient> binding_;
viz::SurfaceInfo last_surface_info_;
viz::LocalSurfaceId last_received_local_surface_id_;
bool connection_error_ = false;
DISALLOW_COPY_AND_ASSIGN(StubEmbeddedFrameSinkClient);
......@@ -150,9 +168,13 @@ class EmbeddedFrameSinkProviderImplTest : public testing::Test {
std::unique_ptr<EmbeddedFrameSinkProviderImpl> provider_;
};
// Mimics the workflow of OffscreenCanvas.commit() on renderer process.
// Mimics the workflow of OffscreenCanvas.commit() on renderer process. Assumes
// surface sync is disabled.
TEST_F(EmbeddedFrameSinkProviderImplTest,
SingleHTMLCanvasElementTransferToOffscreen) {
if (features::IsSurfaceSynchronizationEnabled())
return;
// Mimic connection from the renderer main thread to browser.
StubEmbeddedFrameSinkClient efs_client;
provider()->RegisterEmbeddedFrameSink(kFrameSinkParent, kFrameSinkA,
......@@ -168,15 +190,16 @@ TEST_F(EmbeddedFrameSinkProviderImplTest,
// Mimic connection from the renderer main or worker thread to browser.
viz::mojom::CompositorFrameSinkPtr compositor_frame_sink;
viz::MockCompositorFrameSinkClient compositor_frame_sink_client;
blink::mojom::SurfaceEmbedderPtr surface_embedder;
provider()->CreateCompositorFrameSink(
kFrameSinkA, compositor_frame_sink_client.BindInterfacePtr(),
mojo::MakeRequest(&compositor_frame_sink));
mojo::MakeRequest(&compositor_frame_sink),
mojo::MakeRequest(&surface_embedder));
// Renderer submits a CompositorFrame with |local_id|.
const viz::LocalSurfaceId local_id(1, base::UnguessableToken::Create());
compositor_frame_sink->SubmitCompositorFrame(
local_id, viz::MakeDefaultCompositorFrame(), base::nullopt,
base::TimeTicks::Now().since_origin().InMicroseconds());
local_id, viz::MakeDefaultCompositorFrame(), base::nullopt, 0);
RunUntilIdle();
......@@ -191,6 +214,54 @@ TEST_F(EmbeddedFrameSinkProviderImplTest,
EXPECT_EQ(local_id, surface_info.id().local_surface_id());
}
// Mimics the workflow of OffscreenCanvas.commit() on renderer process. Assumes
// surface sync is enabled.
TEST_F(EmbeddedFrameSinkProviderImplTest,
SingleHTMLCanvasElementTransferToOffscreenSurfaceSync) {
if (!features::IsSurfaceSynchronizationEnabled())
return;
// Mimic connection from the renderer main thread to browser.
StubEmbeddedFrameSinkClient efs_client;
provider()->RegisterEmbeddedFrameSink(kFrameSinkParent, kFrameSinkA,
efs_client.GetInterfacePtr());
EmbeddedFrameSinkImpl* efs_impl = GetEmbeddedFrameSink(kFrameSinkA);
// There should be a single EmbeddedFrameSinkImpl and it should have the
// provided FrameSinkId.
EXPECT_EQ(kFrameSinkA, efs_impl->frame_sink_id());
EXPECT_THAT(GetAllCanvases(), ElementsAre(kFrameSinkA));
// Mimic connection from the renderer main or worker thread to browser.
viz::mojom::CompositorFrameSinkPtr compositor_frame_sink;
viz::MockCompositorFrameSinkClient compositor_frame_sink_client;
blink::mojom::SurfaceEmbedderPtr surface_embedder;
provider()->CreateCompositorFrameSink(
kFrameSinkA, compositor_frame_sink_client.BindInterfacePtr(),
mojo::MakeRequest(&compositor_frame_sink),
mojo::MakeRequest(&surface_embedder));
// Renderer submits a CompositorFrame with |local_id|.
const viz::LocalSurfaceId local_id(1, base::UnguessableToken::Create());
compositor_frame_sink->SubmitCompositorFrame(
local_id, viz::MakeDefaultCompositorFrame(), base::nullopt, 0);
RunUntilIdle();
// EmbeddedFrameSinkImpl in browser should not be obversing surface
// activations so it should not know about |local_id|.
EXPECT_NE(local_id, efs_impl->local_surface_id());
EXPECT_FALSE(efs_impl->local_surface_id().is_valid());
// Notify the embedder of the new LocalSurfaceId.
surface_embedder->SetLocalSurfaceId(local_id);
RunUntilIdle();
// EmbeddedFrameSinkClient in the renderer should now know about |local_id|.
EXPECT_EQ(local_id, efs_client.last_received_local_surface_id());
}
// Check that renderer closing the mojom::EmbeddedFrameSinkClient connection
// destroys the EmbeddedFrameSinkImpl in browser.
TEST_F(EmbeddedFrameSinkProviderImplTest, ClientClosesConnection) {
......@@ -242,11 +313,13 @@ TEST_F(EmbeddedFrameSinkProviderImplTest, ClientConnectionWrongOrder) {
// Mimic connection from the renderer main or worker thread.
viz::mojom::CompositorFrameSinkPtr compositor_frame_sink;
viz::MockCompositorFrameSinkClient compositor_frame_sink_client;
blink::mojom::SurfaceEmbedderPtr surface_embedder;
// Try to connect CompositorFrameSink without first making
// EmbeddedFrameSink connection. This should fail.
provider()->CreateCompositorFrameSink(
kFrameSinkA, compositor_frame_sink_client.BindInterfacePtr(),
mojo::MakeRequest(&compositor_frame_sink));
mojo::MakeRequest(&compositor_frame_sink),
mojo::MakeRequest(&surface_embedder));
// The request will fail and trigger a connection error.
WaitForConnectionError(&compositor_frame_sink);
......@@ -263,9 +336,11 @@ TEST_F(EmbeddedFrameSinkProviderImplTest, ParentNotRegistered) {
viz::MockCompositorFrameSinkClient compositor_frame_sink_client;
// The embedder, kFrameSinkA, has already been invalidated and isn't
// registered at this point. This request should fail.
blink::mojom::SurfaceEmbedderPtr surface_embedder;
provider()->CreateCompositorFrameSink(
kFrameSinkB, compositor_frame_sink_client.BindInterfacePtr(),
mojo::MakeRequest(&compositor_frame_sink));
mojo::MakeRequest(&compositor_frame_sink),
mojo::MakeRequest(&surface_embedder));
// The request will fail and trigger a connection error.
WaitForConnectionError(&compositor_frame_sink);
......
......@@ -7,12 +7,22 @@ module blink.mojom;
import "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom";
import "services/viz/public/interfaces/compositing/frame_sink_id.mojom";
import "services/viz/public/interfaces/compositing/surface_info.mojom";
import "services/viz/public/interfaces/compositing/local_surface_id.mojom";
// Interface back to the embedder so it can be notified about surface
// Interface from the the submitter to the embedder.
interface SurfaceEmbedder {
// Called by the embedee when a new LocalSurfaceId is allocated.
SetLocalSurfaceId(viz.mojom.LocalSurfaceId local_surface_id);
};
// Interface from browser to the embedder so it can be notified about surface
// activations. Closing this interface will destroy the corresponding
// CompositorFrameSink if one exists.
interface EmbeddedFrameSinkClient {
OnFirstSurfaceActivation(viz.mojom.SurfaceInfo surface_info);
// Called when a CompositorFrameSink is created for this frame sink.
// Establishes a direct connection from the embedee to the embedder.
BindSurfaceEmbedder(SurfaceEmbedder& embedder);
};
// Provides embedded CompositorFrameSinks for the renderer. The renderer should
......@@ -31,7 +41,8 @@ interface EmbeddedFrameSinkProvider {
// calling RegisterEmbeddedFrameSink() for |frame_sink_id|.
CreateCompositorFrameSink(viz.mojom.FrameSinkId frame_sink_id,
viz.mojom.CompositorFrameSinkClient client,
viz.mojom.CompositorFrameSink& sink);
viz.mojom.CompositorFrameSink& sink,
SurfaceEmbedder& notifier);
// Ceate CompositorFrameSink directly in a single call (instead of going
// through both function above).
......
......@@ -55,6 +55,10 @@ class PLATFORM_EXPORT BeginFrameProvider
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) final {
NOTIMPLEMENTED();
}
void BindSurfaceEmbedder(
mojom::blink::SurfaceEmbedderRequest request) override {
NOTIMPLEMENTED();
}
void ResetCompositorFrameSink();
......
......@@ -6,6 +6,7 @@
#include <memory>
#include "base/single_thread_task_runner.h"
#include "components/viz/common/features.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/resources/resource_format.h"
......@@ -58,6 +59,8 @@ CanvasResourceDispatcher::CanvasResourceDispatcher(
placeholder_canvas_id_(canvas_id),
num_unreclaimed_frames_posted_(0),
client_(client),
enable_surface_synchronization_(
features::IsSurfaceSynchronizationEnabled()),
weak_ptr_factory_(this) {
// Frameless canvas pass an invalid |frame_sink_id_|; don't create mojo
// channel for this special case.
......@@ -72,7 +75,8 @@ CanvasResourceDispatcher::CanvasResourceDispatcher(
DCHECK(provider);
binding_.Bind(mojo::MakeRequest(&client_ptr_));
provider->CreateCompositorFrameSink(frame_sink_id_, std::move(client_ptr_),
mojo::MakeRequest(&sink_));
mojo::MakeRequest(&sink_),
mojo::MakeRequest(&surface_embedder_));
}
CanvasResourceDispatcher::~CanvasResourceDispatcher() = default;
......@@ -272,6 +276,10 @@ bool CanvasResourceDispatcher::PrepareFrame(
if (change_size_for_next_commit_ ||
!parent_local_surface_id_allocator_.HasValidLocalSurfaceIdAllocation()) {
parent_local_surface_id_allocator_.GenerateId();
if (enable_surface_synchronization_) {
surface_embedder_->SetLocalSurfaceId(
parent_local_surface_id_allocator_.GetCurrentLocalSurfaceId());
}
change_size_for_next_commit_ = false;
}
......
......@@ -11,6 +11,7 @@
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h"
#include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.h"
#include "third_party/blink/renderer/platform/wtf/compiler.h"
namespace blink {
......@@ -110,6 +111,7 @@ class PLATFORM_EXPORT CanvasResourceDispatcher
void ReclaimResourceInternal(const ResourceMap::iterator&);
viz::mojom::blink::CompositorFrameSinkPtr sink_;
mojom::blink::SurfaceEmbedderPtr surface_embedder_;
mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_;
viz::mojom::blink::CompositorFrameSinkClientPtr client_ptr_;
......@@ -128,6 +130,8 @@ class PLATFORM_EXPORT CanvasResourceDispatcher
CanvasResourceDispatcherClient* client_;
const bool enable_surface_synchronization_;
base::WeakPtrFactory<CanvasResourceDispatcher> weak_ptr_factory_;
};
......
......@@ -10,6 +10,7 @@
#include "cc/layers/layer.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/layers/surface_layer.h"
#include "components/viz/common/features.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/common/surfaces/surface_info.h"
#include "media/base/media_switches.h"
......@@ -31,6 +32,9 @@ SurfaceLayerBridge::SurfaceLayerBridge(
update_submission_state_callback_(
std::move(update_submission_state_callback)),
binding_(this),
surface_embedder_binding_(this),
enable_surface_synchronization_(
features::IsSurfaceSynchronizationEnabled()),
frame_sink_id_(Platform::Current()->GenerateFrameSinkId()),
parent_frame_sink_id_(layer_tree_view ? layer_tree_view->GetFrameSinkId()
: viz::FrameSinkId()) {
......@@ -57,10 +61,27 @@ void SurfaceLayerBridge::CreateSolidColorLayer() {
observer_->RegisterContentsLayer(solid_color_layer_.get());
}
void SurfaceLayerBridge::SetLocalSurfaceId(
const viz::LocalSurfaceId& local_surface_id) {
if (!enable_surface_synchronization_) {
NOTREACHED();
return;
}
EmbedSurface(viz::SurfaceId(frame_sink_id_, local_surface_id));
}
void SurfaceLayerBridge::OnFirstSurfaceActivation(
const viz::SurfaceInfo& surface_info) {
if (enable_surface_synchronization_) {
NOTREACHED();
return;
}
DCHECK(surface_info.is_valid());
DCHECK_EQ(frame_sink_id_, surface_info.id().frame_sink_id());
EmbedSurface(surface_info.id());
}
void SurfaceLayerBridge::EmbedSurface(const viz::SurfaceId& surface_id) {
surface_activated_ = true;
if (solid_color_layer_) {
if (observer_)
......@@ -76,20 +97,24 @@ void SurfaceLayerBridge::OnFirstSurfaceActivation(
CreateSurfaceLayer();
}
current_surface_id_ = surface_info.id();
current_surface_id_ = surface_id;
surface_layer_->SetSurfaceId(surface_info.id(),
surface_layer_->SetSurfaceId(surface_id,
cc::DeadlinePolicy::UseSpecifiedDeadline(0u));
surface_layer_->SetOldestAcceptableFallback(surface_info.id());
if (observer_) {
observer_->OnWebLayerUpdated();
observer_->OnSurfaceIdUpdated(surface_info.id());
observer_->OnSurfaceIdUpdated(surface_id);
}
surface_layer_->SetContentsOpaque(opaque_);
}
void SurfaceLayerBridge::BindSurfaceEmbedder(
mojom::blink::SurfaceEmbedderRequest request) {
surface_embedder_binding_.Bind(std::move(request));
}
cc::Layer* SurfaceLayerBridge::GetCcLayer() const {
if (surface_layer_)
return surface_layer_.get();
......
......@@ -33,6 +33,7 @@ class WebLayerTreeView;
// between the Render and Browser processes.
class PLATFORM_EXPORT SurfaceLayerBridge
: public blink::mojom::blink::EmbeddedFrameSinkClient,
public blink::mojom::blink::SurfaceEmbedder,
public WebSurfaceLayerBridge {
public:
SurfaceLayerBridge(
......@@ -45,6 +46,13 @@ class PLATFORM_EXPORT SurfaceLayerBridge
// Implementation of blink::mojom::blink::EmbeddedFrameSinkClient
void OnFirstSurfaceActivation(const viz::SurfaceInfo&) override;
void BindSurfaceEmbedder(
mojom::blink::SurfaceEmbedderRequest request) override;
void EmbedSurface(const viz::SurfaceId& surface_id);
// Implementation of blink::mojom::blink::SurfaceEmbedder
void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id) override;
// Implementation of WebSurfaceLayerBridge.
cc::Layer* GetCcLayer() const override;
......@@ -68,7 +76,9 @@ class PLATFORM_EXPORT SurfaceLayerBridge
cc::UpdateSubmissionStateCB update_submission_state_callback_;
viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
mojo::Binding<blink::mojom::blink::EmbeddedFrameSinkClient> binding_;
mojo::Binding<blink::mojom::blink::SurfaceEmbedder> surface_embedder_binding_;
const bool enable_surface_synchronization_;
const viz::FrameSinkId frame_sink_id_;
viz::SurfaceId current_surface_id_;
const viz::FrameSinkId parent_frame_sink_id_;
......
......@@ -29,7 +29,8 @@ class MockEmbeddedFrameSinkProvider
void CreateCompositorFrameSink(
const viz::FrameSinkId& frame_sink_id,
viz::mojom::blink::CompositorFrameSinkClientPtr client,
viz::mojom::blink::CompositorFrameSinkRequest sink) override {
viz::mojom::blink::CompositorFrameSinkRequest sink,
mojom::blink::SurfaceEmbedderRequest surface_embedder_request) override {
mock_compositor_frame_sink_ = std::make_unique<MockCompositorFrameSink>(
std::move(sink),
num_expected_set_needs_begin_frame_on_sink_construction_);
......
......@@ -10,6 +10,7 @@
#include "base/trace_event/trace_event.h"
#include "cc/paint/filter_operations.h"
#include "cc/scheduler/video_frame_controller.h"
#include "components/viz/common/features.h"
#include "components/viz/common/resources/resource_id.h"
#include "components/viz/common/resources/returned_resource.h"
#include "media/base/video_frame.h"
......@@ -37,6 +38,8 @@ VideoFrameSubmitter::VideoFrameSubmitter(
context_provider_callback_(context_provider_callback),
resource_provider_(std::move(resource_provider)),
rotation_(media::VIDEO_ROTATION_0),
enable_surface_synchronization_(
features::IsSurfaceSynchronizationEnabled()),
weak_ptr_factory_(this) {
DETACH_FROM_THREAD(media_thread_checker_);
}
......@@ -225,7 +228,8 @@ void VideoFrameSubmitter::StartSubmitting() {
binding_.Bind(mojo::MakeRequest(&client));
provider->CreateCompositorFrameSink(
frame_sink_id_, std::move(client),
mojo::MakeRequest(&compositor_frame_sink_));
mojo::MakeRequest(&compositor_frame_sink_),
mojo::MakeRequest(&surface_embedder_));
compositor_frame_sink_.set_connection_error_handler(base::BindOnce(
&VideoFrameSubmitter::OnContextLost, base::Unretained(this)));
......@@ -248,8 +252,15 @@ bool VideoFrameSubmitter::SubmitFrame(
frame_size = gfx::Size(frame_size.height(), frame_size.width());
}
if (frame_size_ != frame_size) {
if (!frame_size_.IsEmpty())
if (!frame_size_.IsEmpty()) {
child_local_surface_id_allocator_.GenerateId();
if (enable_surface_synchronization_) {
surface_embedder_->SetLocalSurfaceId(
child_local_surface_id_allocator_
.GetCurrentLocalSurfaceIdAllocation()
.local_surface_id());
}
}
frame_size_ = frame_size;
}
......
......@@ -18,6 +18,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/buffer.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h"
#include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.h"
#include "third_party/blink/public/platform/web_video_frame_submitter.h"
#include "third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h"
#include "third_party/blink/renderer/platform/platform_export.h"
......@@ -90,7 +91,10 @@ class PLATFORM_EXPORT VideoFrameSubmitter
viz::mojom::blink::CompositorFrameSinkPtr* sink) {
compositor_frame_sink_ = std::move(*sink);
}
void SetSurfaceEmbedderPtrForTesting(
mojom::blink::SurfaceEmbedderPtr embedder) {
surface_embedder_ = std::move(embedder);
}
void SetSurfaceIdForTesting(const viz::SurfaceId&, base::TimeTicks);
private:
......@@ -123,6 +127,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter
cc::VideoFrameProvider* video_frame_provider_ = nullptr;
scoped_refptr<viz::ContextProvider> context_provider_;
viz::mojom::blink::CompositorFrameSinkPtr compositor_frame_sink_;
mojom::blink::SurfaceEmbedderPtr surface_embedder_;
mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_;
WebContextProviderCallback context_provider_callback_;
std::unique_ptr<VideoFrameResourceProvider> resource_provider_;
......@@ -150,6 +155,8 @@ class PLATFORM_EXPORT VideoFrameSubmitter
// size.
viz::ChildLocalSurfaceIdAllocator child_local_surface_id_allocator_;
const bool enable_surface_synchronization_;
THREAD_CHECKER(media_thread_checker_);
base::WeakPtrFactory<VideoFrameSubmitter> weak_ptr_factory_;
......
......@@ -172,6 +172,9 @@ class VideoFrameSubmitterTest : public testing::Test {
// testing easier without having to worry about the first sent frame.
submitter_->UpdateSubmissionState(true);
submitter_->SetCompositorFrameSinkPtrForTesting(&submitter_sink);
mojom::blink::SurfaceEmbedderPtr embedder;
mojo::MakeRequest(&embedder);
submitter_->SetSurfaceEmbedderPtrForTesting(std::move(embedder));
submitter_->SetSurfaceIdForTesting(
viz::SurfaceId(
viz::FrameSinkId(1, 1),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment