// Copyright (c) 2006-2008 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/thread.h" #include "o3d/gpu_plugin/command_buffer.h" #include "o3d/gpu_plugin/np_utils/np_browser_mock.h" #include "o3d/gpu_plugin/np_utils/dynamic_np_object.h" #include "o3d/gpu_plugin/np_utils/np_object_mock.h" #include "o3d/gpu_plugin/np_utils/np_object_pointer.h" #include "o3d/gpu_plugin/system_services/shared_memory_mock.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gmock/include/gmock/gmock.h" using testing::_; using testing::DoAll; using testing::Return; using testing::SetArgumentPointee; using testing::StrictMock; namespace o3d { namespace gpu_plugin { class CommandBufferTest : public testing::Test { protected: virtual void SetUp() { command_buffer_ = NPCreateObject(NULL); ring_buffer_ = NPCreateObject(NULL); ON_CALL(*ring_buffer_.Get(), GetSize()) .WillByDefault(Return(1024)); } MockNPBrowser mock_browser_; NPObjectPointer command_buffer_; NPObjectPointer ring_buffer_; }; TEST_F(CommandBufferTest, NullRingBufferByDefault) { EXPECT_EQ(NPObjectPointer(), command_buffer_->GetRingBuffer()); } TEST_F(CommandBufferTest, InitializesCommandBuffer) { EXPECT_TRUE(command_buffer_->Initialize(ring_buffer_)); EXPECT_TRUE(ring_buffer_ == command_buffer_->GetRingBuffer()); EXPECT_EQ(256, command_buffer_->GetSize()); } TEST_F(CommandBufferTest, InitializeFailsSecondTime) { EXPECT_TRUE(command_buffer_->Initialize(ring_buffer_)); EXPECT_FALSE(command_buffer_->Initialize(ring_buffer_)); } TEST_F(CommandBufferTest, InitializeFailsIfSizeIsNegative) { ON_CALL(*ring_buffer_.Get(), GetSize()) .WillByDefault(Return(-1024)); EXPECT_FALSE(command_buffer_->Initialize(ring_buffer_)); } TEST_F(CommandBufferTest, InitializeFailsIfRingBufferIsNull) { EXPECT_FALSE(command_buffer_->Initialize(NPObjectPointer())); } TEST_F(CommandBufferTest, InitializeFailsIfRingBufferDoesNotImplementGetSize) { EXPECT_FALSE(command_buffer_->Initialize( NPCreateObject(NULL))); } TEST_F(CommandBufferTest, GetAndPutOffsetsDefaultToZero) { EXPECT_EQ(0, command_buffer_->GetGetOffset()); EXPECT_EQ(0, command_buffer_->GetPutOffset()); } class MockCallback : public CallbackRunner { public: MOCK_METHOD1(RunWithParams, void(const Tuple0&)); }; TEST_F(CommandBufferTest, CanSyncGetAndPutOffset) { EXPECT_TRUE(command_buffer_->Initialize(ring_buffer_)); 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_->SyncOffsets(2)); EXPECT_EQ(2, command_buffer_->GetPutOffset()); EXPECT_CALL(*put_offset_change_callback, RunWithParams(_)); EXPECT_EQ(0, command_buffer_->SyncOffsets(4)); EXPECT_EQ(4, command_buffer_->GetPutOffset()); command_buffer_->SetGetOffset(2); EXPECT_EQ(2, command_buffer_->GetGetOffset()); EXPECT_CALL(*put_offset_change_callback, RunWithParams(_)); EXPECT_EQ(2, command_buffer_->SyncOffsets(6)); EXPECT_EQ(-1, command_buffer_->SyncOffsets(-1)); EXPECT_EQ(-1, command_buffer_->SyncOffsets(1024)); } TEST_F(CommandBufferTest, ZeroHandleMapsToNull) { EXPECT_TRUE(NULL == command_buffer_->GetRegisteredObject(0).Get()); } TEST_F(CommandBufferTest, NegativeHandleMapsToNull) { EXPECT_TRUE(NULL == command_buffer_->GetRegisteredObject(-1).Get()); } TEST_F(CommandBufferTest, OutOfRangeHandleMapsToNull) { EXPECT_TRUE(NULL == command_buffer_->GetRegisteredObject(1).Get()); } TEST_F(CommandBufferTest, RegisteringNullObjectReturnsZero) { EXPECT_EQ(0, command_buffer_->RegisterObject(NPObjectPointer())); } TEST_F(CommandBufferTest, RegistersDistinctNonZeroHandlesForObject) { EXPECT_EQ(1, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(1)); EXPECT_EQ(2, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(2)); } TEST_F(CommandBufferTest, RegisterObjectReusesUnregisteredHandles) { EXPECT_EQ(1, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(1)); EXPECT_EQ(2, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(2)); command_buffer_->UnregisterObject(ring_buffer_, 1); EXPECT_EQ(1, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(1)); EXPECT_EQ(3, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(3)); } TEST_F(CommandBufferTest, CannotUnregisterHandleZero) { command_buffer_->UnregisterObject(ring_buffer_, 0); EXPECT_TRUE(NULL == command_buffer_->GetRegisteredObject(0).Get()); EXPECT_EQ(1, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(1)); } TEST_F(CommandBufferTest, CannotUnregisterNegativeHandles) { command_buffer_->UnregisterObject(ring_buffer_, -1); EXPECT_EQ(1, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(1)); } TEST_F(CommandBufferTest, CannotUnregisterUnregisteredHandles) { command_buffer_->UnregisterObject(ring_buffer_, 1); EXPECT_EQ(1, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(1)); } TEST_F(CommandBufferTest, CannotUnregisterHandleWithoutDemonstratingAccessToObject) { EXPECT_EQ(1, command_buffer_->RegisterObject(ring_buffer_)); command_buffer_->UnregisterObject(command_buffer_, 1); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(1)); EXPECT_EQ(2, command_buffer_->RegisterObject(ring_buffer_)); } // Testing this case specifically because there is an optimization that takes // a different code path in this case. TEST_F(CommandBufferTest, UnregistersLastRegisteredHandle) { EXPECT_EQ(1, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(1)); command_buffer_->UnregisterObject(ring_buffer_, 1); EXPECT_EQ(1, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(1)); } // Testing this case specifically because there is an optimization that takes // a different code path in this case. TEST_F(CommandBufferTest, UnregistersTwoLastRegisteredHandles) { EXPECT_EQ(1, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(1)); EXPECT_EQ(2, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(2)); command_buffer_->UnregisterObject(ring_buffer_, 2); command_buffer_->UnregisterObject(ring_buffer_, 1); EXPECT_EQ(1, command_buffer_->RegisterObject(ring_buffer_)); EXPECT_EQ(ring_buffer_, command_buffer_->GetRegisteredObject(1)); } TEST_F(CommandBufferTest, DefaultTokenIsZero) { EXPECT_EQ(0, command_buffer_->GetToken()); } TEST_F(CommandBufferTest, CanSetToken) { command_buffer_->SetToken(7); EXPECT_EQ(7, command_buffer_->GetToken()); } TEST_F(CommandBufferTest, DefaultParseErrorIsNoError) { EXPECT_EQ(0, command_buffer_->ResetParseError()); } TEST_F(CommandBufferTest, CanSetAndResetParseError) { command_buffer_->SetParseError(1); EXPECT_EQ(1, command_buffer_->ResetParseError()); EXPECT_EQ(0, command_buffer_->ResetParseError()); } TEST_F(CommandBufferTest, DefaultErrorStatusIsFalse) { EXPECT_FALSE(command_buffer_->GetErrorStatus()); } TEST_F(CommandBufferTest, CanRaiseErrorStatus) { command_buffer_->RaiseErrorStatus(); EXPECT_TRUE(command_buffer_->GetErrorStatus()); } } // namespace gpu_plugin } // namespace o3d