15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file contains the tests for the RingBuffer class.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/client/ring_buffer.h"
89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/client/cmd_buffer_helper.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/cmd_buffer_engine.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/command_buffer_service.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/gpu_scheduler.h"
169ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "gpu/command_buffer/service/mocks.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/transfer_buffer_manager.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/scoped_nsautorelease_pool.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Mock;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Truly;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Sequence;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::DoAll;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Invoke;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BaseRingBufferTest : public testing::Test {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const unsigned int kBaseOffset = 128;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const unsigned int kBufferSize = 1024;
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  static const unsigned int kAlignment = 4;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RunPendingSetToken() {
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    for (std::vector<const void*>::iterator it = set_token_arguments_.begin();
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         it != set_token_arguments_.end();
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         ++it) {
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      api_mock_->SetToken(cmd::kSetToken, 1, *it);
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    set_token_arguments_.clear();
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    delay_set_token_ = false;
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void SetToken(unsigned int command,
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                unsigned int arg_count,
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                const void* _args) {
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(static_cast<unsigned int>(cmd::kSetToken), command);
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(1u, arg_count);
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (delay_set_token_)
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      set_token_arguments_.push_back(_args);
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    else
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      api_mock_->SetToken(cmd::kSetToken, 1, _args);
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    delay_set_token_ = false;
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    api_mock_.reset(new AsyncAPIMock(true));
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ignore noops in the mock - we don't want to inspect the internals of the
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // helper.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*api_mock_, DoCommand(cmd::kNoop, 0, _))
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .WillRepeatedly(Return(error::kNoError));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Forward the SetToken calls to the engine
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _))
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        .WillRepeatedly(DoAll(Invoke(this, &BaseRingBufferTest::SetToken),
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              Return(error::kNoError)));
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TransferBufferManager* manager = new TransferBufferManager();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transfer_buffer_manager_.reset(manager);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(manager->Initialize());
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_buffer_.reset(
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CommandBufferService(transfer_buffer_manager_.get()));
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(command_buffer_->Initialize());
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gpu_scheduler_.reset(new GpuScheduler(
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        command_buffer_.get(), api_mock_.get(), NULL));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_buffer_->SetPutOffsetChangeCallback(base::Bind(
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &GpuScheduler::PutChanged, base::Unretained(gpu_scheduler_.get())));
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_buffer_->SetGetBufferChangeCallback(base::Bind(
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &GpuScheduler::SetGetBuffer, base::Unretained(gpu_scheduler_.get())));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    api_mock_->set_engine(gpu_scheduler_.get());
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper_.reset(new CommandBufferHelper(command_buffer_.get()));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper_->Initialize(kBufferSize);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 GetToken() {
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return command_buffer_->GetLastState().token;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::mac::ScopedNSAutoreleasePool autorelease_pool_;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop_;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AsyncAPIMock> api_mock_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<CommandBufferService> command_buffer_;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<GpuScheduler> gpu_scheduler_;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<CommandBufferHelper> helper_;
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<const void*> set_token_arguments_;
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool delay_set_token_;
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<int8[]> buffer_;
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int8* buffer_start_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _MSC_VER
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned int BaseRingBufferTest::kBaseOffset;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned int BaseRingBufferTest::kBufferSize;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test fixture for RingBuffer test - Creates a RingBuffer, using a
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it directly, not through the RPC mechanism), making sure Noops are ignored
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and SetToken are properly forwarded to the engine.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RingBufferTest : public BaseRingBufferTest {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BaseRingBufferTest::SetUp();
128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    buffer_.reset(new int8[kBufferSize + kBaseOffset]);
130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    buffer_start_ = buffer_.get() + kBaseOffset;
131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    allocator_.reset(new RingBuffer(kAlignment, kBaseOffset, kBufferSize,
132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                    helper_.get(), buffer_start_));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the GpuScheduler posts any tasks, this forces them to run.
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BaseRingBufferTest::TearDown();
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<RingBuffer> allocator_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks basic alloc and free.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RingBufferTest, TestBasic) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned int kSize = 16;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize());
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSizeNoWaiting());
150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void* pointer = allocator_->Alloc(kSize);
151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_GE(kBufferSize, allocator_->GetOffset(pointer) - kBaseOffset + kSize);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize());
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kBufferSize - kSize, allocator_->GetLargestFreeSizeNoWaiting());
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 token = helper_->InsertToken();
155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  allocator_->FreePendingToken(pointer, token);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks the free-pending-token mechanism.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RingBufferTest, TestFreePendingToken) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned int kSize = 16;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned int kAllocCount = kBufferSize / kSize;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(kAllocCount * kSize == kBufferSize);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  delay_set_token_ = true;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allocate several buffers to fill in the memory.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 tokens[kAllocCount];
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned int ii = 0; ii < kAllocCount; ++ii) {
168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    void* pointer = allocator_->Alloc(kSize);
169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_GE(kBufferSize,
170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)              allocator_->GetOffset(pointer) - kBaseOffset + kSize);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tokens[ii] = helper_->InsertToken();
172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    allocator_->FreePendingToken(pointer, tokens[ii]);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kBufferSize - (kSize * kAllocCount),
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            allocator_->GetLargestFreeSizeNoWaiting());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  RunPendingSetToken();
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This allocation will need to reclaim the space freed above, so that should
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // process the commands until a token is passed.
182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void* pointer1 = allocator_->Alloc(kSize);
183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(kBaseOffset, allocator_->GetOffset(pointer1));
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the token has indeed passed.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LE(tokens[0], GetToken());
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  allocator_->FreePendingToken(pointer1, helper_->InsertToken());
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests GetLargestFreeSizeNoWaiting
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RingBufferTest, TestGetLargestFreeSizeNoWaiting) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSizeNoWaiting());
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void* pointer = allocator_->Alloc(kBufferSize);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, allocator_->GetLargestFreeSizeNoWaiting());
197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  allocator_->FreePendingToken(pointer, helper_->InsertToken());
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RingBufferTest, TestFreeBug) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first and second allocations must not match.
202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const unsigned int kAlloc1 = 3*kAlignment;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned int kAlloc2 = 20;
204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void* pointer = allocator_->Alloc(kAlloc1);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kBufferSize - kAlloc1, allocator_->GetLargestFreeSizeNoWaiting());
206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  allocator_->FreePendingToken(pointer, helper_.get()->InsertToken());
207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  pointer = allocator_->Alloc(kAlloc2);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kBufferSize - kAlloc1 - kAlloc2,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            allocator_->GetLargestFreeSizeNoWaiting());
210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  allocator_->FreePendingToken(pointer, helper_.get()->InsertToken());
211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  pointer = allocator_->Alloc(kBufferSize);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, allocator_->GetLargestFreeSizeNoWaiting());
213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  allocator_->FreePendingToken(pointer, helper_.get()->InsertToken());
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
217