Home | History | Annotate | Download | only in service
      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
      3 // found in the LICENSE file.
      4 
      5 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
      6 
      7 #include <limits>
      8 
      9 #include "base/logging.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "base/debug/trace_event.h"
     12 #include "base/process/process_handle.h"
     13 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
     14 
     15 using ::base::SharedMemory;
     16 
     17 namespace gpu {
     18 
     19 TransferBufferManagerInterface::~TransferBufferManagerInterface() {
     20 }
     21 
     22 TransferBufferManager::TransferBufferManager()
     23     : shared_memory_bytes_allocated_(0) {
     24 }
     25 
     26 TransferBufferManager::~TransferBufferManager() {
     27   while (!registered_buffers_.empty()) {
     28     BufferMap::iterator it = registered_buffers_.begin();
     29     DCHECK(shared_memory_bytes_allocated_ >= it->second.size);
     30     shared_memory_bytes_allocated_ -= it->second.size;
     31     delete it->second.shared_memory;
     32     registered_buffers_.erase(it);
     33   }
     34   DCHECK(!shared_memory_bytes_allocated_);
     35 }
     36 
     37 bool TransferBufferManager::Initialize() {
     38   return true;
     39 }
     40 
     41 bool TransferBufferManager::RegisterTransferBuffer(
     42     int32 id,
     43     base::SharedMemory* shared_memory,
     44     size_t size) {
     45   if (id <= 0) {
     46     DVLOG(0) << "Cannot register transfer buffer with non-positive ID.";
     47     return false;
     48   }
     49 
     50   // Fail if the ID is in use.
     51   if (registered_buffers_.find(id) != registered_buffers_.end()) {
     52     DVLOG(0) << "Buffer ID already in use.";
     53     return false;
     54   }
     55 
     56   // Duplicate the handle.
     57   base::SharedMemoryHandle duped_shared_memory_handle;
     58   if (!shared_memory->ShareToProcess(base::GetCurrentProcessHandle(),
     59                                      &duped_shared_memory_handle)) {
     60     DVLOG(0) << "Failed to duplicate shared memory handle.";
     61     return false;
     62   }
     63   scoped_ptr<SharedMemory> duped_shared_memory(
     64       new SharedMemory(duped_shared_memory_handle, false));
     65 
     66   // Map the shared memory into this process. This validates the size.
     67   if (!duped_shared_memory->Map(size)) {
     68     DVLOG(0) << "Failed to map shared memory.";
     69     return false;
     70   }
     71 
     72   // If it could be mapped register the shared memory with the ID.
     73   Buffer buffer;
     74   buffer.ptr = duped_shared_memory->memory();
     75   buffer.size = size;
     76   buffer.shared_memory = duped_shared_memory.release();
     77 
     78   shared_memory_bytes_allocated_ += size;
     79   TRACE_COUNTER_ID1(
     80       "gpu", "GpuTransferBufferMemory", this, shared_memory_bytes_allocated_);
     81 
     82   registered_buffers_[id] = buffer;
     83 
     84   return true;
     85 }
     86 
     87 void TransferBufferManager::DestroyTransferBuffer(int32 id) {
     88   BufferMap::iterator it = registered_buffers_.find(id);
     89   if (it == registered_buffers_.end()) {
     90     DVLOG(0) << "Transfer buffer ID was not registered.";
     91     return;
     92   }
     93 
     94   DCHECK(shared_memory_bytes_allocated_ >= it->second.size);
     95   shared_memory_bytes_allocated_ -= it->second.size;
     96   TRACE_COUNTER_ID1(
     97       "gpu", "GpuTransferBufferMemory", this, shared_memory_bytes_allocated_);
     98 
     99   delete it->second.shared_memory;
    100   registered_buffers_.erase(it);
    101 }
    102 
    103 Buffer TransferBufferManager::GetTransferBuffer(int32 id) {
    104   if (id == 0)
    105     return Buffer();
    106 
    107   BufferMap::iterator it = registered_buffers_.find(id);
    108   if (it == registered_buffers_.end())
    109     return Buffer();
    110 
    111   return it->second;
    112 }
    113 
    114 }  // namespace gpu
    115 
    116