| 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_host_id_(0) { |
| 325 new BrowserGpuMemoryBufferManager(this, gpu_client_id_)), | |
| 326 gpu_host_id_(0), | |
| 327 next_create_gpu_memory_buffer_request_id_(0) { | |
| 328 } | 230 } |
| 329 | 231 |
| 330 BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() { | 232 BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() { |
| 331 DCHECK(IsMainThread()); | 233 DCHECK(IsMainThread()); |
| 332 if (pending_request_.get()) | 234 if (pending_request_.get()) |
| 333 pending_request_->Cancel(); | 235 pending_request_->Cancel(); |
| 334 for (size_t n = 0; n < established_callbacks_.size(); n++) | 236 for (size_t n = 0; n < established_callbacks_.size(); n++) |
| 335 established_callbacks_[n].Run(); | 237 established_callbacks_[n].Run(); |
| 336 shutdown_event_->Signal(); | 238 shutdown_event_->Signal(); |
| 337 if (gpu_channel_) { | 239 if (gpu_channel_) { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 void BrowserGpuChannelHostFactory::AddFilterOnIO( | 398 void BrowserGpuChannelHostFactory::AddFilterOnIO( |
| 497 int host_id, | 399 int host_id, |
| 498 scoped_refptr<IPC::MessageFilter> filter) { | 400 scoped_refptr<IPC::MessageFilter> filter) { |
| 499 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 401 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 500 | 402 |
| 501 GpuProcessHost* host = GpuProcessHost::FromID(host_id); | 403 GpuProcessHost* host = GpuProcessHost::FromID(host_id); |
| 502 if (host) | 404 if (host) |
| 503 host->AddFilter(filter.get()); | 405 host->AddFilter(filter.get()); |
| 504 } | 406 } |
| 505 | 407 |
| 506 bool BrowserGpuChannelHostFactory::IsGpuMemoryBufferConfigurationSupported( | |
| 507 gfx::GpuMemoryBuffer::Format format, | |
| 508 gfx::GpuMemoryBuffer::Usage usage) { | |
| 509 // Return early if usage is not enabled. | |
| 510 if (!IsGpuMemoryBufferFactoryUsageEnabled(usage)) | |
| 511 return false; | |
| 512 | |
| 513 std::vector<gfx::GpuMemoryBufferType> supported_types; | |
| 514 GpuMemoryBufferFactory::GetSupportedTypes(&supported_types); | |
| 515 DCHECK(!supported_types.empty()); | |
| 516 | |
| 517 // The GPU service will always use the preferred type, if the |format| and | |
| 518 // |usage| allows. | |
| 519 gfx::GpuMemoryBufferType type = supported_types[0]; | |
| 520 | |
| 521 return IsGpuMemoryBufferFactoryConfigurationSupported(format, usage, type); | |
| 522 } | |
| 523 | |
| 524 void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer( | |
| 525 gfx::GpuMemoryBufferId id, | |
| 526 const gfx::Size& size, | |
| 527 gfx::GpuMemoryBuffer::Format format, | |
| 528 gfx::GpuMemoryBuffer::Usage usage, | |
| 529 int client_id, | |
| 530 int32 surface_id, | |
| 531 const CreateGpuMemoryBufferCallback& callback) { | |
| 532 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 533 | |
| 534 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); | |
| 535 if (!host) { | |
| 536 callback.Run(gfx::GpuMemoryBufferHandle()); | |
| 537 return; | |
| 538 } | |
| 539 | |
| 540 uint32 request_id = next_create_gpu_memory_buffer_request_id_++; | |
| 541 create_gpu_memory_buffer_requests_[request_id] = callback; | |
| 542 | |
| 543 host->CreateGpuMemoryBuffer( | |
| 544 id, size, format, usage, client_id, surface_id, | |
| 545 base::Bind(&BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated, | |
| 546 base::Unretained(this), request_id)); | |
| 547 } | |
| 548 | |
| 549 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBuffer( | |
| 550 gfx::GpuMemoryBufferId id, | |
| 551 int client_id, | |
| 552 int32 sync_point) { | |
| 553 BrowserThread::PostTask( | |
| 554 BrowserThread::IO, | |
| 555 FROM_HERE, | |
| 556 base::Bind(&BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO, | |
| 557 base::Unretained(this), | |
| 558 id, | |
| 559 client_id, | |
| 560 sync_point)); | |
| 561 } | |
| 562 | |
| 563 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO( | |
| 564 gfx::GpuMemoryBufferId id, | |
| 565 int client_id, | |
| 566 int32 sync_point) { | |
| 567 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 568 | |
| 569 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); | |
| 570 if (!host) | |
| 571 return; | |
| 572 | |
| 573 host->DestroyGpuMemoryBuffer(id, client_id, sync_point); | |
| 574 } | |
| 575 | |
| 576 void BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated( | |
| 577 uint32 request_id, | |
| 578 const gfx::GpuMemoryBufferHandle& handle) { | |
| 579 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 580 | |
| 581 CreateGpuMemoryBufferCallbackMap::iterator iter = | |
| 582 create_gpu_memory_buffer_requests_.find(request_id); | |
| 583 DCHECK(iter != create_gpu_memory_buffer_requests_.end()); | |
| 584 iter->second.Run(handle); | |
| 585 create_gpu_memory_buffer_requests_.erase(iter); | |
| 586 } | |
| 587 | |
| 588 } // namespace content | 408 } // namespace content |
| OLD | NEW |