| Index: components/viz/host/server_gpu_memory_buffer_manager.cc
|
| diff --git a/components/viz/host/server_gpu_memory_buffer_manager.cc b/components/viz/host/server_gpu_memory_buffer_manager.cc
|
| index 460cbf6747ff53f10f29d4eaed11f0fc6cad7408..ac36c933132868060de381374964e7d67b1ed245 100644
|
| --- a/components/viz/host/server_gpu_memory_buffer_manager.cc
|
| +++ b/components/viz/host/server_gpu_memory_buffer_manager.cc
|
| @@ -5,14 +5,22 @@
|
| #include "components/viz/host/server_gpu_memory_buffer_manager.h"
|
|
|
| #include "base/logging.h"
|
| +#include "base/strings/stringprintf.h"
|
| #include "base/threading/sequenced_task_runner_handle.h"
|
| +#include "base/trace_event/memory_dump_manager.h"
|
| +#include "base/trace_event/process_memory_dump.h"
|
| #include "gpu/ipc/client/gpu_memory_buffer_impl.h"
|
| #include "gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.h"
|
| #include "gpu/ipc/common/gpu_memory_buffer_support.h"
|
| #include "services/ui/gpu/interfaces/gpu_service.mojom.h"
|
| +#include "ui/gfx/buffer_format_util.h"
|
| +#include "ui/gfx/gpu_memory_buffer_tracing.h"
|
|
|
| namespace viz {
|
|
|
| +ServerGpuMemoryBufferManager::BufferInfo::BufferInfo() = default;
|
| +ServerGpuMemoryBufferManager::BufferInfo::~BufferInfo() = default;
|
| +
|
| ServerGpuMemoryBufferManager::ServerGpuMemoryBufferManager(
|
| ui::mojom::GpuService* gpu_service,
|
| int client_id)
|
| @@ -42,6 +50,7 @@ void ServerGpuMemoryBufferManager::AllocateGpuMemoryBuffer(
|
| id, size, format, usage, client_id, surface_handle,
|
| base::Bind(&ServerGpuMemoryBufferManager::OnGpuMemoryBufferAllocated,
|
| weak_factory_.GetWeakPtr(), client_id,
|
| + gfx::BufferSizeForBufferFormat(size, format),
|
| base::Passed(std::move(callback))));
|
| return;
|
| }
|
| @@ -55,6 +64,14 @@ void ServerGpuMemoryBufferManager::AllocateGpuMemoryBuffer(
|
| format)) {
|
| buffer_handle = gpu::GpuMemoryBufferImplSharedMemory::CreateGpuMemoryBuffer(
|
| id, size, format);
|
| + BufferInfo buffer_info;
|
| + DCHECK_EQ(gfx::SHARED_MEMORY_BUFFER, buffer_handle.type);
|
| + buffer_info.type = gfx::SHARED_MEMORY_BUFFER;
|
| + buffer_info.buffer_size_in_bytes =
|
| + gfx::BufferSizeForBufferFormat(size, format);
|
| + buffer_info.shared_memory_guid = buffer_handle.handle.GetGUID();
|
| + allocated_buffers_[client_id].insert(
|
| + std::make_pair(buffer_handle.id, buffer_info));
|
| }
|
|
|
| task_runner_->PostTask(FROM_HERE,
|
| @@ -104,26 +121,92 @@ void ServerGpuMemoryBufferManager::SetDestructionSyncToken(
|
| sync_token);
|
| }
|
|
|
| +bool ServerGpuMemoryBufferManager::OnMemoryDump(
|
| + const base::trace_event::MemoryDumpArgs& args,
|
| + base::trace_event::ProcessMemoryDump* pmd) {
|
| + DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
| + for (const auto& pair : allocated_buffers_) {
|
| + int client_id = pair.first;
|
| + for (const auto& buffer_pair : pair.second) {
|
| + gfx::GpuMemoryBufferId buffer_id = buffer_pair.first;
|
| + const BufferInfo& buffer_info = buffer_pair.second;
|
| + base::trace_event::MemoryAllocatorDump* dump =
|
| + pmd->CreateAllocatorDump(base::StringPrintf(
|
| + "gpumemorybuffer/client_%d/buffer_%d", client_id, buffer_id.id));
|
| + if (!dump)
|
| + return false;
|
| + dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
|
| + base::trace_event::MemoryAllocatorDump::kUnitsBytes,
|
| + buffer_info.buffer_size_in_bytes);
|
| +
|
| + // Create the cross-process ownership edge. If the client creates a
|
| + // corresponding dump for the same buffer, this will avoid to
|
| + // double-count them in tracing. If, instead, no other process will emit a
|
| + // dump with the same guid, the segment will be accounted to the browser.
|
| + uint64_t client_tracing_process_id = ClientIdToTracingId(client_id);
|
| +
|
| + if (buffer_info.type == gfx::SHARED_MEMORY_BUFFER) {
|
| + auto shared_buffer_guid = gfx::GetSharedMemoryGUIDForTracing(
|
| + client_tracing_process_id, buffer_id);
|
| + pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shared_buffer_guid,
|
| + buffer_info.shared_memory_guid,
|
| + 0 /* importance */);
|
| + } else {
|
| + auto shared_buffer_guid = gfx::GetGenericSharedGpuMemoryGUIDForTracing(
|
| + client_tracing_process_id, buffer_id);
|
| + pmd->CreateSharedGlobalAllocatorDump(shared_buffer_guid);
|
| + pmd->AddOwnershipEdge(dump->guid(), shared_buffer_guid);
|
| + }
|
| + }
|
| + }
|
| + return true;
|
| +}
|
| +
|
| void ServerGpuMemoryBufferManager::DestroyGpuMemoryBuffer(
|
| gfx::GpuMemoryBufferId id,
|
| int client_id,
|
| const gpu::SyncToken& sync_token) {
|
| DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
| - if (native_buffers_[client_id].erase(id))
|
| + auto iter = allocated_buffers_[client_id].find(id);
|
| + if (iter == allocated_buffers_[client_id].end())
|
| + return;
|
| + DCHECK_NE(gfx::EMPTY_BUFFER, iter->second.type);
|
| + allocated_buffers_[client_id].erase(id);
|
| + if (iter->second.type != gfx::SHARED_MEMORY_BUFFER)
|
| gpu_service_->DestroyGpuMemoryBuffer(id, client_id, sync_token);
|
| }
|
|
|
| void ServerGpuMemoryBufferManager::DestroyAllGpuMemoryBufferForClient(
|
| int client_id) {
|
| DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
| - for (gfx::GpuMemoryBufferId id : native_buffers_[client_id])
|
| - gpu_service_->DestroyGpuMemoryBuffer(id, client_id, gpu::SyncToken());
|
| - native_buffers_.erase(client_id);
|
| + for (auto pair : allocated_buffers_[client_id]) {
|
| + DCHECK_NE(gfx::EMPTY_BUFFER, pair.second.type);
|
| + if (pair.second.type != gfx::SHARED_MEMORY_BUFFER) {
|
| + gpu_service_->DestroyGpuMemoryBuffer(pair.first, client_id,
|
| + gpu::SyncToken());
|
| + }
|
| + }
|
| + allocated_buffers_.erase(client_id);
|
| pending_buffers_.erase(client_id);
|
| }
|
|
|
| +uint64_t ServerGpuMemoryBufferManager::ClientIdToTracingId(
|
| + int client_id) const {
|
| + if (client_id == client_id_) {
|
| + return base::trace_event::MemoryDumpManager::GetInstance()
|
| + ->GetTracingProcessId();
|
| + }
|
| + // TODO(sad|ssid): Find a better way once crbug.com/661257 is resolved.
|
| + // The hash value is incremented so that the tracing id is never equal to
|
| + // MemoryDumpManager::kInvalidTracingProcessId.
|
| + return static_cast<uint64_t>(base::Hash(
|
| + reinterpret_cast<const char*>(&client_id), sizeof(client_id))) +
|
| + 1;
|
| +}
|
| +
|
| void ServerGpuMemoryBufferManager::OnGpuMemoryBufferAllocated(
|
| int client_id,
|
| + size_t buffer_size_in_bytes,
|
| base::OnceCallback<void(const gfx::GpuMemoryBufferHandle&)> callback,
|
| const gfx::GpuMemoryBufferHandle& handle) {
|
| DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
| @@ -136,8 +219,13 @@ void ServerGpuMemoryBufferManager::OnGpuMemoryBufferAllocated(
|
| std::move(callback).Run(gfx::GpuMemoryBufferHandle());
|
| return;
|
| }
|
| - if (!handle.is_null())
|
| - native_buffers_[client_id].insert(handle.id);
|
| + if (!handle.is_null()) {
|
| + BufferInfo buffer_info;
|
| + buffer_info.type = handle.type;
|
| + buffer_info.buffer_size_in_bytes = buffer_size_in_bytes;
|
| + allocated_buffers_[client_id].insert(
|
| + std::make_pair(handle.id, buffer_info));
|
| + }
|
| std::move(callback).Run(handle);
|
| }
|
|
|
|
|