Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / client / cmd_buffer_helper_test.cc
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.
4
5 // Tests for the Command Buffer Helper.
6
7 #include <list>
8
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"
19
20 #if defined(OS_MACOSX)
21 #include "base/mac/scoped_nsautorelease_pool.h"
22 #endif
23
24 namespace gpu {
25
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::_;
33
34 const int32 kTotalNumCommandEntries = 32;
35 const int32 kCommandBufferSizeBytes =
36     kTotalNumCommandEntries * sizeof(CommandBufferEntry);
37 const int32 kUnusedCommandId = 5;  // we use 0 and 2 currently.
38
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() {}
50
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;
58     }
59   }
60
61   void LockFlush() { flush_locked_ = true; }
62
63   void UnlockFlush() { flush_locked_ = false; }
64
65   int FlushCount() { return flush_count_; }
66
67   virtual void WaitForGetOffsetInRange(int32 start, int32 end) OVERRIDE {
68     if (last_flush_ != -1) {
69       CommandBufferService::Flush(last_flush_);
70       last_flush_ = -1;
71     }
72     CommandBufferService::WaitForGetOffsetInRange(start, end);
73   }
74
75  private:
76   bool flush_locked_;
77   int last_flush_;
78   int flush_count_;
79   DISALLOW_COPY_AND_ASSIGN(CommandBufferServiceLocked);
80 };
81
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));
89
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));
94
95     {
96       TransferBufferManager* manager = new TransferBufferManager();
97       transfer_buffer_manager_.reset(manager);
98       EXPECT_TRUE(manager->Initialize());
99     }
100     command_buffer_.reset(
101         new CommandBufferServiceLocked(transfer_buffer_manager_.get()));
102     EXPECT_TRUE(command_buffer_->Initialize());
103
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())));
110
111     api_mock_->set_engine(gpu_scheduler_.get());
112
113     helper_.reset(new CommandBufferHelper(command_buffer_.get()));
114     helper_->Initialize(kCommandBufferSizeBytes);
115
116     test_command_next_id_ = kUnusedCommandId;
117   }
118
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();
123   }
124
125   const CommandParser* GetParser() const {
126     return gpu_scheduler_->parser();
127   }
128
129   int32 ImmediateEntryCount() const { return helper_->immediate_entry_count_; }
130
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];
146     }
147
148     EXPECT_CALL(*api_mock_, DoCommand(command, arg_count,
149         Truly(AsyncAPIMock::IsArgs(arg_count, args))))
150         .InSequence(sequence_)
151         .WillOnce(Return(_return));
152   }
153
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;
158
159     // Allocate array for args.
160     linked_ptr<std::vector<CommandBufferEntry> > args_ptr(
161         new std::vector<CommandBufferEntry>(arg_count ? arg_count : 1));
162
163     for (int32 ii = 0; ii < arg_count; ++ii) {
164       (*args_ptr)[ii].value_uint32 = 0xF00DF00D + ii;
165     }
166
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);
171   }
172
173   void TestCommandWrappingFull(int32 cmd_size, int32 start_commands) {
174     const int32 num_args = cmd_size - 1;
175     EXPECT_EQ(kTotalNumCommandEntries % cmd_size, 0);
176
177     std::vector<CommandBufferEntry> args(num_args);
178     for (int32 ii = 0; ii < num_args; ++ii) {
179       args[ii].value_uint32 = ii + 1;
180     }
181
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]);
186     }
187     helper_->Finish();
188
189     EXPECT_EQ(GetParser()->put(),
190               (start_commands * cmd_size) % kTotalNumCommandEntries);
191     EXPECT_EQ(GetParser()->get(),
192               (start_commands * cmd_size) % kTotalNumCommandEntries);
193
194     // Lock flushing to force the buffer to get full.
195     command_buffer_->LockFlush();
196
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]);
203     }
204
205     // Flush all commands.
206     command_buffer_->UnlockFlush();
207     helper_->Finish();
208
209     // Check that the commands did happen.
210     Mock::VerifyAndClearExpectations(api_mock_.get());
211
212     // Check the error status.
213     EXPECT_EQ(error::kNoError, GetError());
214   }
215
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);
235       }
236     }
237   }
238
239   int32 GetGetOffset() {
240     return command_buffer_->GetLastState().get_offset;
241   }
242
243   int32 GetPutOffset() {
244     return command_buffer_->GetLastState().put_offset;
245   }
246
247   int32 GetHelperGetOffset() { return helper_->get_offset(); }
248
249   int32 GetHelperPutOffset() { return helper_->put_; }
250
251   uint32 GetHelperFlushGeneration() { return helper_->flush_generation(); }
252
253   error::Error GetError() {
254     return command_buffer_->GetLastState().error;
255   }
256
257   CommandBufferOffset get_helper_put() { return helper_->put_; }
258
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_;
271 };
272
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);
281 }
282
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);
289 }
290
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();
296
297   // Start at Get = Put = 0.
298   EXPECT_EQ(GetHelperPutOffset(), 0);
299   EXPECT_EQ(GetHelperGetOffset(), 0);
300
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);
305
306   helper_->Finish();
307
308   // Check that the commands did happen.
309   Mock::VerifyAndClearExpectations(api_mock_.get());
310
311   // Check the error status.
312   EXPECT_EQ(error::kNoError, GetError());
313 }
314
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();
320
321   // Move to Get = Put = 2.
322   AddUniqueCommandWithExpect(error::kNoError, 2);
323   helper_->Finish();
324   EXPECT_EQ(GetHelperPutOffset(), 2);
325   EXPECT_EQ(GetHelperGetOffset(), 2);
326
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);
331
332   helper_->Finish();
333
334   // Check that the commands did happen.
335   Mock::VerifyAndClearExpectations(api_mock_.get());
336
337   // Check the error status.
338   EXPECT_EQ(error::kNoError, GetError());
339 }
340
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);
351
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();
355
356   EXPECT_EQ(GetHelperGetOffset(), kInitGetOffset);
357   EXPECT_EQ(GetHelperPutOffset(), 0);
358
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);
363
364   helper_->Finish();
365   // Check that the commands did happen.
366   Mock::VerifyAndClearExpectations(api_mock_.get());
367
368   // Check the error status.
369   EXPECT_EQ(error::kNoError, GetError());
370 }
371
372 // Checks immediate_entry_count_ calc when automatic flushing is enabled.
373 TEST_F(CommandBufferHelperTest, TestCalcImmediateEntriesAutoFlushing) {
374   command_buffer_->LockFlush();
375
376   // Start at Get = Put = 0.
377   EXPECT_EQ(GetHelperPutOffset(), 0);
378   EXPECT_EQ(GetHelperGetOffset(), 0);
379
380   // Without auto flushes, up to kTotalNumCommandEntries - 1 is available.
381   helper_->SetAutomaticFlushes(false);
382   EXPECT_EQ(ImmediateEntryCount(), kTotalNumCommandEntries - 1);
383
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);
388
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);
394
395   helper_->Finish();
396   // Check that the commands did happen.
397   Mock::VerifyAndClearExpectations(api_mock_.get());
398
399   // Check the error status.
400   EXPECT_EQ(error::kNoError, GetError());
401 }
402
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();
408
409   // Start at Get = Put = 0.
410   EXPECT_EQ(GetHelperPutOffset(), 0);
411   EXPECT_EQ(GetHelperGetOffset(), 0);
412
413   // Pre-check ImmediateEntryCount is limited with automatic flushing enabled.
414   helper_->SetAutomaticFlushes(true);
415   EXPECT_EQ(ImmediateEntryCount(), kTotalNumCommandEntries / kAutoFlushSmall);
416
417   // Add a command larger than ImmediateEntryCount().
418   AddUniqueCommandWithExpect(error::kNoError, ImmediateEntryCount() + 1);
419
420   // ImmediateEntryCount() should now be 0, to force a flush check on the next
421   // command.
422   EXPECT_EQ(ImmediateEntryCount(), 0);
423
424   // Add a command when ImmediateEntryCount() == 0.
425   AddUniqueCommandWithExpect(error::kNoError, ImmediateEntryCount() + 1);
426
427   helper_->Finish();
428   // Check that the commands did happen.
429   Mock::VerifyAndClearExpectations(api_mock_.get());
430
431   // Check the error status.
432   EXPECT_EQ(error::kNoError, GetError());
433 }
434
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());
443
444   // Add 3 commands through the helper
445   AddCommandWithExpect(error::kNoError, kUnusedCommandId, 0, NULL);
446
447   CommandBufferEntry args1[2];
448   args1[0].value_uint32 = 3;
449   args1[1].value_float = 4.f;
450   AddCommandWithExpect(error::kNoError, kUnusedCommandId, 2, args1);
451
452   CommandBufferEntry args2[2];
453   args2[0].value_uint32 = 5;
454   args2[1].value_float = 6.f;
455   AddCommandWithExpect(error::kNoError, kUnusedCommandId, 2, args2);
456
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());
461
462   // Check that the commands did happen.
463   Mock::VerifyAndClearExpectations(api_mock_.get());
464
465   // Check the error status.
466   EXPECT_EQ(error::kNoError, GetError());
467 }
468
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;
480
481   for (int i = 0; i < kNumCommands; ++i) {
482     AddCommandWithExpect(error::kNoError, kUnusedCommandId + i, 2, args1);
483   }
484
485   helper_->Finish();
486   // Check that the commands did happen.
487   Mock::VerifyAndClearExpectations(api_mock_.get());
488
489   // Check the error status.
490   EXPECT_EQ(error::kNoError, GetError());
491 }
492
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;
503   }
504
505   for (unsigned int i = 0; i < 5; ++i) {
506     AddCommandWithExpect(
507         error::kNoError, i + kUnusedCommandId, kNumArgs, args1);
508   }
509
510   helper_->Finish();
511   // Check that the commands did happen.
512   Mock::VerifyAndClearExpectations(api_mock_.get());
513
514   // Check the error status.
515   EXPECT_EQ(error::kNoError, GetError());
516 }
517
518 // Checks exact wrapping condition with Get = 0.
519 TEST_F(CommandBufferHelperTest, TestCommandWrappingFullAtStart) {
520   TestCommandWrappingFull(2, 0);
521 }
522
523 // Checks exact wrapping condition with 0 < Get < kTotalNumCommandEntries.
524 TEST_F(CommandBufferHelperTest, TestCommandWrappingFullInMiddle) {
525   TestCommandWrappingFull(2, 1);
526 }
527
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);
532 }
533
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;
540
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);
546
547   // Ask for 5 entries.
548   helper_->WaitForAvailableEntries(5);
549
550   CommandBufferOffset put = get_helper_put();
551   CheckFreeSpace(put, 5);
552
553   // Add more commands.
554   AddCommandWithExpect(error::kNoError, kUnusedCommandId + 5, 2, args);
555
556   // Wait until everything is done done.
557   helper_->Finish();
558
559   // Check that the commands did happen.
560   Mock::VerifyAndClearExpectations(api_mock_.get());
561
562   // Check the error status.
563   EXPECT_EQ(error::kNoError, GetError());
564 }
565
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;
571
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();
577
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();
587
588   // Check that the commands did happen.
589   Mock::VerifyAndClearExpectations(api_mock_.get());
590
591   // Check the error status.
592   EXPECT_EQ(error::kNoError, GetError());
593 }
594
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;
600
601   // Add a first command.
602   AddCommandWithExpect(error::kNoError, kUnusedCommandId + 3, 2, args);
603   int32 token = helper_->InsertToken();
604
605   EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _))
606       .WillOnce(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken),
607                       Return(error::kNoError)));
608
609   int flush_count = command_buffer_->FlushCount();
610
611   // Test that waiting for pending token causes a Flush.
612   helper_->WaitForToken(token);
613   EXPECT_EQ(command_buffer_->FlushCount(), flush_count + 1);
614
615   // Test that we don't Flush repeatedly.
616   helper_->WaitForToken(token);
617   EXPECT_EQ(command_buffer_->FlushCount(), flush_count + 1);
618
619   // Add another command.
620   AddCommandWithExpect(error::kNoError, kUnusedCommandId + 4, 2, args);
621
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);
625
626   helper_->Finish();
627
628   // Check that the commands did happen.
629   Mock::VerifyAndClearExpectations(api_mock_.get());
630
631   // Check the error status.
632   EXPECT_EQ(error::kNoError, GetError());
633 }
634
635 TEST_F(CommandBufferHelperTest, FreeRingBuffer) {
636   EXPECT_TRUE(helper_->HaveRingBuffer());
637
638   // Test freeing ring buffer.
639   helper_->FreeRingBuffer();
640   EXPECT_FALSE(helper_->HaveRingBuffer());
641
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());
651
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());
658
659   // Check that the commands did happen.
660   Mock::VerifyAndClearExpectations(api_mock_.get());
661 }
662
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);
669   }
670 }
671
672 TEST_F(CommandBufferHelperTest, IsContextLost) {
673   EXPECT_FALSE(helper_->IsContextLost());
674   command_buffer_->SetParseError(error::kGenericError);
675   EXPECT_TRUE(helper_->IsContextLost());
676 }
677
678 // Checks helper's 'flush generation' updates.
679 TEST_F(CommandBufferHelperTest, TestFlushGeneration) {
680   // Explicit flushing only.
681   helper_->SetAutomaticFlushes(false);
682
683   // Generation should change after Flush() but not before.
684   uint32 gen1, gen2, gen3;
685
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);
693
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);
702
703   helper_->Finish();
704
705   // Check that the commands did happen.
706   Mock::VerifyAndClearExpectations(api_mock_.get());
707
708   // Check the error status.
709   EXPECT_EQ(error::kNoError, GetError());
710 }
711
712 }  // namespace gpu