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

#include <array>
#include <memory>

#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/containers/heap_array.h"
#include "base/memory/raw_ptr.h"
#include "base/process/process.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/gpu_control.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/constants.h"
#include "gpu/command_buffer/common/context_creation_attribs.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "gpu/command_buffer/service/command_buffer_direct.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/gpu_tracer.h"
#include "gpu/command_buffer/service/logger.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/command_buffer/service/shared_image/shared_image_manager.h"
#include "gpu/command_buffer/service/sync_point_manager.h"
#include "gpu/command_buffer/service/transfer_buffer_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_result_reporter.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gl/gl_context_stub.h"
#include "ui/gl/gl_share_group.h"
#include "ui/gl/gl_surface_stub.h"
#include "ui/gl/gl_utils.h"
#include "ui/gl/init/gl_factory.h"

namespace gpu {
namespace {

constexpr int kDefaultRuns = 8;
constexpr int kDefaultIterations = 50000;

// A command buffer that can record and replay commands
// This goes through 3 states, allowing setting up of initial state before
// record/replay a tight loop:
// - kDirect directly sends commands to the service on Flush
// - kRecord doesn't send anything on Flush, but keeps track of the put pointer
// - kReplay allows replaying of commands recorded in the kRecord state
//
// The initial state is kDirect. AdvanceMode is used to transition from one
// state to the next. The transition from kDirect to kRecord requires the
// GetBuffer to have been freed, allowing a fresh start for record.
class RecordReplayCommandBuffer : public CommandBufferDirect {
 public:
  enum Mode { kDirect, kRecord, kReplay };

  RecordReplayCommandBuffer() = default;
  ~RecordReplayCommandBuffer() override = default;

  void AdvanceMode() {
    switch (mode_) {
      case kDirect:
        mode_ = kRecord;
        DCHECK_EQ(current_get_buffer_, -1);
        DCHECK_EQ(service()->GetState().get_offset, 0);
        break;
      case kRecord:
        mode_ = kReplay;
        DCHECK_NE(saved_get_buffer_, -1);
        CommandBufferDirect::SetGetBuffer(saved_get_buffer_);
        break;
      case kReplay:
        mode_ = kDirect;
        break;
    }
  }

  void Flush(int32_t put_offset) override {
    DCHECK_NE(mode_, kReplay);
    if (mode_ == kDirect) {
      CommandBufferDirect::Flush(put_offset);
    } else {
      DCHECK_GE(put_offset, saved_put_offset_);
      saved_put_offset_ = put_offset;
    }
  }

  CommandBuffer::State WaitForTokenInRange(int32_t start,
                                           int32_t end) override {
    DCHECK_EQ(mode_, kDirect);
    return CommandBufferDirect::WaitForTokenInRange(start, end);
  }

  CommandBuffer::State WaitForGetOffsetInRange(uint32_t set_get_buffer_count,
                                               int32_t start,
                                               int32_t end) override {
    DCHECK_EQ(mode_, kDirect);
    return CommandBufferDirect::WaitForGetOffsetInRange(set_get_buffer_count,
                                                        start, end);
  }

  void SetGetBuffer(int32_t transfer_buffer_id) override {
    switch (mode_) {
      case kDirect:
        current_get_buffer_ = transfer_buffer_id;
        CommandBufferDirect::SetGetBuffer(transfer_buffer_id);
        break;
      case kRecord:
        DCHECK_EQ(saved_get_buffer_, -1);
        saved_get_buffer_ = transfer_buffer_id;
        break;
      case kReplay:
        NOTREACHED();
    }
  }

  void OnParseError() override {
    ASSERT_EQ(service()->GetState().error, error::kNoError);
  }

  void Replay() {
    DCHECK_EQ(mode_, kReplay);
    SetGetOffsetForTest(0);
    CommandBufferDirect::Flush(saved_put_offset_);
  }

  int32_t saved_put_offset() const { return saved_put_offset_; }
  Mode mode() const { return mode_; }

 private:
  Mode mode_ = kDirect;
  int32_t saved_put_offset_ = 0;
  int32_t saved_get_buffer_ = -1;
  int32_t current_get_buffer_ = -1;
};

GpuPreferences GetGpuPreferences() {
  GpuPreferences preferences;
  if (gles2::UsePassthroughCommandDecoder(
          base::CommandLine::ForCurrentProcess()))
    preferences.use_passthrough_cmd_decoder = true;
  return preferences;
}

// This wraps a RecordReplayCommandBuffer and gives it a back-end decoder, as
// well as a front-end GLES2Implementation. This allows recording commands at
// the GL level and replaying them to the driver (or a stub).
class RecordReplayContext : public GpuControl {
 public:
  RecordReplayContext()
      : gpu_preferences_(GetGpuPreferences()),
        share_group_(new gl::GLShareGroup),
        translator_cache_(gpu_preferences_) {
    if (base::CommandLine::ForCurrentProcess()->HasSwitch("use-stub")) {
      surface_ = new gl::GLSurfaceStub;
      scoped_refptr<gl::GLContextStub> context_stub =
          new gl::GLContextStub(share_group_.get());
      context_stub->SetGLVersionString("OpenGL ES 3.1");
      context_stub->SetUseStubApi(true);
      context_ = context_stub;
    } else {
      gl::GLContextAttribs attribs;
      if (gpu_preferences_.use_passthrough_cmd_decoder) {
        attribs.allow_client_arrays = false;
      }
      surface_ = gl::init::CreateOffscreenGLSurface(gl::GetDefaultDisplay(),
                                                    gfx::Size());
      context_ = gl::init::CreateGLContext(share_group_.get(), surface_.get(),
                                           attribs);
    }
    context_->MakeCurrent(surface_.get());

    scoped_refptr<gles2::FeatureInfo> feature_info = new gles2::FeatureInfo();
    auto context_group = base::MakeRefCounted<gles2::ContextGroup>(
        gpu_preferences_, /*memory_tracker=*/nullptr, &translator_cache_,
        &completeness_cache_, feature_info,
        /*progress_reporter=*/nullptr, GpuFeatureInfo(),
        &shared_image_manager_);
    command_buffer_ = std::make_unique<RecordReplayCommandBuffer>();

    decoder_ = gles2::GLES2Decoder::Create(command_buffer_.get(),
                                           command_buffer_->service(),
                                           &outputter_, context_group.get());
    command_buffer_->set_handler(decoder_.get());

    decoder_->GetLogger()->set_log_synthesized_gl_errors(false);

    ContextResult result = decoder_->Initialize(
        surface_.get(), context_.get(), /*offscreen=*/true,
        CONTEXT_TYPE_OPENGLES3, /*lose_context_when_out_of_memory=*/false);
    DCHECK_EQ(result, ContextResult::kSuccess);
    capabilities_ = decoder_->GetCapabilities();
    gl_capabilities_ = decoder_->GetGLCapabilities();

    const SharedMemoryLimits limits;
    gles2_helper_ =
        std::make_unique<gles2::GLES2CmdHelper>(command_buffer_.get());
    result = gles2_helper_->Initialize(limits.command_buffer_size);
    DCHECK_EQ(result, ContextResult::kSuccess);

    // Create a transfer buffer.
    transfer_buffer_ = std::make_unique<TransferBuffer>(gles2_helper_.get());

    // Create the object exposing the OpenGL API.
    const bool lose_context_when_out_of_memory = false;
    gles2_implementation_ = std::make_unique<gles2::GLES2Implementation>(
        gles2_helper_.get(), nullptr, transfer_buffer_.get(),
        lose_context_when_out_of_memory, this);

    result = gles2_implementation_->Initialize(limits);
    DCHECK_EQ(result, ContextResult::kSuccess);
  }

  ~RecordReplayContext() override {
    while (command_buffer_->mode() != RecordReplayCommandBuffer::kDirect)
      command_buffer_->AdvanceMode();
    gles2_implementation_.reset();
    transfer_buffer_.reset();
    gles2_helper_.reset();
    decoder_->Destroy(true);
    decoder_.reset();
    command_buffer_.reset();
  }

  void StartRecord() {
    DCHECK_EQ(command_buffer_->mode(), RecordReplayCommandBuffer::kDirect);
    gles2_helper_->FreeRingBuffer();
    command_buffer_->AdvanceMode();
  }

  void WaitExec() { gles2_helper_->Finish(); }

  void StartReplay() {
    DCHECK_EQ(command_buffer_->mode(), RecordReplayCommandBuffer::kRecord);
    gles2_helper_->FlushLazy();
    command_buffer_->AdvanceMode();
  }

  void Replay() { command_buffer_->Replay(); }

  gles2::GLES2Implementation* gl() { return gles2_implementation_.get(); }

 private:
  // GpuControl implementation;
  void SetGpuControlClient(GpuControlClient*) override {}

  const Capabilities& GetCapabilities() const override { return capabilities_; }

  const GLCapabilities& GetGLCapabilities() const override {
    return gl_capabilities_;
  }

  void SignalQuery(uint32_t query, base::OnceClosure callback) override {
    NOTREACHED();
  }

  void CancelAllQueries() override { NOTREACHED(); }

  void CreateGpuFence(uint32_t gpu_fence_id, ClientGpuFence source) override {
    NOTREACHED();
  }

  void GetGpuFence(uint32_t gpu_fence_id,
                   base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)>
                       callback) override {
    NOTREACHED();
  }

  void SetLock(base::Lock*) override { NOTREACHED(); }

  void EnsureWorkVisible() override { NOTREACHED(); }

  gpu::CommandBufferNamespace GetNamespaceID() const override {
    return gpu::CommandBufferNamespace::INVALID;
  }

  CommandBufferId GetCommandBufferID() const override {
    return gpu::CommandBufferId();
  }

  void FlushPendingWork() override { NOTREACHED(); }

  uint64_t GenerateFenceSyncRelease() override { NOTREACHED(); }

  bool IsFenceSyncReleased(uint64_t release) override { NOTREACHED(); }

  void SignalSyncToken(const gpu::SyncToken& sync_token,
                       base::OnceClosure callback) override {
    NOTREACHED();
  }

  void WaitSyncToken(const gpu::SyncToken& sync_token) override {
    NOTREACHED();
  }

  bool CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) override {
    NOTREACHED();
  }

  GpuPreferences gpu_preferences_;

  scoped_refptr<gl::GLShareGroup> share_group_;
  SharedImageManager shared_image_manager_;

  scoped_refptr<gl::GLSurface> surface_;
  scoped_refptr<gl::GLContext> context_;

  gles2::ShaderTranslatorCache translator_cache_;
  gles2::FramebufferCompletenessCache completeness_cache_;

  std::unique_ptr<RecordReplayCommandBuffer> command_buffer_;

  gles2::TraceOutputter outputter_;
  std::unique_ptr<gles2::GLES2Decoder> decoder_;
  gpu::Capabilities capabilities_;
  gpu::GLCapabilities gl_capabilities_;

  std::unique_ptr<gles2::GLES2CmdHelper> gles2_helper_;
  std::unique_ptr<TransferBuffer> transfer_buffer_;
  std::unique_ptr<gles2::GLES2Implementation> gles2_implementation_;
};

// This abstracts the performance capture loop, iterating through a warmup run
// and then a number of performance capturing runs.
class PerfIterator {
 public:
  PerfIterator(std::string story, int runs, int iterations)
      : story_(std::move(story)), runs_(runs), iterations_(iterations) {
    // When running under linux-perf, we try to isolate the microbenchmark
    // performance:
    // 1- sleep 1 second after warmup so that one can skip perf for
    // intitialization with 'perf record -D 1000'
    // 2- exit immediately after the capture loop is finished to skip teardown.
    // 3- avoid unneeded syscalls (time, print).
    for_linux_perf_ =
        base::CommandLine::ForCurrentProcess()->HasSwitch("for-linux-perf");
    if (base::CommandLine::ForCurrentProcess()->HasSwitch("fast-run")) {
      runs_ = 1;
      iterations_ = 100;
    }
  }

  PerfIterator(const PerfIterator&) = delete;
  PerfIterator& operator=(const PerfIterator&) = delete;

  bool Iterate() {
    if (--current_iterations_ > 0)
      return true;
    return NextOuter();
  }

 private:
  bool NextOuter() {
    base::TimeTicks time;
    if (warmup_) {
      warmup_ = false;
      if (for_linux_perf_)
        base::PlatformThread::Sleep(base::Seconds(1));
      else
        time = base::TimeTicks::Now();
    } else if (!for_linux_perf_) {
      time = base::TimeTicks::Now();
      double ns = (time - run_start_time_).InNanoseconds() / iterations_;
      perf_test::PerfResultReporter reporter("Decoder.", story_);
      reporter.RegisterImportantMetric("draw_wall_time", "ns");
      reporter.AddResult("draw_wall_time", ns);
    }
    if (runs_ == 0) {
      if (for_linux_perf_)
        base::Process::TerminateCurrentProcessImmediately(0);
      return false;
    }
    --runs_;
    current_iterations_ = iterations_;
    run_start_time_ = time;
    return true;
  }

  static constexpr int kWarmupIterations = 2;

  std::string story_;
  base::TimeTicks run_start_time_;
  int runs_;
  int iterations_;
  int current_iterations_ = 1 + kWarmupIterations;
  bool warmup_ = true;
  bool for_linux_perf_ = false;
};

class DecoderPerfTest : public testing::Test {
 public:
  ~DecoderPerfTest() override = default;

  void SetUp() override {
    context_ = std::make_unique<RecordReplayContext>();
    gl_ = context_->gl();
    gl_->GenRenderbuffers(1, &renderbuffer_);
    gl_->BindRenderbuffer(GL_RENDERBUFFER, renderbuffer_);
    gl_->RenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 256, 256);
    gl_->GenFramebuffers(1, &framebuffer_);
    gl_->BindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
    gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                 GL_RENDERBUFFER, renderbuffer_);
    gl_->Viewport(0, 0, 256, 256);
  }

  void StartRecord() { context_->StartRecord(); }

  void StartReplay() { context_->StartReplay(); }

  void WaitExec() { context_->WaitExec(); }

  void Replay() { context_->Replay(); }

  GLuint CompileShader(GLenum type, const char* source) {
    GLuint shader = gl_->CreateShader(type);
    GLint length = base::checked_cast<GLint>(strlen(source));
    gl_->ShaderSource(shader, 1, &source, &length);
    gl_->CompileShader(shader);
    GLint compile_status = 0;
    gl_->GetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
    if (!compile_status) {
      GLint log_length = 0;
      gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
      if (log_length) {
        auto log = base::HeapArray<GLchar>::WithSize(log_length);
        GLsizei returned_log_length = 0;
        gl_->GetShaderInfoLog(shader, log_length, &returned_log_length,
                              log.data());
        LOG(ERROR) << std::string(log.data(), returned_log_length);
      }
      gl_->DeleteShader(shader);
      return 0;
    }
    return shader;
  }

  struct AttribBinding {
    const char* name;
    GLuint location;
  };

  GLuint CreateAndLinkProgram(
      const char* vertex_shader,
      const char* fragment_shader,
      const std::initializer_list<AttribBinding>& attrib_bindings) {
    GLuint program = gl_->CreateProgram();
    GLuint vshader = CompileShader(GL_VERTEX_SHADER, vertex_shader);
    DCHECK_NE(0u, vshader);
    gl_->AttachShader(program, vshader);
    gl_->DeleteShader(vshader);
    GLuint fshader = CompileShader(GL_FRAGMENT_SHADER, fragment_shader);
    DCHECK_NE(0u, fshader);
    gl_->AttachShader(program, fshader);
    gl_->DeleteShader(fshader);
    for (const auto& attrib : attrib_bindings)
      gl_->BindAttribLocation(program, attrib.location, attrib.name);
    gl_->LinkProgram(program);
    GLint link_status = 0;
    gl_->GetProgramiv(program, GL_LINK_STATUS, &link_status);
    DCHECK_EQ(link_status, GL_TRUE);
    return program;
  }

  void CreateBasicTexture(GLuint texture) {
    gl_->BindTexture(GL_TEXTURE_2D, texture);
    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA,
                    GL_UNSIGNED_BYTE, nullptr);
  }

 protected:
  std::unique_ptr<RecordReplayContext> context_;
  raw_ptr<gles2::GLES2Implementation> gl_;
  GLuint renderbuffer_ = 0;
  GLuint framebuffer_ = 0;
};

constexpr const char kVertexShader[] =
    "attribute vec2 position;\n"
    "uniform vec2 scale;\n"
    "uniform vec2 offset;\n"
    "varying vec2 texcoords;\n"
    "void main () {\n"
    "  gl_Position = vec4(position * scale + offset, 0.0, 1.0);\n"
    "  texcoords = position;\n"
    "}\n";

constexpr const char kFragmentShader[] =
    "precision mediump float;\n"
    "varying vec2 texcoords;\n"
    "uniform sampler2D texture;\n"
    "void main() {\n"
    "  gl_FragColor = texture2D(texture, texcoords);\n"
    "}\n";

constexpr const float kVertices[] = {
    0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f,
};

// Measures a loop with Uniform2f and DrawArrays.
TEST_F(DecoderPerfTest, BasicDraw) {
  GLuint program =
      CreateAndLinkProgram(kVertexShader, kFragmentShader, {{"postition", 0}});
  gl_->UseProgram(program);

  GLint scale_location = gl_->GetUniformLocation(program, "scale");
  GLint offset_location = gl_->GetUniformLocation(program, "offset");
  GLint texture_location = gl_->GetUniformLocation(program, "texture");

  GLuint texture;
  gl_->GenTextures(1, &texture);
  CreateBasicTexture(texture);

  GLuint buffer;
  gl_->GenBuffers(1, &buffer);
  gl_->BindBuffer(GL_ARRAY_BUFFER, buffer);
  gl_->BufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices,
                  GL_STATIC_DRAW);

  gl_->VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat),
                           nullptr);
  gl_->EnableVertexAttribArray(0);

  gl_->Uniform1i(texture_location, 0);

  constexpr int N = 10;
  gl_->Uniform2f(scale_location, 2.f / N, 2.f / N);

  StartRecord();
  for (int x = 0; x < N; ++x) {
    float xpos = 2.f * x / N - 1.f;
    for (int y = 0; y < N; ++y) {
      float ypos = 2.f * y / N - 1.f;
      gl_->Uniform2f(offset_location, xpos, ypos);
      gl_->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
  }

  StartReplay();
  PerfIterator iterator("basic_draw_100", kDefaultRuns, kDefaultIterations);
  while (iterator.Iterate())
    Replay();
}

// Measures a loop with changing the texture binding between draws.
TEST_F(DecoderPerfTest, TextureDraw) {
  GLuint program =
      CreateAndLinkProgram(kVertexShader, kFragmentShader, {{"position", 0}});
  gl_->UseProgram(program);

  GLint scale_location = gl_->GetUniformLocation(program, "scale");
  GLint offset_location = gl_->GetUniformLocation(program, "offset");
  GLint texture_location = gl_->GetUniformLocation(program, "texture");

  constexpr size_t kTextures = 16;
  GLuint textures[kTextures];
  gl_->GenTextures(kTextures, textures);
  for (GLuint texture : textures)
    CreateBasicTexture(texture);

  GLuint buffer;
  gl_->GenBuffers(1, &buffer);
  gl_->BindBuffer(GL_ARRAY_BUFFER, buffer);
  gl_->BufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices,
                  GL_STATIC_DRAW);

  gl_->VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat),
                           nullptr);
  gl_->EnableVertexAttribArray(0);

  gl_->Uniform1i(texture_location, 0);

  constexpr int N = 10;
  gl_->Uniform2f(scale_location, 2.f / N, 2.f / N);

  StartRecord();
  size_t texture = 0;
  for (int x = 0; x < N; ++x) {
    float xpos = 2.f * x / N - 1.f;
    for (int y = 0; y < N; ++y) {
      float ypos = 2.f * y / N - 1.f;
      gl_->BindTexture(GL_TEXTURE_2D, UNSAFE_TODO(textures[texture]));
      gl_->Uniform2f(offset_location, xpos, ypos);
      gl_->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
      texture = (texture + 1) % kTextures;
    }
  }

  StartReplay();
  PerfIterator iterator("texture_draw_100", kDefaultRuns, kDefaultIterations);
  while (iterator.Iterate())
    Replay();
}

// Measures a loop with changing the program between draws.
TEST_F(DecoderPerfTest, ProgramDraw) {
  const char kVertexShader2[] =
      "attribute vec2 position;\n"
      "uniform vec2 scale;\n"
      "uniform vec2 offset;\n"
      "void main () {\n"
      "  gl_Position = vec4(position * scale + offset, 0.0, 1.0);\n"
      "}\n";

  const char kFragmentShader2[] =
      "precision mediump float;\n"
      "uniform vec4 color;\n"
      "void main() {\n"
      "  gl_FragColor = color;\n"
      "}\n";

  std::array<GLuint, 2> programs;
  programs[0] =
      CreateAndLinkProgram(kVertexShader, kFragmentShader, {{"position", 0}});

  GLint scale_location1 = gl_->GetUniformLocation(programs[0], "scale");
  GLint texture_location1 = gl_->GetUniformLocation(programs[0], "texture");

  programs[1] =
      CreateAndLinkProgram(kVertexShader2, kFragmentShader2, {{"position", 0}});

  GLint scale_location2 = gl_->GetUniformLocation(programs[1], "scale");
  GLint color_location2 = gl_->GetUniformLocation(programs[1], "color");

  GLuint texture;
  gl_->GenTextures(1, &texture);
  CreateBasicTexture(texture);

  GLuint buffer;
  gl_->GenBuffers(1, &buffer);
  gl_->BindBuffer(GL_ARRAY_BUFFER, buffer);
  gl_->BufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices,
                  GL_STATIC_DRAW);

  gl_->VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat),
                           nullptr);
  gl_->EnableVertexAttribArray(0);

  constexpr int N = 10;

  gl_->UseProgram(programs[0]);

  gl_->Uniform1i(texture_location1, 0);
  gl_->Uniform2f(scale_location1, 2.f / N, 2.f / N);

  gl_->UseProgram(programs[1]);
  gl_->Uniform2f(scale_location2, 2.f / N, 2.f / N);
  gl_->Uniform4f(color_location2, 1.f, 0.f, 0.f, 1.f);

  std::array<GLint, 2> offset_locations = {
      gl_->GetUniformLocation(programs[0], "offset"),
      gl_->GetUniformLocation(programs[1], "offset")};

  StartRecord();
  size_t program = 0;
  for (int x = 0; x < N; ++x) {
    float xpos = 2.f * x / N - 1.f;
    for (int y = 0; y < N; ++y) {
      float ypos = 2.f * y / N - 1.f;
      gl_->UseProgram(programs[program]);
      gl_->Uniform2f(offset_locations[program], xpos, ypos);
      gl_->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
      program = 1 - program;
    }
  }
  WaitExec();

  StartReplay();
  PerfIterator iterator("program_draw_100", kDefaultRuns, kDefaultIterations);
  while (iterator.Iterate())
    Replay();
}

}  // anonymous namespace
}  // namespace gpu
