// 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/cmd_buffer_engine.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() {}

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

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

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(NULL, NULL, NULL);
  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(NULL, NULL, NULL);
  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(NULL, NULL, NULL);
  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(NULL, NULL, NULL);
  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(NULL, NULL, NULL);
  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(NULL, NULL, NULL);
  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(NULL, NULL, NULL);
  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);
  // 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);
    AddExpectationsForBindSampler(i, 0);
  }

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

  GetDecoder()->RestoreAllTextureUnitAndSamplerBindings(NULL);
}

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(), NULL, NULL);
  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(), NULL, NULL);
  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
