Skip to content

Commit 79f7c91

Browse files
CJ DiMeglioCommit Bot
authored andcommitted
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. [email protected] 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 <[email protected]> Reviewed-by: François Doray <[email protected]> Reviewed-by: Mounir Lamouri <[email protected]> Reviewed-by: Dale Curtis <[email protected]> Reviewed-by: Kenneth Russell <[email protected]> Reviewed-by: Avi Drissman <[email protected]> Cr-Commit-Position: refs/heads/master@{#587811}
1 parent 08acb89 commit 79f7c91

File tree

11 files changed

+142
-65
lines changed

11 files changed

+142
-65
lines changed

base/threading/thread_restrictions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ class ScopedAllowInitGLBindings;
2323
namespace audio {
2424
class OutputDevice;
2525
}
26+
namespace blink {
27+
class VideoFrameResourceProvider;
28+
}
2629
namespace cc {
2730
class CompletionEvent;
2831
class SingleThreadTaskGraphRunner;
@@ -330,6 +333,7 @@ class BASE_EXPORT ScopedAllowBaseSyncPrimitives {
330333
LaunchXdgUtilityScopedAllowBaseSyncPrimitives;
331334
friend class webrtc::DesktopConfigurationMonitor;
332335
friend class content::ServiceWorkerSubresourceLoader;
336+
friend class blink::VideoFrameResourceProvider;
333337

334338
ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF;
335339
~ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF;

content/renderer/media/media_factory.cc

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "content/renderer/render_frame_impl.h"
2525
#include "content/renderer/render_thread_impl.h"
2626
#include "content/renderer/render_view_impl.h"
27+
#include "media/base/bind_to_current_loop.h"
2728
#include "media/base/cdm_factory.h"
2829
#include "media/base/decoder_factory.h"
2930
#include "media/base/media_switches.h"
@@ -100,38 +101,26 @@ class FrameFetchContext : public media::ResourceFetchContext {
100101
DISALLOW_COPY_AND_ASSIGN(FrameFetchContext);
101102
};
102103

103-
void ObtainAndSetContextProvider(
104-
base::OnceCallback<void(bool,
105-
scoped_refptr<ws::ContextProviderCommandBuffer>)>
106-
set_context_provider_callback,
107-
std::pair<media::GpuVideoAcceleratorFactories*, bool> gpu_info) {
108-
if (gpu_info.first) {
109-
scoped_refptr<ws::ContextProviderCommandBuffer> context_provider =
110-
gpu_info.first->GetMediaContextProvider();
111-
std::move(set_context_provider_callback)
112-
.Run(gpu_info.second, std::move(context_provider));
113-
} else {
114-
std::move(set_context_provider_callback).Run(false, nullptr);
115-
}
116-
}
117-
118104
// Obtains the media ContextProvider and calls the given callback on the same
119105
// thread this is called on. Obtaining the media ContextProvider requires
120-
// getting GPuVideoAcceleratorFactories, which must be done on the main
121-
// thread.
122-
void PostMediaContextProviderToCallback(
106+
// establishing a GPUChannelHost, which must be done on the main thread.
107+
void PostContextProviderToCallback(
123108
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
124-
base::OnceCallback<void(bool,
125-
scoped_refptr<ws::ContextProviderCommandBuffer>)>
126-
set_context_provider_callback) {
127-
base::PostTaskAndReplyWithResult(
128-
main_task_runner.get(), FROM_HERE, base::BindOnce([]() {
129-
return std::pair<media::GpuVideoAcceleratorFactories*, bool>(
130-
content::RenderThreadImpl::current()->GetGpuFactories(),
131-
!content::RenderThreadImpl::current()->IsGpuCompositingDisabled());
132-
}),
133-
base::BindOnce(&ObtainAndSetContextProvider,
134-
std::move(set_context_provider_callback)));
109+
scoped_refptr<viz::ContextProvider> unwanted_context_provider,
110+
blink::WebSubmitterConfigurationCallback set_context_provider_callback) {
111+
main_task_runner->PostTask(
112+
FROM_HERE,
113+
base::BindOnce(
114+
[](scoped_refptr<viz::ContextProvider> unwanted_context_provider,
115+
blink::WebSubmitterConfigurationCallback cb) {
116+
auto* rti = content::RenderThreadImpl::current();
117+
auto context_provider = rti->GetVideoFrameCompositorContextProvider(
118+
unwanted_context_provider);
119+
std::move(cb).Run(!rti->IsGpuCompositingDisabled(),
120+
std::move(context_provider));
121+
},
122+
std::move(unwanted_context_provider),
123+
media::BindToCurrentLoop(std::move(set_context_provider_callback))));
135124
}
136125

137126
} // namespace
@@ -307,12 +296,11 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
307296
std::unique_ptr<blink::WebVideoFrameSubmitter> submitter;
308297
bool use_surface_layer_for_video = VideoSurfaceLayerEnabled();
309298
if (use_surface_layer_for_video) {
310-
// TODO(lethalantidote): Use a separate task_runner. https://crbug/753605.
311299
video_frame_compositor_task_runner =
312-
render_thread->GetMediaThreadTaskRunner();
300+
render_thread->CreateVideoFrameCompositorTaskRunner();
313301
submitter = blink::WebVideoFrameSubmitter::Create(
314302
base::BindRepeating(
315-
&PostMediaContextProviderToCallback,
303+
&PostContextProviderToCallback,
316304
RenderThreadImpl::current()->GetCompositorMainThreadTaskRunner()),
317305
settings);
318306
} else {

content/renderer/render_thread_impl.cc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "base/strings/string_split.h"
3232
#include "base/strings/sys_string_conversions.h"
3333
#include "base/strings/utf_string_conversions.h"
34+
#include "base/task/post_task.h"
3435
#include "base/threading/simple_thread.h"
3536
#include "base/threading/thread_local.h"
3637
#include "base/threading/thread_restrictions.h"
@@ -1191,6 +1192,21 @@ void RenderThreadImpl::InitializeCompositorThread() {
11911192
#endif
11921193
}
11931194

1195+
scoped_refptr<base::SingleThreadTaskRunner>
1196+
RenderThreadImpl::CreateVideoFrameCompositorTaskRunner() {
1197+
if (!video_frame_compositor_task_runner_) {
1198+
// All of Chromium's GPU code must know which thread it's running on, and
1199+
// be the same thread on which the rendering context was initialized. This
1200+
// is why this must be a SingleThreadTaskRunner instead of a
1201+
// SequencedTaskRunner.
1202+
video_frame_compositor_task_runner_ =
1203+
base::CreateSingleThreadTaskRunnerWithTraits(
1204+
{base::MayBlock(), base::TaskPriority::USER_VISIBLE});
1205+
}
1206+
1207+
return video_frame_compositor_task_runner_;
1208+
}
1209+
11941210
void RenderThreadImpl::InitializeWebKit(
11951211
service_manager::BinderRegistry* registry) {
11961212
DCHECK(!blink_platform_impl_);
@@ -1434,6 +1450,39 @@ media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() {
14341450
return gpu_factories_.back().get();
14351451
}
14361452

1453+
scoped_refptr<viz::ContextProvider>
1454+
RenderThreadImpl::GetVideoFrameCompositorContextProvider(
1455+
scoped_refptr<viz::ContextProvider> unwanted_context_provider) {
1456+
if (video_frame_compositor_context_provider_ &&
1457+
video_frame_compositor_context_provider_ != unwanted_context_provider) {
1458+
return video_frame_compositor_context_provider_;
1459+
}
1460+
1461+
video_frame_compositor_context_provider_ = nullptr;
1462+
1463+
scoped_refptr<gpu::GpuChannelHost> gpu_channel_host =
1464+
EstablishGpuChannelSync();
1465+
if (!gpu_channel_host)
1466+
return nullptr;
1467+
1468+
// This context is only used to create textures and mailbox them, so
1469+
// use lower limits than the default.
1470+
gpu::SharedMemoryLimits limits = gpu::SharedMemoryLimits::ForMailboxContext();
1471+
1472+
bool support_locking = false;
1473+
bool support_gles2_interface = true;
1474+
bool support_raster_interface = false;
1475+
bool support_oop_rasterization = false;
1476+
bool support_grcontext = false;
1477+
video_frame_compositor_context_provider_ = CreateOffscreenContext(
1478+
gpu_channel_host, GetGpuMemoryBufferManager(), limits, support_locking,
1479+
support_gles2_interface, support_raster_interface,
1480+
support_oop_rasterization, support_grcontext,
1481+
ws::command_buffer_metrics::ContextType::RENDER_COMPOSITOR,
1482+
kGpuStreamIdMedia, kGpuStreamPriorityMedia);
1483+
return video_frame_compositor_context_provider_;
1484+
}
1485+
14371486
scoped_refptr<ws::ContextProviderCommandBuffer>
14381487
RenderThreadImpl::SharedMainThreadContextProvider() {
14391488
DCHECK(IsMainThread());

content/renderer/render_thread_impl.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,13 @@ class CONTENT_EXPORT RenderThreadImpl
392392
// A TaskRunner instance that runs tasks on the raster worker pool.
393393
base::TaskRunner* GetWorkerTaskRunner();
394394

395+
// Creates a ContextProvider if yet created, and returns it to be used for
396+
// video frame compositing. The ContextProvider given as an argument is
397+
// one that has been lost, and is a hint to the RenderThreadImpl to clear
398+
// it's |video_frame_compositor_context_provider_| if it matches.
399+
scoped_refptr<viz::ContextProvider> GetVideoFrameCompositorContextProvider(
400+
scoped_refptr<viz::ContextProvider>);
401+
395402
// Returns a worker context provider that will be bound on the compositor
396403
// thread.
397404
scoped_refptr<viz::RasterContextProvider>
@@ -508,6 +515,9 @@ class CONTENT_EXPORT RenderThreadImpl
508515
// Sets the current pipeline rendering color space.
509516
void SetRenderingColorSpace(const gfx::ColorSpace& color_space);
510517

518+
scoped_refptr<base::SingleThreadTaskRunner>
519+
CreateVideoFrameCompositorTaskRunner();
520+
511521
private:
512522
void OnProcessFinalRelease() override;
513523
// IPC::Listener
@@ -676,6 +686,10 @@ class CONTENT_EXPORT RenderThreadImpl
676686
// regardless of whether |compositor_thread_| is overriden.
677687
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
678688

689+
// Task to run the VideoFrameCompositor on.
690+
scoped_refptr<base::SingleThreadTaskRunner>
691+
video_frame_compositor_task_runner_;
692+
679693
// Pool of workers used for raster operations (e.g., tile rasterization).
680694
scoped_refptr<CategorizedWorkerPool> categorized_worker_pool_;
681695

@@ -687,6 +701,8 @@ class CONTENT_EXPORT RenderThreadImpl
687701

688702
base::ObserverList<RenderThreadObserver>::Unchecked observers_;
689703

704+
scoped_refptr<viz::ContextProvider> video_frame_compositor_context_provider_;
705+
690706
scoped_refptr<viz::RasterContextProvider> shared_worker_context_provider_;
691707

692708
std::unique_ptr<AudioRendererMixerManager> audio_renderer_mixer_manager_;

third_party/blink/public/platform/web_video_frame_submitter.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,20 @@ namespace cc {
1414
class LayerTreeSettings;
1515
}
1616

17-
namespace ws {
18-
class ContextProviderCommandBuffer;
19-
} // namespace ui
17+
namespace viz {
18+
class ContextProvider;
19+
} // namespace viz
2020

2121
namespace blink {
2222

23+
// Sets the proper context_provider and compositing mode onto the Submitter.
24+
using WebSubmitterConfigurationCallback =
25+
base::OnceCallback<void(bool, scoped_refptr<viz::ContextProvider>)>;
2326
// Callback to obtain the media ContextProvider and a bool indicating whether
2427
// we are in software compositing mode.
25-
using WebContextProviderCallback = base::RepeatingCallback<void(
26-
base::OnceCallback<void(bool,
27-
scoped_refptr<ws::ContextProviderCommandBuffer>)>)>;
28+
using WebContextProviderCallback =
29+
base::RepeatingCallback<void(scoped_refptr<viz::ContextProvider>,
30+
WebSubmitterConfigurationCallback)>;
2831
using WebFrameSinkDestroyedCallback = base::RepeatingCallback<void()>;
2932

3033
// Exposes the VideoFrameSubmitter, which submits CompositorFrames containing

third_party/blink/renderer/platform/graphics/DEPS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ include_rules = [
77

88
# Dependencies.
99
"+base/threading/sequenced_task_runner_handle.h",
10+
"+base/threading/thread_restrictions.h",
1011
"+cc",
1112
"+components/viz/client",
1213
"+components/viz/common",

third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <memory>
88
#include "base/bind.h"
9+
#include "base/threading/thread_restrictions.h"
910
#include "base/trace_event/trace_event.h"
1011
#include "components/viz/client/client_resource_provider.h"
1112
#include "components/viz/common/gpu/context_provider.h"
@@ -92,7 +93,11 @@ void VideoFrameResourceProvider::AppendQuads(
9293
break;
9394
}
9495

96+
// When obtaining frame resources, we end up having to wait. See
97+
// https://crbug/878070.
98+
base::ScopedAllowBaseSyncPrimitives allow_base_sync_primitives;
9599
resource_updater_->ObtainFrameResources(frame);
100+
96101
// TODO(lethalantidote) : update with true value;
97102
gfx::Rect visible_layer_rect = gfx::Rect(rotated_size);
98103
gfx::Rect clip_rect = gfx::Rect(frame->coded_size());

third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ class PLATFORM_EXPORT VideoFrameResourceProvider {
5656
private:
5757
const cc::LayerTreeSettings settings_;
5858

59-
WebContextProviderCallback context_provider_callback_;
6059
viz::ContextProvider* context_provider_;
6160
std::unique_ptr<viz::ClientResourceProvider> resource_provider_;
6261
std::unique_ptr<media::VideoResourceUpdater> resource_updater_;

third_party/blink/renderer/platform/graphics/video_frame_submitter.cc

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ namespace blink {
2525
namespace {
2626

2727
// Delay to retry getting the context_provider.
28-
constexpr int kGetContextProviderRetryMS = 150;
28+
constexpr base::TimeDelta kGetContextProviderRetryTimeout =
29+
base::TimeDelta::FromMilliseconds(150);
2930

3031
} // namespace
3132

@@ -162,33 +163,45 @@ void VideoFrameSubmitter::Initialize(cc::VideoFrameProvider* provider) {
162163
DCHECK(!provider_);
163164
provider_ = provider;
164165
context_provider_callback_.Run(
165-
base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
166-
weak_ptr_factory_.GetWeakPtr()));
166+
nullptr, base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
167+
weak_ptr_factory_.GetWeakPtr()));
167168
}
168169
}
169170

170171
void VideoFrameSubmitter::OnReceivedContextProvider(
171172
bool use_gpu_compositing,
172-
scoped_refptr<ws::ContextProviderCommandBuffer> context_provider) {
173-
// We could get a null |context_provider| back if the context is still lost.
174-
if (!context_provider && use_gpu_compositing) {
175-
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
176-
FROM_HERE,
177-
base::BindOnce(
178-
context_provider_callback_,
179-
base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
180-
weak_ptr_factory_.GetWeakPtr())),
181-
base::TimeDelta::FromMilliseconds(kGetContextProviderRetryMS));
173+
scoped_refptr<viz::ContextProvider> context_provider) {
174+
if (!use_gpu_compositing) {
175+
resource_provider_->Initialize(nullptr, this);
182176
return;
183177
}
184178

185-
context_provider_ = std::move(context_provider);
186-
if (use_gpu_compositing) {
187-
context_provider_->AddObserver(this);
188-
resource_provider_->Initialize(context_provider_.get(), nullptr);
189-
} else {
190-
resource_provider_->Initialize(nullptr, this);
179+
bool has_good_context = false;
180+
while (!has_good_context) {
181+
if (!context_provider) {
182+
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
183+
FROM_HERE,
184+
base::BindOnce(
185+
context_provider_callback_, context_provider_,
186+
base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
187+
weak_ptr_factory_.GetWeakPtr())),
188+
kGetContextProviderRetryTimeout);
189+
return;
190+
}
191+
192+
// Note that |context_provider| is now null after the move, such that if we
193+
// end up having !|has_good_context|, we will retry to obtain the
194+
// context_provider.
195+
context_provider_ = std::move(context_provider);
196+
auto result = context_provider_->BindToCurrentThread();
197+
198+
has_good_context =
199+
result == gpu::ContextResult::kSuccess ||
200+
context_provider_->ContextGL()->GetGraphicsResetStatusKHR() ==
201+
GL_NO_ERROR;
191202
}
203+
context_provider_->AddObserver(this);
204+
resource_provider_->Initialize(context_provider_.get(), nullptr);
192205

193206
if (frame_sink_id_.is_valid())
194207
StartSubmitting();
@@ -339,7 +352,6 @@ void VideoFrameSubmitter::OnContextLost() {
339352

340353
if (context_provider_) {
341354
context_provider_->RemoveObserver(this);
342-
context_provider_ = nullptr;
343355
}
344356
waiting_for_compositor_ack_ = false;
345357

@@ -349,6 +361,7 @@ void VideoFrameSubmitter::OnContextLost() {
349361
compositor_frame_sink_.reset();
350362

351363
context_provider_callback_.Run(
364+
context_provider_,
352365
base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
353366
weak_ptr_factory_.GetWeakPtr()));
354367

third_party/blink/renderer/platform/graphics/video_frame_submitter.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter
4747
return &binding_;
4848
}
4949

50-
void OnReceivedContextProvider(
51-
bool,
52-
scoped_refptr<ws::ContextProviderCommandBuffer>);
50+
void OnReceivedContextProvider(bool, scoped_refptr<viz::ContextProvider>);
5351

5452
// cc::VideoFrameProvider::Client implementation.
5553
void StopUsingProvider() override;
@@ -118,7 +116,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter
118116
bool ShouldSubmit() const;
119117

120118
cc::VideoFrameProvider* provider_ = nullptr;
121-
scoped_refptr<ws::ContextProviderCommandBuffer> context_provider_;
119+
scoped_refptr<viz::ContextProvider> context_provider_;
122120
viz::mojom::blink::CompositorFrameSinkPtr compositor_frame_sink_;
123121
mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_;
124122
WebContextProviderCallback context_provider_callback_;

0 commit comments

Comments
 (0)