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 24namespace gpu { 25 26using testing::Return; 27using testing::Mock; 28using testing::Truly; 29using testing::Sequence; 30using testing::DoAll; 31using testing::Invoke; 32using testing::_; 33 34const int32 kTotalNumCommandEntries = 32; 35const int32 kCommandBufferSizeBytes = 36 kTotalNumCommandEntries * sizeof(CommandBufferEntry); 37const 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. 41class 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). 85class 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. 274TEST_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. 284TEST_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. 292TEST_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. 316TEST_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. 342TEST_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. 373TEST_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. 405TEST_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. 437TEST_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. 471TEST_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. 495TEST_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. 519TEST_F(CommandBufferHelperTest, TestCommandWrappingFullAtStart) { 520 TestCommandWrappingFull(2, 0); 521} 522 523// Checks exact wrapping condition with 0 < Get < kTotalNumCommandEntries. 524TEST_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. 530TEST_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. 536TEST_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. 567TEST_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. 596TEST_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 635TEST_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 663TEST_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 672TEST_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. 679TEST_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