1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/render_thread_impl.h"
13 #include "base/allocator/allocator_extension.h"
14 #include "base/at_exit.h"
15 #include "base/command_line.h"
16 #include "base/lazy_instance.h"
17 #include "base/logging.h"
18 #include "base/macros.h"
19 #include "base/memory/discardable_memory_allocator.h"
20 #include "base/memory/memory_coordinator_client_registry.h"
21 #include "base/memory/shared_memory.h"
22 #include "base/message_loop/message_loop.h"
23 #include "base/metrics/field_trial.h"
24 #include "base/metrics/histogram_functions.h"
25 #include "base/metrics/histogram_macros.h"
26 #include "base/path_service.h"
27 #include "base/process/process_metrics.h"
28 #include "base/run_loop.h"
29 #include "base/strings/string16.h"
30 #include "base/strings/string_number_conversions.h"
31 #include "base/strings/string_split.h"
32 #include "base/strings/sys_string_conversions.h"
33 #include "base/strings/utf_string_conversions.h"
34 #include "base/threading/simple_thread.h"
35 #include "base/threading/thread_local.h"
36 #include "base/threading/thread_restrictions.h"
37 #include "base/threading/thread_task_runner_handle.h"
38 #include "base/trace_event/memory_dump_manager.h"
39 #include "base/trace_event/trace_event.h"
40 #include "base/values.h"
41 #include "build/build_config.h"
42 #include "cc/base/histograms.h"
43 #include "cc/base/switches.h"
44 #include "cc/blink/web_layer_impl.h"
45 #include "cc/raster/task_graph_runner.h"
46 #include "cc/trees/layer_tree_frame_sink.h"
47 #include "cc/trees/layer_tree_host_common.h"
48 #include "cc/trees/layer_tree_settings.h"
49 #include "components/discardable_memory/client/client_discardable_shared_memory_manager.h"
50 #include "components/metrics/public/interfaces/single_sample_metrics.mojom.h"
51 #include "components/metrics/single_sample_metrics.h"
52 #include "components/viz/client/client_layer_tree_frame_sink.h"
53 #include "components/viz/client/client_shared_bitmap_manager.h"
54 #include "components/viz/client/hit_test_data_provider.h"
55 #include "components/viz/client/hit_test_data_provider_draw_quad.h"
56 #include "components/viz/client/hit_test_data_provider_surface_layer.h"
57 #include "components/viz/client/local_surface_id_provider.h"
58 #include "components/viz/common/features.h"
59 #include "components/viz/common/frame_sinks/copy_output_request.h"
60 #include "content/child/memory/child_memory_coordinator_impl.h"
61 #include "content/child/runtime_features.h"
62 #include "content/child/thread_safe_sender.h"
63 #include "content/common/buildflags.h"
64 #include "content/common/content_constants_internal.h"
65 #include "content/common/dom_storage/dom_storage_messages.h"
66 #include "content/common/frame_messages.h"
67 #include "content/common/frame_owner_properties.h"
68 #include "content/common/gpu_stream_constants.h"
69 #include "content/common/view_messages.h"
70 #include "content/public/common/content_constants.h"
71 #include "content/public/common/content_features.h"
72 #include "content/public/common/content_paths.h"
73 #include "content/public/common/content_switches.h"
74 #include "content/public/common/renderer_preferences.h"
75 #include "content/public/common/resource_usage_reporter.mojom.h"
76 #include "content/public/common/resource_usage_reporter_type_converters.h"
77 #include "content/public/common/service_manager_connection.h"
78 #include "content/public/common/service_names.mojom.h"
79 #include "content/public/common/simple_connection_filter.h"
80 #include "content/public/common/url_constants.h"
81 #include "content/public/renderer/content_renderer_client.h"
82 #include "content/public/renderer/render_thread_observer.h"
83 #include "content/public/renderer/render_view_visitor.h"
84 #include "content/renderer/appcache/appcache_dispatcher.h"
85 #include "content/renderer/appcache/appcache_frontend_impl.h"
86 #include "content/renderer/browser_plugin/browser_plugin_manager.h"
87 #include "content/renderer/categorized_worker_pool.h"
88 #include "content/renderer/dom_storage/dom_storage_dispatcher.h"
89 #include "content/renderer/dom_storage/webstoragearea_impl.h"
90 #include "content/renderer/dom_storage/webstoragenamespace_impl.h"
91 #include "content/renderer/effective_connection_type_helper.h"
92 #include "content/renderer/fileapi/file_system_dispatcher.h"
93 #include "content/renderer/fileapi/webfilesystem_impl.h"
94 #include "content/renderer/gpu/frame_swap_message_queue.h"
95 #include "content/renderer/indexed_db/indexed_db_dispatcher.h"
96 #include "content/renderer/input/input_event_filter.h"
97 #include "content/renderer/input/input_handler_manager.h"
98 #include "content/renderer/input/main_thread_input_event_filter.h"
99 #include "content/renderer/input/widget_input_handler_manager.h"
100 #include "content/renderer/loader/resource_dispatcher.h"
101 #include "content/renderer/media/audio_input_message_filter.h"
102 #include "content/renderer/media/audio_message_filter.h"
103 #include "content/renderer/media/audio_renderer_mixer_manager.h"
104 #include "content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h"
105 #include "content/renderer/media/midi/midi_message_filter.h"
106 #include "content/renderer/media/render_media_client.h"
107 #include "content/renderer/media/stream/media_stream_center.h"
108 #include "content/renderer/media/video_capture_impl_manager.h"
109 #include "content/renderer/mus/render_widget_window_tree_client_factory.h"
110 #include "content/renderer/mus/renderer_window_tree_client.h"
111 #include "content/renderer/net_info_helper.h"
112 #include "content/renderer/notifications/notification_dispatcher.h"
113 #include "content/renderer/render_frame_proxy.h"
114 #include "content/renderer/render_process_impl.h"
115 #include "content/renderer/render_view_impl.h"
116 #include "content/renderer/renderer_blink_platform_impl.h"
117 #include "content/renderer/service_worker/embedded_worker_instance_client_impl.h"
118 #include "content/renderer/service_worker/service_worker_context_client.h"
119 #include "content/renderer/service_worker/service_worker_message_filter.h"
120 #include "content/renderer/shared_worker/embedded_shared_worker_stub.h"
121 #include "content/renderer/shared_worker/shared_worker_factory_impl.h"
122 #include "content/renderer/web_database_observer_impl.h"
123 #include "content/renderer/worker_thread_registry.h"
124 #include "device/gamepad/public/cpp/gamepads.h"
125 #include "gin/public/debug.h"
126 #include "gpu/GLES2/gl2extchromium.h"
127 #include "gpu/command_buffer/client/gles2_interface.h"
128 #include "gpu/command_buffer/client/raster_interface.h"
129 #include "gpu/command_buffer/client/shared_memory_limits.h"
130 #include "gpu/config/gpu_switches.h"
131 #include "gpu/ipc/client/command_buffer_proxy_impl.h"
132 #include "gpu/ipc/client/gpu_channel_host.h"
133 #include "ipc/ipc_channel_handle.h"
134 #include "ipc/ipc_channel_mojo.h"
135 #include "ipc/ipc_platform_file.h"
136 #include "media/base/media.h"
137 #include "media/base/media_switches.h"
138 #include "media/media_buildflags.h"
139 #include "media/video/gpu_video_accelerator_factories.h"
140 #include "mojo/public/cpp/bindings/strong_binding.h"
141 #include "mojo/public/cpp/system/message_pipe.h"
142 #include "net/base/net_errors.h"
143 #include "net/base/port_util.h"
144 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
145 #include "net/base/url_util.h"
146 #include "ppapi/buildflags/buildflags.h"
147 #include "services/metrics/public/cpp/mojo_ukm_recorder.h"
148 #include "services/service_manager/public/cpp/connector.h"
149 #include "services/service_manager/public/cpp/interface_provider.h"
150 #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
151 #include "services/ui/public/cpp/gpu/gpu.h"
152 #include "services/ui/public/interfaces/constants.mojom.h"
153 #include "skia/ext/event_tracer_impl.h"
154 #include "skia/ext/skia_memory_dump_provider.h"
155 #include "third_party/blink/public/platform/scheduler/child/webthread_base.h"
156 #include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
157 #include "third_party/blink/public/platform/web_cache.h"
158 #include "third_party/blink/public/platform/web_image_generator.h"
159 #include "third_party/blink/public/platform/web_memory_coordinator.h"
160 #include "third_party/blink/public/platform/web_network_state_notifier.h"
161 #include "third_party/blink/public/platform/web_runtime_features.h"
162 #include "third_party/blink/public/platform/web_string.h"
163 #include "third_party/blink/public/platform/web_thread.h"
164 #include "third_party/blink/public/web/blink.h"
165 #include "third_party/blink/public/web/web_document.h"
166 #include "third_party/blink/public/web/web_frame.h"
167 #include "third_party/blink/public/web/web_script_controller.h"
168 #include "third_party/blink/public/web/web_security_policy.h"
169 #include "third_party/blink/public/web/web_view.h"
170 #include "third_party/boringssl/src/include/openssl/evp.h"
171 #include "third_party/skia/include/core/SkGraphics.h"
172 #include "ui/base/layout.h"
173 #include "ui/base/ui_base_features.h"
174 #include "ui/base/ui_base_switches.h"
175 #include "ui/display/display_switches.h"
176 #include "ui/gl/gl_switches.h"
178 #if BUILDFLAG(ENABLE_WEBRTC)
179 #include "content/renderer/p2p/socket_dispatcher.h"
182 #if defined(OS_ANDROID)
183 #include <cpu-features.h>
184 #include "content/renderer/android/synchronous_compositor_filter.h"
185 #include "content/renderer/android/synchronous_compositor_proxy.h"
186 #include "content/renderer/android/synchronous_layer_tree_frame_sink.h"
187 #include "content/renderer/media/android/stream_texture_factory.h"
188 #include "media/base/android/media_codec_util.h"
191 #if defined(OS_MACOSX)
192 #include "base/mac/mac_util.h"
193 #include "content/renderer/theme_helper_mac.h"
194 #include "content/renderer/webscrollbarbehavior_impl_mac.h"
202 #if BUILDFLAG(ENABLE_WEBRTC)
203 #include "content/renderer/media/stream/aec_dump_message_filter.h"
204 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
205 #include "content/renderer/media/webrtc/peer_connection_tracker.h"
206 #include "content/renderer/media/webrtc/rtc_peer_connection_handler.h"
209 #ifdef ENABLE_VTUNE_JIT_INTERFACE
210 #include "v8/src/third_party/vtune/v8-vtune.h"
213 #if defined(ENABLE_IPC_FUZZER)
214 #include "content/common/external_ipc_dumper.h"
217 #if defined(OS_MACOSX)
218 #include <malloc/malloc.h>
223 using base::ThreadRestrictions;
224 using blink::WebDocument;
225 using blink::WebFrame;
226 using blink::WebNetworkStateNotifier;
227 using blink::WebRuntimeFeatures;
228 using blink::WebScriptController;
229 using blink::WebSecurityPolicy;
230 using blink::WebString;
231 using blink::WebView;
237 const int64_t kInitialIdleHandlerDelayMs = 1000;
238 const int64_t kLongIdleHandlerDelayMs = 30 * 1000;
240 // Maximum allocation size allowed for image scaling filters that
241 // require pre-scaling. Skia will fallback to a filter that doesn't
242 // require pre-scaling if the default filter would require an
243 // allocation that exceeds this limit.
244 const size_t kImageCacheSingleAllocationByteLimit = 64 * 1024 * 1024;
246 #if defined(OS_ANDROID)
247 // Unique identifier for each output surface created.
248 uint32_t g_next_layer_tree_frame_sink_id = 1;
251 // An implementation of mojom::RenderMessageFilter which can be mocked out
252 // for tests which may indirectly send messages over this interface.
253 mojom::RenderMessageFilter* g_render_message_filter_for_testing;
255 // An implementation of RendererBlinkPlatformImpl which can be mocked out
257 RendererBlinkPlatformImpl* g_current_blink_platform_impl_for_testing;
259 // Keep the global RenderThreadImpl in a TLS slot so it is impossible to access
260 // incorrectly from the wrong thread.
261 base::LazyInstance<base::ThreadLocalPointer<RenderThreadImpl>>::DestructorAtExit
262 lazy_tls = LAZY_INSTANCE_INITIALIZER;
264 base::LazyInstance<scoped_refptr<base::SingleThreadTaskRunner>>::
265 DestructorAtExit g_main_task_runner = LAZY_INSTANCE_INITIALIZER;
267 // v8::MemoryPressureLevel should correspond to base::MemoryPressureListener.
268 static_assert(static_cast<v8::MemoryPressureLevel>(
269 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) ==
270 v8::MemoryPressureLevel::kNone, "none level not align");
271 static_assert(static_cast<v8::MemoryPressureLevel>(
272 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE) ==
273 v8::MemoryPressureLevel::kModerate, "moderate level not align");
274 static_assert(static_cast<v8::MemoryPressureLevel>(
275 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) ==
276 v8::MemoryPressureLevel::kCritical, "critical level not align");
278 // WebMemoryPressureLevel should correspond to base::MemoryPressureListener.
279 static_assert(static_cast<blink::WebMemoryPressureLevel>(
280 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) ==
281 blink::kWebMemoryPressureLevelNone,
282 "blink::WebMemoryPressureLevelNone not align");
284 static_cast<blink::WebMemoryPressureLevel>(
285 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE) ==
286 blink::kWebMemoryPressureLevelModerate,
287 "blink::WebMemoryPressureLevelModerate not align");
289 static_cast<blink::WebMemoryPressureLevel>(
290 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) ==
291 blink::kWebMemoryPressureLevelCritical,
292 "blink::WebMemoryPressureLevelCritical not align");
294 void* CreateHistogram(
295 const char *name, int min, int max, size_t buckets) {
298 std::string histogram_name;
299 RenderThreadImpl* render_thread_impl = RenderThreadImpl::current();
300 if (render_thread_impl) { // Can be null in tests.
301 histogram_name = render_thread_impl->
302 histogram_customizer()->ConvertToCustomHistogramName(name);
304 histogram_name = std::string(name);
306 base::HistogramBase* histogram = base::Histogram::FactoryGet(
307 histogram_name, min, max, buckets,
308 base::Histogram::kUmaTargetedHistogramFlag);
312 void AddHistogramSample(void* hist, int sample) {
313 base::Histogram* histogram = static_cast<base::Histogram*>(hist);
314 histogram->Add(sample);
317 class FrameFactoryImpl : public mojom::FrameFactory {
319 explicit FrameFactoryImpl(const service_manager::BindSourceInfo& source_info)
320 : source_info_(source_info), routing_id_highmark_(-1) {}
323 // mojom::FrameFactory:
324 void CreateFrame(int32_t frame_routing_id,
325 mojom::FrameRequest frame_request) override {
326 // TODO(morrita): This is for investigating http://crbug.com/415059 and
327 // should be removed once it is fixed.
328 CHECK_LT(routing_id_highmark_, frame_routing_id);
329 routing_id_highmark_ = frame_routing_id;
331 RenderFrameImpl* frame = RenderFrameImpl::FromRoutingID(frame_routing_id);
332 // We can receive a GetServiceProviderForFrame message for a frame not yet
333 // created due to a race between the message and a
334 // mojom::Renderer::CreateView IPC that triggers creation of the RenderFrame
337 RenderThreadImpl::current()->RegisterPendingFrameCreate(
338 source_info_, frame_routing_id, std::move(frame_request));
342 frame->BindFrame(source_info_, std::move(frame_request));
346 service_manager::BindSourceInfo source_info_;
347 int32_t routing_id_highmark_;
350 void CreateFrameFactory(mojom::FrameFactoryRequest request,
351 const service_manager::BindSourceInfo& source_info) {
352 mojo::MakeStrongBinding(std::make_unique<FrameFactoryImpl>(source_info),
356 scoped_refptr<ui::ContextProviderCommandBuffer> CreateOffscreenContext(
357 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,
358 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
359 const gpu::SharedMemoryLimits& limits,
360 bool support_locking,
361 bool support_gles2_interface,
362 bool support_raster_interface,
363 bool support_oop_rasterization,
364 bool support_grcontext,
365 ui::command_buffer_metrics::ContextType type,
367 gpu::SchedulingPriority stream_priority) {
368 DCHECK(gpu_channel_host);
369 // This is used to create a few different offscreen contexts:
370 // - The shared main thread context, used by blink for 2D Canvas.
371 // - The compositor worker context, used for GPU raster.
372 // - The media context, used for accelerated video decoding.
373 // This is for an offscreen context, so the default framebuffer doesn't need
374 // alpha, depth, stencil, antialiasing.
375 gpu::ContextCreationAttribs attributes;
376 attributes.alpha_size = -1;
377 attributes.depth_size = 0;
378 attributes.stencil_size = 0;
379 attributes.samples = 0;
380 attributes.sample_buffers = 0;
381 attributes.bind_generates_resource = false;
382 attributes.lose_context_when_out_of_memory = true;
383 attributes.enable_gles2_interface = support_gles2_interface;
384 attributes.enable_raster_interface = support_raster_interface;
385 attributes.enable_oop_rasterization = support_oop_rasterization;
387 bool enable_raster_decoder =
388 base::CommandLine::ForCurrentProcess()->HasSwitch(
389 switches::kEnableRasterDecoder);
390 // --enable-raster-decoder supports raster interface, but not
392 attributes.enable_raster_decoder = enable_raster_decoder &&
393 support_raster_interface &&
394 !support_gles2_interface;
396 const bool automatic_flushes = false;
397 return base::MakeRefCounted<ui::ContextProviderCommandBuffer>(
398 std::move(gpu_channel_host), gpu_memory_buffer_manager, stream_id,
399 stream_priority, gpu::kNullSurfaceHandle,
400 GURL("chrome://gpu/RenderThreadImpl::CreateOffscreenContext/" +
401 ui::command_buffer_metrics::ContextTypeToString(type)),
402 automatic_flushes, support_locking, support_grcontext, limits, attributes,
403 nullptr /* share_context */, type);
406 // Hook that allows single-sample metric code from //components/metrics to
407 // connect from the renderer process to the browser process.
408 void CreateSingleSampleMetricsProvider(
409 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
410 service_manager::Connector* connector,
411 metrics::mojom::SingleSampleMetricsProviderRequest request) {
412 if (task_runner->BelongsToCurrentThread()) {
413 connector->BindInterface(mojom::kBrowserServiceName, std::move(request));
417 task_runner->PostTask(
419 base::BindOnce(&CreateSingleSampleMetricsProvider, std::move(task_runner),
420 connector, std::move(request)));
423 class RendererLocalSurfaceIdProvider : public viz::LocalSurfaceIdProvider {
425 const viz::LocalSurfaceId& GetLocalSurfaceIdForFrame(
426 const viz::CompositorFrame& frame) override {
427 auto new_surface_properties =
428 RenderWidgetSurfaceProperties::FromCompositorFrame(frame);
429 if (!local_surface_id_.is_valid() ||
430 new_surface_properties != surface_properties_) {
431 local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
432 surface_properties_ = new_surface_properties;
434 return local_surface_id_;
438 viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
439 viz::LocalSurfaceId local_surface_id_;
440 RenderWidgetSurfaceProperties surface_properties_;
443 // This factory is used to defer binding of the InterfacePtr to the compositor
445 class UkmRecorderFactoryImpl : public cc::UkmRecorderFactory {
447 explicit UkmRecorderFactoryImpl(
448 std::unique_ptr<service_manager::Connector> connector)
449 : connector_(std::move(connector)) {
452 ~UkmRecorderFactoryImpl() override = default;
454 std::unique_ptr<ukm::UkmRecorder> CreateRecorder() override {
455 return ukm::MojoUkmRecorder::Create(connector_.get());
459 std::unique_ptr<service_manager::Connector> connector_;
462 static const int kWaitForWorkersStatsTimeoutMS = 20;
464 class ResourceUsageReporterImpl : public content::mojom::ResourceUsageReporter {
466 explicit ResourceUsageReporterImpl(base::WeakPtr<RenderThread> thread)
467 : workers_to_go_(0), thread_(thread), weak_factory_(this) {}
468 ~ResourceUsageReporterImpl() override {}
471 static void CollectOnWorkerThread(
472 const scoped_refptr<base::TaskRunner>& master,
473 base::WeakPtr<ResourceUsageReporterImpl> impl) {
474 size_t total_bytes = 0;
475 size_t used_bytes = 0;
476 v8::Isolate* isolate = v8::Isolate::GetCurrent();
478 v8::HeapStatistics heap_stats;
479 isolate->GetHeapStatistics(&heap_stats);
480 total_bytes = heap_stats.total_heap_size();
481 used_bytes = heap_stats.used_heap_size();
483 master->PostTask(FROM_HERE,
484 base::BindOnce(&ResourceUsageReporterImpl::ReceiveStats,
485 impl, total_bytes, used_bytes));
488 void ReceiveStats(size_t total_bytes, size_t used_bytes) {
489 usage_data_->v8_bytes_allocated += total_bytes;
490 usage_data_->v8_bytes_used += used_bytes;
497 if (!callback_.is_null())
498 std::move(callback_).Run(std::move(usage_data_));
500 weak_factory_.InvalidateWeakPtrs();
504 void GetUsageData(GetUsageDataCallback callback) override {
505 DCHECK(callback_.is_null());
506 weak_factory_.InvalidateWeakPtrs();
507 usage_data_ = mojom::ResourceUsageData::New();
508 usage_data_->reports_v8_stats = true;
509 callback_ = std::move(callback);
511 // Since it is not safe to call any Blink or V8 functions until Blink has
512 // been initialized (which also initializes V8), early out and send 0 back
513 // for all resources.
519 blink::WebCache::ResourceTypeStats stats;
520 blink::WebCache::GetResourceTypeStats(&stats);
521 usage_data_->web_cache_stats = mojom::ResourceTypeStats::From(stats);
523 v8::Isolate* isolate = v8::Isolate::GetCurrent();
525 v8::HeapStatistics heap_stats;
526 isolate->GetHeapStatistics(&heap_stats);
527 usage_data_->v8_bytes_allocated = heap_stats.total_heap_size();
528 usage_data_->v8_bytes_used = heap_stats.used_heap_size();
530 base::RepeatingClosure collect = base::BindRepeating(
531 &ResourceUsageReporterImpl::CollectOnWorkerThread,
532 base::ThreadTaskRunnerHandle::Get(), weak_factory_.GetWeakPtr());
534 RenderThread::Get()->PostTaskToAllWebWorkers(std::move(collect));
535 if (workers_to_go_) {
536 // The guard task to send out partial stats
537 // in case some workers are not responsive.
538 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
540 base::BindOnce(&ResourceUsageReporterImpl::SendResults,
541 weak_factory_.GetWeakPtr()),
542 base::TimeDelta::FromMilliseconds(kWaitForWorkersStatsTimeoutMS));
544 // No worker threads so just send out the main thread data right away.
549 mojom::ResourceUsageDataPtr usage_data_;
550 GetUsageDataCallback callback_;
552 base::WeakPtr<RenderThread> thread_;
554 base::WeakPtrFactory<ResourceUsageReporterImpl> weak_factory_;
556 DISALLOW_COPY_AND_ASSIGN(ResourceUsageReporterImpl);
559 void CreateResourceUsageReporter(base::WeakPtr<RenderThread> thread,
560 mojom::ResourceUsageReporterRequest request) {
561 mojo::MakeStrongBinding(std::make_unique<ResourceUsageReporterImpl>(thread),
567 RenderThreadImpl::HistogramCustomizer::HistogramCustomizer() {
568 custom_histograms_.insert("V8.MemoryExternalFragmentationTotal");
569 custom_histograms_.insert("V8.MemoryHeapSampleTotalCommitted");
570 custom_histograms_.insert("V8.MemoryHeapSampleTotalUsed");
571 custom_histograms_.insert("V8.MemoryHeapUsed");
572 custom_histograms_.insert("V8.MemoryHeapCommitted");
575 RenderThreadImpl::HistogramCustomizer::~HistogramCustomizer() {}
577 void RenderThreadImpl::HistogramCustomizer::RenderViewNavigatedToHost(
578 const std::string& host, size_t view_count) {
579 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
580 switches::kDisableHistogramCustomizer)) {
583 // Check if all RenderViews are displaying a page from the same host. If there
584 // is only one RenderView, the common host is this view's host. If there are
585 // many, check if this one shares the common host of the other
586 // RenderViews. It's ok to not detect some cases where the RenderViews share a
587 // common host. This information is only used for producing custom histograms.
590 else if (host != common_host_)
591 SetCommonHost(std::string());
594 std::string RenderThreadImpl::HistogramCustomizer::ConvertToCustomHistogramName(
595 const char* histogram_name) const {
596 std::string name(histogram_name);
597 if (!common_host_histogram_suffix_.empty() &&
598 custom_histograms_.find(name) != custom_histograms_.end())
599 name += common_host_histogram_suffix_;
603 void RenderThreadImpl::HistogramCustomizer::SetCommonHost(
604 const std::string& host) {
605 if (host != common_host_) {
607 common_host_histogram_suffix_ = HostToCustomHistogramSuffix(host);
608 blink::MainThreadIsolate()->SetCreateHistogramFunction(CreateHistogram);
612 std::string RenderThreadImpl::HistogramCustomizer::HostToCustomHistogramSuffix(
613 const std::string& host) {
614 if (host == "mail.google.com")
616 if (host == "docs.google.com" || host == "drive.google.com")
618 if (host == "plus.google.com")
620 if (host == "inbox.google.com")
622 if (host == "calendar.google.com")
624 if (host == "www.youtube.com")
626 if (IsAlexaTop10NonGoogleSite(host))
629 return std::string();
632 bool RenderThreadImpl::HistogramCustomizer::IsAlexaTop10NonGoogleSite(
633 const std::string& host) {
634 // The Top10 sites have different TLD and/or subdomains depending on the
636 if (host == "sina.com.cn")
639 std::string sanitized_host =
640 net::registry_controlled_domains::GetDomainAndRegistry(
641 host, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
643 if (sanitized_host == "facebook.com")
645 if (sanitized_host == "baidu.com")
647 if (sanitized_host == "qq.com")
649 if (sanitized_host == "twitter.com")
651 if (sanitized_host == "taobao.com")
653 if (sanitized_host == "live.com")
656 if (!sanitized_host.empty()) {
657 std::vector<base::StringPiece> host_tokens = base::SplitStringPiece(
658 sanitized_host, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
660 if (host_tokens.size() >= 2) {
661 if ((host_tokens[0] == "yahoo") || (host_tokens[0] == "amazon") ||
662 (host_tokens[0] == "wikipedia")) {
671 RenderThreadImpl* RenderThreadImpl::Create(
672 const InProcessChildThreadParams& params,
673 base::MessageLoop* unowned_message_loop) {
674 TRACE_EVENT0("startup", "RenderThreadImpl::Create");
675 std::unique_ptr<blink::scheduler::WebMainThreadScheduler>
676 main_thread_scheduler =
677 blink::scheduler::WebMainThreadScheduler::Create();
678 scoped_refptr<base::SingleThreadTaskRunner> test_task_counter;
679 return new RenderThreadImpl(params, std::move(main_thread_scheduler),
680 test_task_counter, unowned_message_loop);
684 RenderThreadImpl* RenderThreadImpl::Create(
685 std::unique_ptr<base::MessageLoop> main_message_loop,
686 std::unique_ptr<blink::scheduler::WebMainThreadScheduler>
687 main_thread_scheduler) {
688 TRACE_EVENT0("startup", "RenderThreadImpl::Create");
689 return new RenderThreadImpl(std::move(main_message_loop),
690 std::move(main_thread_scheduler));
694 RenderThreadImpl* RenderThreadImpl::current() {
695 return lazy_tls.Pointer()->Get();
699 mojom::RenderMessageFilter* RenderThreadImpl::current_render_message_filter() {
700 if (g_render_message_filter_for_testing)
701 return g_render_message_filter_for_testing;
703 return current()->render_message_filter();
707 RendererBlinkPlatformImpl* RenderThreadImpl::current_blink_platform_impl() {
708 if (g_current_blink_platform_impl_for_testing)
709 return g_current_blink_platform_impl_for_testing;
711 return current()->blink_platform_impl();
715 void RenderThreadImpl::SetRenderMessageFilterForTesting(
716 mojom::RenderMessageFilter* render_message_filter) {
717 g_render_message_filter_for_testing = render_message_filter;
721 void RenderThreadImpl::SetRendererBlinkPlatformImplForTesting(
722 RendererBlinkPlatformImpl* blink_platform_impl) {
723 g_current_blink_platform_impl_for_testing = blink_platform_impl;
727 scoped_refptr<base::SingleThreadTaskRunner>
728 RenderThreadImpl::DeprecatedGetMainTaskRunner() {
729 return g_main_task_runner.Get();
732 // In single-process mode used for debugging, we don't pass a renderer client
733 // ID via command line because RenderThreadImpl lives in the same process as
735 RenderThreadImpl::RenderThreadImpl(
736 const InProcessChildThreadParams& params,
737 std::unique_ptr<blink::scheduler::WebMainThreadScheduler> scheduler,
738 const scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue,
739 base::MessageLoop* unowned_message_loop)
742 .InBrowserProcess(params)
743 .AutoStartServiceManagerConnection(false)
744 .ConnectToBrowser(true)
745 .IPCTaskRunner(scheduler ? scheduler->IPCTaskRunner() : nullptr)
747 main_thread_scheduler_(std::move(scheduler)),
748 main_message_loop_(unowned_message_loop),
749 categorized_worker_pool_(new CategorizedWorkerPool()),
750 renderer_binding_(this),
752 compositing_mode_watcher_binding_(this),
753 weak_factory_(this) {
754 Init(resource_task_queue);
757 // When we run plugins in process, we actually run them on the render thread,
758 // which means that we need to make the render thread pump UI events.
759 RenderThreadImpl::RenderThreadImpl(
760 std::unique_ptr<base::MessageLoop> owned_message_loop,
761 std::unique_ptr<blink::scheduler::WebMainThreadScheduler> scheduler)
764 .AutoStartServiceManagerConnection(false)
765 .ConnectToBrowser(true)
766 .IPCTaskRunner(scheduler ? scheduler->IPCTaskRunner() : nullptr)
768 main_thread_scheduler_(std::move(scheduler)),
769 owned_message_loop_(std::move(owned_message_loop)),
770 main_message_loop_(owned_message_loop_.get()),
771 categorized_worker_pool_(new CategorizedWorkerPool()),
772 is_scroll_animator_enabled_(false),
773 renderer_binding_(this),
774 compositing_mode_watcher_binding_(this),
775 weak_factory_(this) {
776 scoped_refptr<base::SingleThreadTaskRunner> test_task_counter;
777 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
778 switches::kRendererClientId));
779 base::StringToInt(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
780 switches::kRendererClientId),
782 Init(test_task_counter);
785 void RenderThreadImpl::Init(
786 const scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue) {
787 TRACE_EVENT0("startup", "RenderThreadImpl::Init");
789 // Whether owned or unowned, |main_message_loop_| needs to be initialized in
791 DCHECK(main_message_loop_);
793 GetContentClient()->renderer()->PostIOThreadCreated(GetIOTaskRunner().get());
795 base::trace_event::TraceLog::GetInstance()->SetThreadSortIndex(
796 base::PlatformThread::CurrentId(),
797 kTraceEventRendererMainThreadSortIndex);
799 #if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
800 // On Mac and Android Java UI, the select popups are rendered by the browser.
801 blink::WebView::SetUseExternalPopupMenus(true);
804 lazy_tls.Pointer()->Set(this);
805 g_main_task_runner.Get() = main_message_loop_->task_runner();
807 // Register this object as the main thread.
808 ChildProcess::current()->set_main_thread(this);
810 metrics::InitializeSingleSampleMetricsFactory(
811 base::BindRepeating(&CreateSingleSampleMetricsProvider,
812 message_loop()->task_runner(), GetConnector()));
814 gpu_ = ui::Gpu::Create(GetConnector(),
815 base::FeatureList::IsEnabled(features::kMash)
816 ? ui::mojom::kServiceName
817 : mojom::kBrowserServiceName,
820 viz::mojom::SharedBitmapAllocationNotifierPtr
821 shared_bitmap_allocation_notifier_ptr;
822 GetConnector()->BindInterface(
823 mojom::kBrowserServiceName,
824 mojo::MakeRequest(&shared_bitmap_allocation_notifier_ptr));
825 shared_bitmap_manager_ = std::make_unique<viz::ClientSharedBitmapManager>(
826 viz::mojom::ThreadSafeSharedBitmapAllocationNotifierPtr::Create(
827 shared_bitmap_allocation_notifier_ptr.PassInterface(),
828 GetChannel()->ipc_task_runner_refptr()));
830 notification_dispatcher_ = new NotificationDispatcher(
831 thread_safe_sender(), GetWebMainThreadScheduler()->IPCTaskRunner());
832 AddFilter(notification_dispatcher_->GetFilter());
834 resource_dispatcher_.reset(new ResourceDispatcher());
835 url_loader_throttle_provider_ =
836 GetContentClient()->renderer()->CreateURLLoaderThrottleProvider(
837 URLLoaderThrottleProviderType::kFrame);
839 auto registry = std::make_unique<service_manager::BinderRegistry>();
840 InitializeWebKit(resource_task_queue, registry.get());
841 blink_initialized_time_ = base::TimeTicks::Now();
843 // In single process the single process is all there is.
844 webkit_shared_timer_suspended_ = false;
846 hidden_widget_count_ = 0;
847 idle_notification_delay_in_ms_ = kInitialIdleHandlerDelayMs;
848 idle_notifications_to_skip_ = 0;
850 appcache_dispatcher_.reset(
851 new AppCacheDispatcher(new AppCacheFrontendImpl()));
852 registry->AddInterface(
853 base::BindRepeating(&AppCacheDispatcher::Bind,
854 base::Unretained(appcache_dispatcher())),
855 GetWebMainThreadScheduler()->IPCTaskRunner());
856 dom_storage_dispatcher_.reset(new DomStorageDispatcher());
857 main_thread_indexed_db_dispatcher_.reset(new IndexedDBDispatcher());
858 file_system_dispatcher_.reset(new FileSystemDispatcher());
860 vc_manager_.reset(new VideoCaptureImplManager());
862 browser_plugin_manager_.reset(new BrowserPluginManager());
863 AddObserver(browser_plugin_manager_.get());
865 #if BUILDFLAG(ENABLE_WEBRTC)
866 peer_connection_tracker_.reset(new PeerConnectionTracker());
867 AddObserver(peer_connection_tracker_.get());
869 p2p_socket_dispatcher_ = new P2PSocketDispatcher(GetIOTaskRunner().get());
870 AddFilter(p2p_socket_dispatcher_.get());
872 peer_connection_factory_.reset(
873 new PeerConnectionDependencyFactory(p2p_socket_dispatcher_.get()));
875 aec_dump_message_filter_ = new AecDumpMessageFilter(
876 GetIOTaskRunner(), message_loop()->task_runner());
878 AddFilter(aec_dump_message_filter_.get());
880 #endif // BUILDFLAG(ENABLE_WEBRTC)
882 scoped_refptr<AudioInputMessageFilter> audio_input_message_filter;
883 if (!base::FeatureList::IsEnabled(
884 features::kUseMojoAudioInputStreamFactory)) {
885 // In case we shouldn't use mojo factories, we need to create an
886 // AudioInputMessageFilter which |audio_input_ipc_factory_| can use for
888 audio_input_message_filter =
889 base::MakeRefCounted<AudioInputMessageFilter>(GetIOTaskRunner());
890 AddFilter(audio_input_message_filter.get());
893 audio_input_ipc_factory_.emplace(std::move(audio_input_message_filter),
894 message_loop()->task_runner(),
899 scoped_refptr<AudioMessageFilter> audio_output_message_filter;
900 if (!base::FeatureList::IsEnabled(
901 features::kUseMojoAudioOutputStreamFactory)) {
902 // In case we shouldn't use mojo factories, we need to create an
903 // AudioMessageFilter which |audio_output_ipc_factory_| can use for IPC.
904 audio_output_message_filter =
905 base::MakeRefCounted<AudioMessageFilter>(GetIOTaskRunner());
906 AddFilter(audio_output_message_filter.get());
909 audio_output_ipc_factory_.emplace(std::move(audio_output_message_filter),
913 midi_message_filter_ = new MidiMessageFilter(GetIOTaskRunner());
914 AddFilter(midi_message_filter_.get());
916 #if defined(USE_AURA)
917 if (features::IsMusEnabled())
918 CreateRenderWidgetWindowTreeClientFactory(GetServiceManagerConnection());
921 registry->AddInterface(base::Bind(&SharedWorkerFactoryImpl::Create),
922 base::ThreadTaskRunnerHandle::Get());
923 registry->AddInterface(base::BindRepeating(CreateResourceUsageReporter,
924 weak_factory_.GetWeakPtr()),
925 base::ThreadTaskRunnerHandle::Get());
927 GetServiceManagerConnection()->AddConnectionFilter(
928 std::make_unique<SimpleConnectionFilter>(std::move(registry)));
931 auto registry_with_source_info =
932 std::make_unique<service_manager::BinderRegistryWithArgs<
933 const service_manager::BindSourceInfo&>>();
934 registry_with_source_info->AddInterface(
935 base::Bind(&CreateFrameFactory), base::ThreadTaskRunnerHandle::Get());
936 GetServiceManagerConnection()->AddConnectionFilter(
937 std::make_unique<SimpleConnectionFilterWithSourceInfo>(
938 std::move(registry_with_source_info)));
941 GetContentClient()->renderer()->RenderThreadStarted();
943 StartServiceManagerConnection();
945 GetAssociatedInterfaceRegistry()->AddInterface(
946 base::Bind(&RenderThreadImpl::OnRendererInterfaceRequest,
947 base::Unretained(this)));
949 InitSkiaEventTracer();
950 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
951 skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr);
953 const base::CommandLine& command_line =
954 *base::CommandLine::ForCurrentProcess();
956 #if defined(ENABLE_IPC_FUZZER)
957 if (command_line.HasSwitch(switches::kIpcDumpDirectory)) {
958 base::FilePath dump_directory =
959 command_line.GetSwitchValuePath(switches::kIpcDumpDirectory);
960 IPC::ChannelProxy::OutgoingMessageFilter* filter =
961 LoadExternalIPCDumper(dump_directory);
962 GetChannel()->set_outgoing_message_filter(filter);
966 cc::SetClientNameForMetrics("Renderer");
968 is_threaded_animation_enabled_ =
969 !command_line.HasSwitch(cc::switches::kDisableThreadedAnimation);
971 is_zero_copy_enabled_ = command_line.HasSwitch(switches::kEnableZeroCopy);
972 is_partial_raster_enabled_ =
973 !command_line.HasSwitch(switches::kDisablePartialRaster);
974 is_gpu_memory_buffer_compositor_resources_enabled_ = command_line.HasSwitch(
975 switches::kEnableGpuMemoryBufferCompositorResources);
977 // On macOS this value is adjusted in `UpdateScrollbarTheme()`,
978 // but the system default is true.
979 #if defined(OS_MACOSX)
980 is_elastic_overscroll_enabled_ = true;
982 is_elastic_overscroll_enabled_ = false;
985 if (command_line.HasSwitch(switches::kDisableLCDText)) {
986 is_lcd_text_enabled_ = false;
987 } else if (command_line.HasSwitch(switches::kEnableLCDText)) {
988 is_lcd_text_enabled_ = true;
990 #if defined(OS_ANDROID)
991 is_lcd_text_enabled_ = false;
993 is_lcd_text_enabled_ = true;
997 if (command_line.HasSwitch(switches::kDisableGpuCompositing))
998 is_gpu_compositing_disabled_ = true;
1000 is_gpu_rasterization_forced_ =
1001 command_line.HasSwitch(switches::kForceGpuRasterization);
1003 if (command_line.HasSwitch(switches::kGpuRasterizationMSAASampleCount)) {
1004 std::string string_value = command_line.GetSwitchValueASCII(
1005 switches::kGpuRasterizationMSAASampleCount);
1006 bool parsed_msaa_sample_count =
1007 base::StringToInt(string_value, &gpu_rasterization_msaa_sample_count_);
1008 DCHECK(parsed_msaa_sample_count) << string_value;
1009 DCHECK_GE(gpu_rasterization_msaa_sample_count_, 0);
1011 gpu_rasterization_msaa_sample_count_ = -1;
1014 // Note that under Linux, the media library will normally already have
1015 // been initialized by the Zygote before this instance became a Renderer.
1016 media::InitializeMediaLibrary();
1018 #if defined(OS_ANDROID)
1019 if (!command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode) &&
1020 media::MediaCodecUtil::IsMediaCodecAvailable()) {
1021 bool accelerated_video_decode_blacklisted = false;
1022 if (!command_line.HasSwitch(switches::kIgnoreGpuBlacklist)) {
1023 int32_t major_version = 0, minor_version = 0, bugfix_version = 0;
1024 base::SysInfo::OperatingSystemVersionNumbers(
1025 &major_version, &minor_version, &bugfix_version);
1026 if (major_version < 5) {
1027 // Currently accelerated video decode is only blacklisted on
1028 // Android older than Lollipop.
1029 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host =
1030 EstablishGpuChannelSync();
1031 if (!gpu_channel_host ||
1032 gpu_channel_host->gpu_feature_info().status_values
1033 [gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] !=
1034 gpu::kGpuFeatureStatusEnabled) {
1035 accelerated_video_decode_blacklisted = true;
1039 if (!accelerated_video_decode_blacklisted)
1040 media::EnablePlatformDecoderSupport();
1044 memory_pressure_listener_.reset(new base::MemoryPressureListener(
1045 base::Bind(&RenderThreadImpl::OnMemoryPressure, base::Unretained(this)),
1046 base::Bind(&RenderThreadImpl::OnSyncMemoryPressure,
1047 base::Unretained(this))));
1049 if (base::FeatureList::IsEnabled(features::kMemoryCoordinator)) {
1050 // Disable MemoryPressureListener when memory coordinator is enabled.
1051 base::MemoryPressureListener::SetNotificationsSuppressed(true);
1053 // TODO(bashi): Revisit how to manage the lifetime of
1054 // ChildMemoryCoordinatorImpl.
1055 // https://codereview.chromium.org/2094583002/#msg52
1056 mojom::MemoryCoordinatorHandlePtr parent_coordinator;
1057 GetConnector()->BindInterface(mojom::kBrowserServiceName,
1058 mojo::MakeRequest(&parent_coordinator));
1059 memory_coordinator_ = CreateChildMemoryCoordinator(
1060 std::move(parent_coordinator), this);
1063 int num_raster_threads = 0;
1064 std::string string_value =
1065 command_line.GetSwitchValueASCII(switches::kNumRasterThreads);
1066 bool parsed_num_raster_threads =
1067 base::StringToInt(string_value, &num_raster_threads);
1068 DCHECK(parsed_num_raster_threads) << string_value;
1069 DCHECK_GT(num_raster_threads, 0);
1071 categorized_worker_pool_->Start(num_raster_threads);
1073 discardable_memory::mojom::DiscardableSharedMemoryManagerPtr manager_ptr;
1074 if (features::IsMusEnabled()) {
1075 #if defined(USE_AURA)
1076 GetServiceManagerConnection()->GetConnector()->BindInterface(
1077 ui::mojom::kServiceName, &manager_ptr);
1082 ChildThread::Get()->GetConnector()->BindInterface(
1083 mojom::kBrowserServiceName, mojo::MakeRequest(&manager_ptr));
1086 discardable_shared_memory_manager_ = std::make_unique<
1087 discardable_memory::ClientDiscardableSharedMemoryManager>(
1088 std::move(manager_ptr), GetIOTaskRunner());
1090 // TODO(boliu): In single process, browser main loop should set up the
1091 // discardable memory manager, and should skip this if kSingleProcess.
1092 // See crbug.com/503724.
1093 base::DiscardableMemoryAllocator::SetInstance(
1094 discardable_shared_memory_manager_.get());
1096 GetConnector()->BindInterface(mojom::kBrowserServiceName,
1097 mojo::MakeRequest(&storage_partition_service_));
1099 #if defined(OS_LINUX)
1100 render_message_filter()->SetThreadPriority(
1101 ChildProcess::current()->io_thread_id(), base::ThreadPriority::DISPLAY);
1102 render_message_filter()->SetThreadPriority(
1103 categorized_worker_pool_->background_worker_thread_id(),
1104 base::ThreadPriority::BACKGROUND);
1107 process_foregrounded_count_ = 0;
1108 needs_to_record_first_active_paint_ = false;
1109 was_backgrounded_time_ = base::TimeTicks::Min();
1111 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this);
1113 GetConnector()->BindInterface(mojom::kBrowserServiceName,
1114 mojo::MakeRequest(&frame_sink_provider_));
1116 if (!is_gpu_compositing_disabled_) {
1117 GetConnector()->BindInterface(
1118 mojom::kBrowserServiceName,
1119 mojo::MakeRequest(&compositing_mode_reporter_));
1121 // Make |this| a CompositingModeWatcher for the
1122 // |compositing_mode_reporter_|.
1123 viz::mojom::CompositingModeWatcherPtr watcher_ptr;
1124 compositing_mode_watcher_binding_.Bind(mojo::MakeRequest(&watcher_ptr));
1125 compositing_mode_reporter_->AddCompositingModeWatcher(
1126 std::move(watcher_ptr));
1130 RenderThreadImpl::~RenderThreadImpl() {
1131 g_main_task_runner.Get() = nullptr;
1134 void RenderThreadImpl::Shutdown() {
1135 ChildThreadImpl::Shutdown();
1136 file_system_dispatcher_.reset();
1137 WebFileSystemImpl::DeleteThreadSpecificInstance();
1138 // In a multi-process mode, we immediately exit the renderer.
1139 // Historically we had a graceful shutdown sequence here but it was
1140 // 1) a waste of performance and 2) a source of lots of complicated
1141 // crashes caused by shutdown ordering. Immediate exit eliminates
1144 // Give the V8 isolate a chance to dump internal stats useful for performance
1145 // evaluation and debugging.
1146 blink::MainThreadIsolate()->DumpAndResetStats();
1148 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1149 switches::kDumpBlinkRuntimeCallStats))
1150 blink::LogRuntimeCallStats();
1152 // In a single-process mode, we cannot call _exit(0) in Shutdown() because
1153 // it will exit the process before the browser side is ready to exit.
1154 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
1155 switches::kSingleProcess))
1156 base::Process::TerminateCurrentProcessImmediately(0);
1159 bool RenderThreadImpl::ShouldBeDestroyed() {
1160 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
1161 switches::kSingleProcess));
1162 // In a single-process mode, it is unsafe to destruct this renderer thread
1163 // because we haven't run the shutdown sequence. Hence we leak the render
1166 // In this case, we also need to disable at-exit callbacks because some of
1167 // the at-exit callbacks are expected to run after the renderer thread
1168 // has been destructed.
1169 base::AtExitManager::DisableAllAtExitManagers();
1173 bool RenderThreadImpl::Send(IPC::Message* msg) {
1174 // There are cases where we want to pump asynchronous messages while waiting
1175 // synchronously for the replies to the message to be sent here. However, this
1176 // may create an opportunity for re-entrancy into WebKit and other subsystems,
1177 // so we need to take care to disable callbacks, timers, and pending network
1178 // loads that could trigger such callbacks.
1179 bool pumping_events = false;
1180 if (msg->is_sync()) {
1181 if (msg->is_caller_pumping_messages()) {
1182 pumping_events = true;
1186 std::unique_ptr<blink::scheduler::WebMainThreadScheduler::RendererPauseHandle>
1187 renderer_paused_handle;
1189 if (pumping_events) {
1190 renderer_paused_handle = main_thread_scheduler_->PauseRenderer();
1191 WebView::WillEnterModalLoop();
1194 bool rv = ChildThreadImpl::Send(msg);
1197 WebView::DidExitModalLoop();
1202 IPC::SyncChannel* RenderThreadImpl::GetChannel() {
1206 std::string RenderThreadImpl::GetLocale() {
1207 // The browser process should have passed the locale to the renderer via the
1208 // --lang command line flag.
1209 const base::CommandLine& parsed_command_line =
1210 *base::CommandLine::ForCurrentProcess();
1211 const std::string& lang =
1212 parsed_command_line.GetSwitchValueASCII(switches::kLang);
1213 DCHECK(!lang.empty());
1217 IPC::SyncMessageFilter* RenderThreadImpl::GetSyncMessageFilter() {
1218 return sync_message_filter();
1221 void RenderThreadImpl::AddRoute(int32_t routing_id, IPC::Listener* listener) {
1222 ChildThreadImpl::GetRouter()->AddRoute(routing_id, listener);
1223 auto it = pending_frame_creates_.find(routing_id);
1224 if (it == pending_frame_creates_.end())
1227 RenderFrameImpl* frame = RenderFrameImpl::FromRoutingID(routing_id);
1231 scoped_refptr<PendingFrameCreate> create(it->second);
1232 frame->BindFrame(it->second->browser_info(), it->second->TakeFrameRequest());
1233 pending_frame_creates_.erase(it);
1236 void RenderThreadImpl::RemoveRoute(int32_t routing_id) {
1237 ChildThreadImpl::GetRouter()->RemoveRoute(routing_id);
1240 void RenderThreadImpl::RegisterPendingFrameCreate(
1241 const service_manager::BindSourceInfo& browser_info,
1243 mojom::FrameRequest frame_request) {
1244 std::pair<PendingFrameCreateMap::iterator, bool> result =
1245 pending_frame_creates_.insert(std::make_pair(
1246 routing_id, base::MakeRefCounted<PendingFrameCreate>(
1247 browser_info, routing_id, std::move(frame_request))));
1248 CHECK(result.second) << "Inserting a duplicate item.";
1251 mojom::StoragePartitionService* RenderThreadImpl::GetStoragePartitionService() {
1252 return storage_partition_service_.get();
1255 mojom::RendererHost* RenderThreadImpl::GetRendererHost() {
1256 if (!renderer_host_) {
1257 GetChannel()->GetRemoteAssociatedInterface(&renderer_host_);
1259 return renderer_host_.get();
1262 int RenderThreadImpl::GenerateRoutingID() {
1263 int32_t routing_id = MSG_ROUTING_NONE;
1264 render_message_filter()->GenerateRoutingID(&routing_id);
1268 void RenderThreadImpl::AddFilter(IPC::MessageFilter* filter) {
1269 channel()->AddFilter(filter);
1272 void RenderThreadImpl::RemoveFilter(IPC::MessageFilter* filter) {
1273 channel()->RemoveFilter(filter);
1276 void RenderThreadImpl::AddObserver(RenderThreadObserver* observer) {
1277 observers_.AddObserver(observer);
1278 observer->RegisterMojoInterfaces(&associated_interfaces_);
1281 void RenderThreadImpl::RemoveObserver(RenderThreadObserver* observer) {
1282 observer->UnregisterMojoInterfaces(&associated_interfaces_);
1283 observers_.RemoveObserver(observer);
1286 void RenderThreadImpl::SetResourceDispatcherDelegate(
1287 ResourceDispatcherDelegate* delegate) {
1288 resource_dispatcher_->set_delegate(delegate);
1291 void RenderThreadImpl::InitializeCompositorThread() {
1292 blink::WebThreadCreationParams params(
1293 blink::WebThreadType::kCompositorThread);
1294 #if defined(OS_ANDROID)
1295 params.thread_options.priority = base::ThreadPriority::DISPLAY;
1297 compositor_thread_ =
1298 blink::scheduler::WebThreadBase::CreateCompositorThread(params);
1299 blink_platform_impl_->SetCompositorThread(compositor_thread_.get());
1300 compositor_task_runner_ = compositor_thread_->GetTaskRunner();
1301 compositor_task_runner_->PostTask(
1303 base::BindOnce(base::IgnoreResult(&ThreadRestrictions::SetIOAllowed),
1305 GetContentClient()->renderer()->PostCompositorThreadCreated(
1306 compositor_task_runner_.get());
1307 #if defined(OS_LINUX)
1308 render_message_filter()->SetThreadPriority(compositor_thread_->ThreadId(),
1309 base::ThreadPriority::DISPLAY);
1312 if (!base::FeatureList::IsEnabled(features::kMojoInputMessages)) {
1313 SynchronousInputHandlerProxyClient* synchronous_input_handler_proxy_client =
1315 #if defined(OS_ANDROID)
1316 if (GetContentClient()->UsingSynchronousCompositing()) {
1317 sync_compositor_message_filter_ =
1318 new SynchronousCompositorFilter(compositor_task_runner_);
1319 AddFilter(sync_compositor_message_filter_.get());
1320 synchronous_input_handler_proxy_client =
1321 sync_compositor_message_filter_.get();
1324 scoped_refptr<InputEventFilter> compositor_input_event_filter(
1325 new InputEventFilter(main_input_callback_.callback(),
1326 main_thread_compositor_task_runner_,
1327 compositor_task_runner_));
1328 InputHandlerManagerClient* input_handler_manager_client =
1329 compositor_input_event_filter.get();
1330 input_event_filter_ = compositor_input_event_filter;
1331 input_handler_manager_.reset(new InputHandlerManager(
1332 compositor_task_runner_, input_handler_manager_client,
1333 synchronous_input_handler_proxy_client, main_thread_scheduler_.get()));
1337 void RenderThreadImpl::InitializeWebKit(
1338 const scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue,
1339 service_manager::BinderRegistry* registry) {
1340 DCHECK(!blink_platform_impl_);
1342 const base::CommandLine& command_line =
1343 *base::CommandLine::ForCurrentProcess();
1345 #ifdef ENABLE_VTUNE_JIT_INTERFACE
1346 if (command_line.HasSwitch(switches::kEnableVtune))
1347 gin::Debug::SetJitCodeEventHandler(vTune::GetVtuneCodeEventHandler());
1350 blink_platform_impl_.reset(
1351 new RendererBlinkPlatformImpl(main_thread_scheduler_.get()));
1352 SetRuntimeFeaturesDefaultsAndUpdateFromArgs(command_line);
1355 ->SetRuntimeFeaturesDefaultsBeforeBlinkInitialization();
1356 blink::Initialize(blink_platform_impl_.get(), registry);
1358 v8::Isolate* isolate = blink::MainThreadIsolate();
1359 isolate->SetCreateHistogramFunction(CreateHistogram);
1360 isolate->SetAddHistogramSampleFunction(AddHistogramSample);
1361 main_thread_scheduler_->SetRAILModeObserver(this);
1363 main_thread_compositor_task_runner_ =
1364 main_thread_scheduler_->CompositorTaskRunner();
1366 main_input_callback_.Reset(
1367 base::Bind(base::IgnoreResult(&RenderThreadImpl::OnMessageReceived),
1368 base::Unretained(this)));
1370 if (!command_line.HasSwitch(switches::kDisableThreadedCompositing))
1371 InitializeCompositorThread();
1373 if (!input_event_filter_.get()) {
1374 // Always provide an input event filter implementation to ensure consistent
1375 // input event scheduling and prioritization.
1376 // TODO(jdduke): Merge InputEventFilter, InputHandlerManager and
1377 // MainThreadInputEventFilter, crbug.com/436057.
1378 input_event_filter_ = new MainThreadInputEventFilter(
1379 main_input_callback_.callback(), main_thread_compositor_task_runner_);
1381 AddFilter(input_event_filter_.get());
1383 scoped_refptr<base::SingleThreadTaskRunner> compositor_impl_side_task_runner;
1384 if (compositor_task_runner_)
1385 compositor_impl_side_task_runner = compositor_task_runner_;
1387 compositor_impl_side_task_runner = base::ThreadTaskRunnerHandle::Get();
1389 RenderThreadImpl::RegisterSchemes();
1391 RenderMediaClient::Initialize();
1393 idle_timer_.SetTaskRunner(GetWebMainThreadScheduler()->DefaultTaskRunner());
1395 if (GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden()) {
1396 ScheduleIdleHandler(kLongIdleHandlerDelayMs);
1398 // If we do not track widget visibility, then assume conservatively that
1399 // the isolate is in background. This reduces memory usage.
1400 isolate->IsolateInBackgroundNotification();
1403 service_worker_message_filter_ = new ServiceWorkerMessageFilter(
1404 thread_safe_sender(), GetWebMainThreadScheduler()->IPCTaskRunner());
1405 AddFilter(service_worker_message_filter_->GetFilter());
1407 main_thread_scheduler_->SetStoppingWhenBackgroundedEnabled(
1408 GetContentClient()->renderer()->AllowStoppingWhenProcessBackgrounded());
1410 SkGraphics::SetResourceCacheSingleAllocationByteLimit(
1411 kImageCacheSingleAllocationByteLimit);
1413 // Hook up blink's codecs so skia can call them
1414 SkGraphics::SetImageGeneratorFromEncodedDataFactory(
1415 blink::WebImageGenerator::CreateAsSkImageGenerator);
1417 if (command_line.HasSwitch(switches::kExplicitlyAllowedPorts)) {
1418 std::string allowed_ports =
1419 command_line.GetSwitchValueASCII(switches::kExplicitlyAllowedPorts);
1420 net::SetExplicitlyAllowedPorts(allowed_ports);
1424 void RenderThreadImpl::RegisterSchemes() {
1426 WebString chrome_scheme(WebString::FromASCII(kChromeUIScheme));
1427 WebSecurityPolicy::RegisterURLSchemeAsDisplayIsolated(chrome_scheme);
1428 WebSecurityPolicy::RegisterURLSchemeAsNotAllowingJavascriptURLs(
1432 WebString devtools_scheme(WebString::FromASCII(kChromeDevToolsScheme));
1433 WebSecurityPolicy::RegisterURLSchemeAsDisplayIsolated(devtools_scheme);
1436 WebString view_source_scheme(WebString::FromASCII(kViewSourceScheme));
1437 WebSecurityPolicy::RegisterURLSchemeAsDisplayIsolated(view_source_scheme);
1440 WebString error_scheme(WebString::FromASCII(kChromeErrorScheme));
1441 WebSecurityPolicy::RegisterURLSchemeAsDisplayIsolated(error_scheme);
1442 WebSecurityPolicy::RegisterURLSchemeAsNotAllowingJavascriptURLs(error_scheme);
1445 void RenderThreadImpl::RecordAction(const base::UserMetricsAction& action) {
1446 Send(new ViewHostMsg_UserMetricsRecordAction(action.str_));
1449 void RenderThreadImpl::RecordComputedAction(const std::string& action) {
1450 Send(new ViewHostMsg_UserMetricsRecordAction(action));
1453 std::unique_ptr<base::SharedMemory>
1454 RenderThreadImpl::HostAllocateSharedMemoryBuffer(size_t size) {
1455 return ChildThreadImpl::AllocateSharedMemory(size);
1458 viz::SharedBitmapManager* RenderThreadImpl::GetSharedBitmapManager() {
1459 return shared_bitmap_manager();
1462 void RenderThreadImpl::RegisterExtension(v8::Extension* extension) {
1463 WebScriptController::RegisterExtension(extension);
1466 void RenderThreadImpl::ScheduleIdleHandler(int64_t initial_delay_ms) {
1467 idle_notification_delay_in_ms_ = initial_delay_ms;
1469 idle_timer_.Start(FROM_HERE,
1470 base::TimeDelta::FromMilliseconds(initial_delay_ms),
1471 this, &RenderThreadImpl::IdleHandler);
1474 void RenderThreadImpl::IdleHandler() {
1475 bool run_in_foreground_tab = (widget_count_ > hidden_widget_count_) &&
1476 GetContentClient()->renderer()->
1477 RunIdleHandlerWhenWidgetsHidden();
1478 if (run_in_foreground_tab) {
1479 if (idle_notifications_to_skip_ > 0) {
1480 --idle_notifications_to_skip_;
1482 ReleaseFreeMemory();
1484 ScheduleIdleHandler(kLongIdleHandlerDelayMs);
1488 ReleaseFreeMemory();
1490 // Continue the idle timer if the webkit shared timer is not suspended or
1491 // something is left to do.
1492 bool continue_timer = !webkit_shared_timer_suspended_;
1494 // Schedule next invocation. When the tab is originally hidden, an invocation
1495 // is scheduled for kInitialIdleHandlerDelayMs in
1496 // RenderThreadImpl::WidgetHidden in order to race to a minimal heap.
1497 // After that, idle calls can be much less frequent, so run at a maximum of
1498 // once every kLongIdleHandlerDelayMs.
1499 // Dampen the delay using the algorithm (if delay is in seconds):
1500 // delay = delay + 1 / (delay + 2)
1501 // Using floor(delay) has a dampening effect such as:
1502 // 30s, 30, 30, 31, 31, 31, 31, 32, 32, ...
1503 // If the delay is in milliseconds, the above formula is equivalent to:
1504 // delay_ms / 1000 = delay_ms / 1000 + 1 / (delay_ms / 1000 + 2)
1505 // which is equivalent to
1506 // delay_ms = delay_ms + 1000*1000 / (delay_ms + 2000).
1507 if (continue_timer) {
1508 ScheduleIdleHandler(
1509 std::max(kLongIdleHandlerDelayMs,
1510 idle_notification_delay_in_ms_ +
1511 1000000 / (idle_notification_delay_in_ms_ + 2000)));
1517 for (auto& observer : observers_)
1518 observer.IdleNotification();
1521 int64_t RenderThreadImpl::GetIdleNotificationDelayInMs() const {
1522 return idle_notification_delay_in_ms_;
1525 void RenderThreadImpl::SetIdleNotificationDelayInMs(
1526 int64_t idle_notification_delay_in_ms) {
1527 idle_notification_delay_in_ms_ = idle_notification_delay_in_ms;
1530 int RenderThreadImpl::PostTaskToAllWebWorkers(const base::Closure& closure) {
1531 return WorkerThreadRegistry::Instance()->PostTaskToAllThreads(closure);
1534 bool RenderThreadImpl::ResolveProxy(const GURL& url, std::string* proxy_list) {
1535 bool result = false;
1536 Send(new ViewHostMsg_ResolveProxy(url, &result, proxy_list));
1540 void RenderThreadImpl::PostponeIdleNotification() {
1541 idle_notifications_to_skip_ = 2;
1544 media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() {
1545 DCHECK(IsMainThread());
1547 if (!gpu_factories_.empty()) {
1548 if (!gpu_factories_.back()->CheckContextProviderLost())
1549 return gpu_factories_.back().get();
1551 GetMediaThreadTaskRunner()->PostTask(
1553 base::BindOnce(base::IgnoreResult(
1554 &GpuVideoAcceleratorFactoriesImpl::CheckContextLost),
1555 base::Unretained(gpu_factories_.back().get())));
1558 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
1560 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host =
1561 EstablishGpuChannelSync();
1562 if (!gpu_channel_host)
1564 // This context is only used to create textures and mailbox them, so
1565 // use lower limits than the default.
1566 gpu::SharedMemoryLimits limits = gpu::SharedMemoryLimits::ForMailboxContext();
1567 bool support_locking = false;
1568 bool support_gles2_interface = true;
1569 bool support_raster_interface = false;
1570 bool support_oop_rasterization = false;
1571 bool support_grcontext = false;
1572 scoped_refptr<ui::ContextProviderCommandBuffer> media_context_provider =
1573 CreateOffscreenContext(gpu_channel_host, GetGpuMemoryBufferManager(),
1574 limits, support_locking, support_gles2_interface,
1575 support_raster_interface,
1576 support_oop_rasterization, support_grcontext,
1577 ui::command_buffer_metrics::MEDIA_CONTEXT,
1578 kGpuStreamIdMedia, kGpuStreamPriorityMedia);
1580 const bool enable_video_accelerator =
1581 !cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode) &&
1582 (gpu_channel_host->gpu_feature_info()
1583 .status_values[gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] ==
1584 gpu::kGpuFeatureStatusEnabled);
1585 const bool enable_gpu_memory_buffer_video_frames =
1586 !is_gpu_compositing_disabled_ &&
1587 #if defined(OS_MACOSX) || defined(OS_LINUX)
1588 !cmd_line->HasSwitch(switches::kDisableGpuMemoryBufferVideoFrames);
1589 #elif defined(OS_WIN)
1590 !cmd_line->HasSwitch(switches::kDisableGpuMemoryBufferVideoFrames) &&
1591 (cmd_line->HasSwitch(switches::kEnableGpuMemoryBufferVideoFrames) ||
1592 gpu_channel_host->gpu_info().supports_overlays);
1594 cmd_line->HasSwitch(switches::kEnableGpuMemoryBufferVideoFrames);
1597 media::mojom::VideoEncodeAcceleratorProviderPtr vea_provider;
1598 gpu_->CreateVideoEncodeAcceleratorProvider(mojo::MakeRequest(&vea_provider));
1600 gpu_factories_.push_back(GpuVideoAcceleratorFactoriesImpl::Create(
1601 std::move(gpu_channel_host), base::ThreadTaskRunnerHandle::Get(),
1602 GetMediaThreadTaskRunner(), std::move(media_context_provider),
1603 enable_gpu_memory_buffer_video_frames, enable_video_accelerator,
1604 vea_provider.PassInterface()));
1605 gpu_factories_.back()->SetRenderingColorSpace(rendering_color_space_);
1606 return gpu_factories_.back().get();
1609 scoped_refptr<ui::ContextProviderCommandBuffer>
1610 RenderThreadImpl::SharedMainThreadContextProvider() {
1611 DCHECK(IsMainThread());
1612 if (shared_main_thread_contexts_ &&
1613 shared_main_thread_contexts_->ContextGL()->GetGraphicsResetStatusKHR() ==
1615 return shared_main_thread_contexts_;
1617 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(
1618 EstablishGpuChannelSync());
1619 if (!gpu_channel_host) {
1620 shared_main_thread_contexts_ = nullptr;
1624 bool support_locking = false;
1625 bool support_gles2_interface = true;
1626 bool support_raster_interface = false;
1627 bool support_oop_rasterization = false;
1628 bool support_grcontext = true;
1629 shared_main_thread_contexts_ = CreateOffscreenContext(
1630 std::move(gpu_channel_host), GetGpuMemoryBufferManager(),
1631 gpu::SharedMemoryLimits(), support_locking, support_gles2_interface,
1632 support_raster_interface, support_oop_rasterization, support_grcontext,
1633 ui::command_buffer_metrics::RENDERER_MAINTHREAD_CONTEXT,
1634 kGpuStreamIdDefault, kGpuStreamPriorityDefault);
1635 auto result = shared_main_thread_contexts_->BindToCurrentThread();
1636 if (result != gpu::ContextResult::kSuccess)
1637 shared_main_thread_contexts_ = nullptr;
1638 return shared_main_thread_contexts_;
1641 #if defined(OS_ANDROID)
1643 scoped_refptr<StreamTextureFactory> RenderThreadImpl::GetStreamTexureFactory() {
1644 DCHECK(IsMainThread());
1645 if (!stream_texture_factory_.get() ||
1646 stream_texture_factory_->ContextGL()->GetGraphicsResetStatusKHR() !=
1648 scoped_refptr<ui::ContextProviderCommandBuffer> shared_context_provider =
1649 SharedMainThreadContextProvider();
1650 if (!shared_context_provider) {
1651 stream_texture_factory_ = nullptr;
1654 DCHECK(shared_context_provider->GetCommandBufferProxy());
1655 DCHECK(shared_context_provider->GetCommandBufferProxy()->channel());
1656 stream_texture_factory_ =
1657 StreamTextureFactory::Create(std::move(shared_context_provider));
1659 return stream_texture_factory_;
1662 bool RenderThreadImpl::EnableStreamTextureCopy() {
1663 return GetContentClient()->UsingSynchronousCompositing();
1668 AudioRendererMixerManager* RenderThreadImpl::GetAudioRendererMixerManager() {
1669 if (!audio_renderer_mixer_manager_) {
1670 audio_renderer_mixer_manager_ = AudioRendererMixerManager::Create();
1673 return audio_renderer_mixer_manager_.get();
1676 base::WaitableEvent* RenderThreadImpl::GetShutdownEvent() {
1677 return ChildProcess::current()->GetShutDownEvent();
1680 int32_t RenderThreadImpl::GetClientId() {
1684 void RenderThreadImpl::SetRendererProcessType(
1685 blink::scheduler::RendererProcessType type) {
1686 main_thread_scheduler_->SetRendererProcessType(type);
1689 bool RenderThreadImpl::OnMessageReceived(const IPC::Message& msg) {
1690 if (file_system_dispatcher_->OnMessageReceived(msg))
1692 return ChildThreadImpl::OnMessageReceived(msg);
1695 void RenderThreadImpl::OnAssociatedInterfaceRequest(
1696 const std::string& name,
1697 mojo::ScopedInterfaceEndpointHandle handle) {
1698 if (associated_interfaces_.CanBindRequest(name))
1699 associated_interfaces_.BindRequest(name, std::move(handle));
1701 ChildThreadImpl::OnAssociatedInterfaceRequest(name, std::move(handle));
1704 scoped_refptr<base::SingleThreadTaskRunner>
1705 RenderThreadImpl::GetIOTaskRunner() {
1706 return ChildProcess::current()->io_task_runner();
1709 bool RenderThreadImpl::IsGpuRasterizationForced() {
1710 return is_gpu_rasterization_forced_;
1713 int RenderThreadImpl::GetGpuRasterizationMSAASampleCount() {
1714 return gpu_rasterization_msaa_sample_count_;
1717 bool RenderThreadImpl::IsLcdTextEnabled() {
1718 return is_lcd_text_enabled_;
1721 bool RenderThreadImpl::IsZeroCopyEnabled() {
1722 return is_zero_copy_enabled_;
1725 bool RenderThreadImpl::IsPartialRasterEnabled() {
1726 return is_partial_raster_enabled_;
1729 bool RenderThreadImpl::IsGpuMemoryBufferCompositorResourcesEnabled() {
1730 return is_gpu_memory_buffer_compositor_resources_enabled_;
1733 bool RenderThreadImpl::IsElasticOverscrollEnabled() {
1734 return is_elastic_overscroll_enabled_;
1737 scoped_refptr<base::SingleThreadTaskRunner>
1738 RenderThreadImpl::GetCompositorMainThreadTaskRunner() {
1739 return main_thread_compositor_task_runner_;
1742 scoped_refptr<base::SingleThreadTaskRunner>
1743 RenderThreadImpl::GetCompositorImplThreadTaskRunner() {
1744 return compositor_task_runner_;
1747 gpu::GpuMemoryBufferManager* RenderThreadImpl::GetGpuMemoryBufferManager() {
1748 return gpu_->gpu_memory_buffer_manager();
1751 blink::scheduler::WebMainThreadScheduler*
1752 RenderThreadImpl::GetWebMainThreadScheduler() {
1753 return main_thread_scheduler_.get();
1756 std::unique_ptr<viz::SyntheticBeginFrameSource>
1757 RenderThreadImpl::CreateSyntheticBeginFrameSource() {
1758 base::SingleThreadTaskRunner* compositor_impl_side_task_runner =
1759 compositor_task_runner_ ? compositor_task_runner_.get()
1760 : base::ThreadTaskRunnerHandle::Get().get();
1761 return std::make_unique<viz::BackToBackBeginFrameSource>(
1762 std::make_unique<viz::DelayBasedTimeSource>(
1763 compositor_impl_side_task_runner));
1766 cc::TaskGraphRunner* RenderThreadImpl::GetTaskGraphRunner() {
1767 return categorized_worker_pool_->GetTaskGraphRunner();
1770 bool RenderThreadImpl::IsThreadedAnimationEnabled() {
1771 return is_threaded_animation_enabled_;
1774 bool RenderThreadImpl::IsScrollAnimatorEnabled() {
1775 return is_scroll_animator_enabled_;
1778 std::unique_ptr<cc::UkmRecorderFactory>
1779 RenderThreadImpl::CreateUkmRecorderFactory() {
1780 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1781 switches::kDisableCompositorUkmForTests)) {
1785 return std::make_unique<UkmRecorderFactoryImpl>(GetConnector()->Clone());
1788 void RenderThreadImpl::OnRAILModeChanged(v8::RAILMode rail_mode) {
1789 blink::MainThreadIsolate()->SetRAILMode(rail_mode);
1790 blink::SetRAILModeOnWorkerThreadIsolates(rail_mode);
1793 bool RenderThreadImpl::IsMainThread() {
1797 void RenderThreadImpl::OnChannelError() {
1798 // In single-process mode, the renderer can't be restarted after shutdown.
1799 // So, if we get a channel error, crash the whole process right now to get a
1800 // more informative stack, since we will otherwise just crash later when we
1801 // try to restart it.
1802 CHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(
1803 switches::kSingleProcess));
1804 ChildThreadImpl::OnChannelError();
1807 void RenderThreadImpl::OnProcessFinalRelease() {
1808 if (on_channel_error_called())
1810 // The child process shutdown sequence is a request response based mechanism,
1811 // where we send out an initial feeler request to the child process host
1812 // instance in the browser to verify if it's ok to shutdown the child process.
1813 // The browser then sends back a response if it's ok to shutdown. This avoids
1814 // race conditions if the process refcount is 0 but there's an IPC message
1815 // inflight that would addref it.
1816 GetRendererHost()->ShutdownRequest();
1819 bool RenderThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
1820 for (auto& observer : observers_) {
1821 if (observer.OnControlMessageReceived(msg))
1825 // Some messages are handled by delegates.
1826 if (dom_storage_dispatcher_->OnMessageReceived(msg)) {
1832 void RenderThreadImpl::SetSchedulerKeepActive(bool keep_active) {
1833 main_thread_scheduler_->SetSchedulerKeepActive(keep_active);
1836 void RenderThreadImpl::SetProcessBackgrounded(bool backgrounded) {
1837 // Set timer slack to maximum on main thread when in background.
1838 base::TimerSlack timer_slack = base::TIMER_SLACK_NONE;
1840 timer_slack = base::TIMER_SLACK_MAXIMUM;
1841 main_message_loop_->SetTimerSlack(timer_slack);
1843 main_thread_scheduler_->SetRendererBackgrounded(backgrounded);
1845 needs_to_record_first_active_paint_ = false;
1846 GetWebMainThreadScheduler()->DefaultTaskRunner()->PostDelayedTask(
1848 base::BindOnce(&RenderThreadImpl::RecordMemoryUsageAfterBackgrounded,
1849 base::Unretained(this), "5min",
1850 process_foregrounded_count_),
1851 base::TimeDelta::FromMinutes(5));
1852 GetWebMainThreadScheduler()->DefaultTaskRunner()->PostDelayedTask(
1854 base::BindOnce(&RenderThreadImpl::RecordMemoryUsageAfterBackgrounded,
1855 base::Unretained(this), "10min",
1856 process_foregrounded_count_),
1857 base::TimeDelta::FromMinutes(10));
1858 GetWebMainThreadScheduler()->DefaultTaskRunner()->PostDelayedTask(
1860 base::BindOnce(&RenderThreadImpl::RecordMemoryUsageAfterBackgrounded,
1861 base::Unretained(this), "15min",
1862 process_foregrounded_count_),
1863 base::TimeDelta::FromMinutes(15));
1864 was_backgrounded_time_ = base::TimeTicks::Now();
1866 process_foregrounded_count_++;
1870 void RenderThreadImpl::ProcessPurgeAndSuspend() {
1871 if (!RendererIsHidden())
1874 if (!base::FeatureList::IsEnabled(features::kPurgeAndSuspend))
1877 base::MemoryCoordinatorClientRegistry::GetInstance()->PurgeMemory();
1878 needs_to_record_first_active_paint_ = true;
1880 RendererMemoryMetrics memory_metrics;
1881 if (!GetRendererMemoryMetrics(&memory_metrics))
1884 purge_and_suspend_memory_metrics_ = memory_metrics;
1885 GetWebMainThreadScheduler()->DefaultTaskRunner()->PostDelayedTask(
1888 &RenderThreadImpl::RecordPurgeAndSuspendMemoryGrowthMetrics,
1889 base::Unretained(this), "30min", process_foregrounded_count_),
1890 base::TimeDelta::FromMinutes(30));
1891 GetWebMainThreadScheduler()->DefaultTaskRunner()->PostDelayedTask(
1894 &RenderThreadImpl::RecordPurgeAndSuspendMemoryGrowthMetrics,
1895 base::Unretained(this), "60min", process_foregrounded_count_),
1896 base::TimeDelta::FromMinutes(60));
1897 GetWebMainThreadScheduler()->DefaultTaskRunner()->PostDelayedTask(
1900 &RenderThreadImpl::RecordPurgeAndSuspendMemoryGrowthMetrics,
1901 base::Unretained(this), "90min", process_foregrounded_count_),
1902 base::TimeDelta::FromMinutes(90));
1905 bool RenderThreadImpl::GetRendererMemoryMetrics(
1906 RendererMemoryMetrics* memory_metrics) const {
1907 DCHECK(memory_metrics);
1909 // Cache this result, as it can change while this code is running, and is used
1910 // as a divisor below.
1911 size_t render_view_count = RenderView::GetRenderViewCount();
1913 // If there are no render views it doesn't make sense to calculate metrics
1915 if (render_view_count == 0)
1918 blink::WebMemoryStatistics blink_stats = blink::WebMemoryStatistics::Get();
1919 memory_metrics->partition_alloc_kb =
1920 blink_stats.partition_alloc_total_allocated_bytes / 1024;
1921 memory_metrics->blink_gc_kb =
1922 blink_stats.blink_gc_total_allocated_bytes / 1024;
1923 std::unique_ptr<base::ProcessMetrics> metric(
1924 base::ProcessMetrics::CreateCurrentProcessMetrics());
1925 size_t malloc_usage = metric->GetMallocUsage();
1926 memory_metrics->malloc_mb = malloc_usage / 1024 / 1024;
1928 discardable_memory::ClientDiscardableSharedMemoryManager::Statistics
1929 discardable_stats = discardable_shared_memory_manager_->GetStatistics();
1930 size_t discardable_usage =
1931 discardable_stats.total_size - discardable_stats.freelist_size;
1932 memory_metrics->discardable_kb = discardable_usage / 1024;
1934 size_t v8_usage = 0;
1935 if (v8::Isolate* isolate = blink::MainThreadIsolate()) {
1936 v8::HeapStatistics v8_heap_statistics;
1937 isolate->GetHeapStatistics(&v8_heap_statistics);
1938 v8_usage = v8_heap_statistics.total_heap_size();
1940 // TODO(tasak): Currently only memory usage of mainThreadIsolate() is
1941 // reported. We should collect memory usages of all isolates using
1943 memory_metrics->v8_main_thread_isolate_mb = v8_usage / 1024 / 1024;
1944 size_t total_allocated = blink_stats.partition_alloc_total_allocated_bytes +
1945 blink_stats.blink_gc_total_allocated_bytes +
1946 malloc_usage + v8_usage + discardable_usage;
1947 memory_metrics->total_allocated_mb = total_allocated / 1024 / 1024;
1948 memory_metrics->non_discardable_total_allocated_mb =
1949 (total_allocated - discardable_usage) / 1024 / 1024;
1950 memory_metrics->total_allocated_per_render_view_mb =
1951 total_allocated / render_view_count / 1024 / 1024;
1956 static void RecordMemoryUsageAfterBackgroundedMB(const char* basename,
1959 std::string histogram_name = base::StringPrintf("%s.%s", basename, suffix);
1960 base::UmaHistogramMemoryLargeMB(histogram_name, memory_usage);
1963 void RenderThreadImpl::RecordMemoryUsageAfterBackgrounded(
1965 int foregrounded_count) {
1966 // If this renderer is resumed, we should not update UMA.
1967 if (!RendererIsHidden())
1969 // If this renderer was not kept backgrounded for 5/10/15 minutes,
1970 // we should not record current memory usage.
1971 if (foregrounded_count != process_foregrounded_count_)
1974 RendererMemoryMetrics memory_metrics;
1975 if (!GetRendererMemoryMetrics(&memory_metrics))
1977 RecordMemoryUsageAfterBackgroundedMB(
1978 "Memory.Experimental.Renderer.PartitionAlloc.AfterBackgrounded", suffix,
1979 memory_metrics.partition_alloc_kb / 1024);
1980 RecordMemoryUsageAfterBackgroundedMB(
1981 "Memory.Experimental.Renderer.BlinkGC.AfterBackgrounded", suffix,
1982 memory_metrics.blink_gc_kb / 1024);
1983 RecordMemoryUsageAfterBackgroundedMB(
1984 "Memory.Experimental.Renderer.Malloc.AfterBackgrounded", suffix,
1985 memory_metrics.malloc_mb);
1986 RecordMemoryUsageAfterBackgroundedMB(
1987 "Memory.Experimental.Renderer.Discardable.AfterBackgrounded", suffix,
1988 memory_metrics.discardable_kb / 1024);
1989 RecordMemoryUsageAfterBackgroundedMB(
1990 "Memory.Experimental.Renderer.V8MainThreaIsolate.AfterBackgrounded",
1991 suffix, memory_metrics.v8_main_thread_isolate_mb);
1992 RecordMemoryUsageAfterBackgroundedMB(
1993 "Memory.Experimental.Renderer.TotalAllocated.AfterBackgrounded", suffix,
1994 memory_metrics.total_allocated_mb);
1997 #define GET_MEMORY_GROWTH(current, previous, allocator) \
1998 (current.allocator > previous.allocator \
1999 ? current.allocator - previous.allocator \
2002 static void RecordPurgeAndSuspendMemoryGrowthKB(const char* basename,
2005 std::string histogram_name = base::StringPrintf("%s.%s", basename, suffix);
2006 base::UmaHistogramMemoryKB(histogram_name, memory_usage);
2009 void RenderThreadImpl::RecordPurgeAndSuspendMemoryGrowthMetrics(
2011 int foregrounded_count_when_purged) {
2012 // If this renderer is resumed, we should not update UMA.
2013 if (!RendererIsHidden())
2015 if (foregrounded_count_when_purged != process_foregrounded_count_)
2018 RendererMemoryMetrics memory_metrics;
2019 if (!GetRendererMemoryMetrics(&memory_metrics))
2022 RecordPurgeAndSuspendMemoryGrowthKB(
2023 "PurgeAndSuspend.Experimental.MemoryGrowth.PartitionAllocKB", suffix,
2024 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_,
2025 partition_alloc_kb));
2026 RecordPurgeAndSuspendMemoryGrowthKB(
2027 "PurgeAndSuspend.Experimental.MemoryGrowth.BlinkGCKB", suffix,
2028 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_,
2030 RecordPurgeAndSuspendMemoryGrowthKB(
2031 "PurgeAndSuspend.Experimental.MemoryGrowth.MallocKB", suffix,
2032 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_,
2035 RecordPurgeAndSuspendMemoryGrowthKB(
2036 "PurgeAndSuspend.Experimental.MemoryGrowth.DiscardableKB", suffix,
2037 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_,
2039 RecordPurgeAndSuspendMemoryGrowthKB(
2040 "PurgeAndSuspend.Experimental.MemoryGrowth.V8MainThreadIsolateKB", suffix,
2041 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_,
2042 v8_main_thread_isolate_mb) *
2044 RecordPurgeAndSuspendMemoryGrowthKB(
2045 "PurgeAndSuspend.Experimental.MemoryGrowth.TotalAllocatedKB", suffix,
2046 GET_MEMORY_GROWTH(memory_metrics, purge_and_suspend_memory_metrics_,
2047 total_allocated_mb) *
2051 void RenderThreadImpl::CompositingModeFallbackToSoftware() {
2052 gpu_->LoseChannel();
2053 is_gpu_compositing_disabled_ = true;
2056 scoped_refptr<gpu::GpuChannelHost> RenderThreadImpl::EstablishGpuChannelSync() {
2057 TRACE_EVENT0("gpu", "RenderThreadImpl::EstablishGpuChannelSync");
2059 scoped_refptr<gpu::GpuChannelHost> gpu_channel =
2060 gpu_->EstablishGpuChannelSync();
2062 GetContentClient()->SetGpuInfo(gpu_channel->gpu_info());
2066 void RenderThreadImpl::RequestNewLayerTreeFrameSink(
2068 scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue,
2070 const LayerTreeFrameSinkCallback& callback,
2071 mojom::RenderFrameMetadataObserverClientRequest
2072 render_frame_metadata_observer_client_request,
2073 mojom::RenderFrameMetadataObserverPtr render_frame_metadata_observer_ptr) {
2074 // Misconfigured bots (eg. crbug.com/780757) could run layout tests on a
2075 // machine where gpu compositing doesn't work. Don't crash in that case.
2076 if (layout_test_mode() && is_gpu_compositing_disabled_) {
2077 LOG(FATAL) << "Layout tests require gpu compositing, but it is disabled.";
2081 const base::CommandLine& command_line =
2082 *base::CommandLine::ForCurrentProcess();
2083 viz::ClientLayerTreeFrameSink::InitParams params;
2084 params.compositor_task_runner = compositor_task_runner_;
2085 params.enable_surface_synchronization =
2086 features::IsSurfaceSynchronizationEnabled();
2087 params.local_surface_id_provider =
2088 std::make_unique<RendererLocalSurfaceIdProvider>();
2089 if (features::IsVizHitTestingDrawQuadEnabled()) {
2090 params.hit_test_data_provider =
2091 std::make_unique<viz::HitTestDataProviderDrawQuad>(
2092 true /* should_ask_for_child_region */);
2093 } else if (features::IsVizHitTestingSurfaceLayerEnabled()) {
2094 params.hit_test_data_provider =
2095 std::make_unique<viz::HitTestDataProviderSurfaceLayer>();
2098 // The renderer runs animations and layout for animate_only BeginFrames.
2099 params.wants_animate_only_begin_frames = true;
2101 // In disable gpu vsync mode, also let the renderer tick as fast as it
2102 // can. The top level begin frame source will also be running as a back
2103 // to back begin frame source, but using a synthetic begin frame source
2104 // here reduces latency when in this mode (at least for frames
2105 // starting--it potentially increases it for input on the other hand.)
2106 if (command_line.HasSwitch(switches::kDisableGpuVsync) &&
2107 command_line.GetSwitchValueASCII(switches::kDisableGpuVsync) != "gpu") {
2108 params.synthetic_begin_frame_source = CreateSyntheticBeginFrameSource();
2111 #if defined(USE_AURA)
2112 if (base::FeatureList::IsEnabled(features::kMash)) {
2113 if (!RendererWindowTreeClient::Get(routing_id)) {
2114 callback.Run(nullptr);
2117 scoped_refptr<gpu::GpuChannelHost> channel = EstablishGpuChannelSync();
2118 // If the channel could not be established correctly, then return null. This
2119 // would cause the compositor to wait and try again at a later time.
2121 callback.Run(nullptr);
2124 RendererWindowTreeClient::Get(routing_id)
2125 ->RequestLayerTreeFrameSink(
2126 gpu_->CreateContextProvider(std::move(channel)),
2127 GetGpuMemoryBufferManager(), callback);
2132 viz::mojom::CompositorFrameSinkRequest compositor_frame_sink_request =
2133 mojo::MakeRequest(¶ms.pipes.compositor_frame_sink_info);
2134 viz::mojom::CompositorFrameSinkClientPtr compositor_frame_sink_client;
2135 params.pipes.client_request =
2136 mojo::MakeRequest(&compositor_frame_sink_client);
2138 if (is_gpu_compositing_disabled_) {
2139 DCHECK(!layout_test_mode());
2140 frame_sink_provider_->CreateForWidget(
2141 routing_id, std::move(compositor_frame_sink_request),
2142 std::move(compositor_frame_sink_client),
2143 std::move(render_frame_metadata_observer_client_request),
2144 std::move(render_frame_metadata_observer_ptr));
2145 params.shared_bitmap_manager = shared_bitmap_manager();
2146 callback.Run(std::make_unique<viz::ClientLayerTreeFrameSink>(
2147 nullptr, nullptr, ¶ms));
2151 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host =
2152 EstablishGpuChannelSync();
2153 if (!gpu_channel_host) {
2154 // Wait and try again. We may hear that the compositing mode has switched
2155 // to software in the meantime.
2156 callback.Run(nullptr);
2160 scoped_refptr<viz::RasterContextProvider> worker_context_provider =
2161 SharedCompositorWorkerContextProvider();
2162 if (!worker_context_provider) {
2163 // Cause the compositor to wait and try again.
2164 callback.Run(nullptr);
2168 // The renderer compositor context doesn't do a lot of stuff, so we don't
2169 // expect it to need a lot of space for commands or transfer. Raster and
2170 // uploads happen on the worker context instead.
2171 gpu::SharedMemoryLimits limits = gpu::SharedMemoryLimits::ForMailboxContext();
2173 // This is for an offscreen context for the compositor. So the default
2174 // framebuffer doesn't need alpha, depth, stencil, antialiasing.
2175 gpu::ContextCreationAttribs attributes;
2176 attributes.alpha_size = -1;
2177 attributes.depth_size = 0;
2178 attributes.stencil_size = 0;
2179 attributes.samples = 0;
2180 attributes.sample_buffers = 0;
2181 attributes.bind_generates_resource = false;
2182 attributes.lose_context_when_out_of_memory = true;
2183 attributes.enable_gles2_interface = true;
2184 attributes.enable_raster_interface = false;
2185 attributes.enable_oop_rasterization = false;
2187 constexpr bool automatic_flushes = false;
2188 constexpr bool support_locking = false;
2189 constexpr bool support_grcontext = false;
2191 scoped_refptr<ui::ContextProviderCommandBuffer> context_provider(
2192 new ui::ContextProviderCommandBuffer(
2193 gpu_channel_host, GetGpuMemoryBufferManager(), kGpuStreamIdDefault,
2194 kGpuStreamPriorityDefault, gpu::kNullSurfaceHandle, url,
2195 automatic_flushes, support_locking, support_grcontext, limits,
2196 attributes, nullptr /* share_context */,
2197 ui::command_buffer_metrics::RENDER_COMPOSITOR_CONTEXT));
2199 if (layout_test_deps_) {
2200 callback.Run(layout_test_deps_->CreateLayerTreeFrameSink(
2201 routing_id, std::move(gpu_channel_host), std::move(context_provider),
2202 std::move(worker_context_provider), GetGpuMemoryBufferManager(), this));
2206 #if defined(OS_ANDROID)
2207 if (GetContentClient()->UsingSynchronousCompositing()) {
2208 if (base::FeatureList::IsEnabled(features::kMojoInputMessages)) {
2209 RenderViewImpl* view = RenderViewImpl::FromRoutingID(routing_id);
2211 callback.Run(std::make_unique<SynchronousLayerTreeFrameSink>(
2212 std::move(context_provider), std::move(worker_context_provider),
2213 compositor_task_runner_, GetGpuMemoryBufferManager(),
2214 sync_message_filter(), routing_id,
2215 g_next_layer_tree_frame_sink_id++,
2216 std::move(params.synthetic_begin_frame_source),
2217 view->widget_input_handler_manager()
2218 ->GetSynchronousCompositorRegistry(),
2219 std::move(frame_swap_message_queue)));
2225 callback.Run(std::make_unique<SynchronousLayerTreeFrameSink>(
2226 std::move(context_provider), std::move(worker_context_provider),
2227 compositor_task_runner_, GetGpuMemoryBufferManager(),
2228 sync_compositor_message_filter_.get(), routing_id,
2229 g_next_layer_tree_frame_sink_id++,
2230 std::move(params.synthetic_begin_frame_source),
2231 sync_compositor_message_filter_.get(),
2232 std::move(frame_swap_message_queue)));
2237 frame_sink_provider_->CreateForWidget(
2238 routing_id, std::move(compositor_frame_sink_request),
2239 std::move(compositor_frame_sink_client),
2240 std::move(render_frame_metadata_observer_client_request),
2241 std::move(render_frame_metadata_observer_ptr));
2242 params.gpu_memory_buffer_manager = GetGpuMemoryBufferManager();
2243 callback.Run(std::make_unique<viz::ClientLayerTreeFrameSink>(
2244 std::move(context_provider), std::move(worker_context_provider),
2248 blink::AssociatedInterfaceRegistry*
2249 RenderThreadImpl::GetAssociatedInterfaceRegistry() {
2250 return &associated_interfaces_;
2253 std::unique_ptr<cc::SwapPromise>
2254 RenderThreadImpl::RequestCopyOfOutputForLayoutTest(
2256 std::unique_ptr<viz::CopyOutputRequest> request) {
2257 DCHECK(layout_test_deps_);
2258 return layout_test_deps_->RequestCopyOfOutput(routing_id, std::move(request));
2261 std::unique_ptr<blink::WebMediaStreamCenter>
2262 RenderThreadImpl::CreateMediaStreamCenter(
2263 blink::WebMediaStreamCenterClient* client) {
2264 std::unique_ptr<blink::WebMediaStreamCenter> media_stream_center;
2265 #if BUILDFLAG(ENABLE_WEBRTC)
2266 if (!media_stream_center) {
2267 media_stream_center = std::make_unique<MediaStreamCenter>(
2268 client, GetPeerConnectionDependencyFactory());
2271 return media_stream_center;
2274 #if BUILDFLAG(ENABLE_WEBRTC)
2275 PeerConnectionDependencyFactory*
2276 RenderThreadImpl::GetPeerConnectionDependencyFactory() {
2277 return peer_connection_factory_.get();
2281 mojom::RenderFrameMessageFilter*
2282 RenderThreadImpl::render_frame_message_filter() {
2283 if (!render_frame_message_filter_)
2284 GetChannel()->GetRemoteAssociatedInterface(&render_frame_message_filter_);
2285 return render_frame_message_filter_.get();
2288 mojom::RenderMessageFilter* RenderThreadImpl::render_message_filter() {
2289 if (!render_message_filter_)
2290 GetChannel()->GetRemoteAssociatedInterface(&render_message_filter_);
2291 return render_message_filter_.get();
2294 gpu::GpuChannelHost* RenderThreadImpl::GetGpuChannel() {
2295 return gpu_->GetGpuChannel().get();
2298 void RenderThreadImpl::CreateEmbedderRendererService(
2299 service_manager::mojom::ServiceRequest service_request) {
2300 GetContentClient()->renderer()->CreateRendererService(
2301 std::move(service_request));
2304 void RenderThreadImpl::CreateView(mojom::CreateViewParamsPtr params) {
2305 CompositorDependencies* compositor_deps = this;
2306 is_scroll_animator_enabled_ = params->web_preferences.enable_scroll_animator;
2307 // When bringing in render_view, also bring in webkit's glue and jsbindings.
2308 RenderViewImpl::Create(compositor_deps, std::move(params),
2309 RenderWidget::ShowCallback(),
2310 GetWebMainThreadScheduler()->DefaultTaskRunner());
2313 void RenderThreadImpl::CreateFrame(mojom::CreateFrameParamsPtr params) {
2314 CompositorDependencies* compositor_deps = this;
2315 service_manager::mojom::InterfaceProviderPtr interface_provider(
2316 std::move(params->interface_provider));
2317 RenderFrameImpl::CreateFrame(
2318 params->routing_id, std::move(interface_provider),
2319 params->proxy_routing_id, params->opener_routing_id,
2320 params->parent_routing_id, params->previous_sibling_routing_id,
2321 params->devtools_frame_token, params->replication_state, compositor_deps,
2322 *params->widget_params, params->frame_owner_properties,
2323 params->has_committed_real_load);
2326 void RenderThreadImpl::SetUpEmbeddedWorkerChannelForServiceWorker(
2327 mojom::EmbeddedWorkerInstanceClientAssociatedRequest client_request) {
2328 EmbeddedWorkerInstanceClientImpl::Create(
2329 blink_initialized_time_, GetIOTaskRunner(), std::move(client_request));
2332 void RenderThreadImpl::CreateFrameProxy(
2334 int32_t render_view_routing_id,
2335 int32_t opener_routing_id,
2336 int32_t parent_routing_id,
2337 const FrameReplicationState& replicated_state,
2338 const base::UnguessableToken& devtools_frame_token) {
2339 RenderFrameProxy::CreateFrameProxy(
2340 routing_id, render_view_routing_id,
2341 RenderFrameImpl::ResolveOpener(opener_routing_id), parent_routing_id,
2342 replicated_state, devtools_frame_token);
2345 void RenderThreadImpl::OnNetworkConnectionChanged(
2346 net::NetworkChangeNotifier::ConnectionType type,
2347 double max_bandwidth_mbps) {
2348 bool online = type != net::NetworkChangeNotifier::CONNECTION_NONE;
2349 WebNetworkStateNotifier::SetOnLine(online);
2350 for (auto& observer : observers_)
2351 observer.NetworkStateChanged(online);
2352 WebNetworkStateNotifier::SetWebConnection(
2353 NetConnectionTypeToWebConnectionType(type), max_bandwidth_mbps);
2356 void RenderThreadImpl::OnNetworkQualityChanged(
2357 net::EffectiveConnectionType type,
2358 base::TimeDelta http_rtt,
2359 base::TimeDelta transport_rtt,
2360 double downlink_throughput_kbps) {
2361 UMA_HISTOGRAM_BOOLEAN("NQE.RenderThreadNotified", true);
2362 WebNetworkStateNotifier::SetNetworkQuality(
2363 EffectiveConnectionTypeToWebEffectiveConnectionType(type), http_rtt,
2364 transport_rtt, downlink_throughput_kbps);
2367 void RenderThreadImpl::SetWebKitSharedTimersSuspended(bool suspend) {
2368 #if defined(OS_ANDROID)
2370 main_thread_scheduler_->PauseTimersForAndroidWebView();
2372 main_thread_scheduler_->ResumeTimersForAndroidWebView();
2374 webkit_shared_timer_suspended_ = suspend;
2380 void RenderThreadImpl::UpdateScrollbarTheme(
2381 mojom::UpdateScrollbarThemeParamsPtr params) {
2382 #if defined(OS_MACOSX)
2383 static_cast<WebScrollbarBehaviorImpl*>(
2384 blink_platform_impl_->ScrollbarBehavior())
2385 ->set_jump_on_track_click(params->jump_on_track_click);
2387 blink::WebScrollbarTheme::UpdateScrollbarsWithNSDefaults(
2388 params->initial_button_delay, params->autoscroll_button_delay,
2389 params->preferred_scroller_style, params->redraw,
2390 params->button_placement);
2392 is_elastic_overscroll_enabled_ = params->scroll_view_rubber_banding;
2398 void RenderThreadImpl::OnSystemColorsChanged(
2399 int32_t aqua_color_variant,
2400 const std::string& highlight_text_color,
2401 const std::string& highlight_color) {
2402 #if defined(OS_MACOSX)
2403 SystemColorsDidChange(aqua_color_variant, highlight_text_color,
2410 void RenderThreadImpl::PurgePluginListCache(bool reload_pages) {
2411 #if BUILDFLAG(ENABLE_PLUGINS)
2412 // The call below will cause a GetPlugins call with refresh=true, but at this
2413 // point we already know that the browser has refreshed its list, so disable
2414 // refresh temporarily to prevent each renderer process causing the list to be
2416 blink_platform_impl_->set_plugin_refresh_allowed(false);
2417 blink::ResetPluginCache(reload_pages);
2418 blink_platform_impl_->set_plugin_refresh_allowed(true);
2420 for (auto& observer : observers_)
2421 observer.PluginListChanged();
2427 void RenderThreadImpl::OnMemoryPressure(
2428 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
2429 TRACE_EVENT0("memory", "RenderThreadImpl::OnMemoryPressure");
2430 if (blink_platform_impl_) {
2431 blink::WebMemoryCoordinator::OnMemoryPressure(
2432 static_cast<blink::WebMemoryPressureLevel>(memory_pressure_level));
2434 if (memory_pressure_level ==
2435 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
2436 ReleaseFreeMemory();
2439 void RenderThreadImpl::OnMemoryStateChange(base::MemoryState state) {
2440 if (blink_platform_impl_) {
2441 blink::WebMemoryCoordinator::OnMemoryStateChange(
2442 static_cast<blink::MemoryState>(state));
2446 void RenderThreadImpl::OnPurgeMemory() {
2447 // Record amount of purged memory after 2 seconds. 2 seconds is arbitrary
2448 // but it works most cases.
2449 RendererMemoryMetrics metrics;
2450 if (!GetRendererMemoryMetrics(&metrics))
2453 GetWebMainThreadScheduler()->DefaultTaskRunner()->PostDelayedTask(
2455 base::BindOnce(&RenderThreadImpl::RecordPurgeMemory,
2456 base::Unretained(this), std::move(metrics)),
2457 base::TimeDelta::FromSeconds(2));
2459 OnTrimMemoryImmediately();
2460 ReleaseFreeMemory();
2461 if (blink_platform_impl_)
2462 blink::WebMemoryCoordinator::OnPurgeMemory();
2465 void RenderThreadImpl::RecordPurgeMemory(RendererMemoryMetrics before) {
2466 RendererMemoryMetrics after;
2467 if (!GetRendererMemoryMetrics(&after))
2469 int64_t mbytes = static_cast<int64_t>(before.total_allocated_mb) -
2470 static_cast<int64_t>(after.total_allocated_mb);
2473 UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer.PurgedMemory",
2477 scoped_refptr<base::SingleThreadTaskRunner>
2478 RenderThreadImpl::GetMediaThreadTaskRunner() {
2479 DCHECK(message_loop()->task_runner()->BelongsToCurrentThread());
2480 if (!media_thread_) {
2481 media_thread_.reset(new base::Thread("Media"));
2482 media_thread_->Start();
2484 return media_thread_->task_runner();
2487 base::TaskRunner* RenderThreadImpl::GetWorkerTaskRunner() {
2488 return categorized_worker_pool_.get();
2491 scoped_refptr<viz::RasterContextProvider>
2492 RenderThreadImpl::SharedCompositorWorkerContextProvider() {
2493 DCHECK(IsMainThread());
2494 // Try to reuse existing shared worker context provider.
2495 if (shared_worker_context_provider_) {
2496 // Note: If context is lost, delete reference after releasing the lock.
2497 viz::RasterContextProvider::ScopedRasterContextLock lock(
2498 shared_worker_context_provider_.get());
2499 if (lock.RasterInterface()->GetGraphicsResetStatusKHR() == GL_NO_ERROR)
2500 return shared_worker_context_provider_;
2503 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(
2504 EstablishGpuChannelSync());
2505 if (!gpu_channel_host) {
2506 shared_worker_context_provider_ = nullptr;
2507 return shared_worker_context_provider_;
2510 bool support_locking = true;
2511 bool support_oop_rasterization =
2512 base::CommandLine::ForCurrentProcess()->HasSwitch(
2513 switches::kEnableOOPRasterization);
2514 bool support_gles2_interface = !support_oop_rasterization;
2515 bool support_raster_interface = true;
2516 bool support_grcontext = !support_oop_rasterization;
2517 shared_worker_context_provider_ = CreateOffscreenContext(
2518 std::move(gpu_channel_host), GetGpuMemoryBufferManager(),
2519 gpu::SharedMemoryLimits(), support_locking, support_gles2_interface,
2520 support_raster_interface, support_oop_rasterization, support_grcontext,
2521 ui::command_buffer_metrics::RENDER_WORKER_CONTEXT, kGpuStreamIdWorker,
2522 kGpuStreamPriorityWorker);
2523 auto result = shared_worker_context_provider_->BindToCurrentThread();
2524 if (result != gpu::ContextResult::kSuccess)
2525 shared_worker_context_provider_ = nullptr;
2526 return shared_worker_context_provider_;
2529 void RenderThreadImpl::SampleGamepads(device::Gamepads* data) {
2530 blink_platform_impl_->SampleGamepads(*data);
2533 bool RenderThreadImpl::RendererIsHidden() const {
2534 return widget_count_ > 0 && hidden_widget_count_ == widget_count_;
2537 void RenderThreadImpl::WidgetCreated() {
2538 bool renderer_was_hidden = RendererIsHidden();
2540 if (renderer_was_hidden)
2541 OnRendererVisible();
2544 void RenderThreadImpl::WidgetDestroyed() {
2545 // TODO(rmcilroy): Remove the restriction that destroyed widgets must be
2546 // unhidden before WidgetDestroyed is called.
2547 DCHECK_GT(widget_count_, 0);
2548 DCHECK_GT(widget_count_, hidden_widget_count_);
2550 if (RendererIsHidden())
2554 void RenderThreadImpl::WidgetHidden() {
2555 DCHECK_LT(hidden_widget_count_, widget_count_);
2556 hidden_widget_count_++;
2557 if (RendererIsHidden())
2561 void RenderThreadImpl::WidgetRestored() {
2562 bool renderer_was_hidden = RendererIsHidden();
2563 DCHECK_GT(hidden_widget_count_, 0);
2564 hidden_widget_count_--;
2565 if (renderer_was_hidden)
2566 OnRendererVisible();
2569 void RenderThreadImpl::OnRendererHidden() {
2570 blink::MainThreadIsolate()->IsolateInBackgroundNotification();
2571 // TODO(rmcilroy): Remove IdleHandler and replace it with an IdleTask
2572 // scheduled by the RendererScheduler - http://crbug.com/469210.
2573 if (!GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden())
2575 main_thread_scheduler_->SetRendererHidden(true);
2576 ScheduleIdleHandler(kInitialIdleHandlerDelayMs);
2579 void RenderThreadImpl::OnRendererVisible() {
2580 blink::MainThreadIsolate()->IsolateInForegroundNotification();
2581 if (!GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden())
2583 main_thread_scheduler_->SetRendererHidden(false);
2584 ScheduleIdleHandler(kLongIdleHandlerDelayMs);
2587 void RenderThreadImpl::ReleaseFreeMemory() {
2588 base::allocator::ReleaseFreeMemory();
2589 discardable_shared_memory_manager_->ReleaseFreeMemory();
2591 // Do not call into blink if it is not initialized.
2592 if (blink_platform_impl_) {
2593 // Purge Skia font cache, resource cache, and image filter.
2594 SkGraphics::PurgeAllCaches();
2595 blink::DecommitFreeableMemory();
2599 RenderThreadImpl::PendingFrameCreate::PendingFrameCreate(
2600 const service_manager::BindSourceInfo& browser_info,
2602 mojom::FrameRequest frame_request)
2603 : browser_info_(browser_info),
2604 routing_id_(routing_id),
2605 frame_request_(std::move(frame_request)) {}
2607 RenderThreadImpl::PendingFrameCreate::~PendingFrameCreate() {
2610 void RenderThreadImpl::PendingFrameCreate::OnConnectionError() {
2612 RenderThreadImpl::current()->pending_frame_creates_.erase(routing_id_);
2613 DCHECK_EQ(1u, erased);
2616 void RenderThreadImpl::OnSyncMemoryPressure(
2617 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
2618 if (!blink::MainThreadIsolate())
2621 v8::MemoryPressureLevel v8_memory_pressure_level =
2622 static_cast<v8::MemoryPressureLevel>(memory_pressure_level);
2624 #if !BUILDFLAG(ALLOW_CRITICAL_MEMORY_PRESSURE_HANDLING_IN_FOREGROUND)
2625 // In order to reduce performance impact, translate critical level to
2626 // moderate level for foreground renderer.
2627 if (!RendererIsHidden() &&
2628 v8_memory_pressure_level == v8::MemoryPressureLevel::kCritical)
2629 v8_memory_pressure_level = v8::MemoryPressureLevel::kModerate;
2630 #endif // !BUILDFLAG(ALLOW_CRITICAL_MEMORY_PRESSURE_HANDLING_IN_FOREGROUND)
2632 blink::MainThreadIsolate()->MemoryPressureNotification(
2633 v8_memory_pressure_level);
2634 blink::MemoryPressureNotificationToWorkerThreadIsolates(
2635 v8_memory_pressure_level);
2638 // Note that this would be called only when memory_coordinator is enabled.
2639 // OnSyncMemoryPressure() is never called in that case.
2640 void RenderThreadImpl::OnTrimMemoryImmediately() {
2641 if (blink::MainThreadIsolate()) {
2642 blink::MainThreadIsolate()->MemoryPressureNotification(
2643 v8::MemoryPressureLevel::kCritical);
2644 blink::MemoryPressureNotificationToWorkerThreadIsolates(
2645 v8::MemoryPressureLevel::kCritical);
2649 void RenderThreadImpl::OnRendererInterfaceRequest(
2650 mojom::RendererAssociatedRequest request) {
2651 DCHECK(!renderer_binding_.is_bound());
2652 renderer_binding_.Bind(std::move(request),
2653 GetWebMainThreadScheduler()->IPCTaskRunner());
2656 bool RenderThreadImpl::NeedsToRecordFirstActivePaint(
2657 int ttfap_metric_type) const {
2658 if (ttfap_metric_type == RenderWidget::TTFAP_AFTER_PURGED)
2659 return needs_to_record_first_active_paint_;
2661 if (was_backgrounded_time_.is_min())
2663 base::TimeDelta passed = base::TimeTicks::Now() - was_backgrounded_time_;
2664 return passed.InMinutes() >= 5;
2667 void RenderThreadImpl::SetRenderingColorSpace(
2668 const gfx::ColorSpace& color_space) {
2669 DCHECK(IsMainThread());
2670 rendering_color_space_ = color_space;
2672 for (const auto& factories : gpu_factories_) {
2674 factories->SetRenderingColorSpace(color_space);
2678 } // namespace content