summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/client/transfer_buffer_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gpu/command_buffer/client/transfer_buffer_unittest.cc')
-rw-r--r--gpu/command_buffer/client/transfer_buffer_unittest.cc434
1 files changed, 434 insertions, 0 deletions
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
+
+