summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-14 00:34:07 +0000
committerapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-14 00:34:07 +0000
commit392fbb3dd27259adc0a0ff1127bc19ad5c317ce5 (patch)
treee5bf30506de98cae91afbfb48ea38a6a9e84fb47 /gpu
parent1eebbf98440fdb3fed0e8a921c2e31474f91bb1e (diff)
downloadchromium_src-392fbb3dd27259adc0a0ff1127bc19ad5c317ce5.zip
chromium_src-392fbb3dd27259adc0a0ff1127bc19ad5c317ce5.tar.gz
chromium_src-392fbb3dd27259adc0a0ff1127bc19ad5c317ce5.tar.bz2
Revert 172805
> 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 TBR=apatrick@chromium.org Review URL: https://codereview.chromium.org/11578020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173018 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, 226 insertions, 192 deletions
diff --git a/gpu/command_buffer/client/client_test_helper.cc b/gpu/command_buffer/client/client_test_helper.cc
index 92af99d..d9942ef 100644
--- a/gpu/command_buffer/client/client_test_helper.cc
+++ b/gpu/command_buffer/client/client_test_helper.cc
@@ -60,15 +60,16 @@ int32 MockCommandBufferBase::GetNextFreeTransferBufferId() {
return -1;
}
-Buffer MockCommandBufferBase::CreateTransferBuffer(size_t size, int32* id) {
- *id = GetNextFreeTransferBufferId();
- if (*id >= 0) {
- int32 ndx = *id - kTransferBufferBaseId;
+int32 MockCommandBufferBase::CreateTransferBuffer(
+ size_t size, int32 id_request) {
+ int32 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 GetTransferBuffer(*id);
+ return id;
}
void MockCommandBufferBase::DestroyTransferBufferHelper(int32 id) {
@@ -85,6 +86,14 @@ 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 3302b47..25d1014 100644
--- a/gpu/command_buffer/client/client_test_helper.h
+++ b/gpu/command_buffer/client/client_test_helper.h
@@ -32,8 +32,11 @@ 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 Buffer CreateTransferBuffer(size_t size, int32* id) OVERRIDE;
+ virtual int32 CreateTransferBuffer(size_t size, int32 id_request) 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 ad5447a..f7d31c5 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper.cc
@@ -52,13 +52,18 @@ bool CommandBufferHelper::AllocateRingBuffer() {
return true;
}
- int32 id = -1;
- ring_buffer_ = command_buffer_->CreateTransferBuffer(ring_buffer_size_, &id);
+ int32 id = command_buffer_->CreateTransferBuffer(ring_buffer_size_, -1);
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 2c6cdc6..44fb851 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()));
- EXPECT_TRUE(command_buffer_->Initialize());
+ 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 6176525..581981e 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) {
- buffers_[ii] = command_buffer_->CreateTransferBuffer(
- size_ + ii * alignment_,
- &buffer_ids_[ii]);
+ buffer_ids_[ii] = command_buffer_->CreateTransferBuffer(
+ size_ + ii * alignment_, -1);
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 5278fc8..c8d400e 100644
--- a/gpu/command_buffer/client/mapped_memory.cc
+++ b/gpu/command_buffer/client/mapped_memory.cc
@@ -56,10 +56,11 @@ void* MappedMemoryManager::Alloc(
unsigned int chunk_size =
((size + chunk_size_multiple_ - 1) / chunk_size_multiple_) *
chunk_size_multiple_;
- int32 id = -1;
- gpu::Buffer shm = cmd_buf->CreateTransferBuffer(chunk_size, &id);
- if (id < 0)
+ int32 id = cmd_buf->CreateTransferBuffer(chunk_size, -1);
+ if (id == -1) {
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 7492159..7e0b25f 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 = -1;
- buffer_ = helper_->command_buffer()->CreateTransferBuffer(size, &id);
+ int32 id = helper_->command_buffer()->CreateTransferBuffer(size, -1);
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 f40de23..469483b 100644
--- a/gpu/command_buffer/client/transfer_buffer_unittest.cc
+++ b/gpu/command_buffer/client/transfer_buffer_unittest.cc
@@ -16,7 +16,6 @@
using ::testing::_;
using ::testing::Invoke;
using ::testing::Return;
-using ::testing::SetArgPointee;
using ::testing::StrictMock;
namespace gpu {
@@ -212,10 +211,10 @@ class MockClientCommandBufferCanFail : public MockClientCommandBufferMockFlush {
virtual ~MockClientCommandBufferCanFail() {
}
- MOCK_METHOD2(CreateTransferBuffer, Buffer(size_t size, int32* id));
+ MOCK_METHOD2(CreateTransferBuffer, int32(size_t size, int32 id_request));
- Buffer RealCreateTransferBuffer(size_t size, int32* id) {
- return MockCommandBufferBase::CreateTransferBuffer(size, id);
+ int32 RealCreateTransferBuffer(size_t size, int32 id_request) {
+ return MockCommandBufferBase::CreateTransferBuffer(size, id_request);
}
};
@@ -373,7 +372,7 @@ TEST_F(TransferBufferExpandContractTest, Contract) {
// Try to allocate again, fail first request
EXPECT_CALL(*command_buffer(),
CreateTransferBuffer(kStartTransferBufferSize, _))
- .WillOnce(DoAll(SetArgPointee<1>(-1), Return(Buffer())))
+ .WillOnce(Return(-1))
.RetiresOnSaturation();
EXPECT_CALL(*command_buffer(),
CreateTransferBuffer(kMinTransferBufferSize, _))
@@ -425,9 +424,9 @@ TEST_F(TransferBufferExpandContractTest, OutOfMemory) {
// Try to allocate again, fail both requests.
EXPECT_CALL(*command_buffer(), CreateTransferBuffer(_, _))
- .WillOnce(DoAll(SetArgPointee<1>(-1), Return(Buffer())))
- .WillOnce(DoAll(SetArgPointee<1>(-1), Return(Buffer())))
- .WillOnce(DoAll(SetArgPointee<1>(-1), Return(Buffer())))
+ .WillOnce(Return(-1))
+ .WillOnce(Return(-1))
+ .WillOnce(Return(-1))
.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 e100792..6b19ea2 100644
--- a/gpu/command_buffer/common/command_buffer.h
+++ b/gpu/command_buffer/common/command_buffer.h
@@ -101,16 +101,28 @@ 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 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.
+ // 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.
virtual void DestroyTransferBuffer(int32 id) = 0;
- // Get the transfer buffer associated with an ID. Returns a null buffer for
- // ID 0.
- virtual Buffer GetTransferBuffer(int32 id) = 0;
+ // Get the transfer buffer associated with a handle.
+ virtual Buffer GetTransferBuffer(int32 handle) = 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 b2ee11f..0379340 100644
--- a/gpu/command_buffer/common/command_buffer_mock.h
+++ b/gpu/command_buffer/common/command_buffer_mock.h
@@ -28,9 +28,12 @@ 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, Buffer(size_t size, int32* id));
- MOCK_METHOD1(DestroyTransferBuffer, void(int32 id));
- MOCK_METHOD1(GetTransferBuffer, Buffer(int32 id));
+ 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_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 391f335..8b00595 100644
--- a/gpu/command_buffer/service/command_buffer_service.cc
+++ b/gpu/command_buffer/service/command_buffer_service.cc
@@ -116,26 +116,20 @@ void CommandBufferService::SetGetOffset(int32 get_offset) {
get_offset_ = get_offset;
}
-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++;
-
- if (!RegisterTransferBuffer(*id, &buffer, size))
- return Buffer();
+int32 CommandBufferService::CreateTransferBuffer(size_t size,
+ int32 id_request) {
+ return transfer_buffer_manager_->CreateTransferBuffer(size, id_request);
+}
- return GetTransferBuffer(*id);
+int32 CommandBufferService::RegisterTransferBuffer(
+ base::SharedMemory* shared_memory, size_t size, int32 id_request) {
+ return transfer_buffer_manager_->RegisterTransferBuffer(
+ shared_memory, size, id_request);
}
-void CommandBufferService::DestroyTransferBuffer(int32 id) {
- transfer_buffer_manager_->DestroyTransferBuffer(id);
- if (id == ring_buffer_id_) {
+void CommandBufferService::DestroyTransferBuffer(int32 handle) {
+ transfer_buffer_manager_->DestroyTransferBuffer(handle);
+ if (handle == ring_buffer_id_) {
ring_buffer_id_ = -1;
ring_buffer_ = Buffer();
num_entries_ = 0;
@@ -144,17 +138,8 @@ void CommandBufferService::DestroyTransferBuffer(int32 id) {
}
}
-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);
+Buffer CommandBufferService::GetTransferBuffer(int32 handle) {
+ return transfer_buffer_manager_->GetTransferBuffer(handle);
}
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 c53a4bc..c3bb841 100644
--- a/gpu/command_buffer/service/command_buffer_service.h
+++ b/gpu/command_buffer/service/command_buffer_service.h
@@ -31,9 +31,12 @@ 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 Buffer CreateTransferBuffer(size_t size, int32* id) 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 void DestroyTransferBuffer(int32 id) OVERRIDE;
- virtual Buffer GetTransferBuffer(int32 id) OVERRIDE;
+ virtual Buffer GetTransferBuffer(int32 handle) OVERRIDE;
virtual void SetToken(int32 token) OVERRIDE;
virtual void SetParseError(error::Error error) OVERRIDE;
virtual void SetContextLostReason(error::ContextLostReason) OVERRIDE;
@@ -58,13 +61,6 @@ 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 bf4d619..2c9093b 100644
--- a/gpu/command_buffer/service/command_buffer_service_unittest.cc
+++ b/gpu/command_buffer/service/command_buffer_service_unittest.cc
@@ -50,8 +50,7 @@ class CommandBufferServiceTest : public testing::Test {
}
bool Initialize(size_t size) {
- int32 id;
- command_buffer_->CreateTransferBuffer(size, &id);
+ int32 id = command_buffer_->CreateTransferBuffer(size, -1);
EXPECT_GT(id, 0);
command_buffer_->SetGetBuffer(id);
return true;
@@ -118,8 +117,7 @@ TEST_F(CommandBufferServiceTest, CanSyncGetAndPutOffset) {
}
TEST_F(CommandBufferServiceTest, SetGetBuffer) {
- int32 ring_buffer_id;
- command_buffer_->CreateTransferBuffer(1024, &ring_buffer_id);
+ int32 ring_buffer_id = command_buffer_->CreateTransferBuffer(1024, -1);
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 12c9fb1..7bde12a 100644
--- a/gpu/command_buffer/service/transfer_buffer_manager.cc
+++ b/gpu/command_buffer/service/transfer_buffer_manager.cc
@@ -8,7 +8,6 @@
#include "base/process_util.h"
#include "base/debug/trace_event.h"
-#include "gpu/command_buffer/common/gles2_cmd_utils.h"
using ::base::SharedMemory;
@@ -19,15 +18,17 @@ TransferBufferManagerInterface::~TransferBufferManagerInterface() {
TransferBufferManager::TransferBufferManager()
: shared_memory_bytes_allocated_(0) {
+ // Element zero is always NULL.
+ registered_objects_.push_back(Buffer());
}
TransferBufferManager::~TransferBufferManager() {
- 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);
+ 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;
+ }
}
DCHECK(!shared_memory_bytes_allocated_);
}
@@ -36,38 +37,42 @@ bool TransferBufferManager::Initialize() {
return true;
}
-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;
- }
+int32 TransferBufferManager::CreateTransferBuffer(
+ size_t size, int32 id_request) {
+ SharedMemory buffer;
+ if (!buffer.CreateAnonymous(size))
+ return -1;
+
+ return RegisterTransferBuffer(&buffer, size, id_request);
+}
- // Fail if the ID is in use.
- if (registered_buffers_.find(id) != registered_buffers_.end()) {
- DVLOG(ERROR) << "Buffer ID already in use.";
- return false;
+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;
}
+ // 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;
+
// Duplicate the handle.
base::SharedMemoryHandle duped_shared_memory_handle;
if (!shared_memory->ShareToProcess(base::GetCurrentProcessHandle(),
&duped_shared_memory_handle)) {
- DVLOG(ERROR) << "Failed to duplicate shared memory handle.";
- return false;
+ return -1;
}
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)) {
- DVLOG(ERROR) << "Failed to map shared memory.";
- return false;
- }
+ if (!duped_shared_memory->Map(size))
+ return -1;
- // If it could be mapped register the shared memory with the ID.
+ // If it could be mapped, allocate an ID and register the shared memory with
+ // that ID.
Buffer buffer;
buffer.ptr = duped_shared_memory->memory();
buffer.size = size;
@@ -77,36 +82,73 @@ bool TransferBufferManager::RegisterTransferBuffer(
TRACE_COUNTER_ID1(
"gpu", "GpuTransferBufferMemory", this, shared_memory_bytes_allocated_);
- registered_buffers_[id] = buffer;
+ // 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;
+ }
+ }
- return true;
+ 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;
+ }
}
-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.";
+void TransferBufferManager::DestroyTransferBuffer(int32 handle) {
+ if (handle <= 0)
return;
- }
- DCHECK(shared_memory_bytes_allocated_ >= it->second.size);
- shared_memory_bytes_allocated_ -= it->second.size;
+ if (static_cast<size_t>(handle) >= registered_objects_.size())
+ return;
+
+ DCHECK(shared_memory_bytes_allocated_ >= registered_objects_[handle].size);
+ shared_memory_bytes_allocated_ -= registered_objects_[handle].size;
TRACE_COUNTER_ID1(
"CommandBuffer", "SharedMemory", this, shared_memory_bytes_allocated_);
- delete it->second.shared_memory;
- registered_buffers_.erase(it);
+ 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()));
+ }
}
-Buffer TransferBufferManager::GetTransferBuffer(int32 id) {
- if (id == 0)
+Buffer TransferBufferManager::GetTransferBuffer(int32 handle) {
+ if (handle < 0)
return Buffer();
- BufferMap::iterator it = registered_buffers_.find(id);
- if (it == registered_buffers_.end())
+ if (static_cast<size_t>(handle) >= registered_objects_.size())
return Buffer();
- return it->second;
+ return registered_objects_[handle];
}
} // namespace gpu
diff --git a/gpu/command_buffer/service/transfer_buffer_manager.h b/gpu/command_buffer/service/transfer_buffer_manager.h
index b50a5ae..9f24e2c 100644
--- a/gpu/command_buffer/service/transfer_buffer_manager.h
+++ b/gpu/command_buffer/service/transfer_buffer_manager.h
@@ -10,7 +10,6 @@
#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"
@@ -20,11 +19,13 @@ class GPU_EXPORT TransferBufferManagerInterface {
public:
virtual ~TransferBufferManagerInterface();
- virtual bool RegisterTransferBuffer(int32 id,
- base::SharedMemory* shared_memory,
- size_t size) = 0;
+ 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 void DestroyTransferBuffer(int32 id) = 0;
- virtual Buffer GetTransferBuffer(int32 id) = 0;
+ virtual Buffer GetTransferBuffer(int32 handle) = 0;
};
@@ -34,17 +35,19 @@ class GPU_EXPORT TransferBufferManager
TransferBufferManager();
bool Initialize();
- virtual bool RegisterTransferBuffer(int32 id,
- base::SharedMemory* shared_memory,
- size_t size) 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 void DestroyTransferBuffer(int32 id) OVERRIDE;
- virtual Buffer GetTransferBuffer(int32 id) OVERRIDE;
+ virtual Buffer GetTransferBuffer(int32 handle) OVERRIDE;
private:
virtual ~TransferBufferManager();
- typedef base::hash_map<int32, Buffer> BufferMap;
- BufferMap registered_buffers_;
+ std::set<int32> unused_registered_object_elements_;
+ std::vector<Buffer> registered_objects_;
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 68c5c2e..029cb0e 100644
--- a/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc
+++ b/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc
@@ -12,22 +12,14 @@ 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);
- ASSERT_TRUE(manager->Initialize());
+ manager->Initialize();
}
- base::SharedMemory buffers_[3];
scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_;
};
@@ -43,73 +35,59 @@ TEST_F(TransferBufferManagerTest, OutOfRangeHandleMapsToNull) {
EXPECT_TRUE(NULL == transfer_buffer_manager_->GetTransferBuffer(1).ptr);
}
-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, 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, CanDestroyTransferBuffer) {
- EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer(1,
- &buffers_[0],
- kBufferSize));
- transfer_buffer_manager_->DestroyTransferBuffer(1);
- Buffer registered = transfer_buffer_manager_->GetTransferBuffer(1);
+TEST_F(TransferBufferManagerTest, CreateTransferBufferReturnsDistinctHandles) {
+ 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,
+ CreateTransferBufferReusesUnregisteredHandles) {
+ EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
+ EXPECT_EQ(2, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
+ transfer_buffer_manager_->DestroyTransferBuffer(1);
+ EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
+ EXPECT_EQ(3, 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, CannotUnregisterHandleZero) {
+ transfer_buffer_manager_->DestroyTransferBuffer(0);
+ EXPECT_TRUE(NULL == transfer_buffer_manager_->GetTransferBuffer(0).ptr);
+ EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
}
-TEST_F(TransferBufferManagerTest, CanReuseTransferBufferIdAfterDestroying) {
- EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer(1,
- &buffers_[0],
- kBufferSize));
- transfer_buffer_manager_->DestroyTransferBuffer(1);
- EXPECT_TRUE(transfer_buffer_manager_->RegisterTransferBuffer(1,
- &buffers_[1],
- kBufferSize));
+TEST_F(TransferBufferManagerTest, CannotUnregisterNegativeHandles) {
+ transfer_buffer_manager_->DestroyTransferBuffer(-1);
+ EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
}
-TEST_F(TransferBufferManagerTest, DestroyUnusedTransferBufferIdDoesNotCrash) {
+TEST_F(TransferBufferManagerTest, CannotUnregisterUnregisteredHandles) {
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));
+// 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));
+ transfer_buffer_manager_->DestroyTransferBuffer(1);
+ EXPECT_EQ(1, transfer_buffer_manager_->CreateTransferBuffer(1024, -1));
}
-TEST_F(TransferBufferManagerTest, CannotRegisterNegativeTransferBufferId) {
- EXPECT_FALSE(transfer_buffer_manager_->RegisterTransferBuffer(-1,
- &buffers_[0],
- kBufferSize));
+// 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));
}
} // namespace gpu