summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authordongseong.hwang <dongseong.hwang@intel.com>2015-03-03 00:42:55 -0800
committerCommit bot <commit-bot@chromium.org>2015-03-03 08:43:59 +0000
commitfac6a2d44323ad51429ee728e241fe22242f5ebd (patch)
tree433c4f8bd443d0c6595fbcd865ca6606300e2a0e /gpu
parentd5ab8aac09df4a85083ba043ec5ff71fd5e94bdb (diff)
downloadchromium_src-fac6a2d44323ad51429ee728e241fe22242f5ebd.zip
chromium_src-fac6a2d44323ad51429ee728e241fe22242f5ebd.tar.gz
chromium_src-fac6a2d44323ad51429ee728e241fe22242f5ebd.tar.bz2
gpu: introduce glCopySubTextureCHROMIUM
Introduce glCopySubTextureCHROMIUM to support immutable texture as well as to optimize WebGL texSubImage2D(video | canvas). This CL changes gl_renderer to use glCopySubTextureCHROMIUM because the destination texture is immutable. TEST=GLCopyTextureCHROMIUMTest BUG=443151 Review URL: https://codereview.chromium.org/864513004 Cr-Commit-Position: refs/heads/master@{#318855}
Diffstat (limited to 'gpu')
-rw-r--r--gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt50
-rw-r--r--gpu/GLES2/gl2chromium_autogen.h1
-rw-r--r--gpu/GLES2/gl2extchromium.h30
-rw-r--r--gpu/blink/webgraphicscontext3d_impl.cc35
-rw-r--r--gpu/blink/webgraphicscontext3d_impl.h26
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py6
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h15
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h15
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h7
-rw-r--r--gpu/command_buffer/client/gles2_implementation_impl_autogen.h24
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest_autogen.h15
-rw-r--r--gpu/command_buffer/client/gles2_interface_autogen.h6
-rw-r--r--gpu/command_buffer/client/gles2_interface_stub_autogen.h6
-rw-r--r--gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h7
-rw-r--r--gpu/command_buffer/client/gles2_trace_implementation_autogen.h6
-rw-r--r--gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h12
-rw-r--r--gpu/command_buffer/cmd_buffer_functions.txt3
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_autogen.h81
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_test_autogen.h29
-rw-r--r--gpu/command_buffer/common/gles2_cmd_ids_autogen.h71
-rw-r--r--gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc196
-rw-r--r--gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h48
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc349
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h19
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h1
-rw-r--r--gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc341
-rw-r--r--gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc1
27 files changed, 1101 insertions, 299 deletions
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt
index ad9ca68..6845991 100644
--- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt
@@ -36,15 +36,18 @@ Overview
New Procedures and Functions
- void glCopyTextureCHROMIUM (GLenum target, GLenum source_id,
- GLenum dest_id, GLint level,
- GLint internal_format, GLenum dest_type)
+ The command
- Copies the contents of texture referred to by <source_id> to texture
- <dest_id>.
+ void glCopyTextureCHROMIUM (GLenum target, GLenum source_id,
+ GLenum dest_id,
+ GLint internal_format, GLenum dest_type)
- Texture level 0 is copied from the source image to level <level> of the
- destination texture. The level parameter must be 0 at present.
+ Copies the contents of texture referred to by <source_id> to <dest_id>
+ texture. If <source_id> texture is not defined or has different dimension
+ to <dest_id> texture, define <source_id> texture same to <dest_id> texture.
+
+ Texture level 0 is copied from the source image to level 0 of the
+ destination texture.
The internal format of the destination texture is converted to that
specified by <internal_format>. Must be one of the following symbolic
@@ -87,8 +90,37 @@ New Procedures and Functions
been bound as GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_ARB or
GL_TEXTURE_EXTERNAL_OES objects.
- INVALID_VALUE is generated if <level> is not a valid level of the
- destination texture, or if level 0 of the source texture is not defined.
+ INVALID_VALUE is generated if level 0 of the source texture is not defined.
+
+ The command
+
+ void glCopySubTextureCHROMIUM (GLenum target, GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset, GLint yoffset)
+
+ Copies the sub contents of texture referred to by <source_id> to <dest_id>
+ texture without redefining <dest_id> texture.
+
+ See CopyTextureCHROMIUM for the interpretation of the <target> arguments.
+
+ <xoffset> and <yoffset> specify a texel offset in the x and y direction
+ respectively within the destination texture.
+
+ INVALID_OPERATION is generated if source internal_format and destination
+ internal_format are not one of the valid formats described above.
+
+ 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> + source_width) > dest_width,
+ or (<yoffset> + source_height) > dest_height.
Errors
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h
index af745c1..60404dc 100644
--- a/gpu/GLES2/gl2chromium_autogen.h
+++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -279,6 +279,7 @@
#define glPostSubBufferCHROMIUM GLES2_GET_FUN(PostSubBufferCHROMIUM)
#define glTexImageIOSurface2DCHROMIUM GLES2_GET_FUN(TexImageIOSurface2DCHROMIUM)
#define glCopyTextureCHROMIUM GLES2_GET_FUN(CopyTextureCHROMIUM)
+#define glCopySubTextureCHROMIUM GLES2_GET_FUN(CopySubTextureCHROMIUM)
#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 6a31b8f..ec85bf2 100644
--- a/gpu/GLES2/gl2extchromium.h
+++ b/gpu/GLES2/gl2extchromium.h
@@ -394,13 +394,29 @@ typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERCHROMIUMPROC) (GLint srcX0, GLint
#define GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM 0x9241
#endif
#ifdef GL_GLEXT_PROTOTYPES
-GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM(
- GLenum target, GLenum source_id, GLenum dest_id, GLint level,
- GLint internalformat, GLenum dest_type);
-#endif
-typedef void (GL_APIENTRYP PFNGLCOPYTEXTURECHROMIUMPROC) (
- GLenum target, GLenum source_id, GLenum dest_id, GLint level,
- GLint internalformat, GLenum dest_type);
+GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint internalformat,
+ GLenum dest_type);
+
+GL_APICALL void GL_APIENTRY glCopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset);
+#endif
+typedef void(GL_APIENTRYP PFNGLCOPYTEXTURECHROMIUMPROC)(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint internalformat,
+ GLenum dest_type);
+
+typedef void(GL_APIENTRYP PFNGLCOPYSUBTEXTURECHROMIUMPROC)(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset);
#endif /* GL_CHROMIUM_copy_texture */
/* GL_CHROMIUM_lose_context */
diff --git a/gpu/blink/webgraphicscontext3d_impl.cc b/gpu/blink/webgraphicscontext3d_impl.cc
index 4f728cf..3763b5d 100644
--- a/gpu/blink/webgraphicscontext3d_impl.cc
+++ b/gpu/blink/webgraphicscontext3d_impl.cc
@@ -809,8 +809,39 @@ DELEGATE_TO_GL_3(getQueryivEXT, GetQueryivEXT, WGC3Denum, WGC3Denum, WGC3Dint*)
DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivEXT,
WebGLId, WGC3Denum, WGC3Duint*)
-DELEGATE_TO_GL_6(copyTextureCHROMIUM, CopyTextureCHROMIUM, WGC3Denum,
- WebGLId, WebGLId, WGC3Dint, WGC3Denum, WGC3Denum);
+void WebGraphicsContext3DImpl::copyTextureCHROMIUM(WGC3Denum target,
+ WebGLId source_id,
+ WebGLId dest_id,
+ WGC3Dint level,
+ WGC3Denum internal_format,
+ WGC3Denum dest_type) {
+ copyTextureCHROMIUM(target, source_id, dest_id, internal_format, dest_type);
+}
+
+void WebGraphicsContext3DImpl::copySubTextureCHROMIUM(WGC3Denum target,
+ WebGLId source_id,
+ WebGLId dest_id,
+ WGC3Dint level,
+ WGC3Dint xoffset,
+ WGC3Dint yoffset) {
+ copySubTextureCHROMIUM(target, source_id, dest_id, xoffset, yoffset);
+}
+
+DELEGATE_TO_GL_5(copyTextureCHROMIUM,
+ CopyTextureCHROMIUM,
+ WGC3Denum,
+ WebGLId,
+ WebGLId,
+ WGC3Denum,
+ WGC3Denum);
+
+DELEGATE_TO_GL_5(copySubTextureCHROMIUM,
+ CopySubTextureCHROMIUM,
+ WGC3Denum,
+ WebGLId,
+ WebGLId,
+ WGC3Dint,
+ WGC3Dint);
DELEGATE_TO_GL_3(bindUniformLocationCHROMIUM, BindUniformLocationCHROMIUM,
WebGLId, WGC3Dint, const WGC3Dchar*)
diff --git a/gpu/blink/webgraphicscontext3d_impl.h b/gpu/blink/webgraphicscontext3d_impl.h
index ff2ca97..a0d1461 100644
--- a/gpu/blink/webgraphicscontext3d_impl.h
+++ b/gpu/blink/webgraphicscontext3d_impl.h
@@ -451,11 +451,33 @@ class GPU_BLINK_EXPORT WebGraphicsContext3DImpl
virtual void getQueryObjectuivEXT(
WebGLId query, WGC3Denum pname, WGC3Duint* params);
- virtual void copyTextureCHROMIUM(WGC3Denum target, WebGLId source_id,
- WebGLId dest_id, WGC3Dint level,
+ // TODO(dshwang): Remove |level| in Blink and then remove it.
+ void copyTextureCHROMIUM(WGC3Denum target,
+ WebGLId source_id,
+ WebGLId dest_id,
+ WGC3Dint level,
+ WGC3Denum internal_format,
+ WGC3Denum dest_type) override;
+
+ void copySubTextureCHROMIUM(WGC3Denum target,
+ WebGLId source_id,
+ WebGLId dest_id,
+ WGC3Dint level,
+ WGC3Dint xoffset,
+ WGC3Dint yoffset) override;
+
+ virtual void copyTextureCHROMIUM(WGC3Denum target,
+ WebGLId source_id,
+ WebGLId dest_id,
WGC3Denum internal_format,
WGC3Denum dest_type);
+ virtual void copySubTextureCHROMIUM(WGC3Denum target,
+ WebGLId sourceId,
+ WebGLId destId,
+ WGC3Dint xoffset,
+ WGC3Dint yoffset);
+
virtual void bindUniformLocationCHROMIUM(WebGLId program, WGC3Dint location,
const WGC3Dchar* uniform);
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 8dba53b..5e6d9d9 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -3008,6 +3008,12 @@ _FUNCTION_INFO = {
'extension': True,
'chromium': True,
},
+ 'CopySubTextureCHROMIUM': {
+ 'decoder_func': 'DoCopySubTextureCHROMIUM',
+ '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 87616e7..7e0da4b 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1158,12 +1158,19 @@ void GLES2TexImageIOSurface2DCHROMIUM(GLenum target,
void GLES2CopyTextureCHROMIUM(GLenum target,
GLenum source_id,
GLenum dest_id,
- GLint level,
GLint internalformat,
GLenum dest_type) {
- gles2::GetGLContext()->CopyTextureCHROMIUM(target, source_id, dest_id, level,
+ gles2::GetGLContext()->CopyTextureCHROMIUM(target, source_id, dest_id,
internalformat, dest_type);
}
+void GLES2CopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset) {
+ gles2::GetGLContext()->CopySubTextureCHROMIUM(target, source_id, dest_id,
+ xoffset, yoffset);
+}
void GLES2DrawArraysInstancedANGLE(GLenum mode,
GLint first,
GLsizei count,
@@ -2361,6 +2368,10 @@ extern const NameToFunc g_gles2_function_table[] = {
reinterpret_cast<GLES2FunctionPointer>(glCopyTextureCHROMIUM),
},
{
+ "glCopySubTextureCHROMIUM",
+ reinterpret_cast<GLES2FunctionPointer>(glCopySubTextureCHROMIUM),
+ },
+ {
"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 4c1ad05..ad3eb58 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -2312,13 +2312,24 @@ void TexImageIOSurface2DCHROMIUM(GLenum target,
void CopyTextureCHROMIUM(GLenum target,
GLenum source_id,
GLenum dest_id,
- GLint level,
GLint internalformat,
GLenum dest_type) {
gles2::cmds::CopyTextureCHROMIUM* c =
GetCmdSpace<gles2::cmds::CopyTextureCHROMIUM>();
if (c) {
- c->Init(target, source_id, dest_id, level, internalformat, dest_type);
+ c->Init(target, source_id, dest_id, internalformat, dest_type);
+ }
+}
+
+void CopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset) {
+ gles2::cmds::CopySubTextureCHROMIUM* c =
+ GetCmdSpace<gles2::cmds::CopySubTextureCHROMIUM>();
+ if (c) {
+ c->Init(target, source_id, dest_id, xoffset, yoffset);
}
}
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index c570c45..8e032e4 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -873,10 +873,15 @@ void TexImageIOSurface2DCHROMIUM(GLenum target,
void CopyTextureCHROMIUM(GLenum target,
GLenum source_id,
GLenum dest_id,
- GLint level,
GLint internalformat,
GLenum dest_type) override;
+void CopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset) 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 641efde..98447bf 100644
--- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3108,18 +3108,32 @@ void GLES2Implementation::TexImageIOSurface2DCHROMIUM(GLenum target,
void GLES2Implementation::CopyTextureCHROMIUM(GLenum target,
GLenum source_id,
GLenum dest_id,
- GLint level,
GLint internalformat,
GLenum dest_type) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopyTextureCHROMIUM("
<< GLES2Util::GetStringEnum(target) << ", "
<< GLES2Util::GetStringEnum(source_id) << ", "
- << GLES2Util::GetStringEnum(dest_id) << ", " << level
- << ", " << internalformat << ", "
+ << GLES2Util::GetStringEnum(dest_id) << ", "
+ << internalformat << ", "
<< GLES2Util::GetStringPixelType(dest_type) << ")");
- helper_->CopyTextureCHROMIUM(target, source_id, dest_id, level,
- internalformat, dest_type);
+ helper_->CopyTextureCHROMIUM(target, source_id, dest_id, internalformat,
+ dest_type);
+ CheckGLError();
+}
+
+void GLES2Implementation::CopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopySubTextureCHROMIUM("
+ << GLES2Util::GetStringEnum(target) << ", "
+ << GLES2Util::GetStringEnum(source_id) << ", "
+ << GLES2Util::GetStringEnum(dest_id) << ", " << xoffset
+ << ", " << yoffset << ")");
+ helper_->CopySubTextureCHROMIUM(target, source_id, dest_id, xoffset, yoffset);
CheckGLError();
}
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
index 9b43afe..2d8480a 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -2749,9 +2749,20 @@ TEST_F(GLES2ImplementationTest, CopyTextureCHROMIUM) {
cmds::CopyTextureCHROMIUM cmd;
};
Cmds expected;
- expected.cmd.Init(1, 2, 3, 4, GL_ALPHA, GL_UNSIGNED_BYTE);
+ expected.cmd.Init(1, 2, 3, GL_ALPHA, GL_UNSIGNED_BYTE);
- gl_->CopyTextureCHROMIUM(1, 2, 3, 4, GL_ALPHA, GL_UNSIGNED_BYTE);
+ gl_->CopyTextureCHROMIUM(1, 2, 3, GL_ALPHA, GL_UNSIGNED_BYTE);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
+TEST_F(GLES2ImplementationTest, CopySubTextureCHROMIUM) {
+ struct Cmds {
+ cmds::CopySubTextureCHROMIUM cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init(1, 2, 3, 4, 5);
+
+ gl_->CopySubTextureCHROMIUM(1, 2, 3, 4, 5);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
index d5b4f93..f93ec07 100644
--- a/gpu/command_buffer/client/gles2_interface_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -641,9 +641,13 @@ virtual void TexImageIOSurface2DCHROMIUM(GLenum target,
virtual void CopyTextureCHROMIUM(GLenum target,
GLenum source_id,
GLenum dest_id,
- GLint level,
GLint internalformat,
GLenum dest_type) = 0;
+virtual void CopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset) = 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 5ad9385..0381b323 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -624,9 +624,13 @@ void TexImageIOSurface2DCHROMIUM(GLenum target,
void CopyTextureCHROMIUM(GLenum target,
GLenum source_id,
GLenum dest_id,
- GLint level,
GLint internalformat,
GLenum dest_type) override;
+void CopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset) 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 b3f40ac..0f2e5fd 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1069,10 +1069,15 @@ void GLES2InterfaceStub::TexImageIOSurface2DCHROMIUM(GLenum /* target */,
void GLES2InterfaceStub::CopyTextureCHROMIUM(GLenum /* target */,
GLenum /* source_id */,
GLenum /* dest_id */,
- GLint /* level */,
GLint /* internalformat */,
GLenum /* dest_type */) {
}
+void GLES2InterfaceStub::CopySubTextureCHROMIUM(GLenum /* target */,
+ GLenum /* source_id */,
+ GLenum /* dest_id */,
+ GLint /* xoffset */,
+ GLint /* yoffset */) {
+}
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 e5a69a4..8a9be79 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -624,9 +624,13 @@ void TexImageIOSurface2DCHROMIUM(GLenum target,
void CopyTextureCHROMIUM(GLenum target,
GLenum source_id,
GLenum dest_id,
- GLint level,
GLint internalformat,
GLenum dest_type) override;
+void CopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset) 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 6dbbc93..d1479b1 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -1821,14 +1821,22 @@ void GLES2TraceImplementation::TexImageIOSurface2DCHROMIUM(GLenum target,
void GLES2TraceImplementation::CopyTextureCHROMIUM(GLenum target,
GLenum source_id,
GLenum dest_id,
- GLint level,
GLint internalformat,
GLenum dest_type) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CopyTextureCHROMIUM");
- gl_->CopyTextureCHROMIUM(target, source_id, dest_id, level, internalformat,
+ gl_->CopyTextureCHROMIUM(target, source_id, dest_id, internalformat,
dest_type);
}
+void GLES2TraceImplementation::CopySubTextureCHROMIUM(GLenum target,
+ GLenum source_id,
+ GLenum dest_id,
+ GLint xoffset,
+ GLint yoffset) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CopySubTextureCHROMIUM");
+ gl_->CopySubTextureCHROMIUM(target, source_id, dest_id, xoffset, yoffset);
+}
+
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 a03af9e..140db2c 100644
--- a/gpu/command_buffer/cmd_buffer_functions.txt
+++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -263,7 +263,8 @@ GL_APICALL GLuint GL_APIENTRY glCreateGpuMemoryBufferImageCHROMIUM (GLsize
GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLidShader shader, GLsizeiNotNegative bufsize, GLsizeiOptional* length, char* source);
GL_APICALL void GL_APIENTRY glPostSubBufferCHROMIUM (GLint x, GLint y, GLint width, GLint height);
GL_APICALL void GL_APIENTRY glTexImageIOSurface2DCHROMIUM (GLenumTextureBindTarget target, GLsizei width, GLsizei height, GLuint ioSurfaceId, GLuint plane);
-GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id, GLint level, GLintTextureInternalFormat internalformat, GLenumPixelType dest_type);
+GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id, GLintTextureInternalFormat internalformat, GLenumPixelType dest_type);
+GL_APICALL void GL_APIENTRY glCopySubTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id, GLint xoffset, GLint yoffset);
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 71b1f3f..d3cb00a 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -11375,14 +11375,12 @@ struct CopyTextureCHROMIUM {
void Init(GLenum _target,
GLenum _source_id,
GLenum _dest_id,
- GLint _level,
GLint _internalformat,
GLenum _dest_type) {
SetHeader();
target = _target;
source_id = _source_id;
dest_id = _dest_id;
- level = _level;
internalformat = _internalformat;
dest_type = _dest_type;
}
@@ -11391,11 +11389,10 @@ struct CopyTextureCHROMIUM {
GLenum _target,
GLenum _source_id,
GLenum _dest_id,
- GLint _level,
GLint _internalformat,
GLenum _dest_type) {
- static_cast<ValueType*>(cmd)->Init(_target, _source_id, _dest_id, _level,
- _internalformat, _dest_type);
+ static_cast<ValueType*>(cmd)
+ ->Init(_target, _source_id, _dest_id, _internalformat, _dest_type);
return NextCmdAddress<ValueType>(cmd);
}
@@ -11403,13 +11400,12 @@ struct CopyTextureCHROMIUM {
uint32_t target;
uint32_t source_id;
uint32_t dest_id;
- int32_t level;
int32_t internalformat;
uint32_t dest_type;
};
-static_assert(sizeof(CopyTextureCHROMIUM) == 28,
- "size of CopyTextureCHROMIUM should be 28");
+static_assert(sizeof(CopyTextureCHROMIUM) == 24,
+ "size of CopyTextureCHROMIUM should be 24");
static_assert(offsetof(CopyTextureCHROMIUM, header) == 0,
"offset of CopyTextureCHROMIUM header should be 0");
static_assert(offsetof(CopyTextureCHROMIUM, target) == 4,
@@ -11418,12 +11414,69 @@ static_assert(offsetof(CopyTextureCHROMIUM, source_id) == 8,
"offset of CopyTextureCHROMIUM source_id should be 8");
static_assert(offsetof(CopyTextureCHROMIUM, dest_id) == 12,
"offset of CopyTextureCHROMIUM dest_id should be 12");
-static_assert(offsetof(CopyTextureCHROMIUM, level) == 16,
- "offset of CopyTextureCHROMIUM level should be 16");
-static_assert(offsetof(CopyTextureCHROMIUM, internalformat) == 20,
- "offset of CopyTextureCHROMIUM internalformat should be 20");
-static_assert(offsetof(CopyTextureCHROMIUM, dest_type) == 24,
- "offset of CopyTextureCHROMIUM dest_type should be 24");
+static_assert(offsetof(CopyTextureCHROMIUM, internalformat) == 16,
+ "offset of CopyTextureCHROMIUM internalformat should be 16");
+static_assert(offsetof(CopyTextureCHROMIUM, dest_type) == 20,
+ "offset of CopyTextureCHROMIUM dest_type should be 20");
+
+struct CopySubTextureCHROMIUM {
+ typedef CopySubTextureCHROMIUM ValueType;
+ static const CommandId kCmdId = kCopySubTextureCHROMIUM;
+ 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) {
+ SetHeader();
+ target = _target;
+ source_id = _source_id;
+ dest_id = _dest_id;
+ xoffset = _xoffset;
+ yoffset = _yoffset;
+ }
+
+ void* Set(void* cmd,
+ GLenum _target,
+ GLenum _source_id,
+ GLenum _dest_id,
+ GLint _xoffset,
+ GLint _yoffset) {
+ static_cast<ValueType*>(cmd)
+ ->Init(_target, _source_id, _dest_id, _xoffset, _yoffset);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t target;
+ uint32_t source_id;
+ uint32_t dest_id;
+ int32_t xoffset;
+ int32_t yoffset;
+};
+
+static_assert(sizeof(CopySubTextureCHROMIUM) == 24,
+ "size of CopySubTextureCHROMIUM should be 24");
+static_assert(offsetof(CopySubTextureCHROMIUM, header) == 0,
+ "offset of CopySubTextureCHROMIUM header should be 0");
+static_assert(offsetof(CopySubTextureCHROMIUM, target) == 4,
+ "offset of CopySubTextureCHROMIUM target should be 4");
+static_assert(offsetof(CopySubTextureCHROMIUM, source_id) == 8,
+ "offset of CopySubTextureCHROMIUM source_id should be 8");
+static_assert(offsetof(CopySubTextureCHROMIUM, dest_id) == 12,
+ "offset of CopySubTextureCHROMIUM dest_id should be 12");
+static_assert(offsetof(CopySubTextureCHROMIUM, xoffset) == 16,
+ "offset of CopySubTextureCHROMIUM xoffset should be 16");
+static_assert(offsetof(CopySubTextureCHROMIUM, yoffset) == 20,
+ "offset of CopySubTextureCHROMIUM yoffset should be 20");
struct DrawArraysInstancedANGLE {
typedef DrawArraysInstancedANGLE ValueType;
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 1d18fa8..3162276 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -3914,19 +3914,34 @@ TEST_F(GLES2FormatTest, TexImageIOSurface2DCHROMIUM) {
TEST_F(GLES2FormatTest, CopyTextureCHROMIUM) {
cmds::CopyTextureCHROMIUM& cmd = *GetBufferAs<cmds::CopyTextureCHROMIUM>();
- 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<GLenum>(16));
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11),
+ static_cast<GLenum>(12), static_cast<GLenum>(13),
+ static_cast<GLint>(14), static_cast<GLenum>(15));
EXPECT_EQ(static_cast<uint32_t>(cmds::CopyTextureCHROMIUM::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.level);
- EXPECT_EQ(static_cast<GLint>(15), cmd.internalformat);
- EXPECT_EQ(static_cast<GLenum>(16), cmd.dest_type);
+ EXPECT_EQ(static_cast<GLint>(14), cmd.internalformat);
+ EXPECT_EQ(static_cast<GLenum>(15), cmd.dest_type);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, CopySubTextureCHROMIUM) {
+ cmds::CopySubTextureCHROMIUM& cmd =
+ *GetBufferAs<cmds::CopySubTextureCHROMIUM>();
+ 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));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::CopySubTextureCHROMIUM::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);
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index eec1c04..1c739e8 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -254,41 +254,42 @@
OP(PostSubBufferCHROMIUM) /* 495 */ \
OP(TexImageIOSurface2DCHROMIUM) /* 496 */ \
OP(CopyTextureCHROMIUM) /* 497 */ \
- OP(DrawArraysInstancedANGLE) /* 498 */ \
- OP(DrawElementsInstancedANGLE) /* 499 */ \
- OP(VertexAttribDivisorANGLE) /* 500 */ \
- OP(GenMailboxCHROMIUM) /* 501 */ \
- OP(ProduceTextureCHROMIUMImmediate) /* 502 */ \
- OP(ProduceTextureDirectCHROMIUMImmediate) /* 503 */ \
- OP(ConsumeTextureCHROMIUMImmediate) /* 504 */ \
- OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 505 */ \
- OP(BindUniformLocationCHROMIUMBucket) /* 506 */ \
- OP(GenValuebuffersCHROMIUMImmediate) /* 507 */ \
- OP(DeleteValuebuffersCHROMIUMImmediate) /* 508 */ \
- OP(IsValuebufferCHROMIUM) /* 509 */ \
- OP(BindValuebufferCHROMIUM) /* 510 */ \
- OP(SubscribeValueCHROMIUM) /* 511 */ \
- OP(PopulateSubscribedValuesCHROMIUM) /* 512 */ \
- OP(UniformValuebufferCHROMIUM) /* 513 */ \
- OP(BindTexImage2DCHROMIUM) /* 514 */ \
- OP(ReleaseTexImage2DCHROMIUM) /* 515 */ \
- OP(TraceBeginCHROMIUM) /* 516 */ \
- OP(TraceEndCHROMIUM) /* 517 */ \
- OP(AsyncTexSubImage2DCHROMIUM) /* 518 */ \
- OP(AsyncTexImage2DCHROMIUM) /* 519 */ \
- OP(WaitAsyncTexImage2DCHROMIUM) /* 520 */ \
- OP(WaitAllAsyncTexImage2DCHROMIUM) /* 521 */ \
- OP(DiscardFramebufferEXTImmediate) /* 522 */ \
- OP(LoseContextCHROMIUM) /* 523 */ \
- OP(InsertSyncPointCHROMIUM) /* 524 */ \
- OP(WaitSyncPointCHROMIUM) /* 525 */ \
- OP(DrawBuffersEXTImmediate) /* 526 */ \
- OP(DiscardBackbufferCHROMIUM) /* 527 */ \
- OP(ScheduleOverlayPlaneCHROMIUM) /* 528 */ \
- OP(SwapInterval) /* 529 */ \
- OP(MatrixLoadfCHROMIUMImmediate) /* 530 */ \
- OP(MatrixLoadIdentityCHROMIUM) /* 531 */ \
- OP(BlendBarrierKHR) /* 532 */
+ OP(CopySubTextureCHROMIUM) /* 498 */ \
+ OP(DrawArraysInstancedANGLE) /* 499 */ \
+ OP(DrawElementsInstancedANGLE) /* 500 */ \
+ OP(VertexAttribDivisorANGLE) /* 501 */ \
+ OP(GenMailboxCHROMIUM) /* 502 */ \
+ OP(ProduceTextureCHROMIUMImmediate) /* 503 */ \
+ OP(ProduceTextureDirectCHROMIUMImmediate) /* 504 */ \
+ OP(ConsumeTextureCHROMIUMImmediate) /* 505 */ \
+ OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 506 */ \
+ OP(BindUniformLocationCHROMIUMBucket) /* 507 */ \
+ OP(GenValuebuffersCHROMIUMImmediate) /* 508 */ \
+ OP(DeleteValuebuffersCHROMIUMImmediate) /* 509 */ \
+ OP(IsValuebufferCHROMIUM) /* 510 */ \
+ OP(BindValuebufferCHROMIUM) /* 511 */ \
+ OP(SubscribeValueCHROMIUM) /* 512 */ \
+ OP(PopulateSubscribedValuesCHROMIUM) /* 513 */ \
+ OP(UniformValuebufferCHROMIUM) /* 514 */ \
+ OP(BindTexImage2DCHROMIUM) /* 515 */ \
+ OP(ReleaseTexImage2DCHROMIUM) /* 516 */ \
+ OP(TraceBeginCHROMIUM) /* 517 */ \
+ OP(TraceEndCHROMIUM) /* 518 */ \
+ OP(AsyncTexSubImage2DCHROMIUM) /* 519 */ \
+ OP(AsyncTexImage2DCHROMIUM) /* 520 */ \
+ OP(WaitAsyncTexImage2DCHROMIUM) /* 521 */ \
+ OP(WaitAllAsyncTexImage2DCHROMIUM) /* 522 */ \
+ OP(DiscardFramebufferEXTImmediate) /* 523 */ \
+ OP(LoseContextCHROMIUM) /* 524 */ \
+ OP(InsertSyncPointCHROMIUM) /* 525 */ \
+ OP(WaitSyncPointCHROMIUM) /* 526 */ \
+ OP(DrawBuffersEXTImmediate) /* 527 */ \
+ OP(DiscardBackbufferCHROMIUM) /* 528 */ \
+ OP(ScheduleOverlayPlaneCHROMIUM) /* 529 */ \
+ OP(SwapInterval) /* 530 */ \
+ OP(MatrixLoadfCHROMIUMImmediate) /* 531 */ \
+ OP(MatrixLoadIdentityCHROMIUM) /* 532 */ \
+ OP(BlendBarrierKHR) /* 533 */
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 9098aba..e3c9b6a 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
@@ -32,6 +32,11 @@
namespace {
+const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f};
+
enum VertexShaderId {
VERTEX_SHADER_COPY_TEXTURE,
VERTEX_SHADER_COPY_TEXTURE_FLIP_Y,
@@ -188,7 +193,6 @@ void DeleteShader(GLuint shader) {
bool BindFramebufferTexture2D(GLenum target,
GLuint texture_id,
- GLint level,
GLuint framebuffer) {
DCHECK(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB);
glActiveTexture(GL_TEXTURE0);
@@ -200,8 +204,8 @@ bool BindFramebufferTexture2D(GLenum target,
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
- glFramebufferTexture2DEXT(
- GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, texture_id, level);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target,
+ texture_id, 0);
#ifndef NDEBUG
GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
@@ -217,28 +221,20 @@ void DoCopyTexImage2D(const gpu::gles2::GLES2Decoder* decoder,
GLenum source_target,
GLuint source_id,
GLuint dest_id,
- GLint dest_level,
GLenum dest_internal_format,
GLsizei width,
GLsizei height,
GLuint framebuffer) {
DCHECK(source_target == GL_TEXTURE_2D ||
source_target == GL_TEXTURE_RECTANGLE_ARB);
- if (BindFramebufferTexture2D(
- source_target, source_id, 0 /* level */, framebuffer)) {
+ if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) {
glBindTexture(GL_TEXTURE_2D, dest_id);
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);
- glCopyTexImage2D(GL_TEXTURE_2D,
- dest_level,
- dest_internal_format,
- 0 /* x */,
- 0 /* y */,
- width,
- height,
- 0 /* border */);
+ glCopyTexImage2D(GL_TEXTURE_2D, 0 /* level */, dest_internal_format,
+ 0 /* x */, 0 /* y */, width, height, 0 /* border */);
}
decoder->RestoreTextureState(source_id);
@@ -248,6 +244,45 @@ void DoCopyTexImage2D(const gpu::gles2::GLES2Decoder* decoder,
decoder->RestoreFramebufferBindings();
}
+void DoCopyTexSubImage2D(const gpu::gles2::GLES2Decoder* decoder,
+ GLenum source_target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei source_width,
+ GLsizei source_height,
+ GLuint framebuffer) {
+ DCHECK(source_target == GL_TEXTURE_2D ||
+ source_target == GL_TEXTURE_RECTANGLE_ARB);
+ if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) {
+ glBindTexture(GL_TEXTURE_2D, dest_id);
+ 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);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0 /* level */, xoffset, yoffset,
+ 0 /* x */, 0 /* y */, source_width, source_height);
+ }
+
+ decoder->RestoreTextureState(source_id);
+ decoder->RestoreTextureState(dest_id);
+ decoder->RestoreTextureUnitBindings(0);
+ decoder->RestoreActiveTexture();
+ decoder->RestoreFramebufferBindings();
+}
+
+// Copy from SkMatrix44::preTranslate
+void PreTranslate(GLfloat* matrix, GLfloat dx, GLfloat dy, GLfloat dz) {
+ if (!dx && !dy && !dz)
+ return;
+
+ for (int i = 0; i < 4; ++i) {
+ matrix[(3 * 4) + i] = matrix[(0 * 4) + i] * dx + matrix[(1 * 4) + i] * dy +
+ matrix[(2 * 4) + i] * dz + matrix[(3 * 4) + i];
+ }
+}
+
} // namespace
namespace gpu {
@@ -318,7 +353,6 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTexture(
GLuint source_id,
GLenum source_internal_format,
GLuint dest_id,
- GLint dest_level,
GLenum dest_internal_format,
GLsizei width,
GLsizei height,
@@ -342,7 +376,6 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTexture(
source_target,
source_id,
dest_id,
- dest_level,
dest_internal_format,
width,
height,
@@ -350,22 +383,51 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTexture(
return;
}
- // Use default transform matrix if no transform passed in.
- const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f};
- DoCopyTextureWithTransform(decoder,
- source_target,
- source_id,
- dest_id,
- dest_level,
- width,
- height,
- flip_y,
- premultiply_alpha,
- unpremultiply_alpha,
- default_matrix);
+ // Use kIdentityMatrix if no transform passed in.
+ DoCopyTextureWithTransform(decoder, source_target, source_id, dest_id, width,
+ height, flip_y, premultiply_alpha,
+ unpremultiply_alpha, kIdentityMatrix);
+}
+
+void CopyTextureCHROMIUMResourceManager::DoCopySubTexture(
+ const gles2::GLES2Decoder* decoder,
+ GLenum source_target,
+ GLuint source_id,
+ GLenum source_internal_format,
+ GLuint dest_id,
+ GLenum dest_internal_format,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei dest_width,
+ GLsizei dest_height,
+ GLsizei source_width,
+ GLsizei source_height,
+ bool flip_y,
+ bool premultiply_alpha,
+ bool unpremultiply_alpha) {
+ bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha;
+ // GL_INVALID_OPERATION is generated if the currently bound framebuffer's
+ // format does not contain a superset of the components required by the base
+ // format of internalformat.
+ // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml
+ bool source_format_contain_superset_of_dest_format =
+ (source_internal_format == dest_internal_format &&
+ source_internal_format != GL_BGRA_EXT) ||
+ (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB);
+ // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2,
+ // so restrict this to GL_TEXTURE_2D.
+ if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change &&
+ source_format_contain_superset_of_dest_format) {
+ DoCopyTexSubImage2D(decoder, source_target, source_id, dest_id, xoffset,
+ yoffset, source_width, source_height, framebuffer_);
+ return;
+ }
+
+ // Use kIdentityMatrix if no transform passed in.
+ DoCopySubTextureWithTransform(
+ decoder, source_target, source_id, dest_id, xoffset, yoffset, dest_width,
+ dest_height, source_width, source_height, flip_y, premultiply_alpha,
+ unpremultiply_alpha, kIdentityMatrix);
}
void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
@@ -373,16 +435,61 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
GLenum source_target,
GLuint source_id,
GLuint dest_id,
- GLint dest_level,
GLsizei width,
GLsizei height,
bool flip_y,
bool premultiply_alpha,
bool unpremultiply_alpha,
const GLfloat transform_matrix[16]) {
+ GLsizei dest_width = width;
+ GLsizei dest_height = height;
+ DoCopyTextureInternal(decoder, source_target, source_id, dest_id, 0, 0,
+ dest_width, dest_height, width, height, flip_y,
+ premultiply_alpha, unpremultiply_alpha,
+ transform_matrix);
+}
+
+void CopyTextureCHROMIUMResourceManager::DoCopySubTextureWithTransform(
+ const gles2::GLES2Decoder* decoder,
+ GLenum source_target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei dest_width,
+ GLsizei dest_height,
+ GLsizei source_width,
+ GLsizei source_height,
+ bool flip_y,
+ bool premultiply_alpha,
+ bool unpremultiply_alpha,
+ const GLfloat transform_matrix[16]) {
+ DoCopyTextureInternal(decoder, source_target, source_id, dest_id, xoffset,
+ yoffset, dest_width, dest_height, source_width,
+ source_height, flip_y, premultiply_alpha,
+ unpremultiply_alpha, transform_matrix);
+}
+
+void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal(
+ const gles2::GLES2Decoder* decoder,
+ GLenum source_target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei dest_width,
+ GLsizei dest_height,
+ GLsizei source_width,
+ GLsizei source_height,
+ bool flip_y,
+ bool premultiply_alpha,
+ bool unpremultiply_alpha,
+ const GLfloat transform_matrix[16]) {
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);
if (!initialized_) {
DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager.";
return;
@@ -436,14 +543,27 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
}
#endif
- glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix);
+ if (!xoffset && !yoffset) {
+ glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix);
+ } else {
+ // transform offsets from ([0, dest_width], [0, dest_height]) coord.
+ // to ([-1, 1], [-1, 1]) coord.
+ GLfloat xoffset_on_vertex = ((2.f * xoffset) / dest_width);
+ GLfloat yoffset_on_vertex = ((2.f * yoffset) / dest_height);
+
+ // Pass view_matrix * offset_matrix to the program.
+ GLfloat view_transform[16];
+ memcpy(view_transform, transform_matrix, 16 * sizeof(GLfloat));
+ PreTranslate(view_transform, xoffset_on_vertex, yoffset_on_vertex, 0);
+ glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, view_transform);
+ }
if (source_target == GL_TEXTURE_RECTANGLE_ARB)
- glUniform2f(info->half_size_handle, width / 2.0f, height / 2.0f);
+ glUniform2f(info->half_size_handle, source_width / 2.0f,
+ source_height / 2.0f);
else
glUniform2f(info->half_size_handle, 0.5f, 0.5f);
- if (BindFramebufferTexture2D(
- GL_TEXTURE_2D, dest_id, dest_level, framebuffer_)) {
+ if (BindFramebufferTexture2D(GL_TEXTURE_2D, dest_id, framebuffer_)) {
decoder->ClearAllAttributes();
glEnableVertexAttribArray(kVertexPositionAttrib);
@@ -466,7 +586,7 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
- glViewport(0, 0, width, height);
+ glViewport(0, 0, dest_width, dest_height);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h
index 083fc4c..5c62141 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h
@@ -35,7 +35,6 @@ class GPU_EXPORT CopyTextureCHROMIUMResourceManager {
GLuint source_id,
GLenum source_internal_format,
GLuint dest_id,
- GLint dest_level,
GLenum dest_internal_format,
GLsizei width,
GLsizei height,
@@ -43,13 +42,28 @@ class GPU_EXPORT CopyTextureCHROMIUMResourceManager {
bool premultiply_alpha,
bool unpremultiply_alpha);
+ void DoCopySubTexture(const gles2::GLES2Decoder* decoder,
+ GLenum source_target,
+ GLuint source_id,
+ GLenum source_internal_format,
+ GLuint dest_id,
+ GLenum dest_internal_format,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei dest_width,
+ GLsizei dest_height,
+ GLsizei source_width,
+ GLsizei source_height,
+ bool flip_y,
+ bool premultiply_alpha,
+ bool unpremultiply_alpha);
+
// This will apply a transform on the source texture before copying to
// destination texture.
void DoCopyTextureWithTransform(const gles2::GLES2Decoder* decoder,
GLenum source_target,
GLuint source_id,
GLuint dest_id,
- GLint dest_level,
GLsizei width,
GLsizei height,
bool flip_y,
@@ -57,6 +71,21 @@ class GPU_EXPORT CopyTextureCHROMIUMResourceManager {
bool unpremultiply_alpha,
const GLfloat transform_matrix[16]);
+ void DoCopySubTextureWithTransform(const gles2::GLES2Decoder* decoder,
+ GLenum source_target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei dest_width,
+ GLsizei dest_height,
+ GLsizei source_width,
+ GLsizei source_height,
+ bool flip_y,
+ bool premultiply_alpha,
+ bool unpremultiply_alpha,
+ const GLfloat transform_matrix[16]);
+
// The attributes used during invocation of the extension.
static const GLuint kVertexPositionAttrib = 0;
@@ -74,6 +103,21 @@ class GPU_EXPORT CopyTextureCHROMIUMResourceManager {
GLuint sampler_handle;
};
+ void DoCopyTextureInternal(const gles2::GLES2Decoder* decoder,
+ GLenum source_target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei dest_width,
+ GLsizei dest_height,
+ GLsizei source_width,
+ GLsizei source_height,
+ bool flip_y,
+ bool premultiply_alpha,
+ bool unpremultiply_alpha,
+ const GLfloat transform_matrix[16]);
+
bool initialized_;
typedef std::vector<GLuint> ShaderVector;
ShaderVector vertex_shaders_;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 8c24d3c..1eb5c47 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -81,10 +81,15 @@ namespace gles2 {
namespace {
-static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
-static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
-static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
-static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
+const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
+const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
+const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
+const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
+
+const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f};
static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
GLint rangeMax,
@@ -936,13 +941,17 @@ class GLES2DecoderImpl : public GLES2Decoder,
GLuint io_surface_id,
GLuint plane);
- void DoCopyTextureCHROMIUM(
- GLenum target,
- GLuint source_id,
- GLuint target_id,
- GLint level,
- GLenum internal_format,
- GLenum dest_type);
+ void DoCopyTextureCHROMIUM(GLenum target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLenum internal_format,
+ GLenum dest_type);
+
+ void DoCopySubTextureCHROMIUM(GLenum target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLint xoffset,
+ GLint yoffset);
// Wrapper for TexStorage2DEXT.
void DoTexStorage2DEXT(
@@ -1658,6 +1667,11 @@ class GLES2DecoderImpl : public GLES2Decoder,
GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format,
Texture* texture);
+ bool ValidateCopyTextureCHROMIUM(const char* function_name,
+ GLenum target,
+ TextureRef* source_texture_ref,
+ TextureRef* dest_texture_ref,
+ GLenum dest_internal_format);
void RenderWarning(const char* filename, int line, const std::string& msg);
void PerformanceWarning(
@@ -10935,40 +10949,78 @@ static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
}
}
-void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
- GLenum target, GLuint source_id, GLuint dest_id, GLint level,
- GLenum internal_format, GLenum dest_type) {
- TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
-
- TextureRef* dest_texture_ref = GetTexture(dest_id);
- TextureRef* source_texture_ref = GetTexture(source_id);
-
+bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUM(
+ const char* function_name,
+ GLenum target,
+ TextureRef* source_texture_ref,
+ TextureRef* dest_texture_ref,
+ GLenum dest_internal_format) {
if (!source_texture_ref || !dest_texture_ref) {
- LOCAL_SET_GL_ERROR(
- GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
- return;
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown texture id");
+ return false;
}
if (GL_TEXTURE_2D != target) {
- LOCAL_SET_GL_ERROR(
- GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
- return;
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
+ "invalid texture target");
+ return false;
}
Texture* source_texture = source_texture_ref->texture();
Texture* dest_texture = dest_texture_ref->texture();
+ if (source_texture == dest_texture) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
+ "source and destination textures are the same");
+ return false;
+ }
+
if (dest_texture->target() != GL_TEXTURE_2D ||
(source_texture->target() != GL_TEXTURE_2D &&
source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
- "glCopyTextureCHROMIUM",
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
"invalid texture target binding");
- return;
+ return false;
+ }
+
+ GLenum source_type = 0;
+ GLenum source_internal_format = 0;
+ source_texture->GetLevelType(source_texture->target(), 0, &source_type,
+ &source_internal_format);
+
+ // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
+ // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
+ // renderable on some platforms.
+ bool valid_dest_format = dest_internal_format == GL_RGB ||
+ dest_internal_format == GL_RGBA ||
+ dest_internal_format == GL_BGRA_EXT;
+ bool valid_source_format = source_internal_format == GL_ALPHA ||
+ source_internal_format == GL_RGB ||
+ source_internal_format == GL_RGBA ||
+ source_internal_format == GL_LUMINANCE ||
+ source_internal_format == GL_LUMINANCE_ALPHA ||
+ source_internal_format == GL_BGRA_EXT;
+ if (!valid_source_format || !valid_dest_format) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
+ "invalid internal format");
+ return false;
}
+ return true;
+}
- int source_width, source_height, dest_width, dest_height;
+void GLES2DecoderImpl::DoCopyTextureCHROMIUM(GLenum target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLenum internal_format,
+ GLenum dest_type) {
+ TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
+ 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) {
@@ -10991,43 +11043,36 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
}
// Check that this type of texture is allowed.
- if (!texture_manager()->ValidForTarget(
- source_texture->target(), level, source_width, source_height, 1)) {
+ if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
+ source_width, source_height, 1)) {
LOCAL_SET_GL_ERROR(
GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
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, "glCopyTextureCHROMIUM", "dimensions too big");
- return;
- }
-
GLenum source_type = 0;
GLenum source_internal_format = 0;
source_texture->GetLevelType(
source_texture->target(), 0, &source_type, &source_internal_format);
- // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
- // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
- // renderable on some platforms.
- bool valid_dest_format = internal_format == GL_RGB ||
- internal_format == GL_RGBA ||
- internal_format == GL_BGRA_EXT;
- bool valid_source_format = source_internal_format == GL_ALPHA ||
- source_internal_format == GL_RGB ||
- source_internal_format == GL_RGBA ||
- source_internal_format == GL_LUMINANCE ||
- source_internal_format == GL_LUMINANCE_ALPHA ||
- source_internal_format == GL_BGRA_EXT;
- if (!valid_source_format || !valid_dest_format) {
- LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
- "glCopyTextureCHROMIUM",
- "invalid internal format");
+ if (dest_texture->IsImmutable()) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyTextureCHROMIUM",
+ "texture is immutable");
+ return;
+ }
+
+ if (!ValidateCopyTextureCHROMIUM("glCopyTextureCHROMIUM", target,
+ source_texture_ref, dest_texture_ref,
+ internal_format)) {
+ 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, "glCopyTextureCHROMIUM",
+ "dimensions too big");
return;
}
@@ -11044,11 +11089,13 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
GLenum dest_type_previous = dest_type;
GLenum dest_internal_format = internal_format;
- bool dest_level_defined = dest_texture->GetLevelSize(
- GL_TEXTURE_2D, level, &dest_width, &dest_height);
+ int dest_width = 0;
+ int dest_height = 0;
+ bool dest_level_defined =
+ dest_texture->GetLevelSize(GL_TEXTURE_2D, 0, &dest_width, &dest_height);
if (dest_level_defined) {
- dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
+ dest_texture->GetLevelType(GL_TEXTURE_2D, 0, &dest_type_previous,
&dest_internal_format);
}
@@ -11060,9 +11107,8 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
// Ensure that the glTexImage2D succeeds.
LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
- glTexImage2D(
- GL_TEXTURE_2D, level, internal_format, source_width, source_height,
- 0, internal_format, dest_type, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, source_width, source_height,
+ 0, internal_format, dest_type, NULL);
GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
if (error != GL_NO_ERROR) {
RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
@@ -11070,11 +11116,11 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
}
texture_manager()->SetLevelInfo(
- dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
+ dest_texture_ref, GL_TEXTURE_2D, 0, internal_format, source_width,
source_height, 1, 0, internal_format, dest_type, true);
} else {
- texture_manager()->SetLevelCleared(
- dest_texture_ref, GL_TEXTURE_2D, level, true);
+ texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0,
+ true);
}
ScopedModifyPixels modify(dest_texture_ref);
@@ -11082,7 +11128,7 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
// Try using GLImage::CopyTexImage when possible.
bool unpack_premultiply_alpha_change =
unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
- if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
+ if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change) {
glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
if (image->CopyTexImage(GL_TEXTURE_2D))
return;
@@ -11094,36 +11140,149 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
// before presenting.
if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
// TODO(hkuang): get the StreamTexture transform matrix in GPU process
- // instead of using default matrix crbug.com/226218.
- const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f};
+ // instead of using kIdentityMatrix crbug.com/226218.
copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
- this,
- source_texture->target(),
- source_texture->service_id(),
- dest_texture->service_id(),
- level,
- source_width,
- source_height,
- unpack_flip_y_,
- unpack_premultiply_alpha_,
- unpack_unpremultiply_alpha_,
- default_matrix);
+ this, source_texture->target(), source_texture->service_id(),
+ dest_texture->service_id(), source_width, source_height, unpack_flip_y_,
+ unpack_premultiply_alpha_, unpack_unpremultiply_alpha_,
+ kIdentityMatrix);
} else {
- copy_texture_CHROMIUM_->DoCopyTexture(this,
- source_texture->target(),
- source_texture->service_id(),
- source_internal_format,
- dest_texture->service_id(),
- level,
- internal_format,
- source_width,
- source_height,
- unpack_flip_y_,
- unpack_premultiply_alpha_,
- unpack_unpremultiply_alpha_);
+ copy_texture_CHROMIUM_->DoCopyTexture(
+ this, source_texture->target(), source_texture->service_id(),
+ source_internal_format, dest_texture->service_id(), internal_format,
+ source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
+ unpack_unpremultiply_alpha_);
+ }
+
+ DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
+}
+
+void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(GLenum target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLint xoffset,
+ GLint yoffset) {
+ TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopySubTextureCHROMIUM");
+
+ 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, "glCopySubTextureCHROMIUM",
+ "invalid image size");
+ return;
+ }
+ } else {
+ if (!source_texture->GetLevelSize(source_texture->target(), 0,
+ &source_width, &source_height)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
+ "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, "glCopySubTextureCHROMIUM",
+ "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);
+ 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, "glCopySubTextureCHROMIUM",
+ "destination texture is not defined");
+ return;
+ }
+ if (!dest_texture->ValidForTexture(dest_texture->target(), 0, xoffset,
+ yoffset, source_width, source_height,
+ dest_type)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
+ "destination texture bad dimensions.");
+ return;
+ }
+
+ if (!ValidateCopyTextureCHROMIUM("glCopySubTextureCHROMIUM", target,
+ source_texture_ref, dest_texture_ref,
+ dest_internal_format)) {
+ 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, "glCopySubTextureCHROMIUM",
+ "source texture dimensions too big");
+ 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("glCopySubTextureCHROMIUM");
+ copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
+ copy_texture_CHROMIUM_->Initialize(this);
+ RestoreCurrentFramebufferBindings();
+ if (LOCAL_PEEK_GL_ERROR("glCopySubTextureCHROMIUM") != GL_NO_ERROR)
+ return;
+ }
+
+ int dest_width = 0;
+ int dest_height = 0;
+ bool ok =
+ dest_texture->GetLevelSize(GL_TEXTURE_2D, 0, &dest_width, &dest_height);
+ DCHECK(ok);
+ if (xoffset != 0 || yoffset != 0 || source_width != dest_width ||
+ source_height != dest_height) {
+ if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target,
+ 0)) {
+ LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM",
+ "destination texture dimensions too big");
+ return;
+ }
+ } else {
+ texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0,
+ true);
+ }
+
+ ScopedModifyPixels modify(dest_texture_ref);
+
+ DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
+
+ // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
+ // before presenting.
+ if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
+ // TODO(hkuang): get the StreamTexture transform matrix in GPU process
+ // instead of using kIdentityMatrix crbug.com/226218.
+ copy_texture_CHROMIUM_->DoCopySubTextureWithTransform(
+ this, source_texture->target(), source_texture->service_id(),
+ dest_texture->service_id(), xoffset, yoffset, dest_width, dest_height,
+ source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
+ unpack_unpremultiply_alpha_, kIdentityMatrix);
+ } else {
+ copy_texture_CHROMIUM_->DoCopySubTexture(
+ this, source_texture->target(), source_texture->service_id(),
+ source_internal_format, dest_texture->service_id(),
+ dest_internal_format, xoffset, yoffset, dest_width, dest_height,
+ source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
+ unpack_unpremultiply_alpha_);
}
DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
@@ -11728,10 +11887,6 @@ void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
return;
}
- static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f};
-
GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
? state_.projection_matrix
: state_.modelview_matrix;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index c3dfb5d..3c353c4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -4330,7 +4330,6 @@ error::Error GLES2DecoderImpl::HandleCopyTextureCHROMIUM(
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 level = static_cast<GLint>(c.level);
GLint internalformat = static_cast<GLint>(c.internalformat);
GLenum dest_type = static_cast<GLenum>(c.dest_type);
if (!validators_->texture_internal_format.IsValid(internalformat)) {
@@ -4343,8 +4342,22 @@ error::Error GLES2DecoderImpl::HandleCopyTextureCHROMIUM(
"dest_type");
return error::kNoError;
}
- DoCopyTextureCHROMIUM(target, source_id, dest_id, level, internalformat,
- dest_type);
+ DoCopyTextureCHROMIUM(target, source_id, dest_id, internalformat, dest_type);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleCopySubTextureCHROMIUM(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ const gles2::cmds::CopySubTextureCHROMIUM& c =
+ *static_cast<const gles2::cmds::CopySubTextureCHROMIUM*>(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);
+ DoCopySubTextureCHROMIUM(target, source_id, dest_id, xoffset, yoffset);
return error::kNoError;
}
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 f8f4984..29a55ba 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
@@ -235,6 +235,7 @@ TEST_P(GLES2DecoderTest3, PopGroupMarkerEXTValidArgs) {
// TODO(gman): PostSubBufferCHROMIUM
// TODO(gman): TexImageIOSurface2DCHROMIUM
// TODO(gman): CopyTextureCHROMIUM
+// TODO(gman): CopySubTextureCHROMIUM
// TODO(gman): DrawArraysInstancedANGLE
// TODO(gman): DrawElementsInstancedANGLE
// TODO(gman): VertexAttribDivisorANGLE
diff --git a/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc b/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc
index 2c44e1a..ff15241 100644
--- a/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc
+++ b/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc
@@ -17,8 +17,18 @@
namespace gpu {
+namespace {
+enum CopyType { TexImage, TexSubImage };
+const CopyType kCopyTypes[] = {
+ TexImage,
+ TexSubImage,
+};
+}
+
// A collection of tests that exercise the GL_CHROMIUM_copy_texture extension.
-class GLCopyTextureCHROMIUMTest : public testing::Test {
+class GLCopyTextureCHROMIUMTest
+ : public testing::Test,
+ public ::testing::WithParamInterface<CopyType> {
protected:
void SetUp() override {
gl_.Initialize(GLManager::Options());
@@ -50,16 +60,29 @@ class GLCopyTextureCHROMIUMTest : public testing::Test {
GLuint framebuffer_id_;
};
+INSTANTIATE_TEST_CASE_P(CopyType,
+ GLCopyTextureCHROMIUMTest,
+ ::testing::ValuesIn(kCopyTypes));
+
// Test to ensure that the basic functionality of the extension works.
-TEST_F(GLCopyTextureCHROMIUMTest, Basic) {
+TEST_P(GLCopyTextureCHROMIUMTest, Basic) {
+ CopyType copy_type = GetParam();
uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
glBindTexture(GL_TEXTURE_2D, textures_[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
pixels);
- glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
- GL_UNSIGNED_BYTE);
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ }
EXPECT_TRUE(glGetError() == GL_NO_ERROR);
// Check the FB is still bound.
@@ -76,7 +99,51 @@ TEST_F(GLCopyTextureCHROMIUMTest, Basic) {
EXPECT_TRUE(GL_NO_ERROR == glGetError());
}
-TEST_F(GLCopyTextureCHROMIUMTest, InternalFormat) {
+TEST_P(GLCopyTextureCHROMIUMTest, ImmutableTexture) {
+ if (!GLTestHelper::HasExtension("GL_EXT_texture_storage")) {
+ LOG(INFO) << "GL_EXT_texture_storage not supported. Skipping test...";
+ return;
+ }
+ CopyType copy_type = GetParam();
+
+ uint8 pixels[1 * 4] = {255u, 0u, 0u, 255u};
+
+ glBindTexture(GL_TEXTURE_2D, textures_[0]);
+ glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
+ pixels);
+
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ textures_[1], 0);
+ EXPECT_TRUE(glGetError() == GL_NO_ERROR);
+
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
+ EXPECT_TRUE(glGetError() == GL_INVALID_OPERATION);
+ } else {
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ EXPECT_TRUE(glGetError() == GL_NO_ERROR);
+
+ // Check the FB is still bound.
+ GLint value = 0;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
+ GLuint fb_id = value;
+ EXPECT_EQ(framebuffer_id_, fb_id);
+
+ // Check that FB is complete.
+ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
+ glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+ }
+}
+
+TEST_P(GLCopyTextureCHROMIUMTest, InternalFormat) {
+ CopyType copy_type = GetParam();
GLint src_formats[] = {GL_ALPHA, GL_RGB, GL_RGBA,
GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGRA_EXT};
GLint dest_formats[] = {GL_RGB, GL_RGBA};
@@ -85,33 +152,34 @@ TEST_F(GLCopyTextureCHROMIUMTest, InternalFormat) {
for (size_t dest_index = 0; dest_index < arraysize(dest_formats);
dest_index++) {
glBindTexture(GL_TEXTURE_2D, textures_[0]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- src_formats[src_index],
- 1,
- 1,
- 0,
- src_formats[src_index],
- GL_UNSIGNED_BYTE,
- NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, src_formats[src_index], 1, 1, 0,
+ src_formats[src_index], GL_UNSIGNED_BYTE, nullptr);
EXPECT_TRUE(GL_NO_ERROR == glGetError());
- glCopyTextureCHROMIUM(GL_TEXTURE_2D,
- textures_[0],
- textures_[1],
- 0,
- dest_formats[dest_index],
- GL_UNSIGNED_BYTE);
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
+ dest_formats[dest_index], GL_UNSIGNED_BYTE);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, dest_formats[dest_index], 1, 1, 0,
+ dest_formats[dest_index], GL_UNSIGNED_BYTE, nullptr);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
+ 0);
+ }
+
EXPECT_TRUE(GL_NO_ERROR == glGetError()) << "src_index:" << src_index
<< " dest_index:" << dest_index;
}
}
}
-TEST_F(GLCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
+TEST_P(GLCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
+ CopyType copy_type = GetParam();
glBindTexture(GL_TEXTURE_2D, textures_[0]);
- glTexImage2D(
- GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
EXPECT_TRUE(GL_NO_ERROR == glGetError());
// Check unsupported format reports error.
@@ -119,12 +187,17 @@ TEST_F(GLCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
GL_LUMINANCE_ALPHA};
for (size_t dest_index = 0; dest_index < arraysize(unsupported_dest_formats);
dest_index++) {
- glCopyTextureCHROMIUM(GL_TEXTURE_2D,
- textures_[0],
- textures_[1],
- 0,
- unsupported_dest_formats[dest_index],
- GL_UNSIGNED_BYTE);
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
+ unsupported_dest_formats[dest_index],
+ GL_UNSIGNED_BYTE);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, unsupported_dest_formats[dest_index], 1, 1,
+ 0, unsupported_dest_formats[dest_index], GL_UNSIGNED_BYTE,
+ nullptr);
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ }
EXPECT_TRUE(GL_INVALID_OPERATION == glGetError())
<< "dest_index:" << dest_index;
}
@@ -163,8 +236,8 @@ TEST_F(GLCopyTextureCHROMIUMTest, RedefineDestinationTexture) {
// If the dest texture has different properties, glCopyTextureCHROMIUM()
// redefines them.
- glCopyTextureCHROMIUM(
- GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA, GL_UNSIGNED_BYTE);
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
EXPECT_TRUE(GL_NO_ERROR == glGetError());
// glTexSubImage2D() succeeds because textures_[1] is redefined into 2x2
@@ -189,7 +262,8 @@ TEST_F(GLCopyTextureCHROMIUMTest, RedefineDestinationTexture) {
}
// Test that the extension respects the flip-y pixel storage setting.
-TEST_F(GLCopyTextureCHROMIUMTest, FlipY) {
+TEST_P(GLCopyTextureCHROMIUMTest, FlipY) {
+ CopyType copy_type = GetParam();
uint8 pixels[2][2][4];
for (int x = 0; x < 2; ++x) {
for (int y = 0; y < 2; ++y) {
@@ -205,8 +279,16 @@ TEST_F(GLCopyTextureCHROMIUMTest, FlipY) {
pixels);
glPixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
- glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
- GL_UNSIGNED_BYTE);
+
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ }
EXPECT_TRUE(GL_NO_ERROR == glGetError());
uint8 copied_pixels[2][2][4] = {{{0}}};
@@ -225,7 +307,8 @@ TEST_F(GLCopyTextureCHROMIUMTest, FlipY) {
// Test that the extension respects the GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM
// storage setting.
-TEST_F(GLCopyTextureCHROMIUMTest, PremultiplyAlpha) {
+TEST_P(GLCopyTextureCHROMIUMTest, PremultiplyAlpha) {
+ CopyType copy_type = GetParam();
uint8 pixels[1 * 4] = { 2, 2, 2, 128 };
glBindTexture(GL_TEXTURE_2D, textures_[0]);
@@ -233,8 +316,15 @@ TEST_F(GLCopyTextureCHROMIUMTest, PremultiplyAlpha) {
pixels);
glPixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
- glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
- GL_UNSIGNED_BYTE);
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ }
EXPECT_TRUE(GL_NO_ERROR == glGetError());
uint8 copied_pixels[1 * 4] = {0};
@@ -249,7 +339,8 @@ TEST_F(GLCopyTextureCHROMIUMTest, PremultiplyAlpha) {
// Test that the extension respects the GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM
// storage setting.
-TEST_F(GLCopyTextureCHROMIUMTest, UnpremultiplyAlpha) {
+TEST_P(GLCopyTextureCHROMIUMTest, UnpremultiplyAlpha) {
+ CopyType copy_type = GetParam();
uint8 pixels[1 * 4] = { 16, 16, 16, 128 };
glBindTexture(GL_TEXTURE_2D, textures_[0]);
@@ -257,8 +348,15 @@ TEST_F(GLCopyTextureCHROMIUMTest, UnpremultiplyAlpha) {
pixels);
glPixelStorei(GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
- glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
- GL_UNSIGNED_BYTE);
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ }
EXPECT_TRUE(GL_NO_ERROR == glGetError());
uint8 copied_pixels[1 * 4] = {0};
@@ -271,7 +369,8 @@ TEST_F(GLCopyTextureCHROMIUMTest, UnpremultiplyAlpha) {
EXPECT_TRUE(GL_NO_ERROR == glGetError());
}
-TEST_F(GLCopyTextureCHROMIUMTest, FlipYAndPremultiplyAlpha) {
+TEST_P(GLCopyTextureCHROMIUMTest, FlipYAndPremultiplyAlpha) {
+ CopyType copy_type = GetParam();
uint8 pixels[2][2][4];
for (int x = 0; x < 2; ++x) {
for (int y = 0; y < 2; ++y) {
@@ -289,8 +388,15 @@ TEST_F(GLCopyTextureCHROMIUMTest, FlipYAndPremultiplyAlpha) {
glPixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
glPixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
- glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
- GL_UNSIGNED_BYTE);
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ }
EXPECT_TRUE(GL_NO_ERROR == glGetError());
uint8 copied_pixels[2][2][4] = {{{0}}};
@@ -307,7 +413,8 @@ TEST_F(GLCopyTextureCHROMIUMTest, FlipYAndPremultiplyAlpha) {
EXPECT_TRUE(GL_NO_ERROR == glGetError());
}
-TEST_F(GLCopyTextureCHROMIUMTest, FlipYAndUnpremultiplyAlpha) {
+TEST_P(GLCopyTextureCHROMIUMTest, FlipYAndUnpremultiplyAlpha) {
+ CopyType copy_type = GetParam();
uint8 pixels[2][2][4];
for (int x = 0; x < 2; ++x) {
for (int y = 0; y < 2; ++y) {
@@ -325,8 +432,15 @@ TEST_F(GLCopyTextureCHROMIUMTest, FlipYAndUnpremultiplyAlpha) {
glPixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
glPixelStorei(GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
- glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
- GL_UNSIGNED_BYTE);
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ }
EXPECT_TRUE(GL_NO_ERROR == glGetError());
uint8 copied_pixels[2][2][4] = {{{0}}};
@@ -356,7 +470,8 @@ void glEnableDisable(GLint param, GLboolean value) {
// Validate that some basic GL state is not touched upon execution of
// the extension.
-TEST_F(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
+TEST_P(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
+ CopyType copy_type = GetParam();
uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -365,6 +480,12 @@ TEST_F(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
pixels);
+ if (copy_type == TexSubImage) {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ }
+
GLboolean reference_settings[2] = { GL_TRUE, GL_FALSE };
for (int x = 0; x < 2; ++x) {
GLboolean setting = reference_settings[x];
@@ -378,8 +499,12 @@ TEST_F(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
glActiveTexture(GL_TEXTURE1 + x);
- glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
- GL_RGBA, GL_UNSIGNED_BYTE);
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
+ } else {
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ }
EXPECT_TRUE(GL_NO_ERROR == glGetError());
EXPECT_EQ(setting, glIsEnabled(GL_DEPTH_TEST));
@@ -409,13 +534,20 @@ TEST_F(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
// Verify that invocation of the extension does not modify the bound
// texture state.
-TEST_F(GLCopyTextureCHROMIUMTest, TextureStatePreserved) {
+TEST_P(GLCopyTextureCHROMIUMTest, TextureStatePreserved) {
+ CopyType copy_type = GetParam();
// Setup the texture used for the extension invocation.
uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
glBindTexture(GL_TEXTURE_2D, textures_[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
pixels);
+ if (copy_type == TexSubImage) {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ }
+
GLuint texture_ids[2];
glGenTextures(2, texture_ids);
@@ -425,8 +557,12 @@ TEST_F(GLCopyTextureCHROMIUMTest, TextureStatePreserved) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture_ids[1]);
- glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
- GL_RGBA, GL_UNSIGNED_BYTE);
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
+ } else {
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ }
EXPECT_TRUE(GL_NO_ERROR == glGetError());
GLint active_texture = 0;
@@ -451,13 +587,20 @@ TEST_F(GLCopyTextureCHROMIUMTest, TextureStatePreserved) {
// Verify that invocation of the extension does not perturb the currently
// bound FBO state.
-TEST_F(GLCopyTextureCHROMIUMTest, FBOStatePreserved) {
+TEST_P(GLCopyTextureCHROMIUMTest, FBOStatePreserved) {
+ CopyType copy_type = GetParam();
// Setup the texture used for the extension invocation.
uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
glBindTexture(GL_TEXTURE_2D, textures_[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
pixels);
+ if (copy_type == TexSubImage) {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ }
+
GLuint texture_id;
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
@@ -485,8 +628,12 @@ TEST_F(GLCopyTextureCHROMIUMTest, FBOStatePreserved) {
glClear(GL_COLOR_BUFFER_BIT);
GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color);
- glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
- GL_RGBA, GL_UNSIGNED_BYTE);
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
+ } else {
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ }
EXPECT_TRUE(GL_NO_ERROR == glGetError());
EXPECT_TRUE(glIsFramebuffer(framebuffer_id));
@@ -534,7 +681,8 @@ TEST_F(GLCopyTextureCHROMIUMTest, FBOStatePreserved) {
EXPECT_TRUE(GL_NO_ERROR == glGetError());
}
-TEST_F(GLCopyTextureCHROMIUMTest, ProgramStatePreservation) {
+TEST_P(GLCopyTextureCHROMIUMTest, ProgramStatePreservation) {
+ CopyType copy_type = GetParam();
// unbind the one created in setup.
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
@@ -588,8 +736,15 @@ TEST_F(GLCopyTextureCHROMIUMTest, ProgramStatePreservation) {
glBindTexture(GL_TEXTURE_2D, textures_[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
pixels);
- glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
- GL_UNSIGNED_BYTE);
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ }
// test using program after
glClear(GL_COLOR_BUFFER_BIT);
@@ -605,14 +760,22 @@ TEST_F(GLCopyTextureCHROMIUMTest, ProgramStatePreservation) {
}
// Test that glCopyTextureCHROMIUM doesn't leak uninitialized textures.
-TEST_F(GLCopyTextureCHROMIUMTest, UninitializedSource) {
+TEST_P(GLCopyTextureCHROMIUMTest, UninitializedSource) {
+ CopyType copy_type = GetParam();
const GLsizei kWidth = 64, kHeight = 64;
glBindTexture(GL_TEXTURE_2D, textures_[0]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, nullptr);
- glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
- GL_UNSIGNED_BYTE);
+ if (copy_type == TexImage) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
+ GL_UNSIGNED_BYTE);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, nullptr);
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0);
+ }
EXPECT_TRUE(GL_NO_ERROR == glGetError());
uint8 pixels[kHeight][kWidth][4] = {{{1}}};
@@ -629,4 +792,56 @@ TEST_F(GLCopyTextureCHROMIUMTest, UninitializedSource) {
EXPECT_TRUE(GL_NO_ERROR == glGetError());
}
+TEST_F(GLCopyTextureCHROMIUMTest, CopySubTextureDimension) {
+ glBindTexture(GL_TEXTURE_2D, textures_[0]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 1, 1);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+
+ // xoffset < 0
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], -1, 1);
+ EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
+
+ // xoffset + source_width > dest_width
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 2, 2);
+ EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
+}
+
+TEST_F(GLCopyTextureCHROMIUMTest, CopySubTextureOffset) {
+ uint8 red[1 * 4] = {255u, 0u, 0u, 255u};
+ glBindTexture(GL_TEXTURE_2D, textures_[0]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ red);
+
+ uint8 transparent_pixel[4 * 4] = {
+ 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u};
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ transparent_pixel);
+
+ glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 1, 1);
+ EXPECT_TRUE(glGetError() == GL_NO_ERROR);
+
+ // Check the FB is still bound.
+ GLint value = 0;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
+ GLuint fb_id = value;
+ EXPECT_EQ(framebuffer_id_, fb_id);
+
+ // Check that FB is complete.
+ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
+ glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ uint8 transparent[1 * 4] = {0u, 0u, 0u, 0u};
+ GLTestHelper::CheckPixels(0, 0, 1, 1, 0, transparent);
+ GLTestHelper::CheckPixels(1, 1, 1, 1, 0, red);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+}
+
} // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
index 8430dfb..9e37d55 100644
--- a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
+++ b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
@@ -109,7 +109,6 @@ TEST_F(GpuMemoryBufferTest, Lifecycle) {
glCopyTextureCHROMIUM(GL_TEXTURE_2D,
texture_ids_[0],
texture_ids_[1],
- 0,
GL_RGBA,
GL_UNSIGNED_BYTE);
EXPECT_TRUE(glGetError() == GL_NO_ERROR);