summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzmo <zmo@chromium.org>2015-12-02 09:35:56 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-02 17:36:55 +0000
commitcdfe65d79d2f9c02553392e0f38bb5a2279d31b8 (patch)
tree23de32884e7911ee1deefba640e9fd11c2247296
parentc34a2b26aa39a4c6bf9165f59d262c2fe2c9f321 (diff)
downloadchromium_src-cdfe65d79d2f9c02553392e0f38bb5a2279d31b8.zip
chromium_src-cdfe65d79d2f9c02553392e0f38bb5a2279d31b8.tar.gz
chromium_src-cdfe65d79d2f9c02553392e0f38bb5a2279d31b8.tar.bz2
Reland of Upgrade PixelStorei to ES3/WebGL2. (patchset #1 id:1 of https://codereview.chromium.org/1494553002/ )
Reason for revert: revert the revert (i.e., reland) the WebGL 2 CTS failure is due to the bug in the test. I am going to suppress it for now and fix it in khronos and roll in. Original issue's description: > Revert of Upgrade PixelStorei to ES3/WebGL2. (patchset #7 id:160001 of https://codereview.chromium.org/1474513003/ ) > > Reason for revert: > Failing the WebGL 2 CTS: > > WebglConformance.conformance2_state_gl_get_calls: > [3560:1299:1202/051124:INFO:CONSOLE(11)] "context.getParameter(context.UNPACK_SKIP_IMAGES) should be false (of type boolean). Was 0 (of type number).", source: (11) > [3560:1299:1202/051124:INFO:CONSOLE(11)] "FAIL context.getParameter(context.UNPACK_SKIP_IMAGES) should be false (of type boolean). Was 0 (of type number).", source: (11) > [3560:1299:1202/051124:INFO:CONSOLE(11)] "context.getParameter(context.UNPACK_SKIP_PIXELS) should be false (of type boolean). Was 0 (of type number).", source: (11) > [3560:1299:1202/051124:INFO:CONSOLE(11)] "FAIL context.getParameter(context.UNPACK_SKIP_PIXELS) should be false (of type boolean). Was 0 (of type number).", source: (11) > [3560:1299:1202/051124:INFO:CONSOLE(11)] "context.getParameter(context.UNPACK_SKIP_ROWS) should be false (of type boolean). Was 0 (of type number).", source: (11) > [3560:1299:1202/051124:INFO:CONSOLE(11)] "FAIL context.getParameter(context.UNPACK_SKIP_ROWS) should be false (of type boolean). Was 0 (of type number).", source: (11) > > http://build.chromium.org/p/chromium.gpu.fyi/builders/Mac%2010.10%20Release%20%28Intel%29/builds/7016 > http://build.chromium.org/p/chromium.gpu.fyi/builders/Win8%20Debug%20%28NVIDIA%29/builds/10350 > http://build.chromium.org/p/chromium.gpu.fyi/builders/Linux%20Release%20%28NVIDIA%29/builds/33475 > > Original issue's description: > > Upgrade PixelStorei to ES3/WebGL2. > > > > BUG=295792,429053 > > TEST=gpu_unittests, webgl2_conformance > > R=kbr@chromium.org,bajones@chromium.org,piman@chromium.org > > > > Committed: https://crrev.com/c6c114178c562feeddfc4d41a33b9999698a4144 > > Cr-Commit-Position: refs/heads/master@{#362585} > > TBR=bajones@chromium.org,kbr@chromium.org,piman@chromium.org,zmo@chromium.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=295792,429053 > > Committed: https://crrev.com/72ea7571631a1922f7c15e7ef5447b8098c1ab24 > Cr-Commit-Position: refs/heads/master@{#362696} TBR=bajones@chromium.org,kbr@chromium.org,piman@chromium.org,jmadill@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=295792,429053 Review URL: https://codereview.chromium.org/1492013002 Cr-Commit-Position: refs/heads/master@{#362741}
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py83
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc81
-rw-r--r--gpu/command_buffer/client/gles2_implementation.h9
-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
-rw-r--r--third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp116
-rw-r--r--third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h13
-rw-r--r--third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp44
-rw-r--r--third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h7
16 files changed, 709 insertions, 96 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 67579a0..6b672b2 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -418,6 +418,62 @@ _STATES = {
'type': 'GLint',
'enum': 'GL_UNPACK_ALIGNMENT',
'default': '4'
+ },
+ {
+ 'name': 'pack_row_length',
+ 'type': 'GLint',
+ 'enum': 'GL_PACK_ROW_LENGTH',
+ 'default': '0',
+ 'es3': True
+ },
+ {
+ 'name': 'pack_skip_pixels',
+ 'type': 'GLint',
+ 'enum': 'GL_PACK_SKIP_PIXELS',
+ 'default': '0',
+ 'es3': True
+ },
+ {
+ 'name': 'pack_skip_rows',
+ 'type': 'GLint',
+ 'enum': 'GL_PACK_SKIP_ROWS',
+ 'default': '0',
+ 'es3': True
+ },
+ {
+ 'name': 'unpack_row_length',
+ 'type': 'GLint',
+ 'enum': 'GL_UNPACK_ROW_LENGTH',
+ 'default': '0',
+ 'es3': True
+ },
+ {
+ 'name': 'unpack_image_height',
+ 'type': 'GLint',
+ 'enum': 'GL_UNPACK_IMAGE_HEIGHT',
+ 'default': '0',
+ 'es3': True
+ },
+ {
+ 'name': 'unpack_skip_pixels',
+ 'type': 'GLint',
+ 'enum': 'GL_UNPACK_SKIP_PIXELS',
+ 'default': '0',
+ 'es3': True
+ },
+ {
+ 'name': 'unpack_skip_rows',
+ 'type': 'GLint',
+ 'enum': 'GL_UNPACK_SKIP_ROWS',
+ 'default': '0',
+ 'es3': True
+ },
+ {
+ 'name': 'unpack_skip_images',
+ 'type': 'GLint',
+ 'enum': 'GL_UNPACK_SKIP_IMAGES',
+ 'default': '0',
+ 'es3': True
}
],
},
@@ -10186,6 +10242,9 @@ void ContextState::InitState(const ContextState *prev_state) const {
for item in state['states']:
item_name = CachedStateName(item)
+ if 'es3' in item:
+ assert item['es3']
+ f.write(" if (feature_info_->IsES3Capable()) {\n");
if 'extension_flag' in item:
f.write(" if (feature_info_->feature_flags().%s) {\n " %
item['extension_flag'])
@@ -10211,7 +10270,7 @@ void ContextState::InitState(const ContextState *prev_state) const {
(item['enum_set']
if 'enum_set' in item else item['enum']),
item['name']))
- if 'gl_version_flag' in item:
+ if 'gl_version_flag' in item or 'es3' in item:
f.write(" }\n")
if test_prev:
if 'extension_flag' in item:
@@ -10420,7 +10479,7 @@ bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) {
f.write(""" }
}
-void GLES2DecoderTestBase::SetupInitStateExpectations() {
+void GLES2DecoderTestBase::SetupInitStateExpectations(bool es3_capable) {
""")
# We need to sort the keys so the expectations match
for state_name in sorted(_STATES.keys()):
@@ -10445,6 +10504,10 @@ void GLES2DecoderTestBase::SetupInitStateExpectations() {
f.write(" if (group_->feature_info()->feature_flags().%s) {\n" %
item['extension_flag'])
f.write(" ")
+ if 'es3' in item:
+ assert item['es3']
+ f.write(" if (es3_capable) {\n")
+ f.write(" ")
expect_value = item['default']
if isinstance(expect_value, list):
# TODO: Currently we do not check array values.
@@ -10458,7 +10521,7 @@ void GLES2DecoderTestBase::SetupInitStateExpectations() {
expect_value))
f.write(" .Times(1)\n")
f.write(" .RetiresOnSaturation();\n")
- if 'extension_flag' in item:
+ if 'extension_flag' in item or 'es3' in item:
f.write(" }\n")
else:
if 'extension_flag' in state:
@@ -10793,7 +10856,9 @@ const size_t GLES2Util::enum_to_string_table_len_ =
enum)
valid_list = _NAMED_TYPE_INFO[enum]['valid']
if 'valid_es3' in _NAMED_TYPE_INFO[enum]:
- valid_list = valid_list + _NAMED_TYPE_INFO[enum]['valid_es3']
+ for es3_enum in _NAMED_TYPE_INFO[enum]['valid_es3']:
+ if not es3_enum in valid_list:
+ valid_list.append(es3_enum)
assert len(valid_list) == len(set(valid_list))
if len(valid_list) > 0:
f.write(" static const EnumToString string_table[] = {\n")
@@ -11034,6 +11099,7 @@ def main(argv):
# Add in states and capabilites to GLState
gl_state_valid = _NAMED_TYPE_INFO['GLState']['valid']
+ gl_state_valid_es3 = _NAMED_TYPE_INFO['GLState']['valid_es3']
for state_name in sorted(_STATES.keys()):
state = _STATES[state_name]
if 'extension_flag' in state:
@@ -11045,8 +11111,13 @@ def main(argv):
for item in state['states']:
if 'extension_flag' in item:
continue
- if not item['enum'] in gl_state_valid:
- gl_state_valid.append(item['enum'])
+ if 'es3' in item:
+ assert item['es3']
+ if not item['enum'] in gl_state_valid_es3:
+ gl_state_valid_es3.append(item['enum'])
+ else:
+ if not item['enum'] in gl_state_valid:
+ gl_state_valid.append(item['enum'])
for capability in _CAPABILITY_FLAGS:
if 'extension_flag' in capability:
continue
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index c1538fe..208a08b 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -85,6 +85,9 @@ GLES2Implementation::GLES2Implementation(
angle_pack_reverse_row_order_status_(kUnknownExtensionStatus),
chromium_framebuffer_multisample_(kUnknownExtensionStatus),
pack_alignment_(4),
+ pack_row_length_(0),
+ pack_skip_pixels_(0),
+ pack_skip_rows_(0),
unpack_alignment_(4),
unpack_row_length_(0),
unpack_image_height_(0),
@@ -1717,32 +1720,41 @@ void GLES2Implementation::PixelStorei(GLenum pname, GLint param) {
<< param << ")");
switch (pname) {
case GL_PACK_ALIGNMENT:
- pack_alignment_ = param;
- break;
+ pack_alignment_ = param;
+ break;
+ case GL_PACK_ROW_LENGTH:
+ pack_row_length_ = param;
+ break;
+ case GL_PACK_SKIP_PIXELS:
+ pack_skip_pixels_ = param;
+ break;
+ case GL_PACK_SKIP_ROWS:
+ pack_skip_rows_ = param;
+ break;
case GL_UNPACK_ALIGNMENT:
- unpack_alignment_ = param;
- break;
+ unpack_alignment_ = param;
+ break;
case GL_UNPACK_ROW_LENGTH_EXT:
- unpack_row_length_ = param;
- return;
+ unpack_row_length_ = param;
+ return;
case GL_UNPACK_IMAGE_HEIGHT:
- unpack_image_height_ = param;
- return;
+ unpack_image_height_ = param;
+ return;
case GL_UNPACK_SKIP_ROWS_EXT:
- unpack_skip_rows_ = param;
- return;
+ unpack_skip_rows_ = param;
+ return;
case GL_UNPACK_SKIP_PIXELS_EXT:
- unpack_skip_pixels_ = param;
- return;
+ unpack_skip_pixels_ = param;
+ return;
case GL_UNPACK_SKIP_IMAGES:
- unpack_skip_images_ = param;
- return;
+ unpack_skip_images_ = param;
+ return;
case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
- pack_reverse_row_order_ =
- IsAnglePackReverseRowOrderAvailable() ? (param != 0) : false;
- break;
+ pack_reverse_row_order_ =
+ IsAnglePackReverseRowOrderAvailable() ? (param != 0) : false;
+ break;
default:
- break;
+ break;
}
helper_->PixelStorei(pname, param);
CheckGLError();
@@ -3472,6 +3484,14 @@ void GLES2Implementation::ReadPixels(
return;
}
+ if (bound_pixel_pack_buffer_) {
+ // TODO(zmo): Need to handle the case of reading into a PIXEL_PACK_BUFFER
+ // in ES3. For now, generate a GL error.
+ SetGLError(GL_INVALID_OPERATION, "glReadPixels",
+ "ReadPixels to a pixel pack buffer isn't implemented");
+ return;
+ }
+
if (bound_pixel_pack_transfer_buffer_id_) {
GLuint offset = ToGLuint(pixels);
BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
@@ -3491,6 +3511,27 @@ void GLES2Implementation::ReadPixels(
return;
}
+ // compute the advance bytes per row for the dst pixels
+ uint32 dst_padded_row_size;
+ if (pack_row_length_ > 0) {
+ if (!GLES2Util::ComputeImagePaddedRowSize(
+ pack_row_length_, format, type, pack_alignment_,
+ &dst_padded_row_size)) {
+ SetGLError(
+ GL_INVALID_VALUE, "glReadPixels", "pack row length too large");
+ return;
+ }
+ } else {
+ dst_padded_row_size = padded_row_size;
+ }
+
+ // Advance pixels pointer past the skip rows and skip pixels
+ dest += pack_skip_rows_ * dst_padded_row_size;
+ if (pack_skip_pixels_) {
+ uint32 group_size = GLES2Util::ComputeImageGroupSize(format, type);
+ dest += pack_skip_pixels_ * group_size;
+ }
+
// Transfer by rows.
// The max rows we can transfer.
while (height) {
@@ -3521,7 +3562,7 @@ void GLES2Implementation::ReadPixels(
// chunk.
int8* rows_dst;
if (pack_reverse_row_order_) {
- rows_dst = dest + (height - num_rows) * padded_row_size;
+ rows_dst = dest + (height - num_rows) * dst_padded_row_size;
} else {
rows_dst = dest;
}
@@ -3529,7 +3570,7 @@ void GLES2Implementation::ReadPixels(
const int8* src = static_cast<const int8*>(buffer.address());
for (GLint yy = 0; yy < num_rows; ++yy) {
memcpy(rows_dst, src, unpadded_row_size);
- rows_dst += padded_row_size;
+ rows_dst += dst_padded_row_size;
src += padded_row_size;
}
if (!pack_reverse_row_order_) {
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 97398be..1c2eba9 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -692,6 +692,15 @@ class GLES2_IMPL_EXPORT GLES2Implementation
// pack alignment as last set by glPixelStorei
GLint pack_alignment_;
+ // pack row length as last set by glPixelStorei
+ GLint pack_row_length_;
+
+ // pack skip pixels as last set by glPixelStorei
+ GLint pack_skip_pixels_;
+
+ // pack skip rows as last set by glPixelStorei
+ GLint pack_skip_rows_;
+
// unpack alignment as last set by glPixelStorei
GLint unpack_alignment_;
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().
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
index b7ac172..87fddec 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
@@ -169,6 +169,15 @@ void WebGL2RenderingContextBase::initializeNewContext()
m_boundIndexedUniformBuffers.resize(maxUniformBufferBindings);
m_maxBoundUniformBufferIndex = 0;
+ m_packRowLength = 0;
+ m_packSkipPixels = 0;
+ m_packSkipRows = 0;
+ m_unpackRowLength = 0;
+ m_unpackImageHeight = 0;
+ m_unpackSkipPixels = 0;
+ m_unpackSkipRows = 0;
+ m_unpackSkipImages = 0;
+
WebGLRenderingContextBase::initializeNewContext();
}
@@ -528,6 +537,42 @@ void WebGL2RenderingContextBase::readBuffer(GLenum mode)
webContext()->readBuffer(mode);
}
+void WebGL2RenderingContextBase::pixelStorei(GLenum pname, GLint param)
+{
+ if (isContextLost())
+ return;
+ switch (pname) {
+ case GL_PACK_ROW_LENGTH:
+ m_packRowLength = param;
+ break;
+ case GL_PACK_SKIP_PIXELS:
+ m_packSkipPixels = param;
+ break;
+ case GL_PACK_SKIP_ROWS:
+ m_packSkipRows = param;
+ break;
+ case GL_UNPACK_ROW_LENGTH:
+ m_unpackRowLength = param;
+ break;
+ case GL_UNPACK_IMAGE_HEIGHT:
+ m_unpackImageHeight = param;
+ break;
+ case GL_UNPACK_SKIP_PIXELS:
+ m_unpackSkipPixels = param;
+ break;
+ case GL_UNPACK_SKIP_ROWS:
+ m_unpackSkipRows = param;
+ break;
+ case GL_UNPACK_SKIP_IMAGES:
+ m_unpackSkipImages = param;
+ break;
+ default:
+ WebGLRenderingContextBase::pixelStorei(pname, param);
+ return;
+ }
+ webContext()->pixelStorei(pname, param);
+}
+
void WebGL2RenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, DOMArrayBufferView* pixels)
{
if (isContextLost())
@@ -684,6 +729,38 @@ void WebGL2RenderingContextBase::renderbufferStorageMultisample(GLenum target, G
applyStencilTest();
}
+void WebGL2RenderingContextBase::resetUnpackParameters()
+{
+ WebGLRenderingContextBase::resetUnpackParameters();
+
+ if (!m_unpackRowLength)
+ webContext()->pixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ if (!m_unpackImageHeight)
+ webContext()->pixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
+ if (!m_unpackSkipPixels)
+ webContext()->pixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ if (!m_unpackSkipRows)
+ webContext()->pixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ if (!m_unpackSkipImages)
+ webContext()->pixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
+}
+
+void WebGL2RenderingContextBase::restoreUnpackParameters()
+{
+ WebGLRenderingContextBase::restoreUnpackParameters();
+
+ if (!m_unpackRowLength)
+ webContext()->pixelStorei(GL_UNPACK_ROW_LENGTH, m_unpackRowLength);
+ if (!m_unpackImageHeight)
+ webContext()->pixelStorei(GL_UNPACK_IMAGE_HEIGHT, m_unpackImageHeight);
+ if (!m_unpackSkipPixels)
+ webContext()->pixelStorei(GL_UNPACK_SKIP_PIXELS, m_unpackSkipPixels);
+ if (!m_unpackSkipRows)
+ webContext()->pixelStorei(GL_UNPACK_SKIP_ROWS, m_unpackSkipRows);
+ if (!m_unpackSkipImages)
+ webContext()->pixelStorei(GL_UNPACK_SKIP_IMAGES, m_unpackSkipImages);
+}
+
/* Texture objects */
bool WebGL2RenderingContextBase::validateTexStorage(const char* functionName, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, TexStorageType functionType)
{
@@ -872,11 +949,9 @@ void WebGL2RenderingContextBase::texSubImage3DImpl(GLenum target, GLint level, G
}
}
- if (m_unpackAlignment != 1)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ resetUnpackParameters();
webContext()->texSubImage3D(target, level, xoffset, yoffset, zoffset, imageExtractor.imageWidth(), imageExtractor.imageHeight(), 1, format, type, needConversion ? data.data() : imagePixelData);
- if (m_unpackAlignment != 1)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+ restoreUnpackParameters();
}
void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, DOMArrayBufferView* pixels)
@@ -889,22 +964,17 @@ void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint
void* data = pixels->baseAddress();
Vector<uint8_t> tempData;
- bool changeUnpackAlignment = false;
+ bool changeUnpackParameters = false;
if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
- if (!WebGLImageConversion::extractTextureData(width, height, format, type,
- m_unpackAlignment,
- m_unpackFlipY, m_unpackPremultiplyAlpha,
- data,
- tempData))
- return;
- data = tempData.data();
- changeUnpackAlignment = true;
+ // FIXME: WebGLImageConversion needs to be updated to accept image depth.
+ notImplemented();
+ changeUnpackParameters = true;
}
- if (changeUnpackAlignment)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ if (changeUnpackParameters)
+ resetUnpackParameters();
webContext()->texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
- if (changeUnpackAlignment)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+ if (changeUnpackParameters)
+ restoreUnpackParameters();
}
void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, ImageData* pixels)
@@ -928,11 +998,9 @@ void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint
return;
}
}
- if (m_unpackAlignment != 1)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ resetUnpackParameters();
webContext()->texSubImage3D(target, level, xoffset, yoffset, zoffset, pixels->width(), pixels->height(), 1, format, type, needConversion ? data.data() : pixels->data()->data());
- if (m_unpackAlignment != 1)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+ restoreUnpackParameters();
}
void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
@@ -2534,11 +2602,11 @@ ScriptValue WebGL2RenderingContextBase::getParameter(ScriptState* scriptState, G
case GL_UNPACK_ROW_LENGTH:
return getIntParameter(scriptState, pname);
case GL_UNPACK_SKIP_IMAGES:
- return getBooleanParameter(scriptState, pname);
+ return getIntParameter(scriptState, pname);
case GL_UNPACK_SKIP_PIXELS:
- return getBooleanParameter(scriptState, pname);
+ return getIntParameter(scriptState, pname);
case GL_UNPACK_SKIP_ROWS:
- return getBooleanParameter(scriptState, pname);
+ return getIntParameter(scriptState, pname);
default:
return WebGLRenderingContextBase::getParameter(scriptState, pname);
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h
index 38b28b3..47d94d2 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h
@@ -175,6 +175,7 @@ public:
ScriptValue getParameter(ScriptState*, GLenum pname) override;
ScriptValue getTexParameter(ScriptState*, GLenum target, GLenum pname) override;
ScriptValue getFramebufferAttachmentParameter(ScriptState*, GLenum target, GLenum attachment, GLenum pname) override;
+ void pixelStorei(GLenum pname, GLint param) override;
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, DOMArrayBufferView* pixels) override;
void restoreCurrentFramebuffer() override;
@@ -237,6 +238,9 @@ protected:
void removeBoundBuffer(WebGLBuffer*) override;
+ void resetUnpackParameters() override;
+ void restoreUnpackParameters() override;
+
PersistentWillBeMember<WebGLFramebuffer> m_readFramebufferBinding;
PersistentWillBeMember<WebGLTransformFeedback> m_transformFeedbackBinding;
GLint m_maxArrayTextureLayers;
@@ -258,6 +262,15 @@ protected:
PersistentWillBeMember<WebGLQuery> m_currentBooleanOcclusionQuery;
PersistentWillBeMember<WebGLQuery> m_currentTransformFeedbackPrimitivesWrittenQuery;
PersistentHeapVectorWillBeHeapVector<Member<WebGLSampler>> m_samplerUnits;
+
+ GLint m_packRowLength;
+ GLint m_packSkipPixels;
+ GLint m_packSkipRows;
+ GLint m_unpackRowLength;
+ GLint m_unpackImageHeight;
+ GLint m_unpackSkipPixels;
+ GLint m_unpackSkipRows;
+ GLint m_unpackSkipImages;
};
DEFINE_TYPE_CASTS(WebGL2RenderingContextBase, CanvasRenderingContext, context,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index aae2e26..ac5365b 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -4179,11 +4179,9 @@ void WebGLRenderingContextBase::texImage2DImpl(GLenum target, GLint level, GLenu
}
}
- if (m_unpackAlignment != 1)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ resetUnpackParameters();
texImage2DBase(target, level, internalformat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), 0, format, type, needConversion ? data.data() : imagePixelData);
- if (m_unpackAlignment != 1)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+ restoreUnpackParameters();
}
bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexImageFunctionType functionType, TexFuncValidationSourceType sourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset)
@@ -4302,10 +4300,10 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum in
changeUnpackAlignment = true;
}
if (changeUnpackAlignment)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ resetUnpackParameters();
texImage2DBase(target, level, internalformat, width, height, border, format, type, data);
if (changeUnpackAlignment)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+ restoreUnpackParameters();
}
void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
@@ -4333,11 +4331,9 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum in
return;
}
}
- if (m_unpackAlignment != 1)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ resetUnpackParameters();
texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data());
- if (m_unpackAlignment != 1)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+ restoreUnpackParameters();
}
void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
@@ -4602,11 +4598,9 @@ void WebGLRenderingContextBase::texSubImage2DImpl(GLenum target, GLint level, GL
}
}
- if (m_unpackAlignment != 1)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ resetUnpackParameters();
webContext()->texSubImage2D(target, level, xoffset, yoffset, imageExtractor.imageWidth(), imageExtractor.imageHeight(), format, type, needConversion ? data.data() : imagePixelData);
- if (m_unpackAlignment != 1)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+ restoreUnpackParameters();
}
void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
@@ -4627,10 +4621,10 @@ void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint
changeUnpackAlignment = true;
}
if (changeUnpackAlignment)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ resetUnpackParameters();
webContext()->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data);
if (changeUnpackAlignment)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+ restoreUnpackParameters();
}
void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
@@ -4658,11 +4652,9 @@ void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint
return;
}
}
- if (m_unpackAlignment != 1)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ resetUnpackParameters();
webContext()->texSubImage2D(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data());
- if (m_unpackAlignment != 1)
- webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+ restoreUnpackParameters();
}
void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
@@ -6958,4 +6950,16 @@ DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const
return m_drawingBuffer.get();
}
+void WebGLRenderingContextBase::resetUnpackParameters()
+{
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+}
+
+void WebGLRenderingContextBase::restoreUnpackParameters()
+{
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
} // namespace blink
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
index 201fc75..c2862a9 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -276,7 +276,7 @@ public:
void lineWidth(GLfloat);
void linkProgram(WebGLProgram*);
- void pixelStorei(GLenum pname, GLint param);
+ virtual void pixelStorei(GLenum pname, GLint param);
void polygonOffset(GLfloat factor, GLfloat units);
virtual void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, DOMArrayBufferView* pixels);
void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
@@ -487,6 +487,11 @@ protected:
void addCompressedTextureFormat(GLenum);
void removeAllCompressedTextureFormats();
+ // Set UNPACK_ALIGNMENT to 1, all other parameters to 0.
+ virtual void resetUnpackParameters();
+ // Restore the client unpack parameters.
+ virtual void restoreUnpackParameters();
+
PassRefPtr<Image> drawImageIntoBuffer(PassRefPtr<Image>, int width, int height, const char* functionName);
PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*);