// 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 "base/callback.h" #include "base/scoped_nsautorelease_pool.h" #include "base/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::ScopedNSAutoreleasePool autorelease_pool_; scoped_ptr 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 { public: MOCK_METHOD1(RunWithParams, void(const Tuple0&)); }; TEST_F(CommandBufferServiceTest, CanSyncGetAndPutOffset) { command_buffer_->Initialize(1024); StrictMock* put_offset_change_callback = new StrictMock; 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