diff options
author | twiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-04 21:13:03 +0000 |
---|---|---|
committer | twiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-04 21:13:03 +0000 |
commit | 0a1e9ad53f2f7f2fc6139644da122e272b88fb80 (patch) | |
tree | 8fb141e572f89fd34844b8381c758a286853824f | |
parent | dc03f987519668bcffac2c5ecd8d85feab7aa195 (diff) | |
download | chromium_src-0a1e9ad53f2f7f2fc6139644da122e272b88fb80.zip chromium_src-0a1e9ad53f2f7f2fc6139644da122e272b88fb80.tar.gz chromium_src-0a1e9ad53f2f7f2fc6139644da122e272b88fb80.tar.bz2 |
Addition of a set of basic unit tests for the GL_CHROMIUM_copy_texture extension.
This change also introduces a new parameter to the extension, internal_format. This is to bring the extension closer in functionality to glCopyTexImage.
The tests uncovered state that was not being properly restored: GL_BLEND. This is also corrected.
TEST=GLCopyTextureCHROMIUMTest.*
BUG=126178
Review URL: http://codereview.chromium.org/10356004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135434 0039d316-1c4b-4281-b951-d872f2087c98
22 files changed, 392 insertions, 72 deletions
diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc index 5868cb9..b575103 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc @@ -1480,6 +1480,9 @@ DELEGATE_TO_GL_3(getQueryivEXT, GetQueryivEXT, WGC3Denum, WGC3Denum, WGC3Dint*) DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivEXT, WebGLId, WGC3Denum, WGC3Duint*) +DELEGATE_TO_GL_5(copyTextureCHROMIUM, CopyTextureCHROMIUM, WGC3Denum, + WGC3Denum, WGC3Denum, WGC3Dint, WGC3Dint); + #if WEBKIT_USING_SKIA GrGLInterface* WebGraphicsContext3DCommandBufferImpl::onCreateGrGLInterface() { return webkit_glue::CreateCommandBufferSkiaGLBinding(); @@ -1523,4 +1526,3 @@ void WebGraphicsContext3DCommandBufferImpl::OnErrorMessage( error_message_callback_->onErrorMessage(str, id); } } - diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h index 03472a5..7e4335a 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h @@ -555,6 +555,10 @@ class WebGraphicsContext3DCommandBufferImpl virtual void getQueryObjectuivEXT( WebGLId query, WGC3Denum pname, WGC3Duint* params); + virtual void copyTextureCHROMIUM(WGC3Denum target, WGC3Denum source_id, + WGC3Denum dest_id, WGC3Dint level, + WGC3Dint internal_format); + protected: #if WEBKIT_USING_SKIA virtual GrGLInterface* onCreateGrGLInterface(); diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt index c48ac39..0b22f6b 100644 --- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt +++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt @@ -31,7 +31,8 @@ Overview New Procedures and Functions void glCopyTextureCHROMIUM (GLenum target, GLenum source_id, - GLenum dest_id, GLint level) + GLenum dest_id, GLint level, + GLint internal_format) Copies the contents of texture referred to by <source_id> to texture <dest_id>. @@ -39,6 +40,9 @@ New Procedures and Functions Texture level 0 is copied from the source image to level <level> of the destination texture. + The internal format of the destination texture is converted to that + specified by <internal_format> + <target> uses the same parameters as TexImage2D. INVALID_VALUE is generated if <target> is not GL_TEXTURE_2D. @@ -46,6 +50,9 @@ New Procedures and Functions INVALID_VALUE is generated if <source_id> or <dest_id> are not valid texture objects. + INVALID_VALUE is generated if textures corresponding to <source_id> and + <dest_id> have not been bound as GL_TEXTURE_2D 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. diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index fa75173..a9e07fa 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -623,9 +623,10 @@ void GLES2TexImageIOSurface2DCHROMIUM( target, width, height, ioSurfaceId, plane); } void GLES2CopyTextureCHROMIUM( - GLenum target, GLenum source_id, GLenum dest_id, GLint level) { + GLenum target, GLenum source_id, GLenum dest_id, GLint level, + GLint internalformat) { gles2::GetGLContext()->CopyTextureCHROMIUM( - target, source_id, dest_id, level); + target, source_id, dest_id, level, internalformat); } void GLES2DrawArraysInstancedANGLE( GLenum mode, GLint first, GLsizei count, GLsizei primcount) { diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 82b3b15..4a515e9 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -1718,10 +1718,11 @@ } void CopyTextureCHROMIUM( - GLenum target, GLenum source_id, GLenum dest_id, GLint level) { + GLenum target, GLenum source_id, GLenum dest_id, GLint level, + GLint internalformat) { gles2::CopyTextureCHROMIUM* c = GetCmdSpace<gles2::CopyTextureCHROMIUM>(); if (c) { - c->Init(target, source_id, dest_id, level); + c->Init(target, source_id, dest_id, level, internalformat); } } diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index d9ba14ca..4e59049 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -1547,10 +1547,12 @@ void TexImageIOSurface2DCHROMIUM( } void CopyTextureCHROMIUM( - GLenum target, GLenum source_id, GLenum dest_id, GLint level) { + GLenum target, GLenum source_id, GLenum dest_id, GLint level, + GLint internalformat) { GPU_CLIENT_SINGLE_THREAD_CHECK(); - GPU_CLIENT_LOG("[" << this << "] glCopyTextureCHROMIUM(" << GLES2Util::GetStringEnum(target) << ", " << GLES2Util::GetStringEnum(source_id) << ", " << GLES2Util::GetStringEnum(dest_id) << ", " << level << ")"); // NOLINT - helper_->CopyTextureCHROMIUM(target, source_id, dest_id, level); + GPU_CLIENT_LOG("[" << this << "] glCopyTextureCHROMIUM(" << GLES2Util::GetStringEnum(target) << ", " << GLES2Util::GetStringEnum(source_id) << ", " << GLES2Util::GetStringEnum(dest_id) << ", " << level << ", " << internalformat << ")"); // NOLINT + helper_->CopyTextureCHROMIUM( + target, source_id, dest_id, level, internalformat); } void DrawArraysInstancedANGLE( @@ -1579,4 +1581,3 @@ void ConsumeTextureCHROMIUM(GLenum target, const GLbyte* mailbox) { } #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_ - diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index 4545550..8c714bc 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -1639,9 +1639,9 @@ TEST_F(GLES2ImplementationTest, CopyTextureCHROMIUM) { CopyTextureCHROMIUM cmd; }; Cmds expected; - expected.cmd.Init(1, 2, 3, 4); + expected.cmd.Init(1, 2, 3, 4, GL_ALPHA); - gl_->CopyTextureCHROMIUM(1, 2, 3, 4); + gl_->CopyTextureCHROMIUM(1, 2, 3, 4, GL_ALPHA); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index b22d383..c49b35e 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt @@ -178,7 +178,7 @@ GL_APICALL void GL_APIENTRY glDestroyStreamTextureCHROMIUM (GLuint textu GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLidShader shader, GLsizeiNotNegative bufsize, GLsizei* 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); +GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id, GLint level, GLintTextureInternalFormat internalformat); 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 0f01f5c..5b2e605 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -9537,18 +9537,22 @@ struct CopyTextureCHROMIUM { header.SetCmd<ValueType>(); } - void Init(GLenum _target, GLenum _source_id, GLenum _dest_id, GLint _level) { + void Init( + GLenum _target, GLenum _source_id, GLenum _dest_id, GLint _level, + GLint _internalformat) { SetHeader(); target = _target; source_id = _source_id; dest_id = _dest_id; level = _level; + internalformat = _internalformat; } void* Set( void* cmd, GLenum _target, GLenum _source_id, GLenum _dest_id, - GLint _level) { - static_cast<ValueType*>(cmd)->Init(_target, _source_id, _dest_id, _level); + GLint _level, GLint _internalformat) { + static_cast<ValueType*>( + cmd)->Init(_target, _source_id, _dest_id, _level, _internalformat); return NextCmdAddress<ValueType>(cmd); } @@ -9557,10 +9561,11 @@ struct CopyTextureCHROMIUM { uint32 source_id; uint32 dest_id; int32 level; + int32 internalformat; }; -COMPILE_ASSERT(sizeof(CopyTextureCHROMIUM) == 20, - Sizeof_CopyTextureCHROMIUM_is_not_20); +COMPILE_ASSERT(sizeof(CopyTextureCHROMIUM) == 24, + Sizeof_CopyTextureCHROMIUM_is_not_24); COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, header) == 0, OffsetOf_CopyTextureCHROMIUM_header_not_0); COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, target) == 4, @@ -9571,6 +9576,8 @@ COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, dest_id) == 12, OffsetOf_CopyTextureCHROMIUM_dest_id_not_12); COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, level) == 16, OffsetOf_CopyTextureCHROMIUM_level_not_16); +COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, internalformat) == 20, + OffsetOf_CopyTextureCHROMIUM_internalformat_not_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 f3c0661..bc1485a 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -3708,7 +3708,8 @@ TEST_F(GLES2FormatTest, CopyTextureCHROMIUM) { static_cast<GLenum>(11), static_cast<GLenum>(12), static_cast<GLenum>(13), - static_cast<GLint>(14)); + static_cast<GLint>(14), + static_cast<GLint>(15)); EXPECT_EQ(static_cast<uint32>(CopyTextureCHROMIUM::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); @@ -3716,6 +3717,7 @@ TEST_F(GLES2FormatTest, CopyTextureCHROMIUM) { 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); CheckBytesWrittenMatchesExpectedSize( next_cmd, sizeof(cmd)); } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index ebb56bc..7d978d3 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -743,7 +743,8 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, GLenum target, GLuint source_id, GLuint target_id, - GLint level); + GLint level, + GLenum internal_format); // Wrapper for TexStorage2DEXT. void DoTexStorage2DEXT( @@ -1415,6 +1416,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, GLuint mask_stencil_back_; GLclampf clear_depth_; GLboolean mask_depth_; + bool enable_blend_; bool enable_cull_face_; bool enable_scissor_test_; bool enable_depth_test_; @@ -1892,6 +1894,7 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) mask_stencil_back_(-1), clear_depth_(1.0f), mask_depth_(true), + enable_blend_(false), enable_cull_face_(false), enable_scissor_test_(false), enable_depth_test_(false), @@ -3278,6 +3281,7 @@ void GLES2DecoderImpl::ApplyDirtyState() { EnableDisable(GL_STENCIL_TEST, enable_stencil_test_ && have_stencil); EnableDisable(GL_CULL_FACE, enable_cull_face_); EnableDisable(GL_SCISSOR_TEST, enable_scissor_test_); + EnableDisable(GL_BLEND, enable_blend_); state_dirty_ = false; } } @@ -4097,6 +4101,9 @@ void GLES2DecoderImpl::DoFramebufferRenderbuffer( bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) { switch (cap) { + case GL_BLEND: + enable_blend_ = enabled; + return true; case GL_CULL_FACE: enable_cull_face_ = enabled; return true; @@ -6248,6 +6255,12 @@ error::Error GLES2DecoderImpl::HandlePixelStorei( "glPixelSTore: param GL_INVALID_VALUE"); return error::kNoError; } + case GL_UNPACK_FLIP_Y_CHROMIUM: + unpack_flip_y_ = (param != 0); + return error::kNoError; + case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM: + unpack_premultiply_alpha_ = (param != 0); + return error::kNoError; default: break; } @@ -6261,12 +6274,6 @@ error::Error GLES2DecoderImpl::HandlePixelStorei( case GL_UNPACK_ALIGNMENT: unpack_alignment_ = param; break; - case GL_UNPACK_FLIP_Y_CHROMIUM: - unpack_flip_y_ = (param != 0); - break; - case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM: - unpack_premultiply_alpha_ = (param != 0); - break; default: // Validation should have prevented us from getting here. NOTREACHED(); @@ -8380,7 +8387,8 @@ static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) { } void GLES2DecoderImpl::DoCopyTextureCHROMIUM( - GLenum target, GLuint source_id, GLuint dest_id, GLint level) { + GLenum target, GLuint source_id, GLuint dest_id, GLint level, + GLenum internal_format) { TextureManager::TextureInfo* dest_info = GetTextureInfo(dest_id); TextureManager::TextureInfo* source_info = GetTextureInfo(source_id); @@ -8395,18 +8403,18 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( return; } - int source_width, source_height, dest_width, dest_height; - if (!source_info->GetLevelSize(GL_TEXTURE_2D, 0, &source_width, - &source_height)) { + if (dest_info->target() != GL_TEXTURE_2D || + source_info->target() != GL_TEXTURE_2D) { SetGLError(GL_INVALID_VALUE, - "glCopyTextureChromium: source texture has no level 0"); + "glCopyTextureCHROMIUM: invalid texture target binding"); return; } - if (!dest_info->GetLevelSize(GL_TEXTURE_2D, level, &dest_width, - &dest_height)) { + int source_width, source_height, dest_width, dest_height; + if (!source_info->GetLevelSize(GL_TEXTURE_2D, 0, &source_width, + &source_height)) { SetGLError(GL_INVALID_VALUE, - "glCopyTextureChromium: destination texture level does not exist"); + "glCopyTextureChromium: source texture has no level 0"); return; } @@ -8418,28 +8426,44 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( return; } - // Resize the destination texture to the dimensions of the source texture. - if (dest_width != source_width && dest_height != source_height) { - GLenum type; - GLenum internal_format; - dest_info->GetLevelType(GL_TEXTURE_2D, level, &type, &internal_format); + GLenum dest_type; + GLenum dest_internal_format; + bool dest_level_defined = dest_info->GetLevelSize(GL_TEXTURE_2D, level, + &dest_width, + &dest_height); + + if (dest_level_defined) { + dest_info->GetLevelType(GL_TEXTURE_2D, level, &dest_type, + &dest_internal_format); + } else { + GLenum source_internal_format; + source_info->GetLevelType(GL_TEXTURE_2D, 0, &dest_type, + &source_internal_format); + } + // Resize the destination texture to the dimensions of the source texture. + if (!dest_level_defined || dest_width != source_width || + dest_height != source_height || + dest_internal_format != internal_format) { // Ensure that the glTexImage2D succeeds. CopyRealGLErrorsToWrapper(); + glBindTexture(GL_TEXTURE_2D, dest_info->service_id()); WrappedTexImage2D( GL_TEXTURE_2D, level, internal_format, source_width, source_height, - 0, internal_format, type, NULL); + 0, internal_format, dest_type, NULL); GLenum error = PeekGLError(); - if (error != GL_NO_ERROR) + if (error != GL_NO_ERROR) { + RestoreCurrentTexture2DBindings(); return; + } texture_manager()->SetLevelInfo( dest_info, GL_TEXTURE_2D, level, internal_format, source_width, - source_height, 1, 0, internal_format, type, true); + source_height, 1, 0, internal_format, dest_type, true); } state_dirty_ = true; - glViewport(0, 0, dest_width, dest_height); + glViewport(0, 0, source_width, source_height); copy_texture_CHROMIUM_->DoCopyTexture(target, source_info->service_id(), dest_info->service_id(), level, unpack_flip_y_, diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index f2b9f26..49ec263 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -2732,7 +2732,14 @@ error::Error GLES2DecoderImpl::HandleCopyTextureCHROMIUM( 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); - DoCopyTextureCHROMIUM(target, source_id, dest_id, level); + GLint internalformat = static_cast<GLint>(c.internalformat); + if (!validators_->texture_internal_format.IsValid(internalformat)) { + SetGLError( + GL_INVALID_VALUE, + "glCopyTextureCHROMIUM: internalformat GL_INVALID_VALUE"); + return error::kNoError; + } + DoCopyTextureCHROMIUM(target, source_id, dest_id, level, internalformat); return error::kNoError; } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index a1b6613..3c20100 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -3548,7 +3548,8 @@ TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMask) { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -3604,7 +3605,8 @@ TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferDepthMask) { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -3658,7 +3660,8 @@ TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferStencilMask) { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -3713,7 +3716,8 @@ TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMaskFBO) { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -3761,7 +3765,8 @@ TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMaskFBO) { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -3790,7 +3795,8 @@ TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMaskFBO) { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -4015,7 +4021,9 @@ TEST_F(GLES2DecoderManualInitTest, DepthEnableWithDepth) { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled + EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -4075,7 +4083,8 @@ TEST_F(GLES2DecoderManualInitTest, DepthEnableWithoutRequestedDepth) { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -4133,9 +4142,10 @@ TEST_F(GLES2DecoderManualInitTest, StencilEnableWithStencil) { false, // depth enabled -1, // front stencil mask -1, // back stencil mask - true, // stencil enabled + true, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -4195,7 +4205,8 @@ TEST_F(GLES2DecoderManualInitTest, StencilEnableWithoutRequestedStencil) { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -5950,7 +5961,8 @@ TEST_F(GLES2DecoderWithShaderTest, DrawClearsAfterTexImage2DNULLInFBO) { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -6115,7 +6127,8 @@ TEST_F(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnClear) { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT)) .Times(1) @@ -6271,7 +6284,8 @@ TEST_F(GLES2DecoderWithShaderTest, DrawClearsAfterRenderbufferStorageInFBO) { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -6386,7 +6400,8 @@ TEST_F(GLES2DecoderWithShaderTest, 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -6606,7 +6621,8 @@ TEST_F(GLES2DecoderWithShaderTest, 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index 2a43f99..1e717f5 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -665,7 +665,8 @@ void GLES2DecoderTestBase::SetupExpectationsForApplyingDirtyState( GLuint back_stencil_mask, bool stencil_enabled, bool cull_face_enabled, - bool scissor_test_enabled) { + bool scissor_test_enabled, + bool blend_enabled) { EXPECT_CALL(*gl_, ColorMask( (color_bits & 0x1000) != 0, (color_bits & 0x0100) != 0, @@ -710,13 +711,22 @@ void GLES2DecoderTestBase::SetupExpectationsForApplyingDirtyState( .RetiresOnSaturation(); } if (scissor_test_enabled) { - EXPECT_CALL(*gl_, Enable(GL_SCISSOR_TEST)) - .Times(1) - .RetiresOnSaturation(); + EXPECT_CALL(*gl_, Enable(GL_SCISSOR_TEST)) + .Times(1) + .RetiresOnSaturation(); } else { - EXPECT_CALL(*gl_, Disable(GL_SCISSOR_TEST)) - .Times(1) - .RetiresOnSaturation(); + EXPECT_CALL(*gl_, Disable(GL_SCISSOR_TEST)) + .Times(1) + .RetiresOnSaturation(); + } + if (blend_enabled) { + EXPECT_CALL(*gl_, Enable(GL_BLEND)) + .Times(1) + .RetiresOnSaturation(); + } else { + EXPECT_CALL(*gl_, Disable(GL_BLEND)) + .Times(1) + .RetiresOnSaturation(); } } @@ -732,7 +742,8 @@ void GLES2DecoderTestBase::SetupExpectationsForApplyingDefaultDirtyState() { 0, // back stencil mask false, // stencil enabled false, // cull_face_enabled - false); // scissor_test_enabled + false, // scissor_test_enabled + false); // blend_enabled } void GLES2DecoderTestBase::DoBindFramebuffer( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index 64d47f6..2cae914 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -305,7 +305,8 @@ class GLES2DecoderTestBase : public testing::Test { GLuint back_stencil_mask, bool stencil_enabled, bool cull_face_enabled, - bool scissor_test_enabled); + bool scissor_test_enabled, + bool blend_enabled); void SetupExpectationsForApplyingDefaultDirtyState(); diff --git a/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc b/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc new file mode 100644 index 0000000..9020537 --- /dev/null +++ b/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc @@ -0,0 +1,219 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES +#endif + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include "gpu/command_buffer/tests/gl_manager.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu { + +// A collection of tests that exercise the GL_CHROMIUM_copy_texture extension. +class GLCopyTextureCHROMIUMTest : public testing::Test { + protected: + GLCopyTextureCHROMIUMTest() : gl_(NULL, NULL) { + } + + virtual void SetUp() { + gl_.Initialize(gfx::Size(4, 4)); + + glGenTextures(2, textures_); + glBindTexture(GL_TEXTURE_2D, textures_[1]); + + glGenFramebuffers(1, &framebuffer_id_); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + textures_[1], 0); + } + + virtual void TearDown() { + glDeleteTextures(2, textures_); + glDeleteFramebuffers(1, &framebuffer_id_); + gl_.Destroy(); + } + + GLManager gl_; + GLuint textures_[2]; + GLuint framebuffer_id_; +}; + +// Test to ensure that the basic functionality of the extension works. +TEST_F(GLCopyTextureCHROMIUMTest, Basic) { + 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); + EXPECT_TRUE(glGetError() == GL_NO_ERROR); + + uint8 copied_pixels[1 * 4]; + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels); + EXPECT_EQ(pixels[0], copied_pixels[0]); + EXPECT_EQ(pixels[1], copied_pixels[1]); + EXPECT_EQ(pixels[2], copied_pixels[2]); + EXPECT_EQ(pixels[3], copied_pixels[3]); + + EXPECT_TRUE(GL_NO_ERROR == glGetError()); +} + +// Test that the extension respects the flip-y pixel storage setting. +TEST_F(GLCopyTextureCHROMIUMTest, FlipY) { + uint8 pixels[2][2][4]; + for (int x = 0; x < 2; ++x) { + for (int y = 0; y < 2; ++y) { + pixels[y][x][0] = x + y; + pixels[y][x][1] = x + y; + pixels[y][x][2] = x + y; + pixels[y][x][3] = 255u; + } + } + + glBindTexture(GL_TEXTURE_2D, textures_[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixels); + + glPixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); + glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA); + EXPECT_TRUE(GL_NO_ERROR == glGetError()); + + uint8 copied_pixels[2][2][4]; + glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels); + for (int x = 0; x < 2; ++x) { + for (int y = 0; y < 2; ++y) + EXPECT_EQ(pixels[1-y][x][0], copied_pixels[y][x][0]); + } + + EXPECT_TRUE(GL_NO_ERROR == glGetError()); +} + +// Test that the extension respects the GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM +// storage setting. +TEST_F(GLCopyTextureCHROMIUMTest, PremultiplyAlpha) { + uint8 pixels[1 * 4] = { 2, 2, 2, 128 }; + + glBindTexture(GL_TEXTURE_2D, textures_[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixels); + + glPixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE); + glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA); + EXPECT_TRUE(GL_NO_ERROR == glGetError()); + + uint8 copied_pixels[1 * 4]; + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels); + EXPECT_EQ(1u, copied_pixels[0]); + EXPECT_EQ(1u, copied_pixels[1]); + EXPECT_EQ(1u, copied_pixels[2]); + EXPECT_EQ(128u, copied_pixels[3]); + + EXPECT_TRUE(GL_NO_ERROR == glGetError()); +} + +TEST_F(GLCopyTextureCHROMIUMTest, FlipYAndPremultiplyAlpha) { + uint8 pixels[2][2][4]; + for (int x = 0; x < 2; ++x) { + for (int y = 0; y < 2; ++y) { + pixels[y][x][0] = x + y; + pixels[y][x][1] = x + y; + pixels[y][x][2] = x + y; + pixels[y][x][3] = 128u; + } + } + + glBindTexture(GL_TEXTURE_2D, textures_[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixels); + + 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); + EXPECT_TRUE(GL_NO_ERROR == glGetError()); + + uint8 copied_pixels[2][2][4]; + glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels); + for (int x = 0; x < 2; ++x) { + for (int y = 0; y < 2; ++y) { + EXPECT_EQ(pixels[1-y][x][0] / 2, copied_pixels[y][x][0]); + EXPECT_EQ(pixels[1-y][x][1] / 2, copied_pixels[y][x][1]); + EXPECT_EQ(pixels[1-y][x][2] / 2, copied_pixels[y][x][2]); + EXPECT_EQ(pixels[1-y][x][3], copied_pixels[y][x][3]); + } + } + + EXPECT_TRUE(GL_NO_ERROR == glGetError()); +} + +namespace { + +void glEnableDisable(GLint param, GLboolean value) { + if (value) + glEnable(param); + else + glDisable(param); +} + +} // unnamed namespace + +// Validate that some basic GL state is not touched upon execution of +// the extension. +TEST_F(GLCopyTextureCHROMIUMTest, BasicStatePreservation) { + uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u }; + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glBindTexture(GL_TEXTURE_2D, textures_[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixels); + + GLboolean reference_settings[2] = { GL_TRUE, GL_FALSE }; + for (int x = 0; x < 2; ++x) { + GLboolean setting = reference_settings[x]; + glEnableDisable(GL_DEPTH_TEST, setting); + glEnableDisable(GL_SCISSOR_TEST, setting); + glEnableDisable(GL_STENCIL_TEST, setting); + glEnableDisable(GL_CULL_FACE, setting); + glEnableDisable(GL_BLEND, setting); + glColorMask(setting, setting, setting, setting); + glDepthMask(setting); + + glActiveTexture(GL_TEXTURE1 + x); + + glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, + GL_RGBA); + EXPECT_TRUE(GL_NO_ERROR == glGetError()); + + EXPECT_EQ(setting, glIsEnabled(GL_DEPTH_TEST)); + EXPECT_EQ(setting, glIsEnabled(GL_SCISSOR_TEST)); + EXPECT_EQ(setting, glIsEnabled(GL_STENCIL_TEST)); + EXPECT_EQ(setting, glIsEnabled(GL_CULL_FACE)); + EXPECT_EQ(setting, glIsEnabled(GL_BLEND)); + + GLboolean bool_array[4] = { GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE }; + glGetBooleanv(GL_DEPTH_WRITEMASK, bool_array); + EXPECT_EQ(setting, bool_array[0]); + + bool_array[0] = GL_FALSE; + glGetBooleanv(GL_COLOR_WRITEMASK, bool_array); + EXPECT_EQ(setting, bool_array[0]); + EXPECT_EQ(setting, bool_array[1]); + EXPECT_EQ(setting, bool_array[2]); + EXPECT_EQ(setting, bool_array[3]); + + GLint active_texture = 0; + glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); + EXPECT_EQ(GL_TEXTURE1 + x, active_texture); + } + + EXPECT_TRUE(GL_NO_ERROR == glGetError()); +}; + +} // namespace gpu diff --git a/gpu/gpu_common.gypi b/gpu/gpu_common.gypi index 16fa5ba..31322e7 100644 --- a/gpu/gpu_common.gypi +++ b/gpu/gpu_common.gypi @@ -241,9 +241,11 @@ ], 'sources': [ '<@(gles2_c_lib_source_files)', - 'command_buffer/tests/gl_tests_main.cc', + 'command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc', 'command_buffer/tests/gl_manager.cc', 'command_buffer/tests/gl_manager.h', + 'command_buffer/tests/gl_tests_main.cc', + 'command_buffer/tests/gl_unittests.cc', ], }, { diff --git a/third_party/khronos/GLES2/gl2ext.h b/third_party/khronos/GLES2/gl2ext.h index 45943a0..3b162b8 100644 --- a/third_party/khronos/GLES2/gl2ext.h +++ b/third_party/khronos/GLES2/gl2ext.h @@ -1966,10 +1966,10 @@ typedef void (GL_APIENTRYP PFNGLTEXIMAGEIOSURFACE2DCHROMIUM) (GLenum target, GLs #ifdef GL_GLEXT_PROTOTYPES #define glCopyTextureCHROMIUM GLES2_GET_FUN(CopyTextureCHROMIUM) #if !defined(GLES2_USE_CPP_BINDINGS) -GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id, GLint level); +GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM (GLenum target, GLenum source_id, GLenum dest_id, GLint level, GLint internal_format); #endif #else -typedef void (GL_APIENTRYP PFNGLCOPYTEXTURECHROMIUM) (GLenum target, GLenum source_id, GLenum dest_id, GLint level); +typedef void (GL_APIENTRYP PFNGLCOPYTEXTURECHROMIUM) (GLenum target, GLenum source_id, GLenum dest_id, GLint level, GLint internal_format); #endif #endif diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc index b0f6a82..2a69029 100644 --- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc +++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc @@ -1594,6 +1594,9 @@ DELEGATE_TO_GL_3(getQueryivEXT, GetQueryivEXT, WGC3Denum, WGC3Denum, WGC3Dint*) DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivEXT, WebGLId, WGC3Denum, WGC3Duint*) +DELEGATE_TO_GL_5(copyTextureCHROMIUM, CopyTextureCHROMIUM, WGC3Denum, + WGC3Denum, WGC3Denum, WGC3Dint, WGC3Dint) + #if WEBKIT_USING_SKIA GrGLInterface* WebGraphicsContext3DInProcessCommandBufferImpl:: onCreateGrGLInterface() { diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h index aac2019c..dd6b820 100644 --- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h +++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h @@ -475,6 +475,10 @@ class WebGraphicsContext3DInProcessCommandBufferImpl virtual void getQueryObjectuivEXT( WebGLId query, WGC3Denum pname, WGC3Duint* params); + virtual void copyTextureCHROMIUM(WGC3Denum target, WGC3Denum source_id, + WGC3Denum dest_id, WGC3Dint level, + WGC3Dint internal_format); + protected: #if WEBKIT_USING_SKIA virtual GrGLInterface* onCreateGrGLInterface(); diff --git a/webkit/gpu/webgraphicscontext3d_in_process_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_impl.cc index 7e2ec0d..c13fd94 100644 --- a/webkit/gpu/webgraphicscontext3d_in_process_impl.cc +++ b/webkit/gpu/webgraphicscontext3d_in_process_impl.cc @@ -1671,6 +1671,11 @@ DELEGATE_TO_GL_3(getQueryivEXT, GetQueryivARB, WGC3Denum, WGC3Denum, WGC3Dint*) DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivARB, WebGLId, WGC3Denum, WGC3Duint*) +void WebGraphicsContext3DInProcessImpl::copyTextureCHROMIUM( + WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint) +{ +} + #if WEBKIT_USING_SKIA GrGLInterface* WebGraphicsContext3DInProcessImpl::onCreateGrGLInterface() { return gfx::CreateInProcessSkiaGLBinding(); diff --git a/webkit/gpu/webgraphicscontext3d_in_process_impl.h b/webkit/gpu/webgraphicscontext3d_in_process_impl.h index c0bf7b1..c34c404 100644 --- a/webkit/gpu/webgraphicscontext3d_in_process_impl.h +++ b/webkit/gpu/webgraphicscontext3d_in_process_impl.h @@ -472,6 +472,9 @@ class WebGraphicsContext3DInProcessImpl : public WebGraphicsContext3D { virtual void getQueryObjectuivEXT( WebGLId query, WGC3Denum pname, WGC3Duint* params); + virtual void copyTextureCHROMIUM(WGC3Denum target, WGC3Denum source_id, + WGC3Denum dest_id, WGC3Dint level); + protected: #if WEBKIT_USING_SKIA virtual GrGLInterface* onCreateGrGLInterface(); |