| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/at_exit.h" | 5 #include "base/at_exit.h" |
| 6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
| 7 #include "gpu/command_buffer/common/command_buffer_mock.h" | 7 #include "gpu/command_buffer/common/command_buffer_mock.h" |
| 8 #include "gpu/command_buffer/service/mocks.h" | 8 #include "gpu/command_buffer/service/mocks.h" |
| 9 #include "gpu/command_buffer/service/gpu_processor.h" | 9 #include "gpu/command_buffer/service/gpu_processor.h" |
| 10 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 10 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 const size_t kRingBufferSize = 1024; | 24 const size_t kRingBufferSize = 1024; |
| 25 const size_t kRingBufferEntries = kRingBufferSize / sizeof(CommandBufferEntry); | 25 const size_t kRingBufferEntries = kRingBufferSize / sizeof(CommandBufferEntry); |
| 26 | 26 |
| 27 class GPUProcessorTest : public testing::Test { | 27 class GPUProcessorTest : public testing::Test { |
| 28 protected: | 28 protected: |
| 29 virtual void SetUp() { | 29 virtual void SetUp() { |
| 30 shared_memory_.reset(new ::base::SharedMemory); | 30 shared_memory_.reset(new ::base::SharedMemory); |
| 31 shared_memory_->Create(std::wstring(), false, false, kRingBufferSize); | 31 shared_memory_->Create(std::wstring(), false, false, kRingBufferSize); |
| 32 shared_memory_->Map(kRingBufferSize); | 32 shared_memory_->Map(kRingBufferSize); |
| 33 buffer_ = static_cast<int32*>(shared_memory_->memory()); | 33 buffer_ = static_cast<int32*>(shared_memory_->memory()); |
| 34 | 34 shared_memory_buffer_.ptr = buffer_; |
| 35 shared_memory_buffer_.size = kRingBufferSize; |
| 35 memset(buffer_, 0, kRingBufferSize); | 36 memset(buffer_, 0, kRingBufferSize); |
| 36 | 37 |
| 37 command_buffer_.reset(new MockCommandBuffer); | 38 command_buffer_.reset(new MockCommandBuffer); |
| 38 ON_CALL(*command_buffer_.get(), GetRingBuffer()) | 39 ON_CALL(*command_buffer_.get(), GetRingBuffer()) |
| 39 .WillByDefault(Return(shared_memory_.get())); | 40 .WillByDefault(Return(shared_memory_buffer_)); |
| 40 ON_CALL(*command_buffer_.get(), GetSize()) | 41 ON_CALL(*command_buffer_.get(), GetSize()) |
| 41 .WillByDefault(Return(kRingBufferEntries)); | 42 .WillByDefault(Return(kRingBufferEntries)); |
| 42 | 43 |
| 43 async_api_.reset(new StrictMock<gpu::AsyncAPIMock>); | 44 async_api_.reset(new StrictMock<AsyncAPIMock>); |
| 44 | 45 |
| 45 decoder_ = gles2::GLES2Decoder::Create(); | 46 decoder_ = gles2::GLES2Decoder::Create(); |
| 46 | 47 |
| 47 parser_ = new gpu::CommandParser(buffer_, | 48 parser_ = new CommandParser(buffer_, |
| 48 kRingBufferEntries, | 49 kRingBufferEntries, |
| 49 0, | 50 0, |
| 50 kRingBufferEntries, | 51 kRingBufferEntries, |
| 51 0, | 52 0, |
| 52 async_api_.get()); | 53 async_api_.get()); |
| 53 | 54 |
| 54 processor_ = new GPUProcessor(command_buffer_.get(), | 55 processor_ = new GPUProcessor(command_buffer_.get(), |
| 55 decoder_, | 56 decoder_, |
| 56 parser_, | 57 parser_, |
| 57 2); | 58 2); |
| 58 } | 59 } |
| 59 | 60 |
| 60 virtual void TearDown() { | 61 virtual void TearDown() { |
| 61 // Ensure that any unexpected tasks posted by the GPU processor are executed | 62 // Ensure that any unexpected tasks posted by the GPU processor are executed |
| 62 // in order to fail the test. | 63 // in order to fail the test. |
| 63 MessageLoop::current()->RunAllPending(); | 64 MessageLoop::current()->RunAllPending(); |
| 64 } | 65 } |
| 65 | 66 |
| 66 base::AtExitManager at_exit_manager; | 67 base::AtExitManager at_exit_manager; |
| 67 MessageLoop message_loop; | 68 MessageLoop message_loop; |
| 68 scoped_ptr<MockCommandBuffer> command_buffer_; | 69 scoped_ptr<MockCommandBuffer> command_buffer_; |
| 69 scoped_ptr<::base::SharedMemory> shared_memory_; | 70 scoped_ptr<::base::SharedMemory> shared_memory_; |
| 71 Buffer shared_memory_buffer_; |
| 70 int32* buffer_; | 72 int32* buffer_; |
| 71 gpu::gles2::GLES2Decoder* decoder_; | 73 gles2::GLES2Decoder* decoder_; |
| 72 gpu::CommandParser* parser_; | 74 CommandParser* parser_; |
| 73 scoped_ptr<gpu::AsyncAPIMock> async_api_; | 75 scoped_ptr<AsyncAPIMock> async_api_; |
| 74 scoped_refptr<GPUProcessor> processor_; | 76 scoped_refptr<GPUProcessor> processor_; |
| 75 }; | 77 }; |
| 76 | 78 |
| 77 TEST_F(GPUProcessorTest, ProcessorDoesNothingIfRingBufferIsEmpty) { | 79 TEST_F(GPUProcessorTest, ProcessorDoesNothingIfRingBufferIsEmpty) { |
| 78 EXPECT_CALL(*command_buffer_, GetPutOffset()) | 80 EXPECT_CALL(*command_buffer_, GetPutOffset()) |
| 79 .WillOnce(Return(0)); | 81 .WillOnce(Return(0)); |
| 80 EXPECT_CALL(*command_buffer_, SetGetOffset(0)); | 82 EXPECT_CALL(*command_buffer_, SetGetOffset(0)); |
| 81 | 83 |
| 82 processor_->ProcessCommands(); | 84 processor_->ProcessCommands(); |
| 83 | 85 |
| 84 EXPECT_EQ(gpu::parse_error::kParseNoError, | 86 EXPECT_EQ(parse_error::kParseNoError, |
| 85 command_buffer_->ResetParseError()); | 87 command_buffer_->ResetParseError()); |
| 86 EXPECT_FALSE(command_buffer_->GetErrorStatus()); | 88 EXPECT_FALSE(command_buffer_->GetErrorStatus()); |
| 87 } | 89 } |
| 88 | 90 |
| 89 TEST_F(GPUProcessorTest, ProcessesOneCommand) { | 91 TEST_F(GPUProcessorTest, ProcessesOneCommand) { |
| 90 gpu::CommandHeader* header = | 92 CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); |
| 91 reinterpret_cast<gpu::CommandHeader*>(&buffer_[0]); | |
| 92 header[0].command = 7; | 93 header[0].command = 7; |
| 93 header[0].size = 2; | 94 header[0].size = 2; |
| 94 buffer_[1] = 123; | 95 buffer_[1] = 123; |
| 95 | 96 |
| 96 EXPECT_CALL(*command_buffer_, GetPutOffset()) | 97 EXPECT_CALL(*command_buffer_, GetPutOffset()) |
| 97 .WillOnce(Return(2)); | 98 .WillOnce(Return(2)); |
| 98 EXPECT_CALL(*command_buffer_, SetGetOffset(2)); | 99 EXPECT_CALL(*command_buffer_, SetGetOffset(2)); |
| 99 | 100 |
| 100 EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) | 101 EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) |
| 101 .WillOnce(Return(gpu::parse_error::kParseNoError)); | 102 .WillOnce(Return(parse_error::kParseNoError)); |
| 102 | 103 |
| 103 processor_->ProcessCommands(); | 104 processor_->ProcessCommands(); |
| 104 | 105 |
| 105 EXPECT_EQ(gpu::parse_error::kParseNoError, | 106 EXPECT_EQ(parse_error::kParseNoError, |
| 106 command_buffer_->ResetParseError()); | 107 command_buffer_->ResetParseError()); |
| 107 EXPECT_FALSE(command_buffer_->GetErrorStatus()); | 108 EXPECT_FALSE(command_buffer_->GetErrorStatus()); |
| 108 } | 109 } |
| 109 | 110 |
| 110 TEST_F(GPUProcessorTest, ProcessesTwoCommands) { | 111 TEST_F(GPUProcessorTest, ProcessesTwoCommands) { |
| 111 gpu::CommandHeader* header = | 112 CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); |
| 112 reinterpret_cast<gpu::CommandHeader*>(&buffer_[0]); | |
| 113 header[0].command = 7; | 113 header[0].command = 7; |
| 114 header[0].size = 2; | 114 header[0].size = 2; |
| 115 buffer_[1] = 123; | 115 buffer_[1] = 123; |
| 116 header[2].command = 8; | 116 header[2].command = 8; |
| 117 header[2].size = 1; | 117 header[2].size = 1; |
| 118 | 118 |
| 119 EXPECT_CALL(*command_buffer_, GetPutOffset()) | 119 EXPECT_CALL(*command_buffer_, GetPutOffset()) |
| 120 .WillOnce(Return(3)); | 120 .WillOnce(Return(3)); |
| 121 EXPECT_CALL(*command_buffer_, SetGetOffset(3)); | 121 EXPECT_CALL(*command_buffer_, SetGetOffset(3)); |
| 122 | 122 |
| 123 EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) | 123 EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) |
| 124 .WillOnce(Return(gpu::parse_error::kParseNoError)); | 124 .WillOnce(Return(parse_error::kParseNoError)); |
| 125 | 125 |
| 126 EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) | 126 EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) |
| 127 .WillOnce(Return(gpu::parse_error::kParseNoError)); | 127 .WillOnce(Return(parse_error::kParseNoError)); |
| 128 | 128 |
| 129 processor_->ProcessCommands(); | 129 processor_->ProcessCommands(); |
| 130 } | 130 } |
| 131 | 131 |
| 132 TEST_F(GPUProcessorTest, PostsTaskToFinishRemainingCommands) { | 132 TEST_F(GPUProcessorTest, PostsTaskToFinishRemainingCommands) { |
| 133 gpu::CommandHeader* header = | 133 CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); |
| 134 reinterpret_cast<gpu::CommandHeader*>(&buffer_[0]); | |
| 135 header[0].command = 7; | 134 header[0].command = 7; |
| 136 header[0].size = 2; | 135 header[0].size = 2; |
| 137 buffer_[1] = 123; | 136 buffer_[1] = 123; |
| 138 header[2].command = 8; | 137 header[2].command = 8; |
| 139 header[2].size = 1; | 138 header[2].size = 1; |
| 140 header[3].command = 9; | 139 header[3].command = 9; |
| 141 header[3].size = 1; | 140 header[3].size = 1; |
| 142 | 141 |
| 143 EXPECT_CALL(*command_buffer_, GetPutOffset()) | 142 EXPECT_CALL(*command_buffer_, GetPutOffset()) |
| 144 .WillOnce(Return(4)); | 143 .WillOnce(Return(4)); |
| 145 | 144 |
| 146 EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) | 145 EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) |
| 147 .WillOnce(Return(gpu::parse_error::kParseNoError)); | 146 .WillOnce(Return(parse_error::kParseNoError)); |
| 148 | 147 |
| 149 EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) | 148 EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) |
| 150 .WillOnce(Return(gpu::parse_error::kParseNoError)); | 149 .WillOnce(Return(parse_error::kParseNoError)); |
| 151 | 150 |
| 152 EXPECT_CALL(*command_buffer_, SetGetOffset(3)); | 151 EXPECT_CALL(*command_buffer_, SetGetOffset(3)); |
| 153 | 152 |
| 154 processor_->ProcessCommands(); | 153 processor_->ProcessCommands(); |
| 155 | 154 |
| 156 // ProcessCommands is called a second time when the pending task is run. | 155 // ProcessCommands is called a second time when the pending task is run. |
| 157 | 156 |
| 158 EXPECT_CALL(*command_buffer_, GetPutOffset()) | 157 EXPECT_CALL(*command_buffer_, GetPutOffset()) |
| 159 .WillOnce(Return(4)); | 158 .WillOnce(Return(4)); |
| 160 | 159 |
| 161 EXPECT_CALL(*async_api_, DoCommand(9, 0, &buffer_[3])) | 160 EXPECT_CALL(*async_api_, DoCommand(9, 0, &buffer_[3])) |
| 162 .WillOnce(Return(gpu::parse_error::kParseNoError)); | 161 .WillOnce(Return(parse_error::kParseNoError)); |
| 163 | 162 |
| 164 EXPECT_CALL(*command_buffer_, SetGetOffset(4)); | 163 EXPECT_CALL(*command_buffer_, SetGetOffset(4)); |
| 165 | 164 |
| 166 MessageLoop::current()->RunAllPending(); | 165 MessageLoop::current()->RunAllPending(); |
| 167 } | 166 } |
| 168 | 167 |
| 169 TEST_F(GPUProcessorTest, SetsErrorCodeOnCommandBuffer) { | 168 TEST_F(GPUProcessorTest, SetsErrorCodeOnCommandBuffer) { |
| 170 gpu::CommandHeader* header = | 169 CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); |
| 171 reinterpret_cast<gpu::CommandHeader*>(&buffer_[0]); | |
| 172 header[0].command = 7; | 170 header[0].command = 7; |
| 173 header[0].size = 1; | 171 header[0].size = 1; |
| 174 | 172 |
| 175 EXPECT_CALL(*command_buffer_, GetPutOffset()) | 173 EXPECT_CALL(*command_buffer_, GetPutOffset()) |
| 176 .WillOnce(Return(1)); | 174 .WillOnce(Return(1)); |
| 177 EXPECT_CALL(*command_buffer_, SetGetOffset(1)); | 175 EXPECT_CALL(*command_buffer_, SetGetOffset(1)); |
| 178 | 176 |
| 179 EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) | 177 EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) |
| 180 .WillOnce(Return( | 178 .WillOnce(Return( |
| 181 gpu::parse_error::kParseUnknownCommand)); | 179 parse_error::kParseUnknownCommand)); |
| 182 | 180 |
| 183 EXPECT_CALL(*command_buffer_, | 181 EXPECT_CALL(*command_buffer_, |
| 184 SetParseError(gpu::parse_error::kParseUnknownCommand)); | 182 SetParseError(parse_error::kParseUnknownCommand)); |
| 185 | 183 |
| 186 processor_->ProcessCommands(); | 184 processor_->ProcessCommands(); |
| 187 } | 185 } |
| 188 | 186 |
| 189 TEST_F(GPUProcessorTest, | 187 TEST_F(GPUProcessorTest, |
| 190 RecoverableParseErrorsAreNotClearedByFollowingSuccessfulCommands) { | 188 RecoverableParseErrorsAreNotClearedByFollowingSuccessfulCommands) { |
| 191 gpu::CommandHeader* header = | 189 CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); |
| 192 reinterpret_cast<gpu::CommandHeader*>(&buffer_[0]); | |
| 193 header[0].command = 7; | 190 header[0].command = 7; |
| 194 header[0].size = 1; | 191 header[0].size = 1; |
| 195 header[1].command = 8; | 192 header[1].command = 8; |
| 196 header[1].size = 1; | 193 header[1].size = 1; |
| 197 | 194 |
| 198 EXPECT_CALL(*command_buffer_, GetPutOffset()) | 195 EXPECT_CALL(*command_buffer_, GetPutOffset()) |
| 199 .WillOnce(Return(2)); | 196 .WillOnce(Return(2)); |
| 200 EXPECT_CALL(*command_buffer_, SetGetOffset(2)); | 197 EXPECT_CALL(*command_buffer_, SetGetOffset(2)); |
| 201 | 198 |
| 202 EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) | 199 EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) |
| 203 .WillOnce(Return( | 200 .WillOnce(Return( |
| 204 gpu::parse_error::kParseUnknownCommand)); | 201 parse_error::kParseUnknownCommand)); |
| 205 | 202 |
| 206 EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[1])) | 203 EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[1])) |
| 207 .WillOnce(Return(gpu::parse_error::kParseNoError)); | 204 .WillOnce(Return(parse_error::kParseNoError)); |
| 208 | 205 |
| 209 EXPECT_CALL(*command_buffer_, | 206 EXPECT_CALL(*command_buffer_, |
| 210 SetParseError(gpu::parse_error::kParseUnknownCommand)); | 207 SetParseError(parse_error::kParseUnknownCommand)); |
| 211 | 208 |
| 212 processor_->ProcessCommands(); | 209 processor_->ProcessCommands(); |
| 213 } | 210 } |
| 214 | 211 |
| 215 TEST_F(GPUProcessorTest, UnrecoverableParseErrorsRaiseTheErrorStatus) { | 212 TEST_F(GPUProcessorTest, UnrecoverableParseErrorsRaiseTheErrorStatus) { |
| 216 gpu::CommandHeader* header = | 213 CommandHeader* header = |
| 217 reinterpret_cast<gpu::CommandHeader*>(&buffer_[0]); | 214 reinterpret_cast<CommandHeader*>(&buffer_[0]); |
| 218 header[0].command = 7; | 215 header[0].command = 7; |
| 219 header[0].size = 1; | 216 header[0].size = 1; |
| 220 header[1].command = 8; | 217 header[1].command = 8; |
| 221 header[1].size = 1; | 218 header[1].size = 1; |
| 222 | 219 |
| 223 EXPECT_CALL(*command_buffer_, GetPutOffset()) | 220 EXPECT_CALL(*command_buffer_, GetPutOffset()) |
| 224 .WillOnce(Return(2)); | 221 .WillOnce(Return(2)); |
| 225 | 222 |
| 226 EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) | 223 EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) |
| 227 .WillOnce(Return(gpu::parse_error::kParseInvalidSize)); | 224 .WillOnce(Return(parse_error::kParseInvalidSize)); |
| 228 | 225 |
| 229 EXPECT_CALL(*command_buffer_, | 226 EXPECT_CALL(*command_buffer_, |
| 230 SetParseError(gpu::parse_error::kParseInvalidSize)); | 227 SetParseError(parse_error::kParseInvalidSize)); |
| 231 | 228 |
| 232 EXPECT_CALL(*command_buffer_, RaiseErrorStatus()); | 229 EXPECT_CALL(*command_buffer_, RaiseErrorStatus()); |
| 233 | 230 |
| 234 processor_->ProcessCommands(); | 231 processor_->ProcessCommands(); |
| 235 } | 232 } |
| 236 | 233 |
| 237 TEST_F(GPUProcessorTest, ProcessCommandsDoesNothingAfterUnrecoverableError) { | 234 TEST_F(GPUProcessorTest, ProcessCommandsDoesNothingAfterUnrecoverableError) { |
| 238 EXPECT_CALL(*command_buffer_, GetErrorStatus()) | 235 EXPECT_CALL(*command_buffer_, GetErrorStatus()) |
| 239 .WillOnce(Return(true)); | 236 .WillOnce(Return(true)); |
| 240 | 237 |
| 241 EXPECT_CALL(*command_buffer_, GetPutOffset()) | 238 EXPECT_CALL(*command_buffer_, GetPutOffset()) |
| 242 .Times(0); | 239 .Times(0); |
| 243 | 240 |
| 244 processor_->ProcessCommands(); | 241 processor_->ProcessCommands(); |
| 245 } | 242 } |
| 246 | 243 |
| 247 TEST_F(GPUProcessorTest, CanGetAddressOfSharedMemory) { | 244 TEST_F(GPUProcessorTest, CanGetAddressOfSharedMemory) { |
| 248 EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) | 245 EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) |
| 249 .WillOnce(Return(shared_memory_.get())); | 246 .WillOnce(Return(shared_memory_buffer_)); |
| 250 | 247 |
| 251 EXPECT_EQ(&buffer_[0], processor_->GetSharedMemoryAddress(7)); | 248 EXPECT_EQ(&buffer_[0], processor_->GetSharedMemoryBuffer(7).ptr); |
| 252 } | 249 } |
| 253 | 250 |
| 254 ACTION_P2(SetPointee, address, value) { | 251 ACTION_P2(SetPointee, address, value) { |
| 255 *address = value; | 252 *address = value; |
| 256 } | 253 } |
| 257 | 254 |
| 258 TEST_F(GPUProcessorTest, GetAddressOfSharedMemoryMapsMemoryIfUnmapped) { | |
| 259 EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) | |
| 260 .WillOnce(Return(shared_memory_.get())); | |
| 261 | |
| 262 EXPECT_EQ(&buffer_[0], processor_->GetSharedMemoryAddress(7)); | |
| 263 } | |
| 264 | |
| 265 TEST_F(GPUProcessorTest, CanGetSizeOfSharedMemory) { | 255 TEST_F(GPUProcessorTest, CanGetSizeOfSharedMemory) { |
| 266 EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) | 256 EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) |
| 267 .WillOnce(Return(shared_memory_.get())); | 257 .WillOnce(Return(shared_memory_buffer_)); |
| 268 | 258 |
| 269 EXPECT_EQ(kRingBufferSize, processor_->GetSharedMemorySize(7)); | 259 EXPECT_EQ(kRingBufferSize, processor_->GetSharedMemoryBuffer(7).size); |
| 270 } | 260 } |
| 271 | 261 |
| 272 TEST_F(GPUProcessorTest, SetTokenForwardsToCommandBuffer) { | 262 TEST_F(GPUProcessorTest, SetTokenForwardsToCommandBuffer) { |
| 273 EXPECT_CALL(*command_buffer_, SetToken(7)); | 263 EXPECT_CALL(*command_buffer_, SetToken(7)); |
| 274 processor_->set_token(7); | 264 processor_->set_token(7); |
| 275 } | 265 } |
| 276 | 266 |
| 277 } // namespace gpu | 267 } // namespace gpu |
| OLD | NEW |