summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorchristiank <christiank@opera.com>2015-08-19 07:30:37 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-19 14:31:21 +0000
commit00b21807f5c050f8766685c20e1cfc2ed9db636e (patch)
tree9d0ebe81006d2a39cbc9a4826f99e469979822ad /gpu
parentc7da89f96f7010199fb0ae221da1cac82f552771 (diff)
downloadchromium_src-00b21807f5c050f8766685c20e1cfc2ed9db636e.zip
chromium_src-00b21807f5c050f8766685c20e1cfc2ed9db636e.tar.gz
chromium_src-00b21807f5c050f8766685c20e1cfc2ed9db636e.tar.bz2
Add glCompressedCopySubTextureCHROMIUM
This CL adds a GPU command for copying sub regions of compressed textures. The implementation is based on glCopySubTextureCHROMIUM. BUG=434699 Review URL: https://codereview.chromium.org/1272153004 Cr-Commit-Position: refs/heads/master@{#344220}
Diffstat (limited to 'gpu')
-rw-r--r--gpu/GLES2/extensions/CHROMIUM/CHROMIUM_compressed_copy_texture.txt45
-rw-r--r--gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt4
-rw-r--r--gpu/GLES2/gl2chromium_autogen.h2
-rw-r--r--gpu/GLES2/gl2extchromium.h22
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py6
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h17
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h16
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h10
-rw-r--r--gpu/command_buffer/client/gles2_implementation_impl_autogen.h32
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest_autogen.h11
-rw-r--r--gpu/command_buffer/client/gles2_interface_autogen.h9
-rw-r--r--gpu/command_buffer/client/gles2_interface_stub_autogen.h9
-rw-r--r--gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h10
-rw-r--r--gpu/command_buffer/client/gles2_trace_implementation_autogen.h9
-rw-r--r--gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h16
-rw-r--r--gpu/command_buffer/cmd_buffer_functions.txt1
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_autogen.h87
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_test_autogen.h24
-rw-r--r--gpu/command_buffer/common/gles2_cmd_ids_autogen.h99
-rw-r--r--gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc6
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc227
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h31
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h1
-rw-r--r--gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc373
24 files changed, 999 insertions, 68 deletions
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_compressed_copy_texture.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_compressed_copy_texture.txt
index c236ce3..d4f823e 100644
--- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_compressed_copy_texture.txt
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_compressed_copy_texture.txt
@@ -8,7 +8,7 @@ Name Strings
Version
- Last Modifed Date: Jun 15, 2015
+ Last Modifed Date: August 5, 2015
Dependencies
@@ -71,6 +71,48 @@ New Procedures and Functions
INVALID_VALUE is generated if level 0 of the source texture is not defined.
+ The command
+
+ void glCompressedCopySubTextureCHROMIUM (GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height)
+
+ Copies the sub contents of texture referred to by <source_id> to <dest_id>
+ texture without redefining <dest_id> texture.
+
+ <target> uses the same parameters as TexImage2D.
+
+ <xoffset> and <yoffset> specify a texel offset in the x and y direction
+ respectively within the destination texture.
+
+ <x> and <y> specify a texel offset in the x and y direction respectively
+ within the source texture.
+
+ <width> specifies the width of the texture subimage.
+
+ <height> specifies the width of the texture subimage.
+
+ INVALID_OPERATION is generated if internal format of source texture is not
+ one of the following: GL_ATC_RGB_AMD, GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD,
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
+ GL_ETC1_RGB8_OES
+
+ INVALID_VALUE is generated if <target> is not GL_TEXTURE_2D.
+
+ INVALID_OPERATION is generated if the destination texture has not been
+ defined.
+
+ INVALID_VALUE is generated if level 0 of the source texture or
+ the destination texture is not defined.
+
+ INVALID_VALUE is generated if <xoffset> < 0 , or <yoffset> < 0.
+
+ INVALID_VALUE is generated if (<xoffset> + <width>) > dest_width,
+ or (<yoffset> + <height>) > dest_height.
+
Errors
None.
@@ -86,3 +128,4 @@ New State
Revision History
15/6/2015 Documented the extension.
+ 5/8/2015 Added glCompressedCopySubTextureCHROMIUM.
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt
index be60af2..f579dda 100644
--- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt
@@ -136,8 +136,8 @@ New Procedures and Functions
INVALID_VALUE is generated if <xoffset> < 0 , or <yoffset> < 0.
- INVALID_VALUE is generated if (<xoffset> + source_width) > dest_width,
- or (<yoffset> + source_height) > dest_height.
+ INVALID_VALUE is generated if (<xoffset> + <width>) > dest_width,
+ or (<yoffset> + <height>) > dest_height.
Dependencies on ARB_texture_rg
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h
index ddbfa20..a16804f 100644
--- a/gpu/GLES2/gl2chromium_autogen.h
+++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -300,6 +300,8 @@
#define glCopySubTextureCHROMIUM GLES2_GET_FUN(CopySubTextureCHROMIUM)
#define glCompressedCopyTextureCHROMIUM \
GLES2_GET_FUN(CompressedCopyTextureCHROMIUM)
+#define glCompressedCopySubTextureCHROMIUM \
+ GLES2_GET_FUN(CompressedCopySubTextureCHROMIUM)
#define glDrawArraysInstancedANGLE GLES2_GET_FUN(DrawArraysInstancedANGLE)
#define glDrawElementsInstancedANGLE GLES2_GET_FUN(DrawElementsInstancedANGLE)
#define glVertexAttribDivisorANGLE GLES2_GET_FUN(VertexAttribDivisorANGLE)
diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h
index c3b10eb..584d29a 100644
--- a/gpu/GLES2/gl2extchromium.h
+++ b/gpu/GLES2/gl2extchromium.h
@@ -446,9 +446,31 @@ typedef void(GL_APIENTRYP PFNGLCOPYSUBTEXTURECHROMIUMPROC)(
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glCompressedCopyTextureCHROMIUM(
GLenum target, GLenum source_id, GLenum dest_id);
+
+GL_APICALL void GL_APIENTRY glCompressedCopySubTextureCHROMIUM(
+ GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
#endif
typedef void(GL_APIENTRYP PFNGLCOMPRESSEDCOPYTEXTURECHROMIUMPROC)(
GLenum target, GLenum source_id, GLenum dest_id);
+
+typedef void(GL_APIENTRYP PFNGLCOMPRESSEDCOPYSUBTEXTURECHROMIUMPROC)(
+ GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
#endif /* GL_CHROMIUM_compressed_copy_texture */
/* GL_CHROMIUM_lose_context */
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 6b1272d..2566923 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -3760,6 +3760,12 @@ _FUNCTION_INFO = {
'extension': True,
'chromium': True,
},
+ 'CompressedCopySubTextureCHROMIUM': {
+ 'decoder_func': 'DoCompressedCopySubTextureCHROMIUM',
+ 'unit_test': False,
+ 'extension': True,
+ 'chromium': True,
+ },
'TexStorage2DEXT': {
'unit_test': False,
'extension': True,
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index d6eae8f..989c500 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1374,6 +1374,18 @@ void GL_APIENTRY GLES2CompressedCopyTextureCHROMIUM(GLenum target,
gles2::GetGLContext()->CompressedCopyTextureCHROMIUM(target, source_id,
dest_id);
}
+void GL_APIENTRY GLES2CompressedCopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height) {
+ gles2::GetGLContext()->CompressedCopySubTextureCHROMIUM(
+ target, source_id, dest_id, xoffset, yoffset, x, y, width, height);
+}
void GL_APIENTRY GLES2DrawArraysInstancedANGLE(GLenum mode,
GLint first,
GLsizei count,
@@ -2641,6 +2653,11 @@ extern const NameToFunc g_gles2_function_table[] = {
reinterpret_cast<GLES2FunctionPointer>(glCompressedCopyTextureCHROMIUM),
},
{
+ "glCompressedCopySubTextureCHROMIUM",
+ reinterpret_cast<GLES2FunctionPointer>(
+ glCompressedCopySubTextureCHROMIUM),
+ },
+ {
"glDrawArraysInstancedANGLE",
reinterpret_cast<GLES2FunctionPointer>(glDrawArraysInstancedANGLE),
},
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index 46eb093..249e8a4 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -2537,6 +2537,22 @@ void CompressedCopyTextureCHROMIUM(GLenum target,
}
}
+void CompressedCopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height) {
+ gles2::cmds::CompressedCopySubTextureCHROMIUM* c =
+ GetCmdSpace<gles2::cmds::CompressedCopySubTextureCHROMIUM>();
+ if (c) {
+ c->Init(target, source_id, dest_id, xoffset, yoffset, x, y, width, height);
+ }
+}
+
void DrawArraysInstancedANGLE(GLenum mode,
GLint first,
GLsizei count,
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 5d2a4c1..64bfdf4 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -954,6 +954,16 @@ void CompressedCopyTextureCHROMIUM(GLenum target,
GLenum source_id,
GLenum dest_id) override;
+void CompressedCopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height) override;
+
void DrawArraysInstancedANGLE(GLenum mode,
GLint first,
GLsizei count,
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
index 958efac..9f28fe2 100644
--- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3254,6 +3254,38 @@ void GLES2Implementation::CompressedCopyTextureCHROMIUM(GLenum target,
CheckGLError();
}
+void GLES2Implementation::CompressedCopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix()
+ << "] glCompressedCopySubTextureCHROMIUM("
+ << GLES2Util::GetStringEnum(target) << ", "
+ << GLES2Util::GetStringEnum(source_id) << ", "
+ << GLES2Util::GetStringEnum(dest_id) << ", " << xoffset
+ << ", " << yoffset << ", " << x << ", " << y << ", "
+ << width << ", " << height << ")");
+ if (width < 0) {
+ SetGLError(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM",
+ "width < 0");
+ return;
+ }
+ if (height < 0) {
+ SetGLError(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM",
+ "height < 0");
+ return;
+ }
+ helper_->CompressedCopySubTextureCHROMIUM(target, source_id, dest_id, xoffset,
+ yoffset, x, y, width, height);
+ CheckGLError();
+}
+
void GLES2Implementation::GenValuebuffersCHROMIUM(GLsizei n, GLuint* buffers) {
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenValuebuffersCHROMIUM(" << n
<< ", " << static_cast<const void*>(buffers) << ")");
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
index 253b4bf..949ec7e 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -2893,6 +2893,17 @@ TEST_F(GLES2ImplementationTest, CompressedCopyTextureCHROMIUM) {
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
+TEST_F(GLES2ImplementationTest, CompressedCopySubTextureCHROMIUM) {
+ struct Cmds {
+ cmds::CompressedCopySubTextureCHROMIUM cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init(1, 2, 3, 4, 5, 6, 7, 8, 9);
+
+ gl_->CompressedCopySubTextureCHROMIUM(1, 2, 3, 4, 5, 6, 7, 8, 9);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
TEST_F(GLES2ImplementationTest, DrawArraysInstancedANGLE) {
struct Cmds {
cmds::DrawArraysInstancedANGLE cmd;
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
index dc11fb0..815b995 100644
--- a/gpu/command_buffer/client/gles2_interface_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -712,6 +712,15 @@ virtual void CopySubTextureCHROMIUM(GLenum target,
virtual void CompressedCopyTextureCHROMIUM(GLenum target,
GLenum source_id,
GLenum dest_id) = 0;
+virtual void CompressedCopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height) = 0;
virtual void DrawArraysInstancedANGLE(GLenum mode,
GLint first,
GLsizei count,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
index 2675fea..060dbf3 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -689,6 +689,15 @@ void CopySubTextureCHROMIUM(GLenum target,
void CompressedCopyTextureCHROMIUM(GLenum target,
GLenum source_id,
GLenum dest_id) override;
+void CompressedCopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height) override;
void DrawArraysInstancedANGLE(GLenum mode,
GLint first,
GLsizei count,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
index c039d1f..5797b54 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -939,6 +939,16 @@ void GLES2InterfaceStub::CopySubTextureCHROMIUM(
void GLES2InterfaceStub::CompressedCopyTextureCHROMIUM(GLenum /* target */,
GLenum /* source_id */,
GLenum /* dest_id */) {}
+void GLES2InterfaceStub::CompressedCopySubTextureCHROMIUM(
+ GLenum /* target */,
+ GLenum /* source_id */,
+ GLenum /* dest_id */,
+ GLint /* xoffset */,
+ GLint /* yoffset */,
+ GLint /* x */,
+ GLint /* y */,
+ GLsizei /* width */,
+ GLsizei /* height */) {}
void GLES2InterfaceStub::DrawArraysInstancedANGLE(GLenum /* mode */,
GLint /* first */,
GLsizei /* count */,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
index 753bd2b..6f6551d 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -689,6 +689,15 @@ void CopySubTextureCHROMIUM(GLenum target,
void CompressedCopyTextureCHROMIUM(GLenum target,
GLenum source_id,
GLenum dest_id) override;
+void CompressedCopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height) override;
void DrawArraysInstancedANGLE(GLenum mode,
GLint first,
GLsizei count,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
index 24de8af..33234093 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -1992,6 +1992,22 @@ void GLES2TraceImplementation::CompressedCopyTextureCHROMIUM(GLenum target,
gl_->CompressedCopyTextureCHROMIUM(target, source_id, dest_id);
}
+void GLES2TraceImplementation::CompressedCopySubTextureCHROMIUM(
+ GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu",
+ "GLES2Trace::CompressedCopySubTextureCHROMIUM");
+ gl_->CompressedCopySubTextureCHROMIUM(target, source_id, dest_id, xoffset,
+ yoffset, x, y, width, height);
+}
+
void GLES2TraceImplementation::DrawArraysInstancedANGLE(GLenum mode,
GLint first,
GLsizei count,
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt
index 6ce51c6..04ae93a 100644
--- a/gpu/command_buffer/cmd_buffer_functions.txt
+++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -283,6 +283,7 @@ GL_APICALL void GL_APIENTRY glTexImageIOSurface2DCHROMIUM (GLenumTexture
GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id, GLintTextureInternalFormat internalformat, GLenumPixelType dest_type, GLboolean unpack_flip_y, GLboolean unpack_premultiply_alpha, GLboolean unpack_unmultiply_alpha);
GL_APICALL void GL_APIENTRY glCopySubTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, GLboolean unpack_flip_y, GLboolean unpack_premultiply_alpha, GLboolean unpack_unmultiply_alpha);
GL_APICALL void GL_APIENTRY glCompressedCopyTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id);
+GL_APICALL void GL_APIENTRY glCompressedCopySubTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenumDrawMode mode, GLint first, GLsizei count, GLsizei primcount);
GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenumDrawMode mode, GLsizei count, GLenumIndexType type, const void* indices, GLsizei primcount);
GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor);
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index 4b76c2ef..6270b69 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -12523,6 +12523,93 @@ static_assert(offsetof(CompressedCopyTextureCHROMIUM, source_id) == 8,
static_assert(offsetof(CompressedCopyTextureCHROMIUM, dest_id) == 12,
"offset of CompressedCopyTextureCHROMIUM dest_id should be 12");
+struct CompressedCopySubTextureCHROMIUM {
+ typedef CompressedCopySubTextureCHROMIUM ValueType;
+ static const CommandId kCmdId = kCompressedCopySubTextureCHROMIUM;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLenum _target,
+ GLenum _source_id,
+ GLenum _dest_id,
+ GLint _xoffset,
+ GLint _yoffset,
+ GLint _x,
+ GLint _y,
+ GLsizei _width,
+ GLsizei _height) {
+ SetHeader();
+ target = _target;
+ source_id = _source_id;
+ dest_id = _dest_id;
+ xoffset = _xoffset;
+ yoffset = _yoffset;
+ x = _x;
+ y = _y;
+ width = _width;
+ height = _height;
+ }
+
+ void* Set(void* cmd,
+ GLenum _target,
+ GLenum _source_id,
+ GLenum _dest_id,
+ GLint _xoffset,
+ GLint _yoffset,
+ GLint _x,
+ GLint _y,
+ GLsizei _width,
+ GLsizei _height) {
+ static_cast<ValueType*>(cmd)->Init(_target, _source_id, _dest_id, _xoffset,
+ _yoffset, _x, _y, _width, _height);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t target;
+ uint32_t source_id;
+ uint32_t dest_id;
+ int32_t xoffset;
+ int32_t yoffset;
+ int32_t x;
+ int32_t y;
+ int32_t width;
+ int32_t height;
+};
+
+static_assert(sizeof(CompressedCopySubTextureCHROMIUM) == 40,
+ "size of CompressedCopySubTextureCHROMIUM should be 40");
+static_assert(offsetof(CompressedCopySubTextureCHROMIUM, header) == 0,
+ "offset of CompressedCopySubTextureCHROMIUM header should be 0");
+static_assert(offsetof(CompressedCopySubTextureCHROMIUM, target) == 4,
+ "offset of CompressedCopySubTextureCHROMIUM target should be 4");
+static_assert(
+ offsetof(CompressedCopySubTextureCHROMIUM, source_id) == 8,
+ "offset of CompressedCopySubTextureCHROMIUM source_id should be 8");
+static_assert(
+ offsetof(CompressedCopySubTextureCHROMIUM, dest_id) == 12,
+ "offset of CompressedCopySubTextureCHROMIUM dest_id should be 12");
+static_assert(
+ offsetof(CompressedCopySubTextureCHROMIUM, xoffset) == 16,
+ "offset of CompressedCopySubTextureCHROMIUM xoffset should be 16");
+static_assert(
+ offsetof(CompressedCopySubTextureCHROMIUM, yoffset) == 20,
+ "offset of CompressedCopySubTextureCHROMIUM yoffset should be 20");
+static_assert(offsetof(CompressedCopySubTextureCHROMIUM, x) == 24,
+ "offset of CompressedCopySubTextureCHROMIUM x should be 24");
+static_assert(offsetof(CompressedCopySubTextureCHROMIUM, y) == 28,
+ "offset of CompressedCopySubTextureCHROMIUM y should be 28");
+static_assert(offsetof(CompressedCopySubTextureCHROMIUM, width) == 32,
+ "offset of CompressedCopySubTextureCHROMIUM width should be 32");
+static_assert(offsetof(CompressedCopySubTextureCHROMIUM, height) == 36,
+ "offset of CompressedCopySubTextureCHROMIUM height should be 36");
+
struct DrawArraysInstancedANGLE {
typedef DrawArraysInstancedANGLE ValueType;
static const CommandId kCmdId = kDrawArraysInstancedANGLE;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index e362eab..28cf3c68 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -4234,6 +4234,30 @@ TEST_F(GLES2FormatTest, CompressedCopyTextureCHROMIUM) {
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, CompressedCopySubTextureCHROMIUM) {
+ cmds::CompressedCopySubTextureCHROMIUM& cmd =
+ *GetBufferAs<cmds::CompressedCopySubTextureCHROMIUM>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11),
+ static_cast<GLenum>(12), static_cast<GLenum>(13),
+ static_cast<GLint>(14), static_cast<GLint>(15),
+ static_cast<GLint>(16), static_cast<GLint>(17),
+ static_cast<GLsizei>(18), static_cast<GLsizei>(19));
+ EXPECT_EQ(
+ static_cast<uint32_t>(cmds::CompressedCopySubTextureCHROMIUM::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+ EXPECT_EQ(static_cast<GLenum>(12), cmd.source_id);
+ EXPECT_EQ(static_cast<GLenum>(13), cmd.dest_id);
+ EXPECT_EQ(static_cast<GLint>(14), cmd.xoffset);
+ EXPECT_EQ(static_cast<GLint>(15), cmd.yoffset);
+ EXPECT_EQ(static_cast<GLint>(16), cmd.x);
+ EXPECT_EQ(static_cast<GLint>(17), cmd.y);
+ EXPECT_EQ(static_cast<GLsizei>(18), cmd.width);
+ EXPECT_EQ(static_cast<GLsizei>(19), cmd.height);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, DrawArraysInstancedANGLE) {
cmds::DrawArraysInstancedANGLE& cmd =
*GetBufferAs<cmds::DrawArraysInstancedANGLE>();
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index 448dc8e..540bd4e 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -271,55 +271,56 @@
OP(CopyTextureCHROMIUM) /* 512 */ \
OP(CopySubTextureCHROMIUM) /* 513 */ \
OP(CompressedCopyTextureCHROMIUM) /* 514 */ \
- OP(DrawArraysInstancedANGLE) /* 515 */ \
- OP(DrawElementsInstancedANGLE) /* 516 */ \
- OP(VertexAttribDivisorANGLE) /* 517 */ \
- OP(GenMailboxCHROMIUM) /* 518 */ \
- OP(ProduceTextureCHROMIUMImmediate) /* 519 */ \
- OP(ProduceTextureDirectCHROMIUMImmediate) /* 520 */ \
- OP(ConsumeTextureCHROMIUMImmediate) /* 521 */ \
- OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 522 */ \
- OP(BindUniformLocationCHROMIUMBucket) /* 523 */ \
- OP(GenValuebuffersCHROMIUMImmediate) /* 524 */ \
- OP(DeleteValuebuffersCHROMIUMImmediate) /* 525 */ \
- OP(IsValuebufferCHROMIUM) /* 526 */ \
- OP(BindValuebufferCHROMIUM) /* 527 */ \
- OP(SubscribeValueCHROMIUM) /* 528 */ \
- OP(PopulateSubscribedValuesCHROMIUM) /* 529 */ \
- OP(UniformValuebufferCHROMIUM) /* 530 */ \
- OP(BindTexImage2DCHROMIUM) /* 531 */ \
- OP(ReleaseTexImage2DCHROMIUM) /* 532 */ \
- OP(TraceBeginCHROMIUM) /* 533 */ \
- OP(TraceEndCHROMIUM) /* 534 */ \
- OP(AsyncTexSubImage2DCHROMIUM) /* 535 */ \
- OP(AsyncTexImage2DCHROMIUM) /* 536 */ \
- OP(WaitAsyncTexImage2DCHROMIUM) /* 537 */ \
- OP(WaitAllAsyncTexImage2DCHROMIUM) /* 538 */ \
- OP(DiscardFramebufferEXTImmediate) /* 539 */ \
- OP(LoseContextCHROMIUM) /* 540 */ \
- OP(InsertSyncPointCHROMIUM) /* 541 */ \
- OP(WaitSyncPointCHROMIUM) /* 542 */ \
- OP(DrawBuffersEXTImmediate) /* 543 */ \
- OP(DiscardBackbufferCHROMIUM) /* 544 */ \
- OP(ScheduleOverlayPlaneCHROMIUM) /* 545 */ \
- OP(SwapInterval) /* 546 */ \
- OP(FlushDriverCachesCHROMIUM) /* 547 */ \
- OP(MatrixLoadfCHROMIUMImmediate) /* 548 */ \
- OP(MatrixLoadIdentityCHROMIUM) /* 549 */ \
- OP(GenPathsCHROMIUM) /* 550 */ \
- OP(DeletePathsCHROMIUM) /* 551 */ \
- OP(IsPathCHROMIUM) /* 552 */ \
- OP(PathCommandsCHROMIUM) /* 553 */ \
- OP(PathParameterfCHROMIUM) /* 554 */ \
- OP(PathParameteriCHROMIUM) /* 555 */ \
- OP(PathStencilFuncCHROMIUM) /* 556 */ \
- OP(StencilFillPathCHROMIUM) /* 557 */ \
- OP(StencilStrokePathCHROMIUM) /* 558 */ \
- OP(CoverFillPathCHROMIUM) /* 559 */ \
- OP(CoverStrokePathCHROMIUM) /* 560 */ \
- OP(StencilThenCoverFillPathCHROMIUM) /* 561 */ \
- OP(StencilThenCoverStrokePathCHROMIUM) /* 562 */ \
- OP(BlendBarrierKHR) /* 563 */
+ OP(CompressedCopySubTextureCHROMIUM) /* 515 */ \
+ OP(DrawArraysInstancedANGLE) /* 516 */ \
+ OP(DrawElementsInstancedANGLE) /* 517 */ \
+ OP(VertexAttribDivisorANGLE) /* 518 */ \
+ OP(GenMailboxCHROMIUM) /* 519 */ \
+ OP(ProduceTextureCHROMIUMImmediate) /* 520 */ \
+ OP(ProduceTextureDirectCHROMIUMImmediate) /* 521 */ \
+ OP(ConsumeTextureCHROMIUMImmediate) /* 522 */ \
+ OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 523 */ \
+ OP(BindUniformLocationCHROMIUMBucket) /* 524 */ \
+ OP(GenValuebuffersCHROMIUMImmediate) /* 525 */ \
+ OP(DeleteValuebuffersCHROMIUMImmediate) /* 526 */ \
+ OP(IsValuebufferCHROMIUM) /* 527 */ \
+ OP(BindValuebufferCHROMIUM) /* 528 */ \
+ OP(SubscribeValueCHROMIUM) /* 529 */ \
+ OP(PopulateSubscribedValuesCHROMIUM) /* 530 */ \
+ OP(UniformValuebufferCHROMIUM) /* 531 */ \
+ OP(BindTexImage2DCHROMIUM) /* 532 */ \
+ OP(ReleaseTexImage2DCHROMIUM) /* 533 */ \
+ OP(TraceBeginCHROMIUM) /* 534 */ \
+ OP(TraceEndCHROMIUM) /* 535 */ \
+ OP(AsyncTexSubImage2DCHROMIUM) /* 536 */ \
+ OP(AsyncTexImage2DCHROMIUM) /* 537 */ \
+ OP(WaitAsyncTexImage2DCHROMIUM) /* 538 */ \
+ OP(WaitAllAsyncTexImage2DCHROMIUM) /* 539 */ \
+ OP(DiscardFramebufferEXTImmediate) /* 540 */ \
+ OP(LoseContextCHROMIUM) /* 541 */ \
+ OP(InsertSyncPointCHROMIUM) /* 542 */ \
+ OP(WaitSyncPointCHROMIUM) /* 543 */ \
+ OP(DrawBuffersEXTImmediate) /* 544 */ \
+ OP(DiscardBackbufferCHROMIUM) /* 545 */ \
+ OP(ScheduleOverlayPlaneCHROMIUM) /* 546 */ \
+ OP(SwapInterval) /* 547 */ \
+ OP(FlushDriverCachesCHROMIUM) /* 548 */ \
+ OP(MatrixLoadfCHROMIUMImmediate) /* 549 */ \
+ OP(MatrixLoadIdentityCHROMIUM) /* 550 */ \
+ OP(GenPathsCHROMIUM) /* 551 */ \
+ OP(DeletePathsCHROMIUM) /* 552 */ \
+ OP(IsPathCHROMIUM) /* 553 */ \
+ OP(PathCommandsCHROMIUM) /* 554 */ \
+ OP(PathParameterfCHROMIUM) /* 555 */ \
+ OP(PathParameteriCHROMIUM) /* 556 */ \
+ OP(PathStencilFuncCHROMIUM) /* 557 */ \
+ OP(StencilFillPathCHROMIUM) /* 558 */ \
+ OP(StencilStrokePathCHROMIUM) /* 559 */ \
+ OP(CoverFillPathCHROMIUM) /* 560 */ \
+ OP(CoverStrokePathCHROMIUM) /* 561 */ \
+ OP(StencilThenCoverFillPathCHROMIUM) /* 562 */ \
+ OP(StencilThenCoverStrokePathCHROMIUM) /* 563 */ \
+ OP(BlendBarrierKHR) /* 564 */
enum CommandId {
kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
index 6199dfa..a987a39 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
@@ -471,8 +471,10 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal(
DCHECK(source_target == GL_TEXTURE_2D ||
source_target == GL_TEXTURE_RECTANGLE_ARB ||
source_target == GL_TEXTURE_EXTERNAL_OES);
- DCHECK(xoffset >= 0 && xoffset + source_width <= dest_width);
- DCHECK(yoffset >= 0 && yoffset + source_height <= dest_height);
+ DCHECK_GE(xoffset, 0);
+ DCHECK_LE(xoffset + width, dest_width);
+ DCHECK_GE(yoffset, 0);
+ DCHECK_LE(yoffset + height, dest_height);
if (!initialized_) {
DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager.";
return;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index e918b2e..82e9052 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1064,6 +1064,16 @@ class GLES2DecoderImpl : public GLES2Decoder,
GLuint source_id,
GLuint dest_id);
+ void DoCompressedCopySubTextureCHROMIUM(GLenum target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+
// Wrapper for TexStorage2DEXT.
void DoTexStorage2DEXT(
GLenum target,
@@ -12806,6 +12816,223 @@ void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLenum target,
DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
}
+void GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM(GLenum target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height) {
+ TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM");
+
+ TextureRef* source_texture_ref = GetTexture(source_id);
+ TextureRef* dest_texture_ref = GetTexture(dest_id);
+ Texture* source_texture = source_texture_ref->texture();
+ Texture* dest_texture = dest_texture_ref->texture();
+ int source_width = 0;
+ int source_height = 0;
+ gfx::GLImage* image =
+ source_texture->GetLevelImage(source_texture->target(), 0);
+ if (image) {
+ gfx::Size size = image->GetSize();
+ source_width = size.width();
+ source_height = size.height();
+ if (source_width <= 0 || source_height <= 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM",
+ "invalid image size");
+ return;
+ }
+ } else {
+ if (!source_texture->GetLevelSize(source_texture->target(), 0,
+ &source_width, &source_height, nullptr)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM",
+ "source texture has no level 0");
+ return;
+ }
+
+ // Check that this type of texture is allowed.
+ if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
+ source_width, source_height, 1)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM",
+ "source texture bad dimensions");
+ return;
+ }
+ }
+
+ GLenum source_type = 0;
+ GLenum source_internal_format = 0;
+ source_texture->GetLevelType(source_texture->target(), 0, &source_type,
+ &source_internal_format);
+ if (!source_texture->ValidForTexture(source_texture->target(), 0, x, y, 0,
+ width, height, 1, source_type)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM",
+ "source texture bad dimensions.");
+ return;
+ }
+
+ GLenum dest_type = 0;
+ GLenum dest_internal_format = 0;
+ bool dest_level_defined = dest_texture->GetLevelType(
+ dest_texture->target(), 0, &dest_type, &dest_internal_format);
+ if (!dest_level_defined) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
+ "glCompressedCopySubTextureCHROMIUM",
+ "destination texture is not defined");
+ return;
+ }
+ if (!dest_texture->ValidForTexture(dest_texture->target(), 0, xoffset,
+ yoffset, 0, width, height, 1, dest_type)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM",
+ "destination texture bad dimensions.");
+ return;
+ }
+
+ if (!ValidateCompressedCopyTextureCHROMIUM(
+ "glCompressedCopySubTextureCHROMIUM", target, source_texture_ref,
+ dest_texture_ref)) {
+ return;
+ }
+
+ if (!ValidateCompressedTexSubDimensions("glCompressedCopySubTextureCHROMIUM",
+ source_texture->target(), 0, x, y, 0,
+ width, height, 1,
+ source_internal_format,
+ source_texture) ||
+ !ValidateCompressedTexSubDimensions("glCompressedCopySubTextureCHROMIUM",
+ dest_texture->target(), 0,
+ xoffset, yoffset, 0, width, height, 1,
+ dest_internal_format,
+ dest_texture)) {
+ return;
+ }
+
+ // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
+ // needed because it takes 10s of milliseconds to initialize.
+ if (!copy_texture_CHROMIUM_.get()) {
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopySubTextureCHROMIUM");
+ copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
+ copy_texture_CHROMIUM_->Initialize(this);
+ RestoreCurrentFramebufferBindings();
+ if (LOCAL_PEEK_GL_ERROR("glCompressedCopySubTextureCHROMIUM") !=
+ GL_NO_ERROR) {
+ return;
+ }
+ }
+
+ // Clear the source texture if necessary.
+ if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
+ source_texture->target(), 0)) {
+ LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCompressedCopySubTextureCHROMIUM",
+ "source texture dimensions too big");
+ return;
+ }
+
+ int dest_width = 0;
+ int dest_height = 0;
+ bool ok = dest_texture->GetLevelSize(
+ GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr);
+ DCHECK(ok);
+ if (xoffset != 0 || yoffset != 0 || width != dest_width ||
+ height != dest_height) {
+ gfx::Rect cleared_rect;
+ if (CombineAdjacentRects(dest_texture->GetLevelClearedRect(target, 0),
+ gfx::Rect(xoffset, yoffset, width, height),
+ &cleared_rect)) {
+ DCHECK_GE(cleared_rect.size().GetArea(),
+ dest_texture->GetLevelClearedRect(target, 0).size().GetArea());
+ texture_manager()->SetLevelClearedRect(dest_texture_ref, target, 0,
+ cleared_rect);
+ } else {
+ // Otherwise clear part of texture level that is not already cleared.
+ if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target,
+ 0)) {
+ LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY,
+ "glCompressedCopySubTextureCHROMIUM",
+ "destination texture dimensions too big");
+ return;
+ }
+ }
+ } else {
+ texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0,
+ true);
+ }
+
+ ScopedTextureBinder binder(
+ &state_, dest_texture->service_id(), GL_TEXTURE_2D);
+
+ ScopedModifyPixels modify(dest_texture_ref);
+
+ // Try using GLImage::CopyTexSubImage when possible.
+ if (image) {
+ if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(xoffset, yoffset),
+ gfx::Rect(x, y, width, height))) {
+ return;
+ }
+ }
+
+ TRACE_EVENT0(
+ "gpu",
+ "GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM, fallback");
+
+ DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
+
+ // As a fallback, copy into a non-compressed GL_RGBA texture.
+ if (dest_internal_format != GL_RGBA) {
+ // To preserve the contents of the original destination texture we must
+ // first copy the original destination texture to a temporary storage, then
+ // copy it back to the original destination texture.
+ GLuint tmp_service_id;
+ glGenTextures(1, &tmp_service_id);
+ DCHECK_NE(0u, tmp_service_id);
+
+ glBindTexture(GL_TEXTURE_2D, tmp_service_id);
+
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM");
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dest_width, dest_height, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, NULL);
+ GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedCopySubTextureCHROMIUM");
+ if (error != GL_NO_ERROR)
+ return;
+
+ copy_texture_CHROMIUM_->DoCopyTexture(
+ this, dest_texture->target(), dest_texture->service_id(),
+ dest_internal_format, tmp_service_id, GL_RGBA,
+ dest_width, dest_height, false, false, false);
+
+ // Redefine destination texture to use RGBA.
+ glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM");
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dest_width, dest_height, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, NULL);
+ error = LOCAL_PEEK_GL_ERROR("glCompressedCopySubTextureCHROMIUM");
+ if (error != GL_NO_ERROR)
+ return;
+
+ texture_manager()->SetLevelInfo(
+ dest_texture_ref, GL_TEXTURE_2D, 0, GL_RGBA, dest_width, dest_height,
+ 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect(dest_width, dest_height));
+
+ copy_texture_CHROMIUM_->DoCopyTexture(
+ this, GL_TEXTURE_2D, tmp_service_id, GL_RGBA,
+ dest_texture->service_id(), GL_RGBA,
+ dest_width, dest_height, false, false, false);
+
+ glDeleteTextures(1, &tmp_service_id);
+ }
+
+ // TODO(hkuang): get the StreamTexture transform matrix in GPU process.
+ // crbug.com/226218.
+ copy_texture_CHROMIUM_->DoCopySubTexture(
+ this, source_texture->target(), source_texture->service_id(),
+ source_internal_format, dest_texture->service_id(), GL_RGBA,
+ xoffset, yoffset, x, y, width, height, dest_width, dest_height,
+ source_width, source_height, false, false, false);
+
+ DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
+}
+
static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
switch (internalformat) {
case GL_R8:
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index c5de9f5..86c3c67 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -4555,6 +4555,37 @@ error::Error GLES2DecoderImpl::HandleCompressedCopyTextureCHROMIUM(
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleCompressedCopySubTextureCHROMIUM(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ const gles2::cmds::CompressedCopySubTextureCHROMIUM& c =
+ *static_cast<const gles2::cmds::CompressedCopySubTextureCHROMIUM*>(
+ cmd_data);
+ (void)c;
+ GLenum target = static_cast<GLenum>(c.target);
+ GLenum source_id = static_cast<GLenum>(c.source_id);
+ GLenum dest_id = static_cast<GLenum>(c.dest_id);
+ GLint xoffset = static_cast<GLint>(c.xoffset);
+ GLint yoffset = static_cast<GLint>(c.yoffset);
+ GLint x = static_cast<GLint>(c.x);
+ GLint y = static_cast<GLint>(c.y);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ if (width < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM",
+ "width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM",
+ "height < 0");
+ return error::kNoError;
+ }
+ DoCompressedCopySubTextureCHROMIUM(target, source_id, dest_id, xoffset,
+ yoffset, x, y, width, height);
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleProduceTextureCHROMIUMImmediate(
uint32_t immediate_data_size,
const void* cmd_data) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
index 997d425..3f4f390 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
@@ -415,6 +415,7 @@ TEST_P(GLES2DecoderTest3, PopGroupMarkerEXTValidArgs) {
// TODO(gman): CopyTextureCHROMIUM
// TODO(gman): CopySubTextureCHROMIUM
// TODO(gman): CompressedCopyTextureCHROMIUM
+// TODO(gman): CompressedCopySubTextureCHROMIUM
// TODO(gman): DrawArraysInstancedANGLE
// TODO(gman): DrawElementsInstancedANGLE
// TODO(gman): VertexAttribDivisorANGLE
diff --git a/gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc b/gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc
index 86b07cd..d50189d 100644
--- a/gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc
+++ b/gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc
@@ -22,6 +22,12 @@ namespace gpu {
namespace {
+enum CopyType { TexImage, TexSubImage };
+const CopyType kCopyTypes[] = {
+ TexImage,
+ TexSubImage,
+};
+
const uint8 kCompressedImageColor[4] = { 255u, 0u, 0u, 255u };
// Single compressed ATC block of source pixels all set to:
@@ -40,6 +46,15 @@ const uint8 kCompressedImageATCIA[16] = {
const uint8 kCompressedImageDXT1[8] = {
0x00, 0xf8, 0x00, 0xf8, 0xaa, 0xaa, 0xaa, 0xaa };
+// Four compressed DXT1 blocks solidly colored in red, green, blue and black:
+// [R][G]
+// [B][b]
+const uint8 kCompressedImageDXT1RGB[32] = {
+ 0x0, 0xf8, 0x0, 0xf8, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xe0, 0x7, 0xe0, 0x7, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0x1f, 0x0, 0x1f, 0x0, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0x0, 0x0, 0x0, 0x0, 0xaa, 0xaa, 0xaa, 0xaa };
+
// Single compressed DXT5 block of source pixels all set to:
// kCompressedImageColor.
const uint8 kCompressedImageDXT5[16] = {
@@ -51,6 +66,17 @@ const uint8 kCompressedImageDXT5[16] = {
const uint8 kCompressedImageETC1[8] = {
0x0, 0x0, 0xf8, 0x2, 0xff, 0xff, 0x0, 0x0 };
+// Single block of zeroes, used for texture pre-allocation.
+const uint8 kInvalidCompressedImage[8] = {
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+// Four blocks of zeroes, used for texture pre-allocation.
+const uint8 kInvalidCompressedImageLarge[32] = {
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
void glEnableDisable(GLint param, GLboolean value) {
if (value)
glEnable(param);
@@ -62,7 +88,8 @@ void glEnableDisable(GLint param, GLboolean value) {
// A collection of tests that exercise the GL_CHROMIUM_copy_texture extension.
class GLCompressedCopyTextureCHROMIUMTest
- : public testing::Test {
+ : public testing::Test,
+ public ::testing::WithParamInterface<CopyType> {
protected:
void SetUp() override {
gl_.Initialize(GLManager::Options());
@@ -100,14 +127,20 @@ class GLCompressedCopyTextureCHROMIUMTest
GLuint framebuffer_id_;
};
+INSTANTIATE_TEST_CASE_P(CopyType,
+ GLCompressedCopyTextureCHROMIUMTest,
+ ::testing::ValuesIn(kCopyTypes));
+
// Test to ensure that the basic functionality of the extension works.
-TEST_F(GLCompressedCopyTextureCHROMIUMTest, Basic) {
+TEST_P(GLCompressedCopyTextureCHROMIUMTest, Basic) {
if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
LOG(INFO) <<
"GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
return;
}
+ CopyType copy_type = GetParam();
+
glBindTexture(GL_TEXTURE_2D, textures_[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@@ -123,7 +156,17 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, Basic) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
+ if (copy_type == TexImage) {
+ glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
+ } else {
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 4, 4, 0,
+ sizeof(kInvalidCompressedImage),
+ kInvalidCompressedImage);
+
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1], 0, 0, 0, 0, 4, 4);
+ }
EXPECT_TRUE(glGetError() == GL_NO_ERROR);
// Load shader program.
@@ -152,7 +195,9 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, Basic) {
EXPECT_TRUE(GL_NO_ERROR == glGetError());
}
-TEST_F(GLCompressedCopyTextureCHROMIUMTest, InternalFormat) {
+TEST_P(GLCompressedCopyTextureCHROMIUMTest, InternalFormat) {
+ CopyType copy_type = GetParam();
+
struct Image {
const GLint format;
const uint8* data;
@@ -163,8 +208,9 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, InternalFormat) {
};
ScopedVector<Image> supported_formats;
- if (GLTestHelper::HasExtension("GL_AMD_compressed_ATC_texture") ||
- GLTestHelper::HasExtension("GL_ATI_texture_compression_atitc")) {
+ if ((GLTestHelper::HasExtension("GL_AMD_compressed_ATC_texture") ||
+ GLTestHelper::HasExtension("GL_ATI_texture_compression_atitc")) &&
+ copy_type != TexSubImage) {
supported_formats.push_back(new Image(
GL_ATC_RGB_AMD,
kCompressedImageATC,
@@ -187,7 +233,8 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, InternalFormat) {
kCompressedImageDXT5,
sizeof(kCompressedImageDXT5)));
}
- if (GLTestHelper::HasExtension("GL_OES_compressed_ETC1_RGB8_texture")) {
+ if (GLTestHelper::HasExtension("GL_OES_compressed_ETC1_RGB8_texture") &&
+ copy_type != TexSubImage) {
supported_formats.push_back(new Image(
GL_ETC1_RGB8_OES,
kCompressedImageETC1,
@@ -209,18 +256,30 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, InternalFormat) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
+ if (copy_type == TexImage) {
+ glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1]);
+ } else {
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, image->format, 4, 4, 0,
+ sizeof(kInvalidCompressedImage),
+ kInvalidCompressedImage);
+
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1], 0, 0, 0, 0, 4, 4);
+ }
EXPECT_TRUE(GL_NO_ERROR == glGetError());
}
}
-TEST_F(GLCompressedCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
+TEST_P(GLCompressedCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
LOG(INFO) <<
"GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
return;
}
+ CopyType copy_type = GetParam();
+
const uint8 kUncompressedPixels[1 * 4] = { 255u, 0u, 0u, 255u };
glBindTexture(GL_TEXTURE_2D, textures_[0]);
@@ -239,19 +298,29 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// Check that the GL_RGBA format reports an error.
- glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
+ if (copy_type == TexImage) {
+ glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
+ } else {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ kUncompressedPixels);
+
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1], 0, 0, 0, 0, 1, 1);
+ }
EXPECT_TRUE(GL_INVALID_OPERATION == glGetError());
}
// Validate that some basic GL state is not touched upon execution of
// the extension.
-TEST_F(GLCompressedCopyTextureCHROMIUMTest, BasicStatePreservation) {
+TEST_P(GLCompressedCopyTextureCHROMIUMTest, BasicStatePreservation) {
if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
LOG(INFO) <<
"GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
return;
}
+ CopyType copy_type = GetParam();
+
glBindTexture(GL_TEXTURE_2D, textures_[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@@ -268,6 +337,13 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, BasicStatePreservation) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ if (copy_type == TexSubImage) {
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 4, 4, 0,
+ sizeof(kInvalidCompressedImage),
+ kInvalidCompressedImage);
+ }
+
GLboolean reference_settings[2] = { GL_TRUE, GL_FALSE };
for (int x = 0; x < 2; ++x) {
GLboolean setting = reference_settings[x];
@@ -281,7 +357,13 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, BasicStatePreservation) {
glActiveTexture(GL_TEXTURE1 + x);
- glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
+ if (copy_type == TexImage) {
+ glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1]);
+ } else {
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1], 0, 0, 0, 0, 4, 4);
+ }
EXPECT_TRUE(glGetError() == GL_NO_ERROR);
EXPECT_EQ(setting, glIsEnabled(GL_DEPTH_TEST));
@@ -311,13 +393,15 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, BasicStatePreservation) {
// Verify that invocation of the extension does not modify the bound
// texture state.
-TEST_F(GLCompressedCopyTextureCHROMIUMTest, TextureStatePreserved) {
+TEST_P(GLCompressedCopyTextureCHROMIUMTest, TextureStatePreserved) {
if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
LOG(INFO) <<
"GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
return;
}
+ CopyType copy_type = GetParam();
+
glBindTexture(GL_TEXTURE_2D, textures_[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@@ -334,6 +418,13 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, TextureStatePreserved) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ if (copy_type == TexSubImage) {
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 4, 4, 0,
+ sizeof(kInvalidCompressedImage),
+ kInvalidCompressedImage);
+ }
+
GLuint texture_ids[2];
glGenTextures(2, texture_ids);
@@ -343,7 +434,12 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, TextureStatePreserved) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture_ids[1]);
- glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
+ if (copy_type == TexImage) {
+ glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
+ } else {
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1], 0, 0, 0, 0, 4, 4);
+ }
EXPECT_TRUE(GL_NO_ERROR == glGetError());
GLint active_texture = 0;
@@ -366,4 +462,253 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, TextureStatePreserved) {
EXPECT_TRUE(GL_NO_ERROR == glGetError());
}
+TEST_F(GLCompressedCopyTextureCHROMIUMTest, CopySubTextureDimension) {
+ if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
+ LOG(INFO) <<
+ "GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
+ return;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, textures_[0]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 8, 8, 0,
+ sizeof(kCompressedImageDXT1RGB),
+ kCompressedImageDXT1RGB);
+ EXPECT_TRUE(glGetError() == GL_NO_ERROR);
+
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 8, 8, 0,
+ sizeof(kInvalidCompressedImageLarge),
+ kInvalidCompressedImageLarge);
+
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1], 4, 4, 0, 0, 4, 4);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+
+ // Reset the destination texture as it might have been converted to RGBA.
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 8, 8, 0,
+ sizeof(kInvalidCompressedImageLarge),
+ kInvalidCompressedImageLarge);
+
+ // xoffset < 0
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
+ -4, 4, 0, 0, 4, 4);
+ EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
+
+ // x < 0
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
+ 4, 4, -4, 0, 4, 4);
+ EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
+
+ // xoffset + width > dest_width
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
+ 8, 8, 0, 0, 4, 4);
+ EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
+
+ // x + width > source_width
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
+ 0, 0, 8, 8, 4, 4);
+ EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
+
+ // xoffset not within block-boundary
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
+ 3, 0, 0, 0, 4, 4);
+ EXPECT_TRUE(glGetError() == GL_INVALID_OPERATION);
+
+ // x not within block-boundary
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
+ 0, 0, 3, 0, 4, 4);
+ EXPECT_TRUE(glGetError() == GL_INVALID_OPERATION);
+}
+
+TEST_F(GLCompressedCopyTextureCHROMIUMTest, CopySubTextureOffset) {
+ if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
+ LOG(INFO) <<
+ "GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
+ return;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, textures_[0]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 8, 8, 0,
+ sizeof(kCompressedImageDXT1RGB),
+ kCompressedImageDXT1RGB);
+ EXPECT_TRUE(glGetError() == GL_NO_ERROR);
+
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 8, 8, 0,
+ sizeof(kInvalidCompressedImageLarge),
+ kInvalidCompressedImageLarge);
+
+ // Load shader program.
+ GLuint program = LoadProgram();
+ ASSERT_NE(program, 0u);
+ GLint position_loc = glGetAttribLocation(program, "a_position");
+ GLint texture_loc = glGetUniformLocation(program, "u_texture");
+ ASSERT_NE(position_loc, -1);
+ ASSERT_NE(texture_loc, -1);
+ glUseProgram(program);
+
+ // Load geometry.
+ GLuint vbo = GLTestHelper::SetupUnitQuad(position_loc);
+ ASSERT_NE(vbo, 0u);
+
+ // Load texture.
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glUniform1i(texture_loc, 0);
+
+ const uint8 kBlack[1 * 4] = {0u, 0u, 0u, 255u};
+ const uint8 kRed[1 * 4] = {255u, 0u, 0u, 255u};
+ const uint8 kGreen[1 * 4] = {0u, 255u, 0u, 255u};
+ const uint8 kBlue[1 * 4] = {0u, 0u, 255u, 255u};
+
+ // Copy each block one by one in a clockwise fashion. Note that we reset the
+ // destination texture after each copy operation. That's because on some
+ // platforms we might fallback into replacing the compressed destination
+ // texture with an uncompressed one.
+
+ // Move blue block up.
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1], 0, 0, 0, 4, 4, 4);
+ EXPECT_TRUE(glGetError() == GL_NO_ERROR);
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ glFlush();
+ GLTestHelper::CheckPixels(0, 0, 2, 2, 0, kBlue);
+
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 8, 8, 0,
+ sizeof(kInvalidCompressedImageLarge),
+ kInvalidCompressedImageLarge);
+
+ // Move red block right.
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1], 4, 0, 0, 0, 4, 4);
+ EXPECT_TRUE(glGetError() == GL_NO_ERROR);
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ glFlush();
+ GLTestHelper::CheckPixels(2, 0, 2, 2, 0, kRed);
+
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 8, 8, 0,
+ sizeof(kInvalidCompressedImageLarge),
+ kInvalidCompressedImageLarge);
+
+ // Move green block down.
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1], 4, 4, 4, 0, 4, 4);
+ EXPECT_TRUE(glGetError() == GL_NO_ERROR);
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ glFlush();
+ GLTestHelper::CheckPixels(2, 2, 2, 2, 0, kGreen);
+
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 8, 8, 0,
+ sizeof(kInvalidCompressedImageLarge),
+ kInvalidCompressedImageLarge);
+
+ // Move black block left.
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1], 0, 4, 4, 4, 4, 4);
+ EXPECT_TRUE(glGetError() == GL_NO_ERROR);
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ glFlush();
+ GLTestHelper::CheckPixels(0, 2, 2, 2, 0, kBlack);
+
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+}
+
+TEST_F(GLCompressedCopyTextureCHROMIUMTest, CopySubTexturePreservation) {
+ if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
+ LOG(INFO) <<
+ "GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
+ return;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, textures_[0]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 4, 4, 0,
+ sizeof(kCompressedImageDXT1),
+ kCompressedImageDXT1);
+ EXPECT_TRUE(glGetError() == GL_NO_ERROR);
+
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ 8, 8, 0,
+ sizeof(kCompressedImageDXT1RGB),
+ kCompressedImageDXT1RGB);
+
+ // Copy entire first texture into the second, replacing the green block:
+ // [R][R]
+ // [B][b]
+ glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
+ textures_[1], 4, 0, 0, 0, 4, 4);
+ EXPECT_TRUE(glGetError() == GL_NO_ERROR);
+
+ // Load shader program.
+ GLuint program = LoadProgram();
+ ASSERT_NE(program, 0u);
+ GLint position_loc = glGetAttribLocation(program, "a_position");
+ GLint texture_loc = glGetUniformLocation(program, "u_texture");
+ ASSERT_NE(position_loc, -1);
+ ASSERT_NE(texture_loc, -1);
+ glUseProgram(program);
+
+ // Load geometry.
+ GLuint vbo = GLTestHelper::SetupUnitQuad(position_loc);
+ ASSERT_NE(vbo, 0u);
+
+ // Load texture.
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glUniform1i(texture_loc, 0);
+
+ // Draw.
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ glFlush();
+
+ const uint8 kBlack[1 * 4] = {0u, 0u, 0u, 255u};
+ const uint8 kRed[1 * 4] = {255u, 0u, 0u, 255u};
+ const uint8 kBlue[1 * 4] = {0u, 0u, 255u, 255u};
+
+ // Note that while destination texture is 8 x 8 pixels the viewport is only
+ // 4 x 4.
+ GLTestHelper::CheckPixels(0, 0, 4, 2, 0, kRed);
+ GLTestHelper::CheckPixels(0, 2, 2, 2, 0, kBlue);
+ GLTestHelper::CheckPixels(2, 2, 2, 2, 0, kBlack);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+}
+
} // namespace gpu