| 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/browser/gpu/browser_gpu_channel_host_factory.h" | 5 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" |
| 6 | 6 |
| 7 #include <set> | |
| 8 | |
| 9 #include "base/bind.h" | 7 #include "base/bind.h" |
| 10 #include "base/location.h" | 8 #include "base/location.h" |
| 11 #include "base/profiler/scoped_tracker.h" | 9 #include "base/profiler/scoped_tracker.h" |
| 12 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
| 13 #include "base/synchronization/waitable_event.h" | 11 #include "base/synchronization/waitable_event.h" |
| 14 #include "base/thread_task_runner_handle.h" | 12 #include "base/thread_task_runner_handle.h" |
| 15 #include "base/threading/thread_restrictions.h" | 13 #include "base/threading/thread_restrictions.h" |
| 16 #include "base/trace_event/trace_event.h" | 14 #include "base/trace_event/trace_event.h" |
| 17 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" | 15 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" |
| 18 #include "content/browser/gpu/gpu_data_manager_impl.h" | 16 #include "content/browser/gpu/gpu_data_manager_impl.h" |
| 19 #include "content/browser/gpu/gpu_process_host.h" | 17 #include "content/browser/gpu/gpu_process_host.h" |
| 20 #include "content/browser/gpu/gpu_surface_tracker.h" | 18 #include "content/browser/gpu/gpu_surface_tracker.h" |
| 21 #include "content/common/child_process_host_impl.h" | 19 #include "content/common/child_process_host_impl.h" |
| 22 #include "content/common/gpu/gpu_memory_buffer_factory.h" | |
| 23 #include "content/common/gpu/gpu_messages.h" | 20 #include "content/common/gpu/gpu_messages.h" |
| 24 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
| 25 #include "content/public/browser/gpu_data_manager.h" | 22 #include "content/public/browser/gpu_data_manager.h" |
| 26 #include "content/public/common/content_client.h" | 23 #include "content/public/common/content_client.h" |
| 27 #include "gpu/GLES2/gl2extchromium.h" | |
| 28 #include "ipc/ipc_channel_handle.h" | 24 #include "ipc/ipc_channel_handle.h" |
| 29 #include "ipc/ipc_forwarding_message_filter.h" | 25 #include "ipc/ipc_forwarding_message_filter.h" |
| 30 #include "ipc/message_filter.h" | 26 #include "ipc/message_filter.h" |
| 31 | 27 |
| 32 #if defined(OS_MACOSX) | |
| 33 #include "content/common/gpu/gpu_memory_buffer_factory_io_surface.h" | |
| 34 #endif | |
| 35 | |
| 36 #if defined(OS_ANDROID) | |
| 37 #include "content/common/gpu/gpu_memory_buffer_factory_surface_texture.h" | |
| 38 #endif | |
| 39 | |
| 40 #if defined(USE_OZONE) | |
| 41 #include "content/common/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h" | |
| 42 #endif | |
| 43 | |
| 44 namespace content { | 28 namespace content { |
| 45 namespace { | |
| 46 | |
| 47 base::LazyInstance<std::set<gfx::GpuMemoryBuffer::Usage>> | |
| 48 g_enabled_gpu_memory_buffer_usages; | |
| 49 | |
| 50 bool IsGpuMemoryBufferFactoryConfigurationSupported( | |
| 51 gfx::GpuMemoryBuffer::Format format, | |
| 52 gfx::GpuMemoryBuffer::Usage usage, | |
| 53 gfx::GpuMemoryBufferType type) { | |
| 54 switch (type) { | |
| 55 case gfx::SHARED_MEMORY_BUFFER: | |
| 56 // Shared memory buffers must be created in-process. | |
| 57 return false; | |
| 58 #if defined(OS_MACOSX) | |
| 59 case gfx::IO_SURFACE_BUFFER: | |
| 60 return GpuMemoryBufferFactoryIOSurface:: | |
| 61 IsGpuMemoryBufferConfigurationSupported(format, usage); | |
| 62 #endif | |
| 63 #if defined(OS_ANDROID) | |
| 64 case gfx::SURFACE_TEXTURE_BUFFER: | |
| 65 return GpuMemoryBufferFactorySurfaceTexture:: | |
| 66 IsGpuMemoryBufferConfigurationSupported(format, usage); | |
| 67 #endif | |
| 68 #if defined(USE_OZONE) | |
| 69 case gfx::OZONE_NATIVE_BUFFER: | |
| 70 return GpuMemoryBufferFactoryOzoneNativeBuffer:: | |
| 71 IsGpuMemoryBufferConfigurationSupported(format, usage); | |
| 72 #endif | |
| 73 default: | |
| 74 NOTREACHED(); | |
| 75 return false; | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 } // namespace | |
| 80 | 29 |
| 81 BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL; | 30 BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL; |
| 82 | 31 |
| 83 struct BrowserGpuChannelHostFactory::CreateRequest { | 32 struct BrowserGpuChannelHostFactory::CreateRequest { |
| 84 CreateRequest(int32 route_id) | 33 CreateRequest(int32 route_id) |
| 85 : event(true, false), | 34 : event(true, false), |
| 86 gpu_host_id(0), | 35 gpu_host_id(0), |
| 87 route_id(route_id), | 36 route_id(route_id), |
| 88 result(CREATE_COMMAND_BUFFER_FAILED) {} | 37 result(CREATE_COMMAND_BUFFER_FAILED) {} |
| 89 ~CreateRequest() {} | 38 ~CreateRequest() {} |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 base::Closure()); | 216 base::Closure()); |
| 268 } | 217 } |
| 269 } | 218 } |
| 270 | 219 |
| 271 void BrowserGpuChannelHostFactory::Terminate() { | 220 void BrowserGpuChannelHostFactory::Terminate() { |
| 272 DCHECK(instance_); | 221 DCHECK(instance_); |
| 273 delete instance_; | 222 delete instance_; |
| 274 instance_ = NULL; | 223 instance_ = NULL; |
| 275 } | 224 } |
| 276 | 225 |
| 277 // static | |
| 278 void BrowserGpuChannelHostFactory::EnableGpuMemoryBufferFactoryUsage( | |
| 279 gfx::GpuMemoryBuffer::Usage usage) { | |
| 280 g_enabled_gpu_memory_buffer_usages.Get().insert(usage); | |
| 281 } | |
| 282 | |
| 283 // static | |
| 284 bool BrowserGpuChannelHostFactory::IsGpuMemoryBufferFactoryUsageEnabled( | |
| 285 gfx::GpuMemoryBuffer::Usage usage) { | |
| 286 return g_enabled_gpu_memory_buffer_usages.Get().count(usage) != 0; | |
| 287 } | |
| 288 | |
| 289 // static | |
| 290 uint32 BrowserGpuChannelHostFactory::GetImageTextureTarget( | |
| 291 gfx::GpuMemoryBuffer::Format format, | |
| 292 gfx::GpuMemoryBuffer::Usage usage) { | |
| 293 if (!IsGpuMemoryBufferFactoryUsageEnabled(usage)) | |
| 294 return GL_TEXTURE_2D; | |
| 295 | |
| 296 std::vector<gfx::GpuMemoryBufferType> supported_types; | |
| 297 GpuMemoryBufferFactory::GetSupportedTypes(&supported_types); | |
| 298 DCHECK(!supported_types.empty()); | |
| 299 | |
| 300 // The GPU service will always use the preferred type, if the |format| and | |
| 301 // |usage| allows. | |
| 302 gfx::GpuMemoryBufferType type = supported_types[0]; | |
| 303 | |
| 304 if (!IsGpuMemoryBufferFactoryConfigurationSupported(format, usage, type)) | |
| 305 return GL_TEXTURE_2D; | |
| 306 | |
| 307 switch (type) { | |
| 308 case gfx::SURFACE_TEXTURE_BUFFER: | |
| 309 case gfx::OZONE_NATIVE_BUFFER: | |
| 310 // GPU memory buffers that are shared with the GL using EGLImages require | |
| 311 // TEXTURE_EXTERNAL_OES. | |
| 312 return GL_TEXTURE_EXTERNAL_OES; | |
| 313 case gfx::IO_SURFACE_BUFFER: | |
| 314 // IOSurface backed images require GL_TEXTURE_RECTANGLE_ARB. | |
| 315 return GL_TEXTURE_RECTANGLE_ARB; | |
| 316 default: | |
| 317 return GL_TEXTURE_2D; | |
| 318 } | |
| 319 } | |
| 320 | |
| 321 BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory() | 226 BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory() |
| 322 : gpu_client_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), | 227 : gpu_client_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), |
| 323 shutdown_event_(new base::WaitableEvent(true, false)), | 228 shutdown_event_(new base::WaitableEvent(true, false)), |
| 324 gpu_memory_buffer_manager_( | 229 gpu_memory_buffer_manager_( |
| 325 new BrowserGpuMemoryBufferManager(this, gpu_client_id_)), | 230 new BrowserGpuMemoryBufferManager(gpu_client_id_)), |
| 326 gpu_host_id_(0), | 231 gpu_host_id_(0) { |
| 327 next_create_gpu_memory_buffer_request_id_(0) { | |
| 328 } | 232 } |
| 329 | 233 |
| 330 BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() { | 234 BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() { |
| 331 DCHECK(IsMainThread()); | 235 DCHECK(IsMainThread()); |
| 332 if (pending_request_.get()) | 236 if (pending_request_.get()) |
| 333 pending_request_->Cancel(); | 237 pending_request_->Cancel(); |
| 334 for (size_t n = 0; n < established_callbacks_.size(); n++) | 238 for (size_t n = 0; n < established_callbacks_.size(); n++) |
| 335 established_callbacks_[n].Run(); | 239 established_callbacks_[n].Run(); |
| 336 shutdown_event_->Signal(); | 240 shutdown_event_->Signal(); |
| 337 if (gpu_channel_) { | 241 if (gpu_channel_) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 DCHECK(pending_request_.get()); | 371 DCHECK(pending_request_.get()); |
| 468 if (pending_request_->channel_handle().name.empty()) { | 372 if (pending_request_->channel_handle().name.empty()) { |
| 469 DCHECK(!gpu_channel_.get()); | 373 DCHECK(!gpu_channel_.get()); |
| 470 } else { | 374 } else { |
| 471 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466866 | 375 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466866 |
| 472 // is fixed. | 376 // is fixed. |
| 473 tracked_objects::ScopedTracker tracking_profile1( | 377 tracked_objects::ScopedTracker tracking_profile1( |
| 474 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 378 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 475 "466866 BrowserGpuChannelHostFactory::GpuChannelEstablished1")); | 379 "466866 BrowserGpuChannelHostFactory::GpuChannelEstablished1")); |
| 476 GetContentClient()->SetGpuInfo(pending_request_->gpu_info()); | 380 GetContentClient()->SetGpuInfo(pending_request_->gpu_info()); |
| 477 gpu_channel_ = | 381 gpu_channel_ = GpuChannelHost::Create( |
| 478 GpuChannelHost::Create(this, | 382 this, pending_request_->gpu_info(), pending_request_->channel_handle(), |
| 479 pending_request_->gpu_info(), | 383 shutdown_event_.get(), gpu_memory_buffer_manager_.get()); |
| 480 pending_request_->channel_handle(), | |
| 481 shutdown_event_.get(), | |
| 482 BrowserGpuMemoryBufferManager::current()); | |
| 483 } | 384 } |
| 484 gpu_host_id_ = pending_request_->gpu_host_id(); | 385 gpu_host_id_ = pending_request_->gpu_host_id(); |
| 485 pending_request_ = NULL; | 386 pending_request_ = NULL; |
| 486 | 387 |
| 487 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466866 is | 388 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466866 is |
| 488 // fixed. | 389 // fixed. |
| 489 tracked_objects::ScopedTracker tracking_profile2( | 390 tracked_objects::ScopedTracker tracking_profile2( |
| 490 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 391 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 491 "466866 BrowserGpuChannelHostFactory::GpuChannelEstablished2")); | 392 "466866 BrowserGpuChannelHostFactory::GpuChannelEstablished2")); |
| 492 | 393 |
| 493 for (size_t n = 0; n < established_callbacks_.size(); n++) | 394 for (size_t n = 0; n < established_callbacks_.size(); n++) |
| 494 established_callbacks_[n].Run(); | 395 established_callbacks_[n].Run(); |
| 495 | 396 |
| 496 established_callbacks_.clear(); | 397 established_callbacks_.clear(); |
| 497 } | 398 } |
| 498 | 399 |
| 499 // static | 400 // static |
| 500 void BrowserGpuChannelHostFactory::AddFilterOnIO( | 401 void BrowserGpuChannelHostFactory::AddFilterOnIO( |
| 501 int host_id, | 402 int host_id, |
| 502 scoped_refptr<IPC::MessageFilter> filter) { | 403 scoped_refptr<IPC::MessageFilter> filter) { |
| 503 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 404 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 504 | 405 |
| 505 GpuProcessHost* host = GpuProcessHost::FromID(host_id); | 406 GpuProcessHost* host = GpuProcessHost::FromID(host_id); |
| 506 if (host) | 407 if (host) |
| 507 host->AddFilter(filter.get()); | 408 host->AddFilter(filter.get()); |
| 508 } | 409 } |
| 509 | 410 |
| 510 bool BrowserGpuChannelHostFactory::IsGpuMemoryBufferConfigurationSupported( | |
| 511 gfx::GpuMemoryBuffer::Format format, | |
| 512 gfx::GpuMemoryBuffer::Usage usage) { | |
| 513 // Return early if usage is not enabled. | |
| 514 if (!IsGpuMemoryBufferFactoryUsageEnabled(usage)) | |
| 515 return false; | |
| 516 | |
| 517 std::vector<gfx::GpuMemoryBufferType> supported_types; | |
| 518 GpuMemoryBufferFactory::GetSupportedTypes(&supported_types); | |
| 519 DCHECK(!supported_types.empty()); | |
| 520 | |
| 521 // The GPU service will always use the preferred type, if the |format| and | |
| 522 // |usage| allows. | |
| 523 gfx::GpuMemoryBufferType type = supported_types[0]; | |
| 524 | |
| 525 return IsGpuMemoryBufferFactoryConfigurationSupported(format, usage, type); | |
| 526 } | |
| 527 | |
| 528 void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer( | |
| 529 gfx::GpuMemoryBufferId id, | |
| 530 const gfx::Size& size, | |
| 531 gfx::GpuMemoryBuffer::Format format, | |
| 532 gfx::GpuMemoryBuffer::Usage usage, | |
| 533 int client_id, | |
| 534 int32 surface_id, | |
| 535 const CreateGpuMemoryBufferCallback& callback) { | |
| 536 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 537 | |
| 538 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); | |
| 539 if (!host) { | |
| 540 callback.Run(gfx::GpuMemoryBufferHandle()); | |
| 541 return; | |
| 542 } | |
| 543 | |
| 544 uint32 request_id = next_create_gpu_memory_buffer_request_id_++; | |
| 545 create_gpu_memory_buffer_requests_[request_id] = callback; | |
| 546 | |
| 547 host->CreateGpuMemoryBuffer( | |
| 548 id, size, format, usage, client_id, surface_id, | |
| 549 base::Bind(&BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated, | |
| 550 base::Unretained(this), request_id)); | |
| 551 } | |
| 552 | |
| 553 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBuffer( | |
| 554 gfx::GpuMemoryBufferId id, | |
| 555 int client_id, | |
| 556 int32 sync_point) { | |
| 557 BrowserThread::PostTask( | |
| 558 BrowserThread::IO, | |
| 559 FROM_HERE, | |
| 560 base::Bind(&BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO, | |
| 561 base::Unretained(this), | |
| 562 id, | |
| 563 client_id, | |
| 564 sync_point)); | |
| 565 } | |
| 566 | |
| 567 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO( | |
| 568 gfx::GpuMemoryBufferId id, | |
| 569 int client_id, | |
| 570 int32 sync_point) { | |
| 571 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 572 | |
| 573 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); | |
| 574 if (!host) | |
| 575 return; | |
| 576 | |
| 577 host->DestroyGpuMemoryBuffer(id, client_id, sync_point); | |
| 578 } | |
| 579 | |
| 580 void BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated( | |
| 581 uint32 request_id, | |
| 582 const gfx::GpuMemoryBufferHandle& handle) { | |
| 583 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 584 | |
| 585 CreateGpuMemoryBufferCallbackMap::iterator iter = | |
| 586 create_gpu_memory_buffer_requests_.find(request_id); | |
| 587 DCHECK(iter != create_gpu_memory_buffer_requests_.end()); | |
| 588 iter->second.Run(handle); | |
| 589 create_gpu_memory_buffer_requests_.erase(iter); | |
| 590 } | |
| 591 | |
| 592 } // namespace content | 411 } // namespace content |
| OLD | NEW |