// Copyright (c) 2012 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 "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"

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

#include "base/command_line.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "gpu/command_buffer/common/gles2_cmd_format.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/context_state.h"
#include "gpu/command_buffer/service/gl_stream_texture_image_stub.h"
#include "gpu/command_buffer/service/gl_surface_mock.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/image_manager.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/mocks.h"
#include "gpu/command_buffer/service/program_manager.h"
#include "gpu/command_buffer/service/test_helper.h"
#include "gpu/command_buffer/service/validating_abstract_texture_impl.h"
#include "gpu/config/gpu_switches.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_image_stub.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_mock.h"
#include "ui/gl/gl_surface_stub.h"
#include "ui/gl/gpu_timing_fake.h"
#include "ui/gl/scoped_make_current.h"

#if !defined(GL_DEPTH24_STENCIL8)
#define GL_DEPTH24_STENCIL8 0x88F0
#endif

using ::gl::MockGLInterface;
using ::testing::_;
using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::MatcherCast;
using ::testing::Mock;
using ::testing::Pointee;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SetArrayArgument;
using ::testing::SetArgPointee;
using ::testing::StrEq;
using ::testing::StrictMock;

namespace gpu {
namespace gles2 {

using namespace cmds;

void GLES2DecoderRGBBackbufferTest::SetUp() {
  InitState init;
  init.bind_generates_resource = true;
  InitDecoder(init);
  SetupDefaultProgram();
}

void GLES2DecoderManualInitTest::EnableDisableTest(GLenum cap,
                                                   bool enable,
                                                   bool expect_set) {
  if (expect_set) {
    SetupExpectationsForEnableDisable(cap, enable);
  }
  if (enable) {
    Enable cmd;
    cmd.Init(cap);
    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    EXPECT_EQ(GL_NO_ERROR, GetGLError());
  } else {
    Disable cmd;
    cmd.Init(cap);
    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    EXPECT_EQ(GL_NO_ERROR, GetGLError());
  }
}


TEST_P(GLES3DecoderTest, Basic) {
  // Make sure the setup is correct for ES3.
  EXPECT_TRUE(feature_info()->IsWebGL2OrES3Context());
  EXPECT_FALSE(feature_info()->IsWebGLContext());
  EXPECT_TRUE(feature_info()->validators()->texture_bind_target.IsValid(
      GL_TEXTURE_3D));
}

TEST_P(WebGL2DecoderTest, Basic) {
  // Make sure the setup is correct for WebGL2.
  EXPECT_TRUE(feature_info()->IsWebGL2OrES3Context());
  EXPECT_TRUE(feature_info()->IsWebGLContext());
  EXPECT_TRUE(feature_info()->validators()->texture_bind_target.IsValid(
      GL_TEXTURE_3D));
}

TEST_P(GLES2DecoderTest, InvalidCommand) {
  cmd::Noop cmd;
  cmd.header.Init(gles2::kNumCommands, 1);
  EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, 0));
}

TEST_P(GLES2DecoderTest, GetIntegervCached) {
  struct TestInfo {
    GLenum pname;
    GLint expected;
  };
  TestInfo tests[] = {
      {
       GL_MAX_TEXTURE_SIZE, TestHelper::kMaxTextureSize,
      },
      {
       GL_MAX_CUBE_MAP_TEXTURE_SIZE, TestHelper::kMaxCubeMapTextureSize,
      },
      {
       GL_MAX_RENDERBUFFER_SIZE, TestHelper::kMaxRenderbufferSize,
      },
  };
  typedef GetIntegerv::Result Result;
  for (size_t ii = 0; ii < sizeof(tests) / sizeof(tests[0]); ++ii) {
    const TestInfo& test = tests[ii];
    Result* result = static_cast<Result*>(shared_memory_address_);
    EXPECT_CALL(*gl_, GetError())
        .WillOnce(Return(GL_NO_ERROR))
        .WillOnce(Return(GL_NO_ERROR))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl_, GetIntegerv(test.pname, _)).Times(0);
    result->size = 0;
    GetIntegerv cmd2;
    cmd2.Init(test.pname, shared_memory_id_, shared_memory_offset_);
    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
    EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(test.pname),
              result->GetNumResults());
    EXPECT_EQ(GL_NO_ERROR, GetGLError());
    EXPECT_EQ(test.expected, result->GetData()[0]);
  }
}

TEST_P(GLES2DecoderWithShaderTest, GetMaxValueInBufferCHROMIUM) {
  SetupIndexBuffer();
  GetMaxValueInBufferCHROMIUM::Result* result =
      static_cast<GetMaxValueInBufferCHROMIUM::Result*>(shared_memory_address_);
  *result = 0;

  GetMaxValueInBufferCHROMIUM cmd;
  cmd.Init(client_element_buffer_id_, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
           kValidIndexRangeStart * 2, shared_memory_id_, kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(7u, *result);
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
           GL_UNSIGNED_SHORT, kValidIndexRangeStart * 2, shared_memory_id_,
           kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(100u, *result);
  EXPECT_EQ(GL_NO_ERROR, GetGLError());

  cmd.Init(kInvalidClientId, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
           kValidIndexRangeStart * 2, shared_memory_id_, kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
  cmd.Init(client_element_buffer_id_, kOutOfRangeIndexRangeEnd,
           GL_UNSIGNED_SHORT, kValidIndexRangeStart * 2, shared_memory_id_,
           kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
  cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
           GL_UNSIGNED_SHORT, kOutOfRangeIndexRangeEnd * 2, shared_memory_id_,
           kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
  cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
           GL_UNSIGNED_SHORT, kValidIndexRangeStart * 2, shared_memory_id_,
           kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  cmd.Init(client_buffer_id_, kValidIndexRangeCount + 1, GL_UNSIGNED_SHORT,
           kValidIndexRangeStart * 2, shared_memory_id_, kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
  cmd.Init(client_element_buffer_id_,
           kValidIndexRangeCount + 1,
           GL_UNSIGNED_SHORT,
           kValidIndexRangeStart * 2,
           kInvalidSharedMemoryId,
           kSharedMemoryOffset);
  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
  cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
           GL_UNSIGNED_SHORT, kValidIndexRangeStart * 2, shared_memory_id_,
           kInvalidSharedMemoryOffset);
  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
}

TEST_P(GLES2DecoderTest, IsBuffer) {
  EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
  DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
  EXPECT_TRUE(DoIsBuffer(client_buffer_id_));
  EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, 0))
      .Times(1)
      .RetiresOnSaturation();
  DoDeleteBuffer(client_buffer_id_, kServiceBufferId);
  EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
}

TEST_P(GLES2DecoderTest, IsFramebuffer) {
  EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
  DoBindFramebuffer(
      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
  EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_));
  DoDeleteFramebuffer(client_framebuffer_id_,
                      kServiceFramebufferId,
                      true,
                      GL_FRAMEBUFFER,
                      0,
                      true,
                      GL_FRAMEBUFFER,
                      0);
  EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
}

TEST_P(GLES2DecoderTest, IsProgram) {
  // IsProgram is true as soon as the program is created.
  EXPECT_TRUE(DoIsProgram(client_program_id_));
  EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
      .Times(1)
      .RetiresOnSaturation();
  DoDeleteProgram(client_program_id_, kServiceProgramId);
  EXPECT_FALSE(DoIsProgram(client_program_id_));
}

TEST_P(GLES2DecoderTest, IsRenderbuffer) {
  EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
  DoBindRenderbuffer(
      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
  EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_));
  DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
  EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
}

TEST_P(GLES2DecoderTest, IsShader) {
  // IsShader is true as soon as the program is created.
  EXPECT_TRUE(DoIsShader(client_shader_id_));
  DoDeleteShader(client_shader_id_, kServiceShaderId);
  EXPECT_FALSE(DoIsShader(client_shader_id_));
}

TEST_P(GLES2DecoderTest, IsTexture) {
  EXPECT_FALSE(DoIsTexture(client_texture_id_));
  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
  EXPECT_TRUE(DoIsTexture(client_texture_id_));
  DoDeleteTexture(client_texture_id_, kServiceTextureId);
  EXPECT_FALSE(DoIsTexture(client_texture_id_));
}

TEST_P(GLES2DecoderTest, TestImageBindingForDecoderManagement) {
  const GLuint service_id = 123;
  EXPECT_CALL(*gl_, GenTextures(1, _))
      .Times(1)
      .WillOnce(SetArgPointee<1>(service_id))
      .RetiresOnSaturation();
  const GLenum target = GL_TEXTURE_EXTERNAL_OES;
  std::unique_ptr<AbstractTexture> abstract_texture =
      GetDecoder()->CreateAbstractTexture(target, GL_RGBA, 256, /* width */
                                          256,                  /* height */
                                          1,                    /* depth */
                                          0,                    /* border */
                                          GL_RGBA, GL_UNSIGNED_BYTE);
  scoped_refptr<gl::GLImage> image(new gl::GLImageStub);
  abstract_texture->BindImage(image.get(), GetParam());
  ValidatingAbstractTextureImpl* validating_texture =
      static_cast<ValidatingAbstractTextureImpl*>(abstract_texture.get());
  TextureRef* texture_ref = validating_texture->GetTextureRefForTesting();
  Texture::ImageState state;
  EXPECT_EQ(texture_ref->texture()->GetLevelImage(target, 0, &state),
            image.get());
  EXPECT_EQ(state, GetParam() ? Texture::ImageState::BOUND
                              : Texture::ImageState::UNBOUND);

  EXPECT_CALL(*gl_, DeleteTextures(1, _)).Times(1).RetiresOnSaturation();
  abstract_texture.reset();
}

TEST_P(GLES2DecoderTest, CreateAbstractTexture) {
  const GLuint service_id = 123;
  EXPECT_CALL(*gl_, GenTextures(1, _))
      .Times(1)
      .WillOnce(SetArgPointee<1>(service_id))
      .RetiresOnSaturation();
  const GLenum target = GL_TEXTURE_EXTERNAL_OES;
  std::unique_ptr<AbstractTexture> abstract_texture =
      GetDecoder()->CreateAbstractTexture(target, GL_RGBA, 256, /* width */
                                          256,                  /* height */
                                          1,                    /* depth */
                                          0,                    /* border */
                                          GL_RGBA, GL_UNSIGNED_BYTE);
  EXPECT_EQ(abstract_texture->GetTextureBase()->target(), target);
  EXPECT_EQ(abstract_texture->service_id(), service_id);
  Texture* texture = Texture::CheckedCast(abstract_texture->GetTextureBase());
  EXPECT_EQ(texture->SafeToRenderFrom(), false);

  // Set some parameters, and verify that we set them.
  // These three are for ScopedTextureBinder.
  // TODO(liberato): Is there a way to make this less brittle?
  EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(1).RetiresOnSaturation();
  EXPECT_CALL(*gl_, BindTexture(target, _)).Times(1).RetiresOnSaturation();
  EXPECT_CALL(*gl_, BindTexture(target, abstract_texture->service_id()))
      .Times(1)
      .RetiresOnSaturation();

  // This one we actually care about.
  EXPECT_CALL(*gl_, TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
  abstract_texture->SetParameteri(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  EXPECT_EQ(texture->min_filter(), static_cast<GLenum>(GL_LINEAR));

  // Attach an image and see if it works.
  scoped_refptr<gl::GLImage> image(new gl::GLImageStub);
  abstract_texture->BindImage(image.get(), true);
  EXPECT_EQ(abstract_texture->GetImage(), image.get());
  // Binding an image should make the texture renderable.
  EXPECT_EQ(texture->SafeToRenderFrom(), true);
  EXPECT_EQ(texture->GetLevelImage(target, 0), image.get());

  // Unbinding should make it not renderable.
  abstract_texture->BindImage(nullptr, false);
  EXPECT_EQ(texture->SafeToRenderFrom(), false);
  EXPECT_EQ(abstract_texture->GetImage(), nullptr);

  // Attach a stream image, and verify that the image changes and the service_id
  // matches the one we provide.
  scoped_refptr<gpu::gles2::GLStreamTextureImage> stream_image(
      new gpu::gles2::GLStreamTextureImageStub);
  const GLuint surface_texture_service_id = service_id + 1;
  abstract_texture->BindStreamTextureImage(stream_image.get(),
                                           surface_texture_service_id);
  EXPECT_EQ(texture->SafeToRenderFrom(), true);
  EXPECT_EQ(texture->GetLevelStreamTextureImage(target, 0), stream_image.get());
  EXPECT_EQ(abstract_texture->service_id(), surface_texture_service_id);

  // Deleting |abstract_texture| should delete the platform texture as well,
  // since we haven't make a copy of the TextureRef.  Also make sure that the
  // cleanup CB is called.
  EXPECT_CALL(*gl_, DeleteTextures(1, _)).Times(1).RetiresOnSaturation();
  bool cleanup_flag = false;
  abstract_texture->SetCleanupCallback(base::BindOnce(
      [](bool* flag, AbstractTexture*) { *flag = true; }, &cleanup_flag));
  abstract_texture.reset();
  EXPECT_TRUE(cleanup_flag);
}

TEST_P(GLES2DecoderTest, AbstractTextureIsDestroyedWithDecoder) {
  // Deleting the decoder should delete the AbstractTexture's TextureRef.
  const GLuint service_id = 123;
  EXPECT_CALL(*gl_, GenTextures(1, _))
      .Times(1)
      .WillOnce(SetArgPointee<1>(service_id))
      .RetiresOnSaturation();
  const GLenum target = GL_TEXTURE_EXTERNAL_OES;
  std::unique_ptr<AbstractTexture> abstract_texture =
      GetDecoder()->CreateAbstractTexture(target, GL_RGBA, 256, /* width */
                                          256,                  /* height */
                                          1,                    /* depth */
                                          0,                    /* border */
                                          GL_RGBA, GL_UNSIGNED_BYTE);
  bool cleanup_flag = false;
  abstract_texture->SetCleanupCallback(base::BindOnce(
      [](bool* flag, AbstractTexture*) { *flag = true; }, &cleanup_flag));

  // There is only one TextureRef, so it should delete the platform texture.  It
  // should also call the cleanup cb.
  EXPECT_CALL(*gl_, DeleteTextures(1, _)).Times(1).RetiresOnSaturation();
  ResetDecoder();
  // The texture should no longer have a TextureRef.
  EXPECT_EQ(abstract_texture->GetTextureBase(), nullptr);
  EXPECT_TRUE(cleanup_flag);
}

TEST_P(GLES2DecoderTest, AbstractTextureIsDestroyedWhenMadeCurrent) {
  // When an AbstractTexture is destroyed, the ref will be dropped by the next
  // call to MakeCurrent if the context isn't already current.
  const GLuint service_id = 123;
  EXPECT_CALL(*gl_, GenTextures(1, _))
      .Times(1)
      .WillOnce(SetArgPointee<1>(service_id))
      .RetiresOnSaturation();
  const GLenum target = GL_TEXTURE_EXTERNAL_OES;
  std::unique_ptr<AbstractTexture> abstract_texture =
      GetDecoder()->CreateAbstractTexture(target, GL_RGBA, 256, /* width */
                                          256,                  /* height */
                                          1,                    /* depth */
                                          0,                    /* border */
                                          GL_RGBA, GL_UNSIGNED_BYTE);

  // Make the context not current, so that it's not destroyed immediately.
  context_->ReleaseCurrent(surface_.get());
  abstract_texture.reset();
  // Make the context current again, |context_| overrides it with a mock.
  context_->GLContextStub::MakeCurrent(surface_.get());

  // Having textures to delete should signal idle work.
  EXPECT_EQ(GetDecoder()->HasMoreIdleWork(), true);
  EXPECT_CALL(*gl_, DeleteTextures(1, _)).Times(1).RetiresOnSaturation();

  // Allow the context to be made current.
  EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(true));
  GetDecoder()->MakeCurrent();
}

TEST_P(GLES2DecoderTest, AbstractTextureIsDestroyedIfAlreadyCurrent) {
  // When an AbstractTexture is destroyed, the ref will be dropped immediately
  // if the context is current.
  const GLuint service_id = 123;
  EXPECT_CALL(*gl_, GenTextures(1, _))
      .Times(1)
      .WillOnce(SetArgPointee<1>(service_id))
      .RetiresOnSaturation();
  const GLenum target = GL_TEXTURE_EXTERNAL_OES;
  std::unique_ptr<AbstractTexture> abstract_texture =
      GetDecoder()->CreateAbstractTexture(target, GL_RGBA, 256, /* width */
                                          256,                  /* height */
                                          1,                    /* depth */
                                          0,                    /* border */
                                          GL_RGBA, GL_UNSIGNED_BYTE);

  EXPECT_CALL(*gl_, DeleteTextures(1, _)).Times(1).RetiresOnSaturation();
  abstract_texture.reset();
  EXPECT_EQ(GetDecoder()->HasMoreIdleWork(), false);
}

TEST_P(GLES2DecoderTest, TestAbstractTextureSetClearedWorks) {
  const GLuint service_id = 123;
  EXPECT_CALL(*gl_, GenTextures(1, _))
      .Times(1)
      .WillOnce(SetArgPointee<1>(service_id))
      .RetiresOnSaturation();
  const GLenum target = GL_TEXTURE_2D;
  std::unique_ptr<AbstractTexture> abstract_texture =
      GetDecoder()->CreateAbstractTexture(target, GL_RGBA, 256, /* width */
                                          256,                  /* height */
                                          1,                    /* depth */
                                          0,                    /* border */
                                          GL_RGBA, GL_UNSIGNED_BYTE);
  Texture* texture = Texture::CheckedCast(abstract_texture->GetTextureBase());

  // Texture should start off unrenderable.
  EXPECT_EQ(texture->SafeToRenderFrom(), false);

  // Setting it to be cleared should make it renderable.
  abstract_texture->SetCleared();
  EXPECT_EQ(texture->SafeToRenderFrom(), true);

  EXPECT_CALL(*gl_, DeleteTextures(1, _)).Times(1).RetiresOnSaturation();
  abstract_texture.reset();
}

TEST_P(GLES3DecoderTest, GetInternalformativValidArgsSamples) {
  const GLint kNumSampleCounts = 8;
  typedef GetInternalformativ::Result Result;
  Result* result = static_cast<Result*>(shared_memory_address_);
  EXPECT_CALL(*gl_, GetInternalformativ(GL_RENDERBUFFER, GL_RGBA8,
                                        GL_NUM_SAMPLE_COUNTS, 1, _))
      .WillOnce(SetArgPointee<4>(kNumSampleCounts))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl_, GetInternalformativ(GL_RENDERBUFFER, GL_RGBA8,
                                        GL_SAMPLES, kNumSampleCounts,
                                        result->GetData()))
      .Times(1)
      .RetiresOnSaturation();
  result->size = 0;
  GetInternalformativ cmd;
  cmd.Init(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES,
           shared_memory_id_, shared_memory_offset_);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(kNumSampleCounts, result->GetNumResults());
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES3DecoderTest, GetInternalformativValidArgsNumSampleCounts) {
  const GLint kNumSampleCounts = 8;
  typedef GetInternalformativ::Result Result;
  Result* result = static_cast<Result*>(shared_memory_address_);
  EXPECT_CALL(*gl_, GetInternalformativ(GL_RENDERBUFFER, GL_RGBA8,
                                        GL_NUM_SAMPLE_COUNTS, 1, _))
      .WillOnce(SetArgPointee<4>(kNumSampleCounts))
      .RetiresOnSaturation();
  result->size = 0;
  GetInternalformativ cmd;
  cmd.Init(GL_RENDERBUFFER, GL_RGBA8, GL_NUM_SAMPLE_COUNTS,
           shared_memory_id_, shared_memory_offset_);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(1, result->GetNumResults());
  EXPECT_EQ(kNumSampleCounts, result->GetData()[0]);
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES3DecoderTest, ClientWaitSyncValid) {
  typedef ClientWaitSync::Result Result;
  Result* result = static_cast<Result*>(shared_memory_address_);
  ClientWaitSync cmd;
  cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, 0,
           shared_memory_id_, shared_memory_offset_);
  EXPECT_CALL(*gl_,
              ClientWaitSync(reinterpret_cast<GLsync>(kServiceSyncId),
                             GL_SYNC_FLUSH_COMMANDS_BIT, 0))
      .WillOnce(Return(GL_CONDITION_SATISFIED))
      .RetiresOnSaturation();
  *result = GL_WAIT_FAILED;
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), *result);
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES3DecoderTest, ClientWaitSyncNonZeroTimeoutValid) {
  typedef ClientWaitSync::Result Result;
  Result* result = static_cast<Result*>(shared_memory_address_);
  ClientWaitSync cmd;
  const GLuint64 kTimeout = 0xABCDEF0123456789;
  cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, kTimeout,
           shared_memory_id_, shared_memory_offset_);
  EXPECT_CALL(*gl_,
              ClientWaitSync(reinterpret_cast<GLsync>(kServiceSyncId),
                             GL_SYNC_FLUSH_COMMANDS_BIT, kTimeout))
      .WillOnce(Return(GL_CONDITION_SATISFIED))
      .RetiresOnSaturation();
  *result = GL_WAIT_FAILED;
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), *result);
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES3DecoderTest, ClientWaitSyncInvalidSyncFails) {
  typedef ClientWaitSync::Result Result;
  Result* result = static_cast<Result*>(shared_memory_address_);
  ClientWaitSync cmd;
  cmd.Init(kInvalidClientId, GL_SYNC_FLUSH_COMMANDS_BIT, 0,
           shared_memory_id_, shared_memory_offset_);
  *result = GL_WAIT_FAILED;
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(static_cast<GLenum>(GL_WAIT_FAILED), *result);
  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
}

TEST_P(GLES3DecoderTest, ClientWaitSyncResultNotInitFails) {
  typedef ClientWaitSync::Result Result;
  Result* result = static_cast<Result*>(shared_memory_address_);
  ClientWaitSync cmd;
  cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, 0,
           shared_memory_id_, shared_memory_offset_);
  *result = 1;  // Any value other than GL_WAIT_FAILED
  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
}

TEST_P(GLES3DecoderTest, ClientWaitSyncBadSharedMemoryFails) {
  typedef ClientWaitSync::Result Result;
  Result* result = static_cast<Result*>(shared_memory_address_);
  ClientWaitSync cmd;
  *result = GL_WAIT_FAILED;
  cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, 0,
           kInvalidSharedMemoryId, shared_memory_offset_);
  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));

  *result = GL_WAIT_FAILED;
  cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, 0,
           shared_memory_id_, kInvalidSharedMemoryOffset);
  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
}

TEST_P(GLES3DecoderTest, WaitSyncValidArgs) {
  const GLuint64 kTimeout = GL_TIMEOUT_IGNORED;
  EXPECT_CALL(*gl_, WaitSync(reinterpret_cast<GLsync>(kServiceSyncId),
                             0, kTimeout))
      .Times(1)
      .RetiresOnSaturation();

  WaitSync cmd;
  cmd.Init(client_sync_id_, 0, kTimeout);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) {
  InitState init;
  InitDecoder(init);

  BindTexture cmd1;
  cmd1.Init(GL_TEXTURE_2D, kInvalidClientId);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  BindBuffer cmd2;
  cmd2.Init(GL_ARRAY_BUFFER, kInvalidClientId);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  BindFramebuffer cmd3;
  cmd3.Init(GL_FRAMEBUFFER, kInvalidClientId);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd3));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  BindRenderbuffer cmd4;
  cmd4.Init(GL_RENDERBUFFER, kInvalidClientId);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd4));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
}

TEST_P(GLES2DecoderTest, EnableFeatureCHROMIUMBadBucket) {
  const uint32_t kBadBucketId = 123;
  EnableFeatureCHROMIUM cmd;
  cmd.Init(kBadBucketId, shared_memory_id_, shared_memory_offset_);
  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
}

TEST_P(GLES2DecoderTest, RequestExtensionCHROMIUMBadBucket) {
  const uint32_t kBadBucketId = 123;
  RequestExtensionCHROMIUM cmd;
  cmd.Init(kBadBucketId);
  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
}

TEST_P(GLES2DecoderTest, BeginQueryEXTDisabled) {
  // Test something fails if off.
}

TEST_P(GLES2DecoderTest, GenQueriesEXTImmediateValidArgs) {
  GenQueriesEXTImmediate* cmd =
      GetImmediateAs<GenQueriesEXTImmediate>();
  GLuint temp = kNewClientId;
  cmd->Init(1, &temp);
  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*cmd, sizeof(temp)));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  QueryManager* query_manager = decoder_->GetQueryManager();
  ASSERT_TRUE(query_manager != nullptr);
  EXPECT_TRUE(query_manager->IsValidQuery(kNewClientId));
}

TEST_P(GLES2DecoderTest, GenQueriesEXTImmediateDuplicateOrNullIds) {
  GenQueriesEXTImmediate* cmd =
      GetImmediateAs<GenQueriesEXTImmediate>();
  GLuint temp[3] = {kNewClientId, kNewClientId + 1, kNewClientId};
  cmd->Init(3, temp);
  EXPECT_EQ(error::kInvalidArguments, ExecuteImmediateCmd(*cmd, sizeof(temp)));
  QueryManager* query_manager = decoder_->GetQueryManager();
  ASSERT_TRUE(query_manager != nullptr);
  EXPECT_FALSE(query_manager->IsValidQuery(kNewClientId));
  EXPECT_FALSE(query_manager->IsValidQuery(kNewClientId + 1));
  GLuint null_id[2] = {kNewClientId, 0};
  cmd->Init(2, null_id);
  EXPECT_EQ(error::kInvalidArguments,
            ExecuteImmediateCmd(*cmd, sizeof(temp)));
  EXPECT_FALSE(query_manager->IsValidQuery(kNewClientId));
}

TEST_P(GLES2DecoderTest, GenQueriesEXTImmediateInvalidArgs) {
  GenQueriesEXTImmediate* cmd =
      GetImmediateAs<GenQueriesEXTImmediate>();
  cmd->Init(1, &client_query_id_);
  EXPECT_EQ(error::kInvalidArguments,
            ExecuteImmediateCmd(*cmd, sizeof(&client_query_id_)));
}


TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) {
  InitState init;
  init.extensions = "GL_EXT_occlusion_query_boolean";
  init.gl_version = "OpenGL ES 2.0";
  init.has_alpha = true;
  init.request_alpha = true;
  init.bind_generates_resource = true;
  InitDecoder(init);

  // Test end fails if no begin.
  EndQueryEXT end_cmd;
  end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  BeginQueryEXT begin_cmd;

  // Test id = 0 fails.
  begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 0, shared_memory_id_,
                 kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  GenHelper<GenQueriesEXTImmediate>(kNewClientId);

  // Test valid parameters work.
  EXPECT_CALL(*gl_, GenQueries(1, _))
      .WillOnce(SetArgPointee<1>(kNewServiceId))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl_, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId))
      .Times(1)
      .RetiresOnSaturation();

  // Query object should not be created untill BeginQueriesEXT.
  QueryManager* query_manager = decoder_->GetQueryManager();
  ASSERT_TRUE(query_manager != nullptr);
  QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
  EXPECT_TRUE(query == nullptr);

  // BeginQueryEXT should fail  if id is not generated from GenQueriesEXT.
  begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, kInvalidClientId, shared_memory_id_,
                 kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, kNewClientId, shared_memory_id_,
                 kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());

  // After BeginQueriesEXT id name should have query object associated with it.
  query = query_manager->GetQuery(kNewClientId);
  ASSERT_TRUE(query != nullptr);
  EXPECT_FALSE(query->IsPending());

  // Test trying begin again fails
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  // Test end fails with different target
  end_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  // Test end succeeds
  EXPECT_CALL(*gl_, EndQuery(GL_ANY_SAMPLES_PASSED_EXT))
      .Times(1)
      .RetiresOnSaturation();
  end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_TRUE(query->IsPending());

  // Begin should fail if using a different target
  begin_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, kNewClientId,
                 shared_memory_id_, kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  // Begin should fail if using a different sync
  begin_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, kNewClientId,
                 shared_memory_id_, kSharedMemoryOffset + sizeof(QuerySync));
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  // QueryCounter should fail if using a different target
  QueryCounterEXT query_counter_cmd;
  query_counter_cmd.Init(kNewClientId, GL_TIMESTAMP, shared_memory_id_,
                         kSharedMemoryOffset, 1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(query_counter_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  // QueryCounter should fail if using a different sync
  query_counter_cmd.Init(kNewClientId, GL_TIMESTAMP, shared_memory_id_,
                         kSharedMemoryOffset + sizeof(QuerySync), 1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(query_counter_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  EXPECT_CALL(*gl_, DeleteQueries(1, _)).Times(1).RetiresOnSaturation();
}

struct QueryType {
  GLenum type;
  bool is_counter;
};

const QueryType kQueryTypes[] = {
    {GL_COMMANDS_ISSUED_CHROMIUM, false},
    {GL_LATENCY_QUERY_CHROMIUM, false},
    {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, false},
    {GL_GET_ERROR_QUERY_CHROMIUM, false},
    {GL_COMMANDS_COMPLETED_CHROMIUM, false},
    {GL_ANY_SAMPLES_PASSED_EXT, false},
    {GL_TIME_ELAPSED, false},
    {GL_TIMESTAMP, true},
};
const GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);

static void ExecuteGenerateQueryCmd(GLES2DecoderTestBase* test,
                                    ::gl::MockGLInterface* gl,
                                    GLenum target,
                                    GLuint client_id,
                                    GLuint service_id) {
  test->GenHelper<GenQueriesEXTImmediate>(client_id);
  if (GL_ANY_SAMPLES_PASSED_EXT == target) {
    EXPECT_CALL(*gl, GenQueries(1, _))
        .WillOnce(SetArgPointee<1>(service_id))
        .RetiresOnSaturation();
  }
}

static error::Error ExecuteBeginQueryCmd(GLES2DecoderTestBase* test,
                                         ::gl::MockGLInterface* gl,
                                         ::gl::GPUTimingFake* timing_queries,
                                         GLenum target,
                                         GLuint client_id,
                                         GLuint service_id,
                                         int32_t shm_id,
                                         uint32_t shm_offset) {
  if (GL_ANY_SAMPLES_PASSED_EXT == target) {
    EXPECT_CALL(*gl, BeginQuery(target, service_id))
        .Times(1)
        .RetiresOnSaturation();
  } else if (GL_TIME_ELAPSED == target) {
    timing_queries->ExpectGPUTimerQuery(*gl, true);
  }

  BeginQueryEXT begin_cmd;
  begin_cmd.Init(target, client_id, shm_id, shm_offset);
  return test->ExecuteCmd(begin_cmd);
}

static error::Error ExecuteEndQueryCmd(GLES2DecoderTestBase* test,
                                       ::gl::MockGLInterface* gl,
                                       GLenum target,
                                       uint32_t submit_count) {
  if (GL_ANY_SAMPLES_PASSED_EXT == target) {
    EXPECT_CALL(*gl, EndQuery(target))
        .Times(1)
        .RetiresOnSaturation();
  } else if (GL_GET_ERROR_QUERY_CHROMIUM == target) {
    EXPECT_CALL(*gl, GetError())
        .WillOnce(Return(GL_NO_ERROR))
        .RetiresOnSaturation();
  } else if (GL_COMMANDS_COMPLETED_CHROMIUM == target) {
    EXPECT_CALL(*gl, Flush()).RetiresOnSaturation();
    EXPECT_CALL(*gl, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
        .WillOnce(Return(kGlSync))
        .RetiresOnSaturation();
#if DCHECK_IS_ON()
    EXPECT_CALL(*gl, IsSync(kGlSync))
        .WillRepeatedly(Return(GL_TRUE));
#endif
  }

  EndQueryEXT end_cmd;
  end_cmd.Init(target, submit_count);
  return test->ExecuteCmd(end_cmd);
}

static error::Error ExecuteQueryCounterCmd(GLES2DecoderTestBase* test,
                                           ::gl::MockGLInterface* gl,
                                           ::gl::GPUTimingFake* timing_queries,
                                           GLenum target,
                                           GLuint client_id,
                                           GLuint service_id,
                                           int32_t shm_id,
                                           uint32_t shm_offset,
                                           uint32_t submit_count) {
  if (GL_TIMESTAMP == target) {
    timing_queries->ExpectGPUTimeStampQuery(*gl, false);
  }

  QueryCounterEXT query_counter_cmd;
  query_counter_cmd.Init(client_id,
                         target,
                         shm_id,
                         shm_offset,
                         submit_count);
  return test->ExecuteCmd(query_counter_cmd);
}

static void ProcessQuery(GLES2DecoderTestBase* test,
                         ::gl::MockGLInterface* gl,
                         GLenum target,
                         GLuint service_id) {
  if (GL_ANY_SAMPLES_PASSED_EXT == target) {
    EXPECT_CALL(
        *gl, GetQueryObjectuiv(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
        .WillOnce(SetArgPointee<2>(1))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, GetQueryObjectuiv(service_id, GL_QUERY_RESULT_EXT, _))
        .WillOnce(SetArgPointee<2>(1))
        .RetiresOnSaturation();
  } else if (GL_COMMANDS_COMPLETED_CHROMIUM == target) {
    EXPECT_CALL(*gl, ClientWaitSync(kGlSync, _, _))
        .WillOnce(Return(GL_ALREADY_SIGNALED))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
  }

  QueryManager* query_manager = test->GetDecoder()->GetQueryManager();
  ASSERT_TRUE(nullptr != query_manager);
  query_manager->ProcessPendingQueries(false);
}

static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test,
                                             GLuint client_id,
                                             const QueryType& query_type,
                                             int32_t shm_id,
                                             uint32_t shm_offset) {
  // We need to reset the decoder on each iteration, because we lose the
  // context every time.
  GLES2DecoderTestBase::InitState init;
  init.extensions = "GL_EXT_occlusion_query_boolean"
                    " GL_ARB_sync"
                    " GL_ARB_timer_query";
  init.gl_version = "OpenGL ES 3.0";
  init.has_alpha = true;
  init.request_alpha = true;
  init.bind_generates_resource = true;
  test->InitDecoder(init);

  test->GenHelper<GenQueriesEXTImmediate>(client_id);

  // Test bad shared memory fails
  error::Error error = error::kNoError;
  if (query_type.is_counter) {
    QueryCounterEXT query_counter_cmd;
    query_counter_cmd.Init(client_id, query_type.type, shm_id, shm_offset, 1);
    error = test->ExecuteCmd(query_counter_cmd);
  } else {
    BeginQueryEXT begin_cmd;
    begin_cmd.Init(query_type.type, client_id, shm_id, shm_offset);
    error = test->ExecuteCmd(begin_cmd);
  }

  EXPECT_TRUE(error != error::kNoError);

  test->ResetDecoder();
}

TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) {
  for (size_t i = 0; i < base::size(kQueryTypes); ++i) {
    CheckBeginEndQueryBadMemoryFails(this, kNewClientId, kQueryTypes[i],
                                     kInvalidSharedMemoryId,
                                     kSharedMemoryOffset);
  }
}

TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) {
  for (size_t i = 0; i < base::size(kQueryTypes); ++i) {
    // Out-of-bounds.
    CheckBeginEndQueryBadMemoryFails(this, kNewClientId, kQueryTypes[i],
                                     shared_memory_id_,
                                     kInvalidSharedMemoryOffset);
    // Overflow.
    CheckBeginEndQueryBadMemoryFails(this, kNewClientId, kQueryTypes[i],
                                     shared_memory_id_, 0xfffffffcu);
  }
}

TEST_P(GLES2DecoderManualInitTest, QueryReuseTest) {
  for (size_t i = 0; i < base::size(kQueryTypes); ++i) {
    const QueryType& query_type = kQueryTypes[i];

    GLES2DecoderTestBase::InitState init;
    init.extensions = "GL_EXT_occlusion_query_boolean"
                      " GL_ARB_sync"
                      " GL_ARB_timer_query";
    init.gl_version = "OpenGL ES 3.0";
    init.has_alpha = true;
    init.request_alpha = true;
    init.bind_generates_resource = true;
    InitDecoder(init);
    ::testing::StrictMock<::gl::MockGLInterface>* gl = GetGLMock();
    ::gl::GPUTimingFake gpu_timing_queries;

    ExecuteGenerateQueryCmd(this, gl, query_type.type,
                            kNewClientId, kNewServiceId);

    // Query once.
    if (query_type.is_counter) {
      EXPECT_EQ(
          error::kNoError,
          ExecuteQueryCounterCmd(this, gl, &gpu_timing_queries, query_type.type,
                                 kNewClientId, kNewServiceId, shared_memory_id_,
                                 kSharedMemoryOffset, 1));
    } else {
      EXPECT_EQ(
          error::kNoError,
          ExecuteBeginQueryCmd(this, gl, &gpu_timing_queries, query_type.type,
                               kNewClientId, kNewServiceId, shared_memory_id_,
                               kSharedMemoryOffset));
      EXPECT_EQ(error::kNoError, ExecuteEndQueryCmd(this, gl,
                                                    query_type.type, 1));
    }

    ProcessQuery(this, gl, query_type.type, kNewServiceId);

    // Reuse query.
    if (query_type.is_counter) {
      EXPECT_EQ(
          error::kNoError,
          ExecuteQueryCounterCmd(this, gl, &gpu_timing_queries, query_type.type,
                                 kNewClientId, kNewServiceId, shared_memory_id_,
                                 kSharedMemoryOffset, 2));
    } else {
      EXPECT_EQ(
          error::kNoError,
          ExecuteBeginQueryCmd(this, gl, &gpu_timing_queries, query_type.type,
                               kNewClientId, kNewServiceId, shared_memory_id_,
                               kSharedMemoryOffset));
      EXPECT_EQ(error::kNoError, ExecuteEndQueryCmd(this, gl,
                                                    query_type.type, 2));
    }

    ProcessQuery(this, gl, query_type.type, kNewServiceId);

    if (GL_ANY_SAMPLES_PASSED_EXT == query_type.type)
      EXPECT_CALL(*gl, DeleteQueries(1, _)).Times(1).RetiresOnSaturation();
    ResetDecoder();
  }
}

TEST_P(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) {
  BeginQueryEXT begin_cmd;

  GenHelper<GenQueriesEXTImmediate>(kNewClientId);

  // Test valid parameters work.
  begin_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, kNewClientId, shared_memory_id_,
                 kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());

  QueryManager* query_manager = decoder_->GetQueryManager();
  ASSERT_TRUE(query_manager != nullptr);
  QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
  ASSERT_TRUE(query != nullptr);
  EXPECT_FALSE(query->IsPending());

  // Test end succeeds
  EndQueryEXT end_cmd;
  end_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, 1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_FALSE(query->IsPending());
}

TEST_P(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) {
  BeginQueryEXT begin_cmd;

  GenHelper<GenQueriesEXTImmediate>(kNewClientId);

  // Test valid parameters work.
  begin_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, kNewClientId, shared_memory_id_,
                 kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());

  QueryManager* query_manager = decoder_->GetQueryManager();
  ASSERT_TRUE(query_manager != nullptr);
  QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
  ASSERT_TRUE(query != nullptr);
  EXPECT_FALSE(query->IsPending());

  // Test end succeeds
  QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);

  EXPECT_CALL(*gl_, GetError())
      .WillOnce(Return(GL_INVALID_VALUE))
      .RetiresOnSaturation();

  EndQueryEXT end_cmd;
  end_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, 1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_FALSE(query->IsPending());
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE),
            static_cast<GLenum>(sync->result));
}

TEST_P(GLES2DecoderTest, SetDisjointValueSync) {
  SetDisjointValueSyncCHROMIUM cmd;

  cmd.Init(static_cast<uint32_t>(-1), 0u);
  EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));

  cmd.Init(kInvalidSharedMemoryId, 0u);
  EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));

  cmd.Init(shared_memory_id_, kSharedBufferSize);
  EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));

  cmd.Init(shared_memory_id_, kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));

  cmd.Init(shared_memory_id_, kSharedMemoryOffset);
  EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
}

TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) {
  InitState init;
  init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
  init.gl_version = "OpenGL ES 2.0";
  init.has_alpha = true;
  init.request_alpha = true;
  init.bind_generates_resource = true;
  InitDecoder(init);

  GenHelper<GenQueriesEXTImmediate>(kNewClientId);

  BeginQueryEXT begin_cmd;
  begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, kNewClientId,
                 shared_memory_id_, kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());

  QueryManager* query_manager = decoder_->GetQueryManager();
  ASSERT_TRUE(query_manager != nullptr);
  QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
  ASSERT_TRUE(query != nullptr);
  EXPECT_FALSE(query->IsPending());

  EXPECT_CALL(*gl_, Flush()).RetiresOnSaturation();
  EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
      .WillOnce(Return(kGlSync))
      .RetiresOnSaturation();
#if DCHECK_IS_ON()
  EXPECT_CALL(*gl_, IsSync(kGlSync))
      .WillOnce(Return(GL_TRUE))
      .RetiresOnSaturation();
#endif

  EndQueryEXT end_cmd;
  end_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, 1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_TRUE(query->IsPending());

#if DCHECK_IS_ON()
  EXPECT_CALL(*gl_, IsSync(kGlSync))
      .WillOnce(Return(GL_TRUE))
      .RetiresOnSaturation();
#endif
  EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
      .WillOnce(Return(GL_TIMEOUT_EXPIRED))
      .RetiresOnSaturation();
  query_manager->ProcessPendingQueries(false);

  EXPECT_TRUE(query->IsPending());

#if DCHECK_IS_ON()
  EXPECT_CALL(*gl_, IsSync(kGlSync))
      .WillOnce(Return(GL_TRUE))
      .RetiresOnSaturation();
#endif
  EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
      .WillOnce(Return(GL_ALREADY_SIGNALED))
      .RetiresOnSaturation();
  query_manager->ProcessPendingQueries(false);

  EXPECT_FALSE(query->IsPending());

#if DCHECK_IS_ON()
  EXPECT_CALL(*gl_, IsSync(kGlSync))
      .WillOnce(Return(GL_TRUE))
      .RetiresOnSaturation();
#endif
  EXPECT_CALL(*gl_, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
  ResetDecoder();
}

TEST_P(GLES2DecoderManualInitTest, BeginInvalidTargetQueryFails) {
  InitState init;
  init.extensions = "";
  init.gl_version = "OpenGL ES 2.0";
  init.has_alpha = true;
  init.request_alpha = true;
  init.bind_generates_resource = true;
  InitDecoder(init);

  GenHelper<GenQueriesEXTImmediate>(kNewClientId);

  BeginQueryEXT begin_cmd;
  begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, kNewClientId,
                 shared_memory_id_, kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  begin_cmd.Init(GL_ANY_SAMPLES_PASSED, kNewClientId, shared_memory_id_,
                 kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  begin_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, kNewClientId,
                 shared_memory_id_, kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  begin_cmd.Init(GL_TIME_ELAPSED, kNewClientId, shared_memory_id_,
                 kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  begin_cmd.Init(0xdeadbeef, kNewClientId, shared_memory_id_,
                 kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}

TEST_P(GLES2DecoderManualInitTest, QueryCounterEXTTimeStamp) {
  InitState init;
  init.extensions = "GL_ARB_timer_query";
  init.gl_version = "OpenGL ES 3.0";
  init.has_alpha = true;
  init.request_alpha = true;
  init.bind_generates_resource = true;
  InitDecoder(init);

  GenHelper<GenQueriesEXTImmediate>(kNewClientId);

  EXPECT_CALL(*gl_, GenQueries(1, _))
      .WillOnce(SetArgPointee<1>(kNewServiceId))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl_, GetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, _))
      .WillOnce(SetArgPointee<2>(64))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl_, QueryCounter(kNewServiceId, GL_TIMESTAMP))
      .Times(1)
      .RetiresOnSaturation();
  QueryCounterEXT query_counter_cmd;
  query_counter_cmd.Init(kNewClientId, GL_TIMESTAMP, shared_memory_id_,
                         kSharedMemoryOffset, 1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(query_counter_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());

  QueryManager* query_manager = decoder_->GetQueryManager();
  ASSERT_TRUE(query_manager != nullptr);
  QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
  ASSERT_TRUE(query != nullptr);
  EXPECT_TRUE(query->IsPending());
}

TEST_P(GLES2DecoderManualInitTest, InvalidTargetQueryCounterFails) {
  InitState init;
  init.extensions = "";
  init.gl_version = "OpenGL ES 2.0";
  init.has_alpha = true;
  init.request_alpha = true;
  init.bind_generates_resource = true;
  InitDecoder(init);

  GenHelper<GenQueriesEXTImmediate>(kNewClientId);

  QueryCounterEXT query_counter_cmd;
  query_counter_cmd.Init(kNewClientId, GL_TIMESTAMP, shared_memory_id_,
                         kSharedMemoryOffset, 1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(query_counter_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());

  query_counter_cmd.Init(kNewClientId, 0xdeadbeef, shared_memory_id_,
                         kSharedMemoryOffset, 1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(query_counter_cmd));
  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}

TEST_P(GLES2DecoderTest, IsEnabledReturnsCachedValue) {
  // NOTE: There are no expectations because no GL functions should be
  // called for DEPTH_TEST or STENCIL_TEST
  static const GLenum kStates[] = {
      GL_DEPTH_TEST, GL_STENCIL_TEST,
  };
  for (size_t ii = 0; ii < base::size(kStates); ++ii) {
    Enable enable_cmd;
    GLenum state = kStates[ii];
    enable_cmd.Init(state);
    EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
    IsEnabled::Result* result =
        static_cast<IsEnabled::Result*>(shared_memory_address_);
    IsEnabled is_enabled_cmd;
    is_enabled_cmd.Init(state, shared_memory_id_, shared_memory_offset_);
    EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
    EXPECT_NE(0u, *result);
    Disable disable_cmd;
    disable_cmd.Init(state);
    EXPECT_EQ(error::kNoError, ExecuteCmd(disable_cmd));
    EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
    EXPECT_EQ(0u, *result);
  }
}

namespace {

class SizeOnlyMemoryTracker : public MemoryTracker {
 public:
  SizeOnlyMemoryTracker() {
    // Account for the 7 default textures. 1 for TEXTURE_2D and 6 faces for
    // TEXTURE_CUBE_MAP. Each is 1x1, with 4 bytes per channel.
    pool_info_.initial_size = 28;
    pool_info_.size = 0;
  }
  ~SizeOnlyMemoryTracker() override = default;

  void TrackMemoryAllocatedChange(uint64_t delta) override {
    pool_info_.size += delta;
  }

  uint64_t GetSize() const override {
    return pool_info_.size - pool_info_.initial_size;
  }

  uint64_t ClientTracingId() const override { return 0; }
  int ClientId() const override { return 0; }
  uint64_t ContextGroupTracingId() const override { return 0; }

 private:
  struct PoolInfo {
    PoolInfo() : initial_size(0), size(0) {}
    uint64_t initial_size;
    uint64_t size;
  };
  PoolInfo pool_info_;
};

}  // anonymous namespace.

TEST_P(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) {
  auto memory_tracker = std::make_unique<SizeOnlyMemoryTracker>();
  auto* memory_tracker_ptr = memory_tracker.get();
  set_memory_tracker(std::move(memory_tracker));
  InitState init;
  init.bind_generates_resource = true;
  InitDecoder(init);
  // Expect that initial size - size is 0.
  EXPECT_EQ(0u, memory_tracker_ptr->GetSize());
  EXPECT_EQ(0u, memory_tracker_ptr->GetSize());
}

TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) {
  auto memory_tracker = std::make_unique<SizeOnlyMemoryTracker>();
  auto* memory_tracker_ptr = memory_tracker.get();
  set_memory_tracker(std::move(memory_tracker));
  InitState init;
  init.bind_generates_resource = true;
  InitDecoder(init);
  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
               shared_memory_id_, kSharedMemoryOffset);
  EXPECT_EQ(128u, memory_tracker_ptr->GetSize());
  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
               shared_memory_id_, kSharedMemoryOffset);
  EXPECT_EQ(64u, memory_tracker_ptr->GetSize());
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) {
  auto memory_tracker = std::make_unique<SizeOnlyMemoryTracker>();
  auto* memory_tracker_ptr = memory_tracker.get();
  set_memory_tracker(std::move(memory_tracker));
  InitState init;
  init.extensions = "GL_EXT_texture_storage";
  init.bind_generates_resource = true;
  InitDecoder(init);
  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
  EXPECT_CALL(*gl_, TexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4))
      .Times(1)
      .RetiresOnSaturation();
  TexStorage2DEXT cmd;
  cmd.Init(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(128u, memory_tracker_ptr->GetSize());
}

TEST_P(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) {
  GLenum target = GL_TEXTURE_2D;
  GLint level = 0;
  GLenum internal_format = GL_RGBA;
  GLsizei width = 4;
  GLsizei height = 8;
  GLint border = 0;
  auto memory_tracker = std::make_unique<SizeOnlyMemoryTracker>();
  auto* memory_tracker_ptr = memory_tracker.get();
  set_memory_tracker(std::move(memory_tracker));
  InitState init;
  init.has_alpha = true;
  init.request_alpha = true;
  init.bind_generates_resource = true;
  InitDecoder(init);
  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
  EXPECT_CALL(*gl_, GetError())
      .WillOnce(Return(GL_NO_ERROR))
      .WillOnce(Return(GL_NO_ERROR))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl_,
              CopyTexImage2D(
                  target, level, internal_format, 0, 0, width, height, border))
      .Times(1)
      .RetiresOnSaturation();
  CopyTexImage2D cmd;
  cmd.Init(target, level, internal_format, 0, 0, width, height);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(128u, memory_tracker_ptr->GetSize());
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) {
  auto memory_tracker = std::make_unique<SizeOnlyMemoryTracker>();
  auto* memory_tracker_ptr = memory_tracker.get();
  set_memory_tracker(std::move(memory_tracker));
  InitState init;
  init.bind_generates_resource = true;
  InitDecoder(init);
  DoBindRenderbuffer(
      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
  EnsureRenderbufferBound(false);
  EXPECT_CALL(*gl_, GetError())
      .WillOnce(Return(GL_NO_ERROR))
      .WillOnce(Return(GL_NO_ERROR))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl_, RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 8, 4))
      .Times(1)
      .RetiresOnSaturation();
  RenderbufferStorage cmd;
  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 8, 4);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_EQ(128u, memory_tracker_ptr->GetSize());
}

TEST_P(GLES2DecoderManualInitTest, MemoryTrackerBufferData) {
  auto memory_tracker = std::make_unique<SizeOnlyMemoryTracker>();
  auto* memory_tracker_ptr = memory_tracker.get();
  set_memory_tracker(std::move(memory_tracker));
  InitState init;
  init.bind_generates_resource = true;
  InitDecoder(init);
  EXPECT_EQ(0u, memory_tracker_ptr->GetSize());
  DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
  EXPECT_CALL(*gl_, GetError())
      .WillOnce(Return(GL_NO_ERROR))
      .WillOnce(Return(GL_NO_ERROR))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 128, _, GL_STREAM_DRAW))
      .Times(1)
      .RetiresOnSaturation();
  BufferData cmd;
  cmd.Init(GL_ARRAY_BUFFER, 128, 0, 0, GL_STREAM_DRAW);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_EQ(128u, memory_tracker_ptr->GetSize());
}

TEST_P(GLES2DecoderManualInitTest, ImmutableCopyTexImage2D) {
  const GLenum kTarget = GL_TEXTURE_2D;
  const GLint kLevel = 0;
  const GLint kLevels = 2;
  const GLenum kInternalFormat = GL_RGBA;
  const GLenum kSizedInternalFormat = GL_RGBA8;
  const GLsizei kWidth = 4;
  const GLsizei kHeight = 8;
  const GLint kBorder = 0;
  InitState init;
  init.extensions = "GL_EXT_texture_storage";
  init.has_alpha = true;
  init.request_alpha = true;
  init.bind_generates_resource = true;
  init.gl_version = "OpenGL ES 2.0";  // To avoid TexStorage emulation.
  InitDecoder(init);
  DoBindTexture(kTarget, client_texture_id_, kServiceTextureId);

  // CopyTexImage2D will call arbitrary amount of GetErrors.
  EXPECT_CALL(*gl_, GetError())
      .Times(AtLeast(1));

  EXPECT_CALL(*gl_,
              CopyTexImage2D(
                  kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight,
                  kBorder))
      .Times(1);

  EXPECT_CALL(*gl_,
              TexStorage2DEXT(
                  kTarget, kLevels, kSizedInternalFormat, kWidth, kHeight))
      .Times(1);
  CopyTexImage2D copy_cmd;
  copy_cmd.Init(kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight);
  EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());

  TexStorage2DEXT storage_cmd;
  storage_cmd.Init(kTarget, kLevels, kSizedInternalFormat, kWidth, kHeight);
  EXPECT_EQ(error::kNoError, ExecuteCmd(storage_cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());

  // This should not invoke CopyTexImage2D.
  copy_cmd.Init(kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight);
  EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
}

TEST_P(GLES2DecoderTest, LoseContextCHROMIUMGuilty) {
  EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kInnocent))
      .Times(1);
  LoseContextCHROMIUM cmd;
  cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
  EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_TRUE(decoder_->WasContextLost());
  EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension());
}

TEST_P(GLES2DecoderTest, LoseContextCHROMIUMUnkown) {
  EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown))
      .Times(1);
  LoseContextCHROMIUM cmd;
  cmd.Init(GL_UNKNOWN_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB);
  EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_TRUE(decoder_->WasContextLost());
  EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension());
}

TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs0_0) {
  EXPECT_CALL(*mock_decoder_, MarkContextLost(_))
      .Times(0);
  LoseContextCHROMIUM cmd;
  cmd.Init(GL_NONE, GL_GUILTY_CONTEXT_RESET_ARB);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}

TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs1_0) {
  EXPECT_CALL(*mock_decoder_, MarkContextLost(_))
      .Times(0);
  LoseContextCHROMIUM cmd;
  cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_NONE);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}

class GLES2DecoderDoCommandsTest : public GLES2DecoderTest {
 public:
  GLES2DecoderDoCommandsTest() {
    for (int i = 0; i < 3; i++) {
      cmds_[i].Init(GL_BLEND);
    }
    entries_per_cmd_ = ComputeNumEntries(cmds_[0].ComputeSize());
  }

  void SetExpectationsForNCommands(int num_commands) {
    for (int i = 0; i < num_commands; i++)
      SetupExpectationsForEnableDisable(GL_BLEND, true);
  }

 protected:
  Enable cmds_[3];
  int entries_per_cmd_;
};

TEST_P(GLES3DecoderTest, BeginInvalidTargetQueryFails) {
  BeginQueryEXT begin_cmd;
  begin_cmd.Init(0xdeadbeef, kNewClientId, shared_memory_id_,
                 kSharedMemoryOffset);
  EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}


TEST_P(GLES3DecoderTest, BindTransformFeedbackValidArgs) {
  EXPECT_CALL(*gl_, BindTransformFeedback(GL_TRANSFORM_FEEDBACK,
                                          kServiceTransformFeedbackId));
  SpecializedSetup<BindTransformFeedback, 0>(true);
  BindTransformFeedback cmd;
  cmd.Init(GL_TRANSFORM_FEEDBACK, client_transformfeedback_id_);
  EXPECT_CALL(*gl_, BindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES3DecoderTest, DeleteTransformFeedbacksImmediateInvalidArgs) {
  DeleteTransformFeedbacksImmediate& cmd =
      *GetImmediateAs<DeleteTransformFeedbacksImmediate>();
  SpecializedSetup<DeleteTransformFeedbacksImmediate, 0>(false);
  GLuint temp = kInvalidClientId;
  cmd.Init(1, &temp);
  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES3DecoderTest, GetIntegeri_vValidArgs) {
  EXPECT_CALL(*gl_, GetIntegeri_v(_, _, _)).Times(0);
  typedef GetIntegeri_v::Result Result;
  Result* result = static_cast<Result*>(shared_memory_address_);
  result->size = 0;
  GetIntegeri_v cmd;
  cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 2, shared_memory_id_,
           shared_memory_offset_);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
                GL_TRANSFORM_FEEDBACK_BUFFER_BINDING),
            result->GetNumResults());
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES3DecoderTest, GetInteger64i_vValidArgs) {
  EXPECT_CALL(*gl_, GetInteger64i_v(_, _, _)).Times(0);
  typedef GetInteger64i_v::Result Result;
  Result* result = static_cast<Result*>(shared_memory_address_);
  result->size = 0;
  GetInteger64i_v cmd;
  cmd.Init(GL_UNIFORM_BUFFER_SIZE, 2, shared_memory_id_,
           shared_memory_offset_);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
                GL_UNIFORM_BUFFER_SIZE),
            result->GetNumResults());
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES3DecoderTest, GetSamplerBinding) {
  const GLuint kClientID = 12;
  const GLuint kServiceID = 1012;
  const GLuint kUnit = 0;
  DoCreateSampler(kClientID, kServiceID);
  DoBindSampler(kUnit, kClientID, kServiceID);

  EXPECT_CALL(*gl_, GetError())
      .WillOnce(Return(GL_NO_ERROR))
      .WillOnce(Return(GL_NO_ERROR))
      .RetiresOnSaturation();

  typedef cmds::GetIntegerv::Result Result;
  Result* result = static_cast<Result*>(shared_memory_address_);
  cmds::GetIntegerv cmd;
  cmd.Init(GL_SAMPLER_BINDING, shared_memory_id_, shared_memory_offset_);
  result->size = 0;
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(1, result->GetNumResults());
  EXPECT_EQ(kClientID, static_cast<GLuint>(result->GetData()[0]));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES3DecoderTest, GetTransformFeedbackBinding) {
  const GLuint kClientID = 12;
  const GLuint kServiceID = 1012;
  const GLenum kTarget = GL_TRANSFORM_FEEDBACK;
  DoCreateTransformFeedback(kClientID, kServiceID);
  EXPECT_CALL(*gl_, BindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0))
      .Times(1)
      .RetiresOnSaturation();
  DoBindTransformFeedback(kTarget, kClientID, kServiceID);

  EXPECT_CALL(*gl_, GetError())
      .WillOnce(Return(GL_NO_ERROR))
      .WillOnce(Return(GL_NO_ERROR))
      .RetiresOnSaturation();

  typedef cmds::GetIntegerv::Result Result;
  Result* result = static_cast<Result*>(shared_memory_address_);
  cmds::GetIntegerv cmd;
  cmd.Init(
      GL_TRANSFORM_FEEDBACK_BINDING, shared_memory_id_, shared_memory_offset_);
  result->size = 0;
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(1, result->GetNumResults());
  EXPECT_EQ(kClientID, static_cast<GLuint>(result->GetData()[0]));

  EXPECT_CALL(*gl_, BindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0))
      .Times(1)
      .RetiresOnSaturation();
  DoBindTransformFeedback(kTarget, 0, kServiceDefaultTransformFeedbackId);
  DoDeleteTransformFeedback(kClientID, kServiceID);
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

// Test that processing with 0 entries does nothing.
TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOneOfZero) {
  int num_processed = -1;
  SetExpectationsForNCommands(0);
  EXPECT_EQ(
      error::kNoError,
      decoder_->DoCommands(1, &cmds_, entries_per_cmd_ * 0, &num_processed));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_EQ(0, num_processed);
}

// Test processing at granularity of single commands.
TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOneOfOne) {
  int num_processed = -1;
  SetExpectationsForNCommands(1);
  EXPECT_EQ(
      error::kNoError,
      decoder_->DoCommands(1, &cmds_, entries_per_cmd_ * 1, &num_processed));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_EQ(entries_per_cmd_, num_processed);
}

// Test processing at granularity of multiple commands.
TEST_P(GLES2DecoderDoCommandsTest, DoCommandsThreeOfThree) {
  int num_processed = -1;
  SetExpectationsForNCommands(3);
  EXPECT_EQ(
      error::kNoError,
      decoder_->DoCommands(3, &cmds_, entries_per_cmd_ * 3, &num_processed));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_EQ(entries_per_cmd_ * 3, num_processed);
}

// Test processing a request smaller than available entries.
TEST_P(GLES2DecoderDoCommandsTest, DoCommandsTwoOfThree) {
  int num_processed = -1;
  SetExpectationsForNCommands(2);
  EXPECT_EQ(
      error::kNoError,
      decoder_->DoCommands(2, &cmds_, entries_per_cmd_ * 3, &num_processed));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_EQ(entries_per_cmd_ * 2, num_processed);
}

// Test that processing stops on a command with size 0.
TEST_P(GLES2DecoderDoCommandsTest, DoCommandsZeroCmdSize) {
  cmds_[1].header.size = 0;
  int num_processed = -1;
  SetExpectationsForNCommands(1);
  EXPECT_EQ(
      error::kInvalidSize,
      decoder_->DoCommands(2, &cmds_, entries_per_cmd_ * 2, &num_processed));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_EQ(entries_per_cmd_, num_processed);
}

// Test that processing stops on a command with size greater than available.
TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOutOfBounds) {
  int num_processed = -1;
  SetExpectationsForNCommands(1);
  EXPECT_EQ(error::kOutOfBounds,
            decoder_->DoCommands(
                2, &cmds_, entries_per_cmd_ * 2 - 1, &num_processed));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  EXPECT_EQ(entries_per_cmd_, num_processed);
}

// Test that commands with bad argument size are skipped without processing.
TEST_P(GLES2DecoderDoCommandsTest, DoCommandsBadArgSize) {
  cmds_[1].header.size += 1;
  int num_processed = -1;
  SetExpectationsForNCommands(1);
  EXPECT_EQ(error::kInvalidArguments,
            decoder_->DoCommands(
                2, &cmds_, entries_per_cmd_ * 2 + 1, &num_processed));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  // gpu::CommandHeader::size is a 21-bit field, so casting it to int is safe.
  // Without the explicit cast, Visual Studio ends up promoting the left hand
  // side to unsigned, and emits a sign mismatch warning.
  EXPECT_EQ(entries_per_cmd_ + static_cast<int>(cmds_[1].header.size),
            num_processed);
}

class GLES2DecoderDescheduleUntilFinishedTest : public GLES2DecoderTest {
 public:
  GLES2DecoderDescheduleUntilFinishedTest() = default;

  void SetUp() override {
    InitState init;
    init.gl_version = "4.4";
    init.extensions += " GL_ARB_compatibility GL_ARB_sync";
    InitDecoder(init);

    EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
        .Times(2)
        .WillOnce(Return(sync_service_id_))
        .WillOnce(Return(sync_service_id2_))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl_, IsSync(sync_service_id_)).WillRepeatedly(Return(GL_TRUE));
    EXPECT_CALL(*gl_, Flush()).Times(2).RetiresOnSaturation();
    EXPECT_CALL(*gl_, DeleteSync(sync_service_id_))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl_, DeleteSync(sync_service_id2_))
        .Times(1)
        .RetiresOnSaturation();
  }

  void OnDescheduleUntilFinished() override {
    deschedule_until_finished_callback_count_++;
  }
  void OnRescheduleAfterFinished() override {
    reschedule_after_finished_callback_count_++;
  }

 protected:
  int deschedule_until_finished_callback_count_ = 0;
  int reschedule_after_finished_callback_count_ = 0;
  GLsync sync_service_id_ = reinterpret_cast<GLsync>(0x15);
  GLsync sync_service_id2_ = reinterpret_cast<GLsync>(0x15);
};

TEST_P(GLES2DecoderDescheduleUntilFinishedTest, AlreadySignalled) {
  EXPECT_CALL(*gl_, ClientWaitSync(sync_service_id_, 0, 0))
      .Times(1)
      .WillOnce(Return(GL_ALREADY_SIGNALED))
      .RetiresOnSaturation();

  DescheduleUntilFinishedCHROMIUM cmd;
  cmd.Init();
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(0, deschedule_until_finished_callback_count_);
  EXPECT_EQ(0, reschedule_after_finished_callback_count_);

  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(0, deschedule_until_finished_callback_count_);
  EXPECT_EQ(0, reschedule_after_finished_callback_count_);
}

TEST_P(GLES2DecoderDescheduleUntilFinishedTest, NotYetSignalled) {
  EXPECT_CALL(*gl_, ClientWaitSync(sync_service_id_, 0, 0))
      .Times(1)
      .WillOnce(Return(GL_TIMEOUT_EXPIRED))
      .RetiresOnSaturation();

  DescheduleUntilFinishedCHROMIUM cmd;
  cmd.Init();
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(0, deschedule_until_finished_callback_count_);
  EXPECT_EQ(0, reschedule_after_finished_callback_count_);

  EXPECT_EQ(error::kDeferLaterCommands, ExecuteCmd(cmd));
  EXPECT_EQ(1, deschedule_until_finished_callback_count_);
  EXPECT_EQ(0, reschedule_after_finished_callback_count_);
}

void GLES3DecoderTest::SetUp() {
  InitState init;
  init.gl_version = "OpenGL ES 3.0";
  init.bind_generates_resource = true;
  init.context_type = CONTEXT_TYPE_OPENGLES3;
  InitDecoder(init);
}

void WebGL2DecoderTest::SetUp() {
  InitState init;
  init.gl_version = "OpenGL ES 3.0";
  init.bind_generates_resource = true;
  init.context_type = CONTEXT_TYPE_WEBGL2;
  InitDecoder(init);
}

void GLES3DecoderWithShaderTest::SetUp() {
  InitState init;
  init.gl_version = "OpenGL ES 3.0";
  init.bind_generates_resource = true;
  init.context_type = CONTEXT_TYPE_OPENGLES3;
  InitDecoder(init);
  SetupDefaultProgram();
}

void GLES3DecoderRGBBackbufferTest::SetUp() {
  InitState init;
  init.gl_version = "OpenGL ES 3.0";
  init.bind_generates_resource = true;
  init.context_type = CONTEXT_TYPE_OPENGLES3;
  InitDecoder(init);
  SetupDefaultProgram();
}

INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest, ::testing::Bool());

INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderWithShaderTest, ::testing::Bool());

INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderManualInitTest, ::testing::Bool());

INSTANTIATE_TEST_CASE_P(Service,
                        GLES2DecoderRGBBackbufferTest,
                        ::testing::Bool());

INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderDoCommandsTest, ::testing::Bool());

INSTANTIATE_TEST_CASE_P(Service,
                        GLES2DecoderDescheduleUntilFinishedTest,
                        ::testing::Bool());

INSTANTIATE_TEST_CASE_P(Service, GLES3DecoderTest, ::testing::Bool());

INSTANTIATE_TEST_CASE_P(Service, GLES3DecoderWithShaderTest, ::testing::Bool());

INSTANTIATE_TEST_CASE_P(Service, GLES3DecoderManualInitTest, ::testing::Bool());

INSTANTIATE_TEST_CASE_P(Service,
                        GLES3DecoderRGBBackbufferTest,
                        ::testing::Bool());

}  // namespace gles2
}  // namespace gpu
