summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-13 03:33:59 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-13 03:33:59 +0000
commit9cef770978192902cc3d75979f3b2b3eb6d827ee (patch)
treeaf916cb3deb9b3499d399f5c77d78543197c12dd /gpu
parentd65a27f1844fb3790a94bd44260a705995901e3d (diff)
downloadchromium_src-9cef770978192902cc3d75979f3b2b3eb6d827ee.zip
chromium_src-9cef770978192902cc3d75979f3b2b3eb6d827ee.tar.gz
chromium_src-9cef770978192902cc3d75979f3b2b3eb6d827ee.tar.bz2
Made the registration and deletion of transfer buffers async.
Added an IPC to request multiple transfer buffer IDs up front. Every renderer command buffer proxy gets some IPCs immediately after initialization. Removed request_id arg from CreateTransferBuffer. It wasn't being used. Review URL: https://chromiumcodereview.appspot.com/11308296 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@172805 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/client/client_test_helper.cc19
-rw-r--r--gpu/command_buffer/client/client_test_helper.h5
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper.cc9
-rw-r--r--gpu/command_buffer/client/fenced_allocator_test.cc2
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest.cc6
-rw-r--r--gpu/command_buffer/client/mapped_memory.cc7
-rw-r--r--gpu/command_buffer/client/transfer_buffer.cc4
-rw-r--r--gpu/command_buffer/client/transfer_buffer_unittest.cc15
-rw-r--r--gpu/command_buffer/common/command_buffer.h28
-rw-r--r--gpu/command_buffer/common/command_buffer_mock.h9
-rw-r--r--gpu/command_buffer/service/command_buffer_service.cc41
-rw-r--r--gpu/command_buffer/service/command_buffer_service.h14
-rw-r--r--gpu/command_buffer/service/command_buffer_service_unittest.cc6
-rw-r--r--gpu/command_buffer/service/transfer_buffer_manager.cc126
-rw-r--r--gpu/command_buffer/service/transfer_buffer_manager.h25
-rw-r--r--gpu/command_buffer/service/transfer_buffer_manager_unittest.cc102
16 files changed, 192 insertions, 226 deletions
diff --git a/gpu/command_buffer/client/client_test_helper.cc b/gpu/command_buffer/client/client_test_helper.cc
index d9942ef..92af99d 100644
--- a/gpu/command_buffer/client/client_test_helper.cc
+++ b/gpu/command_buffer/client/client_test_helper.cc
@@ -60,16 +60,15 @@ int32 MockCommandBufferBase::GetNextFreeTransferBufferId() {
return -1;
}
-int32 MockCommandBufferBase::CreateTransferBuffer(
- size_t size, int32 id_request) {
- int32 id = GetNextFreeTransferBufferId();
- if (id >= 0) {
- int32 ndx = id - kTransferBufferBaseId;
+Buffer MockCommandBufferBase::CreateTransferBuffer(size_t size, int32* id) {
+ *id = GetNextFreeTransferBufferId();
+ if (*id >= 0) {
+ int32 ndx = *id - kTransferBufferBaseId;
transfer_buffers_[ndx].reset(new int8[size]);
transfer_buffer_buffers_[ndx].ptr = transfer_buffers_[ndx].get();
transfer_buffer_buffers_[ndx].size = size;
}
- return id;
+ return GetTransferBuffer(*id);
}
void MockCommandBufferBase::DestroyTransferBufferHelper(int32 id) {
@@ -86,14 +85,6 @@ Buffer MockCommandBufferBase::GetTransferBuffer(int32 id) {
return transfer_buffer_buffers_[id - kTransferBufferBaseId];
}
-int32 MockCommandBufferBase::RegisterTransferBuffer(
- base::SharedMemory* shared_memory,
- size_t size,
- int32 id_request) {
- GPU_NOTREACHED();
- return -1;
-}
-
void MockCommandBufferBase::FlushHelper(int32 put_offset) {
state_.put_offset = put_offset;
}
diff --git a/gpu/command_buffer/client/client_test_helper.h b/gpu/command_buffer/client/client_test_helper.h
index 25d1014..3302b47 100644
--- a/gpu/command_buffer/client/client_test_helper.h
+++ b/gpu/command_buffer/client/client_test_helper.h
@@ -32,11 +32,8 @@ class MockCommandBufferBase : public CommandBuffer {
virtual State FlushSync(int32 put_offset, int32 last_known_get) OVERRIDE;
virtual void SetGetBuffer(int transfer_buffer_id) OVERRIDE;
virtual void SetGetOffset(int32 get_offset) OVERRIDE;
- virtual int32 CreateTransferBuffer(size_t size, int32 id_request) OVERRIDE;
+ virtual Buffer CreateTransferBuffer(size_t size, int32* id) OVERRIDE;
virtual Buffer GetTransferBuffer(int32 id) OVERRIDE;
- virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory,
- size_t size,
- int32 id_request) OVERRIDE;
virtual void SetToken(int32 token) OVERRIDE;
virtual void SetParseError(error::Error error) OVERRIDE;
virtual void SetContextLostReason(error::ContextLostReason reason) OVERRIDE;
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc
index 54df89e..4fb3b5e 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper.cc
@@ -52,18 +52,13 @@ bool CommandBufferHelper::AllocateRingBuffer() {
return true;
}
- int32 id = command_buffer_->CreateTransferBuffer(ring_buffer_size_, -1);
+ int32 id = -1;
+ ring_buffer_ = command_buffer_->CreateTransferBuffer(ring_buffer_size_, &id);
if (id < 0) {
ClearUsable();
return false;
}
- ring_buffer_ = command_buffer_->GetTransferBuffer(id);
- if (!ring_buffer_.ptr) {
- ClearUsable();
- return false;
- }
-
ring_buffer_id_ = id;
command_buffer_->SetGetBuffer(id);
diff --git a/gpu/command_buffer/client/fenced_allocator_test.cc b/gpu/command_buffer/client/fenced_allocator_test.cc
index 44fb851..2c6cdc6 100644
--- a/gpu/command_buffer/client/fenced_allocator_test.cc
+++ b/gpu/command_buffer/client/fenced_allocator_test.cc
@@ -52,7 +52,7 @@ class BaseFencedAllocatorTest : public testing::Test {
}
command_buffer_.reset(
new CommandBufferService(transfer_buffer_manager_.get()));
- command_buffer_->Initialize();
+ EXPECT_TRUE(command_buffer_->Initialize());
gpu_scheduler_.reset(new GpuScheduler(
command_buffer_.get(), api_mock_.get(), NULL));
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index 581981e..6176525 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -103,10 +103,10 @@ class MockTransferBuffer : public TransferBufferInterface {
// we need to know their address before GLES2Implementation::Initialize
// is called.
for (int ii = 0; ii < kNumBuffers; ++ii) {
- buffer_ids_[ii] = command_buffer_->CreateTransferBuffer(
- size_ + ii * alignment_, -1);
+ buffers_[ii] = command_buffer_->CreateTransferBuffer(
+ size_ + ii * alignment_,
+ &buffer_ids_[ii]);
EXPECT_NE(-1, buffer_ids_[ii]);
- buffers_[ii] = command_buffer_->GetTransferBuffer(buffer_ids_[ii]);
}
}
diff --git a/gpu/command_buffer/client/mapped_memory.cc b/gpu/command_buffer/client/mapped_memory.cc
index c8d400e..5278fc8 100644
--- a/gpu/command_buffer/client/mapped_memory.cc
+++ b/gpu/command_buffer/client/mapped_memory.cc
@@ -56,11 +56,10 @@ void* MappedMemoryManager::Alloc(
unsigned int chunk_size =
((size + chunk_size_multiple_ - 1) / chunk_size_multiple_) *
chunk_size_multiple_;
- int32 id = cmd_buf->CreateTransferBuffer(chunk_size, -1);
- if (id == -1) {
+ int32 id = -1;
+ gpu::Buffer shm = cmd_buf->CreateTransferBuffer(chunk_size, &id);
+ if (id < 0)
return NULL;
- }
- gpu::Buffer shm = cmd_buf->GetTransferBuffer(id);
MemoryChunk* mc = new MemoryChunk(id, shm, helper_);
chunks_.push_back(mc);
void* mem = mc->Alloc(size);
diff --git a/gpu/command_buffer/client/transfer_buffer.cc b/gpu/command_buffer/client/transfer_buffer.cc
index 7e0b25f..7492159 100644
--- a/gpu/command_buffer/client/transfer_buffer.cc
+++ b/gpu/command_buffer/client/transfer_buffer.cc
@@ -81,9 +81,9 @@ void TransferBuffer::FreePendingToken(void* p, unsigned int token) {
void TransferBuffer::AllocateRingBuffer(unsigned int size) {
for (;size >= min_buffer_size_; size /= 2) {
- int32 id = helper_->command_buffer()->CreateTransferBuffer(size, -1);
+ int32 id = -1;
+ buffer_ = helper_->command_buffer()->CreateTransferBuffer(size, &id);
if (id != -1) {
- buffer_ = helper_->command_buffer()->GetTransferBuffer(id);
ring_buffer_.reset(new AlignedRingBuffer(
alignment_,
id,
diff --git a/gpu/command_buffer/client/transfer_buffer_unittest.cc b/gpu/command_buffer/client/transfer_buffer_unittest.cc
index 469483b..f40de23 100644
--- a/gpu/command_buffer/client/transfer_buffer_unittest.cc
+++ b/gpu/command_buffer/client/transfer_buffer_unittest.cc
@@ -16,6 +16,7 @@
using ::testing::_;
using ::testing::Invoke;
using ::testing::Return;
+using ::testing::SetArgPointee;
using ::testing::StrictMock;
namespace gpu {
@@ -211,10 +212,10 @@ class MockClientCommandBufferCanFail : public MockClientCommandBufferMockFlush {
virtual ~MockClientCommandBufferCanFail() {
}
- MOCK_METHOD2(CreateTransferBuffer, int32(size_t size, int32 id_request));
+ MOCK_METHOD2(CreateTransferBuffer, Buffer(size_t size, int32* id));
- int32 RealCreateTransferBuffer(size_t size, int32 id_request) {
- return MockCommandBufferBase::CreateTransferBuffer(size, id_request);
+ Buffer RealCreateTransferBuffer(size_t size, int32* id) {
+ return MockCommandBufferBase::CreateTransferBuffer(size, id);
}
};
@@ -372,7 +373,7 @@ TEST_F(TransferBufferExpandContractTest, Contract) {
// Try to allocate again, fail first request
EXPECT_CALL(*command_buffer(),
CreateTransferBuffer(kStartTransferBufferSize, _))
- .WillOnce(Return(-1))
+ .WillOnce(DoAll(SetArgPointee<1>(-1), Return(Buffer())))
.RetiresOnSaturation();
EXPECT_CALL(*command_buffer(),
CreateTransferBuffer(kMinTransferBufferSize, _))
@@ -424,9 +425,9 @@ TEST_F(TransferBufferExpandContractTest, OutOfMemory) {
// Try to allocate again, fail both requests.
EXPECT_CALL(*command_buffer(), CreateTransferBuffer(_, _))
- .WillOnce(Return(-1))
- .WillOnce(Return(-1))
- .WillOnce(Return(-1))
+ .WillOnce(DoAll(SetArgPointee<1>(-1), Return(Buffer())))
+ .WillOnce(DoAll(SetArgPointee<1>(-1), Return(Buffer())))
+ .WillOnce(DoAll(SetArgPointee<1>(-1), Return(Buffer())))
.RetiresOnSaturation();
const size_t kSize1 = 512 - kStartingOffset;
diff --git a/gpu/command_buffer/common/command_buffer.h b/gpu/command_buffer/common/command_buffer.h
index 6b19ea2..e100792 100644
--- a/gpu/command_buffer/common/command_buffer.h
+++ b/gpu/command_buffer/common/command_buffer.h
@@ -101,28 +101,16 @@ class GPU_EXPORT CommandBuffer {
// Sets the current get offset. This can be called from any thread.
virtual void SetGetOffset(int32 get_offset) = 0;
- // Create a transfer buffer and return a handle that uniquely
- // identifies it or -1 on error. id_request lets the caller request a
- // specific id for the transfer buffer, or -1 if the caller does not care.
- // If the requested id can not be fulfilled, a different id will be returned.
- // id_request must be either -1 or between 0 and 100.
- virtual int32 CreateTransferBuffer(size_t size, int32 id_request) = 0;
-
- // Register an existing shared memory object and get an ID that can be used
- // to identify it in the command buffer. Callee dups the handle until
- // DestroyTransferBuffer is called. id_request lets the caller request a
- // specific id for the transfer buffer, or -1 if the caller does not care.
- // If the requested id can not be fulfilled, a different id will be returned.
- // id_request must be either -1 or between 0 and 100.
- virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory,
- size_t size,
- int32 id_request) = 0;
-
- // Destroy a transfer buffer and recycle the handle.
+ // Create a transfer buffer of the given size. Returns its ID or -1 on
+ // error.
+ virtual Buffer CreateTransferBuffer(size_t size, int32* id) = 0;
+
+ // Destroy a transfer buffer. The ID must be positive.
virtual void DestroyTransferBuffer(int32 id) = 0;
- // Get the transfer buffer associated with a handle.
- virtual Buffer GetTransferBuffer(int32 handle) = 0;
+ // Get the transfer buffer associated with an ID. Returns a null buffer for
+ // ID 0.
+ virtual Buffer GetTransferBuffer(int32 id) = 0;
// Allows the reader to update the current token value.
virtual void SetToken(int32 token) = 0;
diff --git a/gpu/command_buffer/common/command_buffer_mock.h b/gpu/command_buffer/common/command_buffer_mock.h
index 0379340..b2ee11f 100644
--- a/gpu/command_buffer/common/command_buffer_mock.h
+++ b/gpu/command_buffer/common/command_buffer_mock.h
@@ -28,12 +28,9 @@ class MockCommandBuffer : public CommandBuffer {
MOCK_METHOD2(FlushSync, State(int32 put_offset, int32 last_known_get));
MOCK_METHOD1(SetGetBuffer, void(int32 transfer_buffer_id));
MOCK_METHOD1(SetGetOffset, void(int32 get_offset));
- MOCK_METHOD2(CreateTransferBuffer, int32(size_t size, int32 id_request));
- MOCK_METHOD1(DestroyTransferBuffer, void(int32 handle));
- MOCK_METHOD1(GetTransferBuffer, Buffer(int32 handle));
- MOCK_METHOD3(RegisterTransferBuffer, int32(base::SharedMemory* shared_memory,
- size_t size,
- int32 id_request));
+ MOCK_METHOD2(CreateTransferBuffer, Buffer(size_t size, int32* id));
+ MOCK_METHOD1(DestroyTransferBuffer, void(int32 id));
+ MOCK_METHOD1(GetTransferBuffer, Buffer(int32 id));
MOCK_METHOD1(SetToken, void(int32 token));
MOCK_METHOD1(SetParseError, void(error::Error error));
MOCK_METHOD1(SetContextLostReason,
diff --git a/gpu/command_buffer/service/command_buffer_service.cc b/gpu/command_buffer/service/command_buffer_service.cc
index 8b00595..391f335 100644
--- a/gpu/command_buffer/service/command_buffer_service.cc
+++ b/gpu/command_buffer/service/command_buffer_service.cc
@@ -116,20 +116,26 @@ void CommandBufferService::SetGetOffset(int32 get_offset) {
get_offset_ = get_offset;
}
-int32 CommandBufferService::CreateTransferBuffer(size_t size,
- int32 id_request) {
- return transfer_buffer_manager_->CreateTransferBuffer(size, id_request);
-}
+Buffer CommandBufferService::CreateTransferBuffer(size_t size,
+ int32* id) {
+ *id = -1;
+
+ SharedMemory buffer;
+ if (!buffer.CreateAnonymous(size))
+ return Buffer();
+
+ static int32 next_id = 1;
+ *id = next_id++;
-int32 CommandBufferService::RegisterTransferBuffer(
- base::SharedMemory* shared_memory, size_t size, int32 id_request) {
- return transfer_buffer_manager_->RegisterTransferBuffer(
- shared_memory, size, id_request);
+ if (!RegisterTransferBuffer(*id, &buffer, size))
+ return Buffer();
+
+ return GetTransferBuffer(*id);
}
-void CommandBufferService::DestroyTransferBuffer(int32 handle) {
- transfer_buffer_manager_->DestroyTransferBuffer(handle);
- if (handle == ring_buffer_id_) {
+void CommandBufferService::DestroyTransferBuffer(int32 id) {
+ transfer_buffer_manager_->DestroyTransferBuffer(id);
+ if (id == ring_buffer_id_) {
ring_buffer_id_ = -1;
ring_buffer_ = Buffer();
num_entries_ = 0;
@@ -138,8 +144,17 @@ void CommandBufferService::DestroyTransferBuffer(int32 handle) {
}
}
-Buffer CommandBufferService::GetTransferBuffer(int32 handle) {
- return transfer_buffer_manager_->GetTransferBuffer(handle);
+Buffer CommandBufferService::GetTransferBuffer(int32 id) {
+ return transfer_buffer_manager_->GetTransferBuffer(id);
+}
+
+bool CommandBufferService::RegisterTransferBuffer(
+ int32 id,
+ base::SharedMemory* shared_memory,
+ size_t size) {
+ return transfer_buffer_manager_->RegisterTransferBuffer(id,
+ shared_memory,
+ size);
}
void CommandBufferService::SetToken(int32 token) {
diff --git a/gpu/command_buffer/service/command_buffer_service.h b/gpu/command_buffer/service/command_buffer_service.h
index c3bb841..c53a4bc 100644
--- a/gpu/command_buffer/service/command_buffer_service.h
+++ b/gpu/command_buffer/service/command_buffer_service.h
@@ -31,12 +31,9 @@ class GPU_EXPORT CommandBufferService : public CommandBuffer {
virtual State FlushSync(int32 put_offset, int32 last_known_get) OVERRIDE;
virtual void SetGetBuffer(int32 transfer_buffer_id) OVERRIDE;
virtual void SetGetOffset(int32 get_offset) OVERRIDE;
- virtual int32 CreateTransferBuffer(size_t size, int32 id_request) OVERRIDE;
- virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory,
- size_t size,
- int32 id_request) OVERRIDE;
+ virtual Buffer CreateTransferBuffer(size_t size, int32* id) OVERRIDE;
virtual void DestroyTransferBuffer(int32 id) OVERRIDE;
- virtual Buffer GetTransferBuffer(int32 handle) OVERRIDE;
+ virtual Buffer GetTransferBuffer(int32 id) OVERRIDE;
virtual void SetToken(int32 token) OVERRIDE;
virtual void SetParseError(error::Error error) OVERRIDE;
virtual void SetContextLostReason(error::ContextLostReason) OVERRIDE;
@@ -61,6 +58,13 @@ class GPU_EXPORT CommandBufferService : public CommandBuffer {
// Copy the current state into the shared state transfer buffer.
void UpdateState();
+ // Register an existing shared memory object and get an ID that can be used
+ // to identify it in the command buffer. Callee dups the handle until
+ // DestroyTransferBuffer is called.
+ bool RegisterTransferBuffer(int32 id,
+ base::SharedMemory* shared_memory,
+ size_t size);
+
private:
int32 ring_buffer_id_;
Buffer ring_buffer_;
diff --git a/gpu/command_buffer/service/command_buffer_service_unittest.cc b/gpu/command_buffer/service/command_buffer_service_unittest.cc
index 2c9093b..bf4d619 100644
--- a/gpu/command_buffer/service/command_buffer_service_unittest.cc
+++ b/gpu/command_buffer/service/command_buffer_service_unittest.cc
@@ -50,7 +50,8 @@ class CommandBufferServiceTest : public testing::Test {
}
bool Initialize(size_t size) {
- int32 id = command_buffer_->CreateTransferBuffer(size, -1);
+ int32 id;
+ command_buffer_->CreateTransferBuffer(size, &id);
EXPECT_GT(id, 0);
command_buffer_->SetGetBuffer(id);
return true;
@@ -117,7 +118,8 @@ TEST_F(CommandBufferServiceTest, CanSyncGetAndPutOffset) {
}
TEST_F(CommandBufferServiceTest, SetGetBuffer) {
- int32 ring_buffer_id = command_buffer_->CreateTransferBuffer(1024, -1);
+ int32 ring_buffer_id;
+ command_buffer_->CreateTransferBuffer(1024, &ring_buffer_id);
EXPECT_GT(ring_buffer_id, 0);
scoped_ptr<StrictMock<MockCallbackTest> > change_callback(
diff --git a/gpu/command_buffer/service/transfer_buffer_manager.cc b/gpu/command_buffer/service/transfer_buffer_manager.cc
index 7bde12a..12c9fb1 100644
--- a/gpu/command_buffer/service/transfer_buffer_manager.cc
+++ b/gpu/command_buffer/service/transfer_buffer_manager.cc
@@ -8,6 +8,7 @@
#include "base/process_util.h"
#include "base/debug/trace_event.h"
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
using ::base::SharedMemory;
@@ -18,17 +19,15 @@ TransferBufferManagerInterface::~TransferBufferManagerInterface() {
TransferBufferManager::TransferBufferManager()
: shared_memory_bytes_allocated_(0) {
- // Element zero is always NULL.
- registered_objects_.push_back(Buffer());
}
TransferBufferManager::~TransferBufferManager() {
- for (size_t i = 0; i < registered_objects_.size(); ++i) {
- if (registered_objects_[i].shared_memory) {
- DCHECK(shared_memory_bytes_allocated_ >= registered_objects_[i].size);
- shared_memory_bytes_allocated_ -= registered_objects_[i].size;
- delete registered_objects_[i].shared_memory;
- }
+ while (!registered_buffers_.empty()) {
+ BufferMap::iterator it = registered_buffers_.begin();
+ DCHECK(shared_memory_bytes_allocated_ >= it->second.size);
+ shared_memory_bytes_allocated_ -= it->second.size;
+ delete it->second.shared_memory;
+ registered_buffers_.erase(it);
}
DCHECK(!shared_memory_bytes_allocated_);
}
@@ -37,42 +36,38 @@ bool TransferBufferManager::Initialize() {
return true;
}
-int32 TransferBufferManager::CreateTransferBuffer(
- size_t size, int32 id_request) {
- SharedMemory buffer;
- if (!buffer.CreateAnonymous(size))
- return -1;
-
- return RegisterTransferBuffer(&buffer, size, id_request);
-}
-
-int32 TransferBufferManager::RegisterTransferBuffer(
- base::SharedMemory* shared_memory, size_t size, int32 id_request) {
- // Check we haven't exceeded the range that fits in a 32-bit integer.
- if (unused_registered_object_elements_.empty()) {
- if (registered_objects_.size() > std::numeric_limits<uint32>::max())
- return -1;
+bool TransferBufferManager::RegisterTransferBuffer(
+ int32 id,
+ base::SharedMemory* shared_memory,
+ size_t size) {
+ if (id <= 0) {
+ DVLOG(ERROR) << "Cannot register transfer buffer with non-positive ID.";
+ return false;
}
- // Check that the requested ID is sane (not too large, or less than -1)
- if (id_request != -1 && (id_request > 100 || id_request < -1))
- return -1;
+ // Fail if the ID is in use.
+ if (registered_buffers_.find(id) != registered_buffers_.end()) {
+ DVLOG(ERROR) << "Buffer ID already in use.";
+ return false;
+ }
// Duplicate the handle.
base::SharedMemoryHandle duped_shared_memory_handle;
if (!shared_memory->ShareToProcess(base::GetCurrentProcessHandle(),
&duped_shared_memory_handle)) {
- return -1;
+ DVLOG(ERROR) << "Failed to duplicate shared memory handle.";
+ return false;
}
scoped_ptr<SharedMemory> duped_shared_memory(
new SharedMemory(duped_shared_memory_handle, false));
// Map the shared memory into this process. This validates the size.
- if (!duped_shared_memory->Map(size))
- return -1;
+ if (!duped_shared_memory->Map(size)) {
+ DVLOG(ERROR) << "Failed to map shared memory.";
+ return false;
+ }
- // If it could be mapped, allocate an ID and register the shared memory with
- // that ID.
+ // If it could be mapped register the shared memory with the ID.
Buffer buffer;
buffer.ptr = duped_shared_memory->memory();
buffer.size = size;
@@ -82,73 +77,36 @@ int32 TransferBufferManager::RegisterTransferBuffer(
TRACE_COUNTER_ID1(
"gpu", "GpuTransferBufferMemory", this, shared_memory_bytes_allocated_);
- // If caller requested specific id, first try to use id_request.
- if (id_request != -1) {
- int32 cur_size = static_cast<int32>(registered_objects_.size());
- if (cur_size <= id_request) {
- // Pad registered_objects_ to reach id_request.
- registered_objects_.resize(static_cast<size_t>(id_request + 1));
- for (int32 id = cur_size; id < id_request; ++id)
- unused_registered_object_elements_.insert(id);
- registered_objects_[id_request] = buffer;
- return id_request;
- } else if (!registered_objects_[id_request].shared_memory) {
- // id_request is already in free list.
- registered_objects_[id_request] = buffer;
- unused_registered_object_elements_.erase(id_request);
- return id_request;
- }
- }
+ registered_buffers_[id] = buffer;
- if (unused_registered_object_elements_.empty()) {
- int32 handle = static_cast<int32>(registered_objects_.size());
- registered_objects_.push_back(buffer);
- return handle;
- } else {
- int32 handle = *unused_registered_object_elements_.begin();
- unused_registered_object_elements_.erase(
- unused_registered_object_elements_.begin());
- DCHECK(!registered_objects_[handle].shared_memory);
- registered_objects_[handle] = buffer;
- return handle;
- }
+ return true;
}
-void TransferBufferManager::DestroyTransferBuffer(int32 handle) {
- if (handle <= 0)
- return;
-
- if (static_cast<size_t>(handle) >= registered_objects_.size())
+void TransferBufferManager::DestroyTransferBuffer(int32 id) {
+ BufferMap::iterator it = registered_buffers_.find(id);
+ if (it == registered_buffers_.end()) {
+ DVLOG(ERROR) << "Transfer buffer ID was not registered.";
return;
+ }
- DCHECK(shared_memory_bytes_allocated_ >= registered_objects_[handle].size);
- shared_memory_bytes_allocated_ -= registered_objects_[handle].size;
+ DCHECK(shared_memory_bytes_allocated_ >= it->second.size);
+ shared_memory_bytes_allocated_ -= it->second.size;
TRACE_COUNTER_ID1(
"CommandBuffer", "SharedMemory", this, shared_memory_bytes_allocated_);
- delete registered_objects_[handle].shared_memory;
- registered_objects_[handle] = Buffer();
- unused_registered_object_elements_.insert(handle);
-
- // Remove all null objects from the end of the vector. This allows the vector
- // to shrink when, for example, all objects are unregistered. Note that this
- // loop never removes element zero, which is always NULL.
- while (registered_objects_.size() > 1 &&
- !registered_objects_.back().shared_memory) {
- registered_objects_.pop_back();
- unused_registered_object_elements_.erase(
- static_cast<int32>(registered_objects_.size()));
- }
+ delete it->second.shared_memory;
+ registered_buffers_.erase(it);
}
-Buffer TransferBufferManager::GetTransferBuffer(int32 handle) {
- if (handle < 0)
+Buffer TransferBufferManager::GetTransferBuffer(int32 id) {
+ if (id == 0)
return Buffer();
- if (static_cast<size_t>(handle) >= registered_objects_.size())
+ BufferMap::iterator it = registered_buffers_.find(id);
+ if (it == registered_buffers_.end())
return Buffer();
- return registered_objects_[handle];
+ return it->second;
}
} // namespace gpu
diff --git a/gpu/command_buffer/service/transfer_buffer_manager.h b/gpu/command_buffer/service/transfer_buffer_manager.h
index 9f24e2c..b50a5ae 100644
--- a/gpu/command_buffer/service/transfer_buffer_manager.h
+++ b/gpu/command_buffer/service/transfer_buffer_manager.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/hash_tables.h"
#include "base/shared_memory.h"
#include "gpu/command_buffer/common/command_buffer_shared.h"
@@ -19,13 +20,11 @@ class GPU_EXPORT TransferBufferManagerInterface {
public:
virtual ~TransferBufferManagerInterface();
- virtual int32 CreateTransferBuffer(size_t size, int32 id_request) = 0;
- virtual int32 RegisterTransferBuffer(
- base::SharedMemory* shared_memory,
- size_t size,
- int32 id_request) = 0;
+ virtual bool RegisterTransferBuffer(int32 id,
+ base::SharedMemory* shared_memory,
+ size_t size) = 0;
virtual void DestroyTransferBuffer(int32 id) = 0;
- virtual Buffer GetTransferBuffer(int32 handle) = 0;
+ virtual Buffer GetTransferBuffer(int32 id) = 0;
};
@@ -35,19 +34,17 @@ class GPU_EXPORT TransferBufferManager
TransferBufferManager();
bool Initialize();
- virtual int32 CreateTransferBuffer(size_t size, int32 id_request) OVERRIDE;
- virtual int32 RegisterTransferBuffer(
- base::SharedMemory* shared_memory,
- size_t size,
- int32 id_request) OVERRIDE;
+ virtual bool RegisterTransferBuffer(int32 id,
+ base::SharedMemory* shared_memory,
+ size_t size) OVERRIDE;
virtual void DestroyTransferBuffer(int32 id) OVERRIDE;
- virtual Buffer GetTransferBuffer(int32 handle) OVERRIDE;
+ virtual Buffer GetTransferBuffer(int32 id) OVERRIDE;
private:
virtual ~TransferBufferManager();
- std::set<int32> unused_registered_object_elements_;
- std::vector<Buffer> registered_objects_;
+ typedef base::hash_map<int32, Buffer> BufferMap;
+ BufferMap registered_buffers_;
size_t shared_memory_bytes_allocated_;
DISALLOW_COPY_AND_ASSIGN(TransferBufferManager);
diff --git a/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc b/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc
index 029cb0e..68c5c2e 100644
--- a/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc
+++ b/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc
@@ -12,14 +12,22 @@ using base::SharedMemory;
namespace gpu {
+const static size_t kBufferSize = 1024;
+
class TransferBufferManagerTest : public testing::Test {
protected:
virtual void SetUp() {
+ for (size_t i = 0; i < arraysize(buffers_); ++i) {
+ buffers_[i].CreateAnonymous(kBufferSize);
+ buffers_[i].Map(kBufferSize);
+ }
+
TransferBufferManager* manager = new TransferBufferManager();
transfer_buffer_manager_.reset(manager);
- manager->Initialize();
+ ASSERT_TRUE(manager->Initialize());
}
+ base::SharedMemory buffers_[3];
scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_;
};
@@ -35,59 +43,73 @@ TEST_F(TransferBufferManagerTest, OutOfRangeHandleMapsToNull) {
EXPECT_TRUE(NULL == transfer_buffer_manager_->GetTransferBuffer(1).ptr);
}
-TEST_F(TransferBufferManagerTest, CanCreateTransferBuffers) {
- int32 handle = transfer_buffer_manager_->CreateTransferBuffer(1024, -1);
- EXPECT_EQ(1, handle);
- Buffer buffer = transfer_buffer_manager_->GetTransferBuffer(handle);
- ASSERT_TRUE(NULL != buffer.ptr);
- EXPECT_EQ(1024u, buffer.size);
+TEST_F(TransferBufferManagerTest, CanRegisterTransferBuffer) {
+ EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer(1,
+ &buffers_[0],
+ kBufferSize));
+ Buffer registered = transfer_buffer_manager_->GetTransferBuffer(1);
+
+ // Distinct memory range and shared memory handle from that originally
+ // registered.
+ EXPECT_NE(static_cast<void*>(NULL), registered.ptr);
+ EXPECT_NE(buffers_[0].memory(), registered.ptr);
+ EXPECT_EQ(kBufferSize, registered.size);
+ EXPECT_NE(&buffers_[0], registered.shared_memory);
+
+ // But maps to the same physical memory.
+ *static_cast<int*>(registered.ptr) = 7;
+ *static_cast<int*>(buffers_[0].memory()) = 8;
+ EXPECT_EQ(8, *static_cast<int*>(registered.ptr));
}
-TEST_F(TransferBufferManagerTest, CreateTransferBufferReturnsDistinctHandles) {
- EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
-}
-
-TEST_F(TransferBufferManagerTest,
- CreateTransferBufferReusesUnregisteredHandles) {
- EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
- EXPECT_EQ(2, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
+TEST_F(TransferBufferManagerTest, CanDestroyTransferBuffer) {
+ EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer(1,
+ &buffers_[0],
+ kBufferSize));
transfer_buffer_manager_->DestroyTransferBuffer(1);
- EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
- EXPECT_EQ(3, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
-}
+ Buffer registered = transfer_buffer_manager_->GetTransferBuffer(1);
-TEST_F(TransferBufferManagerTest, CannotUnregisterHandleZero) {
- transfer_buffer_manager_->DestroyTransferBuffer(0);
- EXPECT_TRUE(NULL == transfer_buffer_manager_->GetTransferBuffer(0).ptr);
- EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
+ EXPECT_EQ(static_cast<void*>(NULL), registered.ptr);
+ EXPECT_EQ(0U, registered.size);
+ EXPECT_EQ(static_cast<base::SharedMemory*>(NULL), registered.shared_memory);
}
-TEST_F(TransferBufferManagerTest, CannotUnregisterNegativeHandles) {
- transfer_buffer_manager_->DestroyTransferBuffer(-1);
- EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
+TEST_F(TransferBufferManagerTest, CannotRegregisterTransferBufferId) {
+ EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer(1,
+ &buffers_[0],
+ kBufferSize));
+ EXPECT_FALSE(transfer_buffer_manager_->RegisterTransferBuffer(1,
+ &buffers_[0],
+ kBufferSize));
+ EXPECT_FALSE(transfer_buffer_manager_->RegisterTransferBuffer(1,
+ &buffers_[1],
+ kBufferSize));
}
-TEST_F(TransferBufferManagerTest, CannotUnregisterUnregisteredHandles) {
+TEST_F(TransferBufferManagerTest, CanReuseTransferBufferIdAfterDestroying) {
+ EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer(1,
+ &buffers_[0],
+ kBufferSize));
transfer_buffer_manager_->DestroyTransferBuffer(1);
- EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
+ EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer(1,
+ &buffers_[1],
+ kBufferSize));
}
-// Testing this case specifically because there is an optimization that takes
-// a different code path in this case.
-TEST_F(TransferBufferManagerTest, UnregistersLastRegisteredHandle) {
- EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
+TEST_F(TransferBufferManagerTest, DestroyUnusedTransferBufferIdDoesNotCrash) {
transfer_buffer_manager_->DestroyTransferBuffer(1);
- EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
}
-// Testing this case specifically because there is an optimization that takes
-// a different code path in this case.
-TEST_F(TransferBufferManagerTest, UnregistersTwoLastRegisteredHandles) {
- EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
- EXPECT_EQ(2, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
- transfer_buffer_manager_->DestroyTransferBuffer(2);
- transfer_buffer_manager_->DestroyTransferBuffer(1);
- EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
+TEST_F(TransferBufferManagerTest, CannotRegisterNullTransferBuffer) {
+ EXPECT_FALSE(transfer_buffer_manager_->RegisterTransferBuffer(0,
+ &buffers_[0],
+ kBufferSize));
+}
+
+TEST_F(TransferBufferManagerTest, CannotRegisterNegativeTransferBufferId) {
+ EXPECT_FALSE(transfer_buffer_manager_->RegisterTransferBuffer(-1,
+ &buffers_[0],
+ kBufferSize));
}
} // namespace gpu