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

#include "gpu/command_buffer/service/gles2_cmd_decoder.h"

#include <stdint.h>

#include "base/command_line.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_surface_mock.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"

#include "gpu/command_buffer/service/gpu_switches.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 "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_mock.h"
#include "ui/gl/gl_surface_stub.h"

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

using ::gl::MockGLInterface;
using ::testing::_;
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::SetArgPointee;
using ::testing::StrEq;
using ::testing::StrictMock;

namespace gpu {
namespace gles2 {

namespace {

void SetupUpdateES3UnpackParametersExpectations(::gl::MockGLInterface* gl,
                                                GLint row_length,
                                                GLint image_height) {
  EXPECT_CALL(*gl, PixelStorei(GL_UNPACK_ROW_LENGTH, row_length))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(*gl, PixelStorei(GL_UNPACK_IMAGE_HEIGHT, image_height))
      .Times(1)
      .RetiresOnSaturation();
}

}  // namespace anonymous

using namespace cmds;

class GLES2DecoderRestoreStateTest : public GLES2DecoderManualInitTest {
 public:
  GLES2DecoderRestoreStateTest() = default;

 protected:
  void AddExpectationsForActiveTexture(GLenum unit);
  void AddExpectationsForBindTexture(GLenum target, GLuint id);
  void InitializeContextState(ContextState* state,
                              uint32_t non_default_unit,
                              uint32_t active_unit);

  // ES3 specific.
  scoped_refptr<FeatureInfo> SetupForES3Test();
  void AddExpectationsForBindSampler(GLuint unit, GLuint id);
};

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

void GLES2DecoderRestoreStateTest::AddExpectationsForActiveTexture(
    GLenum unit) {
  EXPECT_CALL(*gl_, ActiveTexture(unit)).Times(1).RetiresOnSaturation();
}

void GLES2DecoderRestoreStateTest::AddExpectationsForBindTexture(GLenum target,
                                                                 GLuint id) {
  EXPECT_CALL(*gl_, BindTexture(target, id)).Times(1).RetiresOnSaturation();
}

void GLES2DecoderRestoreStateTest::InitializeContextState(
    ContextState* state,
    uint32_t non_default_unit,
    uint32_t active_unit) {
  state->texture_units.resize(group().max_texture_units());
  for (uint32_t tt = 0; tt < state->texture_units.size(); ++tt) {
    TextureRef* ref_cube_map =
        group().texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
    state->texture_units[tt].bound_texture_cube_map = ref_cube_map;
    TextureRef* ref_2d =
        (tt == non_default_unit)
            ? group().texture_manager()->GetTexture(client_texture_id_)
            : group().texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
    state->texture_units[tt].bound_texture_2d = ref_2d;
  }
  state->active_texture_unit = active_unit;

  // Set up the sampler units just for convenience of the ES3-specific
  // tests in this file.
  state->sampler_units.resize(group().max_texture_units());
}

scoped_refptr<FeatureInfo> GLES2DecoderRestoreStateTest::SetupForES3Test() {
  InitState init;
  init.gl_version = "OpenGL ES 3.0";
  init.context_type = CONTEXT_TYPE_OPENGLES3;
  InitDecoder(init);

  // Construct a previous ContextState assuming an ES3 context and with all
  // texture bindings set to default textures.
  scoped_refptr<FeatureInfo> feature_info = new FeatureInfo;
  TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
      gl_.get(), "", "", "OpenGL ES 3.0", CONTEXT_TYPE_OPENGLES3);
  feature_info->InitializeForTesting(CONTEXT_TYPE_OPENGLES3);
  return feature_info;
}

void GLES2DecoderRestoreStateTest::AddExpectationsForBindSampler(GLuint unit,
                                                                 GLuint id) {
  EXPECT_CALL(*gl_, BindSampler(unit, id)).Times(1).RetiresOnSaturation();
}

TEST_P(GLES2DecoderRestoreStateTest, NullPreviousStateBGR) {
  InitState init;
  init.bind_generates_resource = true;
  InitDecoder(init);
  SetupTexture();

  InSequence sequence;
  // Expect to restore texture bindings for unit GL_TEXTURE0.
  AddExpectationsForActiveTexture(GL_TEXTURE0);
  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
  AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP,
                                TestHelper::kServiceDefaultTextureCubemapId);

  // Expect to restore texture bindings for remaining units.
  for (uint32_t i = 1; i < group().max_texture_units(); ++i) {
    AddExpectationsForActiveTexture(GL_TEXTURE0 + i);
    AddExpectationsForBindTexture(GL_TEXTURE_2D,
                                  TestHelper::kServiceDefaultTexture2dId);
    AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP,
                                  TestHelper::kServiceDefaultTextureCubemapId);
  }

  // Expect to restore the active texture unit to GL_TEXTURE0.
  AddExpectationsForActiveTexture(GL_TEXTURE0);

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(nullptr);
}

TEST_P(GLES2DecoderRestoreStateTest, NullPreviousState) {
  InitState init;
  InitDecoder(init);
  SetupTexture();

  InSequence sequence;
  // Expect to restore texture bindings for unit GL_TEXTURE0.
  AddExpectationsForActiveTexture(GL_TEXTURE0);
  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
  AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP, 0);

  // Expect to restore texture bindings for remaining units.
  for (uint32_t i = 1; i < group().max_texture_units(); ++i) {
    AddExpectationsForActiveTexture(GL_TEXTURE0 + i);
    AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);
    AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP, 0);
  }

  // Expect to restore the active texture unit to GL_TEXTURE0.
  AddExpectationsForActiveTexture(GL_TEXTURE0);

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(nullptr);
}

TEST_P(GLES2DecoderRestoreStateTest, WithPreviousStateBGR) {
  InitState init;
  init.bind_generates_resource = true;
  InitDecoder(init);
  SetupTexture();

  // Construct a previous ContextState with all texture bindings
  // set to default textures.
  ContextState prev_state(nullptr);
  InitializeContextState(&prev_state, std::numeric_limits<uint32_t>::max(), 0);

  InSequence sequence;
  // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE0 unit,
  // since the rest of the bindings haven't changed between the current
  // state and the |prev_state|.
  AddExpectationsForActiveTexture(GL_TEXTURE0);
  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);

  // Expect to restore active texture unit to GL_TEXTURE0.
  AddExpectationsForActiveTexture(GL_TEXTURE0);

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state);
}

TEST_P(GLES2DecoderRestoreStateTest, WithPreviousState) {
  InitState init;
  InitDecoder(init);
  SetupTexture();

  // Construct a previous ContextState with all texture bindings
  // set to default textures.
  ContextState prev_state(nullptr);
  InitializeContextState(&prev_state, std::numeric_limits<uint32_t>::max(), 0);

  InSequence sequence;
  // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE0 unit,
  // since the rest of the bindings haven't changed between the current
  // state and the |prev_state|.
  AddExpectationsForActiveTexture(GL_TEXTURE0);
  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);

  // Expect to restore active texture unit to GL_TEXTURE0.
  AddExpectationsForActiveTexture(GL_TEXTURE0);

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state);
}

TEST_P(GLES2DecoderRestoreStateTest, ActiveUnit1) {
  InitState init;
  InitDecoder(init);

  // Bind a non-default texture to GL_TEXTURE1 unit.
  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
  ActiveTexture cmd;
  cmd.Init(GL_TEXTURE1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  SetupTexture();

  // Construct a previous ContextState with all texture bindings
  // set to default textures.
  ContextState prev_state(nullptr);
  InitializeContextState(&prev_state, std::numeric_limits<uint32_t>::max(), 0);

  InSequence sequence;
  // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE1 unit,
  // since the rest of the bindings haven't changed between the current
  // state and the |prev_state|.
  AddExpectationsForActiveTexture(GL_TEXTURE1);
  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);

  // Expect to restore active texture unit to GL_TEXTURE1.
  AddExpectationsForActiveTexture(GL_TEXTURE1);

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state);
}

TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit0BGR) {
  InitState init;
  init.bind_generates_resource = true;
  InitDecoder(init);

  // Bind a non-default texture to GL_TEXTURE1 unit.
  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
  SpecializedSetup<ActiveTexture, 0>(true);
  ActiveTexture cmd;
  cmd.Init(GL_TEXTURE1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  SetupTexture();

  // Construct a previous ContextState with GL_TEXTURE_2D target in
  // GL_TEXTURE0 unit bound to a non-default texture and the rest
  // set to default textures.
  ContextState prev_state(nullptr);
  InitializeContextState(&prev_state, 0, kServiceTextureId);

  InSequence sequence;
  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE0 unit to
  // a default texture.
  AddExpectationsForActiveTexture(GL_TEXTURE0);
  AddExpectationsForBindTexture(GL_TEXTURE_2D,
                                TestHelper::kServiceDefaultTexture2dId);

  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE1 unit to
  // non-default.
  AddExpectationsForActiveTexture(GL_TEXTURE1);
  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);

  // Expect to restore active texture unit to GL_TEXTURE1.
  AddExpectationsForActiveTexture(GL_TEXTURE1);

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state);
}

TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit1BGR) {
  InitState init;
  init.bind_generates_resource = true;
  InitDecoder(init);

  // Bind a non-default texture to GL_TEXTURE0 unit.
  SetupTexture();

  // Construct a previous ContextState with GL_TEXTURE_2D target in
  // GL_TEXTURE1 unit bound to a non-default texture and the rest
  // set to default textures.
  ContextState prev_state(nullptr);
  InitializeContextState(&prev_state, 1, kServiceTextureId);

  InSequence sequence;
  // Expect to restore GL_TEXTURE_2D binding to the non-default texture
  // for GL_TEXTURE0 unit.
  AddExpectationsForActiveTexture(GL_TEXTURE0);
  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);

  // Expect to restore GL_TEXTURE_2D binding to the default texture
  // for GL_TEXTURE1 unit.
  AddExpectationsForActiveTexture(GL_TEXTURE1);
  AddExpectationsForBindTexture(GL_TEXTURE_2D,
                                TestHelper::kServiceDefaultTexture2dId);

  // Expect to restore active texture unit to GL_TEXTURE0.
  AddExpectationsForActiveTexture(GL_TEXTURE0);

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state);
}

TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit0) {
  InitState init;
  InitDecoder(init);

  // Bind a non-default texture to GL_TEXTURE1 unit.
  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
  SpecializedSetup<ActiveTexture, 0>(true);
  ActiveTexture cmd;
  cmd.Init(GL_TEXTURE1);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
  SetupTexture();

  // Construct a previous ContextState with GL_TEXTURE_2D target in
  // GL_TEXTURE0 unit bound to a non-default texture and the rest
  // set to default textures.
  ContextState prev_state(nullptr);
  InitializeContextState(&prev_state, 0, kServiceTextureId);

  InSequence sequence;
  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE0 unit to
  // the 0 texture.
  AddExpectationsForActiveTexture(GL_TEXTURE0);
  AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);

  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE1 unit to
  // non-default.
  AddExpectationsForActiveTexture(GL_TEXTURE1);
  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);

  // Expect to restore active texture unit to GL_TEXTURE1.
  AddExpectationsForActiveTexture(GL_TEXTURE1);

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state);
}

TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit1) {
  InitState init;
  InitDecoder(init);

  // Bind a non-default texture to GL_TEXTURE0 unit.
  SetupTexture();

  // Construct a previous ContextState with GL_TEXTURE_2D target in
  // GL_TEXTURE1 unit bound to a non-default texture and the rest
  // set to default textures.
  ContextState prev_state(nullptr);
  InitializeContextState(&prev_state, 1, kServiceTextureId);

  InSequence sequence;
  // Expect to restore GL_TEXTURE_2D binding to the non-default texture
  // for GL_TEXTURE0 unit.
  AddExpectationsForActiveTexture(GL_TEXTURE0);
  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);

  // Expect to restore GL_TEXTURE_2D binding to the 0 texture
  // for GL_TEXTURE1 unit.
  AddExpectationsForActiveTexture(GL_TEXTURE1);
  AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);

  // Expect to restore active texture unit to GL_TEXTURE0.
  AddExpectationsForActiveTexture(GL_TEXTURE0);

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state);
}

TEST_P(GLES2DecoderRestoreStateTest, ES3NullPreviousStateWithSampler) {
  // This ES3-specific test is scoped within GLES2DecoderRestoreStateTest
  // to avoid doing large refactorings of these tests.
  InitState init;
  init.gl_version = "OpenGL ES 3.0";
  init.context_type = CONTEXT_TYPE_OPENGLES3;
  InitDecoder(init);
  SetupTexture();
  SetupSampler();

  InSequence sequence;
  // Expect to restore texture bindings for unit GL_TEXTURE0.
  AddExpectationsForActiveTexture(GL_TEXTURE0);
  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
  AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP, 0);
  AddExpectationsForBindTexture(GL_TEXTURE_2D_ARRAY, 0);
  AddExpectationsForBindTexture(GL_TEXTURE_3D, 0);
  // Expect to restore sampler binding for unit GL_TEXTURE0.
  AddExpectationsForBindSampler(0, kServiceSamplerId);

  // Expect to restore texture bindings for remaining units.
  for (uint32_t i = 1; i < group().max_texture_units(); ++i) {
    AddExpectationsForActiveTexture(GL_TEXTURE0 + i);
    AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);
    AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP, 0);
    AddExpectationsForBindTexture(GL_TEXTURE_2D_ARRAY, 0);
    AddExpectationsForBindTexture(GL_TEXTURE_3D, 0);
    AddExpectationsForBindSampler(i, 0);
  }

  // Expect to restore the active texture unit to GL_TEXTURE0.
  AddExpectationsForActiveTexture(GL_TEXTURE0);

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(nullptr);
}

TEST_P(GLES2DecoderRestoreStateTest, ES3RestoreExistingSampler) {
  // This ES3-specific test is scoped within GLES2DecoderRestoreStateTest
  // to avoid doing large refactorings of these tests.
  auto feature_info = SetupForES3Test();
  SetupSampler();

  // Construct a previous ContextState assuming an ES3 context and with all
  // texture bindings set to default textures.
  ContextState prev_state(feature_info.get());
  InitializeContextState(&prev_state, std::numeric_limits<uint32_t>::max(), 0);

  InSequence sequence;
  // Expect to restore sampler binding for unit GL_TEXTURE0.
  AddExpectationsForBindSampler(0, kServiceSamplerId);

  // Expect to restore the active texture unit to GL_TEXTURE0.
  AddExpectationsForActiveTexture(GL_TEXTURE0);

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state);
}

TEST_P(GLES2DecoderRestoreStateTest, ES3RestoreZeroSampler) {
  // This ES3-specific test is scoped within GLES2DecoderRestoreStateTest
  // to avoid doing large refactorings of these tests.
  auto feature_info = SetupForES3Test();

  // Construct a previous ContextState assuming an ES3 context and with all
  // texture bindings set to default textures.
  SamplerManager sampler_manager(feature_info.get());
  ContextState prev_state(feature_info.get());
  InitializeContextState(&prev_state, std::numeric_limits<uint32_t>::max(), 0);
  // Set up a sampler in the previous state. The client_id and service_id
  // don't matter except that they're non-zero.
  prev_state.sampler_units[0] = new Sampler(&sampler_manager, 1, 2);

  InSequence sequence;
  // Expect to restore the zero sampler on unit GL_TEXTURE0.
  AddExpectationsForBindSampler(0, 0);

  // Expect to restore the active texture unit to GL_TEXTURE0.
  AddExpectationsForActiveTexture(GL_TEXTURE0);

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(&prev_state);

  // Tell the sampler manager to destroy itself without a context so we
  // don't have to set up more expectations.
  sampler_manager.Destroy(false);
}

TEST_P(GLES2DecoderManualInitTest, ContextStateCapabilityCaching) {
  struct TestInfo {
    GLenum gl_enum;
    bool default_state;
    bool expect_set;
  };

  // TODO(vmiura): Should autogen this to match build_gles2_cmd_buffer.py.
  TestInfo test[] = {{GL_BLEND, false, true},
                     {GL_CULL_FACE, false, true},
                     {GL_DEPTH_TEST, false, false},
                     {GL_DITHER, true, true},
                     {GL_POLYGON_OFFSET_FILL, false, true},
                     {GL_SAMPLE_ALPHA_TO_COVERAGE, false, true},
                     {GL_SAMPLE_COVERAGE, false, true},
                     {GL_SCISSOR_TEST, false, true},
                     {GL_STENCIL_TEST, false, false},
                     {0, false, false}};

  InitState init;
  InitDecoder(init);

  for (int i = 0; test[i].gl_enum; i++) {
    bool enable_state = test[i].default_state;

    // Test setting default state initially is ignored.
    EnableDisableTest(test[i].gl_enum, enable_state, test[i].expect_set);

    // Test new and cached state changes.
    for (int n = 0; n < 3; n++) {
      enable_state = !enable_state;
      EnableDisableTest(test[i].gl_enum, enable_state, test[i].expect_set);
      EnableDisableTest(test[i].gl_enum, enable_state, test[i].expect_set);
    }
  }
}

TEST_P(GLES3DecoderTest, ES3PixelStoreiWithPixelUnpackBuffer) {
  // Without PIXEL_UNPACK_BUFFER bound, PixelStorei with unpack parameters
  // is cached and not passed down to GL.
  EXPECT_CALL(*gl_, PixelStorei(_, _)).Times(0);
  PixelStorei cmd;
  cmd.Init(GL_UNPACK_ROW_LENGTH, 8);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));

  // When a PIXEL_UNPACK_BUFFER is bound, all cached unpack parameters are
  // applied to GL.
  SetupUpdateES3UnpackParametersExpectations(gl_.get(), 8, 0);
  DoBindBuffer(GL_PIXEL_UNPACK_BUFFER, client_buffer_id_, kServiceBufferId);

  // Now with a bound PIXEL_UNPACK_BUFFER, all PixelStorei calls with unpack
  // parameters are applied to GL.
  EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_ROW_LENGTH, 16))
      .Times(1)
      .RetiresOnSaturation();
  cmd.Init(GL_UNPACK_ROW_LENGTH, 16);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));

  // Now unbind PIXEL_UNPACK_BUFFER, all ES3 unpack parameters are set back to
  // 0.
  SetupUpdateES3UnpackParametersExpectations(gl_.get(), 0, 0);
  DoBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0, 0);

  // Again, PixelStorei calls with unpack parameters are cached.
  EXPECT_CALL(*gl_, PixelStorei(_, _)).Times(0);
  cmd.Init(GL_UNPACK_ROW_LENGTH, 32);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));

  // Bind a PIXEL_UNPACK_BUFFER again.
  SetupUpdateES3UnpackParametersExpectations(gl_.get(), 32, 0);
  DoBindBuffer(GL_PIXEL_UNPACK_BUFFER, client_buffer_id_, kServiceBufferId);
}

TEST_P(GLES2DecoderManualInitTest, MipmapHintOnCoreProfile) {
  // On a core profile, glHint(GL_GENERATE_MIPMAP_HINT) should be a noop
  InitState init;
  init.gl_version = "3.2";
  InitDecoder(init);

  Hint cmd;
  cmd.Init(GL_GENERATE_MIPMAP_HINT, GL_NICEST);

  EXPECT_CALL(*gl_, Hint(GL_GENERATE_MIPMAP_HINT, GL_NICEST)).Times(0);
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

TEST_P(GLES2DecoderManualInitTest, MipmapHintOnCompatibilityProfile) {
  // On a compatibility profile, glHint(GL_GENERATE_MIPMAP_HINT) should be go
  // through
  InitState init;
  init.gl_version = "3.2";
  init.extensions += " GL_ARB_compatibility";
  InitDecoder(init);

  Hint cmd;
  cmd.Init(GL_GENERATE_MIPMAP_HINT, GL_NICEST);

  EXPECT_CALL(*gl_, Hint(GL_GENERATE_MIPMAP_HINT, GL_NICEST))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
  EXPECT_EQ(GL_NO_ERROR, GetGLError());
}

// TODO(vmiura): Tests for VAO restore.

// TODO(vmiura): Tests for ContextState::RestoreAttribute().

// TODO(vmiura): Tests for ContextState::RestoreBufferBindings().

// TODO(vmiura): Tests for ContextState::RestoreProgramBindings().

// TODO(vmiura): Tests for ContextState::RestoreRenderbufferBindings().

// TODO(vmiura): Tests for ContextState::RestoreProgramBindings().

// TODO(vmiura): Tests for ContextState::RestoreGlobalState().

}  // namespace gles2
}  // namespace gpu
