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

// Tests for RasterImplementation.

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

#include <GLES2/gl2.h>
#include <GLES2/gl2extchromium.h>

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

#include <memory>

#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/stl_util.h"
#include "cc/paint/raw_memory_transfer_cache_entry.h"
#include "cc/paint/transfer_cache_serialize_helper.h"
#include "gpu/command_buffer/client/client_test_helper.h"
#include "gpu/command_buffer/client/mock_transfer_buffer.h"
#include "gpu/command_buffer/client/query_tracker.h"
#include "gpu/command_buffer/client/raster_cmd_helper.h"
#include "gpu/command_buffer/client/ring_buffer.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using gpu::gles2::QueryTracker;
using testing::_;
using testing::AtLeast;
using testing::AnyNumber;
using testing::DoAll;
using testing::InSequence;
using testing::Invoke;
using testing::Mock;
using testing::Sequence;
using testing::StrictMock;
using testing::Return;
using testing::ReturnRef;

namespace gpu {
namespace raster {

ACTION_P2(SetMemory, dst, obj) {
  memcpy(dst, &obj, sizeof(obj));
}

ACTION_P3(SetMemoryFromArray, dst, array, size) {
  memcpy(dst, array, size);
}

// Used to help set the transfer buffer result to SizedResult of a single value.
template <typename T>
class SizedResultHelper {
 public:
  explicit SizedResultHelper(T result) : size_(sizeof(result)) {
    memcpy(result_, &result, sizeof(T));
  }

 private:
  uint32_t size_;
  char result_[sizeof(T)];
};

class RasterImplementationTest : public testing::Test {
 protected:
  static const uint8_t kInitialValue = 0xBD;
  static const uint32_t kNumCommandEntries = 500;
  static const uint32_t kCommandBufferSizeBytes =
      kNumCommandEntries * sizeof(CommandBufferEntry);
  static const uint32_t kTransferBufferSize = 512;

  static const GLint kMaxCombinedTextureImageUnits = 8;
  static const GLint kMaxTextureImageUnits = 8;
  static const GLint kMaxTextureSize = 128;
  static const GLint kNumCompressedTextureFormats = 0;
  static const GLuint kStartId = 1024;
  static const GLuint kBuffersStartId = 1;
  static const GLuint kTexturesStartId = 1;
  static const GLuint kQueriesStartId = 1;

  typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo;

  class TestContext {
   public:
    TestContext() : commands_(nullptr), token_(0) {}

    bool Initialize(bool bind_generates_resource_client,
                    bool bind_generates_resource_service,
                    bool lose_context_when_out_of_memory,
                    bool transfer_buffer_initialize_fail,
                    bool sync_query) {
      SharedMemoryLimits limits = SharedMemoryLimitsForTesting();
      command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());

      transfer_buffer_.reset(new MockTransferBuffer(
          command_buffer_.get(), kTransferBufferSize,
          RasterImplementation::kStartingOffset,
          RasterImplementation::kAlignment, transfer_buffer_initialize_fail));

      helper_.reset(new RasterCmdHelper(command_buffer()));
      helper_->Initialize(limits.command_buffer_size);

      gpu_control_.reset(new StrictMock<MockClientGpuControl>());
      capabilities_.max_combined_texture_image_units =
          kMaxCombinedTextureImageUnits;
      capabilities_.max_texture_image_units = kMaxTextureImageUnits;
      capabilities_.max_texture_size = kMaxTextureSize;
      capabilities_.num_compressed_texture_formats =
          kNumCompressedTextureFormats;
      capabilities_.bind_generates_resource_chromium =
          bind_generates_resource_service ? 1 : 0;
      capabilities_.sync_query = sync_query;
      EXPECT_CALL(*gpu_control_, GetCapabilities())
          .WillOnce(ReturnRef(capabilities_));

      {
        InSequence sequence;

        gl_.reset(new RasterImplementation(
            helper_.get(), transfer_buffer_.get(),
            bind_generates_resource_client, lose_context_when_out_of_memory,
            gpu_control_.get(), nullptr /* image_decode_accelerator */));
      }

      // The client should be set to something non-null.
      EXPECT_CALL(*gpu_control_, SetGpuControlClient(gl_.get())).Times(1);

      if (gl_->Initialize(limits) != gpu::ContextResult::kSuccess)
        return false;

      helper_->CommandBufferHelper::Finish();
      Mock::VerifyAndClearExpectations(gl_.get());

      scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
      commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) +
                  command_buffer()->GetServicePutOffset();
      ClearCommands();
      EXPECT_TRUE(transfer_buffer_->InSync());

      Mock::VerifyAndClearExpectations(command_buffer());
      return true;
    }

    void TearDown() {
      Mock::VerifyAndClear(gl_.get());
      EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
      // For command buffer.
      EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
          .Times(AtLeast(1));
      // The client should be unset.
      EXPECT_CALL(*gpu_control_, SetGpuControlClient(nullptr)).Times(1);
      gl_.reset();
    }

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

    int GetNextToken() { return ++token_; }

    void ClearCommands() {
      scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
      memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
    }

    std::unique_ptr<MockClientCommandBuffer> command_buffer_;
    std::unique_ptr<MockClientGpuControl> gpu_control_;
    std::unique_ptr<RasterCmdHelper> helper_;
    std::unique_ptr<MockTransferBuffer> transfer_buffer_;
    std::unique_ptr<RasterImplementation> gl_;
    CommandBufferEntry* commands_;
    int token_;
    Capabilities capabilities_;
  };

  RasterImplementationTest() : commands_(nullptr) {}

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

  bool NoCommandsWritten() {
    scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
    const uint8_t* cmds = static_cast<const uint8_t*>(ring_buffer->memory());
    const uint8_t* end = cmds + ring_buffer->size();
    for (; cmds < end; ++cmds) {
      if (*cmds != kInitialValue) {
        return false;
      }
    }
    return true;
  }

  QueryTracker::Query* GetQuery(GLuint id) {
    return gl_->query_tracker_->GetQuery(id);
  }

  QueryTracker* GetQueryTracker() { return gl_->query_tracker_.get(); }

  struct ContextInitOptions {
    ContextInitOptions()
        : bind_generates_resource_client(true),
          bind_generates_resource_service(true),
          lose_context_when_out_of_memory(false),
          transfer_buffer_initialize_fail(false),
          sync_query(true) {}
    bool bind_generates_resource_client;
    bool bind_generates_resource_service;
    bool lose_context_when_out_of_memory;
    bool transfer_buffer_initialize_fail;
    bool sync_query;
  };

  bool Initialize(const ContextInitOptions& init_options) {
    bool success = true;
    if (!test_context_.Initialize(init_options.bind_generates_resource_client,
                                  init_options.bind_generates_resource_service,
                                  init_options.lose_context_when_out_of_memory,
                                  init_options.transfer_buffer_initialize_fail,
                                  init_options.sync_query)) {
      success = false;
    }

    // Default to test context 0.
    gpu_control_ = test_context_.gpu_control_.get();
    helper_ = test_context_.helper_.get();
    transfer_buffer_ = test_context_.transfer_buffer_.get();
    gl_ = test_context_.gl_.get();
    commands_ = test_context_.commands_;
    return success;
  }

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

  int GetNextToken() { return test_context_.GetNextToken(); }

  const void* GetPut() { return helper_->GetSpace(0); }

  void ClearCommands() {
    scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
    memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
  }

  uint32_t MaxTransferBufferSize() {
    return transfer_buffer_->MaxTransferBufferSize();
  }

  void SetMappedMemoryLimit(size_t limit) {
    gl_->mapped_memory_->set_max_allocated_bytes(limit);
  }

  ExpectedMemoryInfo GetExpectedMemory(uint32_t size) {
    return transfer_buffer_->GetExpectedMemory(size);
  }

  ExpectedMemoryInfo GetExpectedResultMemory(uint32_t size) {
    return transfer_buffer_->GetExpectedResultMemory(size);
  }

  ExpectedMemoryInfo GetExpectedMappedMemory(uint32_t size) {
    ExpectedMemoryInfo mem;

    // Temporarily allocate memory and expect that memory block to be reused.
    mem.ptr = static_cast<uint8_t*>(
        gl_->mapped_memory_->Alloc(size, &mem.id, &mem.offset));
    gl_->mapped_memory_->Free(mem.ptr);

    return mem;
  }

  int CheckError() {
    ExpectedMemoryInfo result =
        GetExpectedResultMemory(sizeof(cmds::GetError::Result));
    EXPECT_CALL(*command_buffer(), OnFlush())
        .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
        .RetiresOnSaturation();
    return gl_->GetError();
  }

  const std::string& GetLastError() { return gl_->GetLastError(); }

  bool GetBucketContents(uint32_t bucket_id, std::vector<int8_t>* data) {
    return gl_->GetBucketContents(bucket_id, data);
  }

  static SharedMemoryLimits SharedMemoryLimitsForTesting() {
    SharedMemoryLimits limits;
    limits.command_buffer_size = kCommandBufferSizeBytes;
    limits.start_transfer_buffer_size = kTransferBufferSize;
    limits.min_transfer_buffer_size = kTransferBufferSize;
    limits.max_transfer_buffer_size = kTransferBufferSize;
    limits.mapped_memory_reclaim_limit = SharedMemoryLimits::kNoLimit;
    return limits;
  }

  TestContext test_context_;

  MockClientGpuControl* gpu_control_;
  RasterCmdHelper* helper_;
  MockTransferBuffer* transfer_buffer_;
  RasterImplementation* gl_;
  CommandBufferEntry* commands_;
};

void RasterImplementationTest::SetUp() {
  ContextInitOptions init_options;
  ASSERT_TRUE(Initialize(init_options));
}

void RasterImplementationTest::TearDown() {
  test_context_.TearDown();
}

class RasterImplementationManualInitTest : public RasterImplementationTest {
 protected:
  void SetUp() override {}
};

// GCC requires these declarations, but MSVC requires they not be present
#ifndef _MSC_VER
const uint8_t RasterImplementationTest::kInitialValue;
const uint32_t RasterImplementationTest::kNumCommandEntries;
const uint32_t RasterImplementationTest::kCommandBufferSizeBytes;
const uint32_t RasterImplementationTest::kTransferBufferSize;
const GLint RasterImplementationTest::kMaxCombinedTextureImageUnits;
const GLint RasterImplementationTest::kMaxTextureImageUnits;
const GLint RasterImplementationTest::kMaxTextureSize;
const GLint RasterImplementationTest::kNumCompressedTextureFormats;
const GLuint RasterImplementationTest::kStartId;
const GLuint RasterImplementationTest::kBuffersStartId;
const GLuint RasterImplementationTest::kTexturesStartId;
const GLuint RasterImplementationTest::kQueriesStartId;
#endif

TEST_F(RasterImplementationTest, GetBucketContents) {
  const uint32_t kBucketId = RasterImplementation::kResultBucketId;
  const uint32_t kTestSize = MaxTransferBufferSize() + 32;

  std::unique_ptr<uint8_t[]> buf(new uint8_t[kTestSize]);
  uint8_t* expected_data = buf.get();
  for (uint32_t ii = 0; ii < kTestSize; ++ii) {
    expected_data[ii] = ii * 3;
  }

  struct Cmds {
    cmd::GetBucketStart get_bucket_start;
    cmd::SetToken set_token1;
    cmd::GetBucketData get_bucket_data;
    cmd::SetToken set_token2;
    cmd::SetBucketSize set_bucket_size2;
  };

  ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
  ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32_t));
  ExpectedMemoryInfo mem2 =
      GetExpectedMemory(kTestSize - MaxTransferBufferSize());

  Cmds expected;
  expected.get_bucket_start.Init(kBucketId, result1.id, result1.offset,
                                 MaxTransferBufferSize(), mem1.id, mem1.offset);
  expected.set_token1.Init(GetNextToken());
  expected.get_bucket_data.Init(kBucketId, MaxTransferBufferSize(),
                                kTestSize - MaxTransferBufferSize(), mem2.id,
                                mem2.offset);
  expected.set_bucket_size2.Init(kBucketId, 0);
  expected.set_token2.Init(GetNextToken());

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(DoAll(
          SetMemory(result1.ptr, kTestSize),
          SetMemoryFromArray(mem1.ptr, expected_data, MaxTransferBufferSize())))
      .WillOnce(SetMemoryFromArray(mem2.ptr,
                                   expected_data + MaxTransferBufferSize(),
                                   kTestSize - MaxTransferBufferSize()))
      .RetiresOnSaturation();

  std::vector<int8_t> data;
  GetBucketContents(kBucketId, &data);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  ASSERT_EQ(kTestSize, data.size());
  EXPECT_EQ(0, memcmp(expected_data, &data[0], data.size()));
}

TEST_F(RasterImplementationTest, BeginEndQueryEXT) {
  //  GL_COMMANDS_COMPLETED_CHROMIUM,
  //  GL_CURRENT_QUERY_EXT

  GLuint expected_ids[2] = {1, 2};  // These must match what's actually genned.
  struct GenCmds {
    cmds::GenQueriesEXTImmediate gen;
    GLuint data[2];
  };
  GenCmds expected_gen_cmds;
  expected_gen_cmds.gen.Init(base::size(expected_ids), &expected_ids[0]);
  GLuint ids[base::size(expected_ids)] = {
      0,
  };
  gl_->GenQueriesEXT(base::size(expected_ids), &ids[0]);
  EXPECT_EQ(0,
            memcmp(&expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
  GLuint id1 = ids[0];
  GLuint id2 = ids[1];
  ClearCommands();

  // Test BeginQueryEXT fails if id = 0.
  gl_->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, 0);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test BeginQueryEXT inserts command.
  struct BeginCmds {
    cmds::BeginQueryEXT begin_query;
  };
  BeginCmds expected_begin_cmds;
  const void* commands = GetPut();
  gl_->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, id1);
  QueryTracker::Query* query = GetQuery(id1);
  ASSERT_TRUE(query != nullptr);
  expected_begin_cmds.begin_query.Init(GL_COMMANDS_COMPLETED_CHROMIUM, id1,
                                       query->shm_id(), query->shm_offset());
  EXPECT_EQ(
      0, memcmp(&expected_begin_cmds, commands, sizeof(expected_begin_cmds)));
  ClearCommands();

  // Test BeginQueryEXT fails if between Begin/End.
  gl_->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, id2);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test EndQueryEXT sends command
  struct EndCmds {
    cmds::EndQueryEXT end_query;
  };
  commands = GetPut();
  gl_->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
  EndCmds expected_end_cmds;
  expected_end_cmds.end_query.Init(GL_COMMANDS_COMPLETED_CHROMIUM,
                                   query->submit_count());
  EXPECT_EQ(0, memcmp(&expected_end_cmds, commands, sizeof(expected_end_cmds)));

  // Test EndQueryEXT fails if no current query.
  ClearCommands();
  gl_->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test 2nd Begin/End increments count.
  base::subtle::Atomic32 old_submit_count = query->submit_count();
  gl_->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, id1);
  EXPECT_EQ(old_submit_count, query->submit_count());
  commands = GetPut();
  gl_->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
  EXPECT_NE(old_submit_count, query->submit_count());
  expected_end_cmds.end_query.Init(GL_COMMANDS_COMPLETED_CHROMIUM,
                                   query->submit_count());
  EXPECT_EQ(0, memcmp(&expected_end_cmds, commands, sizeof(expected_end_cmds)));

  // Test GetQueryObjectuivEXT fails if unused id
  GLuint available = 0xBDu;
  ClearCommands();
  gl_->GetQueryObjectuivEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(0xBDu, available);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test GetQueryObjectuivEXT fails if bad id
  ClearCommands();
  gl_->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(0xBDu, available);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test GetQueryObjectuivEXT CheckResultsAvailable
  ClearCommands();
  gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
  EXPECT_EQ(0u, available);
  available = 1u;
  gl_->GetQueryObjectuivEXT(
      id1, GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT, &available);
  EXPECT_EQ(0u, available);
}

TEST_F(RasterImplementationManualInitTest, BadQueryTargets) {
  ContextInitOptions init_options;
  init_options.sync_query = false;
  ASSERT_TRUE(Initialize(init_options));

  GLuint id = 0;
  gl_->GenQueriesEXT(1, &id);
  ClearCommands();

  gl_->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, id);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_EQ(nullptr, GetQuery(id));

  gl_->BeginQueryEXT(0x123, id);
  EXPECT_EQ(GL_INVALID_ENUM, CheckError());
  EXPECT_EQ(nullptr, GetQuery(id));
}

TEST_F(RasterImplementationTest, GenUnverifiedSyncTokenCHROMIUM) {
  const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO;
  const CommandBufferId kCommandBufferId =
      CommandBufferId::FromUnsafeValue(234u);
  const GLuint64 kFenceSync = 123u;
  SyncToken sync_token;

  EXPECT_CALL(*gpu_control_, GetNamespaceID())
      .WillRepeatedly(Return(kNamespaceId));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillRepeatedly(Return(kCommandBufferId));

  gl_->GenUnverifiedSyncTokenCHROMIUM(nullptr);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_VALUE, CheckError());

  const void* commands = GetPut();
  cmds::InsertFenceSyncCHROMIUM insert_fence_sync;
  insert_fence_sync.Init(kFenceSync);

  EXPECT_CALL(*gpu_control_, GenerateFenceSyncRelease())
      .WillOnce(Return(kFenceSync));
  gl_->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
  EXPECT_EQ(0, memcmp(&insert_fence_sync, commands, sizeof(insert_fence_sync)));
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  EXPECT_FALSE(sync_token.verified_flush());
  EXPECT_EQ(kNamespaceId, sync_token.namespace_id());
  EXPECT_EQ(kCommandBufferId, sync_token.command_buffer_id());
  EXPECT_EQ(kFenceSync, sync_token.release_count());
}

TEST_F(RasterImplementationTest, VerifySyncTokensCHROMIUM) {
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillRepeatedly(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO;
  const CommandBufferId kCommandBufferId =
      CommandBufferId::FromUnsafeValue(234u);
  const GLuint64 kFenceSync = 123u;
  gpu::SyncToken sync_token;
  GLbyte* sync_token_datas[] = {sync_token.GetData()};

  EXPECT_CALL(*gpu_control_, GetNamespaceID())
      .WillRepeatedly(Return(kNamespaceId));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillRepeatedly(Return(kCommandBufferId));

  EXPECT_CALL(*gpu_control_, GenerateFenceSyncRelease())
      .WillOnce(Return(kFenceSync));
  gl_->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
  EXPECT_TRUE(sync_token.HasData());
  EXPECT_FALSE(sync_token.verified_flush());

  ClearCommands();
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(sync_token))
      .WillOnce(Return(false));
  gl_->VerifySyncTokensCHROMIUM(sync_token_datas, 1);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
  EXPECT_FALSE(sync_token.verified_flush());

  ClearCommands();
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(sync_token))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, EnsureWorkVisible());
  gl_->VerifySyncTokensCHROMIUM(sync_token_datas, base::size(sync_token_datas));
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  EXPECT_EQ(kNamespaceId, sync_token.namespace_id());
  EXPECT_EQ(kCommandBufferId, sync_token.command_buffer_id());
  EXPECT_EQ(kFenceSync, sync_token.release_count());
  EXPECT_TRUE(sync_token.verified_flush());
}

TEST_F(RasterImplementationTest, VerifySyncTokensCHROMIUM_Sequence) {
  // To verify sync tokens, the sync tokens must all be verified after
  // CanWaitUnverifiedSyncTokens() are called. This test ensures the right
  // sequence.
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillRepeatedly(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO;
  const CommandBufferId kCommandBufferId =
      CommandBufferId::FromUnsafeValue(234u);
  const GLuint64 kFenceSync1 = 123u;
  const GLuint64 kFenceSync2 = 234u;
  gpu::SyncToken sync_token1;
  gpu::SyncToken sync_token2;
  GLbyte* sync_token_datas[] = {sync_token1.GetData(), sync_token2.GetData()};

  EXPECT_CALL(*gpu_control_, GetNamespaceID())
      .WillRepeatedly(Return(kNamespaceId));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillRepeatedly(Return(kCommandBufferId));

  // Generate sync token 1.
  EXPECT_CALL(*gpu_control_, GenerateFenceSyncRelease())
      .WillOnce(Return(kFenceSync1));
  gl_->GenUnverifiedSyncTokenCHROMIUM(sync_token1.GetData());
  EXPECT_TRUE(sync_token1.HasData());
  EXPECT_FALSE(sync_token1.verified_flush());

  // Generate sync token 2.
  EXPECT_CALL(*gpu_control_, GenerateFenceSyncRelease())
      .WillOnce(Return(kFenceSync2));
  gl_->GenUnverifiedSyncTokenCHROMIUM(sync_token2.GetData());
  EXPECT_TRUE(sync_token2.HasData());
  EXPECT_FALSE(sync_token2.verified_flush());

  // Ensure proper sequence of checking and validating.
  Sequence sequence;
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(sync_token1))
      .InSequence(sequence)
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(sync_token2))
      .InSequence(sequence)
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, EnsureWorkVisible()).InSequence(sequence);
  gl_->VerifySyncTokensCHROMIUM(sync_token_datas, base::size(sync_token_datas));
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  EXPECT_TRUE(sync_token1.verified_flush());
  EXPECT_TRUE(sync_token2.verified_flush());
}

TEST_F(RasterImplementationTest, VerifySyncTokensCHROMIUM_EmptySyncToken) {
  // To verify sync tokens, the sync tokens must all be verified after
  // CanWaitUnverifiedSyncTokens() are called. This test ensures the right
  // sequence.
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillRepeatedly(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  gpu::SyncToken sync_token1, sync_token2;
  GLbyte* sync_token_datas[] = {sync_token1.GetData(), sync_token2.GetData()};

  // Ensure proper sequence of checking and validating.
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(_)).Times(0);
  EXPECT_CALL(*gpu_control_, EnsureWorkVisible()).Times(0);
  gl_->VerifySyncTokensCHROMIUM(sync_token_datas, base::size(sync_token_datas));
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  EXPECT_TRUE(sync_token1.verified_flush());
  EXPECT_TRUE(sync_token2.verified_flush());
}

TEST_F(RasterImplementationTest, WaitSyncTokenCHROMIUM) {
  const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO;
  const CommandBufferId kCommandBufferId =
      CommandBufferId::FromUnsafeValue(234u);
  const GLuint64 kFenceSync = 456u;

  gpu::SyncToken sync_token;
  GLbyte* sync_token_data = sync_token.GetData();

  struct Cmds {
    cmds::InsertFenceSyncCHROMIUM insert_fence_sync;
  };
  Cmds expected;
  expected.insert_fence_sync.Init(kFenceSync);

  EXPECT_CALL(*gpu_control_, GetNamespaceID()).WillOnce(Return(kNamespaceId));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillOnce(Return(kCommandBufferId));
  EXPECT_CALL(*gpu_control_, GenerateFenceSyncRelease())
      .WillOnce(Return(kFenceSync));
  gl_->GenUnverifiedSyncTokenCHROMIUM(sync_token_data);

  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(sync_token))
      .WillOnce(Return(true));
  gpu::SyncToken verified_sync_token = sync_token;
  verified_sync_token.SetVerifyFlush();
  EXPECT_CALL(*gpu_control_, WaitSyncToken(verified_sync_token));
  gl_->WaitSyncTokenCHROMIUM(sync_token_data);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(RasterImplementationTest, WaitSyncTokenCHROMIUMErrors) {
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillRepeatedly(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  // Empty sync tokens should be produce no error and be a nop.
  ClearCommands();
  gl_->WaitSyncTokenCHROMIUM(nullptr);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());

  // Invalid sync tokens should produce no error and be a nop.
  ClearCommands();
  gpu::SyncToken invalid_sync_token;
  gl_->WaitSyncTokenCHROMIUM(invalid_sync_token.GetConstData());
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());

  // Unverified sync token should produce INVALID_OPERATION.
  ClearCommands();
  gpu::SyncToken unverified_sync_token(CommandBufferNamespace::GPU_IO,
                                       gpu::CommandBufferId(), 0);
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(unverified_sync_token))
      .WillOnce(Return(false));
  gl_->WaitSyncTokenCHROMIUM(unverified_sync_token.GetConstData());
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
}

static void CountCallback(int* count) {
  (*count)++;
}

TEST_F(RasterImplementationTest, SignalSyncToken) {
  const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO;
  const CommandBufferId kCommandBufferId = CommandBufferId::FromUnsafeValue(1);
  const uint64_t kFenceSync = 123u;

  EXPECT_CALL(*gpu_control_, GetNamespaceID())
      .WillRepeatedly(Return(kNamespaceId));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillRepeatedly(Return(kCommandBufferId));

  EXPECT_CALL(*gpu_control_, GenerateFenceSyncRelease())
      .WillOnce(Return(kFenceSync));
  gpu::SyncToken sync_token;
  gl_->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());

  int signaled_count = 0;

  // Request a signal sync token, which gives a callback to the GpuControl to
  // run when the sync token is reached.
  base::OnceClosure signal_closure;
  EXPECT_CALL(*gpu_control_, DoSignalSyncToken(_, _))
      .WillOnce(Invoke([&signal_closure](const SyncToken& sync_token,
                                         base::OnceClosure* callback) {
        signal_closure = std::move(*callback);
      }));
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(sync_token))
      .WillOnce(Return(true));
  gl_->SignalSyncToken(sync_token,
                       base::BindOnce(&CountCallback, &signaled_count));
  EXPECT_EQ(0, signaled_count);

  // When GpuControl runs the callback, the original callback we gave to
  // RasterImplementation is run.
  std::move(signal_closure).Run();
  EXPECT_EQ(1, signaled_count);
}

TEST_F(RasterImplementationTest, SignalSyncTokenAfterContextLoss) {
  const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO;
  const CommandBufferId kCommandBufferId = CommandBufferId::FromUnsafeValue(1);
  const uint64_t kFenceSync = 123u;

  EXPECT_CALL(*gpu_control_, GetNamespaceID()).WillOnce(Return(kNamespaceId));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillOnce(Return(kCommandBufferId));
  EXPECT_CALL(*gpu_control_, GenerateFenceSyncRelease())
      .WillOnce(Return(kFenceSync));
  gpu::SyncToken sync_token;
  gl_->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());

  int signaled_count = 0;

  // Request a signal sync token, which gives a callback to the GpuControl to
  // run when the sync token is reached.
  base::OnceClosure signal_closure;
  EXPECT_CALL(*gpu_control_, DoSignalSyncToken(_, _))
      .WillOnce(Invoke([&signal_closure](const SyncToken& sync_token,
                                         base::OnceClosure* callback) {
        signal_closure = std::move(*callback);
      }));
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(sync_token))
      .WillOnce(Return(true));
  gl_->SignalSyncToken(sync_token,
                       base::BindOnce(&CountCallback, &signaled_count));
  EXPECT_EQ(0, signaled_count);

  // Inform the RasterImplementation that the context is lost.
  GpuControlClient* gl_as_client = gl_;
  gl_as_client->OnGpuControlLostContext();

  // When GpuControl runs the callback, the original callback we gave to
  // RasterImplementation is *not* run, since the context is lost and we
  // have already run the lost context callback.
  std::move(signal_closure).Run();
  EXPECT_EQ(0, signaled_count);
}

TEST_F(RasterImplementationTest, ReportLoss) {
  GpuControlClient* gl_as_client = gl_;
  int lost_count = 0;
  gl_->SetLostContextCallback(base::BindOnce(&CountCallback, &lost_count));
  EXPECT_EQ(0, lost_count);

  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetGraphicsResetStatusKHR());
  gl_as_client->OnGpuControlLostContext();
  EXPECT_NE(static_cast<GLenum>(GL_NO_ERROR), gl_->GetGraphicsResetStatusKHR());
  // The lost context callback should be run when RasterImplementation is
  // notified of the loss.
  EXPECT_EQ(1, lost_count);
}

TEST_F(RasterImplementationTest, ReportLossReentrant) {
  GpuControlClient* gl_as_client = gl_;
  int lost_count = 0;
  gl_->SetLostContextCallback(base::BindOnce(&CountCallback, &lost_count));
  EXPECT_EQ(0, lost_count);

  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetGraphicsResetStatusKHR());
  gl_as_client->OnGpuControlLostContextMaybeReentrant();
  EXPECT_NE(static_cast<GLenum>(GL_NO_ERROR), gl_->GetGraphicsResetStatusKHR());
  // The lost context callback should not be run yet to avoid calling back into
  // clients re-entrantly, and having them re-enter RasterImplementation.
  EXPECT_EQ(0, lost_count);
}

TEST_F(RasterImplementationManualInitTest, FailInitOnTransferBufferFail) {
  ContextInitOptions init_options;
  init_options.transfer_buffer_initialize_fail = true;
  EXPECT_FALSE(Initialize(init_options));
}

TEST_F(RasterImplementationTest, TransferCacheSerialization) {
  gl_->set_max_inlined_entry_size_for_testing(768u);
  uint32_t buffer_size = transfer_buffer_->MaxTransferBufferSize();
  ScopedTransferBufferPtr buffer(buffer_size, helper_, transfer_buffer_);
  ASSERT_EQ(buffer.size(), buffer_size);

  char* buffer_start = reinterpret_cast<char*>(buffer.address());
  memset(buffer_start, 0, buffer_size);
  gl_->SetRasterMappedBufferForTesting(std::move(buffer));
  auto transfer_cache = gl_->CreateTransferCacheHelperForTesting();

  std::vector<uint8_t> data(buffer_size - 16u);
  char* memory = buffer_start + 8u;
  cc::ClientRawMemoryTransferCacheEntry inlined_entry(data);
  EXPECT_EQ(transfer_cache->CreateEntry(inlined_entry, memory), data.size());
  EXPECT_EQ(memcmp(data.data(), memory, data.size()), 0);

  data.resize(buffer_size + 16u);
  memory = buffer_start + 8u;
  cc::ClientRawMemoryTransferCacheEntry non_inlined_entry(data);
  EXPECT_EQ(transfer_cache->CreateEntry(non_inlined_entry, memory), 0u);
}

TEST_F(RasterImplementationTest, SetActiveURLCHROMIUM) {
  const uint32_t kURLBucketId = RasterImplementation::kResultBucketId;
  const std::string url = "chrome://test";
  const uint32_t kPaddedStringSize =
      transfer_buffer_->RoundToAlignment(url.size());

  gl_->SetActiveURLCHROMIUM(url.c_str());
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  struct Cmds {
    cmd::SetBucketSize url_size;
    cmd::SetBucketData url_data;
    cmd::SetToken set_token;
    cmds::SetActiveURLCHROMIUM set_url_call;
    cmd::SetBucketSize url_size_end;
  };

  ExpectedMemoryInfo mem = GetExpectedMemory(kPaddedStringSize);
  EXPECT_EQ(0,
            memcmp(url.c_str(), reinterpret_cast<char*>(mem.ptr), url.size()));

  Cmds expected;
  expected.url_size.Init(kURLBucketId, url.size());
  expected.url_data.Init(kURLBucketId, 0, url.size(), mem.id, mem.offset);
  expected.set_token.Init(GetNextToken());
  expected.set_url_call.Init(kURLBucketId);
  expected.url_size_end.Init(kURLBucketId, 0);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));

  // Same URL shouldn't make any commands.
  EXPECT_FALSE(NoCommandsWritten());
  ClearCommands();
  gl_->SetActiveURLCHROMIUM(url.c_str());
  EXPECT_TRUE(NoCommandsWritten());
}

#include "base/macros.h"
#include "gpu/command_buffer/client/raster_implementation_unittest_autogen.h"

}  // namespace raster
}  // namespace gpu
