Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "services/ui/gpu/gpu_service.h" | 5 #include "services/ui/gpu/gpu_service.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/crash_logging.h" | 8 #include "base/debug/crash_logging.h" |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/memory/shared_memory.h" | 10 #include "base/memory/shared_memory.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 | 52 |
| 53 bool GpuLogMessageHandler(int severity, | 53 bool GpuLogMessageHandler(int severity, |
| 54 const char* file, | 54 const char* file, |
| 55 int line, | 55 int line, |
| 56 size_t message_start, | 56 size_t message_start, |
| 57 const std::string& message) { | 57 const std::string& message) { |
| 58 g_log_callback.Get().Run(severity, message_start, message); | 58 g_log_callback.Get().Run(severity, message_start, message); |
| 59 return false; | 59 return false; |
| 60 } | 60 } |
| 61 | 61 |
| 62 // Returns a callback which does a PostTask to run |callback| on the |runner| | |
| 63 // task runner. | |
| 64 template <typename Param> | |
| 65 const base::Callback<void(const Param&)> WrapCallback( | |
| 66 scoped_refptr<base::SingleThreadTaskRunner> runner, | |
| 67 const base::Callback<void(const Param&)>& callback) { | |
| 68 return base::Bind( | |
| 69 [](scoped_refptr<base::SingleThreadTaskRunner> runner, | |
| 70 const base::Callback<void(const Param&)>& callback, | |
| 71 const Param& param) { | |
| 72 runner->PostTask(FROM_HERE, base::Bind(callback, param)); | |
| 73 }, | |
| 74 runner, callback); | |
| 75 } | |
| 76 | |
| 62 } // namespace | 77 } // namespace |
| 63 | 78 |
| 64 GpuService::GpuService(const gpu::GPUInfo& gpu_info, | 79 GpuService::GpuService(const gpu::GPUInfo& gpu_info, |
| 65 std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread, | 80 std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread, |
| 66 gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory, | 81 gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory, |
| 67 scoped_refptr<base::SingleThreadTaskRunner> io_runner, | 82 scoped_refptr<base::SingleThreadTaskRunner> io_runner, |
| 68 const gpu::GpuFeatureInfo& gpu_feature_info) | 83 const gpu::GpuFeatureInfo& gpu_feature_info) |
| 69 : io_runner_(std::move(io_runner)), | 84 : main_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 85 io_runner_(std::move(io_runner)), | |
| 70 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, | 86 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, |
| 71 base::WaitableEvent::InitialState::NOT_SIGNALED), | 87 base::WaitableEvent::InitialState::NOT_SIGNALED), |
| 72 watchdog_thread_(std::move(watchdog_thread)), | 88 watchdog_thread_(std::move(watchdog_thread)), |
| 73 gpu_memory_buffer_factory_(gpu_memory_buffer_factory), | 89 gpu_memory_buffer_factory_(gpu_memory_buffer_factory), |
| 74 gpu_info_(gpu_info), | 90 gpu_info_(gpu_info), |
| 75 gpu_feature_info_(gpu_feature_info), | 91 gpu_feature_info_(gpu_feature_info), |
| 76 sync_point_manager_(nullptr) {} | 92 sync_point_manager_(nullptr), |
| 93 weak_ptr_factory_(this) { | |
| 94 weak_ptr_ = weak_ptr_factory_.GetWeakPtr(); | |
| 95 } | |
| 77 | 96 |
| 78 GpuService::~GpuService() { | 97 GpuService::~GpuService() { |
| 98 DCHECK(main_runner_->BelongsToCurrentThread()); | |
| 79 logging::SetLogMessageHandler(nullptr); | 99 logging::SetLogMessageHandler(nullptr); |
| 80 g_log_callback.Get() = | 100 g_log_callback.Get() = |
| 81 base::Callback<void(int, size_t, const std::string&)>(); | 101 base::Callback<void(int, size_t, const std::string&)>(); |
| 82 bindings_.CloseAllBindings(); | 102 bindings_.CloseAllBindings(); |
| 83 media_gpu_channel_manager_.reset(); | 103 media_gpu_channel_manager_.reset(); |
| 84 gpu_channel_manager_.reset(); | 104 gpu_channel_manager_.reset(); |
| 85 owned_sync_point_manager_.reset(); | 105 owned_sync_point_manager_.reset(); |
| 86 | 106 |
| 87 // Signal this event before destroying the child process. That way all | 107 // Signal this event before destroying the child process. That way all |
| 88 // background threads can cleanup. | 108 // background threads can cleanup. |
| 89 // For example, in the renderer the RenderThread instances will be able to | 109 // For example, in the renderer the RenderThread instances will be able to |
| 90 // notice shutdown before the render process begins waiting for them to exit. | 110 // notice shutdown before the render process begins waiting for them to exit. |
| 91 shutdown_event_.Signal(); | 111 shutdown_event_.Signal(); |
| 92 } | 112 } |
| 93 | 113 |
| 94 void GpuService::UpdateGPUInfoFromPreferences( | 114 void GpuService::UpdateGPUInfoFromPreferences( |
| 95 const gpu::GpuPreferences& preferences) { | 115 const gpu::GpuPreferences& preferences) { |
| 96 DCHECK(CalledOnValidThread()); | 116 DCHECK(main_runner_->BelongsToCurrentThread()); |
| 97 DCHECK(!gpu_host_); | 117 DCHECK(!gpu_host_); |
| 98 gpu_preferences_ = preferences; | 118 gpu_preferences_ = preferences; |
| 99 gpu_info_.video_decode_accelerator_capabilities = | 119 gpu_info_.video_decode_accelerator_capabilities = |
| 100 media::GpuVideoDecodeAccelerator::GetCapabilities(gpu_preferences_); | 120 media::GpuVideoDecodeAccelerator::GetCapabilities(gpu_preferences_); |
| 101 gpu_info_.video_encode_accelerator_supported_profiles = | 121 gpu_info_.video_encode_accelerator_supported_profiles = |
| 102 media::GpuVideoEncodeAccelerator::GetSupportedProfiles(gpu_preferences_); | 122 media::GpuVideoEncodeAccelerator::GetSupportedProfiles(gpu_preferences_); |
| 103 gpu_info_.jpeg_decode_accelerator_supported = | 123 gpu_info_.jpeg_decode_accelerator_supported = |
| 104 media::GpuJpegDecodeAcceleratorFactoryProvider:: | 124 media::GpuJpegDecodeAcceleratorFactoryProvider:: |
| 105 IsAcceleratedJpegDecodeSupported(); | 125 IsAcceleratedJpegDecodeSupported(); |
| 106 // Record initialization only after collecting the GPU info because that can | 126 // Record initialization only after collecting the GPU info because that can |
| 107 // take a significant amount of time. | 127 // take a significant amount of time. |
| 108 gpu_info_.initialization_time = base::Time::Now() - start_time_; | 128 gpu_info_.initialization_time = base::Time::Now() - start_time_; |
| 109 } | 129 } |
| 110 | 130 |
| 111 void GpuService::InitializeWithHost(mojom::GpuHostPtr gpu_host, | 131 void GpuService::InitializeWithHost(mojom::GpuHostPtr gpu_host, |
| 112 gpu::GpuProcessActivityFlags activity_flags, | 132 gpu::GpuProcessActivityFlags activity_flags, |
| 113 gpu::SyncPointManager* sync_point_manager, | 133 gpu::SyncPointManager* sync_point_manager, |
| 114 base::WaitableEvent* shutdown_event) { | 134 base::WaitableEvent* shutdown_event) { |
| 135 DCHECK(main_runner_->BelongsToCurrentThread()); | |
| 115 gpu_host->DidInitialize(gpu_info_, gpu_feature_info_); | 136 gpu_host->DidInitialize(gpu_info_, gpu_feature_info_); |
| 116 gpu_host_ = | 137 gpu_host_ = |
| 117 mojom::ThreadSafeGpuHostPtr::Create(gpu_host.PassInterface(), io_runner_); | 138 mojom::ThreadSafeGpuHostPtr::Create(gpu_host.PassInterface(), io_runner_); |
| 118 if (!in_host_process_) { | 139 if (!in_host_process_) { |
| 119 // The global callback is reset from the dtor. So Unretained() here is safe. | 140 // The global callback is reset from the dtor. So Unretained() here is safe. |
| 120 // Note that the callback can be called from any thread. Consequently, the | 141 // Note that the callback can be called from any thread. Consequently, the |
| 121 // callback cannot use a WeakPtr. | 142 // callback cannot use a WeakPtr. |
| 122 g_log_callback.Get() = | 143 g_log_callback.Get() = |
| 123 base::Bind(&GpuService::RecordLogMessage, base::Unretained(this)); | 144 base::Bind(&GpuService::RecordLogMessage, base::Unretained(this)); |
| 124 logging::SetLogMessageHandler(GpuLogMessageHandler); | 145 logging::SetLogMessageHandler(GpuLogMessageHandler); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 140 gpu_memory_buffer_factory_, gpu_feature_info_, | 161 gpu_memory_buffer_factory_, gpu_feature_info_, |
| 141 std::move(activity_flags))); | 162 std::move(activity_flags))); |
| 142 | 163 |
| 143 media_gpu_channel_manager_.reset( | 164 media_gpu_channel_manager_.reset( |
| 144 new media::MediaGpuChannelManager(gpu_channel_manager_.get())); | 165 new media::MediaGpuChannelManager(gpu_channel_manager_.get())); |
| 145 if (watchdog_thread()) | 166 if (watchdog_thread()) |
| 146 watchdog_thread()->AddPowerObserver(); | 167 watchdog_thread()->AddPowerObserver(); |
| 147 } | 168 } |
| 148 | 169 |
| 149 void GpuService::Bind(mojom::GpuServiceRequest request) { | 170 void GpuService::Bind(mojom::GpuServiceRequest request) { |
| 171 if (main_runner_->BelongsToCurrentThread()) { | |
| 172 io_runner_->PostTask(FROM_HERE, | |
| 173 base::Bind(&GpuService::Bind, base::Unretained(this), | |
| 174 base::Passed(std::move(request)))); | |
| 175 return; | |
| 176 } | |
| 150 bindings_.AddBinding(this, std::move(request)); | 177 bindings_.AddBinding(this, std::move(request)); |
| 151 } | 178 } |
| 152 | 179 |
| 153 void GpuService::RecordLogMessage(int severity, | 180 void GpuService::RecordLogMessage(int severity, |
| 154 size_t message_start, | 181 size_t message_start, |
| 155 const std::string& str) { | 182 const std::string& str) { |
| 183 // This can be run from any thread. | |
| 156 std::string header = str.substr(0, message_start); | 184 std::string header = str.substr(0, message_start); |
| 157 std::string message = str.substr(message_start); | 185 std::string message = str.substr(message_start); |
| 158 (*gpu_host_)->RecordLogMessage(severity, header, message); | 186 (*gpu_host_)->RecordLogMessage(severity, header, message); |
| 159 } | 187 } |
| 160 | 188 |
| 161 void GpuService::CreateGpuMemoryBuffer( | 189 void GpuService::CreateGpuMemoryBuffer( |
| 162 gfx::GpuMemoryBufferId id, | 190 gfx::GpuMemoryBufferId id, |
| 163 const gfx::Size& size, | 191 const gfx::Size& size, |
| 164 gfx::BufferFormat format, | 192 gfx::BufferFormat format, |
| 165 gfx::BufferUsage usage, | 193 gfx::BufferUsage usage, |
| 166 int client_id, | 194 int client_id, |
| 167 gpu::SurfaceHandle surface_handle, | 195 gpu::SurfaceHandle surface_handle, |
| 168 const CreateGpuMemoryBufferCallback& callback) { | 196 const CreateGpuMemoryBufferCallback& callback) { |
| 169 DCHECK(CalledOnValidThread()); | 197 DCHECK(io_runner_->BelongsToCurrentThread()); |
| 198 // This needs to happen in the IO thread. | |
| 170 callback.Run(gpu_memory_buffer_factory_->CreateGpuMemoryBuffer( | 199 callback.Run(gpu_memory_buffer_factory_->CreateGpuMemoryBuffer( |
| 171 id, size, format, usage, client_id, surface_handle)); | 200 id, size, format, usage, client_id, surface_handle)); |
| 172 } | 201 } |
| 173 | 202 |
| 174 void GpuService::DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, | 203 void GpuService::DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, |
| 175 int client_id, | 204 int client_id, |
| 176 const gpu::SyncToken& sync_token) { | 205 const gpu::SyncToken& sync_token) { |
| 177 DCHECK(CalledOnValidThread()); | 206 if (io_runner_->BelongsToCurrentThread()) { |
| 207 main_runner_->PostTask( | |
| 208 FROM_HERE, base::Bind(&GpuService::DestroyGpuMemoryBuffer, weak_ptr_, | |
|
sadrul
2017/03/28 05:40:13
Just a quick note: I deliberately thread-hopped in
| |
| 209 id, client_id, sync_token)); | |
| 210 return; | |
| 211 } | |
| 178 if (gpu_channel_manager_) | 212 if (gpu_channel_manager_) |
| 179 gpu_channel_manager_->DestroyGpuMemoryBuffer(id, client_id, sync_token); | 213 gpu_channel_manager_->DestroyGpuMemoryBuffer(id, client_id, sync_token); |
| 180 } | 214 } |
| 181 | 215 |
| 182 void GpuService::GetVideoMemoryUsageStats( | 216 void GpuService::GetVideoMemoryUsageStats( |
| 183 const GetVideoMemoryUsageStatsCallback& callback) { | 217 const GetVideoMemoryUsageStatsCallback& callback) { |
| 218 if (io_runner_->BelongsToCurrentThread()) { | |
| 219 auto wrap_callback = WrapCallback(io_runner_, callback); | |
| 220 main_runner_->PostTask( | |
| 221 FROM_HERE, base::Bind(&GpuService::GetVideoMemoryUsageStats, weak_ptr_, | |
| 222 wrap_callback)); | |
| 223 return; | |
| 224 } | |
| 184 gpu::VideoMemoryUsageStats video_memory_usage_stats; | 225 gpu::VideoMemoryUsageStats video_memory_usage_stats; |
| 185 if (gpu_channel_manager_) { | 226 if (gpu_channel_manager_) { |
| 186 gpu_channel_manager_->gpu_memory_manager()->GetVideoMemoryUsageStats( | 227 gpu_channel_manager_->gpu_memory_manager()->GetVideoMemoryUsageStats( |
| 187 &video_memory_usage_stats); | 228 &video_memory_usage_stats); |
| 188 } | 229 } |
| 189 callback.Run(video_memory_usage_stats); | 230 callback.Run(video_memory_usage_stats); |
| 190 } | 231 } |
| 191 | 232 |
| 192 void GpuService::RequestCompleteGpuInfo( | 233 void GpuService::RequestCompleteGpuInfo( |
| 193 const RequestCompleteGpuInfoCallback& callback) { | 234 const RequestCompleteGpuInfoCallback& callback) { |
| 235 if (io_runner_->BelongsToCurrentThread()) { | |
| 236 auto wrap_callback = WrapCallback(io_runner_, callback); | |
| 237 main_runner_->PostTask( | |
| 238 FROM_HERE, base::Bind(&GpuService::RequestCompleteGpuInfo, weak_ptr_, | |
| 239 wrap_callback)); | |
| 240 return; | |
| 241 } | |
| 194 UpdateGpuInfoPlatform(); | 242 UpdateGpuInfoPlatform(); |
| 195 callback.Run(gpu_info_); | 243 callback.Run(gpu_info_); |
| 196 #if defined(OS_WIN) | 244 #if defined(OS_WIN) |
| 197 if (!in_host_process_) { | 245 if (!in_host_process_) { |
| 198 // The unsandboxed GPU process fulfilled its duty. Rest in peace. | 246 // The unsandboxed GPU process fulfilled its duty. Rest in peace. |
| 199 base::MessageLoop::current()->QuitWhenIdle(); | 247 base::MessageLoop::current()->QuitWhenIdle(); |
| 200 } | 248 } |
| 201 #endif | 249 #endif |
| 202 } | 250 } |
| 203 | 251 |
| 204 #if defined(OS_MACOSX) | 252 #if defined(OS_MACOSX) |
| 205 void GpuService::UpdateGpuInfoPlatform() { | 253 void GpuService::UpdateGpuInfoPlatform() { |
| 254 DCHECK(main_runner_->BelongsToCurrentThread()); | |
| 206 // gpu::CollectContextGraphicsInfo() is already called during gpu process | 255 // gpu::CollectContextGraphicsInfo() is already called during gpu process |
| 207 // initialization (see GpuInit::InitializeAndStartSandbox()) on non-mac | 256 // initialization (see GpuInit::InitializeAndStartSandbox()) on non-mac |
| 208 // platforms, and during in-browser gpu thread initialization on all platforms | 257 // platforms, and during in-browser gpu thread initialization on all platforms |
| 209 // (See InProcessGpuThread::Init()). | 258 // (See InProcessGpuThread::Init()). |
| 210 if (in_host_process_) | 259 if (in_host_process_) |
| 211 return; | 260 return; |
| 212 | 261 |
| 213 DCHECK_EQ(gpu::kCollectInfoNone, gpu_info_.context_info_state); | 262 DCHECK_EQ(gpu::kCollectInfoNone, gpu_info_.context_info_state); |
| 214 gpu::CollectInfoResult result = gpu::CollectContextGraphicsInfo(&gpu_info_); | 263 gpu::CollectInfoResult result = gpu::CollectContextGraphicsInfo(&gpu_info_); |
| 215 switch (result) { | 264 switch (result) { |
| 216 case gpu::kCollectInfoFatalFailure: | 265 case gpu::kCollectInfoFatalFailure: |
| 217 LOG(ERROR) << "gpu::CollectGraphicsInfo failed (fatal)."; | 266 LOG(ERROR) << "gpu::CollectGraphicsInfo failed (fatal)."; |
| 218 // TODO(piman): can we signal overall failure? | 267 // TODO(piman): can we signal overall failure? |
| 219 break; | 268 break; |
| 220 case gpu::kCollectInfoNonFatalFailure: | 269 case gpu::kCollectInfoNonFatalFailure: |
| 221 DVLOG(1) << "gpu::CollectGraphicsInfo failed (non-fatal)."; | 270 DVLOG(1) << "gpu::CollectGraphicsInfo failed (non-fatal)."; |
| 222 break; | 271 break; |
| 223 case gpu::kCollectInfoNone: | 272 case gpu::kCollectInfoNone: |
| 224 NOTREACHED(); | 273 NOTREACHED(); |
| 225 break; | 274 break; |
| 226 case gpu::kCollectInfoSuccess: | 275 case gpu::kCollectInfoSuccess: |
| 227 break; | 276 break; |
| 228 } | 277 } |
| 229 gpu::SetKeysForCrashLogging(gpu_info_); | 278 gpu::SetKeysForCrashLogging(gpu_info_); |
| 230 } | 279 } |
| 231 #elif defined(OS_WIN) | 280 #elif defined(OS_WIN) |
| 232 void GpuService::UpdateGpuInfoPlatform() { | 281 void GpuService::UpdateGpuInfoPlatform() { |
| 282 DCHECK(main_runner_->BelongsToCurrentThread()); | |
| 233 // GPU full info collection should only happen on un-sandboxed GPU process | 283 // GPU full info collection should only happen on un-sandboxed GPU process |
| 234 // or single process/in-process gpu mode on Windows. | 284 // or single process/in-process gpu mode on Windows. |
| 235 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 285 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 236 DCHECK(command_line->HasSwitch("disable-gpu-sandbox") || in_host_process_); | 286 DCHECK(command_line->HasSwitch("disable-gpu-sandbox") || in_host_process_); |
| 237 | 287 |
| 238 // This is slow, but it's the only thing the unsandboxed GPU process does, | 288 // This is slow, but it's the only thing the unsandboxed GPU process does, |
| 239 // and GpuDataManager prevents us from sending multiple collecting requests, | 289 // and GpuDataManager prevents us from sending multiple collecting requests, |
| 240 // so it's OK to be blocking. | 290 // so it's OK to be blocking. |
| 241 gpu::GetDxDiagnostics(&gpu_info_.dx_diagnostics); | 291 gpu::GetDxDiagnostics(&gpu_info_.dx_diagnostics); |
| 242 gpu_info_.dx_diagnostics_info_state = gpu::kCollectInfoSuccess; | 292 gpu_info_.dx_diagnostics_info_state = gpu::kCollectInfoSuccess; |
| 243 } | 293 } |
| 244 #else | 294 #else |
| 245 void GpuService::UpdateGpuInfoPlatform() {} | 295 void GpuService::UpdateGpuInfoPlatform() {} |
| 246 #endif | 296 #endif |
| 247 | 297 |
| 248 void GpuService::DidCreateOffscreenContext(const GURL& active_url) { | 298 void GpuService::DidCreateOffscreenContext(const GURL& active_url) { |
| 299 DCHECK(main_runner_->BelongsToCurrentThread()); | |
| 249 (*gpu_host_)->DidCreateOffscreenContext(active_url); | 300 (*gpu_host_)->DidCreateOffscreenContext(active_url); |
| 250 } | 301 } |
| 251 | 302 |
| 252 void GpuService::DidDestroyChannel(int client_id) { | 303 void GpuService::DidDestroyChannel(int client_id) { |
| 304 DCHECK(main_runner_->BelongsToCurrentThread()); | |
| 253 media_gpu_channel_manager_->RemoveChannel(client_id); | 305 media_gpu_channel_manager_->RemoveChannel(client_id); |
| 254 (*gpu_host_)->DidDestroyChannel(client_id); | 306 (*gpu_host_)->DidDestroyChannel(client_id); |
| 255 } | 307 } |
| 256 | 308 |
| 257 void GpuService::DidDestroyOffscreenContext(const GURL& active_url) { | 309 void GpuService::DidDestroyOffscreenContext(const GURL& active_url) { |
| 310 DCHECK(main_runner_->BelongsToCurrentThread()); | |
| 258 (*gpu_host_)->DidDestroyOffscreenContext(active_url); | 311 (*gpu_host_)->DidDestroyOffscreenContext(active_url); |
| 259 } | 312 } |
| 260 | 313 |
| 261 void GpuService::DidLoseContext(bool offscreen, | 314 void GpuService::DidLoseContext(bool offscreen, |
| 262 gpu::error::ContextLostReason reason, | 315 gpu::error::ContextLostReason reason, |
| 263 const GURL& active_url) { | 316 const GURL& active_url) { |
| 317 DCHECK(main_runner_->BelongsToCurrentThread()); | |
| 264 (*gpu_host_)->DidLoseContext(offscreen, reason, active_url); | 318 (*gpu_host_)->DidLoseContext(offscreen, reason, active_url); |
| 265 } | 319 } |
| 266 | 320 |
| 267 void GpuService::StoreShaderToDisk(int client_id, | 321 void GpuService::StoreShaderToDisk(int client_id, |
| 268 const std::string& key, | 322 const std::string& key, |
| 269 const std::string& shader) { | 323 const std::string& shader) { |
| 324 DCHECK(main_runner_->BelongsToCurrentThread()); | |
| 270 (*gpu_host_)->StoreShaderToDisk(client_id, key, shader); | 325 (*gpu_host_)->StoreShaderToDisk(client_id, key, shader); |
| 271 } | 326 } |
| 272 | 327 |
| 273 #if defined(OS_WIN) | 328 #if defined(OS_WIN) |
| 274 void GpuService::SendAcceleratedSurfaceCreatedChildWindow( | 329 void GpuService::SendAcceleratedSurfaceCreatedChildWindow( |
| 275 gpu::SurfaceHandle parent_window, | 330 gpu::SurfaceHandle parent_window, |
| 276 gpu::SurfaceHandle child_window) { | 331 gpu::SurfaceHandle child_window) { |
| 332 DCHECK(main_runner_->BelongsToCurrentThread()); | |
| 277 (*gpu_host_)->SetChildSurface(parent_window, child_window); | 333 (*gpu_host_)->SetChildSurface(parent_window, child_window); |
| 278 } | 334 } |
| 279 #endif | 335 #endif |
| 280 | 336 |
| 281 void GpuService::SetActiveURL(const GURL& url) { | 337 void GpuService::SetActiveURL(const GURL& url) { |
| 338 DCHECK(main_runner_->BelongsToCurrentThread()); | |
| 282 constexpr char kActiveURL[] = "url-chunk"; | 339 constexpr char kActiveURL[] = "url-chunk"; |
| 283 base::debug::SetCrashKeyValue(kActiveURL, url.possibly_invalid_spec()); | 340 base::debug::SetCrashKeyValue(kActiveURL, url.possibly_invalid_spec()); |
| 284 } | 341 } |
| 285 | 342 |
| 286 void GpuService::EstablishGpuChannel( | 343 void GpuService::EstablishGpuChannel( |
| 287 int32_t client_id, | 344 int32_t client_id, |
| 288 uint64_t client_tracing_id, | 345 uint64_t client_tracing_id, |
| 289 bool is_gpu_host, | 346 bool is_gpu_host, |
| 290 const EstablishGpuChannelCallback& callback) { | 347 const EstablishGpuChannelCallback& callback) { |
| 291 DCHECK(CalledOnValidThread()); | 348 if (io_runner_->BelongsToCurrentThread()) { |
| 349 EstablishGpuChannelCallback wrap_callback = base::Bind( | |
| 350 [](scoped_refptr<base::SingleThreadTaskRunner> runner, | |
| 351 const EstablishGpuChannelCallback& callback, | |
| 352 mojo::ScopedMessagePipeHandle handle) { | |
| 353 runner->PostTask( | |
| 354 FROM_HERE, base::Bind(callback, base::Passed(std::move(handle)))); | |
| 355 }, | |
| 356 io_runner_, callback); | |
| 357 main_runner_->PostTask( | |
| 358 FROM_HERE, | |
| 359 base::Bind(&GpuService::EstablishGpuChannel, weak_ptr_, client_id, | |
| 360 client_tracing_id, is_gpu_host, wrap_callback)); | |
| 361 return; | |
| 362 } | |
| 292 | 363 |
| 293 if (!gpu_channel_manager_) { | 364 if (!gpu_channel_manager_) { |
| 294 callback.Run(mojo::ScopedMessagePipeHandle()); | 365 callback.Run(mojo::ScopedMessagePipeHandle()); |
| 295 return; | 366 return; |
| 296 } | 367 } |
| 297 | 368 |
| 298 const bool preempts = is_gpu_host; | 369 const bool preempts = is_gpu_host; |
| 299 const bool allow_view_command_buffers = is_gpu_host; | 370 const bool allow_view_command_buffers = is_gpu_host; |
| 300 const bool allow_real_time_streams = is_gpu_host; | 371 const bool allow_real_time_streams = is_gpu_host; |
| 301 mojo::ScopedMessagePipeHandle channel_handle; | 372 mojo::ScopedMessagePipeHandle channel_handle; |
| 302 IPC::ChannelHandle handle = gpu_channel_manager_->EstablishChannel( | 373 IPC::ChannelHandle handle = gpu_channel_manager_->EstablishChannel( |
| 303 client_id, client_tracing_id, preempts, allow_view_command_buffers, | 374 client_id, client_tracing_id, preempts, allow_view_command_buffers, |
| 304 allow_real_time_streams); | 375 allow_real_time_streams); |
| 305 channel_handle.reset(handle.mojo_handle); | 376 channel_handle.reset(handle.mojo_handle); |
| 306 media_gpu_channel_manager_->AddChannel(client_id); | 377 media_gpu_channel_manager_->AddChannel(client_id); |
| 307 callback.Run(std::move(channel_handle)); | 378 callback.Run(std::move(channel_handle)); |
| 308 } | 379 } |
| 309 | 380 |
| 310 void GpuService::CloseChannel(int32_t client_id) { | 381 void GpuService::CloseChannel(int32_t client_id) { |
| 382 if (io_runner_->BelongsToCurrentThread()) { | |
| 383 main_runner_->PostTask( | |
| 384 FROM_HERE, base::Bind(&GpuService::CloseChannel, weak_ptr_, client_id)); | |
| 385 return; | |
| 386 } | |
| 311 if (!gpu_channel_manager_) | 387 if (!gpu_channel_manager_) |
| 312 return; | 388 return; |
| 313 gpu_channel_manager_->RemoveChannel(client_id); | 389 gpu_channel_manager_->RemoveChannel(client_id); |
| 314 } | 390 } |
| 315 | 391 |
| 316 void GpuService::LoadedShader(const std::string& data) { | 392 void GpuService::LoadedShader(const std::string& data) { |
| 393 if (io_runner_->BelongsToCurrentThread()) { | |
| 394 main_runner_->PostTask( | |
| 395 FROM_HERE, base::Bind(&GpuService::LoadedShader, weak_ptr_, data)); | |
| 396 return; | |
| 397 } | |
| 317 if (!gpu_channel_manager_) | 398 if (!gpu_channel_manager_) |
| 318 return; | 399 return; |
| 319 gpu_channel_manager_->PopulateShaderCache(data); | 400 gpu_channel_manager_->PopulateShaderCache(data); |
| 320 } | 401 } |
| 321 | 402 |
| 322 void GpuService::DestroyingVideoSurface( | 403 void GpuService::DestroyingVideoSurface( |
| 323 int32_t surface_id, | 404 int32_t surface_id, |
| 324 const DestroyingVideoSurfaceCallback& callback) { | 405 const DestroyingVideoSurfaceCallback& callback) { |
| 406 DCHECK(io_runner_->BelongsToCurrentThread()); | |
| 325 #if defined(OS_ANDROID) | 407 #if defined(OS_ANDROID) |
| 326 media::AVDACodecAllocator::Instance()->OnSurfaceDestroyed(surface_id); | 408 main_runner_->PostTaskAndReply( |
| 409 FROM_HERE, | |
| 410 base::Bind( | |
| 411 [](int32_t surface_id) { | |
| 412 media::AVDACodecAllocator::Instance()->OnSurfaceDestroyed( | |
| 413 surface_id); | |
| 414 }, | |
| 415 surface_id), | |
| 416 callback); | |
| 327 #else | 417 #else |
| 328 NOTREACHED() << "DestroyingVideoSurface() not supported on this platform."; | 418 NOTREACHED() << "DestroyingVideoSurface() not supported on this platform."; |
| 329 #endif | 419 #endif |
| 330 callback.Run(); | |
| 331 } | 420 } |
| 332 | 421 |
| 333 void GpuService::WakeUpGpu() { | 422 void GpuService::WakeUpGpu() { |
| 423 if (io_runner_->BelongsToCurrentThread()) { | |
| 424 main_runner_->PostTask(FROM_HERE, | |
| 425 base::Bind(&GpuService::WakeUpGpu, weak_ptr_)); | |
| 426 return; | |
| 427 } | |
| 334 #if defined(OS_ANDROID) | 428 #if defined(OS_ANDROID) |
| 335 if (!gpu_channel_manager_) | 429 if (!gpu_channel_manager_) |
| 336 return; | 430 return; |
| 337 gpu_channel_manager_->WakeUpGpu(); | 431 gpu_channel_manager_->WakeUpGpu(); |
| 338 #else | 432 #else |
| 339 NOTREACHED() << "WakeUpGpu() not supported on this platform."; | 433 NOTREACHED() << "WakeUpGpu() not supported on this platform."; |
| 340 #endif | 434 #endif |
| 341 } | 435 } |
| 342 | 436 |
| 343 void GpuService::DestroyAllChannels() { | 437 void GpuService::DestroyAllChannels() { |
| 438 if (io_runner_->BelongsToCurrentThread()) { | |
| 439 main_runner_->PostTask( | |
| 440 FROM_HERE, base::Bind(&GpuService::DestroyAllChannels, weak_ptr_)); | |
| 441 return; | |
| 442 } | |
| 344 if (!gpu_channel_manager_) | 443 if (!gpu_channel_manager_) |
| 345 return; | 444 return; |
| 346 DVLOG(1) << "GPU: Removing all contexts"; | 445 DVLOG(1) << "GPU: Removing all contexts"; |
| 347 gpu_channel_manager_->DestroyAllChannels(); | 446 gpu_channel_manager_->DestroyAllChannels(); |
| 348 } | 447 } |
| 349 | 448 |
| 350 void GpuService::Crash() { | 449 void GpuService::Crash() { |
| 450 DCHECK(io_runner_->BelongsToCurrentThread()); | |
| 351 DVLOG(1) << "GPU: Simulating GPU crash"; | 451 DVLOG(1) << "GPU: Simulating GPU crash"; |
| 352 // Good bye, cruel world. | 452 // Good bye, cruel world. |
| 353 volatile int* it_s_the_end_of_the_world_as_we_know_it = NULL; | 453 volatile int* it_s_the_end_of_the_world_as_we_know_it = NULL; |
| 354 *it_s_the_end_of_the_world_as_we_know_it = 0xdead; | 454 *it_s_the_end_of_the_world_as_we_know_it = 0xdead; |
| 355 } | 455 } |
| 356 | 456 |
| 357 void GpuService::Hang() { | 457 void GpuService::Hang() { |
| 358 DVLOG(1) << "GPU: Simulating GPU hang"; | 458 DCHECK(io_runner_->BelongsToCurrentThread()); |
| 359 for (;;) { | 459 |
| 360 // Do not sleep here. The GPU watchdog timer tracks the amount of user | 460 main_runner_->PostTask(FROM_HERE, base::Bind([] { |
| 361 // time this thread is using and it doesn't use much while calling Sleep. | 461 DVLOG(1) << "GPU: Simulating GPU hang"; |
| 362 } | 462 for (;;) { |
| 463 // Do not sleep here. The GPU watchdog timer tracks | |
| 464 // the amount of user time this thread is using and | |
| 465 // it doesn't use much while calling Sleep. | |
| 466 } | |
| 467 })); | |
| 363 } | 468 } |
| 364 | 469 |
| 365 void GpuService::ThrowJavaException() { | 470 void GpuService::ThrowJavaException() { |
| 471 DCHECK(io_runner_->BelongsToCurrentThread()); | |
| 366 #if defined(OS_ANDROID) | 472 #if defined(OS_ANDROID) |
| 367 base::android::ThrowUncaughtException(); | 473 main_runner_->PostTask( |
| 474 FROM_HERE, base::Bind([] { base::android::ThrowUncaughtException(); })); | |
| 368 #else | 475 #else |
| 369 NOTREACHED() << "Java exception not supported on this platform."; | 476 NOTREACHED() << "Java exception not supported on this platform."; |
| 370 #endif | 477 #endif |
| 371 } | 478 } |
| 372 | 479 |
| 373 void GpuService::Stop(const StopCallback& callback) { | 480 void GpuService::Stop(const StopCallback& callback) { |
| 374 base::MessageLoop::current()->QuitWhenIdle(); | 481 DCHECK(io_runner_->BelongsToCurrentThread()); |
| 375 callback.Run(); | 482 main_runner_->PostTaskAndReply(FROM_HERE, base::Bind([] { |
| 483 base::MessageLoop::current()->QuitWhenIdle(); | |
| 484 }), | |
| 485 callback); | |
| 376 } | 486 } |
| 377 | 487 |
| 378 } // namespace ui | 488 } // namespace ui |
| OLD | NEW |