diff options
Diffstat (limited to 'gpu/command_buffer')
5 files changed, 57 insertions, 16 deletions
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index aa187e0..dc088fd 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -73,6 +73,12 @@ class GLES2MockCommandBufferHelper : public CommandBuffer { return transfer_buffer_buffer_; } + virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, + size_t size) { + GPU_NOTREACHED(); + return -1; + } + virtual void SetToken(int32 token) { GPU_NOTREACHED(); state_.token = token; diff --git a/gpu/command_buffer/common/command_buffer.h b/gpu/command_buffer/common/command_buffer.h index 963b228..b758333 100644 --- a/gpu/command_buffer/common/command_buffer.h +++ b/gpu/command_buffer/common/command_buffer.h @@ -80,6 +80,12 @@ class CommandBuffer { // identifies it or -1 on error. virtual int32 CreateTransferBuffer(size_t size) = 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. + virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, + size_t size) = 0; + // Destroy a transfer buffer and recycle the handle. virtual void DestroyTransferBuffer(int32 id) = 0; diff --git a/gpu/command_buffer/common/command_buffer_mock.h b/gpu/command_buffer/common/command_buffer_mock.h index a633d24..99a72d3 100644 --- a/gpu/command_buffer/common/command_buffer_mock.h +++ b/gpu/command_buffer/common/command_buffer_mock.h @@ -8,6 +8,10 @@ #include "../common/command_buffer.h" #include "testing/gmock/include/gmock/gmock.h" +namespace base { +class SharedMemory; +} + namespace gpu { // An NPObject that implements a shared memory command buffer and a synchronous @@ -26,6 +30,8 @@ class MockCommandBuffer : public CommandBuffer { MOCK_METHOD1(CreateTransferBuffer, int32(size_t size)); MOCK_METHOD1(DestroyTransferBuffer, void(int32 handle)); MOCK_METHOD1(GetTransferBuffer, Buffer(int32 handle)); + MOCK_METHOD2(RegisterTransferBuffer, int32(base::SharedMemory* shared_memory, + size_t size)); MOCK_METHOD1(SetToken, void(int32 token)); MOCK_METHOD1(SetParseError, void(error::Error error)); diff --git a/gpu/command_buffer/service/command_buffer_service.cc b/gpu/command_buffer/service/command_buffer_service.cc index c2a85af..d806de1 100644 --- a/gpu/command_buffer/service/command_buffer_service.cc +++ b/gpu/command_buffer/service/command_buffer_service.cc @@ -7,6 +7,7 @@ #include <limits> #include "base/callback.h" +#include "base/process_util.h" #include "gpu/command_buffer/common/cmd_buffer_common.h" using ::base::SharedMemory; @@ -20,10 +21,14 @@ CommandBufferService::CommandBufferService() token_(0), error_(error::kNoError) { // Element zero is always NULL. - registered_objects_.push_back(linked_ptr<SharedMemory>()); + registered_objects_.push_back(Buffer()); } CommandBufferService::~CommandBufferService() { + for (size_t i = 0; i < registered_objects_.size(); ++i) { + if (registered_objects_[i].shared_memory) + delete registered_objects_[i].shared_memory; + } } bool CommandBufferService::Initialize(int32 size) { @@ -102,9 +107,26 @@ void CommandBufferService::SetGetOffset(int32 get_offset) { } int32 CommandBufferService::CreateTransferBuffer(size_t size) { - linked_ptr<SharedMemory> buffer(new SharedMemory); - if (!buffer->CreateAnonymous(size)) + SharedMemory buffer; + if (!buffer.CreateAnonymous(size)) + return -1; + + return RegisterTransferBuffer(&buffer, size); +} + +int32 CommandBufferService::RegisterTransferBuffer( + base::SharedMemory* shared_memory, size_t size) { + // Duplicate the handle. + base::SharedMemoryHandle shared_memory_handle; + if (!shared_memory->ShareToProcess(base::GetCurrentProcessHandle(), + &shared_memory_handle)) { return -1; + } + + Buffer buffer; + buffer.ptr = NULL; + buffer.size = size; + buffer.shared_memory = new SharedMemory(shared_memory_handle, false); if (unused_registered_object_elements_.empty()) { // Check we haven't exceeded the range that fits in a 32-bit integer. @@ -119,7 +141,7 @@ int32 CommandBufferService::CreateTransferBuffer(size_t size) { int32 handle = *unused_registered_object_elements_.begin(); unused_registered_object_elements_.erase( unused_registered_object_elements_.begin()); - DCHECK(!registered_objects_[handle].get()); + DCHECK(!registered_objects_[handle].shared_memory); registered_objects_[handle] = buffer; return handle; } @@ -131,13 +153,15 @@ void CommandBufferService::DestroyTransferBuffer(int32 handle) { if (static_cast<size_t>(handle) >= registered_objects_.size()) return; - registered_objects_[handle].reset(); + 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().get()) { + 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())); @@ -151,19 +175,16 @@ Buffer CommandBufferService::GetTransferBuffer(int32 handle) { if (static_cast<size_t>(handle) >= registered_objects_.size()) return Buffer(); - base::SharedMemory* shared_memory = registered_objects_[handle].get(); - if (!shared_memory) - return Buffer(); + Buffer buffer = registered_objects_[handle]; + if (!buffer.shared_memory) + return Buffer(); - if (!shared_memory->memory()) { - if (!shared_memory->Map(shared_memory->created_size())) + if (!buffer.shared_memory->memory()) { + if (!buffer.shared_memory->Map(buffer.size)) return Buffer(); } - Buffer buffer; - buffer.ptr = shared_memory->memory(); - buffer.size = shared_memory->created_size(); - buffer.shared_memory = shared_memory; + buffer.ptr = buffer.shared_memory->memory(); return buffer; } diff --git a/gpu/command_buffer/service/command_buffer_service.h b/gpu/command_buffer/service/command_buffer_service.h index 94d77c3..9706008 100644 --- a/gpu/command_buffer/service/command_buffer_service.h +++ b/gpu/command_buffer/service/command_buffer_service.h @@ -32,6 +32,8 @@ class CommandBufferService : public CommandBuffer { virtual State FlushSync(int32 put_offset); virtual void SetGetOffset(int32 get_offset); virtual int32 CreateTransferBuffer(size_t size); + virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, + size_t size); virtual void DestroyTransferBuffer(int32 id); virtual Buffer GetTransferBuffer(int32 handle); virtual void SetToken(int32 token); @@ -55,7 +57,7 @@ class CommandBufferService : public CommandBuffer { int32 get_offset_; int32 put_offset_; scoped_ptr<Callback0::Type> put_offset_change_callback_; - std::vector<linked_ptr< base::SharedMemory> > registered_objects_; + std::vector<Buffer> registered_objects_; std::set<int32> unused_registered_object_elements_; int32 token_; error::Error error_; |