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 shared_memory_.reset(new ::base::SharedMemory); 37 shared_memory_->CreateAndMapAnonymous(kRingBufferSize); 38 buffer_ = static_cast<int32*>(shared_memory_->memory()); 39 shared_memory_buffer_.ptr = buffer_; 40 shared_memory_buffer_.size = 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(), GetState()) 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_->GetState().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_ptr<base::SharedMemory> shared_memory_; 76 Buffer shared_memory_buffer_; 77 int32* buffer_; 78 scoped_ptr<gles2::MockGLES2Decoder> decoder_; 79 scoped_ptr<GpuScheduler> scheduler_; 80 }; 81 82 TEST_F(GpuSchedulerTest, SchedulerDoesNothingIfRingBufferIsEmpty) { 83 CommandBuffer::State state; 84 85 state.put_offset = 0; 86 EXPECT_CALL(*command_buffer_, GetState()) 87 .WillRepeatedly(Return(state)); 88 89 EXPECT_CALL(*command_buffer_, SetParseError(_)) 90 .Times(0); 91 92 scheduler_->PutChanged(); 93 } 94 95 TEST_F(GpuSchedulerTest, GetSetBuffer) { 96 CommandBuffer::State state; 97 98 // Set the get offset to something not 0. 99 EXPECT_CALL(*command_buffer_, SetGetOffset(2)); 100 scheduler_->SetGetOffset(2); 101 EXPECT_EQ(2, scheduler_->GetGetOffset()); 102 103 // Set the buffer. 104 EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId)) 105 .WillOnce(Return(shared_memory_buffer_)); 106 EXPECT_CALL(*command_buffer_, SetGetOffset(0)); 107 EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId)); 108 109 // Check the get offset was reset. 110 EXPECT_EQ(0, scheduler_->GetGetOffset()); 111 } 112 113 TEST_F(GpuSchedulerTest, ProcessesOneCommand) { 114 CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); 115 header[0].command = 7; 116 header[0].size = 2; 117 buffer_[1] = 123; 118 119 CommandBuffer::State state; 120 121 state.put_offset = 2; 122 EXPECT_CALL(*command_buffer_, GetState()) 123 .WillRepeatedly(Return(state)); 124 EXPECT_CALL(*command_buffer_, SetGetOffset(2)); 125 126 EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0])) 127 .WillOnce(Return(error::kNoError)); 128 129 EXPECT_CALL(*command_buffer_, SetParseError(_)) 130 .Times(0); 131 132 scheduler_->PutChanged(); 133 } 134 135 TEST_F(GpuSchedulerTest, ProcessesTwoCommands) { 136 CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); 137 header[0].command = 7; 138 header[0].size = 2; 139 buffer_[1] = 123; 140 header[2].command = 8; 141 header[2].size = 1; 142 143 CommandBuffer::State state; 144 145 state.put_offset = 3; 146 EXPECT_CALL(*command_buffer_, GetState()) 147 .WillRepeatedly(Return(state)); 148 149 EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0])) 150 .WillOnce(Return(error::kNoError)); 151 EXPECT_CALL(*command_buffer_, SetGetOffset(2)); 152 153 EXPECT_CALL(*decoder_, DoCommand(8, 0, &buffer_[2])) 154 .WillOnce(Return(error::kNoError)); 155 EXPECT_CALL(*command_buffer_, SetGetOffset(3)); 156 157 scheduler_->PutChanged(); 158 } 159 160 TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) { 161 CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); 162 header[0].command = 7; 163 header[0].size = 1; 164 165 CommandBuffer::State state; 166 167 state.put_offset = 1; 168 EXPECT_CALL(*command_buffer_, GetState()) 169 .WillRepeatedly(Return(state)); 170 171 EXPECT_CALL(*decoder_, DoCommand(7, 0, &buffer_[0])) 172 .WillOnce(Return( 173 error::kUnknownCommand)); 174 EXPECT_CALL(*command_buffer_, SetGetOffset(1)); 175 176 EXPECT_CALL(*command_buffer_, SetContextLostReason(_)); 177 EXPECT_CALL(*decoder_, GetContextLostReason()) 178 .WillOnce(Return(error::kUnknown)); 179 EXPECT_CALL(*command_buffer_, 180 SetParseError(error::kUnknownCommand)); 181 182 scheduler_->PutChanged(); 183 } 184 185 TEST_F(GpuSchedulerTest, ProcessCommandsDoesNothingAfterError) { 186 CommandBuffer::State state; 187 state.error = error::kGenericError; 188 189 EXPECT_CALL(*command_buffer_, GetState()) 190 .WillRepeatedly(Return(state)); 191 192 scheduler_->PutChanged(); 193 } 194 195 TEST_F(GpuSchedulerTest, CanGetAddressOfSharedMemory) { 196 EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) 197 .WillOnce(Return(shared_memory_buffer_)); 198 199 EXPECT_EQ(&buffer_[0], scheduler_->GetSharedMemoryBuffer(7).ptr); 200 } 201 202 ACTION_P2(SetPointee, address, value) { 203 *address = value; 204 } 205 206 TEST_F(GpuSchedulerTest, CanGetSizeOfSharedMemory) { 207 EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) 208 .WillOnce(Return(shared_memory_buffer_)); 209 210 EXPECT_EQ(kRingBufferSize, scheduler_->GetSharedMemoryBuffer(7).size); 211 } 212 213 TEST_F(GpuSchedulerTest, SetTokenForwardsToCommandBuffer) { 214 EXPECT_CALL(*command_buffer_, SetToken(7)); 215 scheduler_->set_token(7); 216 } 217 218 } // namespace gpu 219