// 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.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

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

#include <memory>

#include "base/functional/bind.h"
#include "base/time/time.h"
#include "gpu/command_buffer/client/client_test_helper.h"
#include "gpu/command_buffer/common/gles2_cmd_format.h"
#include "gpu/command_buffer/service/error_state_mock.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gles2_query_manager.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
#include "gpu/command_buffer/service/gpu_tracer.h"
#include "gpu/command_buffer/service/test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_mock.h"
#include "ui/gl/gpu_timing.h"
#include "ui/gl/gpu_timing_fake.h"

using ::testing::_;
using ::testing::InSequence;
using ::testing::Return;
using ::testing::SetArgPointee;

namespace gpu {
namespace gles2 {

class QueryManagerTest : public GpuServiceTest {
 public:
  static const uint32_t kSharedMemoryOffset = 132;
  static const uint32_t kSharedMemory2Offset = 232;
  static const size_t kSharedBufferSize = 2048;
  static const int32_t kInvalidSharedMemoryId = -1;
  static const uint32_t kInvalidSharedMemoryOffset = kSharedBufferSize + 1;
  static const uint32_t kInitialResult = 0xBDBDBDBDu;
  static const uint8_t kInitialMemoryValue = 0xBDu;

  QueryManagerTest() = default;
  ~QueryManagerTest() override = default;

 protected:
  void SetUp() override {
    GpuServiceTest::SetUpWithGLVersion("OpenGL ES 3.0", "");
    SetUpMockGL("");
  }

  void TearDown() override {
    manager_->Destroy(false);
    manager_.reset();
    decoder_.reset();
    command_buffer_service_.reset();
    GpuServiceTest::TearDown();
  }

  void SetUpMockGL(const char* extension_expectations) {
    command_buffer_service_ = std::make_unique<FakeCommandBufferServiceBase>();
    scoped_refptr<gpu::Buffer> buffer =
        command_buffer_service_->CreateTransferBufferHelper(kSharedBufferSize,
                                                            &shared_memory_id_);
    memset(buffer->memory(), kInitialMemoryValue, kSharedBufferSize);
    buffer = command_buffer_service_->CreateTransferBufferHelper(
        kSharedBufferSize, &shared_memory2_id_);
    memset(buffer->memory(), kInitialMemoryValue, kSharedBufferSize);
    decoder_ = std::make_unique<MockGLES2Decoder>(
        &client_, command_buffer_service_.get(), &outputter_);
    TestHelper::SetupFeatureInfoInitExpectations(
        gl_.get(), extension_expectations);
    EXPECT_CALL(*decoder_.get(), GetGLContext())
      .WillRepeatedly(Return(GetGLContext()));
    scoped_refptr<FeatureInfo> feature_info(new FeatureInfo());
    feature_info->InitializeForTesting();
    manager_ =
        std::make_unique<GLES2QueryManager>(decoder_.get(), feature_info.get());
  }

  QueryManager::Query* CreateQuery(GLenum target,
                                   GLuint client_id,
                                   int32_t shm_id,
                                   uint32_t shm_offset,
                                   GLuint service_id) {
    return CreateQueryOnManager(manager_.get(), target, client_id, shm_id,
                                shm_offset, service_id);
  }

  QueryManager::Query* CreateQueryOnManager(QueryManager* manager,
                                            GLenum target,
                                            GLuint client_id,
                                            int32_t shm_id,
                                            uint32_t shm_offset,
                                            GLuint service_id) {
    if (service_id) {
      EXPECT_CALL(*gl_, GenQueries(1, _))
          .WillOnce(SetArgPointee<1>(service_id))
          .RetiresOnSaturation();
    }
    scoped_refptr<gpu::Buffer> buffer = decoder_->GetSharedMemoryBuffer(shm_id);
    if (!buffer)
      return nullptr;
    QuerySync* sync = static_cast<QuerySync*>(
        buffer->GetDataAddress(shm_offset, sizeof(QuerySync)));
    if (!sync)
      return nullptr;
    return manager->CreateQuery(target, client_id, std::move(buffer), sync);
  }

  void QueueQuery(QueryManager::Query* query,
                  GLuint service_id,
                  base::subtle::Atomic32 submit_count) {
    EXPECT_CALL(*gl_, BeginQuery(query->target(), service_id))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl_, EndQuery(query->target()))
        .Times(1)
        .RetiresOnSaturation();
    manager_->BeginQuery(query);
    manager_->EndQuery(query, submit_count);
  }

  TraceOutputter outputter_;
  std::unique_ptr<FakeCommandBufferServiceBase> command_buffer_service_;
  FakeDecoderClient client_;
  std::unique_ptr<MockGLES2Decoder> decoder_;
  std::unique_ptr<GLES2QueryManager> manager_;

  int32_t shared_memory_id_ = 0;
  int32_t shared_memory2_id_ = 0;
};

class QueryManagerTimerQueryTest : public QueryManagerTest {
 protected:
  void SetUp() override {
    GpuServiceTest::SetUpWithGLVersion("OpenGL ES 3.0",
                                       "GL_EXT_disjoint_timer_query");
    fake_timing_queries_.ExpectDisjointCalls(*gl_);
    SetUpMockGL("GL_EXT_disjoint_timer_query");
  }

  gl::GPUTimingFake fake_timing_queries_;
};

// GCC requires these declarations, but MSVC requires they not be present
#ifndef COMPILER_MSVC
const uint32_t QueryManagerTest::kSharedMemoryOffset;
const uint32_t QueryManagerTest::kSharedMemory2Offset;
const size_t QueryManagerTest::kSharedBufferSize;
const int32_t QueryManagerTest::kInvalidSharedMemoryId;
const uint32_t QueryManagerTest::kInvalidSharedMemoryOffset;
const uint32_t QueryManagerTest::kInitialResult;
const uint8_t QueryManagerTest::kInitialMemoryValue;
#endif

TEST_F(QueryManagerTest, Basic) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  const GLuint kClient2Id = 2;

  EXPECT_FALSE(manager_->HavePendingQueries());
  // Check we can create a Query.
  scoped_refptr<QueryManager::Query> query(
      CreateQuery(GL_ANY_SAMPLES_PASSED_EXT, kClient1Id, shared_memory_id_,
                  kSharedMemoryOffset, kService1Id));
  ASSERT_TRUE(query.get() != nullptr);
  // Check we can get the same Query.
  EXPECT_EQ(query.get(), manager_->GetQuery(kClient1Id));
  // Check we get nothing for a non-existent query.
  EXPECT_TRUE(manager_->GetQuery(kClient2Id) == nullptr);
  // Check we can delete the query.
  EXPECT_CALL(*gl_, DeleteQueries(1, ::testing::Pointee(kService1Id)))
      .Times(1)
      .RetiresOnSaturation();
  manager_->RemoveQuery(kClient1Id);
  // Check we get nothing for a non-existent query.
  EXPECT_TRUE(manager_->GetQuery(kClient1Id) == nullptr);
  // Check query is deleted
  EXPECT_TRUE(query->IsDeleted());
  EXPECT_FALSE(manager_->HavePendingQueries());
}

TEST_F(QueryManagerTest, Destroy) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;

  // Create Query.
  scoped_refptr<QueryManager::Query> query(
      CreateQuery(GL_ANY_SAMPLES_PASSED_EXT, kClient1Id, shared_memory_id_,
                  kSharedMemoryOffset, kService1Id));
  ASSERT_TRUE(query.get() != nullptr);
  EXPECT_CALL(*gl_, DeleteQueries(1, ::testing::Pointee(kService1Id)))
      .Times(1)
      .RetiresOnSaturation();
  manager_->Destroy(true);
  // Check we get nothing for a non-existent query.
  EXPECT_TRUE(manager_->GetQuery(kClient1Id) == nullptr);
  // Check query is deleted
  EXPECT_TRUE(query->IsDeleted());
}

TEST_F(QueryManagerTest, QueryBasic) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;

  // Create Query.
  scoped_refptr<QueryManager::Query> query(
      CreateQuery(kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset,
                  kService1Id));
  ASSERT_TRUE(query.get() != nullptr);

  EXPECT_TRUE(query->IsValid());
  EXPECT_FALSE(query->IsDeleted());
  EXPECT_FALSE(query->IsPending());
  EXPECT_EQ(kTarget, query->target());
}

TEST_F(QueryManagerTest, ProcessPendingQuery) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
  const base::subtle::Atomic32 kSubmitCount = 123;
  const GLuint kResult = 1;

  // Check nothing happens if there are no pending queries.
  manager_->ProcessPendingQueries(false);

  // Create Query.
  scoped_refptr<QueryManager::Query> query(
      CreateQuery(kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset,
                  kService1Id));
  ASSERT_TRUE(query.get() != nullptr);

  // Setup shared memory like client would.
  QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
      shared_memory_id_, kSharedMemoryOffset, sizeof(*sync));
  ASSERT_TRUE(sync != nullptr);
  sync->Reset();

  // Queue it
  QueueQuery(query.get(), kService1Id, kSubmitCount);
  EXPECT_TRUE(query->IsPending());
  EXPECT_TRUE(manager_->HavePendingQueries());

  // Process with return not available.
  // Expect 1 GL command.
  EXPECT_CALL(*gl_,
              GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
      .WillOnce(SetArgPointee<2>(0))
      .RetiresOnSaturation();
  manager_->ProcessPendingQueries(false);
  EXPECT_TRUE(query->IsPending());
  EXPECT_EQ(0, base::subtle::Atomic32{sync->process_count});
  EXPECT_EQ(0u, uint64_t{sync->result});

  // Process with return available.
  // Expect 2 GL commands.
  EXPECT_CALL(*gl_,
              GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
      .WillOnce(SetArgPointee<2>(1))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _))
      .WillOnce(SetArgPointee<2>(kResult))
      .RetiresOnSaturation();
  manager_->ProcessPendingQueries(false);
  EXPECT_FALSE(query->IsPending());
  EXPECT_EQ(kSubmitCount, base::subtle::Atomic32{sync->process_count});
  EXPECT_EQ(kResult, uint64_t{sync->result});
  EXPECT_FALSE(manager_->HavePendingQueries());

  // Process with no queries.
  // Expect no GL commands/
  manager_->ProcessPendingQueries(false);
}

TEST_F(QueryManagerTest, ProcessPendingQueries) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  const GLuint kClient2Id = 2;
  const GLuint kService2Id = 12;
  const GLuint kClient3Id = 3;
  const GLuint kService3Id = 13;
  const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
  const base::subtle::Atomic32 kSubmitCount1 = 123;
  const base::subtle::Atomic32 kSubmitCount2 = 123;
  const base::subtle::Atomic32 kSubmitCount3 = 123;
  const GLuint kResult1 = 1;
  const GLuint kResult2 = 1;
  const GLuint kResult3 = 1;

  // Setup shared memory like client would.
  QuerySync* sync1 = decoder_->GetSharedMemoryAs<QuerySync*>(
      shared_memory_id_, kSharedMemoryOffset, sizeof(*sync1) * 3);
  ASSERT_TRUE(sync1 != nullptr);
  QuerySync* sync2 = sync1 + 1;
  QuerySync* sync3 = sync2 + 1;

  // Create Queries.
  scoped_refptr<QueryManager::Query> query1(
      CreateQuery(kTarget, kClient1Id, shared_memory_id_,
                  kSharedMemoryOffset + sizeof(*sync1) * 0, kService1Id));
  scoped_refptr<QueryManager::Query> query2(
      CreateQuery(kTarget, kClient2Id, shared_memory_id_,
                  kSharedMemoryOffset + sizeof(*sync1) * 1, kService2Id));
  scoped_refptr<QueryManager::Query> query3(
      CreateQuery(kTarget, kClient3Id, shared_memory_id_,
                  kSharedMemoryOffset + sizeof(*sync1) * 2, kService3Id));
  ASSERT_TRUE(query1.get() != nullptr);
  ASSERT_TRUE(query2.get() != nullptr);
  ASSERT_TRUE(query3.get() != nullptr);
  EXPECT_FALSE(manager_->HavePendingQueries());

  sync1->Reset();
  sync2->Reset();
  sync3->Reset();

  // Queue them
  QueueQuery(query1.get(), kService1Id, kSubmitCount1);
  QueueQuery(query2.get(), kService2Id, kSubmitCount2);
  QueueQuery(query3.get(), kService3Id, kSubmitCount3);
  EXPECT_TRUE(query1->IsPending());
  EXPECT_TRUE(query2->IsPending());
  EXPECT_TRUE(query3->IsPending());
  EXPECT_TRUE(manager_->HavePendingQueries());

  // Process with return available for first 2 queries.
  // Expect 4 GL commands.
  {
    InSequence s;
    EXPECT_CALL(
        *gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
        .WillOnce(SetArgPointee<2>(1))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _))
        .WillOnce(SetArgPointee<2>(kResult1))
        .RetiresOnSaturation();
    EXPECT_CALL(
        *gl_, GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
        .WillOnce(SetArgPointee<2>(1))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl_, GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_EXT, _))
        .WillOnce(SetArgPointee<2>(kResult2))
        .RetiresOnSaturation();
    EXPECT_CALL(
        *gl_, GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
        .WillOnce(SetArgPointee<2>(0))
        .RetiresOnSaturation();
    manager_->ProcessPendingQueries(false);
  }
  EXPECT_FALSE(query1->IsPending());
  EXPECT_FALSE(query2->IsPending());
  EXPECT_TRUE(query3->IsPending());
  EXPECT_EQ(kSubmitCount1, base::subtle::Atomic32{sync1->process_count});
  EXPECT_EQ(kSubmitCount2, base::subtle::Atomic32{sync2->process_count});
  EXPECT_EQ(kResult1, uint64_t{sync1->result});
  EXPECT_EQ(kResult2, uint64_t{sync2->result});
  EXPECT_EQ(0, base::subtle::Atomic32{sync3->process_count});
  EXPECT_EQ(0u, uint64_t{sync3->result});
  EXPECT_TRUE(manager_->HavePendingQueries());

  // Process with renaming query. No result.
  // Expect 1 GL commands.
  EXPECT_CALL(*gl_,
              GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
      .WillOnce(SetArgPointee<2>(0))
      .RetiresOnSaturation();
  manager_->ProcessPendingQueries(false);
  EXPECT_TRUE(query3->IsPending());
  EXPECT_EQ(0, base::subtle::Atomic32{sync3->process_count});
  EXPECT_EQ(0u, uint64_t{sync3->result});
  EXPECT_TRUE(manager_->HavePendingQueries());

  // Process with renaming query. With result.
  // Expect 2 GL commands.
  EXPECT_CALL(*gl_,
              GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
      .WillOnce(SetArgPointee<2>(1))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl_, GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_EXT, _))
      .WillOnce(SetArgPointee<2>(kResult3))
      .RetiresOnSaturation();
  manager_->ProcessPendingQueries(false);
  EXPECT_FALSE(query3->IsPending());
  EXPECT_EQ(kSubmitCount3, base::subtle::Atomic32{sync3->process_count});
  EXPECT_EQ(kResult3, uint64_t{sync3->result});
  EXPECT_FALSE(manager_->HavePendingQueries());
}

TEST_F(QueryManagerTest, ExitWithPendingQuery) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
  const base::subtle::Atomic32 kSubmitCount = 123;

  // Create Query.
  scoped_refptr<QueryManager::Query> query(
      CreateQuery(kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset,
                  kService1Id));
  ASSERT_TRUE(query.get() != nullptr);

  // Queue it
  QueueQuery(query.get(), kService1Id, kSubmitCount);
}

TEST_F(QueryManagerTimerQueryTest, TimeElapsedQuery) {
  const GLuint kClient1Id = 1;
  const GLenum kTarget = GL_TIME_ELAPSED_EXT;
  const base::subtle::Atomic32 kSubmitCount = 123;
  decoder_->GetGLContext()->CreateGPUTimingClient()->SetCpuTimeForTesting(
      base::BindRepeating(&gl::GPUTimingFake::GetFakeCPUTime));

  QueryManager::Query* query = CreateQuery(
      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
  ASSERT_TRUE(query != nullptr);

  fake_timing_queries_.ExpectGPUTimerQuery(*gl_, true);
  fake_timing_queries_.SetCurrentGLTime(200 *
                                        base::Time::kNanosecondsPerMicrosecond);
  manager_->BeginQuery(query);
  fake_timing_queries_.SetCurrentGLTime(300 *
                                        base::Time::kNanosecondsPerMicrosecond);
  manager_->EndQuery(query, kSubmitCount);
  manager_->ProcessPendingQueries(false);

  EXPECT_TRUE(query->IsFinished());

  QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
      shared_memory_id_, kSharedMemoryOffset, sizeof(*sync));
  const uint64_t expected_result =
      100u * base::Time::kNanosecondsPerMicrosecond;
  EXPECT_EQ(expected_result, uint64_t{sync->result});

  manager_->Destroy(false);
}

TEST_F(QueryManagerTimerQueryTest, TimeElapsedPauseResume) {
  const GLuint kClient1Id = 1;
  const GLenum kTarget = GL_TIME_ELAPSED_EXT;
  const base::subtle::Atomic32 kSubmitCount = 123;
  decoder_->GetGLContext()->CreateGPUTimingClient()->SetCpuTimeForTesting(
      base::BindRepeating(&gl::GPUTimingFake::GetFakeCPUTime));

  QueryManager::Query* query = CreateQuery(
      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
  ASSERT_TRUE(query != nullptr);

  fake_timing_queries_.ExpectGPUTimerQuery(*gl_, true);
  fake_timing_queries_.SetCurrentGLTime(200 *
                                        base::Time::kNanosecondsPerMicrosecond);
  manager_->BeginQuery(query);

  // Pause and Resume here.
  fake_timing_queries_.SetCurrentGLTime(300 *
                                        base::Time::kNanosecondsPerMicrosecond);
  manager_->PauseQueries();

  fake_timing_queries_.SetCurrentGLTime(400 *
                                        base::Time::kNanosecondsPerMicrosecond);
  manager_->ResumeQueries();

  fake_timing_queries_.SetCurrentGLTime(500 *
                                        base::Time::kNanosecondsPerMicrosecond);
  manager_->EndQuery(query, kSubmitCount);

  manager_->ProcessPendingQueries(false);
  EXPECT_TRUE(query->IsFinished());

  QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
      shared_memory_id_, kSharedMemoryOffset, sizeof(*sync));
  const uint64_t expected_result =
      300u * base::Time::kNanosecondsPerMicrosecond;
  EXPECT_EQ(expected_result, uint64_t{sync->result});

  // Make sure next query works properly.
  fake_timing_queries_.SetCurrentGLTime(600 *
                                        base::Time::kNanosecondsPerMicrosecond);
  manager_->BeginQuery(query);
  fake_timing_queries_.SetCurrentGLTime(700 *
                                        base::Time::kNanosecondsPerMicrosecond);
  manager_->EndQuery(query, kSubmitCount + 1);
  manager_->ProcessPendingQueries(false);

  EXPECT_TRUE(query->IsFinished());

  const uint64_t expected_result2 =
      100u * base::Time::kNanosecondsPerMicrosecond;
  EXPECT_EQ(expected_result2, uint64_t{sync->result});

  manager_->Destroy(false);
}

TEST_F(QueryManagerTimerQueryTest, TimeElapsedDisjoint) {
  DisjointValueSync* disjoint_sync =
      decoder_->GetSharedMemoryAs<DisjointValueSync*>(
          shared_memory2_id_, kSharedMemory2Offset, sizeof(*disjoint_sync));
  manager_->SetDisjointSync(shared_memory2_id_, kSharedMemory2Offset);

  const uint32_t current_disjoint_value = disjoint_sync->GetDisjointCount();
  ASSERT_EQ(0u, current_disjoint_value);

  const GLuint kClient1Id = 1;
  const GLenum kTarget = GL_TIME_ELAPSED_EXT;
  const base::subtle::Atomic32 kSubmitCount = 123;

  QueryManager::Query* query = CreateQuery(
      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
  ASSERT_TRUE(query != nullptr);

  // Disjoint happening before the query should not trigger a disjoint event.
  fake_timing_queries_.SetDisjoint();

  fake_timing_queries_.ExpectGPUTimerQuery(*gl_, true);
  manager_->BeginQuery(query);
  manager_->EndQuery(query, kSubmitCount);
  manager_->ProcessPendingQueries(false);

  EXPECT_TRUE(query->IsFinished());
  EXPECT_EQ(current_disjoint_value, disjoint_sync->GetDisjointCount());

  // Disjoint happening during query should trigger disjoint event.
  fake_timing_queries_.ExpectGPUTimerQuery(*gl_, true);
  manager_->BeginQuery(query);
  fake_timing_queries_.SetDisjoint();
  manager_->EndQuery(query, kSubmitCount);
  manager_->ProcessPendingQueries(false);

  EXPECT_TRUE(query->IsFinished());
  EXPECT_NE(current_disjoint_value, disjoint_sync->GetDisjointCount());

  manager_->Destroy(false);
}

TEST_F(QueryManagerTimerQueryTest, TimeStampQuery) {
  const GLuint kClient1Id = 1;
  const GLenum kTarget = GL_TIMESTAMP_EXT;
  const base::subtle::Atomic32 kSubmitCount = 123;

  decoder_->GetGLContext()->CreateGPUTimingClient()->SetCpuTimeForTesting(
      base::BindRepeating(&gl::GPUTimingFake::GetFakeCPUTime));

  QueryManager::Query* query = CreateQuery(
      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
  ASSERT_TRUE(query != nullptr);

  const uint64_t expected_result =
      100u * base::Time::kNanosecondsPerMicrosecond;
  fake_timing_queries_.SetCurrentGLTime(expected_result);
  fake_timing_queries_.ExpectGPUTimeStampQuery(*gl_, false);
  manager_->QueryCounter(query, kSubmitCount);
  manager_->ProcessPendingQueries(false);

  QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
      shared_memory_id_, kSharedMemoryOffset, sizeof(*sync));
  EXPECT_EQ(expected_result, uint64_t{sync->result});

  manager_->Destroy(false);
}

TEST_F(QueryManagerTimerQueryTest, TimeStampQueryPending) {
  const GLuint kClient1Id = 1;
  const GLenum kTarget = GL_TIMESTAMP_EXT;
  const base::subtle::Atomic32 kSubmitCount = 123;

  decoder_->GetGLContext()->CreateGPUTimingClient()->SetCpuTimeForTesting(
      base::BindRepeating(&gl::GPUTimingFake::GetFakeCPUTime));

  QueryManager::Query* query = CreateQuery(
      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
  ASSERT_TRUE(query != nullptr);

  const uint64_t expected_result =
      100u * base::Time::kNanosecondsPerMicrosecond;
  fake_timing_queries_.SetCurrentGLTime(expected_result);
  fake_timing_queries_.ExpectGPUTimeStampQuery(*gl_, false);
  manager_->QueryCounter(query, kSubmitCount);
  EXPECT_TRUE(query->IsPending());
  fake_timing_queries_.ExpectGPUTimeStampQuery(*gl_, false);
  manager_->QueryCounter(query, kSubmitCount);
  manager_->ProcessPendingQueries(false);

  QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
      shared_memory_id_, kSharedMemoryOffset, sizeof(*sync));
  EXPECT_EQ(expected_result, uint64_t{sync->result});

  manager_->Destroy(false);
}

TEST_F(QueryManagerTimerQueryTest, TimeStampDisjoint) {
  DisjointValueSync* disjoint_sync =
      decoder_->GetSharedMemoryAs<DisjointValueSync*>(
          shared_memory2_id_, kSharedMemory2Offset, sizeof(*disjoint_sync));
  manager_->SetDisjointSync(shared_memory2_id_, kSharedMemory2Offset);

  const uint32_t current_disjoint_value = disjoint_sync->GetDisjointCount();
  ASSERT_EQ(0u, current_disjoint_value);

  const GLuint kClient1Id = 1;
  const GLenum kTarget = GL_TIMESTAMP_EXT;
  const base::subtle::Atomic32 kSubmitCount = 123;

  QueryManager::Query* query = CreateQuery(
      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
  ASSERT_TRUE(query != nullptr);

  // Disjoint happening before the query should not trigger a disjoint event.
  fake_timing_queries_.SetDisjoint();

  fake_timing_queries_.ExpectGPUTimeStampQuery(*gl_, false);
  manager_->QueryCounter(query, kSubmitCount);
  manager_->ProcessPendingQueries(false);

  EXPECT_TRUE(query->IsFinished());
  EXPECT_EQ(current_disjoint_value, disjoint_sync->GetDisjointCount());

  // Disjoint happening during query should trigger disjoint event.
  fake_timing_queries_.ExpectGPUTimeStampQuery(*gl_, false);
  manager_->QueryCounter(query, kSubmitCount);
  fake_timing_queries_.SetDisjoint();
  manager_->ProcessPendingQueries(false);

  EXPECT_TRUE(query->IsFinished());
  EXPECT_NE(current_disjoint_value, disjoint_sync->GetDisjointCount());

  manager_->Destroy(false);
}

TEST_F(QueryManagerTimerQueryTest, DisjointContinualTest) {
  DisjointValueSync* disjoint_sync =
      decoder_->GetSharedMemoryAs<DisjointValueSync*>(
          shared_memory2_id_, kSharedMemory2Offset, sizeof(*disjoint_sync));
  manager_->SetDisjointSync(shared_memory2_id_, kSharedMemory2Offset);

  const uint32_t current_disjoint_value = disjoint_sync->GetDisjointCount();
  ASSERT_EQ(0u, current_disjoint_value);

  // Disjoint value should not be updated until we have a timestamp query.
  fake_timing_queries_.SetDisjoint();
  manager_->ProcessFrameBeginUpdates();
  EXPECT_EQ(current_disjoint_value, disjoint_sync->GetDisjointCount());

  const GLuint kClient1Id = 1;
  const GLenum kTarget = GL_TIMESTAMP_EXT;
  const base::subtle::Atomic32 kSubmitCount = 123;

  QueryManager::Query* query = CreateQuery(
      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
  ASSERT_TRUE(query != nullptr);

  fake_timing_queries_.ExpectGPUTimeStampQuery(*gl_, false);
  manager_->QueryCounter(query, kSubmitCount);
  manager_->ProcessPendingQueries(false);

  EXPECT_EQ(current_disjoint_value, disjoint_sync->GetDisjointCount());
  fake_timing_queries_.SetDisjoint();
  manager_->ProcessFrameBeginUpdates();
  EXPECT_NE(current_disjoint_value, disjoint_sync->GetDisjointCount());

  manager_->Destroy(false);
}

TEST_F(QueryManagerTest, GetErrorQuery) {
  const GLuint kClient1Id = 1;
  const GLenum kTarget = GL_GET_ERROR_QUERY_CHROMIUM;
  const base::subtle::Atomic32 kSubmitCount = 123;

  TestHelper::SetupFeatureInfoInitExpectations(gl_.get(), "");
  scoped_refptr<FeatureInfo> feature_info(new FeatureInfo());
  feature_info->InitializeForTesting();
  std::unique_ptr<GLES2QueryManager> manager(
      new GLES2QueryManager(decoder_.get(), feature_info.get()));

  QueryManager::Query* query =
      CreateQueryOnManager(manager.get(), kTarget, kClient1Id,
                           shared_memory_id_, kSharedMemoryOffset, 0);
  ASSERT_TRUE(query != nullptr);

  // Setup shared memory like client would.
  QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
      shared_memory_id_, kSharedMemoryOffset, sizeof(*sync));
  ASSERT_TRUE(sync != nullptr);
  sync->Reset();

  manager->BeginQuery(query);

  MockErrorState mock_error_state;
  EXPECT_CALL(*decoder_.get(), GetErrorState())
      .WillRepeatedly(Return(&mock_error_state));
  EXPECT_CALL(mock_error_state, GetGLError())
      .WillOnce(Return(GL_INVALID_ENUM))
      .RetiresOnSaturation();

  manager->EndQuery(query, kSubmitCount);
  EXPECT_FALSE(query->IsPending());

  EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), uint64_t{sync->result});

  manager->Destroy(false);
}

TEST_F(QueryManagerTest, OcclusionQuery) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  const GLenum kTarget = GL_SAMPLES_PASSED_ARB;
  const base::subtle::Atomic32 kSubmitCount = 123;

  TestHelper::SetupFeatureInfoInitExpectations(gl_.get(),
                                               "GL_EXT_occlusion_query");
  scoped_refptr<FeatureInfo> feature_info(new FeatureInfo());
  feature_info->InitializeForTesting();
  std::unique_ptr<GLES2QueryManager> manager(
      new GLES2QueryManager(decoder_.get(), feature_info.get()));

  QueryManager::Query* query =
      CreateQueryOnManager(manager.get(), kTarget, kClient1Id,
                           shared_memory_id_, kSharedMemoryOffset, kService1Id);
  ASSERT_TRUE(query != nullptr);

  EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService1Id))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*gl_, EndQuery(GL_SAMPLES_PASSED_ARB))
      .Times(1)
      .RetiresOnSaturation();
  manager->BeginQuery(query);
  manager->EndQuery(query, kSubmitCount);
  manager->Destroy(false);
}

}  // namespace gles2
}  // namespace gpu
