Index: gpu/command_buffer/client/mapped_memory_unittest.cc |
=================================================================== |
--- gpu/command_buffer/client/mapped_memory_unittest.cc (revision 0) |
+++ gpu/command_buffer/client/mapped_memory_unittest.cc (revision 0) |
@@ -0,0 +1,257 @@ |
+// Copyright (c) 2009 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. |
+ |
+#include "gpu/command_buffer/client/mapped_memory.h" |
+#include "base/callback.h" |
+#include "base/message_loop.h" |
+#include "base/scoped_nsautorelease_pool.h" |
+#include "gpu/command_buffer/client/cmd_buffer_helper.h" |
+#include "gpu/command_buffer/service/mocks.h" |
+#include "gpu/command_buffer/service/command_buffer_service.h" |
+#include "gpu/command_buffer/service/gpu_processor.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace gpu { |
+ |
+using testing::Return; |
+using testing::Mock; |
+using testing::Truly; |
+using testing::Sequence; |
+using testing::DoAll; |
+using testing::Invoke; |
+using testing::_; |
+ |
+class MappedMemoryTestBase : public testing::Test { |
+ protected: |
+ static const unsigned int kBufferSize = 1024; |
+ |
+ virtual void SetUp() { |
+ api_mock_.reset(new AsyncAPIMock); |
+ // ignore noops in the mock - we don't want to inspect the internals of the |
+ // helper. |
+ EXPECT_CALL(*api_mock_, DoCommand(cmd::kNoop, 0, _)) |
+ .WillRepeatedly(Return(error::kNoError)); |
+ // Forward the SetToken calls to the engine |
+ EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _)) |
+ .WillRepeatedly(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), |
+ Return(error::kNoError))); |
+ |
+ command_buffer_.reset(new CommandBufferService); |
+ command_buffer_->Initialize(kBufferSize); |
+ Buffer ring_buffer = command_buffer_->GetRingBuffer(); |
+ |
+ parser_ = new CommandParser(ring_buffer.ptr, |
+ ring_buffer.size, |
+ 0, |
+ ring_buffer.size, |
+ 0, |
+ api_mock_.get()); |
+ |
+ gpu_processor_.reset(new GPUProcessor( |
+ command_buffer_.get(), NULL, parser_, INT_MAX)); |
+ command_buffer_->SetPutOffsetChangeCallback(NewCallback( |
+ gpu_processor_.get(), &GPUProcessor::ProcessCommands)); |
+ |
+ api_mock_->set_engine(gpu_processor_.get()); |
+ |
+ helper_.reset(new CommandBufferHelper(command_buffer_.get())); |
+ helper_->Initialize(kBufferSize); |
+ } |
+ |
+ int32 GetToken() { |
+ return command_buffer_->GetState().token; |
+ } |
+ |
+ base::ScopedNSAutoreleasePool autorelease_pool_; |
+ MessageLoop message_loop_; |
+ scoped_ptr<AsyncAPIMock> api_mock_; |
+ scoped_ptr<CommandBufferService> command_buffer_; |
+ scoped_ptr<GPUProcessor> gpu_processor_; |
+ CommandParser* parser_; |
+ scoped_ptr<CommandBufferHelper> helper_; |
+}; |
+ |
+#ifndef _MSC_VER |
+const unsigned int MappedMemoryTestBase::kBufferSize; |
+#endif |
+ |
+// Test fixture for MemoryChunk test - Creates a MemoryChunk, using a |
+// CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling |
+// it directly, not through the RPC mechanism), making sure Noops are ignored |
+// and SetToken are properly forwarded to the engine. |
+class MemoryChunkTest : public MappedMemoryTestBase { |
+ protected: |
+ static const int32 kShmId = 123; |
+ virtual void SetUp() { |
+ MappedMemoryTestBase::SetUp(); |
+ buffer_.reset(new uint8[kBufferSize]); |
+ gpu::Buffer buf; |
+ buf.size = kBufferSize; |
+ buf.ptr = buffer_.get(); |
+ chunk_ = new MemoryChunk(kShmId, buf, helper_.get()); |
+ } |
+ |
+ virtual void TearDown() { |
+ // If the GPUProcessor posts any tasks, this forces them to run. |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ MappedMemoryTestBase::TearDown(); |
+ } |
+ |
+ MemoryChunk::Ref chunk_; |
+ scoped_array<uint8> buffer_; |
+}; |
+ |
+#ifndef _MSC_VER |
+const int32 MemoryChunkTest::kShmId; |
+#endif |
+ |
+TEST_F(MemoryChunkTest, Basic) { |
+ const unsigned int kSize = 16; |
+ EXPECT_EQ(kShmId, chunk_->shm_id()); |
+ EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithoutWaiting()); |
+ EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithWaiting()); |
+ EXPECT_EQ(kBufferSize, chunk_->GetSize()); |
+ void *pointer = chunk_->Alloc(kSize); |
+ ASSERT_TRUE(pointer); |
+ EXPECT_LE(buffer_.get(), static_cast<uint8 *>(pointer)); |
+ EXPECT_GE(kBufferSize, static_cast<uint8 *>(pointer) - buffer_.get() + kSize); |
+ EXPECT_EQ(kBufferSize - kSize, chunk_->GetLargestFreeSizeWithoutWaiting()); |
+ EXPECT_EQ(kBufferSize - kSize, chunk_->GetLargestFreeSizeWithWaiting()); |
+ EXPECT_EQ(kBufferSize, chunk_->GetSize()); |
+ |
+ chunk_->Free(pointer); |
+ EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithoutWaiting()); |
+ EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithWaiting()); |
+ |
+ uint8 *pointer_char = static_cast<uint8*>(chunk_->Alloc(kSize)); |
+ ASSERT_TRUE(pointer_char); |
+ EXPECT_LE(buffer_.get(), pointer_char); |
+ EXPECT_GE(buffer_.get() + kBufferSize, pointer_char + kSize); |
+ EXPECT_EQ(kBufferSize - kSize, chunk_->GetLargestFreeSizeWithoutWaiting()); |
+ EXPECT_EQ(kBufferSize - kSize, chunk_->GetLargestFreeSizeWithWaiting()); |
+ chunk_->Free(pointer_char); |
+ EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithoutWaiting()); |
+ EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithWaiting()); |
+} |
+ |
+class MappedMemoryManagerTest : public MappedMemoryTestBase { |
+ protected: |
+ virtual void SetUp() { |
+ MappedMemoryTestBase::SetUp(); |
+ manager_.reset(new MappedMemoryManager(helper_.get())); |
+ } |
+ |
+ virtual void TearDown() { |
+ // If the GPUProcessor posts any tasks, this forces them to run. |
+ MessageLoop::current()->RunAllPending(); |
+ manager_.reset(); |
+ MappedMemoryTestBase::TearDown(); |
+ } |
+ |
+ scoped_ptr<MappedMemoryManager> manager_; |
+}; |
+ |
+TEST_F(MappedMemoryManagerTest, Basic) { |
+ const unsigned int kSize = 1024; |
+ // Check we can alloc. |
+ int32 id1 = -1; |
+ unsigned int offset1 = 0xFFFFFFFFU; |
+ void* mem1 = manager_->Alloc(kSize, &id1, &offset1); |
+ ASSERT_TRUE(mem1); |
+ EXPECT_NE(-1, id1); |
+ EXPECT_EQ(0u, offset1); |
+ // Check if we free and realloc the same size we get the same memory |
+ int32 id2 = -1; |
+ unsigned int offset2 = 0xFFFFFFFFU; |
+ manager_->Free(mem1); |
+ void* mem2 = manager_->Alloc(kSize, &id2, &offset2); |
+ EXPECT_EQ(mem1, mem2); |
+ EXPECT_EQ(id1, id2); |
+ EXPECT_EQ(offset1, offset2); |
+ // Check if we allocate again we get different shared memory |
+ int32 id3 = -1; |
+ unsigned int offset3 = 0xFFFFFFFFU; |
+ void* mem3 = manager_->Alloc(kSize, &id3, &offset3); |
+ ASSERT_TRUE(mem3 != NULL); |
+ EXPECT_NE(mem2, mem3); |
+ EXPECT_NE(id2, id3); |
+ EXPECT_EQ(0u, offset3); |
+ // Free 3 and allocate 2 half size blocks. |
+ manager_->Free(mem3); |
+ int32 id4 = -1; |
+ int32 id5 = -1; |
+ unsigned int offset4 = 0xFFFFFFFFU; |
+ unsigned int offset5 = 0xFFFFFFFFU; |
+ void* mem4 = manager_->Alloc(kSize / 2, &id4, &offset4); |
+ void* mem5 = manager_->Alloc(kSize / 2, &id5, &offset5); |
+ ASSERT_TRUE(mem4 != NULL); |
+ ASSERT_TRUE(mem5 != NULL); |
+ EXPECT_EQ(id3, id4); |
+ EXPECT_EQ(id4, id5); |
+ EXPECT_EQ(0u, offset4); |
+ EXPECT_EQ(kSize / 2u, offset5); |
+ manager_->Free(mem4); |
+ manager_->Free(mem2); |
+ manager_->Free(mem5); |
+} |
+ |
+TEST_F(MappedMemoryManagerTest, FreePendingToken) { |
+ const unsigned int kSize = 128; |
+ const unsigned int kAllocCount = (kBufferSize / kSize) * 2; |
+ CHECK(kAllocCount * kSize == kBufferSize * 2); |
+ |
+ // Allocate several buffers across multiple chunks. |
+ void *pointers[kAllocCount]; |
+ for (unsigned int i = 0; i < kAllocCount; ++i) { |
+ int32 id = -1; |
+ unsigned int offset = 0xFFFFFFFFu; |
+ pointers[i] = manager_->Alloc(kSize, &id, &offset); |
+ EXPECT_TRUE(pointers[i]); |
+ EXPECT_NE(id, -1); |
+ EXPECT_NE(offset, 0xFFFFFFFFu); |
+ } |
+ |
+ // Free one successful allocation, pending fence. |
+ int32 token = helper_.get()->InsertToken(); |
+ manager_->FreePendingToken(pointers[0], token); |
+ |
+ // The way we hooked up the helper and engine, it won't process commands |
+ // until it has to wait for something. Which means the token shouldn't have |
+ // passed yet at this point. |
+ EXPECT_GT(token, GetToken()); |
+ // Force it to read up to the token |
+ helper_->Finish(); |
+ // Check that the token has indeed passed. |
+ EXPECT_LE(token, GetToken()); |
+ |
+ // This allocation should use the spot just freed above. |
+ int32 new_id = -1; |
+ unsigned int new_offset = 0xFFFFFFFFu; |
+ void* new_ptr = manager_->Alloc(kSize, &new_id, &new_offset); |
+ EXPECT_TRUE(new_ptr); |
+ EXPECT_EQ(new_ptr, pointers[0]); |
+ EXPECT_NE(new_id, -1); |
+ EXPECT_NE(new_offset, 0xFFFFFFFFu); |
+ |
+ // Free up everything. |
+ manager_->Free(new_ptr); |
+ for (unsigned int i = 1; i < kAllocCount; ++i) { |
+ manager_->Free(pointers[i]); |
+ } |
+} |
+ |
+// Check if we don't free we don't crash. |
+TEST_F(MappedMemoryManagerTest, DontFree) { |
+ const unsigned int kSize = 1024; |
+ // Check we can alloc. |
+ int32 id1 = -1; |
+ unsigned int offset1 = 0xFFFFFFFFU; |
+ void* mem1 = manager_->Alloc(kSize, &id1, &offset1); |
+ ASSERT_TRUE(mem1); |
+} |
+ |
+} // namespace gpu |
+ |
+ |
Property changes on: gpu\command_buffer\client\mapped_memory_unittest.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |