OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/gpu/gpu_child_thread.h" | 5 #include "content/gpu/gpu_child_thread.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
| 12 #include "base/threading/thread_checker.h" |
12 #include "build/build_config.h" | 13 #include "build/build_config.h" |
13 #include "content/child/child_process.h" | 14 #include "content/child/child_process.h" |
14 #include "content/common/field_trial_recorder.mojom.h" | 15 #include "content/common/field_trial_recorder.mojom.h" |
15 #include "content/gpu/gpu_service_factory.h" | 16 #include "content/gpu/gpu_service_factory.h" |
16 #include "content/public/common/content_client.h" | 17 #include "content/public/common/content_client.h" |
17 #include "content/public/common/content_switches.h" | 18 #include "content/public/common/content_switches.h" |
18 #include "content/public/common/service_manager_connection.h" | 19 #include "content/public/common/service_manager_connection.h" |
19 #include "content/public/common/service_names.mojom.h" | 20 #include "content/public/common/service_names.mojom.h" |
20 #include "content/public/gpu/content_gpu_client.h" | 21 #include "content/public/gpu/content_gpu_client.h" |
21 #include "gpu/command_buffer/common/activity_flags.h" | 22 #include "gpu/command_buffer/common/activity_flags.h" |
22 #include "gpu/ipc/service/gpu_watchdog_thread.h" | 23 #include "gpu/ipc/service/gpu_watchdog_thread.h" |
23 #include "ipc/ipc_sync_message_filter.h" | 24 #include "ipc/ipc_sync_message_filter.h" |
24 #include "media/gpu/ipc/service/media_gpu_channel_manager.h" | 25 #include "media/gpu/ipc/service/media_gpu_channel_manager.h" |
| 26 #include "services/service_manager/public/cpp/binder_registry.h" |
25 #include "services/service_manager/public/cpp/connector.h" | 27 #include "services/service_manager/public/cpp/connector.h" |
26 #include "services/service_manager/public/cpp/interface_registry.h" | |
27 #include "services/ui/gpu/interfaces/gpu_service.mojom.h" | 28 #include "services/ui/gpu/interfaces/gpu_service.mojom.h" |
28 | 29 |
29 #if defined(USE_OZONE) | 30 #if defined(USE_OZONE) |
30 #include "ui/ozone/public/ozone_platform.h" | 31 #include "ui/ozone/public/ozone_platform.h" |
31 #endif | 32 #endif |
32 | 33 |
33 #if defined(OS_ANDROID) | 34 #if defined(OS_ANDROID) |
34 #include "media/base/android/media_drm_bridge_client.h" | 35 #include "media/base/android/media_drm_bridge_client.h" |
35 #endif | 36 #endif |
36 | 37 |
37 namespace content { | 38 namespace content { |
38 namespace { | 39 namespace { |
39 | 40 |
40 ChildThreadImpl::Options GetOptions() { | 41 ChildThreadImpl::Options GetOptions() { |
41 ChildThreadImpl::Options::Builder builder; | 42 ChildThreadImpl::Options::Builder builder; |
42 | 43 |
43 #if defined(USE_OZONE) | 44 #if defined(USE_OZONE) |
44 IPC::MessageFilter* message_filter = | 45 IPC::MessageFilter* message_filter = |
45 ui::OzonePlatform::GetInstance()->GetGpuMessageFilter(); | 46 ui::OzonePlatform::GetInstance()->GetGpuMessageFilter(); |
46 if (message_filter) | 47 if (message_filter) |
47 builder.AddStartupFilter(message_filter); | 48 builder.AddStartupFilter(message_filter); |
48 #endif | 49 #endif |
49 | 50 |
| 51 builder.AutoStartServiceManagerConnection(false); |
50 builder.ConnectToBrowser(true); | 52 builder.ConnectToBrowser(true); |
51 | 53 |
52 return builder.Build(); | 54 return builder.Build(); |
53 } | 55 } |
54 | 56 |
55 } // namespace | 57 } // namespace |
56 | 58 |
| 59 // This ConnectionFilter queues all incoming bind interface requests until |
| 60 // Release() is called. |
| 61 class GpuChildThread::QueueingConnectionFilter : public ConnectionFilter { |
| 62 public: |
| 63 QueueingConnectionFilter( |
| 64 scoped_refptr<base::SequencedTaskRunner> io_task_runner, |
| 65 std::unique_ptr<service_manager::BinderRegistry> registry) |
| 66 : io_task_runner_(io_task_runner), |
| 67 registry_(std::move(registry)), |
| 68 weak_factory_(this) { |
| 69 // This will be reattached by any of the IO thread functions on first call. |
| 70 io_thread_checker_.DetachFromThread(); |
| 71 } |
| 72 ~QueueingConnectionFilter() override { |
| 73 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 74 } |
| 75 |
| 76 void Release() { |
| 77 base::AutoLock lock(lock_); |
| 78 released_ = true; |
| 79 io_task_runner_->PostTask( |
| 80 FROM_HERE, |
| 81 base::Bind(&QueueingConnectionFilter::ReleaseOnIOThread, GetWeakPtr())); |
| 82 } |
| 83 |
| 84 base::WeakPtr<QueueingConnectionFilter> GetWeakPtr() { |
| 85 return weak_factory_.GetWeakPtr(); |
| 86 } |
| 87 |
| 88 private: |
| 89 struct PendingRequest { |
| 90 service_manager::Identity source_identity; |
| 91 std::string interface_name; |
| 92 mojo::ScopedMessagePipeHandle interface_pipe; |
| 93 }; |
| 94 |
| 95 // ConnectionFilter: |
| 96 void OnBindInterface(const service_manager::ServiceInfo& source_info, |
| 97 const std::string& interface_name, |
| 98 mojo::ScopedMessagePipeHandle* interface_pipe, |
| 99 service_manager::Connector* connector) override { |
| 100 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 101 if (registry_->CanBindInterface(interface_name)) { |
| 102 base::AutoLock lock(lock_); |
| 103 if (released_) { |
| 104 registry_->BindInterface(source_info.identity, interface_name, |
| 105 std::move(*interface_pipe)); |
| 106 } else { |
| 107 std::unique_ptr<PendingRequest> request = |
| 108 base::MakeUnique<PendingRequest>(); |
| 109 request->source_identity = source_info.identity; |
| 110 request->interface_name = interface_name; |
| 111 request->interface_pipe = std::move(*interface_pipe); |
| 112 pending_requests_.push_back(std::move(request)); |
| 113 } |
| 114 } |
| 115 } |
| 116 |
| 117 void ReleaseOnIOThread() { |
| 118 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 119 for (auto& request : pending_requests_) { |
| 120 registry_->BindInterface(request->source_identity, |
| 121 request->interface_name, |
| 122 std::move(request->interface_pipe)); |
| 123 } |
| 124 } |
| 125 |
| 126 base::ThreadChecker io_thread_checker_; |
| 127 scoped_refptr<base::SequencedTaskRunner> io_task_runner_; |
| 128 // Guards |released_|. |
| 129 base::Lock lock_; |
| 130 bool released_ = false; |
| 131 std::vector<std::unique_ptr<PendingRequest>> pending_requests_; |
| 132 std::unique_ptr<service_manager::BinderRegistry> registry_; |
| 133 |
| 134 base::WeakPtrFactory<QueueingConnectionFilter> weak_factory_; |
| 135 |
| 136 DISALLOW_COPY_AND_ASSIGN(QueueingConnectionFilter); |
| 137 }; |
| 138 |
57 GpuChildThread::GpuChildThread( | 139 GpuChildThread::GpuChildThread( |
58 std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread, | 140 std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread, |
59 bool dead_on_arrival, | 141 bool dead_on_arrival, |
60 const gpu::GPUInfo& gpu_info, | 142 const gpu::GPUInfo& gpu_info, |
61 const gpu::GpuFeatureInfo& gpu_feature_info, | 143 const gpu::GpuFeatureInfo& gpu_feature_info, |
62 DeferredMessages deferred_messages) | 144 DeferredMessages deferred_messages) |
63 : GpuChildThread(GetOptions(), | 145 : GpuChildThread(GetOptions(), |
64 std::move(watchdog_thread), | 146 std::move(watchdog_thread), |
65 dead_on_arrival, | 147 dead_on_arrival, |
66 false /* in_browser_process */, | 148 false /* in_browser_process */, |
67 gpu_info, | 149 gpu_info, |
68 gpu_feature_info) { | 150 gpu_feature_info) { |
69 deferred_messages_ = std::move(deferred_messages); | 151 deferred_messages_ = std::move(deferred_messages); |
70 } | 152 } |
71 | 153 |
72 GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params, | 154 GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params, |
73 const gpu::GPUInfo& gpu_info, | 155 const gpu::GPUInfo& gpu_info, |
74 const gpu::GpuFeatureInfo& gpu_feature_info) | 156 const gpu::GpuFeatureInfo& gpu_feature_info) |
75 : GpuChildThread(ChildThreadImpl::Options::Builder() | 157 : GpuChildThread(ChildThreadImpl::Options::Builder() |
76 .InBrowserProcess(params) | 158 .InBrowserProcess(params) |
| 159 .AutoStartServiceManagerConnection(false) |
77 .ConnectToBrowser(true) | 160 .ConnectToBrowser(true) |
78 .Build(), | 161 .Build(), |
79 nullptr /* watchdog_thread */, | 162 nullptr /* watchdog_thread */, |
80 false /* dead_on_arrival */, | 163 false /* dead_on_arrival */, |
81 true /* in_browser_process */, | 164 true /* in_browser_process */, |
82 gpu_info, | 165 gpu_info, |
83 gpu_feature_info) {} | 166 gpu_feature_info) {} |
84 | 167 |
85 GpuChildThread::GpuChildThread( | 168 GpuChildThread::GpuChildThread( |
86 const ChildThreadImpl::Options& options, | 169 const ChildThreadImpl::Options& options, |
(...skipping 25 matching lines...) Expand all Loading... |
112 void GpuChildThread::Init(const base::Time& process_start_time) { | 195 void GpuChildThread::Init(const base::Time& process_start_time) { |
113 gpu_service_->set_start_time(process_start_time); | 196 gpu_service_->set_start_time(process_start_time); |
114 | 197 |
115 #if defined(OS_ANDROID) | 198 #if defined(OS_ANDROID) |
116 // When running in in-process mode, this has been set in the browser at | 199 // When running in in-process mode, this has been set in the browser at |
117 // ChromeBrowserMainPartsAndroid::PreMainMessageLoopRun(). | 200 // ChromeBrowserMainPartsAndroid::PreMainMessageLoopRun(). |
118 if (!in_browser_process_) | 201 if (!in_browser_process_) |
119 media::SetMediaDrmBridgeClient( | 202 media::SetMediaDrmBridgeClient( |
120 GetContentClient()->GetMediaDrmBridgeClient()); | 203 GetContentClient()->GetMediaDrmBridgeClient()); |
121 #endif | 204 #endif |
122 // We don't want to process any incoming interface requests until | 205 AssociatedInterfaceRegistry* associated_registry = &associated_interfaces_; |
123 // OnInitialize() is invoked. | 206 associated_registry->AddInterface(base::Bind( |
124 GetInterfaceRegistry()->PauseBinding(); | 207 &GpuChildThread::CreateGpuMainService, base::Unretained(this))); |
125 | 208 |
| 209 auto registry = base::MakeUnique<service_manager::BinderRegistry>(); |
| 210 registry->AddInterface(base::Bind(&GpuChildThread::BindServiceFactoryRequest, |
| 211 base::Unretained(this)), |
| 212 base::ThreadTaskRunnerHandle::Get()); |
126 if (GetContentClient()->gpu()) // NULL in tests. | 213 if (GetContentClient()->gpu()) // NULL in tests. |
127 GetContentClient()->gpu()->Initialize(this); | 214 GetContentClient()->gpu()->Initialize(this, registry.get()); |
128 AssociatedInterfaceRegistry* registry = &associated_interfaces_; | 215 |
129 registry->AddInterface(base::Bind( | 216 std::unique_ptr<QueueingConnectionFilter> filter = |
130 &GpuChildThread::CreateGpuMainService, base::Unretained(this))); | 217 base::MakeUnique<QueueingConnectionFilter>(GetIOTaskRunner(), |
| 218 std::move(registry)); |
| 219 queueing_filter_ = filter->GetWeakPtr(); |
| 220 GetServiceManagerConnection()->AddConnectionFilter(std::move(filter)); |
| 221 |
| 222 StartServiceManagerConnection(); |
131 } | 223 } |
132 | 224 |
133 void GpuChildThread::OnFieldTrialGroupFinalized(const std::string& trial_name, | 225 void GpuChildThread::OnFieldTrialGroupFinalized(const std::string& trial_name, |
134 const std::string& group_name) { | 226 const std::string& group_name) { |
135 mojom::FieldTrialRecorderPtr field_trial_recorder; | 227 mojom::FieldTrialRecorderPtr field_trial_recorder; |
136 GetConnector()->BindInterface(mojom::kBrowserServiceName, | 228 GetConnector()->BindInterface(mojom::kBrowserServiceName, |
137 &field_trial_recorder); | 229 &field_trial_recorder); |
138 field_trial_recorder->FieldTrialActivated(trial_name); | 230 field_trial_recorder->FieldTrialActivated(trial_name); |
139 } | 231 } |
140 | 232 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 gpu_service_->InitializeWithHost( | 281 gpu_service_->InitializeWithHost( |
190 std::move(gpu_host), | 282 std::move(gpu_host), |
191 gpu::GpuProcessActivityFlags(std::move(activity_flags)), | 283 gpu::GpuProcessActivityFlags(std::move(activity_flags)), |
192 sync_point_manager, ChildProcess::current()->GetShutDownEvent()); | 284 sync_point_manager, ChildProcess::current()->GetShutDownEvent()); |
193 CHECK(gpu_service_->media_gpu_channel_manager()); | 285 CHECK(gpu_service_->media_gpu_channel_manager()); |
194 | 286 |
195 // Only set once per process instance. | 287 // Only set once per process instance. |
196 service_factory_.reset(new GpuServiceFactory( | 288 service_factory_.reset(new GpuServiceFactory( |
197 gpu_service_->media_gpu_channel_manager()->AsWeakPtr())); | 289 gpu_service_->media_gpu_channel_manager()->AsWeakPtr())); |
198 | 290 |
199 GetInterfaceRegistry()->AddInterface(base::Bind( | 291 if (GetContentClient()->gpu()) // NULL in tests. |
200 &GpuChildThread::BindServiceFactoryRequest, base::Unretained(this))); | 292 GetContentClient()->gpu()->GpuServiceInitialized(gpu_preferences); |
201 | 293 |
202 if (GetContentClient()->gpu()) { // NULL in tests. | 294 if (queueing_filter_) |
203 GetContentClient()->gpu()->ExposeInterfacesToBrowser(GetInterfaceRegistry(), | 295 queueing_filter_->Release(); |
204 gpu_preferences); | |
205 GetContentClient()->gpu()->ConsumeInterfacesFromBrowser(GetConnector()); | |
206 } | |
207 | |
208 GetInterfaceRegistry()->ResumeBinding(); | |
209 } | 296 } |
210 | 297 |
211 void GpuChildThread::CreateFrameSinkManager( | 298 void GpuChildThread::CreateFrameSinkManager( |
212 cc::mojom::FrameSinkManagerRequest request, | 299 cc::mojom::FrameSinkManagerRequest request, |
213 cc::mojom::FrameSinkManagerClientPtr client) { | 300 cc::mojom::FrameSinkManagerClientPtr client) { |
214 NOTREACHED(); | 301 NOTREACHED(); |
215 } | 302 } |
216 | 303 |
217 void GpuChildThread::BindServiceFactoryRequest( | 304 void GpuChildThread::BindServiceFactoryRequest( |
218 service_manager::mojom::ServiceFactoryRequest request) { | 305 service_manager::mojom::ServiceFactoryRequest request) { |
219 DVLOG(1) << "GPU: Binding service_manager::mojom::ServiceFactoryRequest"; | 306 DVLOG(1) << "GPU: Binding service_manager::mojom::ServiceFactoryRequest"; |
220 DCHECK(service_factory_); | 307 DCHECK(service_factory_); |
221 service_factory_bindings_.AddBinding(service_factory_.get(), | 308 service_factory_bindings_.AddBinding(service_factory_.get(), |
222 std::move(request)); | 309 std::move(request)); |
223 } | 310 } |
224 | 311 |
225 } // namespace content | 312 } // namespace content |
OLD | NEW |