chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#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/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

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_SUITE_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.gl_version = "OpenGL ES 2.0";
  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;
  init.gl_version = "OpenGL ES 2.0";
  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));
  cmds::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<cmds::ActiveTexture, 0>(true);
  cmds::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<cmds::ActiveTexture, 0>(true);
  cmds::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);
  cmds::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);
}

// 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