| Index: gpu/command_buffer/client/ring_buffer_test.cc
|
| ===================================================================
|
| --- gpu/command_buffer/client/ring_buffer_test.cc (revision 0)
|
| +++ gpu/command_buffer/client/ring_buffer_test.cc (revision 0)
|
| @@ -0,0 +1,256 @@
|
| +// Copyright (c) 2010 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.
|
| +
|
| +// This file contains the tests for the RingBuffer class.
|
| +
|
| +#include "gpu/command_buffer/client/ring_buffer.h"
|
| +#include "base/at_exit.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/cmd_buffer_engine.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 BaseRingBufferTest : public testing::Test {
|
| + protected:
|
| + static const unsigned int kBaseOffset = 128;
|
| + 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 / sizeof(CommandBufferEntry));
|
| + 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();
|
| + }
|
| +
|
| + int32 GetToken() {
|
| + return command_buffer_->GetState().token;
|
| + }
|
| +
|
| + virtual void TearDown() {
|
| + helper_.release();
|
| + }
|
| +
|
| + base::ScopedNSAutoreleasePool autorelease_pool_;
|
| + base::AtExitManager at_exit_manager_;
|
| + 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 COMPILER_MSVC
|
| +const unsigned int BaseRingBufferTest::kBaseOffset;
|
| +const unsigned int BaseRingBufferTest::kBufferSize;
|
| +#endif
|
| +
|
| +// Test fixture for RingBuffer test - Creates a RingBuffer, 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 RingBufferTest : public BaseRingBufferTest {
|
| + protected:
|
| + virtual void SetUp() {
|
| + BaseRingBufferTest::SetUp();
|
| + allocator_.reset(new RingBuffer(kBaseOffset, kBufferSize, helper_.get()));
|
| + }
|
| +
|
| + virtual void TearDown() {
|
| + // If the GPUProcessor posts any tasks, this forces them to run.
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + allocator_.release();
|
| +
|
| + BaseRingBufferTest::TearDown();
|
| + }
|
| +
|
| + scoped_ptr<RingBuffer> allocator_;
|
| +};
|
| +
|
| +// Checks basic alloc and free.
|
| +TEST_F(RingBufferTest, TestBasic) {
|
| + const unsigned int kSize = 16;
|
| + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize());
|
| + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSizeNoWaiting());
|
| + RingBuffer::Offset offset = allocator_->Alloc(kSize);
|
| + EXPECT_GE(kBufferSize, offset - kBaseOffset + kSize);
|
| + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize());
|
| + EXPECT_EQ(kBufferSize - kSize, allocator_->GetLargestFreeSizeNoWaiting());
|
| + int32 token = helper_.get()->InsertToken();
|
| + allocator_->FreePendingToken(offset, token);
|
| +}
|
| +
|
| +// Checks the free-pending-token mechanism.
|
| +TEST_F(RingBufferTest, TestFreePendingToken) {
|
| + const unsigned int kSize = 16;
|
| + const unsigned int kAllocCount = kBufferSize / kSize;
|
| + CHECK(kAllocCount * kSize == kBufferSize);
|
| +
|
| + // Allocate several buffers to fill in the memory.
|
| + int32 tokens[kAllocCount];
|
| + for (unsigned int ii = 0; ii < kAllocCount; ++ii) {
|
| + RingBuffer::Offset offset = allocator_->Alloc(kSize);
|
| + EXPECT_GE(kBufferSize, offset - kBaseOffset + kSize);
|
| + tokens[ii] = helper_.get()->InsertToken();
|
| + allocator_->FreePendingToken(offset, tokens[ii]);
|
| + }
|
| +
|
| + EXPECT_EQ(kBufferSize - (kSize * kAllocCount),
|
| + allocator_->GetLargestFreeSizeNoWaiting());
|
| +
|
| + // This allocation will need to reclaim the space freed above, so that should
|
| + // process the commands until a token is passed.
|
| + RingBuffer::Offset offset1 = allocator_->Alloc(kSize);
|
| + EXPECT_EQ(kBaseOffset, offset1);
|
| +
|
| + // Check that the token has indeed passed.
|
| + EXPECT_LE(tokens[0], GetToken());
|
| +
|
| + allocator_->FreePendingToken(offset1, helper_.get()->InsertToken());
|
| +}
|
| +
|
| +// Tests GetLargestFreeSizeNoWaiting
|
| +TEST_F(RingBufferTest, TestGetLargestFreeSizeNoWaiting) {
|
| + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSizeNoWaiting());
|
| +
|
| + RingBuffer::Offset offset = allocator_->Alloc(kBufferSize);
|
| + EXPECT_EQ(0u, allocator_->GetLargestFreeSizeNoWaiting());
|
| + allocator_->FreePendingToken(offset, helper_.get()->InsertToken());
|
| +}
|
| +
|
| +// Test fixture for RingBufferWrapper test - Creates a
|
| +// RingBufferWrapper, 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 RingBufferWrapperTest : public BaseRingBufferTest {
|
| + protected:
|
| + virtual void SetUp() {
|
| + BaseRingBufferTest::SetUp();
|
| +
|
| + // Though allocating this buffer isn't strictly necessary, it makes
|
| + // allocations point to valid addresses, so they could be used for
|
| + // something.
|
| + buffer_.reset(new int8[kBufferSize + kBaseOffset]);
|
| + buffer_start_ = buffer_.get() + kBaseOffset;
|
| + allocator_.reset(new RingBufferWrapper(
|
| + kBaseOffset, kBufferSize, helper_.get(), buffer_start_));
|
| + }
|
| +
|
| + virtual void TearDown() {
|
| + // If the GPUProcessor posts any tasks, this forces them to run.
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + allocator_.release();
|
| + buffer_.release();
|
| +
|
| + BaseRingBufferTest::TearDown();
|
| + }
|
| +
|
| + scoped_ptr<RingBufferWrapper> allocator_;
|
| + scoped_array<int8> buffer_;
|
| + int8* buffer_start_;
|
| +};
|
| +
|
| +// Checks basic alloc and free.
|
| +TEST_F(RingBufferWrapperTest, TestBasic) {
|
| + const unsigned int kSize = 16;
|
| + void* pointer = allocator_->Alloc(kSize);
|
| + ASSERT_TRUE(pointer);
|
| + EXPECT_LE(buffer_start_, static_cast<int8*>(pointer));
|
| + EXPECT_GE(kBufferSize, static_cast<int8*>(pointer) - buffer_start_ + kSize);
|
| +
|
| + allocator_->FreePendingToken(pointer, helper_.get()->InsertToken());
|
| +
|
| + int8* pointer_int8 = allocator_->AllocTyped<int8>(kSize);
|
| + ASSERT_TRUE(pointer_int8);
|
| + EXPECT_LE(buffer_start_, pointer_int8);
|
| + EXPECT_GE(buffer_start_ + kBufferSize, pointer_int8 + kSize);
|
| + allocator_->FreePendingToken(pointer_int8, helper_.get()->InsertToken());
|
| +
|
| + unsigned int* pointer_uint = allocator_->AllocTyped<unsigned int>(kSize);
|
| + ASSERT_TRUE(pointer_uint);
|
| + EXPECT_LE(buffer_start_, reinterpret_cast<int8*>(pointer_uint));
|
| + EXPECT_GE(buffer_start_ + kBufferSize,
|
| + reinterpret_cast<int8* >(pointer_uint + kSize));
|
| +
|
| + // Check that it did allocate kSize * sizeof(unsigned int). We can't tell
|
| + // directly, except from the remaining size.
|
| + EXPECT_EQ(kBufferSize - kSize - kSize - kSize * sizeof(*pointer_uint),
|
| + allocator_->GetLargestFreeSizeNoWaiting());
|
| + allocator_->FreePendingToken(pointer_uint, helper_.get()->InsertToken());
|
| +}
|
| +
|
| +// Checks the free-pending-token mechanism.
|
| +TEST_F(RingBufferWrapperTest, TestFreePendingToken) {
|
| + const unsigned int kSize = 16;
|
| + const unsigned int kAllocCount = kBufferSize / kSize;
|
| + CHECK(kAllocCount * kSize == kBufferSize);
|
| +
|
| + // Allocate several buffers to fill in the memory.
|
| + int32 tokens[kAllocCount];
|
| + for (unsigned int ii = 0; ii < kAllocCount; ++ii) {
|
| + void* pointer = allocator_->Alloc(kSize);
|
| + EXPECT_TRUE(pointer != NULL);
|
| + tokens[ii] = helper_.get()->InsertToken();
|
| + allocator_->FreePendingToken(pointer, helper_.get()->InsertToken());
|
| + }
|
| +
|
| + EXPECT_EQ(kBufferSize - (kSize * kAllocCount),
|
| + allocator_->GetLargestFreeSizeNoWaiting());
|
| +
|
| + // This allocation will need to reclaim the space freed above, so that should
|
| + // process the commands until the token is passed.
|
| + void* pointer1 = allocator_->Alloc(kSize);
|
| + EXPECT_EQ(buffer_start_, static_cast<int8*>(pointer1));
|
| +
|
| + // Check that the token has indeed passed.
|
| + EXPECT_LE(tokens[0], GetToken());
|
| +
|
| + allocator_->FreePendingToken(pointer1, helper_.get()->InsertToken());
|
| +}
|
| +
|
| +} // namespace gpu
|
|
|
| Property changes on: gpu\command_buffer\client\ring_buffer_test.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|