diff options
author | dongseong.hwang <dongseong.hwang@intel.com> | 2015-03-03 00:42:55 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-03 08:43:59 +0000 |
commit | fac6a2d44323ad51429ee728e241fe22242f5ebd (patch) | |
tree | 433c4f8bd443d0c6595fbcd865ca6606300e2a0e /gpu | |
parent | d5ab8aac09df4a85083ba043ec5ff71fd5e94bdb (diff) | |
download | chromium_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')
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); |