Home | History | Annotate | Download | only in client
      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
    713