// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Tests for the Command Buffer Helper.

#include "gpu/command_buffer/client/transfer_buffer.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>

#include "base/compiler_specific.h"
#include "base/memory/aligned_memory.h"
#include "gpu/command_buffer/client/client_test_helper.h"
#include "gpu/command_buffer/client/cmd_buffer_helper.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::AtMost;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::StrictMock;

namespace gpu {


class TransferBufferTest : public testing::Test {
 protected:
  static const int32_t kNumCommandEntries = 400;
  static const int32_t kCommandBufferSizeBytes =
      kNumCommandEntries * sizeof(CommandBufferEntry);
  static const uint32_t kStartingOffset = 64;
  static const uint32_t kAlignment = 4;
  static const uint32_t kTransferBufferSize = 256;

  TransferBufferTest()
      : transfer_buffer_id_(0) {
  }

  void SetUp() override;
  void TearDown() override;

  virtual void Initialize() {
    ASSERT_TRUE(transfer_buffer_->Initialize(
        kTransferBufferSize, kStartingOffset, kTransferBufferSize,
        kTransferBufferSize, kAlignment));
  }

  MockClientCommandBufferMockFlush* command_buffer() const {
    return command_buffer_.get();
  }

  std::unique_ptr<MockClientCommandBufferMockFlush> command_buffer_;
  std::unique_ptr<CommandBufferHelper> helper_;
  std::unique_ptr<TransferBuffer> transfer_buffer_;
  int32_t transfer_buffer_id_;
};

void TransferBufferTest::SetUp() {
  command_buffer_ =
      std::make_unique<StrictMock<MockClientCommandBufferMockFlush>>();

  helper_ = std::make_unique<CommandBufferHelper>(command_buffer());
  ASSERT_EQ(helper_->Initialize(kCommandBufferSizeBytes),
            gpu::ContextResult::kSuccess);

  transfer_buffer_id_ = command_buffer()->GetNextFreeTransferBufferId();

  transfer_buffer_ = std::make_unique<TransferBuffer>(helper_.get());
}

void TransferBufferTest::TearDown() {
  if (transfer_buffer_->HaveBuffer()) {
    EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
        .Times(1)
        .RetiresOnSaturation();
  }
  // For command buffer.
  EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*command_buffer(), Flush(_)).Times(AtMost(1));
  EXPECT_CALL(*command_buffer(), OrderingBarrier(_)).Times(AtMost(2));
  transfer_buffer_.reset();
}

const int32_t TransferBufferTest::kNumCommandEntries;
const int32_t TransferBufferTest::kCommandBufferSizeBytes;
const uint32_t TransferBufferTest::kStartingOffset;
const uint32_t TransferBufferTest::kAlignment;
const uint32_t TransferBufferTest::kTransferBufferSize;

TEST_F(TransferBufferTest, Basic) {
  Initialize();
  EXPECT_TRUE(transfer_buffer_->HaveBuffer());
  EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
  EXPECT_EQ(
      kTransferBufferSize - kStartingOffset,
      transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
  EXPECT_NE(base::UnguessableToken(), transfer_buffer_->shared_memory_guid());
}

TEST_F(TransferBufferTest, Free) {
  Initialize();
  EXPECT_TRUE(transfer_buffer_->HaveBuffer());
  EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
  EXPECT_NE(base::UnguessableToken(), transfer_buffer_->shared_memory_guid());

  // Free buffer.
  EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
      .Times(1)
      .RetiresOnSaturation();
  transfer_buffer_->Free();
  // See it's freed.
  EXPECT_FALSE(transfer_buffer_->HaveBuffer());
  EXPECT_EQ(base::UnguessableToken(), transfer_buffer_->shared_memory_guid());
  // See that it gets reallocated.
  EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
  EXPECT_TRUE(transfer_buffer_->HaveBuffer());
  EXPECT_NE(base::UnguessableToken(), transfer_buffer_->shared_memory_guid());

  // Free buffer.
  EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
      .Times(1)
      .RetiresOnSaturation();
  transfer_buffer_->Free();
  // See it's freed.
  EXPECT_FALSE(transfer_buffer_->HaveBuffer());
  EXPECT_EQ(base::UnguessableToken(), transfer_buffer_->shared_memory_guid());

  // See that it gets reallocated.
  EXPECT_TRUE(transfer_buffer_->AcquireResultBuffer() != nullptr);
  transfer_buffer_->ReleaseResultBuffer();
  EXPECT_TRUE(transfer_buffer_->HaveBuffer());
  EXPECT_NE(base::UnguessableToken(), transfer_buffer_->shared_memory_guid());

  // Free buffer.
  EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
      .Times(1)
      .RetiresOnSaturation();
  transfer_buffer_->Free();
  // See it's freed.
  EXPECT_FALSE(transfer_buffer_->HaveBuffer());
  EXPECT_EQ(base::UnguessableToken(), transfer_buffer_->shared_memory_guid());

  // See that it gets reallocated.
  uint32_t size = 0;
  void* data = transfer_buffer_->AllocUpTo(1, &size);
  EXPECT_TRUE(data != nullptr);
  EXPECT_TRUE(transfer_buffer_->HaveBuffer());
  EXPECT_NE(base::UnguessableToken(), transfer_buffer_->shared_memory_guid());
  int32_t token = helper_->InsertToken();
  int32_t put_offset = helper_->GetPutOffsetForTest();
  transfer_buffer_->FreePendingToken(data, token);

  // Free buffer. Should cause an ordering barrier.
  EXPECT_CALL(*command_buffer(), OrderingBarrier(_)).Times(AtMost(1));
  EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
      .Times(1)
      .RetiresOnSaturation();
  transfer_buffer_->Free();
  // See it's freed.
  EXPECT_FALSE(transfer_buffer_->HaveBuffer());
  EXPECT_EQ(base::UnguessableToken(), transfer_buffer_->shared_memory_guid());
  // Free should not have caused a finish.
  EXPECT_LT(command_buffer_->GetState().get_offset, put_offset);

  // See that it gets reallocated.
  transfer_buffer_->GetShmId();
  EXPECT_TRUE(transfer_buffer_->HaveBuffer());
  EXPECT_NE(base::UnguessableToken(), transfer_buffer_->shared_memory_guid());

  EXPECT_EQ(
      kTransferBufferSize - kStartingOffset,
      transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());

  // Test freeing twice.
  EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
      .Times(1)
      .RetiresOnSaturation();
  transfer_buffer_->Free();
  transfer_buffer_->Free();
}

TEST_F(TransferBufferTest, TooLargeAllocation) {
  Initialize();
  // Check that we can't allocate large than max size.
  void* ptr = transfer_buffer_->Alloc(kTransferBufferSize + 1);
  EXPECT_TRUE(ptr == nullptr);
  // Check we if we try to allocate larger than max we get max.
  uint32_t size_allocated = 0;
  ptr = transfer_buffer_->AllocUpTo(
      kTransferBufferSize + 1, &size_allocated);
  ASSERT_TRUE(ptr != nullptr);
  EXPECT_EQ(kTransferBufferSize - kStartingOffset, size_allocated);
  transfer_buffer_->FreePendingToken(ptr, 1);
}

TEST_F(TransferBufferTest, MemoryAlignmentAfterZeroAllocation) {
  Initialize();
  void* ptr = transfer_buffer_->Alloc(0);
  EXPECT_TRUE(base::IsAligned(ptr, kAlignment));
  transfer_buffer_->FreePendingToken(ptr, helper_->InsertToken());
  // Check that the pointer is aligned on the following allocation.
  ptr = transfer_buffer_->Alloc(4);
  EXPECT_TRUE(base::IsAligned(ptr, kAlignment));
  transfer_buffer_->FreePendingToken(ptr, helper_->InsertToken());
}

TEST_F(TransferBufferTest, ScopedTransferBuffer) {
  Initialize();
  ScopedTransferBufferPtr scoped_transfer_buffer(1, helper_.get(), transfer_buffer_.get());
  EXPECT_EQ(scoped_transfer_buffer.size(), 1u);
  uint8_t* c = static_cast<uint8_t*>(scoped_transfer_buffer.address());
  EXPECT_FALSE(scoped_transfer_buffer.BelongsToBuffer(UNSAFE_TODO(c - 1)));
  EXPECT_TRUE(scoped_transfer_buffer.BelongsToBuffer(c));
  EXPECT_FALSE(scoped_transfer_buffer.BelongsToBuffer(UNSAFE_TODO(c + 1)));
}

class MockClientCommandBufferCanFail : public MockClientCommandBufferMockFlush {
 public:
  MockClientCommandBufferCanFail() = default;
  ~MockClientCommandBufferCanFail() override = default;

  MOCK_METHOD4(CreateTransferBuffer,
               scoped_refptr<Buffer>(uint32_t size,
                                     int32_t* id,
                                     uint32_t alignment,
                                     TransferBufferAllocationOption option));

  scoped_refptr<gpu::Buffer> RealCreateTransferBuffer(
      uint32_t size,
      int32_t* id,
      uint32_t alignment,
      TransferBufferAllocationOption option) {
    return MockClientCommandBufferMockFlush::CreateTransferBuffer(
        size, id, alignment, option);
  }
};

class TransferBufferExpandContractTest : public testing::Test {
 protected:
  static const int32_t kNumCommandEntries = 400;
  static const int32_t kCommandBufferSizeBytes =
      kNumCommandEntries * sizeof(CommandBufferEntry);
  static const uint32_t kStartingOffset = 64;
  static const uint32_t kAlignment = 4;
  static const uint32_t kStartTransferBufferSize = 256;
  static const uint32_t kMaxTransferBufferSize = 1024;
  static const uint32_t kMinTransferBufferSize = 128;

  TransferBufferExpandContractTest()
      : transfer_buffer_id_(0) {
  }

  void SetUp() override;
  void TearDown() override;

  MockClientCommandBufferCanFail* command_buffer() const {
    return command_buffer_.get();
  }

  std::unique_ptr<MockClientCommandBufferCanFail> command_buffer_;
  std::unique_ptr<CommandBufferHelper> helper_;
  std::unique_ptr<TransferBuffer> transfer_buffer_;
  int32_t transfer_buffer_id_;
};

void TransferBufferExpandContractTest::SetUp() {
  command_buffer_ =
      std::make_unique<StrictMock<MockClientCommandBufferCanFail>>();
  command_buffer_->SetTokenForSetGetBuffer(0);

  EXPECT_CALL(*command_buffer(),
              CreateTransferBuffer(kCommandBufferSizeBytes, _, _, _))
      .WillOnce(
          Invoke(command_buffer(),
                 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
      .RetiresOnSaturation();

  helper_ = std::make_unique<CommandBufferHelper>(command_buffer());
  ASSERT_EQ(helper_->Initialize(kCommandBufferSizeBytes),
            gpu::ContextResult::kSuccess);

  transfer_buffer_id_ = command_buffer()->GetNextFreeTransferBufferId();

  EXPECT_CALL(*command_buffer(),
              CreateTransferBuffer(kStartTransferBufferSize, _, _, _))
      .WillOnce(
          Invoke(command_buffer(),
                 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
      .RetiresOnSaturation();

  transfer_buffer_ = std::make_unique<TransferBuffer>(helper_.get());
  ASSERT_TRUE(transfer_buffer_->Initialize(
      kStartTransferBufferSize, kStartingOffset, kMinTransferBufferSize,
      kMaxTransferBufferSize, kAlignment));
}

void TransferBufferExpandContractTest::TearDown() {
  if (transfer_buffer_->HaveBuffer()) {
    EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
        .Times(1)
        .RetiresOnSaturation();
  }
  // For command buffer.
  EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*command_buffer(), Flush(_)).Times(1).RetiresOnSaturation();
  transfer_buffer_.reset();
}

const int32_t TransferBufferExpandContractTest::kNumCommandEntries;
const int32_t TransferBufferExpandContractTest::kCommandBufferSizeBytes;
const uint32_t TransferBufferExpandContractTest::kStartingOffset;
const uint32_t TransferBufferExpandContractTest::kAlignment;
const uint32_t TransferBufferExpandContractTest::kStartTransferBufferSize;
const uint32_t TransferBufferExpandContractTest::kMaxTransferBufferSize;
const uint32_t TransferBufferExpandContractTest::kMinTransferBufferSize;

TEST_F(TransferBufferExpandContractTest, ExpandWithSmallAllocations) {
  int32_t token = helper_->InsertToken();
  EXPECT_FALSE(helper_->HasTokenPassed(token));

  auto ExpectCreateTransferBuffer = [&](int size) {
    EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*command_buffer(), CreateTransferBuffer(size, _, _, _))
        .WillOnce(
            Invoke(command_buffer(),
                   &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
        .RetiresOnSaturation();
  };

  // Check it starts at starting size.
  EXPECT_EQ(
      kStartTransferBufferSize - kStartingOffset,
      transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());

  // Fill the free space.
  uint32_t size_allocated = 0;
  void* ptr = transfer_buffer_->AllocUpTo(transfer_buffer_->GetFreeSize(),
                                          &size_allocated);
  transfer_buffer_->FreePendingToken(ptr, token);

  // Allocate one more byte to force expansion.
  ExpectCreateTransferBuffer(kStartTransferBufferSize * 2);
  ptr = transfer_buffer_->AllocUpTo(1, &size_allocated);
  ASSERT_TRUE(ptr != nullptr);
  EXPECT_EQ(1u, size_allocated);
  transfer_buffer_->FreePendingToken(ptr, token);

  // Fill free space and expand again.
  ptr = transfer_buffer_->AllocUpTo(transfer_buffer_->GetFreeSize(),
                                    &size_allocated);
  transfer_buffer_->FreePendingToken(ptr, token);
  ExpectCreateTransferBuffer(kStartTransferBufferSize * 4);
  ptr = transfer_buffer_->AllocUpTo(1, &size_allocated);
  ASSERT_TRUE(ptr != nullptr);
  EXPECT_EQ(1u, size_allocated);
  transfer_buffer_->FreePendingToken(ptr, token);

  // Try to expand again, no expansion should occur because we are at max.
  ptr = transfer_buffer_->AllocUpTo(transfer_buffer_->GetFreeSize(),
                                    &size_allocated);
  transfer_buffer_->FreePendingToken(ptr, token);
  EXPECT_CALL(*command_buffer(), Flush(_)).Times(1).RetiresOnSaturation();
  ptr = transfer_buffer_->AllocUpTo(1, &size_allocated);
  ASSERT_TRUE(ptr != nullptr);
  EXPECT_EQ(1u, size_allocated);
  transfer_buffer_->FreePendingToken(ptr, token);
  EXPECT_EQ(kMaxTransferBufferSize - kStartingOffset,
            transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
}

// Verify that expansion does not happen when there are blocks in use.
TEST_F(TransferBufferExpandContractTest, NoExpandWithInUseAllocation) {
  EXPECT_CALL(*command_buffer(), Flush(_)).Times(1).RetiresOnSaturation();

  int32_t token = helper_->InsertToken();
  EXPECT_FALSE(helper_->HasTokenPassed(token));

  // Check it starts at starting size.
  EXPECT_EQ(kStartTransferBufferSize - kStartingOffset,
            transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());

  // Fill the free space in two blocks.
  uint32_t block_size_1 = transfer_buffer_->GetFreeSize() / 2;
  uint32_t block_size_2 = transfer_buffer_->GetFreeSize() - block_size_1;
  uint32_t size_allocated = 0;
  void* block1 = transfer_buffer_->AllocUpTo(block_size_1, &size_allocated);
  EXPECT_EQ(block_size_1, size_allocated);
  void* block2 = transfer_buffer_->AllocUpTo(block_size_2, &size_allocated);
  EXPECT_EQ(block_size_2, size_allocated);
  transfer_buffer_->FreePendingToken(block1, token);

  // Expansion tries to happens when GetFreeSize() is not enough for the
  // allocation.
  EXPECT_EQ(0u, transfer_buffer_->GetFreeSize());

  // Allocate one more byte to try to force expansion, however there are
  // blocks in use, so this should not expand.
  void* block3 = transfer_buffer_->AllocUpTo(1, &size_allocated);
  ASSERT_TRUE(block3 != nullptr);
  EXPECT_EQ(1u, size_allocated);
  transfer_buffer_->FreePendingToken(block3, token);
  transfer_buffer_->FreePendingToken(block2, token);

  // No reallocs should have occurred.
  EXPECT_EQ(kStartTransferBufferSize - kStartingOffset,
            transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
}

TEST_F(TransferBufferExpandContractTest, ExpandWithLargeAllocations) {
  int32_t token = helper_->InsertToken();
  EXPECT_FALSE(helper_->HasTokenPassed(token));

  auto ExpectCreateTransferBuffer = [&](int size) {
    EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*command_buffer(), CreateTransferBuffer(size, _, _, _))
        .WillOnce(
            Invoke(command_buffer(),
                   &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
        .RetiresOnSaturation();
  };

  // Check it starts at starting size.
  EXPECT_EQ(kStartTransferBufferSize - kStartingOffset,
            transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());

  // Allocate one byte more than the free space to force expansion.
  uint32_t size_allocated = 0;
  ExpectCreateTransferBuffer(kStartTransferBufferSize * 2);
  void* ptr = transfer_buffer_->AllocUpTo(transfer_buffer_->GetFreeSize() + 1,
                                          &size_allocated);
  transfer_buffer_->FreePendingToken(ptr, token);

  // Expand again.
  ExpectCreateTransferBuffer(kStartTransferBufferSize * 4);
  uint32_t size_requested = transfer_buffer_->GetFreeSize() + 1;
  ptr = transfer_buffer_->AllocUpTo(size_requested, &size_allocated);
  ASSERT_TRUE(ptr != nullptr);
  EXPECT_EQ(size_requested, size_allocated);
  transfer_buffer_->FreePendingToken(ptr, token);

  // Try to expand again, no expansion should occur because we are at max.
  EXPECT_CALL(*command_buffer(), Flush(_)).Times(1).RetiresOnSaturation();
  size_requested =
      transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc() + 1;
  ptr = transfer_buffer_->AllocUpTo(size_requested, &size_allocated);
  EXPECT_LT(size_allocated, size_requested);
  transfer_buffer_->FreePendingToken(ptr, token);
  EXPECT_EQ(kMaxTransferBufferSize - kStartingOffset,
            transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
}

TEST_F(TransferBufferExpandContractTest, ShrinkRingBuffer) {
  int32_t token = helper_->InsertToken();
  // For this test we want all allocations to be freed immediately.
  command_buffer_->SetToken(token);
  EXPECT_TRUE(helper_->HasTokenPassed(token));

  auto ExpectCreateTransferBuffer = [&](int size) {
    EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*command_buffer(), CreateTransferBuffer(size, _, _, _))
        .WillOnce(
            Invoke(command_buffer(),
                   &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
        .RetiresOnSaturation();
  };

  // Expand the ring buffer to the maximum size.
  ExpectCreateTransferBuffer(kMaxTransferBufferSize);
  void* ptr = transfer_buffer_->Alloc(kMaxTransferBufferSize - kStartingOffset);
  EXPECT_TRUE(ptr != nullptr);
  transfer_buffer_->FreePendingToken(ptr, token);

  // We shouldn't shrink before we reach the allocation threshold.
  for (uint32_t allocated = kMaxTransferBufferSize - kStartingOffset;
       allocated < (kStartTransferBufferSize + kStartingOffset) *
                       (TransferBuffer::kShrinkThreshold);) {
    ptr = transfer_buffer_->Alloc(kStartTransferBufferSize);
    EXPECT_TRUE(ptr != nullptr);
    transfer_buffer_->FreePendingToken(ptr, token);
    allocated += kStartTransferBufferSize;
  }
  // The next allocation should trip the threshold and shrink.
  ExpectCreateTransferBuffer(kStartTransferBufferSize * 2);
  ptr = transfer_buffer_->Alloc(1);
  EXPECT_TRUE(ptr != nullptr);
  transfer_buffer_->FreePendingToken(ptr, token);
}

TEST_F(TransferBufferExpandContractTest, Contract) {
  // Check it starts at starting size.
  EXPECT_EQ(
      kStartTransferBufferSize - kStartingOffset,
      transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());

  // Free buffer.
  EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
      .Times(1)
      .RetiresOnSaturation();
  transfer_buffer_->Free();
  // See it's freed.
  EXPECT_FALSE(transfer_buffer_->HaveBuffer());

  // Try to allocate again, fail first request
  EXPECT_CALL(*command_buffer(),
              CreateTransferBuffer(kStartTransferBufferSize, _, _, _))
      .WillOnce(
          DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>())))
      .RetiresOnSaturation();
  EXPECT_CALL(*command_buffer(),
              CreateTransferBuffer(kMinTransferBufferSize, _, _, _))
      .WillOnce(
          Invoke(command_buffer(),
                 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
      .RetiresOnSaturation();

  const uint32_t kSize1 = 256 - kStartingOffset;
  const uint32_t kSize2 = 128 - kStartingOffset;
  uint32_t size_allocated = 0;
  void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
  ASSERT_TRUE(ptr != nullptr);
  EXPECT_EQ(kSize2, size_allocated);
  EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
  transfer_buffer_->FreePendingToken(ptr, 1);

  // Free buffer.
  EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
      .Times(1)
      .RetiresOnSaturation();
  transfer_buffer_->Free();
  // See it's freed.
  EXPECT_FALSE(transfer_buffer_->HaveBuffer());

  // Try to allocate again,
  EXPECT_CALL(*command_buffer(),
              CreateTransferBuffer(kMinTransferBufferSize, _, _, _))
      .WillOnce(
          Invoke(command_buffer(),
                 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
      .RetiresOnSaturation();

  ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
  ASSERT_TRUE(ptr != nullptr);
  EXPECT_EQ(kSize2, size_allocated);
  EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
  transfer_buffer_->FreePendingToken(ptr, 1);
}

TEST_F(TransferBufferExpandContractTest, OutOfMemory) {
  // Free buffer.
  EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
      .Times(1)
      .RetiresOnSaturation();
  transfer_buffer_->Free();
  // See it's freed.
  EXPECT_FALSE(transfer_buffer_->HaveBuffer());

  // Try to allocate again, fail both requests.
  EXPECT_CALL(*command_buffer(), CreateTransferBuffer(_, _, _, _))
      .WillOnce(
          DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>())))
      .WillOnce(
          DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>())))
      .WillOnce(
          DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>())))
      .RetiresOnSaturation();

  const uint32_t kSize1 = 512 - kStartingOffset;
  uint32_t size_allocated = 0;
  void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
  ASSERT_TRUE(ptr == nullptr);
  EXPECT_FALSE(transfer_buffer_->HaveBuffer());
}

TEST_F(TransferBufferExpandContractTest, ReallocsToDefault) {
  // Free buffer.
  EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*command_buffer(), OrderingBarrier(_))
      .Times(1)
      .RetiresOnSaturation();
  transfer_buffer_->Free();
  // See it's freed.
  EXPECT_FALSE(transfer_buffer_->HaveBuffer());

  // See that it gets reallocated.
  EXPECT_CALL(*command_buffer(),
              CreateTransferBuffer(kStartTransferBufferSize, _, _, _))
      .WillOnce(
          Invoke(command_buffer(),
                 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
      .RetiresOnSaturation();
  EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
  EXPECT_TRUE(transfer_buffer_->HaveBuffer());

  // Check it's the default size.
  EXPECT_EQ(
      kStartTransferBufferSize - kStartingOffset,
      transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
}

TEST_F(TransferBufferExpandContractTest, Shrink) {
  uint32_t alloc_size = transfer_buffer_->GetFreeSize();
  EXPECT_EQ(kStartTransferBufferSize - kStartingOffset, alloc_size);
  uint32_t size_allocated = 0;
  void* ptr = transfer_buffer_->AllocUpTo(alloc_size, &size_allocated);

  ASSERT_NE(ptr, nullptr);
  EXPECT_EQ(alloc_size, size_allocated);
  EXPECT_GT(alloc_size, 0u);
  EXPECT_EQ(0u, transfer_buffer_->GetFreeSize());

  // Shrink once.
  const uint32_t shrink_size1 = 64;
  EXPECT_LT(shrink_size1, alloc_size);
  transfer_buffer_->ShrinkLastBlock(shrink_size1 - kAlignment + 1);
  EXPECT_EQ(alloc_size - shrink_size1, transfer_buffer_->GetFreeSize());

  // Shrink again.
  const uint32_t shrink_size2 = 32;
  EXPECT_LT(shrink_size2, shrink_size1);
  transfer_buffer_->ShrinkLastBlock(shrink_size2);
  EXPECT_EQ(alloc_size - shrink_size2, transfer_buffer_->GetFreeSize());

  // Shrink to zero (minimum size is kAlignment).
  transfer_buffer_->ShrinkLastBlock(0);
  EXPECT_EQ(alloc_size - kAlignment, transfer_buffer_->GetFreeSize());

  transfer_buffer_->FreePendingToken(ptr, 1);
}

TEST_F(TransferBufferTest, MultipleAllocsAndFrees) {
  // An arbitrary size, but is aligned so no padding needed.
  constexpr uint32_t kArbitrarySize = 16;

  Initialize();
  uint32_t original_free_size = transfer_buffer_->GetFreeSize();
  EXPECT_EQ(transfer_buffer_->GetSize(), original_free_size);
  EXPECT_EQ(transfer_buffer_->GetFragmentedFreeSize(), original_free_size);

  void* ptr1 = transfer_buffer_->Alloc(kArbitrarySize);
  EXPECT_NE(ptr1, nullptr);
  EXPECT_EQ(transfer_buffer_->GetSize(), original_free_size);
  EXPECT_EQ(transfer_buffer_->GetFreeSize(),
            original_free_size - kArbitrarySize);
  EXPECT_EQ(transfer_buffer_->GetFragmentedFreeSize(),
            original_free_size - kArbitrarySize);

  void* ptr2 = transfer_buffer_->Alloc(kArbitrarySize);
  EXPECT_NE(ptr2, nullptr);
  EXPECT_EQ(transfer_buffer_->GetSize(), original_free_size);
  EXPECT_EQ(transfer_buffer_->GetFreeSize(),
            original_free_size - kArbitrarySize * 2);
  EXPECT_EQ(transfer_buffer_->GetFragmentedFreeSize(),
            original_free_size - kArbitrarySize * 2);

  void* ptr3 = transfer_buffer_->Alloc(kArbitrarySize);
  EXPECT_NE(ptr3, nullptr);
  EXPECT_EQ(transfer_buffer_->GetSize(), original_free_size);
  EXPECT_EQ(transfer_buffer_->GetFreeSize(),
            original_free_size - kArbitrarySize * 3);
  EXPECT_EQ(transfer_buffer_->GetFragmentedFreeSize(),
            original_free_size - kArbitrarySize * 3);

  // Generate tokens in order, but submit out of order.
  auto token1 = helper_->InsertToken();
  auto token2 = helper_->InsertToken();
  auto token3 = helper_->InsertToken();
  auto token4 = helper_->InsertToken();

  // Freeing the final block here, is not perceivable because it's a hole.
  transfer_buffer_->FreePendingToken(ptr3, token3);
  EXPECT_EQ(transfer_buffer_->GetSize(), original_free_size);
  EXPECT_EQ(transfer_buffer_->GetFreeSize(),
            original_free_size - kArbitrarySize * 3);
  EXPECT_EQ(transfer_buffer_->GetFragmentedFreeSize(),
            original_free_size - kArbitrarySize * 3);

  // Freeing the first block here leaves the second plus a hole after, so
  // perceived two blocks not free yet.  The free size (no waiting) has not
  // changed because the free_offset_ has not moved, but the fragmented free
  // size gets bigger because in_use_offset_ has moved past the first block.
  transfer_buffer_->FreePendingToken(ptr1, token1);
  EXPECT_EQ(transfer_buffer_->GetSize(), original_free_size);
  EXPECT_EQ(transfer_buffer_->GetFreeSize(),
            original_free_size - kArbitrarySize * 3);
  EXPECT_EQ(transfer_buffer_->GetFragmentedFreeSize(),
            original_free_size - kArbitrarySize * 2);

  // Allocate a 4th block.  This leaves the state as: Freed Used Freed Used
  void* ptr4 = transfer_buffer_->Alloc(kArbitrarySize);
  EXPECT_EQ(transfer_buffer_->GetSize(), original_free_size);
  EXPECT_EQ(transfer_buffer_->GetFreeSize(),
            original_free_size - kArbitrarySize * 4);
  EXPECT_EQ(transfer_buffer_->GetFragmentedFreeSize(),
            original_free_size - kArbitrarySize * 3);

  // Freeing the second and fourth block makes everything free, so back to
  // original size.
  transfer_buffer_->FreePendingToken(ptr4, token4);
  transfer_buffer_->FreePendingToken(ptr2, token2);
  EXPECT_EQ(transfer_buffer_->GetSize(), original_free_size);
  EXPECT_EQ(transfer_buffer_->GetFreeSize(), original_free_size);
  EXPECT_EQ(transfer_buffer_->GetFragmentedFreeSize(), original_free_size);
}

#if defined(GTEST_HAS_DEATH_TEST) && DCHECK_IS_ON()

TEST_F(TransferBufferTest, ResizeDuringScopedResultPtr) {
  Initialize();
  ScopedResultPtr<int> ptr(transfer_buffer_.get());
  // If an attempt is made to resize the transfer buffer while a result
  // pointer exists, we should hit a CHECK. Allocate just enough to force a
  // resize.
  uint32_t size_allocated;
  ASSERT_DEATH(transfer_buffer_->AllocUpTo(transfer_buffer_->GetFreeSize() + 1,
                                           &size_allocated),
               "outstanding_result_pointer_");
}

TEST_F(TransferBufferTest, AllocDuringScopedResultPtr) {
  Initialize();
  ScopedResultPtr<int> ptr(transfer_buffer_.get());
  // If an attempt is made to allocate any amount in the transfer buffer while a
  // result pointer exists, we should hit a DCHECK.
  uint32_t size_allocated;
  ASSERT_DEATH(transfer_buffer_->AllocUpTo(transfer_buffer_->GetFreeSize() + 1,
                                           &size_allocated),
               "outstanding_result_pointer_");
}

TEST_F(TransferBufferTest, TwoScopedResultPtrs) {
  Initialize();
  // Attempting to create two ScopedResultPtrs at the same time should DCHECK.
  ScopedResultPtr<int> ptr(transfer_buffer_.get());
  ASSERT_DEATH(ScopedResultPtr<int>(transfer_buffer_.get()),
               "outstanding_result_pointer_");
}

#endif  // defined(GTEST_HAS_DEATH_TEST) && DCHECK_IS_ON()

}  // namespace gpu
