1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/message_loop/message_loop.h" 6 #include "gpu/command_buffer/common/command_buffer_mock.h" 7 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 8 #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" 9 #include "gpu/command_buffer/service/gpu_scheduler.h" 10 #include "gpu/command_buffer/service/mocks.h" 11 #include "testing/gmock/include/gmock/gmock.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 #if defined(OS_MACOSX) 15 #include "base/mac/scoped_nsautorelease_pool.h" 16 #endif 17 18 using testing::_; 19 using testing::DoAll; 20 using testing::Invoke; 21 using testing::NiceMock; 22 using testing::Return; 23 using testing::SetArgumentPointee; 24 using testing::StrictMock; 25 26 namespace gpu { 27 28 const size_t kRingBufferSize = 1024; 29 const size_t kRingBufferEntries = kRingBufferSize / sizeof(CommandBufferEntry); 30 31 class GpuSchedulerTest : public testing::Test { 32 protected: 33 static const int32 kTransferBufferId = 123; 34 35 virtual void SetUp() { 36 scoped_ptr<base::SharedMemory> shared_memory(new ::base::SharedMemory); 37 shared_memory->CreateAndMapAnonymous(kRingBufferSize); 38 buffer_ = static_cast<int32*>(shared_memory->memory()); 39 shared_memory_buffer_ = 40 MakeBufferFromSharedMemory(shared_memory.Pass(), kRingBufferSize); 41 memset(buffer_, 0, kRingBufferSize); 42 43 command_buffer_.reset(new MockCommandBuffer); 44 45 CommandBuffer::State default_state; 46 default_state.num_entries = kRingBufferEntries; 47 ON_CALL(*command_buffer_.get(), GetLastState()) 48 .WillByDefault(Return(default_state)); 49 50 decoder_.reset(new gles2::MockGLES2Decoder()); 51 scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), 52 decoder_.get(), 53 decoder_.get())); 54 EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId)) 55 .WillOnce(Return(shared_memory_buffer_)); 56 EXPECT_CALL(*command_buffer_, SetGetOffset(0)); 57 EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId)); 58 } 59 60 virtual void TearDown() { 61 // Ensure that any unexpected tasks posted by the GPU scheduler are executed 62 // in order to fail the test. 63 base::MessageLoop::current()->RunUntilIdle(); 64 } 65 66 error::Error GetError() { 67 return command_buffer_->GetLastState().error; 68 } 69 70 #if defined(OS_MACOSX) 71 base::mac::ScopedNSAutoreleasePool autorelease_pool_; 72 #endif 73 base::MessageLoop message_loop; 74 scoped_ptr<MockCommandBuffer> command_buffer_; 75 scoped_refptr<Buffer> shared_memory_buffer_; 76 int32* buffer_; 77 scoped_ptr<gles2::MockGLES2Decoder> decoder_; 78 scoped_ptr<GpuScheduler> scheduler_; 79 }; 80 81 TEST_F(GpuSchedulerTest, SchedulerDoesNothingIfRingBufferIsEmpty) { 82 CommandBuffer::State state; 83 84 state.put_offset = 0; 85 EXPECT_CALL(*command_buffer_, GetLastState()) 86 .WillRepeatedly(Return(state)); 87 88 EXPECT_CALL(*command_buffer_, SetParseError(_)) 89 .Times(0); 90 91 scheduler_->PutChanged(); 92 } 93 94 TEST_F(GpuSchedulerTest, GetSetBuffer) { 95 CommandBuffer::State state; 96 97 // Set the get offset to something not 0. 98 EXPECT_CALL(*command_buffer_, SetGetOffset(2)); 99 scheduler_->SetGetOffset(2); 100 EXPECT_EQ(2, scheduler_->GetGetOffset()); 101 102 // Set the buffer. 103 EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId)) 104 .WillOnce(Return(shared_memory_buffer_)); 105 EXPECT_CALL(*command_buffer_, SetGetOffset(0)); 106 EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId)); 107 108 // Check the get offset was reset. 109 EXPECT_EQ(0, scheduler_->GetGetOffset()); 110 } 111 112 TEST_F(GpuSchedulerTest, ProcessesOneCommand) { 113 CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); 114 header[0].command = 7; 115 header[0].size = 2; 116 buffer_[1] = 123; 117 118 CommandBuffer::State state; 119 120 state.put_offset = 2; 121 EXPECT_CALL(*command_buffer_, GetLastState()) 122 .WillRepeatedly(Return(state)); 123 EXPECT_CALL(*command_buffer_, SetGetOffset(2)); 124 125 EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0])) 126 .WillOnce(Return(error::kNoError)); 127 128 EXPECT_CALL(*command_buffer_, SetParseError(_)) 129 .Times(0); 130 131 scheduler_->PutChanged(); 132 } 133 134 TEST_F(GpuSchedulerTest, ProcessesTwoCommands) { 135 CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); 136 header[0].command = 7; 137 header[0].size = 2; 138 buffer_[1] = 123; 139 header[2].command = 8; 140 header[2].size = 1; 141 142 CommandBuffer::State state; 143 144 state.put_offset = 3; 145 EXPECT_CALL(*command_buffer_, GetLastState()) 146 .WillRepeatedly(Return(state)); 147 148 EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0])) 149 .WillOnce(Return(error::kNoError)); 150 EXPECT_CALL(*command_buffer_, SetGetOffset(2)); 151 152 EXPECT_CALL(*decoder_, DoCommand(8, 0, &buffer_[2])) 153 .WillOnce(Return(error::kNoError)); 154 EXPECT_CALL(*command_buffer_, SetGetOffset(3)); 155 156 scheduler_->PutChanged(); 157 } 158 159 TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) { 160 CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); 161 header[0].command = 7; 162 header[0].size = 1; 163 164 CommandBuffer::State state; 165 166 state.put_offset = 1; 167 EXPECT_CALL(*command_buffer_, GetLastState()) 168 .WillRepeatedly(Return(state)); 169 170 EXPECT_CALL(*decoder_, DoCommand(7, 0, &buffer_[0])) 171 .WillOnce(Return( 172 error::kUnknownCommand)); 173 EXPECT_CALL(*command_buffer_, SetGetOffset(1)); 174 175 EXPECT_CALL(*command_buffer_, SetContextLostReason(_)); 176 EXPECT_CALL(*decoder_, GetContextLostReason()) 177 .WillOnce(Return(error::kUnknown)); 178 EXPECT_CALL(*command_buffer_, 179 SetParseError(error::kUnknownCommand)); 180 181 scheduler_->PutChanged(); 182 } 183 184 TEST_F(GpuSchedulerTest, ProcessCommandsDoesNothingAfterError) { 185 CommandBuffer::State state; 186 state.error = error::kGenericError; 187 188 EXPECT_CALL(*command_buffer_, GetLastState()) 189 .WillRepeatedly(Return(state)); 190 191 scheduler_->PutChanged(); 192 } 193 194 TEST_F(GpuSchedulerTest, CanGetAddressOfSharedMemory) { 195 EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) 196 .WillOnce(Return(shared_memory_buffer_)); 197 198 EXPECT_EQ(&buffer_[0], scheduler_->GetSharedMemoryBuffer(7)->memory()); 199 } 200 201 ACTION_P2(SetPointee, address, value) { 202 *address = value; 203 } 204 205 TEST_F(GpuSchedulerTest, CanGetSizeOfSharedMemory) { 206 EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) 207 .WillOnce(Return(shared_memory_buffer_)); 208 209 EXPECT_EQ(kRingBufferSize, scheduler_->GetSharedMemoryBuffer(7)->size()); 210 } 211 212 TEST_F(GpuSchedulerTest, SetTokenForwardsToCommandBuffer) { 213 EXPECT_CALL(*command_buffer_, SetToken(7)); 214 scheduler_->set_token(7); 215 } 216 217 } // namespace gpu 218