Chromium Code Reviews| 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" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 for (auto& usage : kGPUReadWriteUsages) { | 123 for (auto& usage : kGPUReadWriteUsages) { |
| 124 if (IsNativeGpuMemoryBufferFactoryConfigurationSupported(format, usage)) | 124 if (IsNativeGpuMemoryBufferFactoryConfigurationSupported(format, usage)) |
| 125 configurations.insert(std::make_pair(format, usage)); | 125 configurations.insert(std::make_pair(format, usage)); |
| 126 } | 126 } |
| 127 } | 127 } |
| 128 } | 128 } |
| 129 | 129 |
| 130 return configurations; | 130 return configurations; |
| 131 } | 131 } |
| 132 | 132 |
| 133 void DestroyGpuMemoryBufferNoOp(const gpu::SyncToken& sync_token) { | |
|
reveman
2016/05/24 22:19:47
nit: no need for NoOp in the name
ccameron
2016/05/24 22:58:04
Done.
| |
| 134 // No additional state needs to be cleaned up. | |
| 135 } | |
| 136 | |
| 133 BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr; | 137 BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr; |
| 134 | 138 |
| 135 } // namespace | 139 } // namespace |
| 136 | 140 |
| 137 struct BrowserGpuMemoryBufferManager::CreateGpuMemoryBufferRequest { | 141 struct BrowserGpuMemoryBufferManager::CreateGpuMemoryBufferRequest { |
| 138 CreateGpuMemoryBufferRequest(const gfx::Size& size, | 142 CreateGpuMemoryBufferRequest(const gfx::Size& size, |
| 139 gfx::BufferFormat format, | 143 gfx::BufferFormat format, |
| 140 gfx::BufferUsage usage, | 144 gfx::BufferUsage usage, |
| 141 int client_id, | 145 int client_id, |
| 142 gpu::SurfaceHandle surface_handle) | 146 gpu::SurfaceHandle surface_handle) |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 591 return; | 595 return; |
| 592 } | 596 } |
| 593 BufferMap& buffers = client_it->second; | 597 BufferMap& buffers = client_it->second; |
| 594 BufferMap::iterator buffer_it = buffers.find(request->gpu_memory_buffer_id); | 598 BufferMap::iterator buffer_it = buffers.find(request->gpu_memory_buffer_id); |
| 595 if (buffer_it == buffers.end()) { | 599 if (buffer_it == buffers.end()) { |
| 596 LOG(ERROR) << "CreateGpuMemoryBufferFromClientId: invalid id."; | 600 LOG(ERROR) << "CreateGpuMemoryBufferFromClientId: invalid id."; |
| 597 request->event.Signal(); | 601 request->event.Signal(); |
| 598 return; | 602 return; |
| 599 } | 603 } |
| 600 | 604 |
| 601 // TODO(ccameron): Implement this. | 605 // Create a copy of the buffer to provide to the caller. |
| 602 NOTIMPLEMENTED(); | 606 if (buffer_it->second.parent_buffer_instance) { |
| 607 request->result = gpu::GpuMemoryBufferImpl::CreateFromHandle( | |
| 608 buffer_it->second.parent_buffer_instance->GetHandle(), | |
| 609 buffer_it->second.size, buffer_it->second.format, | |
| 610 buffer_it->second.usage, base::Bind(DestroyGpuMemoryBufferNoOp)); | |
| 611 } | |
| 612 | |
| 603 request->event.Signal(); | 613 request->event.Signal(); |
| 604 } | 614 } |
| 605 | 615 |
| 606 void BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO( | 616 void BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO( |
| 607 CreateGpuMemoryBufferRequest* request, | 617 CreateGpuMemoryBufferRequest* request, |
| 608 const gfx::GpuMemoryBufferHandle& handle) { | 618 const gfx::GpuMemoryBufferHandle& handle) { |
| 609 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 619 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 610 | 620 |
| 611 // Early out if factory failed to create the buffer. | 621 // Early out if factory failed to create the buffer. |
| 612 if (handle.is_null()) { | 622 if (handle.is_null()) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 629 void BrowserGpuMemoryBufferManager::CreateGpuMemoryBufferOnIO( | 639 void BrowserGpuMemoryBufferManager::CreateGpuMemoryBufferOnIO( |
| 630 const CreateDelegate& create_delegate, | 640 const CreateDelegate& create_delegate, |
| 631 gfx::GpuMemoryBufferId id, | 641 gfx::GpuMemoryBufferId id, |
| 632 const gfx::Size& size, | 642 const gfx::Size& size, |
| 633 gfx::BufferFormat format, | 643 gfx::BufferFormat format, |
| 634 gfx::BufferUsage usage, | 644 gfx::BufferUsage usage, |
| 635 int client_id, | 645 int client_id, |
| 636 bool reused_gpu_process, | 646 bool reused_gpu_process, |
| 637 const CreateCallback& callback) { | 647 const CreateCallback& callback) { |
| 638 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 648 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 649 TRACE_EVENT0("browser", | |
| 650 "BrowserGpuMemoryBufferManager::CreateGpuMemoryBufferOnIO"); | |
| 639 | 651 |
| 640 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); | 652 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); |
| 641 if (!host) { | 653 if (!host) { |
| 642 host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, | 654 host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, |
| 643 CAUSE_FOR_GPU_LAUNCH_GPU_MEMORY_BUFFER_ALLOCATE); | 655 CAUSE_FOR_GPU_LAUNCH_GPU_MEMORY_BUFFER_ALLOCATE); |
| 644 if (!host) { | 656 if (!host) { |
| 645 LOG(ERROR) << "Failed to launch GPU process."; | 657 LOG(ERROR) << "Failed to launch GPU process."; |
| 646 callback.Run(gfx::GpuMemoryBufferHandle()); | 658 callback.Run(gfx::GpuMemoryBufferHandle()); |
| 647 return; | 659 return; |
| 648 } | 660 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 686 | 698 |
| 687 void BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO( | 699 void BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO( |
| 688 const CreateDelegate& create_delegate, | 700 const CreateDelegate& create_delegate, |
| 689 gfx::GpuMemoryBufferId id, | 701 gfx::GpuMemoryBufferId id, |
| 690 int client_id, | 702 int client_id, |
| 691 int gpu_host_id, | 703 int gpu_host_id, |
| 692 bool reused_gpu_process, | 704 bool reused_gpu_process, |
| 693 const CreateCallback& callback, | 705 const CreateCallback& callback, |
| 694 const gfx::GpuMemoryBufferHandle& handle) { | 706 const gfx::GpuMemoryBufferHandle& handle) { |
| 695 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 707 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 708 TRACE_EVENT0("browser", | |
| 709 "BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO"); | |
| 696 | 710 |
| 697 ClientMap::iterator client_it = clients_.find(client_id); | 711 ClientMap::iterator client_it = clients_.find(client_id); |
| 698 | 712 |
| 699 // This can happen if client is removed while the buffer is being allocated. | 713 // This can happen if client is removed while the buffer is being allocated. |
| 700 if (client_it == clients_.end()) { | 714 if (client_it == clients_.end()) { |
| 701 if (!handle.is_null()) { | 715 if (!handle.is_null()) { |
| 702 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id); | 716 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id); |
| 703 if (host) | 717 if (host) |
| 704 host->DestroyGpuMemoryBuffer(handle.id, client_id, gpu::SyncToken()); | 718 host->DestroyGpuMemoryBuffer(handle.id, client_id, gpu::SyncToken()); |
| 705 } | 719 } |
| 706 callback.Run(gfx::GpuMemoryBufferHandle()); | 720 callback.Run(gfx::GpuMemoryBufferHandle()); |
| 707 return; | 721 return; |
| 708 } | 722 } |
| 709 | 723 |
| 710 BufferMap& buffers = client_it->second; | 724 BufferMap& buffers = client_it->second; |
| 711 | 725 |
| 712 BufferMap::iterator buffer_it = buffers.find(id); | 726 BufferMap::iterator buffer_it = buffers.find(id); |
| 713 DCHECK(buffer_it != buffers.end()); | 727 DCHECK(buffer_it != buffers.end()); |
| 714 DCHECK_EQ(buffer_it->second.type, gfx::EMPTY_BUFFER); | 728 DCHECK_EQ(buffer_it->second.type, gfx::EMPTY_BUFFER); |
| 715 | 729 |
| 716 // If the handle isn't valid, that means that the GPU process crashed or is | 730 // If the handle isn't valid, that means that the GPU process crashed or is |
| 717 // misbehaving. | 731 // misbehaving. |
| 718 bool valid_handle = !handle.is_null() && handle.id == id; | 732 bool valid_handle = !handle.is_null() && handle.id == id; |
| 733 | |
| 734 // Open a copy of the buffer in the browser process for future use. | |
| 735 std::unique_ptr<gpu::GpuMemoryBufferImpl> buffer; | |
| 736 if (valid_handle) { | |
| 737 // This is currently only used by IOSurface buffers. | |
| 738 if (handle.type == gfx::IO_SURFACE_BUFFER) { | |
|
reveman
2016/05/24 22:19:47
This should be the correct behavior on all platfor
ccameron
2016/05/24 22:58:04
Changed this to a TODO. This is the only one that
| |
| 739 buffer = gpu::GpuMemoryBufferImpl::CreateFromHandle( | |
| 740 handle, buffer_it->second.size, buffer_it->second.format, | |
| 741 buffer_it->second.usage, base::Bind(DestroyGpuMemoryBufferNoOp)); | |
| 742 if (!buffer) | |
| 743 valid_handle = false; | |
| 744 } | |
| 745 } | |
| 746 | |
| 719 if (!valid_handle) { | 747 if (!valid_handle) { |
| 720 // If we failed after re-using the GPU process, it may have died in the | 748 // If we failed after re-using the GPU process, it may have died in the |
| 721 // mean time. Retry to have a chance to create a fresh GPU process. | 749 // mean time. Retry to have a chance to create a fresh GPU process. |
| 722 if (handle.is_null() && reused_gpu_process) { | 750 if (handle.is_null() && reused_gpu_process) { |
| 723 DVLOG(1) << "Failed to create buffer through existing GPU process. " | 751 DVLOG(1) << "Failed to create buffer through existing GPU process. " |
| 724 "Trying to restart GPU process."; | 752 "Trying to restart GPU process."; |
| 725 // If the GPU process has already been restarted, retry without failure | 753 // If the GPU process has already been restarted, retry without failure |
| 726 // when GPU process host ID already exists. | 754 // when GPU process host ID already exists. |
| 727 if (gpu_host_id != gpu_host_id_) | 755 if (gpu_host_id != gpu_host_id_) |
| 728 reused_gpu_process = false; | 756 reused_gpu_process = false; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 739 buffers.erase(buffer_it); | 767 buffers.erase(buffer_it); |
| 740 callback.Run(gfx::GpuMemoryBufferHandle()); | 768 callback.Run(gfx::GpuMemoryBufferHandle()); |
| 741 } | 769 } |
| 742 return; | 770 return; |
| 743 } | 771 } |
| 744 | 772 |
| 745 // Store the type and host id of this buffer so it can be cleaned up if the | 773 // Store the type and host id of this buffer so it can be cleaned up if the |
| 746 // client is removed. | 774 // client is removed. |
| 747 buffer_it->second.type = handle.type; | 775 buffer_it->second.type = handle.type; |
| 748 buffer_it->second.gpu_host_id = gpu_host_id; | 776 buffer_it->second.gpu_host_id = gpu_host_id; |
| 777 buffer_it->second.parent_buffer_instance = std::move(buffer); | |
| 749 | 778 |
| 750 callback.Run(handle); | 779 callback.Run(handle); |
| 751 } | 780 } |
| 752 | 781 |
| 753 void BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO( | 782 void BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO( |
| 754 gfx::GpuMemoryBufferId id, | 783 gfx::GpuMemoryBufferId id, |
| 755 int client_id, | 784 int client_id, |
| 756 const gpu::SyncToken& sync_token) { | 785 const gpu::SyncToken& sync_token) { |
| 757 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 786 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 758 DCHECK(clients_.find(client_id) != clients_.end()); | 787 DCHECK(clients_.find(client_id) != clients_.end()); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 799 gfx::GpuMemoryBufferType type, | 828 gfx::GpuMemoryBufferType type, |
| 800 gfx::BufferFormat format, | 829 gfx::BufferFormat format, |
| 801 gfx::BufferUsage usage, | 830 gfx::BufferUsage usage, |
| 802 int gpu_host_id) | 831 int gpu_host_id) |
| 803 : size(size), | 832 : size(size), |
| 804 type(type), | 833 type(type), |
| 805 format(format), | 834 format(format), |
| 806 usage(usage), | 835 usage(usage), |
| 807 gpu_host_id(gpu_host_id) {} | 836 gpu_host_id(gpu_host_id) {} |
| 808 | 837 |
| 809 BrowserGpuMemoryBufferManager::BufferInfo::BufferInfo(const BufferInfo& other) = | 838 BrowserGpuMemoryBufferManager::BufferInfo::BufferInfo(BufferInfo&& other) |
| 810 default; | 839 : size(other.size), |
| 840 type(other.type), | |
| 841 format(other.format), | |
| 842 usage(other.usage), | |
| 843 gpu_host_id(other.gpu_host_id), | |
| 844 parent_buffer_instance(std::move(other.parent_buffer_instance)) {} | |
| 811 | 845 |
| 812 BrowserGpuMemoryBufferManager::BufferInfo::~BufferInfo() {} | 846 BrowserGpuMemoryBufferManager::BufferInfo::~BufferInfo() {} |
| 813 | 847 |
| 814 } // namespace content | 848 } // namespace content |
| OLD | NEW |