OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_memory_buffer_manager.h" | 5 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
12 #include "base/synchronization/waitable_event.h" | 12 #include "base/synchronization/waitable_event.h" |
13 #include "base/threading/thread_restrictions.h" | 13 #include "base/threading/thread_restrictions.h" |
14 #include "base/trace_event/process_memory_dump.h" | 14 #include "base/trace_event/process_memory_dump.h" |
15 #include "base/trace_event/trace_event.h" | 15 #include "base/trace_event/trace_event.h" |
16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
17 #include "content/browser/gpu/gpu_process_host.h" | 17 #include "content/browser/gpu/gpu_process_host.h" |
18 #include "content/common/child_process_host_impl.h" | 18 #include "content/common/child_process_host_impl.h" |
19 #include "content/common/generic_shared_memory_id_generator.h" | 19 #include "content/common/generic_shared_memory_id_generator.h" |
20 #include "content/common/gpu/client/gpu_memory_buffer_impl.h" | |
21 #include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h" | |
22 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
23 #include "content/public/common/content_switches.h" | 21 #include "content/public/common/content_switches.h" |
24 #include "gpu/GLES2/gl2extchromium.h" | 22 #include "gpu/GLES2/gl2extchromium.h" |
| 23 #include "gpu/ipc/client/gpu_memory_buffer_impl.h" |
| 24 #include "gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.h" |
25 #include "gpu/ipc/common/gpu_memory_buffer_support.h" | 25 #include "gpu/ipc/common/gpu_memory_buffer_support.h" |
26 #include "ui/gfx/buffer_format_util.h" | 26 #include "ui/gfx/buffer_format_util.h" |
27 #include "ui/gl/gl_switches.h" | 27 #include "ui/gl/gl_switches.h" |
28 | 28 |
29 namespace content { | 29 namespace content { |
30 namespace { | 30 namespace { |
31 | 31 |
32 void HostCreateGpuMemoryBuffer( | 32 void HostCreateGpuMemoryBuffer( |
33 int surface_id, | 33 int surface_id, |
34 GpuProcessHost* host, | 34 GpuProcessHost* host, |
(...skipping 15 matching lines...) Expand all Loading... |
50 gfx::BufferFormat format, | 50 gfx::BufferFormat format, |
51 gfx::BufferUsage usage, | 51 gfx::BufferUsage usage, |
52 int client_id, | 52 int client_id, |
53 const BrowserGpuMemoryBufferManager::CreateCallback& callback) { | 53 const BrowserGpuMemoryBufferManager::CreateCallback& callback) { |
54 host->CreateGpuMemoryBufferFromHandle(handle, id, size, format, client_id, | 54 host->CreateGpuMemoryBufferFromHandle(handle, id, size, format, client_id, |
55 callback); | 55 callback); |
56 } | 56 } |
57 | 57 |
58 void GpuMemoryBufferDeleted( | 58 void GpuMemoryBufferDeleted( |
59 scoped_refptr<base::SingleThreadTaskRunner> destruction_task_runner, | 59 scoped_refptr<base::SingleThreadTaskRunner> destruction_task_runner, |
60 const GpuMemoryBufferImpl::DestructionCallback& destruction_callback, | 60 const gpu::GpuMemoryBufferImpl::DestructionCallback& destruction_callback, |
61 const gpu::SyncToken& sync_token) { | 61 const gpu::SyncToken& sync_token) { |
62 destruction_task_runner->PostTask( | 62 destruction_task_runner->PostTask( |
63 FROM_HERE, base::Bind(destruction_callback, sync_token)); | 63 FROM_HERE, base::Bind(destruction_callback, sync_token)); |
64 } | 64 } |
65 | 65 |
66 bool IsNativeGpuMemoryBufferFactoryConfigurationSupported( | 66 bool IsNativeGpuMemoryBufferFactoryConfigurationSupported( |
67 gfx::BufferFormat format, | 67 gfx::BufferFormat format, |
68 gfx::BufferUsage usage) { | 68 gfx::BufferUsage usage) { |
69 switch (gpu::GetNativeGpuMemoryBufferType()) { | 69 switch (gpu::GetNativeGpuMemoryBufferType()) { |
70 case gfx::SHARED_MEMORY_BUFFER: | 70 case gfx::SHARED_MEMORY_BUFFER: |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 | 290 |
291 // Use service side allocation for native configurations. | 291 // Use service side allocation for native configurations. |
292 if (IsNativeGpuMemoryBufferConfiguration(format, usage)) { | 292 if (IsNativeGpuMemoryBufferConfiguration(format, usage)) { |
293 CreateGpuMemoryBufferOnIO(base::Bind(&HostCreateGpuMemoryBuffer, 0), id, | 293 CreateGpuMemoryBufferOnIO(base::Bind(&HostCreateGpuMemoryBuffer, 0), id, |
294 size, format, usage, child_client_id, false, | 294 size, format, usage, child_client_id, false, |
295 callback); | 295 callback); |
296 return; | 296 return; |
297 } | 297 } |
298 | 298 |
299 // Early out if we cannot fallback to shared memory buffer. | 299 // Early out if we cannot fallback to shared memory buffer. |
300 if (!GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage) || | 300 if (!gpu::GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage) || |
301 !GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, format)) { | 301 !gpu::GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, |
| 302 format)) { |
302 callback.Run(gfx::GpuMemoryBufferHandle()); | 303 callback.Run(gfx::GpuMemoryBufferHandle()); |
303 return; | 304 return; |
304 } | 305 } |
305 | 306 |
306 BufferMap& buffers = clients_[child_client_id]; | 307 BufferMap& buffers = clients_[child_client_id]; |
307 | 308 |
308 // Allocate shared memory buffer as fallback. | 309 // Allocate shared memory buffer as fallback. |
309 auto insert_result = buffers.insert(std::make_pair( | 310 auto insert_result = buffers.insert(std::make_pair( |
310 id, BufferInfo(size, gfx::SHARED_MEMORY_BUFFER, format, usage, 0))); | 311 id, BufferInfo(size, gfx::SHARED_MEMORY_BUFFER, format, usage, 0))); |
311 if (!insert_result.second) { | 312 if (!insert_result.second) { |
312 DLOG(ERROR) << "Child process attempted to allocate a GpuMemoryBuffer with " | 313 DLOG(ERROR) << "Child process attempted to allocate a GpuMemoryBuffer with " |
313 "an existing ID."; | 314 "an existing ID."; |
314 callback.Run(gfx::GpuMemoryBufferHandle()); | 315 callback.Run(gfx::GpuMemoryBufferHandle()); |
315 return; | 316 return; |
316 } | 317 } |
317 | 318 |
318 callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess( | 319 callback.Run(gpu::GpuMemoryBufferImplSharedMemory::AllocateForChildProcess( |
319 id, size, format, child_process_handle)); | 320 id, size, format, child_process_handle)); |
320 } | 321 } |
321 | 322 |
322 gfx::GpuMemoryBuffer* | 323 gfx::GpuMemoryBuffer* |
323 BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer( | 324 BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer( |
324 ClientBuffer buffer) { | 325 ClientBuffer buffer) { |
325 return GpuMemoryBufferImpl::FromClientBuffer(buffer); | 326 return gpu::GpuMemoryBufferImpl::FromClientBuffer(buffer); |
326 } | 327 } |
327 | 328 |
328 void BrowserGpuMemoryBufferManager::SetDestructionSyncToken( | 329 void BrowserGpuMemoryBufferManager::SetDestructionSyncToken( |
329 gfx::GpuMemoryBuffer* buffer, | 330 gfx::GpuMemoryBuffer* buffer, |
330 const gpu::SyncToken& sync_token) { | 331 const gpu::SyncToken& sync_token) { |
331 static_cast<GpuMemoryBufferImpl*>(buffer) | 332 static_cast<gpu::GpuMemoryBufferImpl*>(buffer)->set_destruction_sync_token( |
332 ->set_destruction_sync_token(sync_token); | 333 sync_token); |
333 } | 334 } |
334 | 335 |
335 bool BrowserGpuMemoryBufferManager::OnMemoryDump( | 336 bool BrowserGpuMemoryBufferManager::OnMemoryDump( |
336 const base::trace_event::MemoryDumpArgs& args, | 337 const base::trace_event::MemoryDumpArgs& args, |
337 base::trace_event::ProcessMemoryDump* pmd) { | 338 base::trace_event::ProcessMemoryDump* pmd) { |
338 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 339 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
339 | 340 |
340 for (const auto& client : clients_) { | 341 for (const auto& client : clients_) { |
341 int client_id = client.first; | 342 int client_id = client.first; |
342 | 343 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 CreateGpuMemoryBufferOnIO( | 456 CreateGpuMemoryBufferOnIO( |
456 base::Bind(&HostCreateGpuMemoryBuffer, request->surface_id), new_id, | 457 base::Bind(&HostCreateGpuMemoryBuffer, request->surface_id), new_id, |
457 request->size, request->format, request->usage, request->client_id, | 458 request->size, request->format, request->usage, request->client_id, |
458 false, | 459 false, |
459 base::Bind( | 460 base::Bind( |
460 &BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO, | 461 &BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO, |
461 base::Unretained(this), base::Unretained(request))); | 462 base::Unretained(this), base::Unretained(request))); |
462 return; | 463 return; |
463 } | 464 } |
464 | 465 |
465 DCHECK(GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage)) | 466 DCHECK(gpu::GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage)) |
466 << static_cast<int>(request->usage); | 467 << static_cast<int>(request->usage); |
467 | 468 |
468 BufferMap& buffers = clients_[request->client_id]; | 469 BufferMap& buffers = clients_[request->client_id]; |
469 | 470 |
470 // Allocate shared memory buffer as fallback. | 471 // Allocate shared memory buffer as fallback. |
471 auto insert_result = buffers.insert(std::make_pair( | 472 auto insert_result = buffers.insert(std::make_pair( |
472 new_id, BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER, | 473 new_id, BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER, |
473 request->format, request->usage, 0))); | 474 request->format, request->usage, 0))); |
474 DCHECK(insert_result.second); | 475 DCHECK(insert_result.second); |
475 | 476 |
476 // Note: Unretained is safe as IO thread is stopped before manager is | 477 // Note: Unretained is safe as IO thread is stopped before manager is |
477 // destroyed. | 478 // destroyed. |
478 request->result = GpuMemoryBufferImplSharedMemory::Create( | 479 request->result = gpu::GpuMemoryBufferImplSharedMemory::Create( |
479 new_id, request->size, request->format, | 480 new_id, request->size, request->format, |
480 base::Bind( | 481 base::Bind( |
481 &GpuMemoryBufferDeleted, | 482 &GpuMemoryBufferDeleted, |
482 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), | 483 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), |
483 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO, | 484 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO, |
484 base::Unretained(this), new_id, request->client_id))); | 485 base::Unretained(this), new_id, request->client_id))); |
485 request->event.Signal(); | 486 request->event.Signal(); |
486 } | 487 } |
487 | 488 |
488 void BrowserGpuMemoryBufferManager::HandleCreateGpuMemoryBufferFromHandleOnIO( | 489 void BrowserGpuMemoryBufferManager::HandleCreateGpuMemoryBufferFromHandleOnIO( |
(...skipping 16 matching lines...) Expand all Loading... |
505 CreateGpuMemoryBufferOnIO( | 506 CreateGpuMemoryBufferOnIO( |
506 base::Bind(&HostCreateGpuMemoryBufferFromHandle, request->handle), | 507 base::Bind(&HostCreateGpuMemoryBufferFromHandle, request->handle), |
507 new_id, request->size, request->format, request->usage, | 508 new_id, request->size, request->format, request->usage, |
508 request->client_id, false, | 509 request->client_id, false, |
509 base::Bind( | 510 base::Bind( |
510 &BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO, | 511 &BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO, |
511 base::Unretained(this), base::Unretained(request))); | 512 base::Unretained(this), base::Unretained(request))); |
512 return; | 513 return; |
513 } | 514 } |
514 | 515 |
515 DCHECK(GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage)) | 516 DCHECK(gpu::GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage)) |
516 << static_cast<int>(request->usage); | 517 << static_cast<int>(request->usage); |
517 | 518 |
518 BufferMap& buffers = clients_[request->client_id]; | 519 BufferMap& buffers = clients_[request->client_id]; |
519 | 520 |
520 // Allocate shared memory buffer. | 521 // Allocate shared memory buffer. |
521 auto insert_result = buffers.insert(std::make_pair( | 522 auto insert_result = buffers.insert(std::make_pair( |
522 new_id, BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER, | 523 new_id, BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER, |
523 request->format, request->usage, 0))); | 524 request->format, request->usage, 0))); |
524 DCHECK(insert_result.second); | 525 DCHECK(insert_result.second); |
525 | 526 |
526 gfx::GpuMemoryBufferHandle handle; | 527 gfx::GpuMemoryBufferHandle handle; |
527 handle.id = new_id; | 528 handle.id = new_id; |
528 handle.handle = request->handle.handle; | 529 handle.handle = request->handle.handle; |
529 handle.offset = request->handle.offset; | 530 handle.offset = request->handle.offset; |
530 handle.stride = request->handle.stride; | 531 handle.stride = request->handle.stride; |
531 | 532 |
532 // Note: Unretained is safe as IO thread is stopped before manager is | 533 // Note: Unretained is safe as IO thread is stopped before manager is |
533 // destroyed. | 534 // destroyed. |
534 request->result = GpuMemoryBufferImplSharedMemory::CreateFromHandle( | 535 request->result = gpu::GpuMemoryBufferImplSharedMemory::CreateFromHandle( |
535 handle, request->size, request->format, request->usage, | 536 handle, request->size, request->format, request->usage, |
536 base::Bind( | 537 base::Bind( |
537 &GpuMemoryBufferDeleted, | 538 &GpuMemoryBufferDeleted, |
538 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), | 539 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), |
539 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO, | 540 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO, |
540 base::Unretained(this), new_id, request->client_id))); | 541 base::Unretained(this), new_id, request->client_id))); |
541 request->event.Signal(); | 542 request->event.Signal(); |
542 } | 543 } |
543 | 544 |
544 void BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO( | 545 void BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO( |
545 CreateGpuMemoryBufferRequest* request, | 546 CreateGpuMemoryBufferRequest* request, |
546 const gfx::GpuMemoryBufferHandle& handle) { | 547 const gfx::GpuMemoryBufferHandle& handle) { |
547 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 548 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
548 | 549 |
549 // Early out if factory failed to create the buffer. | 550 // Early out if factory failed to create the buffer. |
550 if (handle.is_null()) { | 551 if (handle.is_null()) { |
551 request->event.Signal(); | 552 request->event.Signal(); |
552 return; | 553 return; |
553 } | 554 } |
554 | 555 |
555 // Note: Unretained is safe as IO thread is stopped before manager is | 556 // Note: Unretained is safe as IO thread is stopped before manager is |
556 // destroyed. | 557 // destroyed. |
557 request->result = GpuMemoryBufferImpl::CreateFromHandle( | 558 request->result = gpu::GpuMemoryBufferImpl::CreateFromHandle( |
558 handle, request->size, request->format, request->usage, | 559 handle, request->size, request->format, request->usage, |
559 base::Bind( | 560 base::Bind( |
560 &GpuMemoryBufferDeleted, | 561 &GpuMemoryBufferDeleted, |
561 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), | 562 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), |
562 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO, | 563 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO, |
563 base::Unretained(this), handle.id, request->client_id))); | 564 base::Unretained(this), handle.id, request->client_id))); |
564 request->event.Signal(); | 565 request->event.Signal(); |
565 } | 566 } |
566 | 567 |
567 void BrowserGpuMemoryBufferManager::CreateGpuMemoryBufferOnIO( | 568 void BrowserGpuMemoryBufferManager::CreateGpuMemoryBufferOnIO( |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 return gpu_client_tracing_id_; | 725 return gpu_client_tracing_id_; |
725 } | 726 } |
726 | 727 |
727 // In normal cases, |client_id| is a child process id, so we can perform | 728 // In normal cases, |client_id| is a child process id, so we can perform |
728 // the standard conversion. | 729 // the standard conversion. |
729 return ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId( | 730 return ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId( |
730 client_id); | 731 client_id); |
731 } | 732 } |
732 | 733 |
733 } // namespace content | 734 } // namespace content |
OLD | NEW |