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