summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/renderer/gpu/renderer_gl_context.cc42
-rw-r--r--content/renderer/gpu/renderer_gl_context.h3
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py15
-rw-r--r--gpu/command_buffer/client/client_test_helper.cc138
-rw-r--r--gpu/command_buffer/client/client_test_helper.h76
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc748
-rw-r--r--gpu/command_buffer/client/gles2_implementation.h109
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest.cc1247
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest_autogen.h148
-rw-r--r--gpu/command_buffer/client/ring_buffer.h6
-rw-r--r--gpu/command_buffer/client/transfer_buffer.cc211
-rw-r--r--gpu/command_buffer/client/transfer_buffer.h221
-rw-r--r--gpu/command_buffer/client/transfer_buffer_unittest.cc434
-rw-r--r--gpu/command_buffer/common/compiler_specific.h23
-rw-r--r--gpu/demos/framework/window.cc31
-rw-r--r--gpu/demos/framework/window.h6
-rw-r--r--gpu/gles2_conform_support/egl/display.cc31
-rw-r--r--gpu/gles2_conform_support/egl/display.h5
-rw-r--r--gpu/gpu.gyp6
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/nacl.scons1
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.cc31
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.h4
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy_untrusted.gyp1
-rw-r--r--ppapi/shared_impl/ppb_graphics_3d_shared.cc44
-rw-r--r--ppapi/shared_impl/ppb_graphics_3d_shared.h5
-rw-r--r--webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc43
26 files changed, 2233 insertions, 1396 deletions
diff --git a/content/renderer/gpu/renderer_gl_context.cc b/content/renderer/gpu/renderer_gl_context.cc
index 5630a32..04cab30 100644
--- a/content/renderer/gpu/renderer_gl_context.cc
+++ b/content/renderer/gpu/renderer_gl_context.cc
@@ -23,6 +23,7 @@
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/gles2_lib.h"
+#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/constants.h"
#endif // ENABLE_GPU
@@ -31,7 +32,9 @@ namespace {
const int32 kCommandBufferSize = 1024 * 1024;
// TODO(kbr): make the transfer buffer size configurable via context
// creation attributes.
-const int32 kTransferBufferSize = 1024 * 1024;
+const size_t kStartTransferBufferSize = 1 * 1024 * 1024;
+const size_t kMinTransferBufferSize = 1 * 256 * 1024;
+const size_t kMaxTransferBufferSize = 16 * 1024 * 1024;
// Singleton used to initialize and terminate the gles2 library.
class GLES2Initializer {
@@ -281,7 +284,7 @@ RendererGLContext::RendererGLContext(GpuChannelHost* channel)
parent_texture_id_(0),
command_buffer_(NULL),
gles2_helper_(NULL),
- transfer_buffer_id_(-1),
+ transfer_buffer_(NULL),
gles2_implementation_(NULL),
last_error_(SUCCESS),
frame_number_(0) {
@@ -392,31 +395,24 @@ bool RendererGLContext::Initialize(bool onscreen,
TRACE_EVENT0("gpu", "RendererGLContext::Initialize::CreateTransferBuffer");
// Create a transfer buffer used to copy resources between the renderer
// process and the GPU process.
- transfer_buffer_id_ = command_buffer_->CreateTransferBuffer(
- kTransferBufferSize, gpu::kCommandBufferSharedMemoryId);
- if (transfer_buffer_id_ < 0) {
- Destroy();
- return false;
- }
- }
-
- // Map the buffer into the renderer process's address space.
- gpu::Buffer transfer_buffer =
- command_buffer_->GetTransferBuffer(transfer_buffer_id_);
- if (!transfer_buffer.ptr) {
- Destroy();
- return false;
+ transfer_buffer_ = new gpu::TransferBuffer(gles2_helper_);
}
// Create the object exposing the OpenGL API.
gles2_implementation_ = new gpu::gles2::GLES2Implementation(
gles2_helper_,
- transfer_buffer.size,
- transfer_buffer.ptr,
- transfer_buffer_id_,
+ transfer_buffer_,
share_resources,
bind_generates_resources);
+ if (!gles2_implementation_->Initialize(
+ kStartTransferBufferSize,
+ kMinTransferBufferSize,
+ kMaxTransferBufferSize)) {
+ Destroy();
+ return false;
+ }
+
return true;
}
@@ -437,10 +433,10 @@ void RendererGLContext::Destroy() {
gles2_implementation_ = NULL;
}
- // Do not destroy this transfer buffer here, because commands are still
- // in flight on the GPU process that may access them. When the command buffer
- // is destroyed, the associated shared memory will be cleaned up.
- transfer_buffer_id_ = -1;
+ if (transfer_buffer_) {
+ delete transfer_buffer_;
+ transfer_buffer_ = NULL;
+ }
delete gles2_helper_;
gles2_helper_ = NULL;
diff --git a/content/renderer/gpu/renderer_gl_context.h b/content/renderer/gpu/renderer_gl_context.h
index b3a8f74..e491e2c 100644
--- a/content/renderer/gpu/renderer_gl_context.h
+++ b/content/renderer/gpu/renderer_gl_context.h
@@ -25,6 +25,7 @@ class CommandBufferProxy;
class GURL;
namespace gpu {
+class TransferBuffer;
namespace gles2 {
class GLES2CmdHelper;
class GLES2Implementation;
@@ -199,7 +200,7 @@ class RendererGLContext : public base::SupportsWeakPtr<RendererGLContext>,
uint32 parent_texture_id_;
CommandBufferProxy* command_buffer_;
gpu::gles2::GLES2CmdHelper* gles2_helper_;
- int32 transfer_buffer_id_;
+ gpu::TransferBuffer* transfer_buffer_;
gpu::gles2::GLES2Implementation* gles2_implementation_;
Error last_error_;
int frame_number_;
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index db0be00..04f21a9 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -3210,9 +3210,10 @@ TEST_F(GLES2ImplementationTest, %(name)s) {
typedef %(name)s::Result Result;
Result::Type result = 0;
Cmds expected;
- expected.cmd.Init(%(cmd_args)s, transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
+ expected.cmd.Init(%(cmd_args)s, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->%(name)s(%(args)s, &result);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
@@ -4135,10 +4136,12 @@ TEST_F(GLES2ImplementationTest, %(name)s) {
typedef %(name)s::Result Result;
Cmds expected;
- expected.cmd.Init(1, transfer_buffer_id_, 0);
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(%(name)s::Result));
+ expected.cmd.Init(1, result1.id, result1.offset);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(1)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(1)))
.RetiresOnSaturation();
GLboolean result = gl_->%(name)s(1);
diff --git a/gpu/command_buffer/client/client_test_helper.cc b/gpu/command_buffer/client/client_test_helper.cc
new file mode 100644
index 0000000..e6ddfad
--- /dev/null
+++ b/gpu/command_buffer/client/client_test_helper.cc
@@ -0,0 +1,138 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Tests for GLES2Implementation.
+
+#include "gpu/command_buffer/client/client_test_helper.h"
+
+#include "gpu/command_buffer/common/command_buffer.h"
+#include "gpu/command_buffer/client/cmd_buffer_helper.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using ::testing::_;
+using ::testing::Invoke;
+
+namespace gpu {
+
+MockCommandBufferBase::~MockCommandBufferBase() {
+}
+
+bool MockCommandBufferBase::Initialize() {
+ return true;
+}
+
+CommandBuffer::State MockCommandBufferBase::GetState() {
+ return state_;
+}
+
+CommandBuffer::State MockCommandBufferBase::GetLastState() {
+ return state_;
+}
+
+void MockCommandBufferBase::Flush(int32 put_offset) {
+ state_.put_offset = put_offset;
+}
+
+void MockCommandBufferBase::SetGetOffset(int32 get_offset) {
+ state_.get_offset = get_offset;
+}
+
+CommandBuffer::State MockCommandBufferBase::FlushSync(
+ int32 put_offset, int32 last_known_get) {
+ state_.put_offset = put_offset;
+ state_.get_offset = put_offset;
+ OnFlush();
+ return state_;
+}
+
+void MockCommandBufferBase::SetGetBuffer(int transfer_buffer_id) {
+ ring_buffer_buffer_ = GetTransferBuffer(transfer_buffer_id);
+ ring_buffer_ = static_cast<CommandBufferEntry*>(ring_buffer_buffer_.ptr);
+ state_.num_entries = ring_buffer_buffer_.size / sizeof(ring_buffer_[0]);
+ state_.token = 10000; // All token checks in the tests should pass.
+}
+
+// Get's the Id of the next transfer buffer that will be returned
+// by CreateTransferBuffer. This is useful for testing expected ids.
+int32 MockCommandBufferBase::GetNextFreeTransferBufferId() {
+ for (size_t ii = 0; ii < arraysize(transfer_buffers_); ++ii) {
+ if (!transfer_buffers_[ii].get()) {
+ return kTransferBufferBaseId + ii;
+ }
+ }
+ return -1;
+}
+
+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 id;
+}
+
+void MockCommandBufferBase::DestroyTransferBufferHelper(int32 id) {
+ GPU_DCHECK_GE(id, kTransferBufferBaseId);
+ GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers);
+ id -= kTransferBufferBaseId;
+ transfer_buffers_[id].reset();
+ transfer_buffer_buffers_[id] = Buffer();
+}
+
+Buffer MockCommandBufferBase::GetTransferBuffer(int32 id) {
+ GPU_DCHECK_GE(id, kTransferBufferBaseId);
+ GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers);
+ 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::SetToken(int32 token) {
+ GPU_NOTREACHED();
+ state_.token = token;
+}
+
+void MockCommandBufferBase::SetParseError(error::Error error) {
+ GPU_NOTREACHED();
+ state_.error = error;
+}
+
+void MockCommandBufferBase::SetContextLostReason(
+ error::ContextLostReason reason) {
+ GPU_NOTREACHED();
+ state_.context_lost_reason = reason;
+}
+
+// GCC requires these declarations, but MSVC requires they not be present
+#ifndef _MSC_VER
+const int32 MockCommandBufferBase::kTransferBufferBaseId;
+const int32 MockCommandBufferBase::kMaxTransferBuffers;
+#endif
+
+MockClientCommandBuffer::MockClientCommandBuffer() {
+ DelegateToFake();
+}
+
+MockClientCommandBuffer::~MockClientCommandBuffer() {
+}
+
+void MockClientCommandBuffer::DelegateToFake() {
+ ON_CALL(*this, DestroyTransferBuffer(_))
+ .WillByDefault(Invoke(
+ this, &MockCommandBufferBase::DestroyTransferBufferHelper));
+}
+
+} // namespace gpu
+
+
diff --git a/gpu/command_buffer/client/client_test_helper.h b/gpu/command_buffer/client/client_test_helper.h
new file mode 100644
index 0000000..1b32c24
--- /dev/null
+++ b/gpu/command_buffer/client/client_test_helper.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Helper classes for implementing gpu client side unit tests.
+
+#ifndef GPU_COMMAND_BUFFER_CLIENT_CLIENT_TEST_HELPER_H_
+#define GPU_COMMAND_BUFFER_CLIENT_CLIENT_TEST_HELPER_H_
+
+#include "gpu/command_buffer/common/cmd_buffer_common.h"
+#include "gpu/command_buffer/common/command_buffer.h"
+#include "gpu/command_buffer/common/compiler_specific.h"
+#include "gpu/command_buffer/common/scoped_ptr.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace gpu {
+
+class CommandBufferHelper;
+
+class MockCommandBufferBase : public CommandBuffer {
+ public:
+ static const int32 kTransferBufferBaseId = 0x123;
+ static const int32 kMaxTransferBuffers = 6;
+
+ MockCommandBufferBase() { }
+ virtual ~MockCommandBufferBase();
+
+ virtual bool Initialize() OVERRIDE;
+ virtual State GetState() OVERRIDE;
+ virtual State GetLastState() OVERRIDE;
+ virtual void Flush(int32 put_offset) OVERRIDE;
+ 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 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;
+
+ // Get's the Id of the next transfer buffer that will be returned
+ // by CreateTransferBuffer. This is useful for testing expected ids.
+ int32 GetNextFreeTransferBufferId();
+
+ void DestroyTransferBufferHelper(int32 id);
+
+ virtual void OnFlush() = 0;
+
+ private:
+ scoped_array<int8> transfer_buffers_[kMaxTransferBuffers];
+ Buffer transfer_buffer_buffers_[kMaxTransferBuffers];
+ CommandBufferEntry* ring_buffer_;
+ Buffer ring_buffer_buffer_;
+ State state_;
+};
+
+class MockClientCommandBuffer : public MockCommandBufferBase {
+ public:
+ MockClientCommandBuffer();
+ virtual ~MockClientCommandBuffer();
+
+ // This is so we can use all the gmock functions when Flush is called.
+ MOCK_METHOD0(OnFlush, void());
+ MOCK_METHOD1(DestroyTransferBuffer, void(int32 id));
+
+ void DelegateToFake();
+};
+
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_CLIENT_CLIENT_TEST_HELPER_H_
+
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 2428c1e..8f1e415 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -11,6 +11,7 @@
#include <GLES2/gl2ext.h>
#include "../client/mapped_memory.h"
#include "../client/program_info_manager.h"
+#include "../client/transfer_buffer.h"
#include "../common/gles2_cmd_utils.h"
#include "../common/id_allocator.h"
#include "../common/trace_event.h"
@@ -432,7 +433,7 @@ class ClientSideBufferHelper {
}
// Returns true if buffers were setup.
- void SetupSimualtedClientSideBuffers(
+ void SetupSimulatedClientSideBuffers(
GLES2Implementation* gl,
GLES2CmdHelper* gl_helper,
GLsizei num_elements) {
@@ -535,87 +536,9 @@ class ClientSideBufferHelper {
DISALLOW_COPY_AND_ASSIGN(ClientSideBufferHelper);
};
-AlignedRingBuffer::~AlignedRingBuffer() {
-}
-
-TransferBuffer::TransferBuffer(
- CommandBufferHelper* helper,
- int32 buffer_id,
- void* buffer,
- size_t buffer_size,
- size_t result_size,
- unsigned int alignment)
- : helper_(helper),
- buffer_size_(buffer_size),
- result_size_(result_size),
- alignment_(alignment),
- usable_(true) {
- Setup(buffer_id, buffer);
-}
-
-TransferBuffer::~TransferBuffer() {
-}
-
-void TransferBuffer::Setup(int32 buffer_id, void* buffer) {
- GPU_CHECK(!ring_buffer_.get());
- ring_buffer_.reset(new AlignedRingBuffer(
- alignment_,
- buffer_id,
- result_size_,
- buffer_size_ - result_size_,
- helper_,
- static_cast<char*>(buffer) + result_size_));
- buffer_id_ = buffer_id;
- result_buffer_ = buffer;
- result_shm_offset_ = 0;
-}
-
-void TransferBuffer::Free() {
- if (buffer_id_) {
- // TODO(gman): should we check the memory is unused?
- helper_->command_buffer()->DestroyTransferBuffer(buffer_id_);
- buffer_id_ = 0;
- result_buffer_ = NULL;
- result_shm_offset_ = 0;
- ring_buffer_.reset();
- }
-}
-
-void TransferBuffer::AllocateRingBuffer() {
- if (!buffer_id_ && usable_) {
- int32 id = helper_->command_buffer()->CreateTransferBuffer(
- buffer_size_, -1);
- if (id == -1) {
- usable_ = false;
- return;
- }
- gpu::Buffer shm = helper_->command_buffer()->GetTransferBuffer(id);
- Setup(id, shm.ptr);
- }
-}
-
-AlignedRingBuffer* TransferBuffer::GetBuffer() {
- AllocateRingBuffer();
- return ring_buffer_.get();
-}
-
-void* TransferBuffer::GetResultBuffer() {
- AllocateRingBuffer();
- return result_buffer_;
-}
-
-int TransferBuffer::GetResultOffset() {
- AllocateRingBuffer();
- return result_shm_offset_;
-}
-
-int TransferBuffer::GetShmId() {
- AllocateRingBuffer();
- return buffer_id_;
-}
-
#if !defined(_MSC_VER)
const size_t GLES2Implementation::kMaxSizeOfSimpleResult;
+const unsigned int GLES2Implementation::kStartingOffset;
#endif
COMPILE_ASSERT(gpu::kInvalidResource == 0,
@@ -635,19 +558,11 @@ GLES2Implementation::SingleThreadChecker::~SingleThreadChecker() {
GLES2Implementation::GLES2Implementation(
GLES2CmdHelper* helper,
- size_t transfer_buffer_size,
- void* transfer_buffer,
- int32 transfer_buffer_id,
+ TransferBufferInterface* transfer_buffer,
bool share_resources,
bool bind_generates_resource)
: helper_(helper),
- transfer_buffer_(
- helper,
- transfer_buffer_id,
- transfer_buffer,
- transfer_buffer_size,
- GLES2Implementation::kStartingOffset,
- GLES2Implementation::kAlignment),
+ transfer_buffer_(transfer_buffer),
angle_pack_reverse_row_order_status(kUnknownExtensionStatus),
pack_alignment_(4),
unpack_alignment_(4),
@@ -665,18 +580,38 @@ GLES2Implementation::GLES2Implementation(
sharing_resources_(share_resources),
bind_generates_resource_(bind_generates_resource),
use_count_(0) {
+ GPU_DCHECK(helper);
+ GPU_DCHECK(transfer_buffer);
GPU_CLIENT_LOG_CODE_BLOCK({
debug_ = CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableGPUClientLogging);
});
memset(&reserved_ids_, 0, sizeof(reserved_ids_));
+}
+
+bool GLES2Implementation::Initialize(
+ unsigned int starting_transfer_buffer_size,
+ unsigned int min_transfer_buffer_size,
+ unsigned int max_transfer_buffer_size) {
+ GPU_DCHECK_GE(starting_transfer_buffer_size, min_transfer_buffer_size);
+ GPU_DCHECK_LE(starting_transfer_buffer_size, max_transfer_buffer_size);
+ GPU_DCHECK_GE(min_transfer_buffer_size, kStartingOffset);
+
+ if (!transfer_buffer_->Initialize(
+ starting_transfer_buffer_size,
+ kStartingOffset,
+ min_transfer_buffer_size,
+ max_transfer_buffer_size,
+ kAlignment)) {
+ return false;
+ }
mapped_memory_.reset(new MappedMemoryManager(helper_));
SetSharedMemoryChunkSizeMultiple(1024 * 1024 * 2);
- if (share_resources) {
- if (!bind_generates_resource) {
+ if (sharing_resources_) {
+ if (!bind_generates_resource_) {
for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
id_handlers_[i].reset(new StrictSharedIdHandler(
this, static_cast<id_namespaces::IdNamespaces>(i)));
@@ -734,6 +669,8 @@ GLES2Implementation::GLES2Implementation(
reserved_ids_[0],
reserved_ids_[1]));
#endif
+
+ return true;
}
GLES2Implementation::~GLES2Implementation() {
@@ -747,6 +684,18 @@ GLES2Implementation::~GLES2Implementation() {
Finish();
}
+void* GLES2Implementation::GetResultBuffer() {
+ return transfer_buffer_->GetResultBuffer();
+}
+
+int32 GLES2Implementation::GetResultShmId() {
+ return transfer_buffer_->GetShmId();
+}
+
+uint32 GLES2Implementation::GetResultShmOffset() {
+ return transfer_buffer_->GetResultOffset();
+}
+
void GLES2Implementation::SetSharedMemoryChunkSizeMultiple(
unsigned int multiple) {
mapped_memory_->set_chunk_size_multiple(multiple);
@@ -759,7 +708,7 @@ void GLES2Implementation::FreeUnusedSharedMemory() {
void GLES2Implementation::FreeEverything() {
Finish();
FreeUnusedSharedMemory();
- transfer_buffer_.Free();
+ transfer_buffer_->Free();
helper_->FreeRingBuffer();
}
@@ -861,27 +810,18 @@ bool GLES2Implementation::GetBucketContents(uint32 bucket_id,
uint32 size = *result;
data->resize(size);
if (size > 0u) {
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
- return false;
- }
- uint32 max_size = transfer_buffer->GetLargestFreeOrPendingSize();
uint32 offset = 0;
while (size) {
- uint32 part_size = std::min(max_size, size);
- void* buffer = transfer_buffer->Alloc(part_size);
- if (!buffer) {
+ ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
+ if (!buffer.valid()) {
return false;
}
helper_->GetBucketData(
- bucket_id, offset, part_size,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(buffer));
+ bucket_id, offset, buffer.size(), buffer.shm_id(), buffer.offset());
WaitForCmd();
- memcpy(&(*data)[offset], buffer, part_size);
- transfer_buffer->FreePendingToken(buffer, helper_->InsertToken());
- offset += part_size;
- size -= part_size;
+ memcpy(&(*data)[offset], buffer.address(), buffer.size());
+ offset += buffer.size();
+ size -= buffer.size();
}
// Free the bucket. This is not required but it does free up the memory.
// and we don't have to wait for the result so from the client's perspective
@@ -896,26 +836,18 @@ void GLES2Implementation::SetBucketContents(
GPU_DCHECK(data);
helper_->SetBucketSize(bucket_id, size);
if (size > 0u) {
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
- return;
- }
- uint32 max_size = transfer_buffer->GetLargestFreeOrPendingSize();
uint32 offset = 0;
while (size) {
- uint32 part_size = std::min(static_cast<size_t>(max_size), size);
- void* buffer = transfer_buffer->Alloc(part_size);
- if (!buffer) {
+ ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
+ if (!buffer.valid()) {
return;
}
- memcpy(buffer, static_cast<const int8*>(data) + offset, part_size);
+ memcpy(buffer.address(), static_cast<const int8*>(data) + offset,
+ buffer.size());
helper_->SetBucketData(
- bucket_id, offset, part_size,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(buffer));
- transfer_buffer->FreePendingToken(buffer, helper_->InsertToken());
- offset += part_size;
- size -= part_size;
+ bucket_id, offset, buffer.size(), buffer.shm_id(), buffer.offset());
+ offset += buffer.size();
+ size -= buffer.size();
}
}
}
@@ -1124,7 +1056,7 @@ void GLES2Implementation::DrawElements(
}
}
if (have_client_side) {
- client_side_buffer_helper_->SetupSimualtedClientSideBuffers(
+ client_side_buffer_helper_->SetupSimulatedClientSideBuffers(
this, helper_, num_elements);
}
helper_->DrawElements(mode, count, type, offset);
@@ -1190,27 +1122,18 @@ void GLES2Implementation::GenSharedIdsCHROMIUM(
<< namespace_id << ", " << id_offset << ", " << n << ", " <<
static_cast<void*>(ids) << ")");
TRACE_EVENT0("gpu", "GLES2::GenSharedIdsCHROMIUM");
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
- return;
- }
- GLsizei max_size = transfer_buffer->GetLargestFreeOrPendingSize();
- GLsizei max_num_per = max_size / sizeof(ids[0]);
while (n) {
- GLsizei num = std::min(n, max_num_per);
- GLint* id_buffer = transfer_buffer->AllocTyped<GLint>(num);
- if (!id_buffer) {
+ ScopedTransferBufferArray<GLint> id_buffer(n, helper_, transfer_buffer_);
+ if (!id_buffer.valid()) {
return;
}
helper_->GenSharedIdsCHROMIUM(
- namespace_id, id_offset, num,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(id_buffer));
+ namespace_id, id_offset, id_buffer.num_elements(),
+ id_buffer.shm_id(), id_buffer.offset());
WaitForCmd();
- memcpy(ids, id_buffer, sizeof(*ids) * num);
- transfer_buffer->FreePendingToken(id_buffer, helper_->InsertToken());
- n -= num;
- ids += num;
+ memcpy(ids, id_buffer.address(), sizeof(*ids) * id_buffer.num_elements());
+ n -= id_buffer.num_elements();
+ ids += id_buffer.num_elements();
}
GPU_CLIENT_LOG_CODE_BLOCK({
for (GLsizei i = 0; i < n; ++i) {
@@ -1230,27 +1153,18 @@ void GLES2Implementation::DeleteSharedIdsCHROMIUM(
}
});
TRACE_EVENT0("gpu", "GLES2::DeleteSharedIdsCHROMIUM");
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
- return;
- }
- GLsizei max_size = transfer_buffer->GetLargestFreeOrPendingSize();
- GLsizei max_num_per = max_size / sizeof(ids[0]);
while (n) {
- GLsizei num = std::min(n, max_num_per);
- GLint* id_buffer = transfer_buffer->AllocTyped<GLint>(num);
- if (!id_buffer) {
+ ScopedTransferBufferArray<GLint> id_buffer(n, helper_, transfer_buffer_);
+ if (!id_buffer.valid()) {
return;
}
- memcpy(id_buffer, ids, sizeof(*ids) * num);
+ memcpy(id_buffer.address(), ids, sizeof(*ids) * id_buffer.num_elements());
helper_->DeleteSharedIdsCHROMIUM(
- namespace_id, num,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(id_buffer));
+ namespace_id, id_buffer.num_elements(),
+ id_buffer.shm_id(), id_buffer.offset());
WaitForCmd();
- transfer_buffer->FreePendingToken(id_buffer, helper_->InsertToken());
- n -= num;
- ids += num;
+ n -= id_buffer.num_elements();
+ ids += id_buffer.num_elements();
}
}
@@ -1265,27 +1179,18 @@ void GLES2Implementation::RegisterSharedIdsCHROMIUM(
}
});
TRACE_EVENT0("gpu", "GLES2::RegisterSharedIdsCHROMIUM");
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
- return;
- }
- GLsizei max_size = transfer_buffer->GetLargestFreeOrPendingSize();
- GLsizei max_num_per = max_size / sizeof(ids[0]);
while (n) {
- GLsizei num = std::min(n, max_num_per);
- GLint* id_buffer = transfer_buffer->AllocTyped<GLint>(n);
- if (!id_buffer) {
+ ScopedTransferBufferArray<GLint> id_buffer(n, helper_, transfer_buffer_);
+ if (!id_buffer.valid()) {
return;
}
- memcpy(id_buffer, ids, sizeof(*ids) * n);
+ memcpy(id_buffer.address(), ids, sizeof(*ids) * id_buffer.num_elements());
helper_->RegisterSharedIdsCHROMIUM(
- namespace_id, n,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(id_buffer));
+ namespace_id, id_buffer.num_elements(),
+ id_buffer.shm_id(), id_buffer.offset());
WaitForCmd();
- transfer_buffer->FreePendingToken(id_buffer, helper_->InsertToken());
- n -= num;
- ids += num;
+ n -= id_buffer.num_elements();
+ ids += id_buffer.num_elements();
}
}
@@ -1438,28 +1343,26 @@ void GLES2Implementation::ShaderBinary(
SetGLError(GL_INVALID_VALUE, "glShaderBinary length < 0.");
return;
}
- GLsizei shader_id_size = n * sizeof(*shaders);
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
+ // TODO(gman): ShaderBinary should use buckets.
+ unsigned int shader_id_size = n * sizeof(*shaders);
+ ScopedTransferBufferArray<GLint> buffer(
+ shader_id_size + length, helper_, transfer_buffer_);
+ if (!buffer.valid() || buffer.num_elements() != shader_id_size + length) {
+ SetGLError(GL_OUT_OF_MEMORY, "glShaderBinary: out of memory.");
return;
}
- int8* buffer = transfer_buffer->AllocTyped<int8>(shader_id_size + length);
- if (!buffer) {
- return;
- }
- void* shader_ids = buffer;
- void* shader_data = buffer + shader_id_size;
+ void* shader_ids = buffer.elements();
+ void* shader_data = buffer.elements() + shader_id_size;
memcpy(shader_ids, shaders, shader_id_size);
memcpy(shader_data, binary, length);
helper_->ShaderBinary(
n,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(shader_ids),
+ buffer.shm_id(),
+ buffer.offset(),
binaryformat,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(shader_data),
+ buffer.shm_id(),
+ buffer.offset() + shader_id_size,
length);
- transfer_buffer->FreePendingToken(buffer, helper_->InsertToken());
}
void GLES2Implementation::PixelStorei(GLenum pname, GLint param) {
@@ -1555,11 +1458,6 @@ void GLES2Implementation::ShaderSource(
// Concatenate all the strings in to a bucket on the service.
helper_->SetBucketSize(kResultBucketId, total_size);
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
- return;
- }
- uint32 max_size = transfer_buffer->GetLargestFreeOrPendingSize();
uint32 offset = 0;
for (GLsizei ii = 0; ii <= count; ++ii) {
const char* src = ii < count ? source[ii] : "";
@@ -1567,19 +1465,16 @@ void GLES2Implementation::ShaderSource(
uint32 size = ii < count ?
(length ? static_cast<size_t>(length[ii]) : strlen(src)) : 1;
while (size) {
- uint32 part_size = std::min(size, max_size);
- void* buffer = transfer_buffer->Alloc(part_size);
- if (!buffer) {
+ ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
+ if (!buffer.valid()) {
return;
}
- memcpy(buffer, src, part_size);
- helper_->SetBucketData(kResultBucketId, offset, part_size,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(buffer));
- transfer_buffer->FreePendingToken(buffer, helper_->InsertToken());
- offset += part_size;
- src += part_size;
- size -= part_size;
+ memcpy(buffer.address(), src, buffer.size());
+ helper_->SetBucketData(kResultBucketId, offset, buffer.size(),
+ buffer.shm_id(), buffer.offset());
+ offset += buffer.size();
+ src += buffer.size();
+ size -= buffer.size();
}
}
}
@@ -1592,25 +1487,41 @@ void GLES2Implementation::ShaderSource(
void GLES2Implementation::BufferDataHelper(
GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- GLsizeiptr max_size = transfer_buffer->GetLargestFreeOrPendingSize();
- if (size > max_size || !data) {
+ if (size == 0) {
+ return;
+ }
+
+ if (size < 0) {
+ SetGLError(GL_INVALID_VALUE, "glBufferData: size < 0");
+ return;
+ }
+
+ // If there is no data just send BufferData
+ if (!data) {
helper_->BufferData(target, size, 0, 0, usage);
- if (data != NULL) {
- BufferSubDataHelper(target, 0, size, data);
- }
return;
}
- void* buffer = transfer_buffer->Alloc(size);
- memcpy(buffer, data, size);
- helper_->BufferData(
- target,
- size,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(buffer),
- usage);
- transfer_buffer->FreePendingToken(buffer, helper_->InsertToken());
+ // See if we can send all at once.
+ ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
+ if (!buffer.valid()) {
+ return;
+ }
+
+ if (buffer.size() >= static_cast<unsigned int>(size)) {
+ memcpy(buffer.address(), data, size);
+ helper_->BufferData(
+ target,
+ size,
+ buffer.shm_id(),
+ buffer.offset(),
+ usage);
+ return;
+ }
+
+ // Make the buffer with BufferData then send via BufferSubData
+ helper_->BufferData(target, size, 0, 0, usage);
+ BufferSubDataHelperImpl(target, 0, size, data, &buffer);
}
void GLES2Implementation::BufferData(
@@ -1635,26 +1546,31 @@ void GLES2Implementation::BufferSubDataHelper(
return;
}
+ ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
+ BufferSubDataHelperImpl(target, offset, size, data, &buffer);
+}
+
+void GLES2Implementation::BufferSubDataHelperImpl(
+ GLenum target, GLintptr offset, GLsizeiptr size, const void* data,
+ ScopedTransferBufferPtr* buffer) {
+ GPU_DCHECK(buffer);
+ GPU_DCHECK_GT(size, 0);
+
const int8* source = static_cast<const int8*>(data);
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
- return;
- }
- GLsizeiptr max_size = transfer_buffer->GetLargestFreeOrPendingSize();
while (size) {
- GLsizeiptr part_size = std::min(size, max_size);
- void* buffer = transfer_buffer->Alloc(part_size);
- if (!buffer) {
- return;
+ if (!buffer->valid() || buffer->size() == 0) {
+ buffer->Reset(size);
+ if (!buffer->valid()) {
+ return;
+ }
}
- memcpy(buffer, source, part_size);
- helper_->BufferSubData(target, offset, part_size,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(buffer));
- transfer_buffer->FreePendingToken(buffer, helper_->InsertToken());
- offset += part_size;
- source += part_size;
- size -= part_size;
+ memcpy(buffer->address(), source, buffer->size());
+ helper_->BufferSubData(
+ target, offset, buffer->size(), buffer->shm_id(), buffer->offset());
+ offset += buffer->size();
+ source += buffer->size();
+ size -= buffer->size();
+ buffer->Release();
}
}
@@ -1783,42 +1699,44 @@ void GLES2Implementation::TexImage2D(
return;
}
- // Check if we can send it all at once.
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
- return;
- }
- unsigned int max_size = transfer_buffer->GetLargestFreeOrPendingSize();
- if (size > max_size || !pixels) {
- // No, so send it using TexSubImage2D.
+ // If there's no data just issue TexImage2D
+ if (!pixels) {
helper_->TexImage2D(
target, level, internalformat, width, height, border, format, type,
0, 0);
- if (pixels) {
- TexSubImage2DImpl(
- target, level, 0, 0, width, height, format, type, pixels, GL_TRUE);
- }
return;
}
- void* buffer = transfer_buffer->Alloc(size);
- if (!buffer) {
+ // Check if we can send it all at once.
+ ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
+ if (!buffer.valid()) {
return;
}
- bool copy_success = true;
- if (unpack_flip_y_) {
- copy_success = CopyRectToBufferFlipped(
- pixels, width, height, format, type, buffer);
- } else {
- memcpy(buffer, pixels, size);
- }
- if (copy_success) {
- helper_->TexImage2D(
- target, level, internalformat, width, height, border, format, type,
- transfer_buffer->GetShmId(), transfer_buffer->GetOffset(buffer));
+ if (buffer.size() >= size) {
+ bool copy_success = true;
+ if (unpack_flip_y_) {
+ copy_success = CopyRectToBufferFlipped(
+ pixels, width, height, format, type, buffer.address());
+ } else {
+ memcpy(buffer.address(), pixels, size);
+ }
+
+ if (copy_success) {
+ helper_->TexImage2D(
+ target, level, internalformat, width, height, border, format, type,
+ buffer.shm_id(), buffer.offset());
+ }
+ return;
}
- transfer_buffer->FreePendingToken(buffer, helper_->InsertToken());
+
+ // No, so send it using TexSubImage2D.
+ helper_->TexImage2D(
+ target, level, internalformat, width, height, border, format, type,
+ 0, 0);
+ TexSubImage2DImpl(
+ target, level, 0, 0, width, height, format, type, pixels, GL_TRUE,
+ &buffer);
}
void GLES2Implementation::TexSubImage2D(
@@ -1833,15 +1751,7 @@ void GLES2Implementation::TexSubImage2D(
<< GLES2Util::GetStringTextureFormat(format) << ", "
<< GLES2Util::GetStringPixelType(type) << ", "
<< static_cast<const void*>(pixels) << ")");
- TexSubImage2DImpl(
- target, level, xoffset, yoffset, width, height, format, type, pixels,
- GL_FALSE);
-}
-void GLES2Implementation::TexSubImage2DImpl(
- GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
- GLsizei height, GLenum format, GLenum type, const void* pixels,
- GLboolean internal) {
if (level < 0 || height < 0 || width < 0) {
SetGLError(GL_INVALID_VALUE, "glTexSubImage2D dimension < 0");
return;
@@ -1849,12 +1759,41 @@ void GLES2Implementation::TexSubImage2DImpl(
if (height == 0 || width == 0) {
return;
}
- const int8* source = static_cast<const int8*>(pixels);
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
+
+ uint32 temp_size;
+ if (!GLES2Util::ComputeImageDataSize(
+ width, height, format, type, unpack_alignment_, &temp_size)) {
+ SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large");
return;
}
- GLsizeiptr max_size = transfer_buffer->GetLargestFreeOrPendingSize();
+
+ ScopedTransferBufferPtr buffer(temp_size, helper_, transfer_buffer_);
+ TexSubImage2DImpl(
+ target, level, xoffset, yoffset, width, height, format, type, pixels,
+ GL_FALSE, &buffer);
+}
+
+static GLint ComputeNumRowsThatFitInBuffer(
+ GLsizeiptr padded_row_size, GLsizeiptr unpadded_row_size,
+ unsigned int size) {
+ GPU_DCHECK_GE(unpadded_row_size, 0);
+ if (padded_row_size == 0) {
+ return 1;
+ }
+ GLint num_rows = size / padded_row_size;
+ return num_rows + (size - num_rows * padded_row_size) / unpadded_row_size;
+}
+
+void GLES2Implementation::TexSubImage2DImpl(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+ GLsizei height, GLenum format, GLenum type, const void* pixels,
+ GLboolean internal, ScopedTransferBufferPtr* buffer) {
+ GPU_DCHECK(buffer);
+ GPU_DCHECK_GE(level, 0);
+ GPU_DCHECK_GT(height, 0);
+ GPU_DCHECK_GT(width, 0);
+
+ const int8* source = static_cast<const int8*>(pixels);
uint32 temp_size;
if (!GLES2Util::ComputeImageDataSize(
width, 1, format, type, unpack_alignment_, &temp_size)) {
@@ -1874,70 +1813,37 @@ void GLES2Implementation::TexSubImage2DImpl(
}
GLint original_yoffset = yoffset;
- if (padded_row_size <= max_size) {
- // Transfer by rows.
- GLint max_rows = max_size / std::max(padded_row_size,
- static_cast<GLsizeiptr>(1));
- while (height) {
- GLint num_rows = std::min(height, max_rows);
- GLsizeiptr part_size =
- (num_rows - 1) * padded_row_size + unpadded_row_size;
- void* buffer = transfer_buffer->Alloc(part_size);
- if (!buffer) {
+ // Transfer by rows.
+ while (height) {
+ unsigned int desired_size =
+ padded_row_size * (height - 1) + unpadded_row_size;
+ if (!buffer->valid() || buffer->size() == 0) {
+ buffer->Reset(desired_size);
+ if (!buffer->valid()) {
return;
}
- GLint y;
- if (unpack_flip_y_) {
- CopyRectToBufferFlipped(
- source, width, num_rows, format, type, buffer);
- // GPU_DCHECK(copy_success); // can't check this because bot fails!
- y = original_yoffset + height - num_rows;
- } else {
- memcpy(buffer, source, part_size);
- y = yoffset;
- }
- helper_->TexSubImage2D(
- target, level, xoffset, y, width, num_rows, format, type,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(buffer), internal);
- transfer_buffer->FreePendingToken(buffer, helper_->InsertToken());
- yoffset += num_rows;
- source += num_rows * padded_row_size;
- height -= num_rows;
}
- } else {
- // Transfer by sub rows. Because GL has no maximum texture dimensions.
- uint32 temp;
- GLES2Util::ComputeImageDataSize(
- 1, 1, format, type, unpack_alignment_, &temp);
- GLsizeiptr element_size = temp;
- max_size -= max_size % element_size;
- GLint max_sub_row_pixels = max_size / element_size;
- for (; height; --height) {
- GLint temp_width = width;
- GLint temp_xoffset = xoffset;
- const int8* row_source = source;
- while (temp_width) {
- GLint num_pixels = std::min(width, max_sub_row_pixels);
- GLsizeiptr part_size = num_pixels * element_size;
- void* buffer = transfer_buffer->Alloc(part_size);
- if (!buffer) {
- return;
- }
- memcpy(buffer, row_source, part_size);
- GLint y = unpack_flip_y_ ? (original_yoffset + height - 1) : yoffset;
- helper_->TexSubImage2D(
- target, level, temp_xoffset, y, num_pixels, 1, format, type,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(buffer), internal);
- transfer_buffer->FreePendingToken(buffer, helper_->InsertToken());
- row_source += part_size;
- temp_xoffset += num_pixels;
- temp_width -= num_pixels;
- }
- ++yoffset;
- source += padded_row_size;
+
+ GLint num_rows = ComputeNumRowsThatFitInBuffer(
+ padded_row_size, unpadded_row_size, buffer->size());
+ num_rows = std::min(num_rows, height);
+ GLint y;
+ if (unpack_flip_y_) {
+ CopyRectToBufferFlipped(
+ source, width, num_rows, format, type, buffer->address());
+ y = original_yoffset + height - num_rows;
+ } else {
+ temp_size = padded_row_size * (num_rows - 1) + unpadded_row_size;
+ memcpy(buffer->address(), source, temp_size);
+ y = yoffset;
}
+ helper_->TexSubImage2D(
+ target, level, xoffset, y, width, num_rows, format, type,
+ buffer->shm_id(), buffer->offset(), internal);
+ buffer->Release();
+ yoffset += num_rows;
+ source += num_rows * padded_row_size;
+ height -= num_rows;
}
}
@@ -2095,19 +2001,15 @@ void GLES2Implementation::GetAttachedShaders(
TRACE_EVENT0("gpu", "GLES2::GetAttachedShaders");
typedef gles2::GetAttachedShaders::Result Result;
uint32 size = Result::ComputeSize(maxcount);
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
- return;
- }
- Result* result = transfer_buffer->AllocTyped<Result>(size);
+ Result* result = static_cast<Result*>(transfer_buffer_->Alloc(size));
if (!result) {
return;
}
result->SetNumResults(0);
helper_->GetAttachedShaders(
program,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(result),
+ transfer_buffer_->GetShmId(),
+ transfer_buffer_->GetOffset(result),
size);
int32 token = helper_->InsertToken();
WaitForCmd();
@@ -2120,7 +2022,7 @@ void GLES2Implementation::GetAttachedShaders(
GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
}
});
- transfer_buffer->FreePendingToken(result, token);
+ transfer_buffer_->FreePendingToken(result, token);
}
void GLES2Implementation::GetShaderPrecisionFormat(
@@ -2281,16 +2183,8 @@ void GLES2Implementation::ReadPixels(
TRACE_EVENT0("gpu", "GLES2::ReadPixels");
typedef gles2::ReadPixels::Result Result;
- Result* result = GetResultAs<Result*>();
- if (!result) {
- return;
- }
+
int8* dest = reinterpret_cast<int8*>(pixels);
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
- return;
- }
- GLsizeiptr max_size = transfer_buffer->GetLargestFreeOrPendingSize();
uint32 temp_size;
if (!GLES2Util::ComputeImageDataSize(
width, 1, format, type, pack_alignment_, &temp_size)) {
@@ -2303,107 +2197,61 @@ void GLES2Implementation::ReadPixels(
SetGLError(GL_INVALID_VALUE, "glReadPixels: size too large.");
return;
}
- GLsizeiptr padded_row_size = temp_size - unpadded_row_size;
+ GLsizei padded_row_size = temp_size - unpadded_row_size;
if (padded_row_size < 0 || unpadded_row_size < 0) {
SetGLError(GL_INVALID_VALUE, "glReadPixels: size too large.");
return;
}
- // Check if we have enough space to transfer at least an entire row.
- if (padded_row_size <= max_size) {
- // Transfer by rows.
- // The max rows we can transfer.
- GLint max_rows = max_size / std::max(padded_row_size,
- static_cast<GLsizeiptr>(1));
- while (height) {
- // Compute how many rows to transfer.
- GLint num_rows = std::min(height, max_rows);
- // Compute how much space those rows will take. The last row will not
- // include padding.
- GLsizeiptr part_size =
- unpadded_row_size + padded_row_size * (num_rows - 1);
- void* buffer = transfer_buffer->Alloc(part_size);
- if (!buffer) {
- return;
+ // Transfer by rows.
+ // The max rows we can transfer.
+ while (height) {
+ GLsizei desired_size = padded_row_size * height - 1 + unpadded_row_size;
+ ScopedTransferBufferPtr buffer(desired_size, helper_, transfer_buffer_);
+ if (!buffer.valid()) {
+ return;
+ }
+ GLint num_rows = ComputeNumRowsThatFitInBuffer(
+ padded_row_size, unpadded_row_size, buffer.size());
+ num_rows = std::min(num_rows, height);
+ // NOTE: We must look up the address of the result area AFTER allocation
+ // of the transfer buffer since the transfer buffer may be reallocated.
+ Result* result = GetResultAs<Result*>();
+ if (!result) {
+ return;
+ }
+ *result = 0; // mark as failed.
+ helper_->ReadPixels(
+ xoffset, yoffset, width, num_rows, format, type,
+ buffer.shm_id(), buffer.offset(),
+ GetResultShmId(), GetResultShmOffset());
+ WaitForCmd();
+ if (*result != 0) {
+ // when doing a y-flip we have to iterate through top-to-bottom chunks
+ // of the dst. The service side handles reversing the rows within a
+ // chunk.
+ int8* rows_dst;
+ if (pack_reverse_row_order_) {
+ rows_dst = dest + (height - num_rows) * padded_row_size;
+ } else {
+ rows_dst = dest;
}
- *result = 0; // mark as failed.
- helper_->ReadPixels(
- xoffset, yoffset, width, num_rows, format, type,
- transfer_buffer->GetShmId(), transfer_buffer->GetOffset(buffer),
- GetResultShmId(), GetResultShmOffset());
- WaitForCmd();
- if (*result != 0) {
- // when doing a y-flip we have to iterate through top-to-bottom chunks
- // of the dst. The service side handles reversing the rows within a
- // chunk.
- int8* rows_dst;
- if (pack_reverse_row_order_) {
- rows_dst = dest + (height - num_rows) * padded_row_size;
- } else {
- rows_dst = dest;
- }
- // We have to copy 1 row at a time to avoid writing pad bytes.
- const int8* src = static_cast<const int8*>(buffer);
- for (GLint yy = 0; yy < num_rows; ++yy) {
- memcpy(rows_dst, src, unpadded_row_size);
- rows_dst += padded_row_size;
- src += padded_row_size;
- }
- if (!pack_reverse_row_order_) {
- dest = rows_dst;
- }
+ // We have to copy 1 row at a time to avoid writing pad bytes.
+ const int8* src = static_cast<const int8*>(buffer.address());
+ for (GLint yy = 0; yy < num_rows; ++yy) {
+ memcpy(rows_dst, src, unpadded_row_size);
+ rows_dst += padded_row_size;
+ src += padded_row_size;
}
- transfer_buffer->FreePendingToken(buffer, helper_->InsertToken());
- // If it was not marked as successful exit.
- if (*result == 0) {
- return;
+ if (!pack_reverse_row_order_) {
+ dest = rows_dst;
}
- yoffset += num_rows;
- height -= num_rows;
}
- } else {
- // Transfer by sub rows. Because GL has no maximum texture dimensions.
- GLES2Util::ComputeImageDataSize(
- 1, 1, format, type, pack_alignment_, &temp_size);
- GLsizeiptr element_size = temp_size;
- max_size -= max_size % element_size;
- GLint max_sub_row_pixels = max_size / element_size;
- if (pack_reverse_row_order_) {
- // start at the last row when flipping y.
- dest = dest + (height - 1) * padded_row_size;
- }
- for (; height; --height) {
- GLint temp_width = width;
- GLint temp_xoffset = xoffset;
- int8* row_dest = dest;
- while (temp_width) {
- GLint num_pixels = std::min(width, max_sub_row_pixels);
- GLsizeiptr part_size = num_pixels * element_size;
- void* buffer = transfer_buffer->Alloc(part_size);
- if (!buffer) {
- return;
- }
- *result = 0; // mark as failed.
- helper_->ReadPixels(
- temp_xoffset, yoffset, temp_width, 1, format, type,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(buffer),
- GetResultShmId(), GetResultShmOffset());
- WaitForCmd();
- if (*result != 0) {
- memcpy(row_dest, buffer, part_size);
- }
- transfer_buffer->FreePendingToken(buffer, helper_->InsertToken());
- // If it was not marked as successful exit.
- if (*result == 0) {
- return;
- }
- row_dest += part_size;
- temp_xoffset += num_pixels;
- temp_width -= num_pixels;
- }
- ++yoffset;
- dest += pack_reverse_row_order_ ? -padded_row_size : padded_row_size;
+ // If it was not marked as successful exit.
+ if (*result == 0) {
+ return;
}
+ yoffset += num_rows;
+ height -= num_rows;
}
}
@@ -2615,7 +2463,7 @@ void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) {
bool have_client_side =
client_side_buffer_helper_->HaveEnabledClientSideBuffers();
if (have_client_side) {
- client_side_buffer_helper_->SetupSimualtedClientSideBuffers(
+ client_side_buffer_helper_->SetupSimulatedClientSideBuffers(
this, helper_, first + count);
}
#endif
@@ -2971,11 +2819,7 @@ void GLES2Implementation::GetMultipleIntegervCHROMIUM(
}
uint32 size_needed =
count * sizeof(pnames[0]) + num_results * sizeof(results[0]);
- AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer();
- if (!transfer_buffer) {
- return;
- }
- void* buffer = transfer_buffer->Alloc(size_needed);
+ void* buffer = transfer_buffer_->Alloc(size_needed);
if (!buffer) {
return;
}
@@ -2984,16 +2828,16 @@ void GLES2Implementation::GetMultipleIntegervCHROMIUM(
memcpy(pnames_buffer, pnames, count * sizeof(GLenum));
memset(results_buffer, 0, num_results * sizeof(GLint));
helper_->GetMultipleIntegervCHROMIUM(
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(pnames_buffer),
+ transfer_buffer_->GetShmId(),
+ transfer_buffer_->GetOffset(pnames_buffer),
count,
- transfer_buffer->GetShmId(),
- transfer_buffer->GetOffset(results_buffer),
+ transfer_buffer_->GetShmId(),
+ transfer_buffer_->GetOffset(results_buffer),
size);
WaitForCmd();
memcpy(results, results_buffer, size);
// TODO(gman): We should be able to free without a token.
- transfer_buffer->FreePendingToken(buffer, helper_->InsertToken());
+ transfer_buffer_->FreePendingToken(buffer, helper_->InsertToken());
GPU_CLIENT_LOG(" returned");
GPU_CLIENT_LOG_CODE_BLOCK({
for (int i = 0; i < num_results; ++i) {
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 0d1a633..d8adc44 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -74,12 +74,13 @@
namespace gpu {
class MappedMemoryManager;
+class ScopedTransferBufferPtr;
+class TransferBufferInterface;
namespace gles2 {
class ClientSideBufferHelper;
class ProgramInfoManager;
-class AlignedRingBuffer;
// Base class for IdHandlers
class IdHandlerInterface {
@@ -97,84 +98,6 @@ class IdHandlerInterface {
virtual bool MarkAsUsedForBind(GLuint id) = 0;
};
-// Wraps RingBufferWrapper to provide aligned allocations.
-class AlignedRingBuffer : public RingBufferWrapper {
- public:
- AlignedRingBuffer(
- unsigned int alignment,
- int32 shm_id,
- RingBuffer::Offset base_offset,
- unsigned int size,
- CommandBufferHelper* helper,
- void* base)
- : RingBufferWrapper(base_offset, size, helper, base),
- alignment_(alignment),
- shm_id_(shm_id) {
- }
- ~AlignedRingBuffer();
-
- // Overrriden from RingBufferWrapper
- void* Alloc(unsigned int size) {
- return RingBufferWrapper::Alloc(RoundToAlignment(size));
- }
-
- template <typename T>T* AllocTyped(unsigned int count) {
- return static_cast<T*>(Alloc(count * sizeof(T)));
- }
-
- int32 GetShmId() const {
- return shm_id_;
- }
-
- private:
- unsigned int RoundToAlignment(unsigned int size) {
- return (size + alignment_ - 1) & ~(alignment_ - 1);
- }
-
- unsigned int alignment_;
- int32 shm_id_;
-};
-
-// Manages the transfer buffer.
-class TransferBuffer {
- public:
- TransferBuffer(
- CommandBufferHelper* helper,
- int32 buffer_id,
- void* buffer,
- size_t buffer_size,
- size_t result_size,
- unsigned int alignment);
- ~TransferBuffer();
-
- AlignedRingBuffer* GetBuffer();
- int GetShmId();
- void* GetResultBuffer();
- int GetResultOffset();
-
- void Free();
-
- // This is for unit testing only.
- bool HaveBuffer() const {
- return buffer_id_ != 0;
- }
-
- private:
- void AllocateRingBuffer();
-
- void Setup(int32 buffer_id, void* buffer);
-
- CommandBufferHelper* helper_;
- scoped_ptr<AlignedRingBuffer> ring_buffer_;
- unsigned int buffer_size_;
- unsigned int result_size_;
- unsigned int alignment_;
- int32 buffer_id_;
- void* result_buffer_;
- uint32 result_shm_offset_;
- bool usable_;
-};
-
// This class emulates GLES2 over command buffers. It can be used by a client
// program so that the program does not need deal with shared memory and command
// buffer management. See gl2_lib.h. Note that there is a performance gain to
@@ -235,14 +158,17 @@ class GLES2Implementation {
GLES2Implementation(
GLES2CmdHelper* helper,
- size_t transfer_buffer_size,
- void* transfer_buffer,
- int32 transfer_buffer_id,
+ TransferBufferInterface* transfer_buffer,
bool share_resources,
bool bind_generates_resource);
~GLES2Implementation();
+ bool Initialize(
+ unsigned int starting_transfer_buffer_size,
+ unsigned int min_transfer_buffer_size,
+ unsigned int max_transfer_buffer_size);
+
// The GLES2CmdHelper being used by this GLES2Implementation. You can use
// this to issue cmds at a lower level for certain kinds of optimization.
GLES2CmdHelper* helper() const {
@@ -402,16 +328,12 @@ class GLES2Implementation {
// Gets the value of the result.
template <typename T>
T GetResultAs() {
- return static_cast<T>(transfer_buffer_.GetResultBuffer());
+ return static_cast<T>(GetResultBuffer());
}
- int32 GetResultShmId() {
- return transfer_buffer_.GetShmId();
- }
-
- uint32 GetResultShmOffset() {
- return transfer_buffer_.GetResultOffset();
- }
+ void* GetResultBuffer();
+ int32 GetResultShmId();
+ uint32 GetResultShmOffset();
// Lazily determines if GL_ANGLE_pack_reverse_row_order is available
bool IsAnglePackReverseRowOrderAvailable();
@@ -472,6 +394,9 @@ class GLES2Implementation {
GLenum target, GLsizeiptr size, const void* data, GLenum usage);
void BufferSubDataHelper(
GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
+ void BufferSubDataHelperImpl(
+ GLenum target, GLintptr offset, GLsizeiptr size, const void* data,
+ ScopedTransferBufferPtr* buffer);
// Helper for GetVertexAttrib
bool GetVertexAttribHelper(GLuint index, GLenum pname, uint32* param);
@@ -485,7 +410,7 @@ class GLES2Implementation {
void TexSubImage2DImpl(
GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
GLsizei height, GLenum format, GLenum type, const void* pixels,
- GLboolean internal);
+ GLboolean internal, ScopedTransferBufferPtr* buffer);
// Helpers for query functions.
bool GetHelper(GLenum pname, GLint* params);
@@ -507,8 +432,8 @@ class GLES2Implementation {
GLES2Util util_;
GLES2CmdHelper* helper_;
+ TransferBufferInterface* transfer_buffer_;
scoped_ptr<IdHandlerInterface> id_handlers_[id_namespaces::kNumIdNamespaces];
- TransferBuffer transfer_buffer_;
std::string last_error_;
std::queue<int32> swap_buffers_tokens_;
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index 46f60ae..c354e9e 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Tests for the Command Buffer Helper.
+// Tests for GLES2Implementation.
#include "gpu/command_buffer/client/gles2_implementation.h"
#include <GLES2/gl2ext.h>
+#include "gpu/command_buffer/client/client_test_helper.h"
+#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/command_buffer.h"
+#include "gpu/command_buffer/common/compiler_specific.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -22,162 +25,19 @@ using testing::InSequence;
using testing::Invoke;
using testing::Mock;
using testing::Sequence;
+using testing::StrictMock;
using testing::Truly;
using testing::Return;
namespace gpu {
-
-class GLES2MockCommandBufferHelper : public CommandBuffer {
- public:
- static const int32 kTransferBufferBaseId = 0x123;
- static const int32 kMaxTransferBuffers = 6;
-
- GLES2MockCommandBufferHelper() { }
- virtual ~GLES2MockCommandBufferHelper() { }
-
- // CommandBuffer implementation:
- virtual bool Initialize() {
- return true;
- }
-
- virtual State GetState() {
- return state_;
- }
-
- virtual State GetLastState() {
- return state_;
- }
-
- virtual void Flush(int32 put_offset) {
- state_.put_offset = put_offset;
- }
-
- virtual State FlushSync(int32 put_offset, int32 last_known_get) {
- state_.put_offset = put_offset;
- state_.get_offset = put_offset;
- // Warning: This is a hack. We just happen to know that the default
- // transfer buffer will be the first transfer buffer.
- OnFlush(transfer_buffer_buffers_[0].ptr);
- return state_;
- }
-
- virtual void SetGetBuffer(int transfer_buffer_id) {
- ring_buffer_buffer_ = GetTransferBuffer(transfer_buffer_id);
- ring_buffer_ = static_cast<CommandBufferEntry*>(ring_buffer_buffer_.ptr);
- state_.num_entries = ring_buffer_buffer_.size / sizeof(ring_buffer_[0]);
- state_.token = 10000; // All token checks in the tests should pass.
- }
-
- virtual void SetGetOffset(int32 get_offset) {
- state_.get_offset = get_offset;
- }
-
- // Get's the Id of the next transfer buffer that will be returned
- // by CreateTransferBuffer. This is useful for testing expected ids.
- int32 GetNextFreeTransferBufferId() {
- for (size_t ii = 0; ii < arraysize(transfer_buffers_); ++ii) {
- if (!transfer_buffers_[ii].get()) {
- return kTransferBufferBaseId + ii;
- }
- }
- return -1;
- }
-
- virtual int32 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 id;
- }
-
- void DestroyTransferBufferHelper(int32 id) {
- GPU_DCHECK_GE(id, kTransferBufferBaseId);
- GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers);
- id -= kTransferBufferBaseId;
- transfer_buffers_[id].reset();
- transfer_buffer_buffers_[id] = Buffer();
- }
-
- virtual Buffer GetTransferBuffer(int32 id) {
- GPU_DCHECK_GE(id, kTransferBufferBaseId);
- GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers);
- return transfer_buffer_buffers_[id - kTransferBufferBaseId];
- }
-
- virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory,
- size_t size,
- int32 id_request) {
- GPU_NOTREACHED();
- return -1;
- }
-
- virtual void SetToken(int32 token) {
- GPU_NOTREACHED();
- state_.token = token;
- }
-
- virtual void SetParseError(error::Error error) {
- GPU_NOTREACHED();
- state_.error = error;
- }
-
- virtual void SetContextLostReason(error::ContextLostReason reason) {
- GPU_NOTREACHED();
- state_.context_lost_reason = reason;
- }
-
- virtual void OnFlush(void* transfer_buffer) = 0;
-
- private:
- scoped_array<int8> transfer_buffers_[kMaxTransferBuffers];
- Buffer transfer_buffer_buffers_[kMaxTransferBuffers];
- CommandBufferEntry* ring_buffer_;
- Buffer ring_buffer_buffer_;
- State state_;
-};
-
-class MockGLES2CommandBuffer : public GLES2MockCommandBufferHelper {
- public:
- MockGLES2CommandBuffer() {
- DelegateToFake();
- }
-
- virtual ~MockGLES2CommandBuffer() {
- }
-
- // This is so we can use all the gmock functions when Flush is called.
- MOCK_METHOD1(OnFlush, void(void* result));
- MOCK_METHOD1(DestroyTransferBuffer, void(int32 id));
-
- void DelegateToFake() {
- ON_CALL(*this, DestroyTransferBuffer(_))
- .WillByDefault(Invoke(
- this, &GLES2MockCommandBufferHelper::DestroyTransferBufferHelper));
- }
-};
-
-// GCC requires these declarations, but MSVC requires they not be present
-#ifndef _MSC_VER
-const int32 GLES2MockCommandBufferHelper::kTransferBufferBaseId;
-const int32 GLES2MockCommandBufferHelper::kMaxTransferBuffers;
-#endif
-
namespace gles2 {
-ACTION_P(SetMemory, obj) {
- memcpy(arg0, &obj, sizeof(obj));
+ACTION_P2(SetMemory, dst, obj) {
+ memcpy(dst, &obj, sizeof(obj));
}
-ACTION_P2(SetMemoryAtOffset, offset, obj) {
- memcpy(static_cast<char*>(arg0) + offset, &obj, sizeof(obj));
-}
-
-ACTION_P3(SetMemoryAtOffsetFromArray, offset, array, size) {
- memcpy(static_cast<char*>(arg0) + offset, array, size);
+ACTION_P3(SetMemoryFromArray, dst, array, size) {
+ memcpy(dst, array, size);
}
// Used to help set the transfer buffer result to SizedResult of a single value.
@@ -216,211 +76,229 @@ struct Str7 {
};
#pragma pack(pop)
-class GLES2CommandBufferTestBase : public testing::Test {
- protected:
- static const int32 kNumCommandEntries = 400;
- static const int32 kCommandBufferSizeBytes =
- kNumCommandEntries * sizeof(CommandBufferEntry);
- static const size_t kTransferBufferSize = 256;
- static const uint8 kInitialValue = 0xBD;
+class MockTransferBuffer : public TransferBufferInterface {
+ public:
+ struct ExpectedMemoryInfo {
+ uint32 offset;
+ int32 id;
+ uint8* ptr;
+ };
- GLES2CommandBufferTestBase()
- : commands_(NULL),
- token_(0),
- offset_(0),
- initial_offset_(0),
- alignment_(0),
- transfer_buffer_id_(-1) {
+ MockTransferBuffer(
+ CommandBuffer* command_buffer,
+ unsigned int size,
+ unsigned int result_size,
+ unsigned int alignment)
+ : command_buffer_(command_buffer),
+ size_(size),
+ result_size_(result_size),
+ alignment_(alignment),
+ actual_buffer_index_(0),
+ expected_buffer_index_(0),
+ last_alloc_(NULL),
+ expected_offset_(result_size),
+ actual_offset_(result_size) {
+ // We have to allocate the buffers here because
+ // 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);
+ EXPECT_NE(-1, buffer_ids_[ii]);
+ buffers_[ii] = command_buffer_->GetTransferBuffer(buffer_ids_[ii]);
+ }
}
- void SetupCommandBuffer(unsigned int offset, unsigned alignment) {
- initial_offset_ = offset;
- offset_ = offset;
- alignment_ = alignment;
-
- command_buffer_.reset(new MockGLES2CommandBuffer());
- command_buffer_->Initialize();
+ virtual ~MockTransferBuffer() { }
+
+ bool Initialize(
+ unsigned int starting_buffer_size,
+ unsigned int result_size,
+ unsigned int /* min_buffer_size */,
+ unsigned int /* max_buffer_size */,
+ unsigned int alignment) OVERRIDE;
+ virtual int GetShmId() OVERRIDE;
+ virtual void* GetResultBuffer() OVERRIDE;
+ virtual int GetResultOffset() OVERRIDE;
+ virtual void Free() OVERRIDE;
+ virtual bool HaveBuffer() const OVERRIDE;
+ virtual void* AllocUpTo(
+ unsigned int size, unsigned int* size_allocated) OVERRIDE;
+ virtual void* Alloc(unsigned int size) OVERRIDE;
+ virtual RingBuffer::Offset GetOffset(void* pointer) const OVERRIDE;
+ virtual void FreePendingToken(void* p, unsigned int /* token */) OVERRIDE;
- transfer_buffer_id_ =
- command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1);
- transfer_buffer_ = command_buffer_->GetTransferBuffer(transfer_buffer_id_);
- ClearTransferBuffer();
-
- helper_.reset(new GLES2CmdHelper(command_buffer_.get()));
- helper_->Initialize(kCommandBufferSizeBytes);
+ size_t MaxTransferBufferSize() {
+ return size_ - result_size_;
}
- const void* GetPut() {
- return helper_->GetSpace(0);
+ unsigned int RoundToAlignment(unsigned int size) {
+ return (size + alignment_ - 1) & ~(alignment_ - 1);
}
- size_t MaxTransferBufferSize() {
- return kTransferBufferSize - initial_offset_;
+ bool InSync() {
+ return expected_buffer_index_ == actual_buffer_index_;
}
- void ClearCommands() {
- Buffer ring_buffer = helper_->get_ring_buffer();
- memset(ring_buffer.ptr, kInitialValue, ring_buffer.size);
+ ExpectedMemoryInfo GetExpectedMemory(size_t size) {
+ ExpectedMemoryInfo mem;
+ mem.offset = AllocateExpectedTransferBuffer(size);
+ mem.id = GetExpectedTransferBufferId();
+ mem.ptr = static_cast<uint8*>(
+ GetExpectedTransferAddressFromOffset(mem.offset, size));
+ return mem;
}
- bool NoCommandsWritten() {
- return static_cast<const uint8*>(static_cast<const void*>(commands_))[0] ==
- kInitialValue;
+ ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
+ ExpectedMemoryInfo mem;
+ mem.offset = GetExpectedResultBufferOffset();
+ mem.id = GetExpectedResultBufferId();
+ mem.ptr = static_cast<uint8*>(
+ GetExpectedTransferAddressFromOffset(mem.offset, size));
+ return mem;
}
- void ClearTransferBuffer() {
- memset(transfer_buffer_.ptr, kInitialValue, kTransferBufferSize);
+ private:
+ static const int kNumBuffers = 2;
+
+ uint8* actual_buffer() const {
+ return static_cast<uint8*>(buffers_[actual_buffer_index_].ptr);
}
- unsigned int RoundToAlignment(unsigned int size) {
- return (size + alignment_ - 1) & ~(alignment_ - 1);
+ uint8* expected_buffer() const {
+ return static_cast<uint8*>(buffers_[expected_buffer_index_].ptr);
}
- int GetNextToken() {
- return ++token_;
+ uint32 AllocateExpectedTransferBuffer(size_t size) {
+ EXPECT_LE(size, MaxTransferBufferSize());
+
+ // Toggle which buffer we get each time to simulate the buffer being
+ // reallocated.
+ expected_buffer_index_ = (expected_buffer_index_ + 1) % kNumBuffers;
+
+ if (expected_offset_ + size > size_) {
+ expected_offset_ = result_size_;
+ }
+ uint32 offset = expected_offset_;
+ expected_offset_ += RoundToAlignment(size);
+
+ // Make sure each buffer has a different offset.
+ return offset + expected_buffer_index_ * alignment_;
}
- int32 GetNextFreeTransferBufferId() {
- return command_buffer_->GetNextFreeTransferBufferId();
+ void* GetExpectedTransferAddressFromOffset(uint32 offset, size_t size) {
+ EXPECT_GE(offset, expected_buffer_index_ * alignment_);
+ EXPECT_LE(offset + size, size_ + expected_buffer_index_ * alignment_);
+ return expected_buffer() + offset;
}
- uint32 AllocateTransferBuffer(size_t size) {
- if (offset_ + size > kTransferBufferSize) {
- offset_ = initial_offset_;
- }
- uint32 offset = offset_;
- offset_ += RoundToAlignment(size);
- return offset;
+ int GetExpectedResultBufferId() {
+ return buffer_ids_[expected_buffer_index_];
}
- void* GetTransferAddressFromOffset(uint32 offset, size_t size) {
- EXPECT_LE(offset + size, transfer_buffer_.size);
- return static_cast<int8*>(transfer_buffer_.ptr) + offset;
+ uint32 GetExpectedResultBufferOffset() {
+ return expected_buffer_index_ * alignment_;
}
- template <typename T>
- T* GetTransferAddressFromOffsetAs(uint32 offset, size_t size) {
- return static_cast<T*>(GetTransferAddressFromOffset(offset, size));
+ int GetExpectedTransferBufferId() {
+ return buffer_ids_[expected_buffer_index_];
}
- Buffer transfer_buffer_;
- CommandBufferEntry* commands_;
- scoped_ptr<MockGLES2CommandBuffer> command_buffer_;
- scoped_ptr<GLES2CmdHelper> helper_;
- int token_;
- uint32 offset_;
- uint32 initial_offset_;
+ CommandBuffer* command_buffer_;
+ size_t size_;
+ size_t result_size_;
uint32 alignment_;
- int32 transfer_buffer_id_;
+ int buffer_ids_[kNumBuffers];
+ gpu::Buffer buffers_[kNumBuffers];
+ int actual_buffer_index_;
+ int expected_buffer_index_;
+ void* last_alloc_;
+ uint32 expected_offset_;
+ uint32 actual_offset_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer);
};
-// GCC requires these declarations, but MSVC requires they not be present
-#ifndef _MSC_VER
-const int32 GLES2CommandBufferTestBase::kNumCommandEntries;
-const int32 GLES2CommandBufferTestBase::kCommandBufferSizeBytes;
-const size_t GLES2CommandBufferTestBase::kTransferBufferSize;
-const uint8 GLES2CommandBufferTestBase::kInitialValue;
-#endif
+bool MockTransferBuffer::Initialize(
+ unsigned int starting_buffer_size,
+ unsigned int result_size,
+ unsigned int /* min_buffer_size */,
+ unsigned int /* max_buffer_size */,
+ unsigned int alignment) {
+ // Just check they match.
+ return size_ == starting_buffer_size &&
+ result_size_ == result_size &&
+ alignment_ == alignment;
+};
-class TransferBufferTest : public GLES2CommandBufferTestBase {
- protected:
- static const unsigned int kStartingOffset = 64;
- static const unsigned int kAlignment = 4;
+int MockTransferBuffer::GetShmId() {
+ return buffer_ids_[actual_buffer_index_];
+}
- TransferBufferTest() { }
+void* MockTransferBuffer::GetResultBuffer() {
+ return actual_buffer() + actual_buffer_index_ * alignment_;
+}
- virtual void SetUp() {
- SetupCommandBuffer(
- GLES2Implementation::kStartingOffset,
- GLES2Implementation::kAlignment);
+int MockTransferBuffer::GetResultOffset() {
+ return actual_buffer_index_ * alignment_;
+}
- transfer_buffer_id_ =
- command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1);
+void MockTransferBuffer::Free() {
+ GPU_NOTREACHED();
+}
- transfer_buffer_.reset(new TransferBuffer(
- helper_.get(),
- transfer_buffer_id_,
- GetTransferAddressFromOffset(0, 0),
- kTransferBufferSize,
- kStartingOffset,
- kAlignment));
- }
+bool MockTransferBuffer::HaveBuffer() const {
+ return true;
+}
- virtual void TearDown() {
- transfer_buffer_.reset();
- }
+void* MockTransferBuffer::AllocUpTo(
+ unsigned int size, unsigned int* size_allocated) {
+ EXPECT_TRUE(size_allocated != NULL);
+ EXPECT_TRUE(last_alloc_ == NULL);
- scoped_ptr<TransferBuffer> transfer_buffer_;
-};
+ // Toggle which buffer we get each time to simulate the buffer being
+ // reallocated.
+ actual_buffer_index_ = (actual_buffer_index_ + 1) % kNumBuffers;
-// GCC requires these declarations, but MSVC requires they not be present
-#ifndef _MSC_VER
-const unsigned int TransferBufferTest::kStartingOffset;
-const unsigned int TransferBufferTest::kAlignment;
-#endif
+ size = std::min(static_cast<size_t>(size), MaxTransferBufferSize());
+ if (actual_offset_ + size > size_) {
+ actual_offset_ = result_size_;
+ }
+ uint32 offset = actual_offset_;
+ actual_offset_ += RoundToAlignment(size);
+ *size_allocated = size;
-TEST_F(TransferBufferTest, Basic) {
- EXPECT_TRUE(transfer_buffer_->HaveBuffer());
- EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
+ // Make sure each buffer has a different offset.
+ last_alloc_ = actual_buffer() + offset + actual_buffer_index_ * alignment_;
+ return last_alloc_;
}
-TEST_F(TransferBufferTest, Free) {
- EXPECT_TRUE(transfer_buffer_->HaveBuffer());
+void* MockTransferBuffer::Alloc(unsigned int size) {
+ EXPECT_LE(size, MaxTransferBufferSize());
+ unsigned int temp = 0;
+ void* p = AllocUpTo(size, &temp);
+ EXPECT_EQ(temp, size);
+ return p;
+}
- // Free buffer.
- EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_))
- .Times(1)
- .RetiresOnSaturation();
- transfer_buffer_->Free();
- // See it's freed.
- EXPECT_FALSE(transfer_buffer_->HaveBuffer());
- // See that it gets reallocated.
- EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
- EXPECT_TRUE(transfer_buffer_->HaveBuffer());
-
- // Free buffer.
- EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_))
- .Times(1)
- .RetiresOnSaturation();
- transfer_buffer_->Free();
- // See it's freed.
- EXPECT_FALSE(transfer_buffer_->HaveBuffer());
- // See that it gets reallocated.
- EXPECT_TRUE(transfer_buffer_->GetResultBuffer() != NULL);
- EXPECT_TRUE(transfer_buffer_->HaveBuffer());
-
- // Free buffer.
- EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_))
- .Times(1)
- .RetiresOnSaturation();
- transfer_buffer_->Free();
- // See it's freed.
- EXPECT_FALSE(transfer_buffer_->HaveBuffer());
- // See that it gets reallocated.
- EXPECT_TRUE(transfer_buffer_->GetBuffer() != NULL);
- EXPECT_TRUE(transfer_buffer_->HaveBuffer());
-
- // Free buffer.
- EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_))
- .Times(1)
- .RetiresOnSaturation();
- transfer_buffer_->Free();
- // See it's freed.
- EXPECT_FALSE(transfer_buffer_->HaveBuffer());
- // See that it gets reallocated.
- transfer_buffer_->GetResultOffset();
- EXPECT_TRUE(transfer_buffer_->HaveBuffer());
-
- // Test freeing twice.
- EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_))
- .Times(1)
- .RetiresOnSaturation();
- transfer_buffer_->Free();
- transfer_buffer_->Free();
+RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const {
+ // Make sure each buffer has a different offset.
+ return static_cast<uint8*>(pointer) - actual_buffer();
}
-class GLES2ImplementationTest : public GLES2CommandBufferTestBase {
+void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) {
+ EXPECT_EQ(last_alloc_, p);
+ last_alloc_ = NULL;
+}
+
+class GLES2ImplementationTest : public testing::Test {
protected:
+ static const uint8 kInitialValue = 0xBD;
+ static const int32 kNumCommandEntries = 400;
+ static const int32 kCommandBufferSizeBytes =
+ kNumCommandEntries * sizeof(CommandBufferEntry);
+ static const size_t kTransferBufferSize = 256;
+
static const GLint kMaxCombinedTextureImageUnits = 8;
static const GLint kMaxCubeMapTextureSize = 64;
static const GLint kMaxFragmentUniformVectors = 16;
@@ -441,22 +319,33 @@ class GLES2ImplementationTest : public GLES2CommandBufferTestBase {
static const GLuint kRenderbuffersStartId = 1;
static const GLuint kTexturesStartId = 1;
- GLES2ImplementationTest() { }
+ typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo;
- virtual void SetUp() {
- Initialize(false, true);
+ GLES2ImplementationTest()
+ : commands_(NULL),
+ token_(0) {
}
- virtual void TearDown() {
- Mock::VerifyAndClear(gl_.get());
- EXPECT_CALL(*command_buffer_, OnFlush(_)).Times(AnyNumber());
- gl_.reset();
+ virtual void SetUp() OVERRIDE;
+ virtual void TearDown() OVERRIDE;
+
+ bool NoCommandsWritten() {
+ return static_cast<const uint8*>(static_cast<const void*>(commands_))[0] ==
+ kInitialValue;
}
void Initialize(bool shared_resources, bool bind_generates_resource) {
- SetupCommandBuffer(
+ command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());
+ ASSERT_TRUE(command_buffer_->Initialize());
+
+ transfer_buffer_.reset(new MockTransferBuffer(
+ command_buffer(),
+ kTransferBufferSize,
GLES2Implementation::kStartingOffset,
- GLES2Implementation::kAlignment);
+ GLES2Implementation::kAlignment));
+
+ helper_.reset(new GLES2CmdHelper(command_buffer()));
+ helper_->Initialize(kCommandBufferSizeBytes);
GLES2Implementation::GLState state;
state.max_combined_texture_image_units = kMaxCombinedTextureImageUnits;
@@ -475,14 +364,13 @@ class GLES2ImplementationTest : public GLES2CommandBufferTestBase {
// This just happens to work for now because GLState has 1 GLint per
// state. If GLState gets more complicated this code will need to get
// more complicated.
- AllocateTransferBuffer(sizeof(state)); // in
- uint32 offset = AllocateTransferBuffer(sizeof(state)); // out
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(state) * 2);
{
InSequence sequence;
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemoryAtOffset(offset, state))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(mem1.ptr + sizeof(state), state))
.RetiresOnSaturation();
GetNextToken(); // eat the token that starting up will use.
@@ -500,9 +388,9 @@ class GLES2ImplementationTest : public GLES2CommandBufferTestBase {
while (num_ids) {
GLuint num = std::min(num_ids, max_num_per);
size_t size = num * sizeof(ids[0]);
- uint32 offset = AllocateTransferBuffer(size);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemoryAtOffsetFromArray(offset, ids, size))
+ ExpectedMemoryInfo mem = GetExpectedMemory(size);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemoryFromArray(mem.ptr, ids, size))
.RetiresOnSaturation();
GetNextToken();
start += num;
@@ -514,36 +402,93 @@ class GLES2ImplementationTest : public GLES2CommandBufferTestBase {
gl_.reset(new GLES2Implementation(
helper_.get(),
- kTransferBufferSize,
- transfer_buffer_.ptr,
- transfer_buffer_id_,
+ transfer_buffer_.get(),
shared_resources,
bind_generates_resource));
+ ASSERT_TRUE(gl_->Initialize(
+ kTransferBufferSize,
+ kTransferBufferSize,
+ kTransferBufferSize));
}
- EXPECT_CALL(*command_buffer_, OnFlush(_))
+ EXPECT_CALL(*command_buffer(), OnFlush())
.Times(1)
.RetiresOnSaturation();
helper_->CommandBufferHelper::Finish();
+ ::testing::Mock::VerifyAndClearExpectations(gl_.get());
+
Buffer ring_buffer = helper_->get_ring_buffer();
commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) +
- command_buffer_->GetState().put_offset;
+ command_buffer()->GetState().put_offset;
ClearCommands();
+ EXPECT_TRUE(transfer_buffer_->InSync());
+
+ ::testing::Mock::VerifyAndClearExpectations(command_buffer());
+ }
+
+ MockClientCommandBuffer* command_buffer() const {
+ return command_buffer_.get();
+ }
+
+ int GetNextToken() {
+ return ++token_;
+ }
+
+ const void* GetPut() {
+ return helper_->GetSpace(0);
+ }
+
+ void ClearCommands() {
+ Buffer ring_buffer = helper_->get_ring_buffer();
+ memset(ring_buffer.ptr, kInitialValue, ring_buffer.size);
+ }
+
+ size_t MaxTransferBufferSize() {
+ return transfer_buffer_->MaxTransferBufferSize();
+ }
+
+ ExpectedMemoryInfo GetExpectedMemory(size_t size) {
+ return transfer_buffer_->GetExpectedMemory(size);
+ }
+
+ ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
+ return transfer_buffer_->GetExpectedResultMemory(size);
}
Sequence sequence_;
+ scoped_ptr<MockClientCommandBuffer> command_buffer_;
+ scoped_ptr<GLES2CmdHelper> helper_;
+ scoped_ptr<MockTransferBuffer> transfer_buffer_;
scoped_ptr<GLES2Implementation> gl_;
+ CommandBufferEntry* commands_;
+ int token_;
};
+void GLES2ImplementationTest::SetUp() {
+ Initialize(false, true);
+}
+
+void GLES2ImplementationTest::TearDown() {
+ Mock::VerifyAndClear(gl_.get());
+ EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
+ gl_.reset();
+}
+
class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest {
protected:
- virtual void SetUp() {
- Initialize(true, false);
- }
+ virtual void SetUp() OVERRIDE;
};
+void GLES2ImplementationStrictSharedTest::SetUp() {
+ Initialize(true, false);
+}
+
// GCC requires these declarations, but MSVC requires they not be present
#ifndef _MSC_VER
+const uint8 GLES2ImplementationTest::kInitialValue;
+const int32 GLES2ImplementationTest::kNumCommandEntries;
+const int32 GLES2ImplementationTest::kCommandBufferSizeBytes;
+const size_t GLES2ImplementationTest::kTransferBufferSize;
const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits;
const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize;
const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors;
@@ -565,7 +510,7 @@ const GLuint GLES2ImplementationTest::kTexturesStartId;
#endif
TEST_F(GLES2ImplementationTest, ShaderSource) {
- const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation
+ const uint32 kBucketId = GLES2Implementation::kResultBucketId;
const GLuint kShaderId = 456;
const char* kString1 = "foobar";
const char* kString2 = "barfoo";
@@ -573,9 +518,12 @@ TEST_F(GLES2ImplementationTest, ShaderSource) {
const size_t kString2Size = strlen(kString2);
const size_t kString3Size = 1; // Want the NULL;
const size_t kSourceSize = kString1Size + kString2Size + kString3Size;
- const size_t kPaddedString1Size = RoundToAlignment(kString1Size);
- const size_t kPaddedString2Size = RoundToAlignment(kString2Size);
- const size_t kPaddedString3Size = RoundToAlignment(kString3Size);
+ const size_t kPaddedString1Size =
+ transfer_buffer_->RoundToAlignment(kString1Size);
+ const size_t kPaddedString2Size =
+ transfer_buffer_->RoundToAlignment(kString2Size);
+ const size_t kPaddedString3Size =
+ transfer_buffer_->RoundToAlignment(kString3Size);
struct Cmds {
cmd::SetBucketSize set_bucket_size;
cmd::SetBucketData set_bucket_data1;
@@ -587,20 +535,22 @@ TEST_F(GLES2ImplementationTest, ShaderSource) {
ShaderSourceBucket shader_source_bucket;
cmd::SetBucketSize clear_bucket_size;
};
+
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
+ ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);
+ ExpectedMemoryInfo mem3 = GetExpectedMemory(kPaddedString3Size);
+
Cmds expected;
expected.set_bucket_size.Init(kBucketId, kSourceSize);
expected.set_bucket_data1.Init(
- kBucketId, 0, kString1Size, transfer_buffer_id_,
- AllocateTransferBuffer(kPaddedString1Size));
+ kBucketId, 0, kString1Size, mem1.id, mem1.offset);
expected.set_token1.Init(GetNextToken());
expected.set_bucket_data2.Init(
- kBucketId, kString1Size, kString2Size, transfer_buffer_id_,
- AllocateTransferBuffer(kPaddedString2Size));
+ kBucketId, kString1Size, kString2Size, mem2.id, mem2.offset);
expected.set_token2.Init(GetNextToken());
expected.set_bucket_data3.Init(
kBucketId, kString1Size + kString2Size,
- kString3Size, transfer_buffer_id_,
- AllocateTransferBuffer(kPaddedString3Size));
+ kString3Size, mem3.id, mem3.offset);
expected.set_token3.Init(GetNextToken());
expected.shader_source_bucket.Init(kShaderId, kBucketId);
expected.clear_bucket_size.Init(kBucketId, 0);
@@ -613,7 +563,7 @@ TEST_F(GLES2ImplementationTest, ShaderSource) {
}
TEST_F(GLES2ImplementationTest, GetShaderSource) {
- const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation
+ const uint32 kBucketId = GLES2Implementation::kResultBucketId;
const GLuint kShaderId = 456;
const Str7 kString = {"foobar"};
const char kBad = 0x12;
@@ -625,25 +575,29 @@ TEST_F(GLES2ImplementationTest, GetShaderSource) {
cmd::SetToken set_token1;
cmd::SetBucketSize set_bucket_size2;
};
- uint32 offset = AllocateTransferBuffer(sizeof(kString));
+
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(kString));
+
Cmds expected;
expected.set_bucket_size1.Init(kBucketId, 0);
expected.get_shader_source.Init(kShaderId, kBucketId);
- expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0);
+ expected.get_bucket_size.Init(kBucketId, result1.id, result1.offset);
expected.get_bucket_data.Init(
- kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset);
+ kBucketId, 0, sizeof(kString), mem1.id, mem1.offset);
expected.set_token1.Init(GetNextToken());
expected.set_bucket_size2.Init(kBucketId, 0);
char buf[sizeof(kString) + 1];
memset(buf, kBad, sizeof(buf));
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(sizeof(kString))))
- .WillOnce(SetMemoryAtOffset(offset, kString))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(sizeof(kString))))
+ .WillOnce(SetMemory(mem1.ptr, kString))
.RetiresOnSaturation();
GLsizei length = 0;
gl_->GetShaderSource(kShaderId, sizeof(buf), &length, buf);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
EXPECT_EQ(sizeof(kString) - 1, static_cast<size_t>(length));
EXPECT_STREQ(kString.str, buf);
EXPECT_EQ(buf[sizeof(kString)], kBad);
@@ -685,33 +639,34 @@ TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) {
arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
const GLsizei kEmuOffset1 = 0;
const GLsizei kEmuOffset2 = kSize1;
-
const GLsizei kTotalSize = kSize1 + kSize2;
+
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
+ ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
+
Cmds expected;
expected.enable1.Init(kAttribIndex1);
expected.enable2.Init(kAttribIndex2);
expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
expected.copy_data1.Init(
- GL_ARRAY_BUFFER, kEmuOffset1, kSize1, transfer_buffer_id_,
- AllocateTransferBuffer(kSize1));
+ GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
expected.set_token1.Init(GetNextToken());
- expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
- GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
+ expected.set_pointer1.Init(
+ kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
expected.copy_data2.Init(
- GL_ARRAY_BUFFER, kEmuOffset2, kSize2, transfer_buffer_id_,
- AllocateTransferBuffer(kSize2));
+ GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
expected.set_token2.Init(GetNextToken());
- expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
- GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
+ expected.set_pointer2.Init(
+ kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
expected.draw.Init(GL_POINTS, kFirst, kCount);
expected.restore.Init(GL_ARRAY_BUFFER, 0);
gl_->EnableVertexAttribArray(kAttribIndex1);
gl_->EnableVertexAttribArray(kAttribIndex2);
- gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
- GL_FLOAT, GL_FALSE, kClientStride, verts);
- gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
- GL_FLOAT, GL_FALSE, kClientStride, verts);
+ gl_->VertexAttribPointer(
+ kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
+ gl_->VertexAttribPointer(
+ kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
gl_->DrawArrays(GL_POINTS, kFirst, kCount);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
@@ -760,8 +715,12 @@ TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
const GLsizei kEmuOffset1 = 0;
const GLsizei kEmuOffset2 = kSize1;
-
const GLsizei kTotalSize = kSize1 + kSize2;
+
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
+ ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
+ ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
+
Cmds expected;
expected.enable1.Init(kAttribIndex1);
expected.enable2.Init(kAttribIndex2);
@@ -769,20 +728,17 @@ TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
expected.set_index_size.Init(
GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
expected.copy_data0.Init(
- GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, transfer_buffer_id_,
- AllocateTransferBuffer(kIndexSize));
+ GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
expected.set_token0.Init(GetNextToken());
expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
expected.copy_data1.Init(
- GL_ARRAY_BUFFER, kEmuOffset1, kSize1, transfer_buffer_id_,
- AllocateTransferBuffer(kSize1));
+ GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
expected.set_token1.Init(GetNextToken());
- expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
- GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
+ expected.set_pointer1.Init(
+ kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
expected.copy_data2.Init(
- GL_ARRAY_BUFFER, kEmuOffset2, kSize2, transfer_buffer_id_,
- AllocateTransferBuffer(kSize2));
+ GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
expected.set_token2.Init(GetNextToken());
expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
@@ -838,33 +794,36 @@ TEST_F(GLES2ImplementationTest,
arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
const GLsizei kEmuOffset1 = 0;
const GLsizei kEmuOffset2 = kSize1;
-
const GLsizei kTotalSize = kSize1 + kSize2;
+
+ ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(uint32));
+ ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
+ ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
+
+
Cmds expected;
expected.enable1.Init(kAttribIndex1);
expected.enable2.Init(kAttribIndex2);
expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT,
- kIndexOffset, transfer_buffer_id_, 0);
+ kIndexOffset, mem1.id, mem1.offset);
expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
expected.copy_data1.Init(
- GL_ARRAY_BUFFER, kEmuOffset1, kSize1, transfer_buffer_id_,
- AllocateTransferBuffer(kSize1));
+ GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
expected.set_token1.Init(GetNextToken());
expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
expected.copy_data2.Init(
- GL_ARRAY_BUFFER, kEmuOffset2, kSize2, transfer_buffer_id_,
- AllocateTransferBuffer(kSize2));
+ GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
expected.set_token2.Init(GetNextToken());
expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset);
expected.restore.Init(GL_ARRAY_BUFFER, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(kMaxIndex))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(mem1.ptr,kMaxIndex))
.RetiresOnSaturation();
gl_->EnableVertexAttribArray(kAttribIndex1);
@@ -897,16 +856,19 @@ TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) {
VertexAttribPointer set_pointer;
GetVertexAttribPointerv get_pointer;
};
+
+ ExpectedMemoryInfo mem1 = GetExpectedResultMemory(16);
+
Cmds expected;
expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
kStride2, kOffset2);
expected.get_pointer.Init(kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER,
- transfer_buffer_id_, 0);
+ mem1.id, mem1.offset);
// One call to flush to way for GetVertexAttribPointerv
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<uint32>(kOffset2)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(mem1.ptr, SizedResultHelper<uint32>(kOffset2)))
.RetiresOnSaturation();
// Set one client side buffer.
@@ -952,6 +914,10 @@ TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
GetVertexAttribiv get1; // for getting the buffer from attrib2
GetVertexAttribfv get2; // for getting the value from attrib1
};
+
+ ExpectedMemoryInfo mem1 = GetExpectedResultMemory(16);
+ ExpectedMemoryInfo mem2 = GetExpectedResultMemory(16);
+
Cmds expected;
expected.enable.Init(kAttribIndex1);
expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
@@ -959,17 +925,19 @@ TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
kStride2, kOffset2);
expected.get1.Init(kAttribIndex2,
GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
- transfer_buffer_id_, 0);
+ mem1.id, mem1.offset);
expected.get2.Init(kAttribIndex1,
GL_CURRENT_VERTEX_ATTRIB,
- transfer_buffer_id_, 0);
+ mem2.id, mem2.offset);
FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f);
// One call to flush to way for GetVertexAttribiv
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<GLuint>(kBufferId)))
- .WillOnce(SetMemory(SizedResultHelper<FourFloats>(current_attrib)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(
+ mem1.ptr, SizedResultHelper<GLuint>(kBufferId)))
+ .WillOnce(SetMemory(
+ mem2.ptr, SizedResultHelper<FourFloats>(current_attrib)))
.RetiresOnSaturation();
gl_->EnableVertexAttribArray(kAttribIndex1);
@@ -1025,11 +993,14 @@ TEST_F(GLES2ImplementationTest, ReservedIds) {
GetError get;
};
Cmds expected;
- expected.get.Init(transfer_buffer_id_, 0);
+
+ ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(GetError::Result));
+
+ expected.get.Init(mem1.id, mem1.offset);
// One call to flush to wait for GetError
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(mem1.ptr, GLuint(GL_NO_ERROR)))
.RetiresOnSaturation();
gl_->BindBuffer(
@@ -1060,24 +1031,29 @@ TEST_F(GLES2ImplementationTest, ReadPixels2Reads) {
const GLenum kFormat = GL_RGBA;
const GLenum kType = GL_UNSIGNED_BYTE;
+ ExpectedMemoryInfo mem1 =
+ GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(ReadPixels::Result));
+ ExpectedMemoryInfo mem2 =
+ GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
+ ExpectedMemoryInfo result2 =
+ GetExpectedResultMemory(sizeof(ReadPixels::Result));
+
Cmds expected;
expected.read1.Init(
0, 0, kWidth, kHeight / 2, kFormat, kType,
- transfer_buffer_id_,
- AllocateTransferBuffer(kWidth * kHeight / 2 * kBytesPerPixel),
- transfer_buffer_id_, 0);
+ mem1.id, mem1.offset, result1.id, result1.offset);
expected.set_token1.Init(GetNextToken());
expected.read2.Init(
0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
- transfer_buffer_id_,
- AllocateTransferBuffer(kWidth * kHeight / 2 * kBytesPerPixel),
- transfer_buffer_id_, 0);
+ mem2.id, mem2.offset, result2.id, result2.offset);
expected.set_token2.Init(GetNextToken());
scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(static_cast<uint32>(1)))
- .WillOnce(SetMemory(static_cast<uint32>(1)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, static_cast<uint32>(1)))
+ .WillOnce(SetMemory(result2.ptr, static_cast<uint32>(1)))
.RetiresOnSaturation();
gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
@@ -1095,16 +1071,19 @@ TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) {
const GLenum kFormat = 0;
const GLenum kType = 0;
+ ExpectedMemoryInfo mem1 =
+ GetExpectedMemory(kWidth * kHeight * kBytesPerPixel);
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(ReadPixels::Result));
+
Cmds expected;
expected.read.Init(
- 0, 0, kWidth, kHeight / 2, kFormat, kType,
- transfer_buffer_id_,
- AllocateTransferBuffer(kWidth * kHeight * kBytesPerPixel),
- transfer_buffer_id_, 0);
+ 0, 0, kWidth, kHeight, kFormat, kType,
+ mem1.id, mem1.offset, result1.id, result1.offset);
expected.set_token.Init(GetNextToken());
scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
+ EXPECT_CALL(*command_buffer(), OnFlush())
.Times(1)
.RetiresOnSaturation();
@@ -1120,17 +1099,18 @@ TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) {
const GLintptr kOffset = 15;
const GLsizeiptr kSize = 16;
- uint32 offset = 0;
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize);
+
Cmds expected;
expected.buf.Init(
- kTarget, kOffset, kSize, transfer_buffer_id_, offset);
+ kTarget, kOffset, kSize, mem1.id, mem1.offset);
expected.set_token.Init(GetNextToken());
void* mem = gl_->MapBufferSubDataCHROMIUM(
kTarget, kOffset, kSize, GL_WRITE_ONLY);
ASSERT_TRUE(mem != NULL);
gl_->UnmapBufferSubDataCHROMIUM(mem);
- EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_))
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
.Times(1)
.RetiresOnSaturation();
gl_->FreeUnusedSharedMemory();
@@ -1148,7 +1128,8 @@ TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) {
uint32 offset = 0;
Cmds expected;
expected.buf.Init(
- kTarget, kOffset, kSize, GetNextFreeTransferBufferId(), offset);
+ kTarget, kOffset, kSize,
+ command_buffer()->GetNextFreeTransferBufferId(), offset);
expected.set_token.Init(GetNextToken());
void* mem = gl_->MapBufferSubDataCHROMIUM(
@@ -1163,12 +1144,21 @@ TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUMBadArgs) {
const GLintptr kOffset = 15;
const GLsizeiptr kSize = 16;
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result2 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result3 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result4 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+
// Calls to flush to wait for GetError
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
.RetiresOnSaturation();
void* mem;
@@ -1203,7 +1193,8 @@ TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) {
Cmds expected;
expected.tex.Init(
GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat,
- kType, GetNextFreeTransferBufferId(), offset, GL_FALSE);
+ kType,
+ command_buffer()->GetNextFreeTransferBufferId(), offset, GL_FALSE);
expected.set_token.Init(GetNextToken());
void* mem = gl_->MapTexSubImage2DCHROMIUM(
@@ -1230,15 +1221,30 @@ TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) {
const GLenum kFormat = GL_RGBA;
const GLenum kType = GL_UNSIGNED_BYTE;
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result2 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result3 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result4 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result5 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result6 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result7 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+
// Calls to flush to wait for GetError
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result7.ptr, GLuint(GL_NO_ERROR)))
.RetiresOnSaturation();
void* mem;
@@ -1333,13 +1339,18 @@ TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) {
};
const GLsizei kNumPnames = arraysize(pnames);
const GLsizeiptr kResultsSize = num_results * sizeof(results[0]);
- const uint32 kPnamesOffset =
- AllocateTransferBuffer(kNumPnames * sizeof(pnames[0]));
- const uint32 kResultsOffset = AllocateTransferBuffer(kResultsSize);
+ const size_t kPNamesSize = kNumPnames * sizeof(pnames[0]);
+
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(kPNamesSize + kResultsSize);
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(
+ sizeof(GetError::Result));
+
+ const uint32 kPnamesOffset = mem1.offset;
+ const uint32 kResultsOffset = mem1.offset + kPNamesSize;
Cmds expected;
expected.get_multiple.Init(
- transfer_buffer_id_, kPnamesOffset, kNumPnames,
- transfer_buffer_id_, kResultsOffset, kResultsSize);
+ mem1.id, kPnamesOffset, kNumPnames,
+ mem1.id, kResultsOffset, kResultsSize);
expected.set_token.Init(GetNextToken());
const GLint kSentinel = 0x12345678;
@@ -1349,10 +1360,10 @@ TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) {
1, 0, 1, 0, 1, -1,
};
// One call to flush to wait for results
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemoryAtOffsetFromArray(
- kResultsOffset, returned_results, sizeof(returned_results)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemoryFromArray(mem1.ptr + kPNamesSize,
+ returned_results, sizeof(returned_results)))
+ .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
.RetiresOnSaturation();
gl_->GetMultipleIntegervCHROMIUM(
@@ -1374,12 +1385,21 @@ TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMBadArgs) {
const GLsizei kNumPnames = arraysize(pnames);
const GLsizeiptr kResultsSize = num_results * sizeof(results[0]);
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result2 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result3 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result4 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+
// Calls to flush to wait for GetError
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
.RetiresOnSaturation();
const GLint kSentinel = 0x12345678;
@@ -1422,19 +1442,25 @@ TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMBadArgs) {
}
TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
- const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation
+ const uint32 kBucketId = GLES2Implementation::kResultBucketId;
const GLuint kProgramId = 123;
const char kBad = 0x12;
GLsizei size = 0;
const Str7 kString = {"foobar"};
char buf[20];
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(cmd::GetBucketSize::Result));
+ ExpectedMemoryInfo mem1 =
+ GetExpectedMemory(sizeof(kString));
+ ExpectedMemoryInfo result2 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+
memset(buf, kBad, sizeof(buf));
- uint32 offset = AllocateTransferBuffer(sizeof(kString));
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(sizeof(kString))))
- .WillOnce(SetMemoryAtOffset(offset, kString))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(sizeof(kString))))
+ .WillOnce(SetMemory(mem1.ptr, kString))
+ .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
.RetiresOnSaturation();
struct Cmds {
@@ -1448,9 +1474,9 @@ TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
Cmds expected;
expected.set_bucket_size1.Init(kBucketId, 0);
expected.get_program_info.Init(kProgramId, kBucketId);
- expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0);
+ expected.get_bucket_size.Init(kBucketId, result1.id, result1.offset);
expected.get_bucket_data.Init(
- kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset);
+ kBucketId, 0, sizeof(kString), mem1.id, mem1.offset);
expected.set_token1.Init(GetNextToken());
expected.set_bucket_size2.Init(kBucketId, 0);
gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
@@ -1462,19 +1488,28 @@ TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
}
TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) {
- const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation
+ const uint32 kBucketId = GLES2Implementation::kResultBucketId;
const GLuint kProgramId = 123;
GLsizei size = 0;
const Str7 kString = {"foobar"};
char buf[20];
- uint32 offset = AllocateTransferBuffer(sizeof(kString));
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(sizeof(kString))))
- .WillOnce(SetMemoryAtOffset(offset, kString))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(cmd::GetBucketSize::Result));
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(kString));
+ ExpectedMemoryInfo result2 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result3 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result4 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(sizeof(kString))))
+ .WillOnce(SetMemory(mem1.ptr, kString))
+ .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
.RetiresOnSaturation();
// try bufsize not big enough.
@@ -1489,9 +1524,9 @@ TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) {
Cmds expected;
expected.set_bucket_size1.Init(kBucketId, 0);
expected.get_program_info.Init(kProgramId, kBucketId);
- expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0);
+ expected.get_bucket_size.Init(kBucketId, result1.id, result1.offset);
expected.get_bucket_data.Init(
- kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset);
+ kBucketId, 0, sizeof(kString), mem1.id, mem1.offset);
expected.set_token1.Init(GetNextToken());
expected.set_bucket_size2.Init(kBucketId, 0);
gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf);
@@ -1546,8 +1581,11 @@ TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) {
EXPECT_EQ(pv.expected, v);
}
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
.RetiresOnSaturation();
EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
}
@@ -1582,8 +1620,11 @@ TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) {
EXPECT_EQ(pv.expected, v);
}
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
.RetiresOnSaturation();
EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
}
@@ -1663,11 +1704,13 @@ TEST_F(GLES2ImplementationTest, TexImage2D) {
31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
41, 42, 43, 43, 44, 45, 45, 46, 47,
};
- uint32 offset = AllocateTransferBuffer(sizeof(pixels));
+
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
+
Cmds expected;
expected.tex_image_2d.Init(
kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
- transfer_buffer_id_, offset);
+ mem1.id, mem1.offset);
expected.set_token.Init(GetNextToken());
gl_->TexImage2D(
kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
@@ -1675,14 +1718,14 @@ TEST_F(GLES2ImplementationTest, TexImage2D) {
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
EXPECT_TRUE(CheckRect(
kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false,
- pixels, GetTransferAddressFromOffsetAs<uint8>(offset, sizeof(pixels))));
+ pixels, mem1.ptr));
ClearCommands();
- uint32 offset2 = AllocateTransferBuffer(sizeof(pixels));
+ ExpectedMemoryInfo mem2 = GetExpectedMemory(sizeof(pixels));
Cmds2 expected2;
expected2.tex_image_2d.Init(
kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
- transfer_buffer_id_, offset2);
+ mem2.id, mem2.offset);
expected2.set_token.Init(GetNextToken());
const void* commands2 = GetPut();
gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
@@ -1692,7 +1735,7 @@ TEST_F(GLES2ImplementationTest, TexImage2D) {
EXPECT_EQ(0, memcmp(&expected2, commands2, sizeof(expected2)));
EXPECT_TRUE(CheckRect(
kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, true,
- pixels, GetTransferAddressFromOffsetAs<uint8>(offset2, sizeof(pixels))));
+ pixels, mem2.ptr));
}
// Test TexImage2D with 2 writes
@@ -1731,27 +1774,29 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) {
for (uint32 ii = 0; ii < size; ++ii) {
pixels[ii] = static_cast<uint8>(ii);
}
- uint32 offset1 = AllocateTransferBuffer(half_size);
- uint32 offset2 = AllocateTransferBuffer(half_size);
+
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(half_size);
+ ExpectedMemoryInfo mem2 = GetExpectedMemory(half_size);
+
Cmds expected;
expected.tex_image_2d.Init(
kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
0, 0);
expected.tex_sub_image_2d1.Init(
kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
- transfer_buffer_id_, offset1, true);
+ mem1.id, mem1.offset, true);
expected.set_token1.Init(GetNextToken());
expected.tex_sub_image_2d2.Init(
kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
- transfer_buffer_id_, offset2, true);
+ mem2.id, mem2.offset, true);
expected.set_token2.Init(GetNextToken());
// TODO(gman): Make it possible to run this test
- // EXPECT_CALL(*command_buffer_, OnFlush(_))
+ // EXPECT_CALL(*command_buffer(), OnFlush())
// .WillOnce(CheckRectAction(
// kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
// false, pixels.get(),
- // GetTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
+ // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
// .RetiresOnSaturation();
gl_->TexImage2D(
@@ -1760,31 +1805,30 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) {
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
EXPECT_TRUE(CheckRect(
kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, false,
- pixels.get() + kHeight / 2 * padded_row_size,
- GetTransferAddressFromOffsetAs<uint8>(offset2, half_size)));
+ pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr));
ClearCommands();
const void* commands2 = GetPut();
- uint32 offset3 = AllocateTransferBuffer(half_size);
- uint32 offset4 = AllocateTransferBuffer(half_size);
+ ExpectedMemoryInfo mem3 = GetExpectedMemory(half_size);
+ ExpectedMemoryInfo mem4 = GetExpectedMemory(half_size);
expected.tex_image_2d.Init(
kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
0, 0);
expected.tex_sub_image_2d1.Init(
kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
- transfer_buffer_id_, offset3, true);
+ mem3.id, mem3.offset, true);
expected.set_token1.Init(GetNextToken());
expected.tex_sub_image_2d2.Init(
kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
- transfer_buffer_id_, offset4, true);
+ mem4.id, mem4.offset, true);
expected.set_token2.Init(GetNextToken());
// TODO(gman): Make it possible to run this test
- // EXPECT_CALL(*command_buffer_, OnFlush(_))
+ // EXPECT_CALL(*command_buffer(), OnFlush())
// .WillOnce(CheckRectAction(
// kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
// true, pixels.get(),
- // GetTransferAddressFromOffsetAs<uint8>(offset3, half_size)))
+ // GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size)))
// .RetiresOnSaturation();
gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
@@ -1794,145 +1838,7 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) {
EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected)));
EXPECT_TRUE(CheckRect(
kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
- pixels.get() + kHeight / 2 * padded_row_size,
- GetTransferAddressFromOffsetAs<uint8>(offset4, half_size)));
-}
-
-// Test TexImage2D with sub rows
-TEST_F(GLES2ImplementationTest, TexImage2DSubRows) {
- struct Cmds {
- TexImage2D tex_image_2d;
- TexSubImage2D tex_sub_image_2d1;
- cmd::SetToken set_token1;
- TexSubImage2D tex_sub_image_2d2;
- cmd::SetToken set_token2;
- TexSubImage2D tex_sub_image_2d3;
- cmd::SetToken set_token3;
- TexSubImage2D tex_sub_image_2d4;
- cmd::SetToken set_token4;
- };
- const GLenum kTarget = GL_TEXTURE_2D;
- const GLint kLevel = 0;
- const GLenum kFormat = GL_RGB;
- const GLint kBorder = 0;
- const GLenum kType = GL_UNSIGNED_BYTE;
- const GLint kPixelStoreUnpackAlignment = 4;
- const GLsizei kHeight = 2;
- const GLsizei kWidth = (MaxTransferBufferSize() / 3) * 2;
-
- uint32 size = 0;
- uint32 unpadded_row_size = 0;
- uint32 padded_row_size = 0;
- ASSERT_TRUE(ComputeImageDataSizes(
- kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
- &size, &unpadded_row_size, &padded_row_size));
- uint32 part_size = kWidth * 3 / 2;
-
- scoped_array<uint8> pixels(new uint8[size]);
- for (uint32 ii = 0; ii < size; ++ii) {
- pixels[ii] = static_cast<uint8>(ii);
- }
- uint32 offset1 = AllocateTransferBuffer(part_size);
- uint32 offset2 = AllocateTransferBuffer(part_size);
- uint32 offset3 = AllocateTransferBuffer(part_size);
- uint32 offset4 = AllocateTransferBuffer(part_size);
- Cmds expected;
- expected.tex_image_2d.Init(
- kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
- 0, 0);
- expected.tex_sub_image_2d1.Init(
- kTarget, kLevel, 0, 0, kWidth / 2, 1, kFormat, kType,
- transfer_buffer_id_, offset1, true);
- expected.set_token1.Init(GetNextToken());
- expected.tex_sub_image_2d2.Init(
- kTarget, kLevel, kWidth / 2, 0, kWidth / 2, 1, kFormat, kType,
- transfer_buffer_id_, offset2, true);
- expected.set_token2.Init(GetNextToken());
- expected.tex_sub_image_2d3.Init(
- kTarget, kLevel, 0, 1, kWidth / 2, 1, kFormat, kType,
- transfer_buffer_id_, offset3, true);
- expected.set_token3.Init(GetNextToken());
- expected.tex_sub_image_2d4.Init(
- kTarget, kLevel, kWidth / 2, 1, kWidth / 2, 1, kFormat, kType,
- transfer_buffer_id_, offset4, true);
- expected.set_token4.Init(GetNextToken());
-
- // TODO(gman): Make it possible to run this test
- // EXPECT_CALL(*command_buffer_, OnFlush(_))
- // .WillOnce(CheckRectAction(
- // kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false,
- // pixels.get(),
- // GetTransferAddressFromOffsetAs<uint8>(offset1, part_size)))
- // .WillOnce(CheckRectAction(
- // kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false,
- // pixels.get() + part_size,
- // GetTransferAddressFromOffsetAs<uint8>(offset2, part_size)))
- // .WillOnce(CheckRectAction(
- // kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false,
- // pixels.get() + padded_row_size,
- // GetTransferAddressFromOffsetAs<uint8>(offset3, part_size)))
- // .RetiresOnSaturation();
-
- gl_->TexImage2D(
- kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
- pixels.get());
- EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
- EXPECT_TRUE(CheckRect(
- kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false,
- pixels.get() + padded_row_size + part_size,
- GetTransferAddressFromOffsetAs<uint8>(offset4, part_size)));
-
- ClearCommands();
- const void* commands2 = GetPut();
- offset1 = AllocateTransferBuffer(part_size);
- offset2 = AllocateTransferBuffer(part_size);
- offset3 = AllocateTransferBuffer(part_size);
- offset4 = AllocateTransferBuffer(part_size);
- expected.tex_image_2d.Init(
- kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
- 0, 0);
- expected.tex_sub_image_2d1.Init(
- kTarget, kLevel, 0, 1, kWidth / 2, 1, kFormat, kType,
- transfer_buffer_id_, offset1, true);
- expected.set_token1.Init(GetNextToken());
- expected.tex_sub_image_2d2.Init(
- kTarget, kLevel, kWidth / 2, 1, kWidth / 2, 1, kFormat, kType,
- transfer_buffer_id_, offset2, true);
- expected.set_token2.Init(GetNextToken());
- expected.tex_sub_image_2d3.Init(
- kTarget, kLevel, 0, 0, kWidth / 2, 1, kFormat, kType,
- transfer_buffer_id_, offset3, true);
- expected.set_token3.Init(GetNextToken());
- expected.tex_sub_image_2d4.Init(
- kTarget, kLevel, kWidth / 2, 0, kWidth / 2, 1, kFormat, kType,
- transfer_buffer_id_, offset4, true);
- expected.set_token4.Init(GetNextToken());
-
- // TODO(gman): Make it possible to run this test
- // EXPECT_CALL(*command_buffer_, OnFlush(_))
- // .WillOnce(CheckRectAction(
- // kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false,
- // pixels.get(),
- // GetTransferAddressFromOffsetAs<uint8>(offset1, part_size)))
- // .WillOnce(CheckRectAction(
- // kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false,
- // pixels.get() + part_size,
- // GetTransferAddressFromOffsetAs<uint8>(offset2, part_size)))
- // .WillOnce(CheckRectAction(
- // kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false,
- // pixels.get() + padded_row_size,
- // GetTransferAddressFromOffsetAs<uint8>(offset3, part_size)))
- // .RetiresOnSaturation();
-
- gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
- gl_->TexImage2D(
- kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
- pixels.get());
- EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected)));
- EXPECT_TRUE(CheckRect(
- kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false,
- pixels.get() + padded_row_size + part_size,
- GetTransferAddressFromOffsetAs<uint8>(offset4, part_size)));
+ pixels.get() + kHeight / 2 * padded_row_size, mem4.ptr));
}
// Test TexSubImage2D with GL_PACK_FLIP_Y set and partial multirow transfers
@@ -1963,8 +1869,9 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) {
ASSERT_TRUE(GLES2Util::ComputeImageDataSize(
kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
&sub_2_high_size));
- uint32 offset1 = AllocateTransferBuffer(sub_2_high_size);
- uint32 offset2 = AllocateTransferBuffer(sub_2_high_size);
+
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(sub_2_high_size);
+ ExpectedMemoryInfo mem2 = GetExpectedMemory(sub_2_high_size);
Cmds expected;
expected.pixel_store_i1.Init(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
@@ -1973,11 +1880,11 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) {
kType, 0, NULL);
expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset,
kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType,
- transfer_buffer_id_, offset1, false);
+ mem1.id, mem1.offset, false);
expected.set_token1.Init(GetNextToken());
expected.tex_sub_image_2d2.Init(kTarget, kLevel, kSubImageXOffset,
- kSubImageYOffset, kSubImageWidth , 2, kFormat, kType, transfer_buffer_id_,
- offset2, false);
+ kSubImageYOffset, kSubImageWidth , 2, kFormat, kType,
+ mem2.id, mem2.offset, false);
expected.set_token2.Init(GetNextToken());
gl_->PixelStorei(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
@@ -2000,7 +1907,7 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) {
EXPECT_TRUE(CheckRect(
kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
reinterpret_cast<uint8*>(pixels.get() + 2 * kSubImageWidth),
- GetTransferAddressFromOffsetAs<uint8>(offset2, sub_2_high_size)));
+ mem2.ptr));
}
// Test that GenBuffer does not call GenSharedIds.
@@ -2041,8 +1948,11 @@ TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) {
for (size_t ii = 0; ii < num_pairs; ++ii) {
const PNameValue& pv = pairs[ii];
GLint v = -1;
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<GLuint>(pv.expected)))
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(GetIntegerv::Result));
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr,
+ SizedResultHelper<GLuint>(pv.expected)))
.RetiresOnSaturation();
gl_->GetIntegerv(pv.pname, &v);
EXPECT_EQ(pv.expected, v);
@@ -2052,13 +1962,26 @@ TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) {
TEST_F(GLES2ImplementationStrictSharedTest, CanNotDeleteIdsWeDidNotCreate) {
GLuint id = 0x12345678;
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result2 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result3 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result4 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result5 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+ ExpectedMemoryInfo result6 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR)))
+ .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR)))
.RetiresOnSaturation();
gl_->DeleteBuffers(1, &id);
@@ -2078,28 +2001,32 @@ TEST_F(GLES2ImplementationStrictSharedTest, CanNotDeleteIdsWeDidNotCreate) {
TEST_F(GLES2ImplementationTest, CreateStreamTextureCHROMIUM) {
const GLuint kTextureId = 123;
const GLuint kResult = 456;
- const uint32 kResultOffset = 0;
struct Cmds {
CreateStreamTextureCHROMIUM create_stream;
};
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(CreateStreamTextureCHROMIUM::Result));
+ ExpectedMemoryInfo result2 =
+ GetExpectedResultMemory(sizeof(GetError::Result));
+
Cmds expected;
- expected.create_stream.Init(kTextureId, transfer_buffer_id_, kResultOffset);
+ expected.create_stream.Init(kTextureId, result1.id, result1.offset);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemoryAtOffset(kResultOffset, kResult))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, kResult))
+ .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
.RetiresOnSaturation();
GLuint handle = gl_->CreateStreamTextureCHROMIUM(kTextureId);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
EXPECT_EQ(handle, kResult);
EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
- EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
TEST_F(GLES2ImplementationTest, GetString) {
- const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation
+ const uint32 kBucketId = GLES2Implementation::kResultBucketId;
const Str7 kString = {"foobar"};
// GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into
// GLES2Implementation.
@@ -2113,21 +2040,23 @@ TEST_F(GLES2ImplementationTest, GetString) {
cmd::SetToken set_token1;
cmd::SetBucketSize set_bucket_size2;
};
- uint32 offset = AllocateTransferBuffer(sizeof(kString));
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(cmd::GetBucketSize::Result));
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(kString));
Cmds expected;
expected.set_bucket_size1.Init(kBucketId, 0);
expected.get_string.Init(GL_EXTENSIONS, kBucketId);
- expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0);
+ expected.get_bucket_size.Init(kBucketId, result1.id, result1.offset);
expected.get_bucket_data.Init(
- kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset);
+ kBucketId, 0, sizeof(kString), mem1.id, mem1.offset);
expected.set_token1.Init(GetNextToken());
expected.set_bucket_size2.Init(kBucketId, 0);
char buf[sizeof(kString) + 1];
memset(buf, kBad, sizeof(buf));
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(sizeof(kString))))
- .WillOnce(SetMemoryAtOffset(offset, kString))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(sizeof(kString))))
+ .WillOnce(SetMemory(mem1.ptr, kString))
.RetiresOnSaturation();
const GLubyte* result = gl_->GetString(GL_EXTENSIONS);
@@ -2136,7 +2065,7 @@ TEST_F(GLES2ImplementationTest, GetString) {
}
TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) {
- const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation
+ const uint32 kBucketId = GLES2Implementation::kResultBucketId;
const Str7 kString = {"foobar"};
struct Cmds {
cmd::SetBucketSize set_bucket_size1;
@@ -2147,20 +2076,24 @@ TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) {
cmd::SetBucketSize set_bucket_size2;
PixelStorei pixel_store;
};
- uint32 offset = AllocateTransferBuffer(sizeof(kString));
+
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(cmd::GetBucketSize::Result));
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(kString));
+
Cmds expected;
expected.set_bucket_size1.Init(kBucketId, 0);
expected.get_string.Init(GL_EXTENSIONS, kBucketId);
- expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0);
+ expected.get_bucket_size.Init(kBucketId, result1.id, result1.offset);
expected.get_bucket_data.Init(
- kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset);
+ kBucketId, 0, sizeof(kString), mem1.id, mem1.offset);
expected.set_token1.Init(GetNextToken());
expected.set_bucket_size2.Init(kBucketId, 0);
expected.pixel_store.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(sizeof(kString))))
- .WillOnce(SetMemoryAtOffset(offset, kString))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(sizeof(kString))))
+ .WillOnce(SetMemory(mem1.ptr, kString))
.RetiresOnSaturation();
gl_->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
@@ -2190,16 +2123,18 @@ TEST_F(GLES2ImplementationTest, BufferDataLargerThanTransferBuffer) {
const unsigned kUsableSize =
kTransferBufferSize - GLES2Implementation::kStartingOffset;
uint8 buf[kUsableSize * 2] = { 0, };
+
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(kUsableSize);
+ ExpectedMemoryInfo mem2 = GetExpectedMemory(kUsableSize);
+
Cmds expected;
expected.set_size.Init(
GL_ARRAY_BUFFER, arraysize(buf), 0, 0, GL_DYNAMIC_DRAW);
expected.copy_data1.Init(
- GL_ARRAY_BUFFER, 0, kUsableSize, transfer_buffer_id_,
- AllocateTransferBuffer(kUsableSize));
+ GL_ARRAY_BUFFER, 0, kUsableSize, mem1.id, mem1.offset);
expected.set_token1.Init(GetNextToken());
expected.copy_data2.Init(
- GL_ARRAY_BUFFER, kUsableSize, kUsableSize, transfer_buffer_id_,
- AllocateTransferBuffer(kUsableSize));
+ GL_ARRAY_BUFFER, kUsableSize, kUsableSize, mem2.id, mem2.offset);
expected.set_token2.Init(GetNextToken());
gl_->BufferData(GL_ARRAY_BUFFER, arraysize(buf), buf, GL_DYNAMIC_DRAW);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
index e8cf5f9..fae58d97 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -130,10 +130,12 @@ TEST_F(GLES2ImplementationTest, CheckFramebufferStatus) {
typedef CheckFramebufferStatus::Result Result;
Cmds expected;
- expected.cmd.Init(1, transfer_buffer_id_, 0);
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(CheckFramebufferStatus::Result));
+ expected.cmd.Init(1, result1.id, result1.offset);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(1)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(1)))
.RetiresOnSaturation();
GLboolean result = gl_->CheckFramebufferStatus(1);
@@ -551,9 +553,10 @@ TEST_F(GLES2ImplementationTest, GetBooleanv) {
typedef GetBooleanv::Result Result;
Result::Type result = 0;
Cmds expected;
- expected.cmd.Init(123, transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
+ expected.cmd.Init(123, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->GetBooleanv(123, &result);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
@@ -567,9 +570,10 @@ TEST_F(GLES2ImplementationTest, GetBufferParameteriv) {
typedef GetBufferParameteriv::Result Result;
Result::Type result = 0;
Cmds expected;
- expected.cmd.Init(123, GL_BUFFER_SIZE, transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
+ expected.cmd.Init(123, GL_BUFFER_SIZE, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->GetBufferParameteriv(123, GL_BUFFER_SIZE, &result);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
@@ -583,9 +587,10 @@ TEST_F(GLES2ImplementationTest, GetFloatv) {
typedef GetFloatv::Result Result;
Result::Type result = 0;
Cmds expected;
- expected.cmd.Init(123, transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
+ expected.cmd.Init(123, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->GetFloatv(123, &result);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
@@ -599,11 +604,12 @@ TEST_F(GLES2ImplementationTest, GetFramebufferAttachmentParameteriv) {
typedef GetFramebufferAttachmentParameteriv::Result Result;
Result::Type result = 0;
Cmds expected;
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
expected.cmd.Init(
123, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
- transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->GetFramebufferAttachmentParameteriv(
123, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
@@ -619,9 +625,10 @@ TEST_F(GLES2ImplementationTest, GetIntegerv) {
typedef GetIntegerv::Result Result;
Result::Type result = 0;
Cmds expected;
- expected.cmd.Init(123, transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
+ expected.cmd.Init(123, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->GetIntegerv(123, &result);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
@@ -635,9 +642,10 @@ TEST_F(GLES2ImplementationTest, GetProgramiv) {
typedef GetProgramiv::Result Result;
Result::Type result = 0;
Cmds expected;
- expected.cmd.Init(123, GL_DELETE_STATUS, transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
+ expected.cmd.Init(123, GL_DELETE_STATUS, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->GetProgramiv(123, GL_DELETE_STATUS, &result);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
@@ -652,9 +660,10 @@ TEST_F(GLES2ImplementationTest, GetRenderbufferParameteriv) {
typedef GetRenderbufferParameteriv::Result Result;
Result::Type result = 0;
Cmds expected;
- expected.cmd.Init(123, GL_RENDERBUFFER_RED_SIZE, transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
+ expected.cmd.Init(123, GL_RENDERBUFFER_RED_SIZE, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->GetRenderbufferParameteriv(123, GL_RENDERBUFFER_RED_SIZE, &result);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
@@ -668,9 +677,10 @@ TEST_F(GLES2ImplementationTest, GetShaderiv) {
typedef GetShaderiv::Result Result;
Result::Type result = 0;
Cmds expected;
- expected.cmd.Init(123, GL_SHADER_TYPE, transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
+ expected.cmd.Init(123, GL_SHADER_TYPE, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->GetShaderiv(123, GL_SHADER_TYPE, &result);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
@@ -686,9 +696,10 @@ TEST_F(GLES2ImplementationTest, GetTexParameterfv) {
typedef GetTexParameterfv::Result Result;
Result::Type result = 0;
Cmds expected;
- expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
+ expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->GetTexParameterfv(123, GL_TEXTURE_MAG_FILTER, &result);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
@@ -702,9 +713,10 @@ TEST_F(GLES2ImplementationTest, GetTexParameteriv) {
typedef GetTexParameteriv::Result Result;
Result::Type result = 0;
Cmds expected;
- expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
+ expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->GetTexParameteriv(123, GL_TEXTURE_MAG_FILTER, &result);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
@@ -721,10 +733,11 @@ TEST_F(GLES2ImplementationTest, GetVertexAttribfv) {
typedef GetVertexAttribfv::Result Result;
Result::Type result = 0;
Cmds expected;
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
expected.cmd.Init(
- 123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ 123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->GetVertexAttribfv(123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &result);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
@@ -738,10 +751,11 @@ TEST_F(GLES2ImplementationTest, GetVertexAttribiv) {
typedef GetVertexAttribiv::Result Result;
Result::Type result = 0;
Cmds expected;
+ ExpectedMemoryInfo result1 = GetExpectedResultMemory(4);
expected.cmd.Init(
- 123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, transfer_buffer_id_, 0);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1)))
+ 123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, result1.id, result1.offset);
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1)))
.RetiresOnSaturation();
gl_->GetVertexAttribiv(123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &result);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
@@ -766,10 +780,12 @@ TEST_F(GLES2ImplementationTest, IsBuffer) {
typedef IsBuffer::Result Result;
Cmds expected;
- expected.cmd.Init(1, transfer_buffer_id_, 0);
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(IsBuffer::Result));
+ expected.cmd.Init(1, result1.id, result1.offset);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(1)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(1)))
.RetiresOnSaturation();
GLboolean result = gl_->IsBuffer(1);
@@ -784,10 +800,12 @@ TEST_F(GLES2ImplementationTest, IsEnabled) {
typedef IsEnabled::Result Result;
Cmds expected;
- expected.cmd.Init(1, transfer_buffer_id_, 0);
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(IsEnabled::Result));
+ expected.cmd.Init(1, result1.id, result1.offset);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(1)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(1)))
.RetiresOnSaturation();
GLboolean result = gl_->IsEnabled(1);
@@ -802,10 +820,12 @@ TEST_F(GLES2ImplementationTest, IsFramebuffer) {
typedef IsFramebuffer::Result Result;
Cmds expected;
- expected.cmd.Init(1, transfer_buffer_id_, 0);
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(IsFramebuffer::Result));
+ expected.cmd.Init(1, result1.id, result1.offset);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(1)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(1)))
.RetiresOnSaturation();
GLboolean result = gl_->IsFramebuffer(1);
@@ -820,10 +840,12 @@ TEST_F(GLES2ImplementationTest, IsProgram) {
typedef IsProgram::Result Result;
Cmds expected;
- expected.cmd.Init(1, transfer_buffer_id_, 0);
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(IsProgram::Result));
+ expected.cmd.Init(1, result1.id, result1.offset);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(1)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(1)))
.RetiresOnSaturation();
GLboolean result = gl_->IsProgram(1);
@@ -838,10 +860,12 @@ TEST_F(GLES2ImplementationTest, IsRenderbuffer) {
typedef IsRenderbuffer::Result Result;
Cmds expected;
- expected.cmd.Init(1, transfer_buffer_id_, 0);
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(IsRenderbuffer::Result));
+ expected.cmd.Init(1, result1.id, result1.offset);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(1)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(1)))
.RetiresOnSaturation();
GLboolean result = gl_->IsRenderbuffer(1);
@@ -856,10 +880,12 @@ TEST_F(GLES2ImplementationTest, IsShader) {
typedef IsShader::Result Result;
Cmds expected;
- expected.cmd.Init(1, transfer_buffer_id_, 0);
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(IsShader::Result));
+ expected.cmd.Init(1, result1.id, result1.offset);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(1)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(1)))
.RetiresOnSaturation();
GLboolean result = gl_->IsShader(1);
@@ -874,10 +900,12 @@ TEST_F(GLES2ImplementationTest, IsTexture) {
typedef IsTexture::Result Result;
Cmds expected;
- expected.cmd.Init(1, transfer_buffer_id_, 0);
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(IsTexture::Result));
+ expected.cmd.Init(1, result1.id, result1.offset);
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(uint32(1)))
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32(1)))
.RetiresOnSaturation();
GLboolean result = gl_->IsTexture(1);
diff --git a/gpu/command_buffer/client/ring_buffer.h b/gpu/command_buffer/client/ring_buffer.h
index e3a3980..582d4ee 100644
--- a/gpu/command_buffer/client/ring_buffer.h
+++ b/gpu/command_buffer/client/ring_buffer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -165,12 +165,12 @@ class RingBufferWrapper {
}
// Gets a pointer to a memory block given the base memory and the offset.
- void* GetPointer(RingBuffer::Offset offset) {
+ void* GetPointer(RingBuffer::Offset offset) const {
return static_cast<int8*>(base_) + offset;
}
// Gets the offset to a memory block given the base memory and the address.
- RingBuffer::Offset GetOffset(void* pointer) {
+ RingBuffer::Offset GetOffset(void* pointer) const {
return static_cast<int8*>(pointer) - static_cast<int8*>(base_);
}
diff --git a/gpu/command_buffer/client/transfer_buffer.cc b/gpu/command_buffer/client/transfer_buffer.cc
new file mode 100644
index 0000000..28bb0e6
--- /dev/null
+++ b/gpu/command_buffer/client/transfer_buffer.cc
@@ -0,0 +1,211 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A class to Manage a growing transfer buffer.
+
+#include "../client/transfer_buffer.h"
+#include "../client/cmd_buffer_helper.h"
+
+namespace gpu {
+
+AlignedRingBuffer::~AlignedRingBuffer() {
+}
+
+TransferBuffer::TransferBuffer(
+ CommandBufferHelper* helper)
+ : helper_(helper),
+ result_size_(0),
+ min_buffer_size_(0),
+ max_buffer_size_(0),
+ alignment_(),
+ buffer_id_(-1),
+ result_buffer_(NULL),
+ result_shm_offset_(0),
+ usable_(true) {
+}
+
+TransferBuffer::~TransferBuffer() {
+ Free();
+}
+
+bool TransferBuffer::Initialize(
+ unsigned int starting_buffer_size,
+ unsigned int result_size,
+ unsigned int min_buffer_size,
+ unsigned int max_buffer_size,
+ unsigned int alignment) {
+ result_size_ = result_size;
+ min_buffer_size_ = min_buffer_size;
+ max_buffer_size_ = max_buffer_size;
+ alignment_ = alignment;
+ ReallocateRingBuffer(starting_buffer_size - result_size);
+ return HaveBuffer();
+}
+
+void TransferBuffer::Free() {
+ if (HaveBuffer()) {
+ helper_->Finish();
+ helper_->command_buffer()->DestroyTransferBuffer(buffer_id_);
+ buffer_id_ = -1;
+ buffer_.ptr = NULL;
+ buffer_.size = 0;
+ result_buffer_ = NULL;
+ result_shm_offset_ = 0;
+ ring_buffer_.reset();
+ }
+}
+
+bool TransferBuffer::HaveBuffer() const {
+ return buffer_id_ != -1;
+}
+
+RingBuffer::Offset TransferBuffer::GetOffset(void* pointer) const {
+ return ring_buffer_->GetOffset(pointer);
+}
+
+void TransferBuffer::FreePendingToken(void* p, unsigned int token) {
+ ring_buffer_->FreePendingToken(p, token);
+}
+
+void TransferBuffer::AllocateRingBuffer(unsigned int size) {
+ for (;size >= min_buffer_size_; size /= 2) {
+ int32 id = helper_->command_buffer()->CreateTransferBuffer(size, -1);
+ if (id != -1) {
+ buffer_ = helper_->command_buffer()->GetTransferBuffer(id);
+ ring_buffer_.reset(new AlignedRingBuffer(
+ alignment_,
+ id,
+ result_size_,
+ buffer_.size - result_size_,
+ helper_,
+ static_cast<char*>(buffer_.ptr) + result_size_));
+ buffer_id_ = id;
+ result_buffer_ = buffer_.ptr;
+ result_shm_offset_ = 0;
+ return;
+ }
+ // we failed so don't try larger than this.
+ max_buffer_size_ = size / 2;
+ }
+ usable_ = false;
+}
+
+// Returns the integer i such as 2^i <= n < 2^(i+1)
+static int Log2Floor(uint32 n) {
+ if (n == 0)
+ return -1;
+ int log = 0;
+ uint32 value = n;
+ for (int i = 4; i >= 0; --i) {
+ int shift = (1 << i);
+ uint32 x = value >> shift;
+ if (x != 0) {
+ value = x;
+ log += shift;
+ }
+ }
+ GPU_DCHECK_EQ(value, 1u);
+ return log;
+}
+
+// Returns the integer i such as 2^(i-1) < n <= 2^i
+static int Log2Ceiling(uint32 n) {
+ if (n == 0) {
+ return -1;
+ } else {
+ // Log2Floor returns -1 for 0, so the following works correctly for n=1.
+ return 1 + Log2Floor(n - 1);
+ }
+}
+
+static unsigned int ComputePOTSize(unsigned int dimension) {
+ return (dimension == 0) ? 0 : 1 << Log2Ceiling(dimension);
+}
+
+void TransferBuffer::ReallocateRingBuffer(unsigned int size) {
+ // What size buffer would we ask for if we needed a new one?
+ unsigned int needed_buffer_size = ComputePOTSize(size + result_size_);
+ needed_buffer_size = std::max(needed_buffer_size, min_buffer_size_);
+ needed_buffer_size = std::min(needed_buffer_size, max_buffer_size_);
+
+ if (usable_ && (!HaveBuffer() || needed_buffer_size > buffer_.size)) {
+ if (HaveBuffer()) {
+ Free();
+ }
+ AllocateRingBuffer(needed_buffer_size);
+ }
+}
+
+void* TransferBuffer::AllocUpTo(
+ unsigned int size, unsigned int* size_allocated) {
+ GPU_DCHECK(size_allocated);
+
+ ReallocateRingBuffer(size);
+
+ if (!HaveBuffer()) {
+ return NULL;
+ }
+
+ unsigned int max_size = ring_buffer_->GetLargestFreeOrPendingSize();
+ *size_allocated = std::min(max_size, size);
+ return ring_buffer_->Alloc(*size_allocated);
+}
+
+void* TransferBuffer::Alloc(unsigned int size) {
+ ReallocateRingBuffer(size);
+
+ if (!HaveBuffer()) {
+ return NULL;
+ }
+
+ unsigned int max_size = ring_buffer_->GetLargestFreeOrPendingSize();
+ if (size > max_size) {
+ return NULL;
+ }
+
+ return ring_buffer_->Alloc(size);
+}
+
+void* TransferBuffer::GetResultBuffer() {
+ ReallocateRingBuffer(result_size_);
+ return result_buffer_;
+}
+
+int TransferBuffer::GetResultOffset() {
+ ReallocateRingBuffer(result_size_);
+ return result_shm_offset_;
+}
+
+int TransferBuffer::GetShmId() {
+ ReallocateRingBuffer(result_size_);
+ return buffer_id_;
+}
+
+unsigned int TransferBuffer::GetCurrentMaxAllocationWithoutRealloc() const {
+ return HaveBuffer() ? ring_buffer_->GetLargestFreeOrPendingSize() : 0;
+}
+
+unsigned int TransferBuffer::GetMaxAllocation() const {
+ return HaveBuffer() ? max_buffer_size_ - result_size_ : 0;
+}
+
+void ScopedTransferBufferPtr::Release() {
+ if (buffer_) {
+ transfer_buffer_->FreePendingToken(buffer_, helper_->InsertToken());
+ buffer_ = NULL;
+ size_ = 0;
+ }
+}
+
+void ScopedTransferBufferPtr::Reset(unsigned int new_size) {
+ Release();
+ // NOTE: we allocate buffers of size 0 so that HaveBuffer will be true, so
+ // that address will return a pointer just like malloc, and so that GetShmId
+ // will be valid. That has the side effect that we'll insert a token on free.
+ // We could add code skip the token for a zero size buffer but it doesn't seem
+ // worth the complication.
+ buffer_ = transfer_buffer_->AllocUpTo(new_size, &size_);
+}
+
+} // namespace gpu
diff --git a/gpu/command_buffer/client/transfer_buffer.h b/gpu/command_buffer/client/transfer_buffer.h
new file mode 100644
index 0000000..654465c
--- /dev/null
+++ b/gpu/command_buffer/client/transfer_buffer.h
@@ -0,0 +1,221 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
+#define GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
+
+#include "../common/buffer.h"
+#include "../common/compiler_specific.h"
+#include "../common/gles2_cmd_utils.h"
+#include "../common/scoped_ptr.h"
+#include "../client/ring_buffer.h"
+
+namespace gpu {
+
+class CommandBufferHelper;
+
+// Wraps RingBufferWrapper to provide aligned allocations.
+class AlignedRingBuffer : public RingBufferWrapper {
+ public:
+ AlignedRingBuffer(
+ unsigned int alignment,
+ int32 shm_id,
+ RingBuffer::Offset base_offset,
+ unsigned int size,
+ CommandBufferHelper* helper,
+ void* base)
+ : RingBufferWrapper(base_offset, size, helper, base),
+ alignment_(alignment),
+ shm_id_(shm_id) {
+ }
+ ~AlignedRingBuffer();
+
+ // Hiding Alloc from RingBufferWrapper
+ void* Alloc(unsigned int size) {
+ return RingBufferWrapper::Alloc(RoundToAlignment(size));
+ }
+
+ int32 GetShmId() const {
+ return shm_id_;
+ }
+
+ private:
+ unsigned int RoundToAlignment(unsigned int size) {
+ return (size + alignment_ - 1) & ~(alignment_ - 1);
+ }
+
+ unsigned int alignment_;
+ int32 shm_id_;
+};
+
+// Interface for managing the transfer buffer.
+class TransferBufferInterface {
+ public:
+ TransferBufferInterface() { }
+ virtual ~TransferBufferInterface() { }
+
+ virtual bool Initialize(
+ unsigned int buffer_size,
+ unsigned int result_size,
+ unsigned int min_buffer_size,
+ unsigned int max_buffer_size,
+ unsigned int alignment) = 0;
+
+ virtual int GetShmId() = 0;
+ virtual void* GetResultBuffer() = 0;
+ virtual int GetResultOffset() = 0;
+
+ virtual void Free() = 0;
+
+ virtual bool HaveBuffer() const = 0;
+
+ // Allocates up to size bytes.
+ virtual void* AllocUpTo(unsigned int size, unsigned int* size_allocated) = 0;
+
+ // Allocates size bytes.
+ // Note: Alloc will fail if it can not return size bytes.
+ virtual void* Alloc(unsigned int size) = 0;
+
+ virtual RingBuffer::Offset GetOffset(void* pointer) const = 0;
+
+ virtual void FreePendingToken(void* p, unsigned int token) = 0;
+};
+
+// Class that manages the transfer buffer.
+class TransferBuffer : public TransferBufferInterface {
+ public:
+ TransferBuffer(CommandBufferHelper* helper);
+ virtual ~TransferBuffer();
+
+ // Overridden from TransferBufferInterface.
+ virtual bool Initialize(
+ unsigned int buffer_size,
+ unsigned int result_size,
+ unsigned int min_buffer_size,
+ unsigned int max_buffer_size,
+ unsigned int alignment) OVERRIDE;
+ virtual int GetShmId() OVERRIDE;
+ virtual void* GetResultBuffer() OVERRIDE;
+ virtual int GetResultOffset() OVERRIDE;
+ virtual void Free() OVERRIDE;
+ virtual bool HaveBuffer() const OVERRIDE;
+ virtual void* AllocUpTo(
+ unsigned int size, unsigned int* size_allocated) OVERRIDE;
+ virtual void* Alloc(unsigned int size) OVERRIDE;
+ virtual RingBuffer::Offset GetOffset(void* pointer) const OVERRIDE;
+ virtual void FreePendingToken(void* p, unsigned int token) OVERRIDE;
+
+ // These are for testing.
+ unsigned int GetCurrentMaxAllocationWithoutRealloc() const;
+ unsigned int GetMaxAllocation() const;
+
+ private:
+ // Tries to reallocate the ring buffer if it's not large enough for size.
+ void ReallocateRingBuffer(unsigned int size);
+
+ void AllocateRingBuffer(unsigned int size);
+
+ CommandBufferHelper* helper_;
+ scoped_ptr<AlignedRingBuffer> ring_buffer_;
+
+ // size reserved for results
+ unsigned int result_size_;
+
+ // min size we'll consider successful
+ unsigned int min_buffer_size_;
+
+ // max size we'll let the buffer grow
+ unsigned int max_buffer_size_;
+
+ // alignment for allocations
+ unsigned int alignment_;
+
+ // the current buffer.
+ gpu::Buffer buffer_;
+
+ // id of buffer. -1 = no buffer
+ int32 buffer_id_;
+
+ // address of result area
+ void* result_buffer_;
+
+ // offset to result area
+ uint32 result_shm_offset_;
+
+ // false if we failed to allocate min_buffer_size
+ bool usable_;
+};
+
+// A class that will manage the lifetime of a transferbuffer allocation.
+class ScopedTransferBufferPtr {
+ public:
+ ScopedTransferBufferPtr(
+ unsigned int size,
+ CommandBufferHelper* helper,
+ TransferBufferInterface* transfer_buffer)
+ : buffer_(NULL),
+ size_(0),
+ helper_(helper),
+ transfer_buffer_(transfer_buffer) {
+ Reset(size);
+ }
+
+ ~ScopedTransferBufferPtr() {
+ Release();
+ }
+
+ bool valid() const {
+ return buffer_ != NULL;
+ }
+
+ unsigned int size() const {
+ return size_;
+ }
+
+ int shm_id() const {
+ return transfer_buffer_->GetShmId();
+ }
+
+ RingBuffer::Offset offset() const {
+ return transfer_buffer_->GetOffset(buffer_);
+ }
+
+ void* address() const {
+ return buffer_;
+ }
+
+ void Release();
+
+ void Reset(unsigned int new_size);
+
+ private:
+ void* buffer_;
+ unsigned int size_;
+ CommandBufferHelper* helper_;
+ TransferBufferInterface* transfer_buffer_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedTransferBufferPtr);
+};
+
+template <typename T>
+class ScopedTransferBufferArray : public ScopedTransferBufferPtr {
+ public:
+ ScopedTransferBufferArray(
+ unsigned int num_elements,
+ CommandBufferHelper* helper, TransferBufferInterface* transfer_buffer)
+ : ScopedTransferBufferPtr(
+ num_elements * sizeof(T), helper, transfer_buffer) {
+ }
+
+ T* elements() {
+ return static_cast<T*>(address());
+ }
+
+ unsigned int num_elements() const {
+ return size() / sizeof(T);
+ }
+};
+
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
diff --git a/gpu/command_buffer/client/transfer_buffer_unittest.cc b/gpu/command_buffer/client/transfer_buffer_unittest.cc
new file mode 100644
index 0000000..26b2057
--- /dev/null
+++ b/gpu/command_buffer/client/transfer_buffer_unittest.cc
@@ -0,0 +1,434 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Tests for the Command Buffer Helper.
+
+#include "gpu/command_buffer/client/transfer_buffer.h"
+
+#include "gpu/command_buffer/client/client_test_helper.h"
+#include "gpu/command_buffer/client/cmd_buffer_helper.h"
+#include "gpu/command_buffer/common/command_buffer.h"
+#include "gpu/command_buffer/common/compiler_specific.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using ::testing::_;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+namespace gpu {
+
+class TransferBufferTest : public testing::Test {
+ protected:
+ static const int32 kNumCommandEntries = 400;
+ static const int32 kCommandBufferSizeBytes =
+ kNumCommandEntries * sizeof(CommandBufferEntry);
+ static const unsigned int kStartingOffset = 64;
+ static const unsigned int kAlignment = 4;
+ static const size_t kTransferBufferSize = 256;
+
+ TransferBufferTest()
+ : transfer_buffer_id_(0) {
+ }
+
+ virtual void SetUp() OVERRIDE;
+ virtual void TearDown() OVERRIDE;
+
+ MockClientCommandBuffer* command_buffer() const {
+ return command_buffer_.get();
+ }
+
+ scoped_ptr<MockClientCommandBuffer> command_buffer_;
+ scoped_ptr<CommandBufferHelper> helper_;
+ scoped_ptr<TransferBuffer> transfer_buffer_;
+ int32 transfer_buffer_id_;
+};
+
+void TransferBufferTest::SetUp() {
+ command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());
+ ASSERT_TRUE(command_buffer_->Initialize());
+
+ helper_.reset(new CommandBufferHelper(command_buffer()));
+ ASSERT_TRUE(helper_->Initialize(kCommandBufferSizeBytes));
+
+ transfer_buffer_id_ = command_buffer()->GetNextFreeTransferBufferId();
+
+ transfer_buffer_.reset(new TransferBuffer(helper_.get()));
+ ASSERT_TRUE(transfer_buffer_->Initialize(
+ kTransferBufferSize,
+ kStartingOffset,
+ kTransferBufferSize,
+ kTransferBufferSize,
+ kAlignment));
+}
+
+void TransferBufferTest::TearDown() {
+ if (transfer_buffer_->HaveBuffer()) {
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+ transfer_buffer_.reset();
+}
+
+// GCC requires these declarations, but MSVC requires they not be present
+#ifndef _MSC_VER
+const int32 TransferBufferTest::kNumCommandEntries;
+const int32 TransferBufferTest::kCommandBufferSizeBytes;
+const unsigned int TransferBufferTest::kStartingOffset;
+const unsigned int TransferBufferTest::kAlignment;
+const size_t TransferBufferTest::kTransferBufferSize;
+#endif
+
+TEST_F(TransferBufferTest, Basic) {
+ EXPECT_TRUE(transfer_buffer_->HaveBuffer());
+ EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
+ EXPECT_EQ(
+ kTransferBufferSize - kStartingOffset,
+ transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
+}
+
+TEST_F(TransferBufferTest, Free) {
+ EXPECT_TRUE(transfer_buffer_->HaveBuffer());
+ EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
+
+ // Free buffer.
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ transfer_buffer_->Free();
+ // See it's freed.
+ EXPECT_FALSE(transfer_buffer_->HaveBuffer());
+ // See that it gets reallocated.
+ EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
+ EXPECT_TRUE(transfer_buffer_->HaveBuffer());
+
+ // Free buffer.
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ transfer_buffer_->Free();
+ // See it's freed.
+ EXPECT_FALSE(transfer_buffer_->HaveBuffer());
+ // See that it gets reallocated.
+ EXPECT_TRUE(transfer_buffer_->GetResultBuffer() != NULL);
+ EXPECT_TRUE(transfer_buffer_->HaveBuffer());
+
+ // Free buffer.
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ transfer_buffer_->Free();
+ // See it's freed.
+ EXPECT_FALSE(transfer_buffer_->HaveBuffer());
+ // See that it gets reallocated.
+ unsigned int size = 0;
+ void* data = transfer_buffer_->AllocUpTo(1, &size);
+ EXPECT_TRUE(data != NULL);
+ EXPECT_TRUE(transfer_buffer_->HaveBuffer());
+ transfer_buffer_->FreePendingToken(data, 1);
+
+ // Free buffer.
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ transfer_buffer_->Free();
+ // See it's freed.
+ EXPECT_FALSE(transfer_buffer_->HaveBuffer());
+ // See that it gets reallocated.
+ transfer_buffer_->GetResultOffset();
+ EXPECT_TRUE(transfer_buffer_->HaveBuffer());
+
+ EXPECT_EQ(
+ kTransferBufferSize - kStartingOffset,
+ transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
+
+ // Test freeing twice.
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ transfer_buffer_->Free();
+ transfer_buffer_->Free();
+}
+
+TEST_F(TransferBufferTest, TooLargeAllocation) {
+ // Check that we can't allocate large than max size.
+ void* ptr = transfer_buffer_->Alloc(kTransferBufferSize + 1);
+ EXPECT_TRUE(ptr == NULL);
+ // Check we if we try to allocate larger than max we get max.
+ unsigned int size_allocated = 0;
+ ptr = transfer_buffer_->AllocUpTo(
+ kTransferBufferSize + 1, &size_allocated);
+ ASSERT_TRUE(ptr != NULL);
+ EXPECT_EQ(kTransferBufferSize - kStartingOffset, size_allocated);
+ transfer_buffer_->FreePendingToken(ptr, 1);
+}
+
+class MockClientCommandBufferCanFail : public MockClientCommandBuffer {
+ public:
+ MockClientCommandBufferCanFail() {
+ }
+ virtual ~MockClientCommandBufferCanFail() {
+ }
+
+ MOCK_METHOD2(CreateTransferBuffer, int32(size_t size, int32 id_request));
+
+ int32 RealCreateTransferBuffer(size_t size, int32 id_request) {
+ return MockCommandBufferBase::CreateTransferBuffer(size, id_request);
+ }
+};
+
+class TransferBufferExpandContractTest : public testing::Test {
+ protected:
+ static const int32 kNumCommandEntries = 400;
+ static const int32 kCommandBufferSizeBytes =
+ kNumCommandEntries * sizeof(CommandBufferEntry);
+ static const unsigned int kStartingOffset = 64;
+ static const unsigned int kAlignment = 4;
+ static const size_t kStartTransferBufferSize = 256;
+ static const size_t kMaxTransferBufferSize = 1024;
+ static const size_t kMinTransferBufferSize = 128;
+
+ TransferBufferExpandContractTest()
+ : transfer_buffer_id_(0) {
+ }
+
+ virtual void SetUp() OVERRIDE;
+ virtual void TearDown() OVERRIDE;
+
+ MockClientCommandBufferCanFail* command_buffer() const {
+ return command_buffer_.get();
+ }
+
+ scoped_ptr<MockClientCommandBufferCanFail> command_buffer_;
+ scoped_ptr<CommandBufferHelper> helper_;
+ scoped_ptr<TransferBuffer> transfer_buffer_;
+ int32 transfer_buffer_id_;
+};
+
+void TransferBufferExpandContractTest::SetUp() {
+ command_buffer_.reset(new StrictMock<MockClientCommandBufferCanFail>());
+ ASSERT_TRUE(command_buffer_->Initialize());
+
+ EXPECT_CALL(*command_buffer(),
+ CreateTransferBuffer(kCommandBufferSizeBytes, _))
+ .WillOnce(Invoke(
+ command_buffer(),
+ &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
+ .RetiresOnSaturation();
+
+ helper_.reset(new CommandBufferHelper(command_buffer()));
+ ASSERT_TRUE(helper_->Initialize(kCommandBufferSizeBytes));
+
+ transfer_buffer_id_ = command_buffer()->GetNextFreeTransferBufferId();
+
+ EXPECT_CALL(*command_buffer(),
+ CreateTransferBuffer(kStartTransferBufferSize, _))
+ .WillOnce(Invoke(
+ command_buffer(),
+ &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
+ .RetiresOnSaturation();
+
+ transfer_buffer_.reset(new TransferBuffer(helper_.get()));
+ ASSERT_TRUE(transfer_buffer_->Initialize(
+ kStartTransferBufferSize,
+ kStartingOffset,
+ kMinTransferBufferSize,
+ kMaxTransferBufferSize,
+ kAlignment));
+}
+
+void TransferBufferExpandContractTest::TearDown() {
+ if (transfer_buffer_->HaveBuffer()) {
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+ transfer_buffer_.reset();
+}
+
+// GCC requires these declarations, but MSVC requires they not be present
+#ifndef _MSC_VER
+const int32 TransferBufferExpandContractTest::kNumCommandEntries;
+const int32 TransferBufferExpandContractTest::kCommandBufferSizeBytes;
+const unsigned int TransferBufferExpandContractTest::kStartingOffset;
+const unsigned int TransferBufferExpandContractTest::kAlignment;
+const size_t TransferBufferExpandContractTest::kStartTransferBufferSize;
+const size_t TransferBufferExpandContractTest::kMaxTransferBufferSize;
+const size_t TransferBufferExpandContractTest::kMinTransferBufferSize;
+#endif
+
+TEST_F(TransferBufferExpandContractTest, Expand) {
+ // Check it starts at starting size.
+ EXPECT_EQ(
+ kStartTransferBufferSize - kStartingOffset,
+ transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
+
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(),
+ CreateTransferBuffer(kStartTransferBufferSize * 2, _))
+ .WillOnce(Invoke(
+ command_buffer(),
+ &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
+ .RetiresOnSaturation();
+
+ // Try next power of 2.
+ const size_t kSize1 = 512 - kStartingOffset;
+ unsigned int size_allocated = 0;
+ void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
+ ASSERT_TRUE(ptr != NULL);
+ EXPECT_EQ(kSize1, size_allocated);
+ EXPECT_EQ(kSize1, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
+ transfer_buffer_->FreePendingToken(ptr, 1);
+
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(),
+ CreateTransferBuffer(kMaxTransferBufferSize, _))
+ .WillOnce(Invoke(
+ command_buffer(),
+ &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
+ .RetiresOnSaturation();
+
+ // Try next power of 2.
+ const size_t kSize2 = 1024 - kStartingOffset;
+ ptr = transfer_buffer_->AllocUpTo(kSize2, &size_allocated);
+ ASSERT_TRUE(ptr != NULL);
+ EXPECT_EQ(kSize2, size_allocated);
+ EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
+ transfer_buffer_->FreePendingToken(ptr, 1);
+
+ // Try next one more. Should not go past max.
+ size_allocated = 0;
+ const size_t kSize3 = kSize2 + 1;
+ ptr = transfer_buffer_->AllocUpTo(kSize3, &size_allocated);
+ EXPECT_EQ(kSize2, size_allocated);
+ EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
+ transfer_buffer_->FreePendingToken(ptr, 1);
+}
+
+TEST_F(TransferBufferExpandContractTest, Contract) {
+ // Check it starts at starting size.
+ EXPECT_EQ(
+ kStartTransferBufferSize - kStartingOffset,
+ transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
+
+ // Free buffer.
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ transfer_buffer_->Free();
+ // See it's freed.
+ EXPECT_FALSE(transfer_buffer_->HaveBuffer());
+
+ // Try to allocate again, fail first request
+ EXPECT_CALL(*command_buffer(),
+ CreateTransferBuffer(kStartTransferBufferSize, _))
+ .WillOnce(Return(-1))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(),
+ CreateTransferBuffer(kMinTransferBufferSize, _))
+ .WillOnce(Invoke(
+ command_buffer(),
+ &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
+ .RetiresOnSaturation();
+
+ const size_t kSize1 = 256 - kStartingOffset;
+ const size_t kSize2 = 128 - kStartingOffset;
+ unsigned int size_allocated = 0;
+ void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
+ ASSERT_TRUE(ptr != NULL);
+ EXPECT_EQ(kSize2, size_allocated);
+ EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
+ transfer_buffer_->FreePendingToken(ptr, 1);
+
+ // Free buffer.
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ transfer_buffer_->Free();
+ // See it's freed.
+ EXPECT_FALSE(transfer_buffer_->HaveBuffer());
+
+ // Try to allocate again,
+ EXPECT_CALL(*command_buffer(),
+ CreateTransferBuffer(kMinTransferBufferSize, _))
+ .WillOnce(Invoke(
+ command_buffer(),
+ &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
+ .RetiresOnSaturation();
+
+ ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
+ ASSERT_TRUE(ptr != NULL);
+ EXPECT_EQ(kSize2, size_allocated);
+ EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
+ transfer_buffer_->FreePendingToken(ptr, 1);
+}
+
+TEST_F(TransferBufferExpandContractTest, OutOfMemory) {
+ // Free buffer.
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ transfer_buffer_->Free();
+ // See it's freed.
+ EXPECT_FALSE(transfer_buffer_->HaveBuffer());
+
+ // Try to allocate again, fail both requests.
+ EXPECT_CALL(*command_buffer(), CreateTransferBuffer(_, _))
+ .WillOnce(Return(-1))
+ .WillOnce(Return(-1))
+ .WillOnce(Return(-1))
+ .RetiresOnSaturation();
+
+ const size_t kSize1 = 512 - kStartingOffset;
+ unsigned int size_allocated = 0;
+ void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
+ ASSERT_TRUE(ptr == NULL);
+ EXPECT_FALSE(transfer_buffer_->HaveBuffer());
+}
+
+} // namespace gpu
+
+
diff --git a/gpu/command_buffer/common/compiler_specific.h b/gpu/command_buffer/common/compiler_specific.h
new file mode 100644
index 0000000..8cbc713
--- /dev/null
+++ b/gpu/command_buffer/common/compiler_specific.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_COMMON_COMPILER_SPECIFIC_H_
+#define GPU_COMMAND_BUFFER_COMMON_COMPILER_SPECIFIC_H_
+#pragma once
+
+// Annotate a virtual method indicating it must be overriding a virtual
+// method in the parent class.
+// Use like:
+// virtual void foo() OVERRIDE;
+#ifndef OVERRIDE
+#ifdef _MSC_VER
+#define OVERRIDE override
+#elif defined(__clang__)
+#define OVERRIDE override
+#else
+#define OVERRIDE
+#endif
+#endif
+
+#endif // GPU_COMMAND_BUFFER_COMMON_COMPILER_SPECIFIC_H_
diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc
index ca07a25..722eaf0 100644
--- a/gpu/demos/framework/window.cc
+++ b/gpu/demos/framework/window.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,6 +10,7 @@
#include "base/memory/scoped_ptr.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/gles2_lib.h"
+#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/demos/framework/demo.h"
#include "gpu/demos/framework/demo_factory.h"
@@ -19,6 +20,7 @@ using gpu::CommandBufferService;
using gpu::GpuScheduler;
using gpu::gles2::GLES2CmdHelper;
using gpu::gles2::GLES2Implementation;
+using gpu::TransferBuffer;
namespace {
const int32 kCommandBufferSize = 1024 * 1024;
@@ -103,19 +105,24 @@ bool Window::CreateRenderContext(gfx::PluginWindowHandle hwnd) {
if (!gles2_cmd_helper_->Initialize(kCommandBufferSize))
return false;
- int32 transfer_buffer_id =
- command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1);
- Buffer transfer_buffer =
- command_buffer_->GetTransferBuffer(transfer_buffer_id);
- if (transfer_buffer.ptr == NULL) return false;
+ transfer_buffer_.reset(new gpu::TransferBuffer(gles2_cmd_helper_.get()));
::gles2::Initialize();
- ::gles2::SetGLContext(new GLES2Implementation(gles2_cmd_helper_.get(),
- transfer_buffer.size,
- transfer_buffer.ptr,
- transfer_buffer_id,
- false,
- true));
+ GLES2Implementation* gles2_implementation = new GLES2Implementation(
+ gles2_cmd_helper_.get(),
+ transfer_buffer_.get(),
+ false,
+ true);
+
+ ::gles2::SetGLContext(gles2_implementation);
+
+ if (!gles2_implementation->Initialize(
+ kTransferBufferSize,
+ kTransferBufferSize,
+ kTransferBufferSize)) {
+ return false;
+ }
+
return true;
}
diff --git a/gpu/demos/framework/window.h b/gpu/demos/framework/window.h
index 4c6cd46..80b8b67 100644
--- a/gpu/demos/framework/window.h
+++ b/gpu/demos/framework/window.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,6 +15,9 @@
#include "ui/gfx/native_widget_types.h"
namespace gpu {
+
+class TransferBuffer;
+
namespace demos {
class Demo;
@@ -52,6 +55,7 @@ class Window {
scoped_refptr<gfx::GLContext> context_;
scoped_refptr<gfx::GLSurface> surface_;
scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper_;
+ scoped_ptr<gpu::TransferBuffer> transfer_buffer_;
DISALLOW_COPY_AND_ASSIGN(Window);
};
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc
index 47fcd51..1b540f4 100644
--- a/gpu/gles2_conform_support/egl/display.cc
+++ b/gpu/gles2_conform_support/egl/display.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "gpu/command_buffer/client/gles2_lib.h"
+#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/gles2_conform_support/egl/config.h"
#include "gpu/gles2_conform_support/egl/surface.h"
@@ -21,8 +22,7 @@ namespace egl {
Display::Display(EGLNativeDisplayType display_id)
: display_id_(display_id),
- is_initialized_(false),
- transfer_buffer_id_(-1) {
+ is_initialized_(false) {
}
Display::~Display() {
@@ -131,15 +131,11 @@ EGLSurface Display::CreateWindowSurface(EGLConfig config,
if (!cmd_helper->Initialize(kCommandBufferSize))
return false;
- int32 transfer_buffer_id =
- command_buffer->CreateTransferBuffer(kTransferBufferSize, -1);
- gpu::Buffer transfer_buffer =
- command_buffer->GetTransferBuffer(transfer_buffer_id);
- if (transfer_buffer.ptr == NULL)
- return false;
+ scoped_ptr<gpu::TransferBuffer> transfer_buffer(new gpu::TransferBuffer(
+ cmd_helper.get()));
command_buffer_.reset(command_buffer.release());
- transfer_buffer_id_ = transfer_buffer_id;
+ transfer_buffer_.reset(transfer_buffer.release());
gles2_cmd_helper_.reset(cmd_helper.release());
surface_.reset(new Surface(win));
@@ -171,23 +167,26 @@ EGLContext Display::CreateContext(EGLConfig config,
EGLContext share_ctx,
const EGLint* attrib_list) {
DCHECK(IsValidConfig(config));
- // TODO(alokp): Command buffer does not support shared contexts.
+ // TODO(alokp): Add support for shared contexts.
if (share_ctx != NULL)
return EGL_NO_CONTEXT;
DCHECK(command_buffer_ != NULL);
- DCHECK(transfer_buffer_id_ != -1);
- gpu::Buffer buffer = command_buffer_->GetTransferBuffer(transfer_buffer_id_);
- DCHECK(buffer.ptr != NULL);
+ DCHECK(transfer_buffer_.get());
bool share_resources = share_ctx != NULL;
context_.reset(new gpu::gles2::GLES2Implementation(
gles2_cmd_helper_.get(),
- buffer.size,
- buffer.ptr,
- transfer_buffer_id_,
+ transfer_buffer_.get(),
share_resources,
true));
+ if (!context_->Initialize(
+ kTransferBufferSize / 2,
+ kTransferBufferSize,
+ kTransferBufferSize * 2)) {
+ return EGL_NO_CONTEXT;
+ }
+
context_->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets");
context_->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs");
diff --git a/gpu/gles2_conform_support/egl/display.h b/gpu/gles2_conform_support/egl/display.h
index 19571b3..f7e20e8 100644
--- a/gpu/gles2_conform_support/egl/display.h
+++ b/gpu/gles2_conform_support/egl/display.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -19,6 +19,7 @@
namespace gpu {
class CommandBufferService;
class GpuScheduler;
+class TransferBuffer;
namespace gles2 {
class GLES2CmdHelper;
@@ -71,7 +72,7 @@ class Display {
scoped_refptr<gfx::GLContext> gl_context_;
scoped_refptr<gfx::GLSurface> gl_surface_;
scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper_;
- int32 transfer_buffer_id_;
+ scoped_ptr<gpu::TransferBuffer> transfer_buffer_;
// TODO(alokp): Support more than one config, surface, and context.
scoped_ptr<Config> config_;
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp
index f9f945b..c24c4d1 100644
--- a/gpu/gpu.gyp
+++ b/gpu/gpu.gyp
@@ -51,6 +51,7 @@
'command_buffer/common/cmd_buffer_common.h',
'command_buffer/common/cmd_buffer_common.cc',
'command_buffer/common/command_buffer.h',
+ 'command_buffer/common/compiler_specific.h',
'command_buffer/common/constants.h',
'command_buffer/common/gles2_cmd_ids_autogen.h',
'command_buffer/common/gles2_cmd_ids.h',
@@ -198,6 +199,8 @@
'command_buffer/client/mapped_memory.h',
'command_buffer/client/ring_buffer.cc',
'command_buffer/client/ring_buffer.h',
+ 'command_buffer/client/transfer_buffer.cc',
+ 'command_buffer/client/transfer_buffer.h',
],
},
{
@@ -302,12 +305,15 @@
],
'sources': [
'<@(gles2_c_lib_source_files)',
+ 'command_buffer/client/client_test_helper.cc',
+ 'command_buffer/client/client_test_helper.h',
'command_buffer/client/cmd_buffer_helper_test.cc',
'command_buffer/client/fenced_allocator_test.cc',
'command_buffer/client/gles2_implementation_unittest.cc',
'command_buffer/client/mapped_memory_unittest.cc',
'command_buffer/client/program_info_manager_unittest.cc',
'command_buffer/client/ring_buffer_test.cc',
+ 'command_buffer/client/transfer_buffer_unittest.cc',
'command_buffer/common/bitfield_helpers_test.cc',
'command_buffer/common/command_buffer_mock.cc',
'command_buffer/common/command_buffer_mock.h',
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/nacl.scons b/ppapi/native_client/src/shared/ppapi_proxy/nacl.scons
index 2bfed5d..050e419 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/nacl.scons
+++ b/ppapi/native_client/src/shared/ppapi_proxy/nacl.scons
@@ -35,6 +35,7 @@ command_buffer_client_srcs = [
'command_buffer/client/gles2_lib.cc',
'command_buffer/client/mapped_memory.cc',
'command_buffer/client/ring_buffer.cc',
+ 'command_buffer/client/transfer_buffer.cc',
'command_buffer/common/id_allocator.cc',
]
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.cc
index 2fc4bd6..a3220f9 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.cc
@@ -7,6 +7,7 @@
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "gpu/command_buffer/client/transfer_buffer.h"
#include "native_client/src/shared/ppapi_proxy/command_buffer_nacl.h"
#include "native_client/src/shared/ppapi_proxy/object_serialize.h"
#include "native_client/src/shared/ppapi_proxy/plugin_callback.h"
@@ -25,8 +26,10 @@ namespace ppapi_proxy {
namespace {
-const int32 kRingBufferSize = 4096 * 1024;
-const int32 kTransferBufferSize = 4096 * 1024;
+const size_t kRingBufferSize = 4 * 1024 * 1024;
+const size_t kStartTransferBufferSize = 4 * 1024 * 1024;
+const size_t kMinTransferBufferSize = 256 * 1024;
+const size_t kMaxTransferBufferSize = 16 * 1024 * 1024;
int32_t GetNumAttribs(const int32_t* attrib_list) {
int32_t num = 0;
@@ -181,6 +184,7 @@ PluginGraphics3D::~PluginGraphics3D() {
DebugPrintf("PluginGraphics3D::~PluginGraphics3D()\n");
// Explicitly tear down scopted pointers; ordering below matters.
gles2_implementation_.reset();
+ transfer_buffer_.reset();
gles2_helper_.reset();
command_buffer_.reset();
// Invalidate the cache.
@@ -213,19 +217,16 @@ bool PluginGraphics3D::InitFromBrowserResource(PP_Resource res) {
if (command_buffer_->Initialize()) {
gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get()));
if (gles2_helper_->Initialize(kRingBufferSize)) {
- // Request id -1 to signify 'don't care'
- int32 transfer_buffer_id =
- command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1);
- gpu::Buffer transfer_buffer =
- command_buffer_->GetTransferBuffer(transfer_buffer_id);
- if (transfer_buffer.ptr) {
- gles2_implementation_.reset(new gpu::gles2::GLES2Implementation(
- gles2_helper_.get(),
- transfer_buffer.size,
- transfer_buffer.ptr,
- transfer_buffer_id,
- false,
- true));
+ transfer_buffer_.reset(new gpu::TransferBuffer(gles2_helper_.get()));
+ gles2_implementation_.reset(new gpu::gles2::GLES2Implementation(
+ gles2_helper_.get(),
+ transfer_buffer_.get(),
+ false,
+ true));
+ if (gles2_implementation_->Initialize(
+ kStartTransferBufferSize,
+ kMinTransferBufferSize,
+ kMaxTransferBufferSize)) {
return true;
}
}
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.h
index 115cc25..84af986 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.h
+++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,6 +15,7 @@
namespace gpu {
class CommandBuffer;
+class TransferBuffer;
namespace gles2 {
class GLES2CmdHelper;
class GLES2Implementation;
@@ -63,6 +64,7 @@ class PluginGraphics3D : public PluginResource {
// GLES2 Implementation objects.
scoped_ptr<gpu::CommandBuffer> command_buffer_;
scoped_ptr<gpu::gles2::GLES2Implementation> gles2_implementation_;
+ scoped_ptr<gpu::TransferBuffer> transfer_buffer_;
scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_;
PP_Instance instance_id_;
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy_untrusted.gyp b/ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy_untrusted.gyp
index 58dad08..80f2a11 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy_untrusted.gyp
+++ b/ppapi/native_client/src/shared/ppapi_proxy/ppapi_proxy_untrusted.gyp
@@ -34,6 +34,7 @@
'<(DEPTH)/gpu/command_buffer/client/gles2_cmd_helper.cc',
'<(DEPTH)/gpu/command_buffer/client/gles2_implementation.cc',
'<(DEPTH)/gpu/command_buffer/client/program_info_manager.cc',
+ '<(DEPTH)/gpu/command_buffer/client/transfer_buffer.cc',
'<(DEPTH)/gpu/command_buffer/client/gles2_lib.cc',
'<(DEPTH)/gpu/command_buffer/client/mapped_memory.cc',
'<(DEPTH)/gpu/command_buffer/client/ring_buffer.cc',
diff --git a/ppapi/shared_impl/ppb_graphics_3d_shared.cc b/ppapi/shared_impl/ppb_graphics_3d_shared.cc
index d444516..37b3d0b 100644
--- a/ppapi/shared_impl/ppb_graphics_3d_shared.cc
+++ b/ppapi/shared_impl/ppb_graphics_3d_shared.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,24 +7,23 @@
#include "base/logging.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "gpu/command_buffer/client/transfer_buffer.h"
#include "ppapi/c/pp_errors.h"
namespace ppapi {
PPB_Graphics3D_Shared::PPB_Graphics3D_Shared(PP_Instance instance)
- : Resource(instance),
- transfer_buffer_id_(-1) {
+ : Resource(instance) {
}
PPB_Graphics3D_Shared::PPB_Graphics3D_Shared(const HostResource& host_resource)
- : Resource(host_resource),
- transfer_buffer_id_(-1) {
+ : Resource(host_resource) {
}
PPB_Graphics3D_Shared::~PPB_Graphics3D_Shared() {
// Make sure that GLES2 implementation has already been destroyed.
- DCHECK_EQ(transfer_buffer_id_, -1);
DCHECK(!gles2_helper_.get());
+ DCHECK(!transfer_buffer_.get());
DCHECK(!gles2_impl_.get());
}
@@ -110,39 +109,30 @@ bool PPB_Graphics3D_Shared::CreateGLES2Impl(int32 command_buffer_size,
// Create a transfer buffer used to copy resources between the renderer
// process and the GPU process.
- transfer_buffer_id_ =
- command_buffer->CreateTransferBuffer(transfer_buffer_size, -1);
- if (transfer_buffer_id_ < 0)
- return false;
-
- // Map the buffer into the renderer process's address space.
- gpu::Buffer transfer_buffer =
- command_buffer->GetTransferBuffer(transfer_buffer_id_);
- if (!transfer_buffer.ptr)
- return false;
+ const int32 kMinTransferBufferSize = 256 * 1024;
+ const int32 kMaxTransferBufferSize = 16 * 1024 * 1024;
+ transfer_buffer_.reset(new gpu::TransferBuffer(gles2_helper_.get()));
// Create the object exposing the OpenGL API.
gles2_impl_.reset(new gpu::gles2::GLES2Implementation(
gles2_helper_.get(),
- transfer_buffer.size,
- transfer_buffer.ptr,
- transfer_buffer_id_,
+ transfer_buffer_.get(),
false,
true));
+ if (!gles2_impl_->Initialize(
+ transfer_buffer_size,
+ kMinTransferBufferSize,
+ std::max(kMaxTransferBufferSize, transfer_buffer_size))) {
+ return false;
+ }
+
return true;
}
void PPB_Graphics3D_Shared::DestroyGLES2Impl() {
gles2_impl_.reset();
-
- if (transfer_buffer_id_ != -1) {
- gpu::CommandBuffer* command_buffer = GetCommandBuffer();
- DCHECK(command_buffer);
- command_buffer->DestroyTransferBuffer(transfer_buffer_id_);
- transfer_buffer_id_ = -1;
- }
-
+ transfer_buffer_.reset();
gles2_helper_.reset();
}
diff --git a/ppapi/shared_impl/ppb_graphics_3d_shared.h b/ppapi/shared_impl/ppb_graphics_3d_shared.h
index 8804181..2a89e40 100644
--- a/ppapi/shared_impl/ppb_graphics_3d_shared.h
+++ b/ppapi/shared_impl/ppb_graphics_3d_shared.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,6 +15,7 @@
namespace gpu {
class CommandBuffer;
+class TransferBuffer;
namespace gles2 {
class GLES2CmdHelper;
class GLES2Implementation;
@@ -68,8 +69,8 @@ class PPAPI_SHARED_EXPORT PPB_Graphics3D_Shared
void DestroyGLES2Impl();
private:
- int32 transfer_buffer_id_;
scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_;
+ scoped_ptr<gpu::TransferBuffer> transfer_buffer_;
scoped_ptr<gpu::gles2::GLES2Implementation> gles2_impl_;
// Callback that needs to be executed when swap-buffers is completed.
diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
index 510f642..c2c0f39 100644
--- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
+++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
@@ -28,6 +28,7 @@
#include "base/synchronization/lock.h"
#include "gpu/command_buffer/client/gles2_lib.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/constants.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/gpu_scheduler.h"
@@ -46,6 +47,7 @@ using gpu::CommandBufferService;
using gpu::gles2::GLES2CmdHelper;
using gpu::gles2::GLES2Implementation;
using gpu::GpuScheduler;
+using gpu::TransferBuffer;
namespace webkit {
namespace gpu {
@@ -190,7 +192,7 @@ class GLInProcessContext : public base::SupportsWeakPtr<GLInProcessContext> {
scoped_refptr<gfx::GLContext> context_;
scoped_refptr<gfx::GLSurface> surface_;
scoped_ptr<GLES2CmdHelper> gles2_helper_;
- int32 transfer_buffer_id_;
+ scoped_ptr<TransferBuffer> transfer_buffer_;
scoped_ptr<GLES2Implementation> gles2_implementation_;
Error last_error_;
@@ -202,7 +204,9 @@ namespace {
const int32 kCommandBufferSize = 1024 * 1024;
// TODO(kbr): make the transfer buffer size configurable via context
// creation attributes.
-const int32 kTransferBufferSize = 1024 * 1024;
+const size_t kStartTransferBufferSize = 4 * 1024 * 1024;
+const size_t kMinTransferBufferSize = 1 * 256 * 1024;
+const size_t kMaxTransferBufferSize = 16 * 1024 * 1024;
static base::LazyInstance<
std::set<WebGraphicsContext3DInProcessCommandBufferImpl*> >
@@ -392,7 +396,6 @@ GLInProcessContext::GLInProcessContext(GLInProcessContext* parent)
: parent_(parent ?
parent->AsWeakPtr() : base::WeakPtr<GLInProcessContext>()),
parent_texture_id_(0),
- transfer_buffer_id_(-1),
last_error_(SUCCESS) {
}
@@ -529,31 +532,22 @@ bool GLInProcessContext::Initialize(bool onscreen,
}
// Create a transfer buffer.
- transfer_buffer_id_ =
- command_buffer_->CreateTransferBuffer(
- kTransferBufferSize, ::gpu::kCommandBufferSharedMemoryId);
- if (transfer_buffer_id_ < 0) {
- Destroy();
- return false;
- }
-
- // Map the buffer.
- Buffer transfer_buffer =
- command_buffer_->GetTransferBuffer(transfer_buffer_id_);
- if (!transfer_buffer.ptr) {
- Destroy();
- return false;
- }
+ transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get()));
// Create the object exposing the OpenGL API.
gles2_implementation_.reset(new GLES2Implementation(
gles2_helper_.get(),
- transfer_buffer.size,
- transfer_buffer.ptr,
- transfer_buffer_id_,
+ transfer_buffer_.get(),
true,
false));
+ if (!gles2_implementation_->Initialize(
+ kStartTransferBufferSize,
+ kMinTransferBufferSize,
+ kMaxTransferBufferSize)) {
+ return false;
+ }
+
return true;
}
@@ -574,13 +568,8 @@ void GLInProcessContext::Destroy() {
gles2_implementation_.reset();
}
- if (command_buffer_.get() && transfer_buffer_id_ != -1) {
- command_buffer_->DestroyTransferBuffer(transfer_buffer_id_);
- transfer_buffer_id_ = -1;
- }
-
+ transfer_buffer_.reset();
gles2_helper_.reset();
-
command_buffer_.reset();
}