// Copyright 2017 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 "base/command_line.h"
#include "base/process/process.h"
#include "base/threading/platform_thread.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/image_manager.h"
#include "gpu/command_buffer/service/logger.h"
#include "gpu/command_buffer/service/mailbox_manager_impl.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "gpu/command_buffer/service/passthrough_discardable_manager.h"
#include "gpu/command_buffer/service/service_discardable_manager.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/command_buffer/service/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_test.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/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 };

  explicit RecordReplayCommandBuffer(
      TransferBufferManager* transfer_buffer_manager)
      : CommandBufferDirect(transfer_buffer_manager) {}

  ~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();
        break;
    }
  }

  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_) {
    bool bind_generates_resource = false;
    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.bind_generates_resource = bind_generates_resource;
      surface_ = gl::init::CreateOffscreenGLSurface(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();
    scoped_refptr<gles2::ContextGroup> context_group = new gles2::ContextGroup(
        gpu_preferences_, true, &mailbox_manager_, nullptr /* memory_tracker */,
        &translator_cache_, &completeness_cache_, feature_info,
        bind_generates_resource, &image_manager_, nullptr /* image_factory */,
        nullptr /* progress_reporter */, GpuFeatureInfo(),
        &discardable_manager_, &passthrough_discardable_manager_,
        &shared_image_manager_);
    command_buffer_.reset(new RecordReplayCommandBuffer(
        context_group->transfer_buffer_manager()));

    decoder_.reset(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);

    ContextCreationAttribs attrib_helper;
    attrib_helper.offscreen_framebuffer_size = gfx::Size(16, 16);
    attrib_helper.red_size = 8;
    attrib_helper.green_size = 8;
    attrib_helper.blue_size = 8;
    attrib_helper.alpha_size = 8;
    attrib_helper.depth_size = 0;
    attrib_helper.stencil_size = 0;
    attrib_helper.context_type = CONTEXT_TYPE_OPENGLES3;

    ContextResult result =
        decoder_->Initialize(surface_.get(), context_.get(), true,
                             gles2::DisallowedFeatures(), attrib_helper);
    DCHECK_EQ(result, ContextResult::kSuccess);
    capabilities_ = decoder_->GetCapabilities();

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

    // Create a transfer buffer.
    transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get()));

    // Create the object exposing the OpenGL API.
    const bool lose_context_when_out_of_memory = false;
    const bool support_client_side_arrays = false;
    gles2_implementation_.reset(new gles2::GLES2Implementation(
        gles2_helper_.get(), nullptr, transfer_buffer_.get(),
        bind_generates_resource, lose_context_when_out_of_memory,
        support_client_side_arrays, 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();
    command_buffer_.reset();
    decoder_->Destroy(true);
    decoder_.reset();
  }

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

  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_; }

  int32_t CreateImage(ClientBuffer buffer,
                      size_t width,
                      size_t height) override {
    NOTIMPLEMENTED();
    return -1;
  }

  void DestroyImage(int32_t id) override { NOTIMPLEMENTED(); }

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

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

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

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

  void EnsureWorkVisible() override {}

  gpu::CommandBufferNamespace GetNamespaceID() const override {
    return command_buffer_->GetNamespaceID();
  }

  CommandBufferId GetCommandBufferID() const override {
    return command_buffer_->GetCommandBufferID();
  }

  void FlushPendingWork() override {}

  uint64_t GenerateFenceSyncRelease() override {
    NOTIMPLEMENTED();
    return 0;
  }

  bool IsFenceSyncReleased(uint64_t release) override {
    NOTIMPLEMENTED();
    return true;
  }

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

  void WaitSyncTokenHint(const gpu::SyncToken& sync_token) override {}

  bool CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) override {
    NOTIMPLEMENTED();
    return true;
  }

  GpuPreferences gpu_preferences_;

  gles2::MailboxManagerImpl mailbox_manager_;
  scoped_refptr<gl::GLShareGroup> share_group_;
  gles2::ImageManager image_manager_;
  ServiceDiscardableManager discardable_manager_;
  PassthroughDiscardableManager passthrough_discardable_manager_;
  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_;

  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 name, int runs, int iterations)
      : name_(std::move(name)), 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;
    }
  }

  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::TimeDelta::FromSeconds(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::PrintResult(name_, "", "wall_time", ns, "ns", true);
    }
    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 name_;
  base::TimeTicks run_start_time_;
  int runs_;
  int iterations_;
  int current_iterations_ = 1 + kWarmupIterations;
  bool warmup_ = true;
  bool for_linux_perf_ = false;

  DISALLOW_COPY_AND_ASSIGN(PerfIterator);
};

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 TearDown() override { context_.reset(); }

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

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

  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) {
        std::unique_ptr<GLchar[]> log(new GLchar[log_length]);
        GLsizei returned_log_length = 0;
        gl_->GetShaderInfoLog(shader, log_length, &returned_log_length,
                              log.get());
        LOG(ERROR) << std::string(log.get(), 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_;
  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("decoder_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, textures[texture]);
      gl_->Uniform2f(offset_location, xpos, ypos);
      gl_->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
      texture = (texture + 1) % kTextures;
    }
  }

  StartReplay();
  PerfIterator iterator("decoder_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";

  GLuint programs[2];
  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);

  GLint offset_locations[2] = {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;
    }
  }

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

}  // anonymous namespace
}  // namespace gpu
