| // 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 <stddef.h> | |
| #include <stdint.h> | |
| #include <memory> | |
| #include "base/compiler_specific.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 "testing/gmock/include/gmock/gmock.h" | |
| #include "testing/gtest/include/gtest/gtest.h" | |
| using ::testing::_; | |
| using ::testing::AtMost; | |
| using ::testing::Invoke; | |
| using ::testing::Return; | |
| using ::testing::SetArgPointee; | |
| using ::testing::StrictMock; | |
| namespace gpu { | |
| class TransferBufferTest : public testing::Test { | |
| protected: | |
| static const int32_t kNumCommandEntries = 400; | |
| static const int32_t 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) { | |
| } | |
| void SetUp() override; | |
| void TearDown() override; | |
| virtual void Initialize(unsigned int size_to_flush) { | |
| ASSERT_TRUE(transfer_buffer_->Initialize( | |
| kTransferBufferSize, | |
| kStartingOffset, | |
| kTransferBufferSize, | |
| kTransferBufferSize, | |
| kAlignment, | |
| size_to_flush)); | |
| } | |
| MockClientCommandBufferMockFlush* command_buffer() const { | |
| return command_buffer_.get(); | |
| } | |
| std::unique_ptr<MockClientCommandBufferMockFlush> command_buffer_; | |
| std::unique_ptr<CommandBufferHelper> helper_; | |
| std::unique_ptr<TransferBuffer> transfer_buffer_; | |
| int32_t transfer_buffer_id_; | |
| }; | |
| void TransferBufferTest::SetUp() { | |
| command_buffer_.reset(new StrictMock<MockClientCommandBufferMockFlush>()); | |
| helper_.reset(new CommandBufferHelper(command_buffer())); | |
| ASSERT_EQ(helper_->Initialize(kCommandBufferSizeBytes), | |
| gpu::ContextResult::kSuccess); | |
| transfer_buffer_id_ = command_buffer()->GetNextFreeTransferBufferId(); | |
| transfer_buffer_.reset(new TransferBuffer(helper_.get())); | |
| } | |
| void TransferBufferTest::TearDown() { | |
| if (transfer_buffer_->HaveBuffer()) { | |
| EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) | |
| .Times(1) | |
| .RetiresOnSaturation(); | |
| } | |
| // For command buffer. | |
| EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) | |
| .Times(1) | |
| .RetiresOnSaturation(); | |
| EXPECT_CALL(*command_buffer(), OnFlush()).Times(AtMost(1)); | |
| EXPECT_CALL(*command_buffer(), Flush(_)).Times(AtMost(1)); | |
| transfer_buffer_.reset(); | |
| } | |
| // GCC requires these declarations, but MSVC requires they not be present | |
| #ifndef _MSC_VER | |
| const int32_t TransferBufferTest::kNumCommandEntries; | |
| const int32_t TransferBufferTest::kCommandBufferSizeBytes; | |
| const unsigned int TransferBufferTest::kStartingOffset; | |
| const unsigned int TransferBufferTest::kAlignment; | |
| const size_t TransferBufferTest::kTransferBufferSize; | |
| #endif | |
| TEST_F(TransferBufferTest, Basic) { | |
| Initialize(0); | |
| EXPECT_TRUE(transfer_buffer_->HaveBuffer()); | |
| EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); | |
| EXPECT_EQ( | |
| kTransferBufferSize - kStartingOffset, | |
| transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc()); | |
| EXPECT_NE(base::UnguessableToken(), | |
| transfer_buffer_->shared_memory_handle().GetGUID()); | |
| } | |
| TEST_F(TransferBufferTest, Free) { | |
| Initialize(0); | |
| EXPECT_TRUE(transfer_buffer_->HaveBuffer()); | |
| EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); | |
| EXPECT_NE(base::UnguessableToken(), | |
| transfer_buffer_->shared_memory_handle().GetGUID()); | |
| // Free buffer. | |
| EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) | |
| .Times(1) | |
| .RetiresOnSaturation(); | |
| transfer_buffer_->Free(); | |
| // See it's freed. | |
| EXPECT_FALSE(transfer_buffer_->HaveBuffer()); | |
| EXPECT_EQ(base::UnguessableToken(), | |
| transfer_buffer_->shared_memory_handle().GetGUID()); | |
| // See that it gets reallocated. | |
| EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); | |
| EXPECT_TRUE(transfer_buffer_->HaveBuffer()); | |
| EXPECT_NE(base::UnguessableToken(), | |
| transfer_buffer_->shared_memory_handle().GetGUID()); | |
| // Free buffer. | |
| EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) | |
| .Times(1) | |
| .RetiresOnSaturation(); | |
| transfer_buffer_->Free(); | |
| // See it's freed. | |
| EXPECT_FALSE(transfer_buffer_->HaveBuffer()); | |
| EXPECT_EQ(base::UnguessableToken(), | |
| transfer_buffer_->shared_memory_handle().GetGUID()); | |
| // See that it gets reallocated. | |
| EXPECT_TRUE(transfer_buffer_->GetResultBuffer() != NULL); | |
| EXPECT_TRUE(transfer_buffer_->HaveBuffer()); | |
| EXPECT_NE(base::UnguessableToken(), | |
| transfer_buffer_->shared_memory_handle().GetGUID()); | |
| // Free buffer. | |
| EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) | |
| .Times(1) | |
| .RetiresOnSaturation(); | |
| transfer_buffer_->Free(); | |
| // See it's freed. | |
| EXPECT_FALSE(transfer_buffer_->HaveBuffer()); | |
| EXPECT_EQ(base::UnguessableToken(), | |
| transfer_buffer_->shared_memory_handle().GetGUID()); | |
| // 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()); | |
| EXPECT_NE(base::UnguessableToken(), | |
| transfer_buffer_->shared_memory_handle().GetGUID()); | |
| int32_t token = helper_->InsertToken(); | |
| int32_t put_offset = helper_->GetPutOffsetForTest(); | |
| transfer_buffer_->FreePendingToken(data, token); | |
| // Free buffer. Should cause a Flush. | |
| EXPECT_CALL(*command_buffer(), Flush(_)).Times(AtMost(1)); | |
| EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) | |
| .Times(1) | |
| .RetiresOnSaturation(); | |
| transfer_buffer_->Free(); | |
| // See it's freed. | |
| EXPECT_FALSE(transfer_buffer_->HaveBuffer()); | |
| EXPECT_EQ(base::UnguessableToken(), | |
| transfer_buffer_->shared_memory_handle().GetGUID()); | |
| // Free should have flushed. | |
| EXPECT_EQ(put_offset, command_buffer_->GetServicePutOffset()); | |
| // However it shouldn't have caused a finish. | |
| EXPECT_LT(command_buffer_->GetState().get_offset, put_offset); | |
| // See that it gets reallocated. | |
| transfer_buffer_->GetResultOffset(); | |
| EXPECT_TRUE(transfer_buffer_->HaveBuffer()); | |
| EXPECT_NE(base::UnguessableToken(), | |
| transfer_buffer_->shared_memory_handle().GetGUID()); | |
| EXPECT_EQ( | |
| kTransferBufferSize - kStartingOffset, | |
| transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc()); | |
| // Test freeing twice. | |
| EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) | |
| .Times(1) | |
| .RetiresOnSaturation(); | |
| transfer_buffer_->Free(); | |
| transfer_buffer_->Free(); | |
| } | |
| TEST_F(TransferBufferTest, TooLargeAllocation) { | |
| Initialize(0); | |
| // 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); | |
| } | |
| TEST_F(TransferBufferTest, MemoryAlignmentAfterZeroAllocation) { | |
| Initialize(32u); | |
| void* ptr = transfer_buffer_->Alloc(0); | |
| EXPECT_EQ((reinterpret_cast<uintptr_t>(ptr) & (kAlignment - 1)), 0u); | |
| transfer_buffer_->FreePendingToken(ptr, helper_->InsertToken()); | |
| // Check that the pointer is aligned on the following allocation. | |
| ptr = transfer_buffer_->Alloc(4); | |
| EXPECT_EQ((reinterpret_cast<uintptr_t>(ptr) & (kAlignment - 1)), 0u); | |
| transfer_buffer_->FreePendingToken(ptr, helper_->InsertToken()); | |
| } | |
| TEST_F(TransferBufferTest, Flush) { | |
| Initialize(16u); | |
| unsigned int size_allocated = 0; | |
| for (int i = 0; i < 8; ++i) { | |
| void* ptr = transfer_buffer_->AllocUpTo(8u, &size_allocated); | |
| ASSERT_TRUE(ptr != NULL); | |
| EXPECT_EQ(8u, size_allocated); | |
| if (i % 2) { | |
| EXPECT_CALL(*command_buffer(), Flush(_)) | |
| .Times(1) | |
| .RetiresOnSaturation(); | |
| } | |
| transfer_buffer_->FreePendingToken(ptr, helper_->InsertToken()); | |
| } | |
| for (int i = 0; i < 8; ++i) { | |
| void* ptr = transfer_buffer_->Alloc(8u); | |
| ASSERT_TRUE(ptr != NULL); | |
| if (i % 2) { | |
| EXPECT_CALL(*command_buffer(), Flush(_)) | |
| .Times(1) | |
| .RetiresOnSaturation(); | |
| } | |
| transfer_buffer_->FreePendingToken(ptr, helper_->InsertToken()); | |
| } | |
| } | |
| class MockClientCommandBufferCanFail : public MockClientCommandBufferMockFlush { | |
| public: | |
| MockClientCommandBufferCanFail() { | |
| } | |
| virtual ~MockClientCommandBufferCanFail() { | |
| } | |
| MOCK_METHOD2(CreateTransferBuffer, | |
| scoped_refptr<Buffer>(size_t size, int32_t* id)); | |
| scoped_refptr<gpu::Buffer> RealCreateTransferBuffer(size_t size, | |
| int32_t* id) { | |
| return MockClientCommandBufferMockFlush::CreateTransferBuffer(size, id); | |
| } | |
| }; | |
| class TransferBufferExpandContractTest : public testing::Test { | |
| protected: | |
| static const int32_t kNumCommandEntries = 400; | |
| static const int32_t 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) { | |
| } | |
| void SetUp() override; | |
| void TearDown() override; | |
| MockClientCommandBufferCanFail* command_buffer() const { | |
| return command_buffer_.get(); | |
| } | |
| std::unique_ptr<MockClientCommandBufferCanFail> command_buffer_; | |
| std::unique_ptr<CommandBufferHelper> helper_; | |
| std::unique_ptr<TransferBuffer> transfer_buffer_; | |
| int32_t transfer_buffer_id_; | |
| }; | |
| void TransferBufferExpandContractTest::SetUp() { | |
| command_buffer_.reset(new StrictMock<MockClientCommandBufferCanFail>()); | |
| EXPECT_CALL(*command_buffer(), | |
| CreateTransferBuffer(kCommandBufferSizeBytes, _)) | |
| .WillOnce(Invoke( | |
| command_buffer(), | |
| &MockClientCommandBufferCanFail::RealCreateTransferBuffer)) | |
| .RetiresOnSaturation(); | |
| helper_.reset(new CommandBufferHelper(command_buffer())); | |
| ASSERT_EQ(helper_->Initialize(kCommandBufferSizeBytes), | |
| gpu::ContextResult::kSuccess); | |
| 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, | |
| 0)); | |
| } | |
| void TransferBufferExpandContractTest::TearDown() { | |
| if (transfer_buffer_->HaveBuffer()) { | |
| EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) | |
| .Times(1) | |
| .RetiresOnSaturation(); | |
| } | |
| // For command buffer. | |
| 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_t TransferBufferExpandContractTest::kNumCommandEntries; | |
| const int32_t 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(), 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(), 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(), 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( | |
| DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>()))) | |
| .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(), 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(), 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( | |
| DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>()))) | |
| .WillOnce( | |
| DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>()))) | |
| .WillOnce( | |
| DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>()))) | |
| .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()); | |
| } | |
| TEST_F(TransferBufferExpandContractTest, ReallocsToDefault) { | |
| // 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_CALL(*command_buffer(), | |
| CreateTransferBuffer(kStartTransferBufferSize, _)) | |
| .WillOnce(Invoke( | |
| command_buffer(), | |
| &MockClientCommandBufferCanFail::RealCreateTransferBuffer)) | |
| .RetiresOnSaturation(); | |
| EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); | |
| EXPECT_TRUE(transfer_buffer_->HaveBuffer()); | |
| // Check it's the default size. | |
| EXPECT_EQ( | |
| kStartTransferBufferSize - kStartingOffset, | |
| transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc()); | |
| } | |
| TEST_F(TransferBufferExpandContractTest, Shrink) { | |
| unsigned int alloc_size = transfer_buffer_->GetFreeSize(); | |
| EXPECT_EQ(kStartTransferBufferSize - kStartingOffset, alloc_size); | |
| unsigned int size_allocated = 0; | |
| void* ptr = transfer_buffer_->AllocUpTo(alloc_size, &size_allocated); | |
| ASSERT_NE(ptr, nullptr); | |
| EXPECT_EQ(alloc_size, size_allocated); | |
| EXPECT_GT(alloc_size, 0u); | |
| EXPECT_EQ(0u, transfer_buffer_->GetFreeSize()); | |
| // Shrink once. | |
| const unsigned int shrink_size1 = 80; | |
| EXPECT_LT(shrink_size1, alloc_size); | |
| transfer_buffer_->ShrinkLastBlock(shrink_size1); | |
| EXPECT_EQ(alloc_size - shrink_size1, transfer_buffer_->GetFreeSize()); | |
| // Shrink again. | |
| const unsigned int shrink_size2 = 30; | |
| EXPECT_LT(shrink_size2, shrink_size1); | |
| transfer_buffer_->ShrinkLastBlock(shrink_size2); | |
| EXPECT_EQ(alloc_size - shrink_size2, transfer_buffer_->GetFreeSize()); | |
| // Shrink to zero (minimum size is 1). | |
| transfer_buffer_->ShrinkLastBlock(0); | |
| EXPECT_EQ(alloc_size - 1, transfer_buffer_->GetFreeSize()); | |
| transfer_buffer_->FreePendingToken(ptr, 1); | |
| } | |
| } // namespace gpu |