Commit 79f7c91a authored by CJ DiMeglio's avatar CJ DiMeglio Committed by Commit Bot

Moves cc::Surfaces for Videos onto its own thread.

Previously we were running the cc::Surface for Videos project on the media thread.
This was found to cause some smoothness regressions. This CL fixes that by pushing the
work onto its own thread.

TBR=gab@chromium.org

Bug: 866508
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_slimming_paint_v2;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: Ide12cb6cebc9dea83a7686c09e6688537bf3389a
Reviewed-on: https://chromium-review.googlesource.com/1176879
Commit-Queue: CJ DiMeglio <lethalantidote@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarKenneth Russell <kbr@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#587811}
parent 08acb899
...@@ -23,6 +23,9 @@ class ScopedAllowInitGLBindings; ...@@ -23,6 +23,9 @@ class ScopedAllowInitGLBindings;
namespace audio { namespace audio {
class OutputDevice; class OutputDevice;
} }
namespace blink {
class VideoFrameResourceProvider;
}
namespace cc { namespace cc {
class CompletionEvent; class CompletionEvent;
class SingleThreadTaskGraphRunner; class SingleThreadTaskGraphRunner;
...@@ -330,6 +333,7 @@ class BASE_EXPORT ScopedAllowBaseSyncPrimitives { ...@@ -330,6 +333,7 @@ class BASE_EXPORT ScopedAllowBaseSyncPrimitives {
LaunchXdgUtilityScopedAllowBaseSyncPrimitives; LaunchXdgUtilityScopedAllowBaseSyncPrimitives;
friend class webrtc::DesktopConfigurationMonitor; friend class webrtc::DesktopConfigurationMonitor;
friend class content::ServiceWorkerSubresourceLoader; friend class content::ServiceWorkerSubresourceLoader;
friend class blink::VideoFrameResourceProvider;
ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF; ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF;
~ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF; ~ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "content/renderer/render_frame_impl.h" #include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_thread_impl.h" #include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h" #include "content/renderer/render_view_impl.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/cdm_factory.h" #include "media/base/cdm_factory.h"
#include "media/base/decoder_factory.h" #include "media/base/decoder_factory.h"
#include "media/base/media_switches.h" #include "media/base/media_switches.h"
...@@ -100,38 +101,26 @@ class FrameFetchContext : public media::ResourceFetchContext { ...@@ -100,38 +101,26 @@ class FrameFetchContext : public media::ResourceFetchContext {
DISALLOW_COPY_AND_ASSIGN(FrameFetchContext); DISALLOW_COPY_AND_ASSIGN(FrameFetchContext);
}; };
void ObtainAndSetContextProvider(
base::OnceCallback<void(bool,
scoped_refptr<ws::ContextProviderCommandBuffer>)>
set_context_provider_callback,
std::pair<media::GpuVideoAcceleratorFactories*, bool> gpu_info) {
if (gpu_info.first) {
scoped_refptr<ws::ContextProviderCommandBuffer> context_provider =
gpu_info.first->GetMediaContextProvider();
std::move(set_context_provider_callback)
.Run(gpu_info.second, std::move(context_provider));
} else {
std::move(set_context_provider_callback).Run(false, nullptr);
}
}
// Obtains the media ContextProvider and calls the given callback on the same // Obtains the media ContextProvider and calls the given callback on the same
// thread this is called on. Obtaining the media ContextProvider requires // thread this is called on. Obtaining the media ContextProvider requires
// getting GPuVideoAcceleratorFactories, which must be done on the main // establishing a GPUChannelHost, which must be done on the main thread.
// thread. void PostContextProviderToCallback(
void PostMediaContextProviderToCallback(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
base::OnceCallback<void(bool, scoped_refptr<viz::ContextProvider> unwanted_context_provider,
scoped_refptr<ws::ContextProviderCommandBuffer>)> blink::WebSubmitterConfigurationCallback set_context_provider_callback) {
set_context_provider_callback) { main_task_runner->PostTask(
base::PostTaskAndReplyWithResult( FROM_HERE,
main_task_runner.get(), FROM_HERE, base::BindOnce([]() { base::BindOnce(
return std::pair<media::GpuVideoAcceleratorFactories*, bool>( [](scoped_refptr<viz::ContextProvider> unwanted_context_provider,
content::RenderThreadImpl::current()->GetGpuFactories(), blink::WebSubmitterConfigurationCallback cb) {
!content::RenderThreadImpl::current()->IsGpuCompositingDisabled()); auto* rti = content::RenderThreadImpl::current();
}), auto context_provider = rti->GetVideoFrameCompositorContextProvider(
base::BindOnce(&ObtainAndSetContextProvider, unwanted_context_provider);
std::move(set_context_provider_callback))); std::move(cb).Run(!rti->IsGpuCompositingDisabled(),
std::move(context_provider));
},
std::move(unwanted_context_provider),
media::BindToCurrentLoop(std::move(set_context_provider_callback))));
} }
} // namespace } // namespace
...@@ -307,12 +296,11 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer( ...@@ -307,12 +296,11 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
std::unique_ptr<blink::WebVideoFrameSubmitter> submitter; std::unique_ptr<blink::WebVideoFrameSubmitter> submitter;
bool use_surface_layer_for_video = VideoSurfaceLayerEnabled(); bool use_surface_layer_for_video = VideoSurfaceLayerEnabled();
if (use_surface_layer_for_video) { if (use_surface_layer_for_video) {
// TODO(lethalantidote): Use a separate task_runner. https://crbug/753605.
video_frame_compositor_task_runner = video_frame_compositor_task_runner =
render_thread->GetMediaThreadTaskRunner(); render_thread->CreateVideoFrameCompositorTaskRunner();
submitter = blink::WebVideoFrameSubmitter::Create( submitter = blink::WebVideoFrameSubmitter::Create(
base::BindRepeating( base::BindRepeating(
&PostMediaContextProviderToCallback, &PostContextProviderToCallback,
RenderThreadImpl::current()->GetCompositorMainThreadTaskRunner()), RenderThreadImpl::current()->GetCompositorMainThreadTaskRunner()),
settings); settings);
} else { } else {
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/threading/simple_thread.h" #include "base/threading/simple_thread.h"
#include "base/threading/thread_local.h" #include "base/threading/thread_local.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
...@@ -1191,6 +1192,21 @@ void RenderThreadImpl::InitializeCompositorThread() { ...@@ -1191,6 +1192,21 @@ void RenderThreadImpl::InitializeCompositorThread() {
#endif #endif
} }
scoped_refptr<base::SingleThreadTaskRunner>
RenderThreadImpl::CreateVideoFrameCompositorTaskRunner() {
if (!video_frame_compositor_task_runner_) {
// All of Chromium's GPU code must know which thread it's running on, and
// be the same thread on which the rendering context was initialized. This
// is why this must be a SingleThreadTaskRunner instead of a
// SequencedTaskRunner.
video_frame_compositor_task_runner_ =
base::CreateSingleThreadTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE});
}
return video_frame_compositor_task_runner_;
}
void RenderThreadImpl::InitializeWebKit( void RenderThreadImpl::InitializeWebKit(
service_manager::BinderRegistry* registry) { service_manager::BinderRegistry* registry) {
DCHECK(!blink_platform_impl_); DCHECK(!blink_platform_impl_);
...@@ -1434,6 +1450,39 @@ media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() { ...@@ -1434,6 +1450,39 @@ media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() {
return gpu_factories_.back().get(); return gpu_factories_.back().get();
} }
scoped_refptr<viz::ContextProvider>
RenderThreadImpl::GetVideoFrameCompositorContextProvider(
scoped_refptr<viz::ContextProvider> unwanted_context_provider) {
if (video_frame_compositor_context_provider_ &&
video_frame_compositor_context_provider_ != unwanted_context_provider) {
return video_frame_compositor_context_provider_;
}
video_frame_compositor_context_provider_ = nullptr;
scoped_refptr<gpu::GpuChannelHost> gpu_channel_host =
EstablishGpuChannelSync();
if (!gpu_channel_host)
return nullptr;
// This context is only used to create textures and mailbox them, so
// use lower limits than the default.
gpu::SharedMemoryLimits limits = gpu::SharedMemoryLimits::ForMailboxContext();
bool support_locking = false;
bool support_gles2_interface = true;
bool support_raster_interface = false;
bool support_oop_rasterization = false;
bool support_grcontext = false;
video_frame_compositor_context_provider_ = CreateOffscreenContext(
gpu_channel_host, GetGpuMemoryBufferManager(), limits, support_locking,
support_gles2_interface, support_raster_interface,
support_oop_rasterization, support_grcontext,
ws::command_buffer_metrics::ContextType::RENDER_COMPOSITOR,
kGpuStreamIdMedia, kGpuStreamPriorityMedia);
return video_frame_compositor_context_provider_;
}
scoped_refptr<ws::ContextProviderCommandBuffer> scoped_refptr<ws::ContextProviderCommandBuffer>
RenderThreadImpl::SharedMainThreadContextProvider() { RenderThreadImpl::SharedMainThreadContextProvider() {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
......
...@@ -392,6 +392,13 @@ class CONTENT_EXPORT RenderThreadImpl ...@@ -392,6 +392,13 @@ class CONTENT_EXPORT RenderThreadImpl
// A TaskRunner instance that runs tasks on the raster worker pool. // A TaskRunner instance that runs tasks on the raster worker pool.
base::TaskRunner* GetWorkerTaskRunner(); base::TaskRunner* GetWorkerTaskRunner();
// Creates a ContextProvider if yet created, and returns it to be used for
// video frame compositing. The ContextProvider given as an argument is
// one that has been lost, and is a hint to the RenderThreadImpl to clear
// it's |video_frame_compositor_context_provider_| if it matches.
scoped_refptr<viz::ContextProvider> GetVideoFrameCompositorContextProvider(
scoped_refptr<viz::ContextProvider>);
// Returns a worker context provider that will be bound on the compositor // Returns a worker context provider that will be bound on the compositor
// thread. // thread.
scoped_refptr<viz::RasterContextProvider> scoped_refptr<viz::RasterContextProvider>
...@@ -508,6 +515,9 @@ class CONTENT_EXPORT RenderThreadImpl ...@@ -508,6 +515,9 @@ class CONTENT_EXPORT RenderThreadImpl
// Sets the current pipeline rendering color space. // Sets the current pipeline rendering color space.
void SetRenderingColorSpace(const gfx::ColorSpace& color_space); void SetRenderingColorSpace(const gfx::ColorSpace& color_space);
scoped_refptr<base::SingleThreadTaskRunner>
CreateVideoFrameCompositorTaskRunner();
private: private:
void OnProcessFinalRelease() override; void OnProcessFinalRelease() override;
// IPC::Listener // IPC::Listener
...@@ -676,6 +686,10 @@ class CONTENT_EXPORT RenderThreadImpl ...@@ -676,6 +686,10 @@ class CONTENT_EXPORT RenderThreadImpl
// regardless of whether |compositor_thread_| is overriden. // regardless of whether |compositor_thread_| is overriden.
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
// Task to run the VideoFrameCompositor on.
scoped_refptr<base::SingleThreadTaskRunner>
video_frame_compositor_task_runner_;
// Pool of workers used for raster operations (e.g., tile rasterization). // Pool of workers used for raster operations (e.g., tile rasterization).
scoped_refptr<CategorizedWorkerPool> categorized_worker_pool_; scoped_refptr<CategorizedWorkerPool> categorized_worker_pool_;
...@@ -687,6 +701,8 @@ class CONTENT_EXPORT RenderThreadImpl ...@@ -687,6 +701,8 @@ class CONTENT_EXPORT RenderThreadImpl
base::ObserverList<RenderThreadObserver>::Unchecked observers_; base::ObserverList<RenderThreadObserver>::Unchecked observers_;
scoped_refptr<viz::ContextProvider> video_frame_compositor_context_provider_;
scoped_refptr<viz::RasterContextProvider> shared_worker_context_provider_; scoped_refptr<viz::RasterContextProvider> shared_worker_context_provider_;
std::unique_ptr<AudioRendererMixerManager> audio_renderer_mixer_manager_; std::unique_ptr<AudioRendererMixerManager> audio_renderer_mixer_manager_;
......
...@@ -14,17 +14,20 @@ namespace cc { ...@@ -14,17 +14,20 @@ namespace cc {
class LayerTreeSettings; class LayerTreeSettings;
} }
namespace ws { namespace viz {
class ContextProviderCommandBuffer; class ContextProvider;
} // namespace ui } // namespace viz
namespace blink { namespace blink {
// Sets the proper context_provider and compositing mode onto the Submitter.
using WebSubmitterConfigurationCallback =
base::OnceCallback<void(bool, scoped_refptr<viz::ContextProvider>)>;
// Callback to obtain the media ContextProvider and a bool indicating whether // Callback to obtain the media ContextProvider and a bool indicating whether
// we are in software compositing mode. // we are in software compositing mode.
using WebContextProviderCallback = base::RepeatingCallback<void( using WebContextProviderCallback =
base::OnceCallback<void(bool, base::RepeatingCallback<void(scoped_refptr<viz::ContextProvider>,
scoped_refptr<ws::ContextProviderCommandBuffer>)>)>; WebSubmitterConfigurationCallback)>;
using WebFrameSinkDestroyedCallback = base::RepeatingCallback<void()>; using WebFrameSinkDestroyedCallback = base::RepeatingCallback<void()>;
// Exposes the VideoFrameSubmitter, which submits CompositorFrames containing // Exposes the VideoFrameSubmitter, which submits CompositorFrames containing
......
...@@ -7,6 +7,7 @@ include_rules = [ ...@@ -7,6 +7,7 @@ include_rules = [
# Dependencies. # Dependencies.
"+base/threading/sequenced_task_runner_handle.h", "+base/threading/sequenced_task_runner_handle.h",
"+base/threading/thread_restrictions.h",
"+cc", "+cc",
"+components/viz/client", "+components/viz/client",
"+components/viz/common", "+components/viz/common",
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <memory> #include <memory>
#include "base/bind.h" #include "base/bind.h"
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "components/viz/client/client_resource_provider.h" #include "components/viz/client/client_resource_provider.h"
#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/gpu/context_provider.h"
...@@ -92,7 +93,11 @@ void VideoFrameResourceProvider::AppendQuads( ...@@ -92,7 +93,11 @@ void VideoFrameResourceProvider::AppendQuads(
break; break;
} }
// When obtaining frame resources, we end up having to wait. See
// https://crbug/878070.
base::ScopedAllowBaseSyncPrimitives allow_base_sync_primitives;
resource_updater_->ObtainFrameResources(frame); resource_updater_->ObtainFrameResources(frame);
// TODO(lethalantidote) : update with true value; // TODO(lethalantidote) : update with true value;
gfx::Rect visible_layer_rect = gfx::Rect(rotated_size); gfx::Rect visible_layer_rect = gfx::Rect(rotated_size);
gfx::Rect clip_rect = gfx::Rect(frame->coded_size()); gfx::Rect clip_rect = gfx::Rect(frame->coded_size());
......
...@@ -56,7 +56,6 @@ class PLATFORM_EXPORT VideoFrameResourceProvider { ...@@ -56,7 +56,6 @@ class PLATFORM_EXPORT VideoFrameResourceProvider {
private: private:
const cc::LayerTreeSettings settings_; const cc::LayerTreeSettings settings_;
WebContextProviderCallback context_provider_callback_;
viz::ContextProvider* context_provider_; viz::ContextProvider* context_provider_;
std::unique_ptr<viz::ClientResourceProvider> resource_provider_; std::unique_ptr<viz::ClientResourceProvider> resource_provider_;
std::unique_ptr<media::VideoResourceUpdater> resource_updater_; std::unique_ptr<media::VideoResourceUpdater> resource_updater_;
......
...@@ -25,7 +25,8 @@ namespace blink { ...@@ -25,7 +25,8 @@ namespace blink {
namespace { namespace {
// Delay to retry getting the context_provider. // Delay to retry getting the context_provider.
constexpr int kGetContextProviderRetryMS = 150; constexpr base::TimeDelta kGetContextProviderRetryTimeout =
base::TimeDelta::FromMilliseconds(150);
} // namespace } // namespace
...@@ -162,33 +163,45 @@ void VideoFrameSubmitter::Initialize(cc::VideoFrameProvider* provider) { ...@@ -162,33 +163,45 @@ void VideoFrameSubmitter::Initialize(cc::VideoFrameProvider* provider) {
DCHECK(!provider_); DCHECK(!provider_);
provider_ = provider; provider_ = provider;
context_provider_callback_.Run( context_provider_callback_.Run(
base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider, nullptr, base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
} }
} }
void VideoFrameSubmitter::OnReceivedContextProvider( void VideoFrameSubmitter::OnReceivedContextProvider(
bool use_gpu_compositing, bool use_gpu_compositing,
scoped_refptr<ws::ContextProviderCommandBuffer> context_provider) { scoped_refptr<viz::ContextProvider> context_provider) {
// We could get a null |context_provider| back if the context is still lost. if (!use_gpu_compositing) {
if (!context_provider && use_gpu_compositing) { resource_provider_->Initialize(nullptr, this);
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(
context_provider_callback_,
base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
weak_ptr_factory_.GetWeakPtr())),
base::TimeDelta::FromMilliseconds(kGetContextProviderRetryMS));
return; return;
} }
context_provider_ = std::move(context_provider); bool has_good_context = false;
if (use_gpu_compositing) { while (!has_good_context) {
context_provider_->AddObserver(this); if (!context_provider) {
resource_provider_->Initialize(context_provider_.get(), nullptr); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
} else { FROM_HERE,
resource_provider_->Initialize(nullptr, this); base::BindOnce(
context_provider_callback_, context_provider_,
base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
weak_ptr_factory_.GetWeakPtr())),
kGetContextProviderRetryTimeout);
return;
}
// Note that |context_provider| is now null after the move, such that if we
// end up having !|has_good_context|, we will retry to obtain the
// context_provider.
context_provider_ = std::move(context_provider);
auto result = context_provider_->BindToCurrentThread();
has_good_context =
result == gpu::ContextResult::kSuccess ||
context_provider_->ContextGL()->GetGraphicsResetStatusKHR() ==
GL_NO_ERROR;
} }
context_provider_->AddObserver(this);
resource_provider_->Initialize(context_provider_.get(), nullptr);
if (frame_sink_id_.is_valid()) if (frame_sink_id_.is_valid())
StartSubmitting(); StartSubmitting();
...@@ -339,7 +352,6 @@ void VideoFrameSubmitter::OnContextLost() { ...@@ -339,7 +352,6 @@ void VideoFrameSubmitter::OnContextLost() {
if (context_provider_) { if (context_provider_) {
context_provider_->RemoveObserver(this); context_provider_->RemoveObserver(this);
context_provider_ = nullptr;
} }
waiting_for_compositor_ack_ = false; waiting_for_compositor_ack_ = false;
...@@ -349,6 +361,7 @@ void VideoFrameSubmitter::OnContextLost() { ...@@ -349,6 +361,7 @@ void VideoFrameSubmitter::OnContextLost() {
compositor_frame_sink_.reset(); compositor_frame_sink_.reset();
context_provider_callback_.Run( context_provider_callback_.Run(
context_provider_,
base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider, base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
......
...@@ -47,9 +47,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter ...@@ -47,9 +47,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter
return &binding_; return &binding_;
} }
void OnReceivedContextProvider( void OnReceivedContextProvider(bool, scoped_refptr<viz::ContextProvider>);
bool,
scoped_refptr<ws::ContextProviderCommandBuffer>);
// cc::VideoFrameProvider::Client implementation. // cc::VideoFrameProvider::Client implementation.
void StopUsingProvider() override; void StopUsingProvider() override;
...@@ -118,7 +116,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter ...@@ -118,7 +116,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter
bool ShouldSubmit() const; bool ShouldSubmit() const;
cc::VideoFrameProvider* provider_ = nullptr; cc::VideoFrameProvider* provider_ = nullptr;
scoped_refptr<ws::ContextProviderCommandBuffer> context_provider_; scoped_refptr<viz::ContextProvider> context_provider_;
viz::mojom::blink::CompositorFrameSinkPtr compositor_frame_sink_; viz::mojom::blink::CompositorFrameSinkPtr compositor_frame_sink_;
mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_; mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_;
WebContextProviderCallback context_provider_callback_; WebContextProviderCallback context_provider_callback_;
......
...@@ -148,8 +148,9 @@ class VideoFrameSubmitterTest : public testing::Test { ...@@ -148,8 +148,9 @@ class VideoFrameSubmitterTest : public testing::Test {
context_provider_.get(), nullptr); context_provider_.get(), nullptr);
submitter_ = std::make_unique<VideoFrameSubmitter>( submitter_ = std::make_unique<VideoFrameSubmitter>(
base::BindRepeating( base::BindRepeating(
[](base::OnceCallback<void( [](scoped_refptr<viz::ContextProvider>,
bool, scoped_refptr<ws::ContextProviderCommandBuffer>)>) {}), base::OnceCallback<void(
bool, scoped_refptr<viz::ContextProvider>)>) {}),
base::WrapUnique<MockVideoFrameResourceProvider>(resource_provider_)); base::WrapUnique<MockVideoFrameResourceProvider>(resource_provider_));
submitter_->Initialize(provider_.get()); submitter_->Initialize(provider_.get());
......
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