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

#include <stdint.h>

#include <memory>

#include "base/bind.h"
#include "gpu/command_buffer/client/client_test_helper.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
#include "gpu/command_buffer/service/gpu_tracer.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"

namespace gpu {
namespace gles2 {
namespace {

using ::testing::_;
using ::testing::AtMost;
using ::testing::Exactly;
using ::testing::Invoke;
using ::testing::Return;

int64_t g_fakeCPUTime = 0;
int64_t FakeCpuTime() {
  return g_fakeCPUTime;
}

class MockOutputter : public Outputter {
 public:
  MockOutputter() = default;
  ~MockOutputter() override = default;

  MOCK_METHOD5(TraceDevice,
               void(GpuTracerSource source,
                    const std::string& category,
                    const std::string& name,
                    int64_t start_time,
                    int64_t end_time));
  MOCK_METHOD3(TraceServiceBegin,
               void(GpuTracerSource source,
                    const std::string& category, const std::string& name));
  MOCK_METHOD3(TraceServiceEnd,
               void(GpuTracerSource source,
                    const std::string& category, const std::string& name));
};

class GPUTracerTester : public GPUTracer {
 public:
  explicit GPUTracerTester(GLES2Decoder* decoder)
      : GPUTracer(decoder), tracing_enabled_(0) {
    gpu_timing_client_->SetCpuTimeForTesting(base::BindRepeating(&FakeCpuTime));

    // Force tracing to be dependent on our mock variable here.
    gpu_trace_srv_category_ = &tracing_enabled_;
    gpu_trace_dev_category_ = &tracing_enabled_;
  }

  ~GPUTracerTester() override = default;

  void SetTracingEnabled(bool enabled) {
    tracing_enabled_ = enabled ? 1 : 0;
  }

 private:
  unsigned char tracing_enabled_;
};

class BaseGpuTest : public GpuServiceTest {
 public:
  explicit BaseGpuTest(gl::GPUTiming::TimerType test_timer_type)
      : test_timer_type_(test_timer_type) {}

 protected:
  void SetUp() override {
    g_fakeCPUTime = 0;
    const char* gl_version = "3.2";
    const char* extensions = "";
    if (GetTimerType() == gl::GPUTiming::kTimerTypeEXT) {
      gl_version = "2.1";
      extensions = "GL_EXT_timer_query";
    } else if (GetTimerType() == gl::GPUTiming::kTimerTypeDisjoint) {
      gl_version = "OpenGL ES 3.0";
      extensions = "GL_EXT_disjoint_timer_query";
    } else if (GetTimerType() == gl::GPUTiming::kTimerTypeARB) {
      // TODO(sievers): The tracer should not depend on ARB_occlusion_query.
      // Try merge Query APIs (core, ARB, EXT) into a single binding each.
      extensions = "GL_ARB_timer_query GL_ARB_occlusion_query";
    }
    GpuServiceTest::SetUpWithGLVersion(gl_version, extensions);

    // Disjoint check should only be called by kTracerTypeDisjointTimer type.
    if (GetTimerType() == gl::GPUTiming::kTimerTypeDisjoint)
      gl_fake_queries_.ExpectDisjointCalls(*gl_);
    else
      gl_fake_queries_.ExpectNoDisjointCalls(*gl_);

    gpu_timing_client_ = GetGLContext()->CreateGPUTimingClient();
    gpu_timing_client_->SetCpuTimeForTesting(base::BindRepeating(&FakeCpuTime));
    gl_fake_queries_.Reset();
  }

  void TearDown() override {
    gpu_timing_client_ = nullptr;
    gl_fake_queries_.Reset();
    GpuServiceTest::TearDown();
  }

  void ExpectTraceQueryMocks() {
    if (gpu_timing_client_->IsAvailable()) {
      // Delegate query APIs used by GPUTrace to a GlFakeQueries
      const bool elapsed = (GetTimerType() == gl::GPUTiming::kTimerTypeEXT);
      gl_fake_queries_.ExpectGPUTimerQuery(*gl_, elapsed);
    }
  }

  void ExpectOutputterBeginMocks(MockOutputter* outputter,
                                 GpuTracerSource source,
                                 const std::string& category,
                                 const std::string& name) {
    EXPECT_CALL(*outputter,
                TraceServiceBegin(source, category, name));
  }

  void ExpectOutputterEndMocks(MockOutputter* outputter,
                               GpuTracerSource source,
                               const std::string& category,
                               const std::string& name,
                               int64_t expect_start_time,
                               int64_t expect_end_time,
                               bool trace_service,
                               bool trace_device) {
    if (trace_service) {
      EXPECT_CALL(*outputter,
                  TraceServiceEnd(source, category, name));
    }

    if (trace_device) {
      EXPECT_CALL(*outputter,
                  TraceDevice(source, category, name,
                              expect_start_time, expect_end_time))
          .Times(Exactly(1));
    } else {
      EXPECT_CALL(*outputter, TraceDevice(source, category, name,
                                          expect_start_time, expect_end_time))
          .Times(Exactly(0));
    }
  }

  void ExpectDisjointOutputMocks(MockOutputter* outputter,
                                 int64_t expect_start_time,
                                 int64_t expect_end_time) {
    EXPECT_CALL(*outputter,
                TraceDevice(kTraceDisjoint, "DisjointEvent", _,
                            expect_start_time, expect_end_time))
          .Times(Exactly(1));
  }

  void ExpectNoDisjointOutputMocks(MockOutputter* outputter) {
    EXPECT_CALL(*outputter,
                TraceDevice(kTraceDisjoint, "DisjointEvent", _, _, _))
          .Times(Exactly(0));
  }

  void ExpectOutputterMocks(MockOutputter* outputter,
                            bool tracing_service,
                            bool tracing_device,
                            GpuTracerSource source,
                            const std::string& category,
                            const std::string& name,
                            int64_t expect_start_time,
                            int64_t expect_end_time) {
    if (tracing_service)
      ExpectOutputterBeginMocks(outputter, source, category, name);
    const bool valid_timer = tracing_device &&
                             gpu_timing_client_->IsAvailable();
    ExpectOutputterEndMocks(outputter, source, category, name,
                            expect_start_time, expect_end_time,
                            tracing_service, valid_timer);
  }

  void ExpectTracerOffsetQueryMocks() {
    if (GetTimerType() != gl::GPUTiming::kTimerTypeARB) {
      gl_fake_queries_.ExpectNoOffsetCalculationQuery(*gl_);
    } else {
      gl_fake_queries_.ExpectOffsetCalculationQuery(*gl_);
    }
  }

  gl::GPUTiming::TimerType GetTimerType() { return test_timer_type_; }

  gl::GPUTiming::TimerType test_timer_type_;
  gl::GPUTimingFake gl_fake_queries_;

  scoped_refptr<gl::GPUTimingClient> gpu_timing_client_;
  MockOutputter outputter_;
};

// Test GPUTrace calls all the correct gl calls.
class BaseGpuTraceTest : public BaseGpuTest {
 public:
  explicit BaseGpuTraceTest(gl::GPUTiming::TimerType test_timer_type)
      : BaseGpuTest(test_timer_type) {}

  void DoTraceTest(bool tracing_service, bool tracing_device) {
    // Expected results
    const GpuTracerSource tracer_source = kTraceCHROMIUM;
    const std::string category_name("trace_category");
    const std::string trace_name("trace_test");
    const int64_t offset_time = 3231;
    const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond;
    const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond;
    const int64_t expect_start_time =
        (start_timestamp / base::Time::kNanosecondsPerMicrosecond) +
        offset_time;
    const int64_t expect_end_time =
        (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;

    ExpectOutputterMocks(&outputter_, tracing_service, tracing_device,
                         tracer_source, category_name, trace_name,
                         expect_start_time, expect_end_time);

    if (tracing_device)
      ExpectTraceQueryMocks();

    scoped_refptr<GPUTrace> trace = new GPUTrace(
        &outputter_, gpu_timing_client_.get(), tracer_source, category_name,
        trace_name, tracing_service, tracing_device);

    gl_fake_queries_.SetCurrentGLTime(start_timestamp);
    g_fakeCPUTime = expect_start_time;
    trace->Start();

    // Shouldn't be available before End() call
    gl_fake_queries_.SetCurrentGLTime(end_timestamp);
    g_fakeCPUTime = expect_end_time;
    if (tracing_device)
      EXPECT_FALSE(trace->IsAvailable());

    trace->End();

    // Shouldn't be available until the queries complete
    gl_fake_queries_.SetCurrentGLTime(end_timestamp -
                                      base::Time::kNanosecondsPerMicrosecond);
    g_fakeCPUTime = expect_end_time - 1;
    if (tracing_device)
      EXPECT_FALSE(trace->IsAvailable());

    // Now it should be available
    gl_fake_queries_.SetCurrentGLTime(end_timestamp);
    g_fakeCPUTime = expect_end_time;
    EXPECT_TRUE(trace->IsAvailable());

    // Process should output expected Trace results to MockOutputter
    trace->Process();

    // Destroy trace after we are done.
    trace->Destroy(true);
  }
};

class GpuARBTimerTraceTest : public BaseGpuTraceTest {
 public:
  GpuARBTimerTraceTest() : BaseGpuTraceTest(gl::GPUTiming::kTimerTypeARB) {}
};

class GpuDisjointTimerTraceTest : public BaseGpuTraceTest {
 public:
  GpuDisjointTimerTraceTest()
      : BaseGpuTraceTest(gl::GPUTiming::kTimerTypeDisjoint) {}
};

TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTestOff) {
  DoTraceTest(false, false);
}

TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTestServiceOnly) {
  DoTraceTest(true, false);
}

TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTestDeviceOnly) {
  DoTraceTest(false, true);
}

TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTestBothOn) {
  DoTraceTest(true, true);
}

TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTestOff) {
  DoTraceTest(false, false);
}

TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTestServiceOnly) {
  DoTraceTest(true, false);
}

TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTestDeviceOnly) {
  DoTraceTest(false, true);
}

TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTestBothOn) {
  DoTraceTest(true, true);
}

// Test GPUTracer calls all the correct gl calls.
class BaseGpuTracerTest : public BaseGpuTest {
 public:
  explicit BaseGpuTracerTest(gl::GPUTiming::TimerType test_timer_type)
      : BaseGpuTest(test_timer_type) {}

  void DoBasicTracerTest() {
    ExpectTracerOffsetQueryMocks();

    FakeCommandBufferServiceBase command_buffer_service;
    FakeDecoderClient client;
    MockOutputter outputter;
    MockGLES2Decoder decoder(&client, &command_buffer_service, &outputter);
    EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
    GPUTracerTester tracer(&decoder);
    tracer.SetTracingEnabled(true);

    ASSERT_TRUE(tracer.BeginDecoding());
    ASSERT_TRUE(tracer.EndDecoding());
  }

  void DoDisabledTracingTest() {
    ExpectTracerOffsetQueryMocks();

    const GpuTracerSource source = static_cast<GpuTracerSource>(0);

    FakeCommandBufferServiceBase command_buffer_service;
    FakeDecoderClient client;
    MockOutputter outputter;
    MockGLES2Decoder decoder(&client, &command_buffer_service, &outputter);
    EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
    GPUTracerTester tracer(&decoder);
    tracer.SetTracingEnabled(false);

    ASSERT_TRUE(tracer.BeginDecoding());
    ASSERT_TRUE(tracer.Begin("disabled_category", "disabled_name", source));
    ASSERT_TRUE(tracer.End(source));
    ASSERT_TRUE(tracer.EndDecoding());
  }

  void DoTracerMarkersTest() {
    ExpectTracerOffsetQueryMocks();
    gl_fake_queries_.ExpectGetErrorCalls(*gl_);

    const std::string category_name("trace_category");
    const std::string trace_name("trace_test");
    const int64_t offset_time = 3231;
    const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond;
    const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond;
    const int64_t expect_start_time =
        (start_timestamp / base::Time::kNanosecondsPerMicrosecond) +
        offset_time;
    const int64_t expect_end_time =
        (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;

    FakeCommandBufferServiceBase command_buffer_service;
    FakeDecoderClient client;
    MockOutputter outputter;
    MockGLES2Decoder decoder(&client, &command_buffer_service, &outputter);
    EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
    GPUTracerTester tracer(&decoder);
    tracer.SetTracingEnabled(true);

    gl_fake_queries_.SetCurrentGLTime(start_timestamp);
    g_fakeCPUTime = expect_start_time;

    ASSERT_TRUE(tracer.BeginDecoding());

    ExpectTraceQueryMocks();

    // This will test multiple marker sources which overlap one another.
    for (int i = 0; i < NUM_TRACER_SOURCES; ++i) {
      // Set times so each source has a different time.
      gl_fake_queries_.SetCurrentGLTime(
          start_timestamp +
          (i * base::Time::kNanosecondsPerMicrosecond));
      g_fakeCPUTime = expect_start_time + i;

      // Each trace name should be different to differentiate.
      const char num_char = static_cast<char>('0' + i);
      std::string source_category = category_name + num_char;
      std::string source_trace_name = trace_name + num_char;

      const GpuTracerSource source = static_cast<GpuTracerSource>(i);
      ExpectOutputterBeginMocks(&outputter, source, source_category,
                                source_trace_name);
      ASSERT_TRUE(tracer.Begin(source_category, source_trace_name, source));
    }
    for (int i = 0; i < NUM_TRACER_SOURCES; ++i) {
      // Set times so each source has a different time.
      gl_fake_queries_.SetCurrentGLTime(
          end_timestamp +
          (i * base::Time::kNanosecondsPerMicrosecond));
      g_fakeCPUTime = expect_end_time + i;

      // Each trace name should be different to differentiate.
      const char num_char = static_cast<char>('0' + i);
      std::string source_category = category_name + num_char;
      std::string source_trace_name = trace_name + num_char;

      const bool valid_timer = gpu_timing_client_->IsAvailable();
      const GpuTracerSource source = static_cast<GpuTracerSource>(i);
      ExpectOutputterEndMocks(&outputter, source, source_category,
                              source_trace_name, expect_start_time + i,
                              expect_end_time + i, true, valid_timer);
      // Check if the current category/name are correct for this source.
      ASSERT_EQ(source_category, tracer.CurrentCategory(source));
      ASSERT_EQ(source_trace_name, tracer.CurrentName(source));

      ASSERT_TRUE(tracer.End(source));
    }
    ASSERT_TRUE(tracer.EndDecoding());
    tracer.ProcessTraces();
  }

  void DoOngoingTracerMarkerTest() {
    ExpectTracerOffsetQueryMocks();
    gl_fake_queries_.ExpectGetErrorCalls(*gl_);

    const std::string category_name("trace_category");
    const std::string trace_name("trace_test");
    const GpuTracerSource source = static_cast<GpuTracerSource>(0);
    const int64_t offset_time = 3231;
    const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond;
    const int64_t expect_start_time =
        (start_timestamp / base::Time::kNanosecondsPerMicrosecond) +
        offset_time;
    const bool valid_timer = gpu_timing_client_->IsAvailable();

    FakeCommandBufferServiceBase command_buffer_service;
    FakeDecoderClient client;
    MockOutputter outputter;
    MockGLES2Decoder decoder(&client, &command_buffer_service, &outputter);
    EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
    GPUTracerTester tracer(&decoder);

    // Create trace marker while traces are disabled.
    gl_fake_queries_.SetCurrentGLTime(start_timestamp);
    g_fakeCPUTime = expect_start_time;

    tracer.SetTracingEnabled(false);
    ASSERT_TRUE(tracer.BeginDecoding());
    ASSERT_TRUE(tracer.Begin(category_name, trace_name, source));
    ASSERT_TRUE(tracer.EndDecoding());

    // Enable traces now.
    tracer.SetTracingEnabled(true);
    ExpectTraceQueryMocks();

    // trace should happen when decoding begins, at time start+1.
    gl_fake_queries_.SetCurrentGLTime(
        start_timestamp +
        (1 * base::Time::kNanosecondsPerMicrosecond));
    g_fakeCPUTime = expect_start_time + 1;
    ASSERT_TRUE(tracer.BeginDecoding());

    // End decoding at time start+2.
    ExpectOutputterEndMocks(&outputter, source, category_name, trace_name,
                            expect_start_time + 1, expect_start_time + 2, true,
                            valid_timer);
    gl_fake_queries_.SetCurrentGLTime(
        start_timestamp +
        (2 * base::Time::kNanosecondsPerMicrosecond));
    g_fakeCPUTime = expect_start_time + 2;
    ASSERT_TRUE(tracer.EndDecoding());

    // Begin decoding again at time start+3.
    gl_fake_queries_.SetCurrentGLTime(
        start_timestamp +
        (3 * base::Time::kNanosecondsPerMicrosecond));
    g_fakeCPUTime = expect_start_time + 3;
    ASSERT_TRUE(tracer.BeginDecoding());

    // End trace at time start+4
    gl_fake_queries_.SetCurrentGLTime(
        start_timestamp +
        (4 * base::Time::kNanosecondsPerMicrosecond));
    g_fakeCPUTime = expect_start_time + 4;
    ExpectOutputterEndMocks(&outputter, source, category_name, trace_name,
                            expect_start_time + 3, expect_start_time + 4, true,
                            valid_timer);
    ASSERT_TRUE(tracer.End(source));

    // Increment time before we end decoding to test trace does not stop here.
    gl_fake_queries_.SetCurrentGLTime(
        start_timestamp +
        (5 * base::Time::kNanosecondsPerMicrosecond));
    g_fakeCPUTime = expect_start_time + 5;
    ASSERT_TRUE(tracer.EndDecoding());
    tracer.ProcessTraces();
  }

  void DoDisjointTest() {
    // Cause a disjoint in a middle of a trace and expect no output calls.
    ExpectTracerOffsetQueryMocks();
    gl_fake_queries_.ExpectGetErrorCalls(*gl_);

    const std::string category_name("trace_category");
    const std::string trace_name("trace_test");
    const GpuTracerSource source = static_cast<GpuTracerSource>(0);
    const int64_t offset_time = 3231;
    const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond;
    const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond;
    const int64_t expect_start_time =
        (start_timestamp / base::Time::kNanosecondsPerMicrosecond) +
        offset_time;
    const int64_t expect_end_time =
        (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;

    FakeCommandBufferServiceBase command_buffer_service;
    FakeDecoderClient client;
    MockOutputter outputter;
    MockGLES2Decoder decoder(&client, &command_buffer_service, &outputter);
    EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
    GPUTracerTester tracer(&decoder);
    tracer.SetTracingEnabled(true);

    gl_fake_queries_.SetCurrentGLTime(start_timestamp);
    g_fakeCPUTime = expect_start_time;

    ASSERT_TRUE(tracer.BeginDecoding());

    ExpectTraceQueryMocks();

    ExpectOutputterBeginMocks(&outputter, source, category_name, trace_name);
    ASSERT_TRUE(tracer.Begin(category_name, trace_name, source));

    gl_fake_queries_.SetCurrentGLTime(end_timestamp);
    g_fakeCPUTime = expect_end_time;

    // Create GPUTimingClient to make sure disjoint value is correct. This
    // should not interfere with the tracer's disjoint value.
    scoped_refptr<gl::GPUTimingClient> disjoint_client =
        GetGLContext()->CreateGPUTimingClient();

    // We assert here based on the disjoint_client because if disjoints are not
    // working properly there is no point testing the tracer output.
    ASSERT_FALSE(disjoint_client->CheckAndResetTimerErrors());
    gl_fake_queries_.SetDisjoint();
    ASSERT_TRUE(disjoint_client->CheckAndResetTimerErrors());

    ExpectDisjointOutputMocks(&outputter, expect_start_time, expect_end_time);

    ExpectOutputterEndMocks(&outputter, source, category_name, trace_name,
                            expect_start_time, expect_end_time, true, false);

    ASSERT_TRUE(tracer.End(source));
    ASSERT_TRUE(tracer.EndDecoding());
    tracer.ProcessTraces();
  }

  void DoOutsideDisjointTest() {
    ExpectTracerOffsetQueryMocks();
    gl_fake_queries_.ExpectGetErrorCalls(*gl_);

    const std::string category_name("trace_category");
    const std::string trace_name("trace_test");
    const GpuTracerSource source = static_cast<GpuTracerSource>(0);
    const int64_t offset_time = 3231;
    const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond;
    const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond;
    const int64_t expect_start_time =
        (start_timestamp / base::Time::kNanosecondsPerMicrosecond) +
        offset_time;
    const int64_t expect_end_time =
        (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;

    FakeCommandBufferServiceBase command_buffer_service;
    FakeDecoderClient client;
    MockOutputter outputter;
    MockGLES2Decoder decoder(&client, &command_buffer_service, &outputter);
    EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
    EXPECT_CALL(decoder, MakeCurrent()).WillRepeatedly(Return(true));
    GPUTracerTester tracer(&decoder);

    // Start a trace before tracing is enabled.
    tracer.SetTracingEnabled(false);
    ASSERT_TRUE(tracer.BeginDecoding());
    ASSERT_TRUE(tracer.Begin(category_name, trace_name, source));
    ASSERT_TRUE(tracer.EndDecoding());

    // Enabling traces now, trace should be ongoing.
    tracer.SetTracingEnabled(true);
    gl_fake_queries_.SetCurrentGLTime(start_timestamp);
    g_fakeCPUTime = expect_start_time;

    // Disjoints before we start tracing anything should not do anything.
    ExpectNoDisjointOutputMocks(&outputter);
    gl_fake_queries_.SetDisjoint();

    ExpectTraceQueryMocks();
    ExpectOutputterBeginMocks(&outputter, source, category_name, trace_name);
    ASSERT_TRUE(tracer.BeginDecoding());

    // Set times so each source has a different time.
    gl_fake_queries_.SetCurrentGLTime(end_timestamp);
    g_fakeCPUTime = expect_end_time;

    ExpectOutputterEndMocks(&outputter, source, category_name, trace_name,
                            expect_start_time, expect_end_time, true, true);

    ASSERT_TRUE(tracer.End(source));
    ASSERT_TRUE(tracer.EndDecoding());
    tracer.ProcessTraces();
  }
};

class InvalidTimerTracerTest : public BaseGpuTracerTest {
 public:
  InvalidTimerTracerTest()
      : BaseGpuTracerTest(gl::GPUTiming::kTimerTypeInvalid) {}
};

class GpuEXTTimerTracerTest : public BaseGpuTracerTest {
 public:
  GpuEXTTimerTracerTest() : BaseGpuTracerTest(gl::GPUTiming::kTimerTypeEXT) {}
};

class GpuARBTimerTracerTest : public BaseGpuTracerTest {
 public:
  GpuARBTimerTracerTest() : BaseGpuTracerTest(gl::GPUTiming::kTimerTypeARB) {}
};

class GpuDisjointTimerTracerTest : public BaseGpuTracerTest {
 public:
  GpuDisjointTimerTracerTest()
      : BaseGpuTracerTest(gl::GPUTiming::kTimerTypeDisjoint) {}
};

TEST_F(InvalidTimerTracerTest, InvalidTimerBasicTracerTest) {
  DoBasicTracerTest();
}

TEST_F(GpuEXTTimerTracerTest, EXTTimerBasicTracerTest) {
  DoBasicTracerTest();
}

TEST_F(GpuARBTimerTracerTest, ARBTimerBasicTracerTest) {
  DoBasicTracerTest();
}

TEST_F(GpuDisjointTimerTracerTest, DisjointTimerBasicTracerTest) {
  DoBasicTracerTest();
}

TEST_F(InvalidTimerTracerTest, InvalidTimerDisabledTest) {
  DoDisabledTracingTest();
}

TEST_F(GpuEXTTimerTracerTest, EXTTimerDisabledTest) {
  DoDisabledTracingTest();
}

TEST_F(GpuARBTimerTracerTest, ARBTimerDisabledTest) {
  DoDisabledTracingTest();
}

TEST_F(GpuDisjointTimerTracerTest, DisjointTimerDisabledTest) {
  DoDisabledTracingTest();
}

TEST_F(InvalidTimerTracerTest, InvalidTimerTracerMarkersTest) {
  DoTracerMarkersTest();
}

TEST_F(GpuEXTTimerTracerTest, EXTTimerTracerMarkersTest) {
  DoTracerMarkersTest();
}

TEST_F(GpuARBTimerTracerTest, ARBTimerTracerMarkersTest) {
  DoTracerMarkersTest();
}

TEST_F(GpuDisjointTimerTracerTest, DisjointTimerBasicTracerMarkersTest) {
  DoTracerMarkersTest();
}

TEST_F(InvalidTimerTracerTest, InvalidTimerOngoingTracerMarkersTest) {
  DoOngoingTracerMarkerTest();
}

TEST_F(GpuEXTTimerTracerTest, EXTTimerOngoingTracerMarkersTest) {
  DoOngoingTracerMarkerTest();
}

TEST_F(GpuARBTimerTracerTest, ARBTimerBasicOngoingTracerMarkersTest) {
  DoOngoingTracerMarkerTest();
}

TEST_F(GpuDisjointTimerTracerTest, DisjointTimerOngoingTracerMarkersTest) {
  DoOngoingTracerMarkerTest();
}

TEST_F(GpuDisjointTimerTracerTest, DisjointTimerDisjointTraceTest) {
  DoDisjointTest();
}

TEST_F(GpuDisjointTimerTracerTest, NonrelevantDisjointTraceTest) {
  DoOutsideDisjointTest();
}

class GPUTracerTest : public GpuServiceTest {
 protected:
  void SetUp() override {
    g_fakeCPUTime = 0;
    GpuServiceTest::SetUpWithGLVersion("3.2", "");
    decoder_ = std::make_unique<MockGLES2Decoder>(
        &client_, &command_buffer_service_, &outputter_);
    EXPECT_CALL(*decoder_, GetGLContext())
        .Times(AtMost(1))
        .WillRepeatedly(Return(GetGLContext()));
    tracer_tester_ = std::make_unique<GPUTracerTester>(decoder_.get());
  }

  void TearDown() override {
    tracer_tester_ = nullptr;
    decoder_ = nullptr;
    GpuServiceTest::TearDown();
  }

  FakeCommandBufferServiceBase command_buffer_service_;
  FakeDecoderClient client_;
  MockOutputter outputter_;
  std::unique_ptr<MockGLES2Decoder> decoder_;
  std::unique_ptr<GPUTracerTester> tracer_tester_;
};

TEST_F(GPUTracerTest, IsTracingTest) {
  EXPECT_FALSE(tracer_tester_->IsTracing());
  tracer_tester_->SetTracingEnabled(true);
  EXPECT_TRUE(tracer_tester_->IsTracing());
}
// Test basic functionality of the GPUTracerTester.
TEST_F(GPUTracerTest, DecodeTest) {
  ASSERT_TRUE(tracer_tester_->BeginDecoding());
  EXPECT_FALSE(tracer_tester_->BeginDecoding());
  ASSERT_TRUE(tracer_tester_->EndDecoding());
  EXPECT_FALSE(tracer_tester_->EndDecoding());
}

TEST_F(GPUTracerTest, TraceDuringDecodeTest) {
  const std::string category_name("trace_category");
  const std::string trace_name("trace_test");

  EXPECT_FALSE(
      tracer_tester_->Begin(category_name, trace_name, kTraceCHROMIUM));

  ASSERT_TRUE(tracer_tester_->BeginDecoding());
  EXPECT_TRUE(
      tracer_tester_->Begin(category_name, trace_name, kTraceCHROMIUM));
  ASSERT_TRUE(tracer_tester_->EndDecoding());
}

TEST_F(GpuDisjointTimerTracerTest, MultipleClientsDisjointTest) {
  scoped_refptr<gl::GPUTimingClient> client1 =
      GetGLContext()->CreateGPUTimingClient();
  scoped_refptr<gl::GPUTimingClient> client2 =
      GetGLContext()->CreateGPUTimingClient();

  // Test both clients are initialized as no errors.
  ASSERT_FALSE(client1->CheckAndResetTimerErrors());
  ASSERT_FALSE(client2->CheckAndResetTimerErrors());

  // Issue a disjoint.
  gl_fake_queries_.SetDisjoint();

  ASSERT_TRUE(client1->CheckAndResetTimerErrors());
  ASSERT_TRUE(client2->CheckAndResetTimerErrors());

  // Test both are now reset.
  ASSERT_FALSE(client1->CheckAndResetTimerErrors());
  ASSERT_FALSE(client2->CheckAndResetTimerErrors());

  // Issue a disjoint.
  gl_fake_queries_.SetDisjoint();

  // Test new client disjoint value is cleared.
  scoped_refptr<gl::GPUTimingClient> client3 =
      GetGLContext()->CreateGPUTimingClient();
  ASSERT_TRUE(client1->CheckAndResetTimerErrors());
  ASSERT_TRUE(client2->CheckAndResetTimerErrors());
  ASSERT_FALSE(client3->CheckAndResetTimerErrors());
}

}  // namespace
}  // namespace gles2
}  // namespace gpu
