| 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
|
|
|
|
|