Clone of chromium aad1ce808763f59c7a3753e08f1500a104ecc6fd refs/remotes/origin/HEAD
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
new file mode 100644
index 0000000..136834d
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -0,0 +1,1679 @@
+// 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_base.h"
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.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/logger.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/program_manager.h"
+#include "gpu/command_buffer/service/test_helper.h"
+#include "gpu/command_buffer/service/vertex_attrib_manager.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.h"
+
+using ::gfx::MockGLInterface;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::InvokeWithoutArgs;
+using ::testing::MatcherCast;
+using ::testing::Pointee;
+using ::testing::Return;
+using ::testing::SetArrayArgument;
+using ::testing::SetArgPointee;
+using ::testing::SetArgumentPointee;
+using ::testing::StrEq;
+using ::testing::StrictMock;
+using ::testing::WithArg;
+
+namespace {
+
+void NormalizeInitState(gpu::gles2::GLES2DecoderTestBase::InitState* init) {
+ CHECK(init);
+ const char* kVAOExtensions[] = {
+ "GL_OES_vertex_array_object",
+ "GL_ARB_vertex_array_object",
+ "GL_APPLE_vertex_array_object"
+ };
+ bool contains_vao_extension = false;
+ for (size_t ii = 0; ii < arraysize(kVAOExtensions); ++ii) {
+ if (init->extensions.find(kVAOExtensions[ii]) != std::string::npos) {
+ contains_vao_extension = true;
+ break;
+ }
+ }
+ if (init->use_native_vao) {
+ if (contains_vao_extension)
+ return;
+ if (!init->extensions.empty())
+ init->extensions += " ";
+ if (StartsWithASCII(init->gl_version, "opengl es", false)) {
+ init->extensions += kVAOExtensions[0];
+ } else {
+#if !defined(OS_MACOSX)
+ init->extensions += kVAOExtensions[1];
+#else
+ init->extensions += kVAOExtensions[2];
+#endif // OS_MACOSX
+ }
+ } else {
+ // Make sure we don't set up an invalid InitState.
+ CHECK(!contains_vao_extension);
+ }
+}
+
+} // namespace Anonymous
+
+namespace gpu {
+namespace gles2 {
+
+GLES2DecoderTestBase::GLES2DecoderTestBase()
+ : surface_(NULL),
+ context_(NULL),
+ memory_tracker_(NULL),
+ client_buffer_id_(100),
+ client_framebuffer_id_(101),
+ client_program_id_(102),
+ client_renderbuffer_id_(103),
+ client_shader_id_(104),
+ client_texture_id_(106),
+ client_element_buffer_id_(107),
+ client_vertex_shader_id_(121),
+ client_fragment_shader_id_(122),
+ client_query_id_(123),
+ client_vertexarray_id_(124),
+ service_renderbuffer_id_(0),
+ service_renderbuffer_valid_(false),
+ ignore_cached_state_for_test_(GetParam()),
+ cached_color_mask_red_(true),
+ cached_color_mask_green_(true),
+ cached_color_mask_blue_(true),
+ cached_color_mask_alpha_(true),
+ cached_depth_mask_(true),
+ cached_stencil_front_mask_(static_cast<GLuint>(-1)),
+ cached_stencil_back_mask_(static_cast<GLuint>(-1)) {
+ memset(immediate_buffer_, 0xEE, sizeof(immediate_buffer_));
+}
+
+GLES2DecoderTestBase::~GLES2DecoderTestBase() {}
+
+void GLES2DecoderTestBase::SetUp() {
+ InitState init;
+ init.gl_version = "3.0";
+ init.has_alpha = true;
+ init.has_depth = true;
+ init.request_alpha = true;
+ init.request_depth = true;
+ init.bind_generates_resource = true;
+ InitDecoder(init);
+}
+
+void GLES2DecoderTestBase::AddExpectationsForVertexAttribManager() {
+ for (GLint ii = 0; ii < kNumVertexAttribs; ++ii) {
+ EXPECT_CALL(*gl_, VertexAttrib4f(ii, 0.0f, 0.0f, 0.0f, 1.0f))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+}
+
+GLES2DecoderTestBase::InitState::InitState()
+ : has_alpha(false),
+ has_depth(false),
+ has_stencil(false),
+ request_alpha(false),
+ request_depth(false),
+ request_stencil(false),
+ bind_generates_resource(false),
+ lose_context_when_out_of_memory(false),
+ use_native_vao(true) {
+}
+
+void GLES2DecoderTestBase::InitDecoder(const InitState& init) {
+ InitDecoderWithCommandLine(init, NULL);
+}
+
+void GLES2DecoderTestBase::InitDecoderWithCommandLine(
+ const InitState& init,
+ const base::CommandLine* command_line) {
+ InitState normalized_init = init;
+ NormalizeInitState(&normalized_init);
+ Framebuffer::ClearFramebufferCompleteComboMap();
+
+ gfx::SetGLGetProcAddressProc(gfx::MockGLInterface::GetGLProcAddress);
+ gfx::GLSurface::InitializeOneOffWithMockBindingsForTests();
+
+ gl_.reset(new StrictMock<MockGLInterface>());
+ ::gfx::MockGLInterface::SetGLInterface(gl_.get());
+
+ SetupMockGLBehaviors();
+
+ // Only create stream texture manager if extension is requested.
+ std::vector<std::string> list;
+ base::SplitString(normalized_init.extensions, ' ', &list);
+ scoped_refptr<FeatureInfo> feature_info;
+ if (command_line)
+ feature_info = new FeatureInfo(*command_line);
+ group_ = scoped_refptr<ContextGroup>(
+ new ContextGroup(NULL,
+ memory_tracker_,
+ new ShaderTranslatorCache,
+ feature_info.get(),
+ normalized_init.bind_generates_resource));
+ bool use_default_textures = normalized_init.bind_generates_resource;
+
+ InSequence sequence;
+
+ surface_ = new gfx::GLSurfaceStub;
+ surface_->SetSize(gfx::Size(kBackBufferWidth, kBackBufferHeight));
+
+ // Context needs to be created before initializing ContextGroup, which will
+ // in turn initialize FeatureInfo, which needs a context to determine
+ // extension support.
+ context_ = new gfx::GLContextStubWithExtensions;
+ context_->AddExtensionsString(normalized_init.extensions.c_str());
+ context_->SetGLVersionString(normalized_init.gl_version.c_str());
+
+ context_->MakeCurrent(surface_.get());
+ gfx::GLSurface::InitializeDynamicMockBindingsForTests(context_.get());
+
+ TestHelper::SetupContextGroupInitExpectations(
+ gl_.get(),
+ DisallowedFeatures(),
+ normalized_init.extensions.c_str(),
+ normalized_init.gl_version.c_str(),
+ normalized_init.bind_generates_resource);
+
+ // We initialize the ContextGroup with a MockGLES2Decoder so that
+ // we can use the ContextGroup to figure out how the real GLES2Decoder
+ // will initialize itself.
+ mock_decoder_.reset(new MockGLES2Decoder());
+
+ // Install FakeDoCommands handler so we can use individual DoCommand()
+ // expectations.
+ EXPECT_CALL(*mock_decoder_, DoCommands(_, _, _, _)).WillRepeatedly(
+ Invoke(mock_decoder_.get(), &MockGLES2Decoder::FakeDoCommands));
+
+ EXPECT_TRUE(
+ group_->Initialize(mock_decoder_.get(), DisallowedFeatures()));
+
+ if (group_->feature_info()->feature_flags().native_vertex_array_object) {
+ EXPECT_CALL(*gl_, GenVertexArraysOES(1, _))
+ .WillOnce(SetArgumentPointee<1>(kServiceVertexArrayId))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindVertexArrayOES(_)).Times(1).RetiresOnSaturation();
+ }
+
+ if (group_->feature_info()->workarounds().init_vertex_attributes)
+ AddExpectationsForVertexAttribManager();
+
+ AddExpectationsForBindVertexArrayOES();
+
+ EXPECT_CALL(*gl_, EnableVertexAttribArray(0))
+ .Times(1)
+ .RetiresOnSaturation();
+ static GLuint attrib_0_id[] = {
+ kServiceAttrib0BufferId,
+ };
+ static GLuint fixed_attrib_buffer_id[] = {
+ kServiceFixedAttribBufferId,
+ };
+ EXPECT_CALL(*gl_, GenBuffersARB(arraysize(attrib_0_id), _))
+ .WillOnce(SetArrayArgument<1>(attrib_0_id,
+ attrib_0_id + arraysize(attrib_0_id)))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, kServiceAttrib0BufferId))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, VertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, 0))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GenBuffersARB(arraysize(fixed_attrib_buffer_id), _))
+ .WillOnce(SetArrayArgument<1>(
+ fixed_attrib_buffer_id,
+ fixed_attrib_buffer_id + arraysize(fixed_attrib_buffer_id)))
+ .RetiresOnSaturation();
+
+ for (GLint tt = 0; tt < TestHelper::kNumTextureUnits; ++tt) {
+ EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0 + tt))
+ .Times(1)
+ .RetiresOnSaturation();
+ if (group_->feature_info()->feature_flags().oes_egl_image_external) {
+ EXPECT_CALL(*gl_,
+ BindTexture(GL_TEXTURE_EXTERNAL_OES,
+ use_default_textures
+ ? TestHelper::kServiceDefaultExternalTextureId
+ : 0))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+ if (group_->feature_info()->feature_flags().arb_texture_rectangle) {
+ EXPECT_CALL(
+ *gl_,
+ BindTexture(GL_TEXTURE_RECTANGLE_ARB,
+ use_default_textures
+ ? TestHelper::kServiceDefaultRectangleTextureId
+ : 0))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+ EXPECT_CALL(*gl_,
+ BindTexture(GL_TEXTURE_CUBE_MAP,
+ use_default_textures
+ ? TestHelper::kServiceDefaultTextureCubemapId
+ : 0))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(
+ *gl_,
+ BindTexture(
+ GL_TEXTURE_2D,
+ use_default_textures ? TestHelper::kServiceDefaultTexture2dId : 0))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+ EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER, 0))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
+ .WillOnce(SetArgumentPointee<1>(normalized_init.has_alpha ? 8 : 0))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
+ .WillOnce(SetArgumentPointee<1>(normalized_init.has_depth ? 24 : 0))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
+ .WillOnce(SetArgumentPointee<1>(normalized_init.has_stencil ? 8 : 0))
+ .RetiresOnSaturation();
+
+ EXPECT_CALL(*gl_, Enable(GL_VERTEX_PROGRAM_POINT_SIZE))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ EXPECT_CALL(*gl_, Enable(GL_POINT_SPRITE))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ static GLint max_viewport_dims[] = {
+ kMaxViewportWidth,
+ kMaxViewportHeight
+ };
+ EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VIEWPORT_DIMS, _))
+ .WillOnce(SetArrayArgument<1>(
+ max_viewport_dims, max_viewport_dims + arraysize(max_viewport_dims)))
+ .RetiresOnSaturation();
+
+ SetupInitCapabilitiesExpectations();
+ SetupInitStateExpectations();
+
+ EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, 0))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER, 0))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindRenderbufferEXT(GL_RENDERBUFFER, 0))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ // TODO(boliu): Remove OS_ANDROID once crbug.com/259023 is fixed and the
+ // workaround has been reverted.
+#if !defined(OS_ANDROID)
+ EXPECT_CALL(*gl_, Clear(
+ GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
+ .Times(1)
+ .RetiresOnSaturation();
+#endif
+
+ engine_.reset(new StrictMock<MockCommandBufferEngine>());
+ scoped_refptr<gpu::Buffer> buffer =
+ engine_->GetSharedMemoryBuffer(kSharedMemoryId);
+ shared_memory_offset_ = kSharedMemoryOffset;
+ shared_memory_address_ =
+ reinterpret_cast<int8*>(buffer->memory()) + shared_memory_offset_;
+ shared_memory_id_ = kSharedMemoryId;
+ shared_memory_base_ = buffer->memory();
+
+ static const int32 kLoseContextWhenOutOfMemory = 0x10002;
+
+ int32 attributes[] = {
+ EGL_ALPHA_SIZE,
+ normalized_init.request_alpha ? 8 : 0,
+ EGL_DEPTH_SIZE,
+ normalized_init.request_depth ? 24 : 0,
+ EGL_STENCIL_SIZE,
+ normalized_init.request_stencil ? 8 : 0,
+ kLoseContextWhenOutOfMemory,
+ normalized_init.lose_context_when_out_of_memory ? 1 : 0, };
+ std::vector<int32> attribs(attributes, attributes + arraysize(attributes));
+
+ decoder_.reset(GLES2Decoder::Create(group_.get()));
+ decoder_->SetIgnoreCachedStateForTest(ignore_cached_state_for_test_);
+ decoder_->GetLogger()->set_log_synthesized_gl_errors(false);
+ decoder_->Initialize(surface_,
+ context_,
+ false,
+ surface_->GetSize(),
+ DisallowedFeatures(),
+ attribs);
+ decoder_->MakeCurrent();
+ decoder_->set_engine(engine_.get());
+ decoder_->BeginDecoding();
+
+ EXPECT_CALL(*gl_, GenBuffersARB(_, _))
+ .WillOnce(SetArgumentPointee<1>(kServiceBufferId))
+ .RetiresOnSaturation();
+ GenHelper<cmds::GenBuffersImmediate>(client_buffer_id_);
+ EXPECT_CALL(*gl_, GenFramebuffersEXT(_, _))
+ .WillOnce(SetArgumentPointee<1>(kServiceFramebufferId))
+ .RetiresOnSaturation();
+ GenHelper<cmds::GenFramebuffersImmediate>(client_framebuffer_id_);
+ EXPECT_CALL(*gl_, GenRenderbuffersEXT(_, _))
+ .WillOnce(SetArgumentPointee<1>(kServiceRenderbufferId))
+ .RetiresOnSaturation();
+ GenHelper<cmds::GenRenderbuffersImmediate>(client_renderbuffer_id_);
+ EXPECT_CALL(*gl_, GenTextures(_, _))
+ .WillOnce(SetArgumentPointee<1>(kServiceTextureId))
+ .RetiresOnSaturation();
+ GenHelper<cmds::GenTexturesImmediate>(client_texture_id_);
+ EXPECT_CALL(*gl_, GenBuffersARB(_, _))
+ .WillOnce(SetArgumentPointee<1>(kServiceElementBufferId))
+ .RetiresOnSaturation();
+ GenHelper<cmds::GenBuffersImmediate>(client_element_buffer_id_);
+
+ DoCreateProgram(client_program_id_, kServiceProgramId);
+ DoCreateShader(GL_VERTEX_SHADER, client_shader_id_, kServiceShaderId);
+
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+void GLES2DecoderTestBase::ResetDecoder() {
+ if (!decoder_.get())
+ return;
+ // All Tests should have read all their GLErrors before getting here.
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+ EXPECT_CALL(*gl_, DeleteBuffersARB(1, _))
+ .Times(2)
+ .RetiresOnSaturation();
+ if (group_->feature_info()->feature_flags().native_vertex_array_object) {
+ EXPECT_CALL(*gl_, DeleteVertexArraysOES(1, Pointee(kServiceVertexArrayId)))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+
+ decoder_->EndDecoding();
+ decoder_->Destroy(true);
+ decoder_.reset();
+ group_->Destroy(mock_decoder_.get(), false);
+ engine_.reset();
+ ::gfx::MockGLInterface::SetGLInterface(NULL);
+ gl_.reset();
+ gfx::ClearGLBindings();
+}
+
+void GLES2DecoderTestBase::TearDown() {
+ ResetDecoder();
+}
+
+void GLES2DecoderTestBase::ExpectEnableDisable(GLenum cap, bool enable) {
+ if (enable) {
+ EXPECT_CALL(*gl_, Enable(cap))
+ .Times(1)
+ .RetiresOnSaturation();
+ } else {
+ EXPECT_CALL(*gl_, Disable(cap))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+}
+
+
+GLint GLES2DecoderTestBase::GetGLError() {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ cmds::GetError cmd;
+ cmd.Init(shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ return static_cast<GLint>(*GetSharedMemoryAs<GLenum*>());
+}
+
+void GLES2DecoderTestBase::DoCreateShader(
+ GLenum shader_type, GLuint client_id, GLuint service_id) {
+ EXPECT_CALL(*gl_, CreateShader(shader_type))
+ .Times(1)
+ .WillOnce(Return(service_id))
+ .RetiresOnSaturation();
+ cmds::CreateShader cmd;
+ cmd.Init(shader_type, client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+bool GLES2DecoderTestBase::DoIsShader(GLuint client_id) {
+ return IsObjectHelper<cmds::IsShader, cmds::IsShader::Result>(client_id);
+}
+
+void GLES2DecoderTestBase::DoDeleteShader(
+ GLuint client_id, GLuint service_id) {
+ EXPECT_CALL(*gl_, DeleteShader(service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ cmds::DeleteShader cmd;
+ cmd.Init(client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::DoCreateProgram(
+ GLuint client_id, GLuint service_id) {
+ EXPECT_CALL(*gl_, CreateProgram())
+ .Times(1)
+ .WillOnce(Return(service_id))
+ .RetiresOnSaturation();
+ cmds::CreateProgram cmd;
+ cmd.Init(client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+bool GLES2DecoderTestBase::DoIsProgram(GLuint client_id) {
+ return IsObjectHelper<cmds::IsProgram, cmds::IsProgram::Result>(client_id);
+}
+
+void GLES2DecoderTestBase::DoDeleteProgram(
+ GLuint client_id, GLuint /* service_id */) {
+ cmds::DeleteProgram cmd;
+ cmd.Init(client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::SetBucketAsCString(
+ uint32 bucket_id, const char* str) {
+ uint32 size = str ? (strlen(str) + 1) : 0;
+ cmd::SetBucketSize cmd1;
+ cmd1.Init(bucket_id, size);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+ if (str) {
+ memcpy(shared_memory_address_, str, size);
+ cmd::SetBucketData cmd2;
+ cmd2.Init(bucket_id, 0, size, kSharedMemoryId, kSharedMemoryOffset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+ ClearSharedMemory();
+ }
+}
+
+void GLES2DecoderTestBase::SetupClearTextureExpectations(
+ GLuint service_id,
+ GLuint old_service_id,
+ GLenum bind_target,
+ GLenum target,
+ GLint level,
+ GLenum internal_format,
+ GLenum format,
+ GLenum type,
+ GLsizei width,
+ GLsizei height) {
+ EXPECT_CALL(*gl_, BindTexture(bind_target, service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, TexImage2D(
+ target, level, internal_format, width, height, 0, format, type, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindTexture(bind_target, old_service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+}
+
+void GLES2DecoderTestBase::SetupExpectationsForFramebufferClearing(
+ GLenum target,
+ GLuint clear_bits,
+ GLclampf restore_red,
+ GLclampf restore_green,
+ GLclampf restore_blue,
+ GLclampf restore_alpha,
+ GLuint restore_stencil,
+ GLclampf restore_depth,
+ bool restore_scissor_test) {
+ SetupExpectationsForFramebufferClearingMulti(
+ 0,
+ 0,
+ target,
+ clear_bits,
+ restore_red,
+ restore_green,
+ restore_blue,
+ restore_alpha,
+ restore_stencil,
+ restore_depth,
+ restore_scissor_test);
+}
+
+void GLES2DecoderTestBase::SetupExpectationsForRestoreClearState(
+ GLclampf restore_red,
+ GLclampf restore_green,
+ GLclampf restore_blue,
+ GLclampf restore_alpha,
+ GLuint restore_stencil,
+ GLclampf restore_depth,
+ bool restore_scissor_test) {
+ EXPECT_CALL(*gl_, ClearColor(
+ restore_red, restore_green, restore_blue, restore_alpha))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, ClearStencil(restore_stencil))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, ClearDepth(restore_depth))
+ .Times(1)
+ .RetiresOnSaturation();
+ if (restore_scissor_test) {
+ EXPECT_CALL(*gl_, Enable(GL_SCISSOR_TEST))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::SetupExpectationsForFramebufferClearingMulti(
+ GLuint read_framebuffer_service_id,
+ GLuint draw_framebuffer_service_id,
+ GLenum target,
+ GLuint clear_bits,
+ GLclampf restore_red,
+ GLclampf restore_green,
+ GLclampf restore_blue,
+ GLclampf restore_alpha,
+ GLuint restore_stencil,
+ GLclampf restore_depth,
+ bool restore_scissor_test) {
+ // TODO(gman): Figure out why InSequence stopped working.
+ // InSequence sequence;
+ EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(target))
+ .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
+ .RetiresOnSaturation();
+ if (target == GL_READ_FRAMEBUFFER_EXT) {
+ EXPECT_CALL(*gl_, BindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindFramebufferEXT(
+ GL_DRAW_FRAMEBUFFER_EXT, read_framebuffer_service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+ if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0) {
+ EXPECT_CALL(*gl_, ClearColor(0.0f, 0.0f, 0.0f, 0.0f))
+ .Times(1)
+ .RetiresOnSaturation();
+ SetupExpectationsForColorMask(true, true, true, true);
+ }
+ if ((clear_bits & GL_STENCIL_BUFFER_BIT) != 0) {
+ EXPECT_CALL(*gl_, ClearStencil(0))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, StencilMask(static_cast<GLuint>(-1)))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+ if ((clear_bits & GL_DEPTH_BUFFER_BIT) != 0) {
+ EXPECT_CALL(*gl_, ClearDepth(1.0f))
+ .Times(1)
+ .RetiresOnSaturation();
+ SetupExpectationsForDepthMask(true);
+ }
+ SetupExpectationsForEnableDisable(GL_SCISSOR_TEST, false);
+ EXPECT_CALL(*gl_, Clear(clear_bits))
+ .Times(1)
+ .RetiresOnSaturation();
+ SetupExpectationsForRestoreClearState(
+ restore_red, restore_green, restore_blue, restore_alpha,
+ restore_stencil, restore_depth, restore_scissor_test);
+ if (target == GL_READ_FRAMEBUFFER_EXT) {
+ EXPECT_CALL(*gl_, BindFramebufferEXT(
+ GL_READ_FRAMEBUFFER_EXT, read_framebuffer_service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindFramebufferEXT(
+ GL_DRAW_FRAMEBUFFER_EXT, draw_framebuffer_service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::SetupShaderForUniform(GLenum uniform_type) {
+ static AttribInfo attribs[] = {
+ { "foo", 1, GL_FLOAT, 1, },
+ { "goo", 1, GL_FLOAT, 2, },
+ };
+ UniformInfo uniforms[] = {
+ { "bar", 1, uniform_type, 0, 2, -1, },
+ { "car", 4, uniform_type, 1, 1, -1, },
+ };
+ const GLuint kClientVertexShaderId = 5001;
+ const GLuint kServiceVertexShaderId = 6001;
+ const GLuint kClientFragmentShaderId = 5002;
+ const GLuint kServiceFragmentShaderId = 6002;
+ SetupShader(attribs, arraysize(attribs), uniforms, arraysize(uniforms),
+ client_program_id_, kServiceProgramId,
+ kClientVertexShaderId, kServiceVertexShaderId,
+ kClientFragmentShaderId, kServiceFragmentShaderId);
+
+ EXPECT_CALL(*gl_, UseProgram(kServiceProgramId))
+ .Times(1)
+ .RetiresOnSaturation();
+ cmds::UseProgram cmd;
+ cmd.Init(client_program_id_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::DoBindBuffer(
+ GLenum target, GLuint client_id, GLuint service_id) {
+ EXPECT_CALL(*gl_, BindBuffer(target, service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ cmds::BindBuffer cmd;
+ cmd.Init(target, client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+bool GLES2DecoderTestBase::DoIsBuffer(GLuint client_id) {
+ return IsObjectHelper<cmds::IsBuffer, cmds::IsBuffer::Result>(client_id);
+}
+
+void GLES2DecoderTestBase::DoDeleteBuffer(
+ GLuint client_id, GLuint service_id) {
+ EXPECT_CALL(*gl_, DeleteBuffersARB(1, Pointee(service_id)))
+ .Times(1)
+ .RetiresOnSaturation();
+ GenHelper<cmds::DeleteBuffersImmediate>(client_id);
+}
+
+void GLES2DecoderTestBase::SetupExpectationsForColorMask(bool red,
+ bool green,
+ bool blue,
+ bool alpha) {
+ if (ignore_cached_state_for_test_ || cached_color_mask_red_ != red ||
+ cached_color_mask_green_ != green || cached_color_mask_blue_ != blue ||
+ cached_color_mask_alpha_ != alpha) {
+ cached_color_mask_red_ = red;
+ cached_color_mask_green_ = green;
+ cached_color_mask_blue_ = blue;
+ cached_color_mask_alpha_ = alpha;
+ EXPECT_CALL(*gl_, ColorMask(red, green, blue, alpha))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::SetupExpectationsForDepthMask(bool mask) {
+ if (ignore_cached_state_for_test_ || cached_depth_mask_ != mask) {
+ cached_depth_mask_ = mask;
+ EXPECT_CALL(*gl_, DepthMask(mask)).Times(1).RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::SetupExpectationsForStencilMask(GLuint front_mask,
+ GLuint back_mask) {
+ if (ignore_cached_state_for_test_ ||
+ cached_stencil_front_mask_ != front_mask) {
+ cached_stencil_front_mask_ = front_mask;
+ EXPECT_CALL(*gl_, StencilMaskSeparate(GL_FRONT, front_mask))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+
+ if (ignore_cached_state_for_test_ ||
+ cached_stencil_back_mask_ != back_mask) {
+ cached_stencil_back_mask_ = back_mask;
+ EXPECT_CALL(*gl_, StencilMaskSeparate(GL_BACK, back_mask))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::SetupExpectationsForEnableDisable(GLenum cap,
+ bool enable) {
+ switch (cap) {
+ case GL_BLEND:
+ if (enable_flags_.cached_blend == enable &&
+ !ignore_cached_state_for_test_)
+ return;
+ enable_flags_.cached_blend = enable;
+ break;
+ case GL_CULL_FACE:
+ if (enable_flags_.cached_cull_face == enable &&
+ !ignore_cached_state_for_test_)
+ return;
+ enable_flags_.cached_cull_face = enable;
+ break;
+ case GL_DEPTH_TEST:
+ if (enable_flags_.cached_depth_test == enable &&
+ !ignore_cached_state_for_test_)
+ return;
+ enable_flags_.cached_depth_test = enable;
+ break;
+ case GL_DITHER:
+ if (enable_flags_.cached_dither == enable &&
+ !ignore_cached_state_for_test_)
+ return;
+ enable_flags_.cached_dither = enable;
+ break;
+ case GL_POLYGON_OFFSET_FILL:
+ if (enable_flags_.cached_polygon_offset_fill == enable &&
+ !ignore_cached_state_for_test_)
+ return;
+ enable_flags_.cached_polygon_offset_fill = enable;
+ break;
+ case GL_SAMPLE_ALPHA_TO_COVERAGE:
+ if (enable_flags_.cached_sample_alpha_to_coverage == enable &&
+ !ignore_cached_state_for_test_)
+ return;
+ enable_flags_.cached_sample_alpha_to_coverage = enable;
+ break;
+ case GL_SAMPLE_COVERAGE:
+ if (enable_flags_.cached_sample_coverage == enable &&
+ !ignore_cached_state_for_test_)
+ return;
+ enable_flags_.cached_sample_coverage = enable;
+ break;
+ case GL_SCISSOR_TEST:
+ if (enable_flags_.cached_scissor_test == enable &&
+ !ignore_cached_state_for_test_)
+ return;
+ enable_flags_.cached_scissor_test = enable;
+ break;
+ case GL_STENCIL_TEST:
+ if (enable_flags_.cached_stencil_test == enable &&
+ !ignore_cached_state_for_test_)
+ return;
+ enable_flags_.cached_stencil_test = enable;
+ break;
+ default:
+ NOTREACHED();
+ return;
+ }
+ if (enable) {
+ EXPECT_CALL(*gl_, Enable(cap)).Times(1).RetiresOnSaturation();
+ } else {
+ EXPECT_CALL(*gl_, Disable(cap)).Times(1).RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::SetupExpectationsForApplyingDirtyState(
+ bool framebuffer_is_rgb,
+ bool framebuffer_has_depth,
+ bool framebuffer_has_stencil,
+ GLuint color_bits,
+ bool depth_mask,
+ bool depth_enabled,
+ GLuint front_stencil_mask,
+ GLuint back_stencil_mask,
+ bool stencil_enabled) {
+ bool color_mask_red = (color_bits & 0x1000) != 0;
+ bool color_mask_green = (color_bits & 0x0100) != 0;
+ bool color_mask_blue = (color_bits & 0x0010) != 0;
+ bool color_mask_alpha = (color_bits & 0x0001) && !framebuffer_is_rgb;
+
+ SetupExpectationsForColorMask(
+ color_mask_red, color_mask_green, color_mask_blue, color_mask_alpha);
+ SetupExpectationsForDepthMask(depth_mask);
+ SetupExpectationsForStencilMask(front_stencil_mask, back_stencil_mask);
+ SetupExpectationsForEnableDisable(GL_DEPTH_TEST,
+ framebuffer_has_depth && depth_enabled);
+ SetupExpectationsForEnableDisable(GL_STENCIL_TEST,
+ framebuffer_has_stencil && stencil_enabled);
+}
+
+void GLES2DecoderTestBase::SetupExpectationsForApplyingDefaultDirtyState() {
+ SetupExpectationsForApplyingDirtyState(false, // Framebuffer is RGB
+ false, // Framebuffer has depth
+ false, // Framebuffer has stencil
+ 0x1111, // color bits
+ true, // depth mask
+ false, // depth enabled
+ 0, // front stencil mask
+ 0, // back stencil mask
+ false); // stencil enabled
+}
+
+GLES2DecoderTestBase::EnableFlags::EnableFlags()
+ : cached_blend(false),
+ cached_cull_face(false),
+ cached_depth_test(false),
+ cached_dither(true),
+ cached_polygon_offset_fill(false),
+ cached_sample_alpha_to_coverage(false),
+ cached_sample_coverage(false),
+ cached_scissor_test(false),
+ cached_stencil_test(false) {
+}
+
+void GLES2DecoderTestBase::DoBindFramebuffer(
+ GLenum target, GLuint client_id, GLuint service_id) {
+ EXPECT_CALL(*gl_, BindFramebufferEXT(target, service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ cmds::BindFramebuffer cmd;
+ cmd.Init(target, client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+bool GLES2DecoderTestBase::DoIsFramebuffer(GLuint client_id) {
+ return IsObjectHelper<cmds::IsFramebuffer, cmds::IsFramebuffer::Result>(
+ client_id);
+}
+
+void GLES2DecoderTestBase::DoDeleteFramebuffer(
+ GLuint client_id, GLuint service_id,
+ bool reset_draw, GLenum draw_target, GLuint draw_id,
+ bool reset_read, GLenum read_target, GLuint read_id) {
+ if (reset_draw) {
+ EXPECT_CALL(*gl_, BindFramebufferEXT(draw_target, draw_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+ if (reset_read) {
+ EXPECT_CALL(*gl_, BindFramebufferEXT(read_target, read_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+ EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, Pointee(service_id)))
+ .Times(1)
+ .RetiresOnSaturation();
+ GenHelper<cmds::DeleteFramebuffersImmediate>(client_id);
+}
+
+void GLES2DecoderTestBase::DoBindRenderbuffer(
+ GLenum target, GLuint client_id, GLuint service_id) {
+ service_renderbuffer_id_ = service_id;
+ service_renderbuffer_valid_ = true;
+ EXPECT_CALL(*gl_, BindRenderbufferEXT(target, service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ cmds::BindRenderbuffer cmd;
+ cmd.Init(target, client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::DoRenderbufferStorageMultisampleCHROMIUM(
+ GLenum target,
+ GLsizei samples,
+ GLenum internal_format,
+ GLenum gl_format,
+ GLsizei width,
+ GLsizei height) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_,
+ RenderbufferStorageMultisampleEXT(
+ target, samples, gl_format, width, height))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ cmds::RenderbufferStorageMultisampleCHROMIUM cmd;
+ cmd.Init(target, samples, internal_format, width, height);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+void GLES2DecoderTestBase::RestoreRenderbufferBindings() {
+ GetDecoder()->RestoreRenderbufferBindings();
+ service_renderbuffer_valid_ = false;
+}
+
+void GLES2DecoderTestBase::EnsureRenderbufferBound(bool expect_bind) {
+ EXPECT_NE(expect_bind, service_renderbuffer_valid_);
+
+ if (expect_bind) {
+ service_renderbuffer_valid_ = true;
+ EXPECT_CALL(*gl_,
+ BindRenderbufferEXT(GL_RENDERBUFFER, service_renderbuffer_id_))
+ .Times(1)
+ .RetiresOnSaturation();
+ } else {
+ EXPECT_CALL(*gl_, BindRenderbufferEXT(_, _)).Times(0);
+ }
+}
+
+bool GLES2DecoderTestBase::DoIsRenderbuffer(GLuint client_id) {
+ return IsObjectHelper<cmds::IsRenderbuffer, cmds::IsRenderbuffer::Result>(
+ client_id);
+}
+
+void GLES2DecoderTestBase::DoDeleteRenderbuffer(
+ GLuint client_id, GLuint service_id) {
+ EXPECT_CALL(*gl_, DeleteRenderbuffersEXT(1, Pointee(service_id)))
+ .Times(1)
+ .RetiresOnSaturation();
+ GenHelper<cmds::DeleteRenderbuffersImmediate>(client_id);
+}
+
+void GLES2DecoderTestBase::DoBindTexture(
+ GLenum target, GLuint client_id, GLuint service_id) {
+ EXPECT_CALL(*gl_, BindTexture(target, service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ cmds::BindTexture cmd;
+ cmd.Init(target, client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+bool GLES2DecoderTestBase::DoIsTexture(GLuint client_id) {
+ return IsObjectHelper<cmds::IsTexture, cmds::IsTexture::Result>(client_id);
+}
+
+void GLES2DecoderTestBase::DoDeleteTexture(
+ GLuint client_id, GLuint service_id) {
+ EXPECT_CALL(*gl_, DeleteTextures(1, Pointee(service_id)))
+ .Times(1)
+ .RetiresOnSaturation();
+ GenHelper<cmds::DeleteTexturesImmediate>(client_id);
+}
+
+void GLES2DecoderTestBase::DoTexImage2D(
+ GLenum target, GLint level, GLenum internal_format,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type,
+ uint32 shared_memory_id, uint32 shared_memory_offset) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, TexImage2D(target, level, internal_format,
+ width, height, border, format, type, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ cmds::TexImage2D cmd;
+ cmd.Init(target, level, internal_format, width, height, format,
+ type, shared_memory_id, shared_memory_offset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::DoTexImage2DConvertInternalFormat(
+ GLenum target, GLint level, GLenum requested_internal_format,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type,
+ uint32 shared_memory_id, uint32 shared_memory_offset,
+ GLenum expected_internal_format) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, TexImage2D(target, level, expected_internal_format,
+ width, height, border, format, type, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ cmds::TexImage2D cmd;
+ cmd.Init(target, level, requested_internal_format, width, height,
+ format, type, shared_memory_id, shared_memory_offset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::DoCompressedTexImage2D(
+ GLenum target, GLint level, GLenum format,
+ GLsizei width, GLsizei height, GLint border,
+ GLsizei size, uint32 bucket_id) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, CompressedTexImage2D(
+ target, level, format, width, height, border, size, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ CommonDecoder::Bucket* bucket = decoder_->CreateBucket(bucket_id);
+ bucket->SetSize(size);
+ cmds::CompressedTexImage2DBucket cmd;
+ cmd.Init(
+ target, level, format, width, height,
+ bucket_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::DoRenderbufferStorage(
+ GLenum target, GLenum internal_format, GLenum actual_format,
+ GLsizei width, GLsizei height, GLenum error) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, RenderbufferStorageEXT(
+ target, actual_format, width, height))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(error))
+ .RetiresOnSaturation();
+ cmds::RenderbufferStorage cmd;
+ cmd.Init(target, internal_format, width, height);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::DoFramebufferTexture2D(
+ GLenum target, GLenum attachment, GLenum textarget,
+ GLuint texture_client_id, GLuint texture_service_id, GLint level,
+ GLenum error) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, FramebufferTexture2DEXT(
+ target, attachment, textarget, texture_service_id, level))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(error))
+ .RetiresOnSaturation();
+ cmds::FramebufferTexture2D cmd;
+ cmd.Init(target, attachment, textarget, texture_client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::DoFramebufferRenderbuffer(
+ GLenum target,
+ GLenum attachment,
+ GLenum renderbuffer_target,
+ GLuint renderbuffer_client_id,
+ GLuint renderbuffer_service_id,
+ GLenum error) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
+ target, attachment, renderbuffer_target, renderbuffer_service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(error))
+ .RetiresOnSaturation();
+ cmds::FramebufferRenderbuffer cmd;
+ cmd.Init(target, attachment, renderbuffer_target, renderbuffer_client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::DoVertexAttribPointer(
+ GLuint index, GLint size, GLenum type, GLsizei stride, GLuint offset) {
+ EXPECT_CALL(*gl_,
+ VertexAttribPointer(index, size, type, GL_FALSE, stride,
+ BufferOffset(offset)))
+ .Times(1)
+ .RetiresOnSaturation();
+ cmds::VertexAttribPointer cmd;
+ cmd.Init(index, size, GL_FLOAT, GL_FALSE, stride, offset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::DoVertexAttribDivisorANGLE(
+ GLuint index, GLuint divisor) {
+ EXPECT_CALL(*gl_,
+ VertexAttribDivisorANGLE(index, divisor))
+ .Times(1)
+ .RetiresOnSaturation();
+ cmds::VertexAttribDivisorANGLE cmd;
+ cmd.Init(index, divisor);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::AddExpectationsForGenVertexArraysOES(){
+ if (group_->feature_info()->feature_flags().native_vertex_array_object) {
+ EXPECT_CALL(*gl_, GenVertexArraysOES(1, _))
+ .WillOnce(SetArgumentPointee<1>(kServiceVertexArrayId))
+ .RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::AddExpectationsForDeleteVertexArraysOES(){
+ if (group_->feature_info()->feature_flags().native_vertex_array_object) {
+ EXPECT_CALL(*gl_, DeleteVertexArraysOES(1, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::AddExpectationsForDeleteBoundVertexArraysOES() {
+ // Expectations are the same as a delete, followed by binding VAO 0.
+ AddExpectationsForDeleteVertexArraysOES();
+ AddExpectationsForBindVertexArrayOES();
+}
+
+void GLES2DecoderTestBase::AddExpectationsForBindVertexArrayOES() {
+ if (group_->feature_info()->feature_flags().native_vertex_array_object) {
+ EXPECT_CALL(*gl_, BindVertexArrayOES(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ } else {
+ for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
+ AddExpectationsForRestoreAttribState(vv);
+ }
+
+ EXPECT_CALL(*gl_, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::AddExpectationsForRestoreAttribState(GLuint attrib) {
+ EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, _))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ EXPECT_CALL(*gl_, VertexAttribPointer(attrib, _, _, _, _, _))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(attrib, _))
+ .Times(testing::AtMost(1))
+ .RetiresOnSaturation();
+
+ EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, _))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ if (attrib != 0 ||
+ gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
+
+ // TODO(bajones): Not sure if I can tell which of these will be called
+ EXPECT_CALL(*gl_, EnableVertexAttribArray(attrib))
+ .Times(testing::AtMost(1))
+ .RetiresOnSaturation();
+
+ EXPECT_CALL(*gl_, DisableVertexAttribArray(attrib))
+ .Times(testing::AtMost(1))
+ .RetiresOnSaturation();
+ }
+}
+
+// GCC requires these declarations, but MSVC requires they not be present
+#ifndef COMPILER_MSVC
+const int GLES2DecoderTestBase::kBackBufferWidth;
+const int GLES2DecoderTestBase::kBackBufferHeight;
+
+const GLint GLES2DecoderTestBase::kMaxTextureSize;
+const GLint GLES2DecoderTestBase::kMaxCubeMapTextureSize;
+const GLint GLES2DecoderTestBase::kNumVertexAttribs;
+const GLint GLES2DecoderTestBase::kNumTextureUnits;
+const GLint GLES2DecoderTestBase::kMaxTextureImageUnits;
+const GLint GLES2DecoderTestBase::kMaxVertexTextureImageUnits;
+const GLint GLES2DecoderTestBase::kMaxFragmentUniformVectors;
+const GLint GLES2DecoderTestBase::kMaxVaryingVectors;
+const GLint GLES2DecoderTestBase::kMaxVertexUniformVectors;
+const GLint GLES2DecoderTestBase::kMaxViewportWidth;
+const GLint GLES2DecoderTestBase::kMaxViewportHeight;
+
+const GLint GLES2DecoderTestBase::kViewportX;
+const GLint GLES2DecoderTestBase::kViewportY;
+const GLint GLES2DecoderTestBase::kViewportWidth;
+const GLint GLES2DecoderTestBase::kViewportHeight;
+
+const GLuint GLES2DecoderTestBase::kServiceAttrib0BufferId;
+const GLuint GLES2DecoderTestBase::kServiceFixedAttribBufferId;
+
+const GLuint GLES2DecoderTestBase::kServiceBufferId;
+const GLuint GLES2DecoderTestBase::kServiceFramebufferId;
+const GLuint GLES2DecoderTestBase::kServiceRenderbufferId;
+const GLuint GLES2DecoderTestBase::kServiceTextureId;
+const GLuint GLES2DecoderTestBase::kServiceProgramId;
+const GLuint GLES2DecoderTestBase::kServiceShaderId;
+const GLuint GLES2DecoderTestBase::kServiceElementBufferId;
+const GLuint GLES2DecoderTestBase::kServiceQueryId;
+const GLuint GLES2DecoderTestBase::kServiceVertexArrayId;
+
+const int32 GLES2DecoderTestBase::kSharedMemoryId;
+const size_t GLES2DecoderTestBase::kSharedBufferSize;
+const uint32 GLES2DecoderTestBase::kSharedMemoryOffset;
+const int32 GLES2DecoderTestBase::kInvalidSharedMemoryId;
+const uint32 GLES2DecoderTestBase::kInvalidSharedMemoryOffset;
+const uint32 GLES2DecoderTestBase::kInitialResult;
+const uint8 GLES2DecoderTestBase::kInitialMemoryValue;
+
+const uint32 GLES2DecoderTestBase::kNewClientId;
+const uint32 GLES2DecoderTestBase::kNewServiceId;
+const uint32 GLES2DecoderTestBase::kInvalidClientId;
+
+const GLuint GLES2DecoderTestBase::kServiceVertexShaderId;
+const GLuint GLES2DecoderTestBase::kServiceFragmentShaderId;
+
+const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumShaderId;
+const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumProgramId;
+
+const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumTextureBufferId;
+const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumVertexBufferId;
+const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumFBOId;
+const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumPositionAttrib;
+const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumTexAttrib;
+const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumSamplerLocation;
+
+const GLsizei GLES2DecoderTestBase::kNumVertices;
+const GLsizei GLES2DecoderTestBase::kNumIndices;
+const int GLES2DecoderTestBase::kValidIndexRangeStart;
+const int GLES2DecoderTestBase::kValidIndexRangeCount;
+const int GLES2DecoderTestBase::kInvalidIndexRangeStart;
+const int GLES2DecoderTestBase::kInvalidIndexRangeCount;
+const int GLES2DecoderTestBase::kOutOfRangeIndexRangeEnd;
+const GLuint GLES2DecoderTestBase::kMaxValidIndex;
+
+const GLint GLES2DecoderTestBase::kMaxAttribLength;
+const GLint GLES2DecoderTestBase::kAttrib1Size;
+const GLint GLES2DecoderTestBase::kAttrib2Size;
+const GLint GLES2DecoderTestBase::kAttrib3Size;
+const GLint GLES2DecoderTestBase::kAttrib1Location;
+const GLint GLES2DecoderTestBase::kAttrib2Location;
+const GLint GLES2DecoderTestBase::kAttrib3Location;
+const GLenum GLES2DecoderTestBase::kAttrib1Type;
+const GLenum GLES2DecoderTestBase::kAttrib2Type;
+const GLenum GLES2DecoderTestBase::kAttrib3Type;
+const GLint GLES2DecoderTestBase::kInvalidAttribLocation;
+const GLint GLES2DecoderTestBase::kBadAttribIndex;
+
+const GLint GLES2DecoderTestBase::kMaxUniformLength;
+const GLint GLES2DecoderTestBase::kUniform1Size;
+const GLint GLES2DecoderTestBase::kUniform2Size;
+const GLint GLES2DecoderTestBase::kUniform3Size;
+const GLint GLES2DecoderTestBase::kUniform1RealLocation;
+const GLint GLES2DecoderTestBase::kUniform2RealLocation;
+const GLint GLES2DecoderTestBase::kUniform2ElementRealLocation;
+const GLint GLES2DecoderTestBase::kUniform3RealLocation;
+const GLint GLES2DecoderTestBase::kUniform1FakeLocation;
+const GLint GLES2DecoderTestBase::kUniform2FakeLocation;
+const GLint GLES2DecoderTestBase::kUniform2ElementFakeLocation;
+const GLint GLES2DecoderTestBase::kUniform3FakeLocation;
+const GLint GLES2DecoderTestBase::kUniform1DesiredLocation;
+const GLint GLES2DecoderTestBase::kUniform2DesiredLocation;
+const GLint GLES2DecoderTestBase::kUniform3DesiredLocation;
+const GLenum GLES2DecoderTestBase::kUniform1Type;
+const GLenum GLES2DecoderTestBase::kUniform2Type;
+const GLenum GLES2DecoderTestBase::kUniform3Type;
+const GLenum GLES2DecoderTestBase::kUniformCubemapType;
+const GLint GLES2DecoderTestBase::kInvalidUniformLocation;
+const GLint GLES2DecoderTestBase::kBadUniformIndex;
+
+#endif
+
+const char* GLES2DecoderTestBase::kAttrib1Name = "attrib1";
+const char* GLES2DecoderTestBase::kAttrib2Name = "attrib2";
+const char* GLES2DecoderTestBase::kAttrib3Name = "attrib3";
+const char* GLES2DecoderTestBase::kUniform1Name = "uniform1";
+const char* GLES2DecoderTestBase::kUniform2Name = "uniform2[0]";
+const char* GLES2DecoderTestBase::kUniform3Name = "uniform3[0]";
+
+void GLES2DecoderTestBase::SetupDefaultProgram() {
+ {
+ static AttribInfo attribs[] = {
+ { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
+ { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
+ { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
+ };
+ static UniformInfo uniforms[] = {
+ { kUniform1Name, kUniform1Size, kUniform1Type,
+ kUniform1FakeLocation, kUniform1RealLocation,
+ kUniform1DesiredLocation },
+ { kUniform2Name, kUniform2Size, kUniform2Type,
+ kUniform2FakeLocation, kUniform2RealLocation,
+ kUniform2DesiredLocation },
+ { kUniform3Name, kUniform3Size, kUniform3Type,
+ kUniform3FakeLocation, kUniform3RealLocation,
+ kUniform3DesiredLocation },
+ };
+ SetupShader(attribs, arraysize(attribs), uniforms, arraysize(uniforms),
+ client_program_id_, kServiceProgramId,
+ client_vertex_shader_id_, kServiceVertexShaderId,
+ client_fragment_shader_id_, kServiceFragmentShaderId);
+ }
+
+ {
+ EXPECT_CALL(*gl_, UseProgram(kServiceProgramId))
+ .Times(1)
+ .RetiresOnSaturation();
+ cmds::UseProgram cmd;
+ cmd.Init(client_program_id_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ }
+}
+
+void GLES2DecoderTestBase::SetupCubemapProgram() {
+ {
+ static AttribInfo attribs[] = {
+ { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
+ { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
+ { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
+ };
+ static UniformInfo uniforms[] = {
+ { kUniform1Name, kUniform1Size, kUniformCubemapType,
+ kUniform1FakeLocation, kUniform1RealLocation,
+ kUniform1DesiredLocation, },
+ { kUniform2Name, kUniform2Size, kUniform2Type,
+ kUniform2FakeLocation, kUniform2RealLocation,
+ kUniform2DesiredLocation, },
+ { kUniform3Name, kUniform3Size, kUniform3Type,
+ kUniform3FakeLocation, kUniform3RealLocation,
+ kUniform3DesiredLocation, },
+ };
+ SetupShader(attribs, arraysize(attribs), uniforms, arraysize(uniforms),
+ client_program_id_, kServiceProgramId,
+ client_vertex_shader_id_, kServiceVertexShaderId,
+ client_fragment_shader_id_, kServiceFragmentShaderId);
+ }
+
+ {
+ EXPECT_CALL(*gl_, UseProgram(kServiceProgramId))
+ .Times(1)
+ .RetiresOnSaturation();
+ cmds::UseProgram cmd;
+ cmd.Init(client_program_id_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ }
+}
+
+void GLES2DecoderTestBase::SetupSamplerExternalProgram() {
+ {
+ static AttribInfo attribs[] = {
+ { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
+ { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
+ { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
+ };
+ static UniformInfo uniforms[] = {
+ { kUniform1Name, kUniform1Size, kUniformSamplerExternalType,
+ kUniform1FakeLocation, kUniform1RealLocation,
+ kUniform1DesiredLocation, },
+ { kUniform2Name, kUniform2Size, kUniform2Type,
+ kUniform2FakeLocation, kUniform2RealLocation,
+ kUniform2DesiredLocation, },
+ { kUniform3Name, kUniform3Size, kUniform3Type,
+ kUniform3FakeLocation, kUniform3RealLocation,
+ kUniform3DesiredLocation, },
+ };
+ SetupShader(attribs, arraysize(attribs), uniforms, arraysize(uniforms),
+ client_program_id_, kServiceProgramId,
+ client_vertex_shader_id_, kServiceVertexShaderId,
+ client_fragment_shader_id_, kServiceFragmentShaderId);
+ }
+
+ {
+ EXPECT_CALL(*gl_, UseProgram(kServiceProgramId))
+ .Times(1)
+ .RetiresOnSaturation();
+ cmds::UseProgram cmd;
+ cmd.Init(client_program_id_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ }
+}
+
+void GLES2DecoderWithShaderTestBase::TearDown() {
+ GLES2DecoderTestBase::TearDown();
+}
+
+void GLES2DecoderTestBase::SetupShader(
+ GLES2DecoderTestBase::AttribInfo* attribs, size_t num_attribs,
+ GLES2DecoderTestBase::UniformInfo* uniforms, size_t num_uniforms,
+ GLuint program_client_id, GLuint program_service_id,
+ GLuint vertex_shader_client_id, GLuint vertex_shader_service_id,
+ GLuint fragment_shader_client_id, GLuint fragment_shader_service_id) {
+ {
+ InSequence s;
+
+ EXPECT_CALL(*gl_,
+ AttachShader(program_service_id, vertex_shader_service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_,
+ AttachShader(program_service_id, fragment_shader_service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ TestHelper::SetupShader(
+ gl_.get(), attribs, num_attribs, uniforms, num_uniforms,
+ program_service_id);
+ }
+
+ DoCreateShader(
+ GL_VERTEX_SHADER, vertex_shader_client_id, vertex_shader_service_id);
+ DoCreateShader(
+ GL_FRAGMENT_SHADER, fragment_shader_client_id,
+ fragment_shader_service_id);
+
+ TestHelper::SetShaderStates(
+ gl_.get(), GetShader(vertex_shader_client_id), true);
+ TestHelper::SetShaderStates(
+ gl_.get(), GetShader(fragment_shader_client_id), true);
+
+ cmds::AttachShader attach_cmd;
+ attach_cmd.Init(program_client_id, vertex_shader_client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(attach_cmd));
+
+ attach_cmd.Init(program_client_id, fragment_shader_client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(attach_cmd));
+
+ cmds::LinkProgram link_cmd;
+ link_cmd.Init(program_client_id);
+
+ EXPECT_EQ(error::kNoError, ExecuteCmd(link_cmd));
+}
+
+void GLES2DecoderTestBase::DoEnableDisable(GLenum cap, bool enable) {
+ SetupExpectationsForEnableDisable(cap, enable);
+ if (enable) {
+ cmds::Enable cmd;
+ cmd.Init(cap);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ } else {
+ cmds::Disable cmd;
+ cmd.Init(cap);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ }
+}
+
+void GLES2DecoderTestBase::DoEnableVertexAttribArray(GLint index) {
+ EXPECT_CALL(*gl_, EnableVertexAttribArray(index))
+ .Times(1)
+ .RetiresOnSaturation();
+ cmds::EnableVertexAttribArray cmd;
+ cmd.Init(index);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::DoBufferData(GLenum target, GLsizei size) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BufferData(target, size, _, GL_STREAM_DRAW))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ cmds::BufferData cmd;
+ cmd.Init(target, size, 0, 0, GL_STREAM_DRAW);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::DoBufferSubData(
+ GLenum target, GLint offset, GLsizei size, const void* data) {
+ EXPECT_CALL(*gl_, BufferSubData(target, offset, size,
+ shared_memory_address_))
+ .Times(1)
+ .RetiresOnSaturation();
+ memcpy(shared_memory_address_, data, size);
+ cmds::BufferSubData cmd;
+ cmd.Init(target, offset, size, shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+void GLES2DecoderTestBase::SetupVertexBuffer() {
+ DoEnableVertexAttribArray(1);
+ DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
+ GLfloat f = 0;
+ DoBufferData(GL_ARRAY_BUFFER, kNumVertices * 2 * sizeof(f));
+}
+
+void GLES2DecoderTestBase::SetupAllNeededVertexBuffers() {
+ DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
+ DoBufferData(GL_ARRAY_BUFFER, kNumVertices * 16 * sizeof(float));
+ DoEnableVertexAttribArray(0);
+ DoEnableVertexAttribArray(1);
+ DoEnableVertexAttribArray(2);
+ DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
+ DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+ DoVertexAttribPointer(2, 2, GL_FLOAT, 0, 0);
+}
+
+void GLES2DecoderTestBase::SetupIndexBuffer() {
+ DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
+ client_element_buffer_id_,
+ kServiceElementBufferId);
+ static const GLshort indices[] = {100, 1, 2, 3, 4, 5, 6, 7, 100, 9};
+ COMPILE_ASSERT(arraysize(indices) == kNumIndices, Indices_is_not_10);
+ DoBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices));
+ DoBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 2, indices);
+ DoBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 2, sizeof(indices) - 2, &indices[1]);
+}
+
+void GLES2DecoderTestBase::SetupTexture() {
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ kSharedMemoryId, kSharedMemoryOffset);
+};
+
+void GLES2DecoderTestBase::DeleteVertexBuffer() {
+ DoDeleteBuffer(client_buffer_id_, kServiceBufferId);
+}
+
+void GLES2DecoderTestBase::DeleteIndexBuffer() {
+ DoDeleteBuffer(client_element_buffer_id_, kServiceElementBufferId);
+}
+
+void GLES2DecoderTestBase::AddExpectationsForSimulatedAttrib0WithError(
+ GLsizei num_vertices, GLuint buffer_id, GLenum error) {
+ if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
+ return;
+ }
+
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(error))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, kServiceAttrib0BufferId))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER,
+ num_vertices * sizeof(GLfloat) * 4,
+ _, GL_DYNAMIC_DRAW))
+ .Times(1)
+ .RetiresOnSaturation();
+ if (error == GL_NO_ERROR) {
+ EXPECT_CALL(*gl_, BufferSubData(
+ GL_ARRAY_BUFFER, 0, num_vertices * sizeof(GLfloat) * 4, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, VertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, buffer_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::AddExpectationsForSimulatedAttrib0(
+ GLsizei num_vertices, GLuint buffer_id) {
+ AddExpectationsForSimulatedAttrib0WithError(
+ num_vertices, buffer_id, GL_NO_ERROR);
+}
+
+void GLES2DecoderTestBase::SetupMockGLBehaviors() {
+ ON_CALL(*gl_, BindVertexArrayOES(_))
+ .WillByDefault(Invoke(
+ &gl_states_,
+ &GLES2DecoderTestBase::MockGLStates::OnBindVertexArrayOES));
+ ON_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, _))
+ .WillByDefault(WithArg<1>(Invoke(
+ &gl_states_,
+ &GLES2DecoderTestBase::MockGLStates::OnBindArrayBuffer)));
+ ON_CALL(*gl_, VertexAttribPointer(_, _, _, _, _, NULL))
+ .WillByDefault(InvokeWithoutArgs(
+ &gl_states_,
+ &GLES2DecoderTestBase::MockGLStates::OnVertexAttribNullPointer));
+}
+
+GLES2DecoderWithShaderTestBase::MockCommandBufferEngine::
+MockCommandBufferEngine() {
+
+ scoped_ptr<base::SharedMemory> shm(new base::SharedMemory());
+ shm->CreateAndMapAnonymous(kSharedBufferSize);
+ valid_buffer_ = MakeBufferFromSharedMemory(shm.Pass(), kSharedBufferSize);
+
+ ClearSharedMemory();
+}
+
+GLES2DecoderWithShaderTestBase::MockCommandBufferEngine::
+~MockCommandBufferEngine() {}
+
+scoped_refptr<gpu::Buffer>
+GLES2DecoderWithShaderTestBase::MockCommandBufferEngine::GetSharedMemoryBuffer(
+ int32 shm_id) {
+ return shm_id == kSharedMemoryId ? valid_buffer_ : invalid_buffer_;
+}
+
+void GLES2DecoderWithShaderTestBase::MockCommandBufferEngine::set_token(
+ int32 token) {
+ DCHECK(false);
+}
+
+bool GLES2DecoderWithShaderTestBase::MockCommandBufferEngine::SetGetBuffer(
+ int32 /* transfer_buffer_id */) {
+ DCHECK(false);
+ return false;
+}
+
+bool GLES2DecoderWithShaderTestBase::MockCommandBufferEngine::SetGetOffset(
+ int32 offset) {
+ DCHECK(false);
+ return false;
+}
+
+int32 GLES2DecoderWithShaderTestBase::MockCommandBufferEngine::GetGetOffset() {
+ DCHECK(false);
+ return 0;
+}
+
+void GLES2DecoderWithShaderTestBase::SetUp() {
+ GLES2DecoderTestBase::SetUp();
+ SetupDefaultProgram();
+}
+
+// Include the auto-generated part of this file. We split this because it means
+// we can easily edit the non-auto generated parts right here in this file
+// instead of having to edit some template or the code generator.
+#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h"
+
+} // namespace gles2
+} // namespace gpu