summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service
diff options
context:
space:
mode:
Diffstat (limited to 'gpu/command_buffer/service')
-rw-r--r--gpu/command_buffer/service/context_state.cc38
-rw-r--r--gpu/command_buffer/service/context_state.h7
-rw-r--r--gpu/command_buffer/service/context_state_autogen.h8
-rw-r--r--gpu/command_buffer/service/context_state_impl_autogen.h168
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc121
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h42
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc64
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().