Handle account removal correctly on all platforms.
[chromium-blink-merge.git] / gpu / command_buffer / client / cmd_buffer_helper_test.cc
blob625007455032b171629a25bc2da4158a5c220142
1 // Copyright (c) 2012 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.
5 // Tests for the Command Buffer Helper.
7 #include <list>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/memory/linked_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "gpu/command_buffer/client/cmd_buffer_helper.h"
14 #include "gpu/command_buffer/service/command_buffer_service.h"
15 #include "gpu/command_buffer/service/gpu_scheduler.h"
16 #include "gpu/command_buffer/service/mocks.h"
17 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 #if defined(OS_MACOSX)
21 #include "base/mac/scoped_nsautorelease_pool.h"
22 #endif
24 namespace gpu {
26 using testing::Return;
27 using testing::Mock;
28 using testing::Truly;
29 using testing::Sequence;
30 using testing::DoAll;
31 using testing::Invoke;
32 using testing::_;
34 const int32 kTotalNumCommandEntries = 32;
35 const int32 kCommandBufferSizeBytes =
36 kTotalNumCommandEntries * sizeof(CommandBufferEntry);
37 const int32 kUnusedCommandId = 5; // we use 0 and 2 currently.
39 // Override CommandBufferService::Flush() to lock flushing and simulate
40 // the buffer becoming full in asynchronous mode.
41 class CommandBufferServiceLocked : public CommandBufferService {
42 public:
43 explicit CommandBufferServiceLocked(
44 TransferBufferManagerInterface* transfer_buffer_manager)
45 : CommandBufferService(transfer_buffer_manager),
46 flush_locked_(false),
47 last_flush_(-1),
48 flush_count_(0) {}
49 virtual ~CommandBufferServiceLocked() {}
51 virtual void Flush(int32 put_offset) OVERRIDE {
52 flush_count_++;
53 if (!flush_locked_) {
54 last_flush_ = -1;
55 CommandBufferService::Flush(put_offset);
56 } else {
57 last_flush_ = put_offset;
61 void LockFlush() { flush_locked_ = true; }
63 void UnlockFlush() { flush_locked_ = false; }
65 int FlushCount() { return flush_count_; }
67 virtual void WaitForGetOffsetInRange(int32 start, int32 end) OVERRIDE {
68 if (last_flush_ != -1) {
69 CommandBufferService::Flush(last_flush_);
70 last_flush_ = -1;
72 CommandBufferService::WaitForGetOffsetInRange(start, end);
75 private:
76 bool flush_locked_;
77 int last_flush_;
78 int flush_count_;
79 DISALLOW_COPY_AND_ASSIGN(CommandBufferServiceLocked);
82 // Test fixture for CommandBufferHelper test - Creates a CommandBufferHelper,
83 // using a CommandBufferEngine with a mock AsyncAPIInterface for its interface
84 // (calling it directly, not through the RPC mechanism).
85 class CommandBufferHelperTest : public testing::Test {
86 protected:
87 virtual void SetUp() {
88 api_mock_.reset(new AsyncAPIMock(true));
90 // ignore noops in the mock - we don't want to inspect the internals of the
91 // helper.
92 EXPECT_CALL(*api_mock_, DoCommand(cmd::kNoop, _, _))
93 .WillRepeatedly(Return(error::kNoError));
96 TransferBufferManager* manager = new TransferBufferManager();
97 transfer_buffer_manager_.reset(manager);
98 EXPECT_TRUE(manager->Initialize());
100 command_buffer_.reset(
101 new CommandBufferServiceLocked(transfer_buffer_manager_.get()));
102 EXPECT_TRUE(command_buffer_->Initialize());
104 gpu_scheduler_.reset(new GpuScheduler(
105 command_buffer_.get(), api_mock_.get(), NULL));
106 command_buffer_->SetPutOffsetChangeCallback(base::Bind(
107 &GpuScheduler::PutChanged, base::Unretained(gpu_scheduler_.get())));
108 command_buffer_->SetGetBufferChangeCallback(base::Bind(
109 &GpuScheduler::SetGetBuffer, base::Unretained(gpu_scheduler_.get())));
111 api_mock_->set_engine(gpu_scheduler_.get());
113 helper_.reset(new CommandBufferHelper(command_buffer_.get()));
114 helper_->Initialize(kCommandBufferSizeBytes);
116 test_command_next_id_ = kUnusedCommandId;
119 virtual void TearDown() {
120 // If the GpuScheduler posts any tasks, this forces them to run.
121 base::MessageLoop::current()->RunUntilIdle();
122 test_command_args_.clear();
125 const CommandParser* GetParser() const {
126 return gpu_scheduler_->parser();
129 int32 ImmediateEntryCount() const { return helper_->immediate_entry_count_; }
131 // Adds a command to the buffer through the helper, while adding it as an
132 // expected call on the API mock.
133 void AddCommandWithExpect(error::Error _return,
134 unsigned int command,
135 int arg_count,
136 CommandBufferEntry *args) {
137 CommandHeader header;
138 header.size = arg_count + 1;
139 header.command = command;
140 CommandBufferEntry* cmds =
141 static_cast<CommandBufferEntry*>(helper_->GetSpace(arg_count + 1));
142 CommandBufferOffset put = 0;
143 cmds[put++].value_header = header;
144 for (int ii = 0; ii < arg_count; ++ii) {
145 cmds[put++] = args[ii];
148 EXPECT_CALL(*api_mock_, DoCommand(command, arg_count,
149 Truly(AsyncAPIMock::IsArgs(arg_count, args))))
150 .InSequence(sequence_)
151 .WillOnce(Return(_return));
154 void AddUniqueCommandWithExpect(error::Error _return, int cmd_size) {
155 EXPECT_GE(cmd_size, 1);
156 EXPECT_LT(cmd_size, kTotalNumCommandEntries);
157 int arg_count = cmd_size - 1;
159 // Allocate array for args.
160 linked_ptr<std::vector<CommandBufferEntry> > args_ptr(
161 new std::vector<CommandBufferEntry>(arg_count ? arg_count : 1));
163 for (int32 ii = 0; ii < arg_count; ++ii) {
164 (*args_ptr)[ii].value_uint32 = 0xF00DF00D + ii;
167 // Add command and save args in test_command_args_ until the test completes.
168 AddCommandWithExpect(
169 _return, test_command_next_id_++, arg_count, &(*args_ptr)[0]);
170 test_command_args_.insert(test_command_args_.end(), args_ptr);
173 void TestCommandWrappingFull(int32 cmd_size, int32 start_commands) {
174 const int32 num_args = cmd_size - 1;
175 EXPECT_EQ(kTotalNumCommandEntries % cmd_size, 0);
177 std::vector<CommandBufferEntry> args(num_args);
178 for (int32 ii = 0; ii < num_args; ++ii) {
179 args[ii].value_uint32 = ii + 1;
182 // Initially insert commands up to start_commands and Finish().
183 for (int32 ii = 0; ii < start_commands; ++ii) {
184 AddCommandWithExpect(
185 error::kNoError, ii + kUnusedCommandId, num_args, &args[0]);
187 helper_->Finish();
189 EXPECT_EQ(GetParser()->put(),
190 (start_commands * cmd_size) % kTotalNumCommandEntries);
191 EXPECT_EQ(GetParser()->get(),
192 (start_commands * cmd_size) % kTotalNumCommandEntries);
194 // Lock flushing to force the buffer to get full.
195 command_buffer_->LockFlush();
197 // Add enough commands to over fill the buffer.
198 for (int32 ii = 0; ii < kTotalNumCommandEntries / cmd_size + 2; ++ii) {
199 AddCommandWithExpect(error::kNoError,
200 start_commands + ii + kUnusedCommandId,
201 num_args,
202 &args[0]);
205 // Flush all commands.
206 command_buffer_->UnlockFlush();
207 helper_->Finish();
209 // Check that the commands did happen.
210 Mock::VerifyAndClearExpectations(api_mock_.get());
212 // Check the error status.
213 EXPECT_EQ(error::kNoError, GetError());
216 // Checks that the buffer from put to put+size is free in the parser.
217 void CheckFreeSpace(CommandBufferOffset put, unsigned int size) {
218 CommandBufferOffset parser_put = GetParser()->put();
219 CommandBufferOffset parser_get = GetParser()->get();
220 CommandBufferOffset limit = put + size;
221 if (parser_get > parser_put) {
222 // "busy" buffer wraps, so "free" buffer is between put (inclusive) and
223 // get (exclusive).
224 EXPECT_LE(parser_put, put);
225 EXPECT_GT(parser_get, limit);
226 } else {
227 // "busy" buffer does not wrap, so the "free" buffer is the top side (from
228 // put to the limit) and the bottom side (from 0 to get).
229 if (put >= parser_put) {
230 // we're on the top side, check we are below the limit.
231 EXPECT_GE(kTotalNumCommandEntries, limit);
232 } else {
233 // we're on the bottom side, check we are below get.
234 EXPECT_GT(parser_get, limit);
239 int32 GetGetOffset() {
240 return command_buffer_->GetLastState().get_offset;
243 int32 GetPutOffset() {
244 return command_buffer_->GetLastState().put_offset;
247 int32 GetHelperGetOffset() { return helper_->get_offset(); }
249 int32 GetHelperPutOffset() { return helper_->put_; }
251 uint32 GetHelperFlushGeneration() { return helper_->flush_generation(); }
253 error::Error GetError() {
254 return command_buffer_->GetLastState().error;
257 CommandBufferOffset get_helper_put() { return helper_->put_; }
259 #if defined(OS_MACOSX)
260 base::mac::ScopedNSAutoreleasePool autorelease_pool_;
261 #endif
262 base::MessageLoop message_loop_;
263 scoped_ptr<AsyncAPIMock> api_mock_;
264 scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_;
265 scoped_ptr<CommandBufferServiceLocked> command_buffer_;
266 scoped_ptr<GpuScheduler> gpu_scheduler_;
267 scoped_ptr<CommandBufferHelper> helper_;
268 std::list<linked_ptr<std::vector<CommandBufferEntry> > > test_command_args_;
269 unsigned int test_command_next_id_;
270 Sequence sequence_;
273 // Checks immediate_entry_count_ changes based on 'usable' state.
274 TEST_F(CommandBufferHelperTest, TestCalcImmediateEntriesNotUsable) {
275 // Auto flushing mode is tested separately.
276 helper_->SetAutomaticFlushes(false);
277 EXPECT_EQ(helper_->usable(), true);
278 EXPECT_EQ(ImmediateEntryCount(), kTotalNumCommandEntries - 1);
279 helper_->ClearUsable();
280 EXPECT_EQ(ImmediateEntryCount(), 0);
283 // Checks immediate_entry_count_ changes based on RingBuffer state.
284 TEST_F(CommandBufferHelperTest, TestCalcImmediateEntriesNoRingBuffer) {
285 helper_->SetAutomaticFlushes(false);
286 EXPECT_EQ(ImmediateEntryCount(), kTotalNumCommandEntries - 1);
287 helper_->FreeRingBuffer();
288 EXPECT_EQ(ImmediateEntryCount(), 0);
291 // Checks immediate_entry_count_ calc when Put >= Get and Get == 0.
292 TEST_F(CommandBufferHelperTest, TestCalcImmediateEntriesGetAtZero) {
293 // No internal auto flushing.
294 helper_->SetAutomaticFlushes(false);
295 command_buffer_->LockFlush();
297 // Start at Get = Put = 0.
298 EXPECT_EQ(GetHelperPutOffset(), 0);
299 EXPECT_EQ(GetHelperGetOffset(), 0);
301 // Immediate count should be 1 less than the end of the buffer.
302 EXPECT_EQ(ImmediateEntryCount(), kTotalNumCommandEntries - 1);
303 AddUniqueCommandWithExpect(error::kNoError, 2);
304 EXPECT_EQ(ImmediateEntryCount(), kTotalNumCommandEntries - 3);
306 helper_->Finish();
308 // Check that the commands did happen.
309 Mock::VerifyAndClearExpectations(api_mock_.get());
311 // Check the error status.
312 EXPECT_EQ(error::kNoError, GetError());
315 // Checks immediate_entry_count_ calc when Put >= Get and Get > 0.
316 TEST_F(CommandBufferHelperTest, TestCalcImmediateEntriesGetInMiddle) {
317 // No internal auto flushing.
318 helper_->SetAutomaticFlushes(false);
319 command_buffer_->LockFlush();
321 // Move to Get = Put = 2.
322 AddUniqueCommandWithExpect(error::kNoError, 2);
323 helper_->Finish();
324 EXPECT_EQ(GetHelperPutOffset(), 2);
325 EXPECT_EQ(GetHelperGetOffset(), 2);
327 // Immediate count should be up to the end of the buffer.
328 EXPECT_EQ(ImmediateEntryCount(), kTotalNumCommandEntries - 2);
329 AddUniqueCommandWithExpect(error::kNoError, 2);
330 EXPECT_EQ(ImmediateEntryCount(), kTotalNumCommandEntries - 4);
332 helper_->Finish();
334 // Check that the commands did happen.
335 Mock::VerifyAndClearExpectations(api_mock_.get());
337 // Check the error status.
338 EXPECT_EQ(error::kNoError, GetError());
341 // Checks immediate_entry_count_ calc when Put < Get.
342 TEST_F(CommandBufferHelperTest, TestCalcImmediateEntriesGetBeforePut) {
343 // Move to Get = kTotalNumCommandEntries / 4, Put = 0.
344 const int kInitGetOffset = kTotalNumCommandEntries / 4;
345 helper_->SetAutomaticFlushes(false);
346 command_buffer_->LockFlush();
347 AddUniqueCommandWithExpect(error::kNoError, kInitGetOffset);
348 helper_->Finish();
349 AddUniqueCommandWithExpect(error::kNoError,
350 kTotalNumCommandEntries - kInitGetOffset);
352 // Flush instead of Finish will let Put wrap without the command buffer
353 // immediately processing the data between Get and Put.
354 helper_->Flush();
356 EXPECT_EQ(GetHelperGetOffset(), kInitGetOffset);
357 EXPECT_EQ(GetHelperPutOffset(), 0);
359 // Immediate count should be up to Get - 1.
360 EXPECT_EQ(ImmediateEntryCount(), kInitGetOffset - 1);
361 AddUniqueCommandWithExpect(error::kNoError, 2);
362 EXPECT_EQ(ImmediateEntryCount(), kInitGetOffset - 3);
364 helper_->Finish();
365 // Check that the commands did happen.
366 Mock::VerifyAndClearExpectations(api_mock_.get());
368 // Check the error status.
369 EXPECT_EQ(error::kNoError, GetError());
372 // Checks immediate_entry_count_ calc when automatic flushing is enabled.
373 TEST_F(CommandBufferHelperTest, TestCalcImmediateEntriesAutoFlushing) {
374 command_buffer_->LockFlush();
376 // Start at Get = Put = 0.
377 EXPECT_EQ(GetHelperPutOffset(), 0);
378 EXPECT_EQ(GetHelperGetOffset(), 0);
380 // Without auto flushes, up to kTotalNumCommandEntries - 1 is available.
381 helper_->SetAutomaticFlushes(false);
382 EXPECT_EQ(ImmediateEntryCount(), kTotalNumCommandEntries - 1);
384 // With auto flushes, and Get == Last Put,
385 // up to kTotalNumCommandEntries / kAutoFlushSmall is available.
386 helper_->SetAutomaticFlushes(true);
387 EXPECT_EQ(ImmediateEntryCount(), kTotalNumCommandEntries / kAutoFlushSmall);
389 // With auto flushes, and Get != Last Put,
390 // up to kTotalNumCommandEntries / kAutoFlushBig is available.
391 AddUniqueCommandWithExpect(error::kNoError, 2);
392 helper_->Flush();
393 EXPECT_EQ(ImmediateEntryCount(), kTotalNumCommandEntries / kAutoFlushBig);
395 helper_->Finish();
396 // Check that the commands did happen.
397 Mock::VerifyAndClearExpectations(api_mock_.get());
399 // Check the error status.
400 EXPECT_EQ(error::kNoError, GetError());
403 // Checks immediate_entry_count_ calc when automatic flushing is enabled, and
404 // we allocate commands over the immediate_entry_count_ size.
405 TEST_F(CommandBufferHelperTest, TestCalcImmediateEntriesOverFlushLimit) {
406 // Lock internal flushing.
407 command_buffer_->LockFlush();
409 // Start at Get = Put = 0.
410 EXPECT_EQ(GetHelperPutOffset(), 0);
411 EXPECT_EQ(GetHelperGetOffset(), 0);
413 // Pre-check ImmediateEntryCount is limited with automatic flushing enabled.
414 helper_->SetAutomaticFlushes(true);
415 EXPECT_EQ(ImmediateEntryCount(), kTotalNumCommandEntries / kAutoFlushSmall);
417 // Add a command larger than ImmediateEntryCount().
418 AddUniqueCommandWithExpect(error::kNoError, ImmediateEntryCount() + 1);
420 // ImmediateEntryCount() should now be 0, to force a flush check on the next
421 // command.
422 EXPECT_EQ(ImmediateEntryCount(), 0);
424 // Add a command when ImmediateEntryCount() == 0.
425 AddUniqueCommandWithExpect(error::kNoError, ImmediateEntryCount() + 1);
427 helper_->Finish();
428 // Check that the commands did happen.
429 Mock::VerifyAndClearExpectations(api_mock_.get());
431 // Check the error status.
432 EXPECT_EQ(error::kNoError, GetError());
435 // Checks that commands in the buffer are properly executed, and that the
436 // status/error stay valid.
437 TEST_F(CommandBufferHelperTest, TestCommandProcessing) {
438 // Check initial state of the engine - it should have been configured by the
439 // helper.
440 EXPECT_TRUE(GetParser() != NULL);
441 EXPECT_EQ(error::kNoError, GetError());
442 EXPECT_EQ(0, GetGetOffset());
444 // Add 3 commands through the helper
445 AddCommandWithExpect(error::kNoError, kUnusedCommandId, 0, NULL);
447 CommandBufferEntry args1[2];
448 args1[0].value_uint32 = 3;
449 args1[1].value_float = 4.f;
450 AddCommandWithExpect(error::kNoError, kUnusedCommandId, 2, args1);
452 CommandBufferEntry args2[2];
453 args2[0].value_uint32 = 5;
454 args2[1].value_float = 6.f;
455 AddCommandWithExpect(error::kNoError, kUnusedCommandId, 2, args2);
457 // Wait until it's done.
458 helper_->Finish();
459 // Check that the engine has no more work to do.
460 EXPECT_TRUE(GetParser()->IsEmpty());
462 // Check that the commands did happen.
463 Mock::VerifyAndClearExpectations(api_mock_.get());
465 // Check the error status.
466 EXPECT_EQ(error::kNoError, GetError());
469 // Checks that commands in the buffer are properly executed when wrapping the
470 // buffer, and that the status/error stay valid.
471 TEST_F(CommandBufferHelperTest, TestCommandWrapping) {
472 // Add num_commands * commands of size 3 through the helper to make sure we
473 // do wrap. kTotalNumCommandEntries must not be a multiple of 3.
474 COMPILE_ASSERT(kTotalNumCommandEntries % 3 != 0,
475 Is_multiple_of_num_command_entries);
476 const int kNumCommands = (kTotalNumCommandEntries / 3) * 2;
477 CommandBufferEntry args1[2];
478 args1[0].value_uint32 = 5;
479 args1[1].value_float = 4.f;
481 for (int i = 0; i < kNumCommands; ++i) {
482 AddCommandWithExpect(error::kNoError, kUnusedCommandId + i, 2, args1);
485 helper_->Finish();
486 // Check that the commands did happen.
487 Mock::VerifyAndClearExpectations(api_mock_.get());
489 // Check the error status.
490 EXPECT_EQ(error::kNoError, GetError());
493 // Checks the case where the command inserted exactly matches the space left in
494 // the command buffer.
495 TEST_F(CommandBufferHelperTest, TestCommandWrappingExactMultiple) {
496 const int32 kCommandSize = kTotalNumCommandEntries / 2;
497 const size_t kNumArgs = kCommandSize - 1;
498 COMPILE_ASSERT(kTotalNumCommandEntries % kCommandSize == 0,
499 Not_multiple_of_num_command_entries);
500 CommandBufferEntry args1[kNumArgs];
501 for (size_t ii = 0; ii < kNumArgs; ++ii) {
502 args1[ii].value_uint32 = ii + 1;
505 for (unsigned int i = 0; i < 5; ++i) {
506 AddCommandWithExpect(
507 error::kNoError, i + kUnusedCommandId, kNumArgs, args1);
510 helper_->Finish();
511 // Check that the commands did happen.
512 Mock::VerifyAndClearExpectations(api_mock_.get());
514 // Check the error status.
515 EXPECT_EQ(error::kNoError, GetError());
518 // Checks exact wrapping condition with Get = 0.
519 TEST_F(CommandBufferHelperTest, TestCommandWrappingFullAtStart) {
520 TestCommandWrappingFull(2, 0);
523 // Checks exact wrapping condition with 0 < Get < kTotalNumCommandEntries.
524 TEST_F(CommandBufferHelperTest, TestCommandWrappingFullInMiddle) {
525 TestCommandWrappingFull(2, 1);
528 // Checks exact wrapping condition with Get = kTotalNumCommandEntries.
529 // Get should wrap back to 0, but making sure.
530 TEST_F(CommandBufferHelperTest, TestCommandWrappingFullAtEnd) {
531 TestCommandWrappingFull(2, kTotalNumCommandEntries / 2);
534 // Checks that asking for available entries work, and that the parser
535 // effectively won't use that space.
536 TEST_F(CommandBufferHelperTest, TestAvailableEntries) {
537 CommandBufferEntry args[2];
538 args[0].value_uint32 = 3;
539 args[1].value_float = 4.f;
541 // Add 2 commands through the helper - 8 entries
542 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 1, 0, NULL);
543 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 2, 0, NULL);
544 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 3, 2, args);
545 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 4, 2, args);
547 // Ask for 5 entries.
548 helper_->WaitForAvailableEntries(5);
550 CommandBufferOffset put = get_helper_put();
551 CheckFreeSpace(put, 5);
553 // Add more commands.
554 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 5, 2, args);
556 // Wait until everything is done done.
557 helper_->Finish();
559 // Check that the commands did happen.
560 Mock::VerifyAndClearExpectations(api_mock_.get());
562 // Check the error status.
563 EXPECT_EQ(error::kNoError, GetError());
566 // Checks that the InsertToken/WaitForToken work.
567 TEST_F(CommandBufferHelperTest, TestToken) {
568 CommandBufferEntry args[2];
569 args[0].value_uint32 = 3;
570 args[1].value_float = 4.f;
572 // Add a first command.
573 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 3, 2, args);
574 // keep track of the buffer position.
575 CommandBufferOffset command1_put = get_helper_put();
576 int32 token = helper_->InsertToken();
578 EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _))
579 .WillOnce(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken),
580 Return(error::kNoError)));
581 // Add another command.
582 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 4, 2, args);
583 helper_->WaitForToken(token);
584 // check that the get pointer is beyond the first command.
585 EXPECT_LE(command1_put, GetGetOffset());
586 helper_->Finish();
588 // Check that the commands did happen.
589 Mock::VerifyAndClearExpectations(api_mock_.get());
591 // Check the error status.
592 EXPECT_EQ(error::kNoError, GetError());
595 // Checks WaitForToken doesn't Flush if token is already read.
596 TEST_F(CommandBufferHelperTest, TestWaitForTokenFlush) {
597 CommandBufferEntry args[2];
598 args[0].value_uint32 = 3;
599 args[1].value_float = 4.f;
601 // Add a first command.
602 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 3, 2, args);
603 int32 token = helper_->InsertToken();
605 EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _))
606 .WillOnce(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken),
607 Return(error::kNoError)));
609 int flush_count = command_buffer_->FlushCount();
611 // Test that waiting for pending token causes a Flush.
612 helper_->WaitForToken(token);
613 EXPECT_EQ(command_buffer_->FlushCount(), flush_count + 1);
615 // Test that we don't Flush repeatedly.
616 helper_->WaitForToken(token);
617 EXPECT_EQ(command_buffer_->FlushCount(), flush_count + 1);
619 // Add another command.
620 AddCommandWithExpect(error::kNoError, kUnusedCommandId + 4, 2, args);
622 // Test that we don't Flush repeatedly even if commands are pending.
623 helper_->WaitForToken(token);
624 EXPECT_EQ(command_buffer_->FlushCount(), flush_count + 1);
626 helper_->Finish();
628 // Check that the commands did happen.
629 Mock::VerifyAndClearExpectations(api_mock_.get());
631 // Check the error status.
632 EXPECT_EQ(error::kNoError, GetError());
635 TEST_F(CommandBufferHelperTest, FreeRingBuffer) {
636 EXPECT_TRUE(helper_->HaveRingBuffer());
638 // Test freeing ring buffer.
639 helper_->FreeRingBuffer();
640 EXPECT_FALSE(helper_->HaveRingBuffer());
642 // Test that InsertToken allocates a new one
643 int32 token = helper_->InsertToken();
644 EXPECT_TRUE(helper_->HaveRingBuffer());
645 EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _))
646 .WillOnce(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken),
647 Return(error::kNoError)));
648 helper_->WaitForToken(token);
649 helper_->FreeRingBuffer();
650 EXPECT_FALSE(helper_->HaveRingBuffer());
652 // Test that WaitForAvailableEntries allocates a new one
653 AddCommandWithExpect(error::kNoError, kUnusedCommandId, 0, NULL);
654 EXPECT_TRUE(helper_->HaveRingBuffer());
655 helper_->Finish();
656 helper_->FreeRingBuffer();
657 EXPECT_FALSE(helper_->HaveRingBuffer());
659 // Check that the commands did happen.
660 Mock::VerifyAndClearExpectations(api_mock_.get());
663 TEST_F(CommandBufferHelperTest, Noop) {
664 for (int ii = 1; ii < 4; ++ii) {
665 CommandBufferOffset put_before = get_helper_put();
666 helper_->Noop(ii);
667 CommandBufferOffset put_after = get_helper_put();
668 EXPECT_EQ(ii, put_after - put_before);
672 TEST_F(CommandBufferHelperTest, IsContextLost) {
673 EXPECT_FALSE(helper_->IsContextLost());
674 command_buffer_->SetParseError(error::kGenericError);
675 EXPECT_TRUE(helper_->IsContextLost());
678 // Checks helper's 'flush generation' updates.
679 TEST_F(CommandBufferHelperTest, TestFlushGeneration) {
680 // Explicit flushing only.
681 helper_->SetAutomaticFlushes(false);
683 // Generation should change after Flush() but not before.
684 uint32 gen1, gen2, gen3;
686 gen1 = GetHelperFlushGeneration();
687 AddUniqueCommandWithExpect(error::kNoError, 2);
688 gen2 = GetHelperFlushGeneration();
689 helper_->Flush();
690 gen3 = GetHelperFlushGeneration();
691 EXPECT_EQ(gen2, gen1);
692 EXPECT_NE(gen3, gen2);
694 // Generation should change after Finish() but not before.
695 gen1 = GetHelperFlushGeneration();
696 AddUniqueCommandWithExpect(error::kNoError, 2);
697 gen2 = GetHelperFlushGeneration();
698 helper_->Finish();
699 gen3 = GetHelperFlushGeneration();
700 EXPECT_EQ(gen2, gen1);
701 EXPECT_NE(gen3, gen2);
703 helper_->Finish();
705 // Check that the commands did happen.
706 Mock::VerifyAndClearExpectations(api_mock_.get());
708 // Check the error status.
709 EXPECT_EQ(error::kNoError, GetError());
712 } // namespace gpu