blob: 7f06639267efc5c619665f9999e1d4763dd0e1fc [file] [log] [blame]
// 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.
#include "base/callback.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/threading/thread.h"
#include "gpu/command_buffer/common/cmd_buffer_common.h"
#include "gpu/command_buffer/service/command_buffer_service.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gmock/include/gmock/gmock.h"
using base::SharedMemory;
using testing::_;
using testing::DoAll;
using testing::Return;
using testing::SetArgumentPointee;
using testing::StrictMock;
namespace gpu {
class CommandBufferServiceTest : public testing::Test {
protected:
virtual void SetUp() {
command_buffer_.reset(new CommandBufferService);
}
int32 GetGetOffset() {
return command_buffer_->GetState().get_offset;
}
int32 GetPutOffset() {
return command_buffer_->GetState().put_offset;
}
int32 GetToken() {
return command_buffer_->GetState().token;
}
int32 GetError() {
return command_buffer_->GetState().error;
}
base::mac::ScopedNSAutoreleasePool autorelease_pool_;
scoped_ptr<CommandBufferService> command_buffer_;
};
TEST_F(CommandBufferServiceTest, NullRingBufferByDefault) {
EXPECT_TRUE(NULL == command_buffer_->GetRingBuffer().ptr);
}
TEST_F(CommandBufferServiceTest, InitializesCommandBuffer) {
EXPECT_TRUE(command_buffer_->Initialize(1024));
EXPECT_TRUE(NULL != command_buffer_->GetRingBuffer().ptr);
CommandBuffer::State state = command_buffer_->GetState();
EXPECT_EQ(1024, state.size);
EXPECT_EQ(0, state.get_offset);
EXPECT_EQ(0, state.put_offset);
EXPECT_EQ(0, state.token);
EXPECT_EQ(error::kNoError, state.error);
}
TEST_F(CommandBufferServiceTest, InitializationSizeIsInEntriesNotBytes) {
EXPECT_TRUE(command_buffer_->Initialize(1024));
EXPECT_TRUE(NULL != command_buffer_->GetRingBuffer().ptr);
EXPECT_GE(1024 * sizeof(CommandBufferEntry),
command_buffer_->GetRingBuffer().size);
}
TEST_F(CommandBufferServiceTest, InitializationFailsIfSizeIsZero) {
EXPECT_FALSE(command_buffer_->Initialize(0));
}
TEST_F(CommandBufferServiceTest, InitializationFailsIfSizeOutOfRange) {
EXPECT_FALSE(command_buffer_->Initialize(
CommandBuffer::kMaxCommandBufferSize + 1));
}
TEST_F(CommandBufferServiceTest, InitializationFailsIfSizeIsNegative) {
EXPECT_FALSE(command_buffer_->Initialize(-1));
}
TEST_F(CommandBufferServiceTest, InitializeFailsSecondTime) {
EXPECT_TRUE(command_buffer_->Initialize(1024));
EXPECT_FALSE(command_buffer_->Initialize(1024));
}
class MockCallback : public CallbackRunner<Tuple0> {
public:
MOCK_METHOD1(RunWithParams, void(const Tuple0&));
};
TEST_F(CommandBufferServiceTest, CanSyncGetAndPutOffset) {
command_buffer_->Initialize(1024);
StrictMock<MockCallback>* put_offset_change_callback =
new StrictMock<MockCallback>;
command_buffer_->SetPutOffsetChangeCallback(put_offset_change_callback);
EXPECT_CALL(*put_offset_change_callback, RunWithParams(_));
EXPECT_EQ(0, command_buffer_->Flush(2).get_offset);
EXPECT_EQ(2, GetPutOffset());
EXPECT_CALL(*put_offset_change_callback, RunWithParams(_));
EXPECT_EQ(0, command_buffer_->Flush(4).get_offset);
EXPECT_EQ(4, GetPutOffset());
command_buffer_->SetGetOffset(2);
EXPECT_EQ(2, GetGetOffset());
EXPECT_CALL(*put_offset_change_callback, RunWithParams(_));
EXPECT_EQ(2, command_buffer_->Flush(6).get_offset);
EXPECT_NE(error::kNoError, command_buffer_->Flush(-1).error);
EXPECT_NE(error::kNoError,
command_buffer_->Flush(1024).error);
}
TEST_F(CommandBufferServiceTest, ZeroHandleMapsToNull) {
EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(0).ptr);
}
TEST_F(CommandBufferServiceTest, NegativeHandleMapsToNull) {
EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(-1).ptr);
}
TEST_F(CommandBufferServiceTest, OutOfRangeHandleMapsToNull) {
EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(1).ptr);
}
TEST_F(CommandBufferServiceTest, CanCreateTransferBuffers) {
int32 handle = command_buffer_->CreateTransferBuffer(1024);
EXPECT_EQ(1, handle);
Buffer buffer = command_buffer_->GetTransferBuffer(handle);
ASSERT_TRUE(NULL != buffer.ptr);
EXPECT_EQ(1024u, buffer.size);
}
TEST_F(CommandBufferServiceTest, CreateTransferBufferReturnsDistinctHandles) {
EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024));
}
TEST_F(CommandBufferServiceTest,
CreateTransferBufferReusesUnregisteredHandles) {
EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024));
EXPECT_EQ(2, command_buffer_->CreateTransferBuffer(1024));
command_buffer_->DestroyTransferBuffer(1);
EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024));
EXPECT_EQ(3, command_buffer_->CreateTransferBuffer(1024));
}
TEST_F(CommandBufferServiceTest, CannotUnregisterHandleZero) {
command_buffer_->DestroyTransferBuffer(0);
EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(0).ptr);
EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024));
}
TEST_F(CommandBufferServiceTest, CannotUnregisterNegativeHandles) {
command_buffer_->DestroyTransferBuffer(-1);
EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024));
}
TEST_F(CommandBufferServiceTest, CannotUnregisterUnregisteredHandles) {
command_buffer_->DestroyTransferBuffer(1);
EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024));
}
// Testing this case specifically because there is an optimization that takes
// a different code path in this case.
TEST_F(CommandBufferServiceTest, UnregistersLastRegisteredHandle) {
EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024));
command_buffer_->DestroyTransferBuffer(1);
EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024));
}
// Testing this case specifically because there is an optimization that takes
// a different code path in this case.
TEST_F(CommandBufferServiceTest, UnregistersTwoLastRegisteredHandles) {
EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024));
EXPECT_EQ(2, command_buffer_->CreateTransferBuffer(1024));
command_buffer_->DestroyTransferBuffer(2);
command_buffer_->DestroyTransferBuffer(1);
EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024));
}
TEST_F(CommandBufferServiceTest, DefaultTokenIsZero) {
EXPECT_EQ(0, GetToken());
}
TEST_F(CommandBufferServiceTest, CanSetToken) {
command_buffer_->SetToken(7);
EXPECT_EQ(7, GetToken());
}
TEST_F(CommandBufferServiceTest, DefaultParseErrorIsNoError) {
EXPECT_EQ(0, GetError());
}
TEST_F(CommandBufferServiceTest, CanSetParseError) {
command_buffer_->SetParseError(error::kInvalidSize);
EXPECT_EQ(1, GetError());
}
} // namespace gpu