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 // Tests for the Command Buffer Helper. | 5 // Tests for the Command Buffer Helper. |
6 | 6 |
7 #include "base/at_exit.h" | 7 #include "base/at_exit.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/scoped_nsautorelease_pool.h" | 10 #include "base/scoped_nsautorelease_pool.h" |
11 #include "gpu/command_buffer/client/cmd_buffer_helper.h" | 11 #include "gpu/command_buffer/client/cmd_buffer_helper.h" |
12 #include "gpu/command_buffer/service/mocks.h" | 12 #include "gpu/command_buffer/service/mocks.h" |
13 #include "gpu/command_buffer/service/command_buffer_service.h" | 13 #include "gpu/command_buffer/service/command_buffer_service.h" |
14 #include "gpu/command_buffer/service/gpu_processor.h" | 14 #include "gpu/command_buffer/service/gpu_processor.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
16 | 16 |
17 namespace gpu { | 17 namespace gpu { |
18 | 18 |
19 using testing::Return; | 19 using testing::Return; |
20 using testing::Mock; | 20 using testing::Mock; |
21 using testing::Truly; | 21 using testing::Truly; |
22 using testing::Sequence; | 22 using testing::Sequence; |
23 using testing::DoAll; | 23 using testing::DoAll; |
24 using testing::Invoke; | 24 using testing::Invoke; |
25 using testing::_; | 25 using testing::_; |
26 | 26 |
27 const int32 kNumCommandEntries = 10; | 27 const int32 kTotalNumCommandEntries = 12; |
28 const int32 kUsableNumCommandEntries = 10; | |
28 const int32 kCommandBufferSizeBytes = | 29 const int32 kCommandBufferSizeBytes = |
29 kNumCommandEntries * sizeof(CommandBufferEntry); | 30 kTotalNumCommandEntries * sizeof(CommandBufferEntry); |
31 const int32 kUnusedCommandId = 5; // we use 0 and 2 currently. | |
30 | 32 |
31 // Test fixture for CommandBufferHelper test - Creates a CommandBufferHelper, | 33 // Test fixture for CommandBufferHelper test - Creates a CommandBufferHelper, |
32 // using a CommandBufferEngine with a mock AsyncAPIInterface for its interface | 34 // using a CommandBufferEngine with a mock AsyncAPIInterface for its interface |
33 // (calling it directly, not through the RPC mechanism). | 35 // (calling it directly, not through the RPC mechanism). |
34 class CommandBufferHelperTest : public testing::Test { | 36 class CommandBufferHelperTest : public testing::Test { |
35 protected: | 37 protected: |
38 // Helper so mock can handle the Jump command. | |
39 class DoJumpCommand { | |
40 public: | |
41 explicit DoJumpCommand(CommandParser* parser) | |
42 : parser_(parser) { | |
43 } | |
44 | |
45 error::Error DoCommand( | |
46 unsigned int command, | |
47 unsigned int arg_count, | |
48 const void* cmd_data) { | |
49 const cmd::Jump* jump_cmd = static_cast<const cmd::Jump*>(cmd_data); | |
50 parser_->set_get(jump_cmd->offset); | |
51 return error::kNoError; | |
52 }; | |
53 | |
54 private: | |
55 CommandParser* parser_; | |
56 }; | |
57 | |
36 virtual void SetUp() { | 58 virtual void SetUp() { |
37 api_mock_.reset(new AsyncAPIMock); | 59 api_mock_.reset(new AsyncAPIMock); |
38 // ignore noops in the mock - we don't want to inspect the internals of the | 60 // ignore noops in the mock - we don't want to inspect the internals of the |
39 // helper. | 61 // helper. |
40 EXPECT_CALL(*api_mock_, DoCommand(0, _, _)) | 62 EXPECT_CALL(*api_mock_, DoCommand(cmd::kNoop, _, _)) |
41 .WillRepeatedly(Return(error::kNoError)); | 63 .WillRepeatedly(Return(error::kNoError)); |
42 | 64 |
43 command_buffer_.reset(new CommandBufferService); | 65 command_buffer_.reset(new CommandBufferService); |
44 command_buffer_->Initialize(kCommandBufferSizeBytes); | 66 command_buffer_->Initialize(kCommandBufferSizeBytes); |
45 Buffer ring_buffer = command_buffer_->GetRingBuffer(); | 67 Buffer ring_buffer = command_buffer_->GetRingBuffer(); |
46 | 68 |
47 parser_ = new CommandParser(ring_buffer.ptr, | 69 parser_ = new CommandParser(ring_buffer.ptr, |
48 ring_buffer.size, | 70 ring_buffer.size, |
49 0, | 71 0, |
50 ring_buffer.size, | 72 ring_buffer.size, |
51 0, | 73 0, |
52 api_mock_.get()); | 74 api_mock_.get()); |
53 | 75 |
76 do_jump_command_.reset(new DoJumpCommand(parser_)); | |
77 EXPECT_CALL(*api_mock_, DoCommand(cmd::kJump, _, _)) | |
78 .WillRepeatedly( | |
79 Invoke(do_jump_command_.get(), &DoJumpCommand::DoCommand)); | |
80 | |
54 gpu_processor_.reset(new GPUProcessor( | 81 gpu_processor_.reset(new GPUProcessor( |
55 command_buffer_.get(), NULL, parser_, 1)); | 82 command_buffer_.get(), NULL, parser_, 1)); |
56 command_buffer_->SetPutOffsetChangeCallback(NewCallback( | 83 command_buffer_->SetPutOffsetChangeCallback(NewCallback( |
57 gpu_processor_.get(), &GPUProcessor::ProcessCommands)); | 84 gpu_processor_.get(), &GPUProcessor::ProcessCommands)); |
58 | 85 |
59 api_mock_->set_engine(gpu_processor_.get()); | 86 api_mock_->set_engine(gpu_processor_.get()); |
60 | 87 |
61 helper_.reset(new CommandBufferHelper(command_buffer_.get())); | 88 helper_.reset(new CommandBufferHelper(command_buffer_.get())); |
62 helper_->Initialize(kCommandBufferSizeBytes); | 89 helper_->Initialize(kCommandBufferSizeBytes); |
63 } | 90 } |
(...skipping 14 matching lines...) Expand all Loading... | |
78 header.command = command; | 105 header.command = command; |
79 CommandBufferEntry* cmds = helper_->GetSpace(arg_count + 1); | 106 CommandBufferEntry* cmds = helper_->GetSpace(arg_count + 1); |
80 CommandBufferOffset put = 0; | 107 CommandBufferOffset put = 0; |
81 cmds[put++].value_header = header; | 108 cmds[put++].value_header = header; |
82 for (int ii = 0; ii < arg_count; ++ii) { | 109 for (int ii = 0; ii < arg_count; ++ii) { |
83 cmds[put++] = args[ii]; | 110 cmds[put++] = args[ii]; |
84 } | 111 } |
85 | 112 |
86 EXPECT_CALL(*api_mock_, DoCommand(command, arg_count, | 113 EXPECT_CALL(*api_mock_, DoCommand(command, arg_count, |
87 Truly(AsyncAPIMock::IsArgs(arg_count, args)))) | 114 Truly(AsyncAPIMock::IsArgs(arg_count, args)))) |
88 .InSequence(sequence_) | 115 // .InSequence(sequence_) |
apatrick_chromium
2010/06/02 22:24:43
Uncomment or delete line?
| |
89 .WillOnce(Return(_return)); | 116 .WillOnce(Return(_return)); |
90 } | 117 } |
91 | 118 |
92 // Checks that the buffer from put to put+size is free in the parser. | 119 // Checks that the buffer from put to put+size is free in the parser. |
93 void CheckFreeSpace(CommandBufferOffset put, unsigned int size) { | 120 void CheckFreeSpace(CommandBufferOffset put, unsigned int size) { |
94 CommandBufferOffset parser_put = parser_->put(); | 121 CommandBufferOffset parser_put = parser_->put(); |
95 CommandBufferOffset parser_get = parser_->get(); | 122 CommandBufferOffset parser_get = parser_->get(); |
96 CommandBufferOffset limit = put + size; | 123 CommandBufferOffset limit = put + size; |
97 if (parser_get > parser_put) { | 124 if (parser_get > parser_put) { |
98 // "busy" buffer wraps, so "free" buffer is between put (inclusive) and | 125 // "busy" buffer wraps, so "free" buffer is between put (inclusive) and |
99 // get (exclusive). | 126 // get (exclusive). |
100 EXPECT_LE(parser_put, put); | 127 EXPECT_LE(parser_put, put); |
101 EXPECT_GT(parser_get, limit); | 128 EXPECT_GT(parser_get, limit); |
102 } else { | 129 } else { |
103 // "busy" buffer does not wrap, so the "free" buffer is the top side (from | 130 // "busy" buffer does not wrap, so the "free" buffer is the top side (from |
104 // put to the limit) and the bottom side (from 0 to get). | 131 // put to the limit) and the bottom side (from 0 to get). |
105 if (put >= parser_put) { | 132 if (put >= parser_put) { |
106 // we're on the top side, check we are below the limit. | 133 // we're on the top side, check we are below the limit. |
107 EXPECT_GE(kNumCommandEntries, limit); | 134 EXPECT_GE(kTotalNumCommandEntries, limit); |
108 } else { | 135 } else { |
109 // we're on the bottom side, check we are below get. | 136 // we're on the bottom side, check we are below get. |
110 EXPECT_GT(parser_get, limit); | 137 EXPECT_GT(parser_get, limit); |
111 } | 138 } |
112 } | 139 } |
113 } | 140 } |
114 | 141 |
115 int32 GetGetOffset() { | 142 int32 GetGetOffset() { |
116 return command_buffer_->GetState().get_offset; | 143 return command_buffer_->GetState().get_offset; |
117 } | 144 } |
118 | 145 |
119 int32 GetPutOffset() { | 146 int32 GetPutOffset() { |
120 return command_buffer_->GetState().put_offset; | 147 return command_buffer_->GetState().put_offset; |
121 } | 148 } |
122 | 149 |
123 error::Error GetError() { | 150 error::Error GetError() { |
124 return command_buffer_->GetState().error; | 151 return command_buffer_->GetState().error; |
125 } | 152 } |
126 | 153 |
127 CommandBufferOffset get_helper_put() { return helper_->put_; } | 154 CommandBufferOffset get_helper_put() { return helper_->put_; } |
128 | 155 |
129 base::ScopedNSAutoreleasePool autorelease_pool_; | 156 base::ScopedNSAutoreleasePool autorelease_pool_; |
130 base::AtExitManager at_exit_manager_; | 157 base::AtExitManager at_exit_manager_; |
131 MessageLoop message_loop_; | 158 MessageLoop message_loop_; |
132 scoped_ptr<AsyncAPIMock> api_mock_; | 159 scoped_ptr<AsyncAPIMock> api_mock_; |
133 scoped_ptr<CommandBufferService> command_buffer_; | 160 scoped_ptr<CommandBufferService> command_buffer_; |
134 scoped_ptr<GPUProcessor> gpu_processor_; | 161 scoped_ptr<GPUProcessor> gpu_processor_; |
135 CommandParser* parser_; | 162 CommandParser* parser_; |
136 scoped_ptr<CommandBufferHelper> helper_; | 163 scoped_ptr<CommandBufferHelper> helper_; |
137 Sequence sequence_; | 164 // Sequence sequence_; |
apatrick_chromium
2010/06/02 22:24:43
Uncomment or delete line?
| |
165 scoped_ptr<DoJumpCommand> do_jump_command_; | |
138 }; | 166 }; |
139 | 167 |
140 // Checks that commands in the buffer are properly executed, and that the | 168 // Checks that commands in the buffer are properly executed, and that the |
141 // status/error stay valid. | 169 // status/error stay valid. |
142 TEST_F(CommandBufferHelperTest, TestCommandProcessing) { | 170 TEST_F(CommandBufferHelperTest, TestCommandProcessing) { |
143 // Check initial state of the engine - it should have been configured by the | 171 // Check initial state of the engine - it should have been configured by the |
144 // helper. | 172 // helper. |
145 EXPECT_TRUE(parser_ != NULL); | 173 EXPECT_TRUE(parser_ != NULL); |
146 EXPECT_EQ(error::kNoError, GetError()); | 174 EXPECT_EQ(error::kNoError, GetError()); |
147 EXPECT_EQ(0, GetGetOffset()); | 175 EXPECT_EQ(0, GetGetOffset()); |
148 | 176 |
149 // Add 3 commands through the helper | 177 // Add 3 commands through the helper |
150 AddCommandWithExpect(error::kNoError, 1, 0, NULL); | 178 AddCommandWithExpect(error::kNoError, kUnusedCommandId, 0, NULL); |
151 | 179 |
152 CommandBufferEntry args1[2]; | 180 CommandBufferEntry args1[2]; |
153 args1[0].value_uint32 = 3; | 181 args1[0].value_uint32 = 3; |
154 args1[1].value_float = 4.f; | 182 args1[1].value_float = 4.f; |
155 AddCommandWithExpect(error::kNoError, 2, 2, args1); | 183 AddCommandWithExpect(error::kNoError, kUnusedCommandId, 2, args1); |
156 | 184 |
157 CommandBufferEntry args2[2]; | 185 CommandBufferEntry args2[2]; |
158 args2[0].value_uint32 = 5; | 186 args2[0].value_uint32 = 5; |
159 args2[1].value_float = 6.f; | 187 args2[1].value_float = 6.f; |
160 AddCommandWithExpect(error::kNoError, 3, 2, args2); | 188 AddCommandWithExpect(error::kNoError, kUnusedCommandId, 2, args2); |
161 | 189 |
162 helper_->Flush(); | 190 helper_->Flush(); |
163 // Check that the engine has work to do now. | 191 // Check that the engine has work to do now. |
164 EXPECT_FALSE(parser_->IsEmpty()); | 192 EXPECT_FALSE(parser_->IsEmpty()); |
165 | 193 |
166 // Wait until it's done. | 194 // Wait until it's done. |
167 helper_->Finish(); | 195 helper_->Finish(); |
168 // Check that the engine has no more work to do. | 196 // Check that the engine has no more work to do. |
169 EXPECT_TRUE(parser_->IsEmpty()); | 197 EXPECT_TRUE(parser_->IsEmpty()); |
170 | 198 |
171 // Check that the commands did happen. | 199 // Check that the commands did happen. |
172 Mock::VerifyAndClearExpectations(api_mock_.get()); | 200 Mock::VerifyAndClearExpectations(api_mock_.get()); |
173 | 201 |
174 // Check the error status. | 202 // Check the error status. |
175 EXPECT_EQ(error::kNoError, GetError()); | 203 EXPECT_EQ(error::kNoError, GetError()); |
176 } | 204 } |
177 | 205 |
178 // Checks that commands in the buffer are properly executed when wrapping the | 206 // Checks that commands in the buffer are properly executed when wrapping the |
179 // buffer, and that the status/error stay valid. | 207 // buffer, and that the status/error stay valid. |
180 TEST_F(CommandBufferHelperTest, TestCommandWrapping) { | 208 TEST_F(CommandBufferHelperTest, TestCommandWrapping) { |
181 // Add 5 commands of size 3 through the helper to make sure we do wrap. | 209 // Add 5 commands of size 3 through the helper to make sure we do wrap. |
182 CommandBufferEntry args1[2]; | 210 CommandBufferEntry args1[2]; |
183 args1[0].value_uint32 = 5; | 211 args1[0].value_uint32 = 5; |
184 args1[1].value_float = 4.f; | 212 args1[1].value_float = 4.f; |
185 | 213 |
186 for (unsigned int i = 0; i < 5; ++i) { | 214 for (unsigned int i = 0; i < 5; ++i) { |
187 AddCommandWithExpect(error::kNoError, i + 1, 2, args1); | 215 AddCommandWithExpect(error::kNoError, kUnusedCommandId + i, 2, args1); |
188 } | 216 } |
189 | 217 |
190 helper_->Finish(); | 218 helper_->Finish(); |
191 // Check that the commands did happen. | 219 // Check that the commands did happen. |
192 Mock::VerifyAndClearExpectations(api_mock_.get()); | 220 Mock::VerifyAndClearExpectations(api_mock_.get()); |
193 | 221 |
194 // Check the error status. | 222 // Check the error status. |
195 EXPECT_EQ(error::kNoError, GetError()); | 223 EXPECT_EQ(error::kNoError, GetError()); |
196 } | 224 } |
197 | 225 |
198 // Checks the case where the command inserted exactly matches the space left in | 226 // Checks the case where the command inserted exactly matches the space left in |
199 // the command buffer. | 227 // the command buffer. |
200 TEST_F(CommandBufferHelperTest, TestCommandWrappingExactMultiple) { | 228 TEST_F(CommandBufferHelperTest, TestCommandWrappingExactMultiple) { |
201 const int32 kCommandSize = 5; | 229 const int32 kCommandSize = 5; |
202 const size_t kNumArgs = kCommandSize - 1; | 230 const size_t kNumArgs = kCommandSize - 1; |
203 COMPILE_ASSERT(kNumCommandEntries % kCommandSize == 0, | 231 COMPILE_ASSERT(kUsableNumCommandEntries % kCommandSize == 0, |
204 Not_multiple_of_num_command_entries); | 232 Not_multiple_of_num_command_entries); |
205 CommandBufferEntry args1[kNumArgs]; | 233 CommandBufferEntry args1[kNumArgs]; |
206 for (size_t ii = 0; ii < kNumArgs; ++ii) { | 234 for (size_t ii = 0; ii < kNumArgs; ++ii) { |
207 args1[0].value_uint32 = ii + 1; | 235 args1[0].value_uint32 = ii + 1; |
208 } | 236 } |
209 | 237 |
210 for (unsigned int i = 0; i < 5; ++i) { | 238 for (unsigned int i = 0; i < 5; ++i) { |
211 AddCommandWithExpect(error::kNoError, i + 1, kNumArgs, args1); | 239 AddCommandWithExpect( |
240 error::kNoError, i + kUnusedCommandId, kNumArgs, args1); | |
212 } | 241 } |
213 | 242 |
214 helper_->Finish(); | 243 helper_->Finish(); |
215 // Check that the commands did happen. | 244 // Check that the commands did happen. |
216 Mock::VerifyAndClearExpectations(api_mock_.get()); | 245 Mock::VerifyAndClearExpectations(api_mock_.get()); |
217 | 246 |
218 // Check the error status. | 247 // Check the error status. |
219 EXPECT_EQ(error::kNoError, GetError()); | 248 EXPECT_EQ(error::kNoError, GetError()); |
220 } | 249 } |
221 | 250 |
222 // Checks that asking for available entries work, and that the parser | 251 // Checks that asking for available entries work, and that the parser |
223 // effectively won't use that space. | 252 // effectively won't use that space. |
224 TEST_F(CommandBufferHelperTest, TestAvailableEntries) { | 253 TEST_F(CommandBufferHelperTest, TestAvailableEntries) { |
225 CommandBufferEntry args[2]; | 254 CommandBufferEntry args[2]; |
226 args[0].value_uint32 = 3; | 255 args[0].value_uint32 = 3; |
227 args[1].value_float = 4.f; | 256 args[1].value_float = 4.f; |
228 | 257 |
229 // Add 2 commands through the helper - 8 entries | 258 // Add 2 commands through the helper - 8 entries |
230 AddCommandWithExpect(error::kNoError, 1, 0, NULL); | 259 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 1, 0, NULL); |
231 AddCommandWithExpect(error::kNoError, 2, 0, NULL); | 260 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 2, 0, NULL); |
232 AddCommandWithExpect(error::kNoError, 3, 2, args); | 261 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 3, 2, args); |
233 AddCommandWithExpect(error::kNoError, 4, 2, args); | 262 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 4, 2, args); |
234 | 263 |
235 // Ask for 5 entries. | 264 // Ask for 5 entries. |
236 helper_->WaitForAvailableEntries(5); | 265 helper_->WaitForAvailableEntries(5); |
237 | 266 |
238 CommandBufferOffset put = get_helper_put(); | 267 CommandBufferOffset put = get_helper_put(); |
239 CheckFreeSpace(put, 5); | 268 CheckFreeSpace(put, 5); |
240 | 269 |
241 // Add more commands. | 270 // Add more commands. |
242 AddCommandWithExpect(error::kNoError, 5, 2, args); | 271 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 5, 2, args); |
243 | 272 |
244 // Wait until everything is done done. | 273 // Wait until everything is done done. |
245 helper_->Finish(); | 274 helper_->Finish(); |
246 | 275 |
247 // Check that the commands did happen. | 276 // Check that the commands did happen. |
248 Mock::VerifyAndClearExpectations(api_mock_.get()); | 277 Mock::VerifyAndClearExpectations(api_mock_.get()); |
249 | 278 |
250 // Check the error status. | 279 // Check the error status. |
251 EXPECT_EQ(error::kNoError, GetError()); | 280 EXPECT_EQ(error::kNoError, GetError()); |
252 } | 281 } |
253 | 282 |
254 // Checks that the InsertToken/WaitForToken work. | 283 // Checks that the InsertToken/WaitForToken work. |
255 TEST_F(CommandBufferHelperTest, TestToken) { | 284 TEST_F(CommandBufferHelperTest, TestToken) { |
256 CommandBufferEntry args[2]; | 285 CommandBufferEntry args[2]; |
257 args[0].value_uint32 = 3; | 286 args[0].value_uint32 = 3; |
258 args[1].value_float = 4.f; | 287 args[1].value_float = 4.f; |
259 | 288 |
260 // Add a first command. | 289 // Add a first command. |
261 AddCommandWithExpect(error::kNoError, 3, 2, args); | 290 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 3, 2, args); |
262 // keep track of the buffer position. | 291 // keep track of the buffer position. |
263 CommandBufferOffset command1_put = get_helper_put(); | 292 CommandBufferOffset command1_put = get_helper_put(); |
264 int32 token = helper_->InsertToken(); | 293 int32 token = helper_->InsertToken(); |
265 | 294 |
266 EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _)) | 295 EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _)) |
267 .WillOnce(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), | 296 .WillOnce(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), |
268 Return(error::kNoError))); | 297 Return(error::kNoError))); |
269 // Add another command. | 298 // Add another command. |
270 AddCommandWithExpect(error::kNoError, 4, 2, args); | 299 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 4, 2, args); |
271 helper_->WaitForToken(token); | 300 helper_->WaitForToken(token); |
272 // check that the get pointer is beyond the first command. | 301 // check that the get pointer is beyond the first command. |
273 EXPECT_LE(command1_put, GetGetOffset()); | 302 EXPECT_LE(command1_put, GetGetOffset()); |
274 helper_->Finish(); | 303 helper_->Finish(); |
275 | 304 |
276 // Check that the commands did happen. | 305 // Check that the commands did happen. |
277 Mock::VerifyAndClearExpectations(api_mock_.get()); | 306 Mock::VerifyAndClearExpectations(api_mock_.get()); |
278 | 307 |
279 // Check the error status. | 308 // Check the error status. |
280 EXPECT_EQ(error::kNoError, GetError()); | 309 EXPECT_EQ(error::kNoError, GetError()); |
281 } | 310 } |
282 | 311 |
283 } // namespace gpu | 312 } // namespace gpu |
OLD | NEW |