diff options
Diffstat (limited to 'gpu/command_buffer/service')
9 files changed, 427 insertions, 25 deletions
diff --git a/gpu/command_buffer/service/context_state.cc b/gpu/command_buffer/service/context_state.cc index e8c0072..44ad319 100644 --- a/gpu/command_buffer/service/context_state.cc +++ b/gpu/command_buffer/service/context_state.cc @@ -270,8 +270,10 @@ void ContextState::RestoreBufferBindings() const { GetBufferId(bound_copy_write_buffer.get())); glBindBuffer(GL_PIXEL_PACK_BUFFER, GetBufferId(bound_pixel_pack_buffer.get())); + UpdatePackParameters(); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, GetBufferId(bound_pixel_unpack_buffer.get())); + UpdateUnpackParameters(); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GetBufferId(bound_transform_feedback_buffer.get())); glBindBuffer(GL_UNIFORM_BUFFER, GetBufferId(bound_uniform_buffer.get())); @@ -442,6 +444,38 @@ void ContextState::EnableDisable(GLenum pname, bool enable) const { } } +void ContextState::UpdatePackParameters() const { + if (!feature_info_->IsES3Capable()) + return; + if (bound_pixel_pack_buffer.get()) { + glPixelStorei(GL_PACK_ROW_LENGTH, pack_row_length); + glPixelStorei(GL_PACK_SKIP_PIXELS, pack_skip_pixels); + glPixelStorei(GL_PACK_SKIP_ROWS, pack_skip_rows); + } else { + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + glPixelStorei(GL_PACK_SKIP_ROWS, 0); + } +} + +void ContextState::UpdateUnpackParameters() const { + if (!feature_info_->IsES3Capable()) + return; + if (bound_pixel_unpack_buffer.get()) { + glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, unpack_image_height); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpack_skip_pixels); + glPixelStorei(GL_UNPACK_SKIP_ROWS, unpack_skip_rows); + glPixelStorei(GL_UNPACK_SKIP_IMAGES, unpack_skip_images); + } else { + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); + } +} + void ContextState::SetBoundBuffer(GLenum target, Buffer* buffer) { switch (target) { case GL_ARRAY_BUFFER: @@ -458,9 +492,11 @@ void ContextState::SetBoundBuffer(GLenum target, Buffer* buffer) { break; case GL_PIXEL_PACK_BUFFER: bound_pixel_pack_buffer = buffer; + UpdatePackParameters(); break; case GL_PIXEL_UNPACK_BUFFER: bound_pixel_unpack_buffer = buffer; + UpdateUnpackParameters(); break; case GL_TRANSFORM_FEEDBACK_BUFFER: bound_transform_feedback_buffer = buffer; @@ -488,9 +524,11 @@ void ContextState::RemoveBoundBuffer(Buffer* buffer) { } if (bound_pixel_pack_buffer.get() == buffer) { bound_pixel_pack_buffer = nullptr; + UpdatePackParameters(); } if (bound_pixel_unpack_buffer.get() == buffer) { bound_pixel_unpack_buffer = nullptr; + UpdateUnpackParameters(); } if (bound_transform_feedback_buffer.get() == buffer) { bound_transform_feedback_buffer = nullptr; diff --git a/gpu/command_buffer/service/context_state.h b/gpu/command_buffer/service/context_state.h index f9d4ff7..71bb8a5 100644 --- a/gpu/command_buffer/service/context_state.h +++ b/gpu/command_buffer/service/context_state.h @@ -266,6 +266,13 @@ struct GPU_EXPORT ContextState { private: void EnableDisable(GLenum pname, bool enable) const; + // If a buffer object is bound to PIXEL_PACK_BUFFER, set all pack parameters + // user values; otherwise, set them to 0. + void UpdatePackParameters() const; + // If a buffer object is bound to PIXEL_UNPACK_BUFFER, set all unpack + // parameters user values; otherwise, set them to 0. + void UpdateUnpackParameters() const; + FeatureInfo* feature_info_; scoped_ptr<ErrorState> error_state_; }; diff --git a/gpu/command_buffer/service/context_state_autogen.h b/gpu/command_buffer/service/context_state_autogen.h index 7278a24..d354bd0 100644 --- a/gpu/command_buffer/service/context_state_autogen.h +++ b/gpu/command_buffer/service/context_state_autogen.h @@ -83,6 +83,14 @@ GLint stencil_path_ref; GLuint stencil_path_mask; GLint pack_alignment; GLint unpack_alignment; +GLint pack_row_length; +GLint pack_skip_pixels; +GLint pack_skip_rows; +GLint unpack_row_length; +GLint unpack_image_height; +GLint unpack_skip_pixels; +GLint unpack_skip_rows; +GLint unpack_skip_images; GLfloat polygon_offset_factor; GLfloat polygon_offset_units; GLclampf sample_coverage_value; diff --git a/gpu/command_buffer/service/context_state_impl_autogen.h b/gpu/command_buffer/service/context_state_impl_autogen.h index ce9f70f..263841b 100644 --- a/gpu/command_buffer/service/context_state_impl_autogen.h +++ b/gpu/command_buffer/service/context_state_impl_autogen.h @@ -112,6 +112,14 @@ void ContextState::Initialize() { stencil_path_mask = 0xFFFFFFFFU; pack_alignment = 4; unpack_alignment = 4; + pack_row_length = 0; + pack_skip_pixels = 0; + pack_skip_rows = 0; + unpack_row_length = 0; + unpack_image_height = 0; + unpack_skip_pixels = 0; + unpack_skip_rows = 0; + unpack_skip_images = 0; polygon_offset_factor = 0.0f; polygon_offset_units = 0.0f; sample_coverage_value = 1.0f; @@ -314,6 +322,46 @@ void ContextState::InitState(const ContextState* prev_state) const { if (prev_state->unpack_alignment != unpack_alignment) { glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment); } + if (feature_info_->IsES3Capable()) { + if (prev_state->pack_row_length != pack_row_length) { + glPixelStorei(GL_PACK_ROW_LENGTH, pack_row_length); + } + } + if (feature_info_->IsES3Capable()) { + if (prev_state->pack_skip_pixels != pack_skip_pixels) { + glPixelStorei(GL_PACK_SKIP_PIXELS, pack_skip_pixels); + } + } + if (feature_info_->IsES3Capable()) { + if (prev_state->pack_skip_rows != pack_skip_rows) { + glPixelStorei(GL_PACK_SKIP_ROWS, pack_skip_rows); + } + } + if (feature_info_->IsES3Capable()) { + if (prev_state->unpack_row_length != unpack_row_length) { + glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length); + } + } + if (feature_info_->IsES3Capable()) { + if (prev_state->unpack_image_height != unpack_image_height) { + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, unpack_image_height); + } + } + if (feature_info_->IsES3Capable()) { + if (prev_state->unpack_skip_pixels != unpack_skip_pixels) { + glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpack_skip_pixels); + } + } + if (feature_info_->IsES3Capable()) { + if (prev_state->unpack_skip_rows != unpack_skip_rows) { + glPixelStorei(GL_UNPACK_SKIP_ROWS, unpack_skip_rows); + } + } + if (feature_info_->IsES3Capable()) { + if (prev_state->unpack_skip_images != unpack_skip_images) { + glPixelStorei(GL_UNPACK_SKIP_IMAGES, unpack_skip_images); + } + } if ((polygon_offset_factor != prev_state->polygon_offset_factor) || (polygon_offset_units != prev_state->polygon_offset_units)) glPolygonOffset(polygon_offset_factor, polygon_offset_units); @@ -392,6 +440,30 @@ void ContextState::InitState(const ContextState* prev_state) const { stencil_path_mask); glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment); glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment); + if (feature_info_->IsES3Capable()) { + glPixelStorei(GL_PACK_ROW_LENGTH, pack_row_length); + } + if (feature_info_->IsES3Capable()) { + glPixelStorei(GL_PACK_SKIP_PIXELS, pack_skip_pixels); + } + if (feature_info_->IsES3Capable()) { + glPixelStorei(GL_PACK_SKIP_ROWS, pack_skip_rows); + } + if (feature_info_->IsES3Capable()) { + glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length); + } + if (feature_info_->IsES3Capable()) { + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, unpack_image_height); + } + if (feature_info_->IsES3Capable()) { + glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpack_skip_pixels); + } + if (feature_info_->IsES3Capable()) { + glPixelStorei(GL_UNPACK_SKIP_ROWS, unpack_skip_rows); + } + if (feature_info_->IsES3Capable()) { + glPixelStorei(GL_UNPACK_SKIP_IMAGES, unpack_skip_images); + } glPolygonOffset(polygon_offset_factor, polygon_offset_units); glSampleCoverage(sample_coverage_value, sample_coverage_invert); glScissor(scissor_x, scissor_y, scissor_width, scissor_height); @@ -616,6 +688,54 @@ bool ContextState::GetStateAsGLint(GLenum pname, params[0] = static_cast<GLint>(unpack_alignment); } return true; + case GL_PACK_ROW_LENGTH: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(pack_row_length); + } + return true; + case GL_PACK_SKIP_PIXELS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(pack_skip_pixels); + } + return true; + case GL_PACK_SKIP_ROWS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(pack_skip_rows); + } + return true; + case GL_UNPACK_ROW_LENGTH: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(unpack_row_length); + } + return true; + case GL_UNPACK_IMAGE_HEIGHT: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(unpack_image_height); + } + return true; + case GL_UNPACK_SKIP_PIXELS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(unpack_skip_pixels); + } + return true; + case GL_UNPACK_SKIP_ROWS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(unpack_skip_rows); + } + return true; + case GL_UNPACK_SKIP_IMAGES: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(unpack_skip_images); + } + return true; case GL_POLYGON_OFFSET_FACTOR: *num_written = 1; if (params) { @@ -996,6 +1116,54 @@ bool ContextState::GetStateAsGLfloat(GLenum pname, params[0] = static_cast<GLfloat>(unpack_alignment); } return true; + case GL_PACK_ROW_LENGTH: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(pack_row_length); + } + return true; + case GL_PACK_SKIP_PIXELS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(pack_skip_pixels); + } + return true; + case GL_PACK_SKIP_ROWS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(pack_skip_rows); + } + return true; + case GL_UNPACK_ROW_LENGTH: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(unpack_row_length); + } + return true; + case GL_UNPACK_IMAGE_HEIGHT: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(unpack_image_height); + } + return true; + case GL_UNPACK_SKIP_PIXELS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(unpack_skip_pixels); + } + return true; + case GL_UNPACK_SKIP_ROWS: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(unpack_skip_rows); + } + return true; + case GL_UNPACK_SKIP_IMAGES: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(unpack_skip_images); + } + return true; case GL_POLYGON_OFFSET_FACTOR: *num_written = 1; if (params) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 0cc2771..b2f7f96 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -183,6 +183,11 @@ GLuint GetClientId(const MANAGER_TYPE* manager, const OBJECT_TYPE* object) { return client_id; } +template <typename OBJECT_TYPE> +GLuint GetServiceId(const OBJECT_TYPE* object) { + return object ? object->service_id() : 0; +} + struct Vec4f { explicit Vec4f(const Vec4& data) { data.GetValues(v); @@ -8809,10 +8814,9 @@ void GLES2DecoderImpl::FinishReadPixels( return; } memcpy(pixels, data, pixels_size); - // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't - // have to restore the state. glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); + glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, + GetServiceId(state_.bound_pixel_pack_buffer.get())); glDeleteBuffersARB(1, &buffer); } @@ -8892,6 +8896,13 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size, } typedef cmds::ReadPixels::Result Result; uint32 pixels_size; + if (state_.bound_pixel_pack_buffer.get()) { + // TODO(zmo): Need to handle the case of reading into a PIXEL_PACK_BUFFER + // in ES3, including more pack parameters. For now, generate a GL error. + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadPixels", + "ReadPixels to a pixel pack buffer isn't implemented"); + return error::kNoError; + } if (!GLES2Util::ComputeImageDataSizes( width, height, 1, format, type, state_.pack_alignment, &pixels_size, NULL, NULL)) { @@ -9079,7 +9090,12 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size, dst += padded_row_size; } } else { - if (async && features().use_async_readpixels) { + if (async && features().use_async_readpixels && + !state_.bound_pixel_pack_buffer.get()) { + // To simply the state tracking, we don't go down the async path if + // a PIXEL_PACK_BUFFER is bound (in which case the client can + // implement something similar on their own - all necessary functions + // should be exposed). GLuint buffer = 0; glGenBuffersARB(1, &buffer); glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); @@ -9089,6 +9105,9 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size, glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint); GLenum error = glGetError(); if (error == GL_NO_ERROR) { + // No need to worry about ES3 pxiel pack parameters, because no + // PIXEL_PACK_BUFFER is bound, and all these settings haven't been + // sent to GL. glReadPixels(x, y, width, height, format, type, 0); pending_readpixel_fences_.push(linked_ptr<FenceCallback>( new FenceCallback())); @@ -9120,7 +9139,7 @@ error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size, const gles2::cmds::PixelStorei& c = *static_cast<const gles2::cmds::PixelStorei*>(cmd_data); GLenum pname = c.pname; - GLenum param = c.param; + GLint param = c.param; if (!validators_->pixel_store.IsValid(pname)) { LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname"); return error::kNoError; @@ -9128,30 +9147,88 @@ error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size, switch (pname) { case GL_PACK_ALIGNMENT: case GL_UNPACK_ALIGNMENT: - if (!validators_->pixel_store_alignment.IsValid(param)) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE"); - return error::kNoError; - } - break; + if (!validators_->pixel_store_alignment.IsValid(param)) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glPixelStorei", "invalid param"); + return error::kNoError; + } + break; + case GL_PACK_ROW_LENGTH: + case GL_PACK_SKIP_PIXELS: + case GL_PACK_SKIP_ROWS: + case GL_UNPACK_ROW_LENGTH: + case GL_UNPACK_IMAGE_HEIGHT: + case GL_UNPACK_SKIP_PIXELS: + case GL_UNPACK_SKIP_ROWS: + case GL_UNPACK_SKIP_IMAGES: + if (param < 0) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glPixelStorei", "invalid param"); + return error::kNoError; + } default: - break; + break; + } + // For pack and unpack parameters (except for alignment), we don't apply them + // if no buffer is bound at PIXEL_PACK or PIXEL_UNPACK. We will handle pack + // and unpack according to the user specified parameters on the client side. + switch (pname) { + case GL_PACK_ROW_LENGTH: + case GL_PACK_SKIP_PIXELS: + case GL_PACK_SKIP_ROWS: + if (state_.bound_pixel_pack_buffer.get()) + glPixelStorei(pname, param); + break; + case GL_UNPACK_ROW_LENGTH: + case GL_UNPACK_IMAGE_HEIGHT: + case GL_UNPACK_SKIP_PIXELS: + case GL_UNPACK_SKIP_ROWS: + case GL_UNPACK_SKIP_IMAGES: + if (state_.bound_pixel_unpack_buffer.get()) + glPixelStorei(pname, param); + break; + default: + glPixelStorei(pname, param); + break; } - glPixelStorei(pname, param); switch (pname) { case GL_PACK_ALIGNMENT: - state_.pack_alignment = param; - break; + state_.pack_alignment = param; + break; case GL_PACK_REVERSE_ROW_ORDER_ANGLE: - state_.pack_reverse_row_order = (param != 0); - break; + state_.pack_reverse_row_order = (param != 0); + break; + case GL_PACK_ROW_LENGTH: + state_.pack_row_length = param; + break; + case GL_PACK_SKIP_PIXELS: + state_.pack_skip_pixels = param; + break; + case GL_PACK_SKIP_ROWS: + state_.pack_skip_rows = param; + break; case GL_UNPACK_ALIGNMENT: - state_.unpack_alignment = param; - break; + state_.unpack_alignment = param; + break; + case GL_UNPACK_ROW_LENGTH: + state_.unpack_row_length = param; + break; + case GL_UNPACK_IMAGE_HEIGHT: + state_.unpack_image_height = param; + break; + case GL_UNPACK_SKIP_PIXELS: + state_.unpack_skip_pixels = param; + break; + case GL_UNPACK_SKIP_ROWS: + state_.unpack_skip_rows = param; + break; + case GL_UNPACK_SKIP_IMAGES: + state_.unpack_skip_images = param; + break; default: - // Validation should have prevented us from getting here. - NOTREACHED(); - break; + // Validation should have prevented us from getting here. + NOTREACHED(); + break; } return error::kNoError; } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h index d934bce..116b9c6 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h @@ -34,7 +34,7 @@ void GLES2DecoderTestBase::SetupInitCapabilitiesExpectations(bool es3_capable) { } } -void GLES2DecoderTestBase::SetupInitStateExpectations() { +void GLES2DecoderTestBase::SetupInitStateExpectations(bool es3_capable) { EXPECT_CALL(*gl_, BlendColor(0.0f, 0.0f, 0.0f, 0.0f)) .Times(1) .RetiresOnSaturation(); @@ -88,6 +88,46 @@ void GLES2DecoderTestBase::SetupInitStateExpectations() { EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_ALIGNMENT, 4)) .Times(1) .RetiresOnSaturation(); + if (es3_capable) { + EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ROW_LENGTH, 0)) + .Times(1) + .RetiresOnSaturation(); + } + if (es3_capable) { + EXPECT_CALL(*gl_, PixelStorei(GL_PACK_SKIP_PIXELS, 0)) + .Times(1) + .RetiresOnSaturation(); + } + if (es3_capable) { + EXPECT_CALL(*gl_, PixelStorei(GL_PACK_SKIP_ROWS, 0)) + .Times(1) + .RetiresOnSaturation(); + } + if (es3_capable) { + EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_ROW_LENGTH, 0)) + .Times(1) + .RetiresOnSaturation(); + } + if (es3_capable) { + EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0)) + .Times(1) + .RetiresOnSaturation(); + } + if (es3_capable) { + EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_SKIP_PIXELS, 0)) + .Times(1) + .RetiresOnSaturation(); + } + if (es3_capable) { + EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_SKIP_ROWS, 0)) + .Times(1) + .RetiresOnSaturation(); + } + if (es3_capable) { + EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_SKIP_IMAGES, 0)) + .Times(1) + .RetiresOnSaturation(); + } EXPECT_CALL(*gl_, PolygonOffset(0.0f, 0.0f)).Times(1).RetiresOnSaturation(); EXPECT_CALL(*gl_, SampleCoverage(1.0f, false)).Times(1).RetiresOnSaturation(); EXPECT_CALL(*gl_, diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index d443418..c704c28 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -358,7 +358,7 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( .RetiresOnSaturation(); SetupInitCapabilitiesExpectations(group_->feature_info()->IsES3Capable()); - SetupInitStateExpectations(); + SetupInitStateExpectations(group_->feature_info()->IsES3Capable()); EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)) .Times(1) diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index 09c4c8a..d19937d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -240,7 +240,7 @@ class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> { GLuint fragment_shader_client_id, GLuint fragment_shader_service_id); void SetupInitCapabilitiesExpectations(bool es3_capable); - void SetupInitStateExpectations(); + void SetupInitStateExpectations(bool es3_capable); void ExpectEnableDisable(GLenum cap, bool enable); // Setups up a shader for testing glUniform. diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc index b1ddbba..1b3feaa 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc @@ -48,6 +48,34 @@ using ::testing::StrictMock; namespace gpu { namespace gles2 { +namespace { + +void SetupUpdateES3UnpackParametersExpectations( + ::gfx::MockGLInterface* gl, + GLint row_length, + GLint image_height, + GLint skip_pixels, + GLint skip_rows, + GLint skip_images) { + 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(); + EXPECT_CALL(*gl, PixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, PixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, PixelStorei(GL_UNPACK_SKIP_IMAGES, skip_images)) + .Times(1) + .RetiresOnSaturation(); +} + +} // namespace anonymous + using namespace cmds; class GLES2DecoderRestoreStateTest : public GLES2DecoderManualInitTest { @@ -396,6 +424,42 @@ TEST_P(GLES2DecoderManualInitTest, ContextStateCapabilityCaching) { } } +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_SKIP_ROWS, 2); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + + // When a PIXEL_UNPACK_BUFFER is bound, all cached unpack parameters are + // applied to GL. + SetupUpdateES3UnpackParametersExpectations(gl_.get(), 0, 0, 0, 2, 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, 0, 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_SKIP_ROWS, 3); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + + // Bind a PIXEL_UNPACK_BUFFER again. + SetupUpdateES3UnpackParametersExpectations(gl_.get(), 16, 0, 0, 3, 0); + DoBindBuffer(GL_PIXEL_UNPACK_BUFFER, client_buffer_id_, kServiceBufferId); +} + // TODO(vmiura): Tests for VAO restore. // TODO(vmiura): Tests for ContextState::RestoreAttribute(). |