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