diff options
author | twiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-19 03:20:27 +0000 |
---|---|---|
committer | twiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-19 03:20:27 +0000 |
commit | b64c2495b3b3ac66edcb31667e17942dd7888b1a (patch) | |
tree | 1c18d654caa67a8d99cbd81a16679c2ee36f9ba9 /gpu | |
parent | 7e1942af8a3fd104735e9c3b7b8800772b8c13b6 (diff) | |
download | chromium_src-b64c2495b3b3ac66edcb31667e17942dd7888b1a.zip chromium_src-b64c2495b3b3ac66edcb31667e17942dd7888b1a.tar.gz chromium_src-b64c2495b3b3ac66edcb31667e17942dd7888b1a.tar.bz2 |
Introduction of CHROMIUM_copy_texture extension that respects pixel-store semantics, and allows copying of BGRA textures.
OpenGL ES does not natively allow for copying textures with a BGRA format. The EXT_texture_format_BGRA8888 extension does not specify support for glCopyTexImage calls on these textures.
This extension provides a routine to perform texture copies to/from BGRA-backed textures that also respects the following CHROMIUM pixel storage modifiers:
UNPACK_FLIP_Y_CHROMIUM
UNPACK_PREMULTIPLY_ALPHA_CHROMIUM
This extension will be useful for the following purposes:
- Copying accelerated Canvas2D contents to WebGL textures without a software readback. (And potentially the same for video-webgl texture copies.)
- Copying Canvas2D contents to the compositor backing store.
BUG=101051
TEST=none
Review URL: http://codereview.chromium.org/9968113
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132934 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
25 files changed, 968 insertions, 42 deletions
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt new file mode 100644 index 0000000..c48ac39 --- /dev/null +++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt @@ -0,0 +1,66 @@ +Name + + CHROMIUM_copy_texture + +Name Strings + + GL_CHROMIUM_copy_texture + +Version + + Last Modifed Date: April 3, 2012 + +Dependencies + + OpenGL ES 2.0 is required. + + CHROMIUM_flipy affects the definition of this extension. + EXT_texture_format_BGRA8888 affects the definition of this extension. + +Overview + + This extension expands on the functionality provided by the + glCopyTexImage2D command. A new function is exported, + glCopyTextureCHROMIUM, that performs the same copy operation as + glCopyTexImage2D, while respecting the pixel-storage modifiers + UNPACK_FLIP_Y_CHROMIUM and GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM. + + The extension also supports copying BGRA textures, which is not explicitly + granted by EXT_texture_format_BGRA8888. + +New Procedures and Functions + + void glCopyTextureCHROMIUM (GLenum target, GLenum source_id, + GLenum dest_id, GLint level) + + Copies the contents of texture referred to by <source_id> to texture + <dest_id>. + + Texture level 0 is copied from the source image to level <level> of the + destination texture. + + <target> uses the same parameters as TexImage2D. + + INVALID_VALUE is generated if <target> is not GL_TEXTURE_2D. + + INVALID_VALUE is generated if <source_id> or <dest_id> are not valid texture + 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. + +Errors + + None. + +New Tokens + + None. + +New State + + None. + +Revision History + + 8/1/2011 Documented the extension diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index e29b692..39d2025 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -587,6 +587,8 @@ _ENUM_LISTS = { 'valid': [ 'GL_PACK_ALIGNMENT', 'GL_UNPACK_ALIGNMENT', + 'GL_UNPACK_FLIP_Y_CHROMIUM', + 'GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM', ], 'invalid': [ 'GL_PACK_SWAP_BYTES', @@ -1510,6 +1512,9 @@ _FUNCTION_INFO = { 'GLsizei stride, GLuint offset', 'client_test': False, }, + 'Viewport': { + 'decoder_func': 'DoViewport', + }, 'ResizeCHROMIUM': { 'type': 'Custom', 'impl_func': False, @@ -1564,6 +1569,12 @@ _FUNCTION_INFO = { 'extension': True, 'chromium': True, }, + 'CopyTextureCHROMIUM': { + 'decoder_func': 'DoCopyTextureCHROMIUM', + '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 6d86539..263c868 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -622,6 +622,11 @@ void GLES2TexImageIOSurface2DCHROMIUM( gles2::GetGLContext()->TexImageIOSurface2DCHROMIUM( target, width, height, ioSurfaceId, plane); } +void GLES2CopyTextureCHROMIUM( + GLenum target, GLenum source_id, GLenum dest_id, GLint level) { + gles2::GetGLContext()->CopyTextureCHROMIUM( + target, source_id, dest_id, level); +} void GLES2DrawArraysInstancedANGLE( GLenum mode, GLint first, GLsizei count, GLsizei primcount) { gles2::GetGLContext()->DrawArraysInstancedANGLE( diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 77e1ff2..b520491 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -1717,6 +1717,14 @@ } } + void CopyTextureCHROMIUM( + GLenum target, GLenum source_id, GLenum dest_id, GLint level) { + gles2::CopyTextureCHROMIUM* c = GetCmdSpace<gles2::CopyTextureCHROMIUM>(); + if (c) { + c->Init(target, source_id, dest_id, level); + } + } + void DrawArraysInstancedANGLE( GLenum mode, GLint first, GLsizei count, GLsizei primcount) { gles2::DrawArraysInstancedANGLE* c = diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 4f5d427..ef25113 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -1254,7 +1254,7 @@ void GLES2Implementation::PixelStorei(GLenum pname, GLint param) { return; case GL_UNPACK_FLIP_Y_CHROMIUM: unpack_flip_y_ = (param != 0); - return; + break; case GL_PACK_REVERSE_ROW_ORDER_ANGLE: pack_reverse_row_order_ = IsAnglePackReverseRowOrderAvailable() ? (param != 0) : false; diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index dbebd67..9193535 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -1546,6 +1546,13 @@ void TexImageIOSurface2DCHROMIUM( target, width, height, ioSurfaceId, plane); } +void CopyTextureCHROMIUM( + GLenum target, GLenum source_id, GLenum dest_id, GLint level) { + 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); +} + void DrawArraysInstancedANGLE( GLenum mode, GLint first, GLsizei count, GLsizei primcount); diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index 4bb5830..a999f01 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -296,7 +296,7 @@ void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) { class GLES2ImplementationTest : public testing::Test { protected: static const uint8 kInitialValue = 0xBD; - static const int32 kNumCommandEntries = 400; + static const int32 kNumCommandEntries = 500; static const int32 kCommandBufferSizeBytes = kNumCommandEntries * sizeof(CommandBufferEntry); static const size_t kTransferBufferSize = 256; @@ -1910,6 +1910,8 @@ TEST_F(GLES2ImplementationTest, TexImage2D) { pixels, mem1.ptr)); ClearCommands(); + gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); + ExpectedMemoryInfo mem2 = GetExpectedMemory(sizeof(pixels)); Cmds2 expected2; expected2.tex_image_2d.Init( @@ -1917,7 +1919,6 @@ TEST_F(GLES2ImplementationTest, TexImage2D) { mem2.id, mem2.offset); expected2.set_token.Init(GetNextToken()); const void* commands2 = GetPut(); - gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); gl_->TexImage2D( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, pixels); @@ -1997,6 +1998,7 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) { pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr)); ClearCommands(); + gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); const void* commands2 = GetPut(); ExpectedMemoryInfo mem3 = GetExpectedMemory(half_size); ExpectedMemoryInfo mem4 = GetExpectedMemory(half_size); @@ -2020,7 +2022,6 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) { // GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size))) // .RetiresOnSaturation(); - gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); gl_->TexImage2D( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, pixels.get()); @@ -2048,6 +2049,7 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) { struct Cmds { PixelStorei pixel_store_i1; TexImage2D tex_image_2d; + PixelStorei pixel_store_i2; TexSubImage2D tex_sub_image_2d1; cmd::SetToken set_token1; TexSubImage2D tex_sub_image_2d2; @@ -2067,6 +2069,7 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) { expected.tex_image_2d.Init( kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kBorder, kFormat, kType, 0, 0); + expected.pixel_store_i2.Init(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset, kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType, mem1.id, mem1.offset, false); @@ -2080,12 +2083,11 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) { gl_->TexImage2D( kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kBorder, kFormat, kType, NULL); - // this call should not emit commands (handled client-side) gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); scoped_array<uint32> pixels(new uint32[kSubImageWidth * kSubImageHeight]); for (int y = 0; y < kSubImageHeight; ++y) { for (int x = 0; x < kSubImageWidth; ++x) { - pixels.get()[kSubImageWidth * y + x] = x | (y << 16); + pixels.get()[kSubImageWidth * y + x] = x | (y << 16); } } gl_->TexSubImage2D( @@ -2125,11 +2127,13 @@ TEST_F(GLES2ImplementationTest, SubImageUnpack) { struct { PixelStorei pixel_store_i; + PixelStorei pixel_store_i2; TexImage2D tex_image_2d; } texImageExpected; struct { PixelStorei pixel_store_i; + PixelStorei pixel_store_i2; TexImage2D tex_image_2d; TexSubImage2D tex_sub_image_2d; } texSubImageExpected; @@ -2172,6 +2176,8 @@ TEST_F(GLES2ImplementationTest, SubImageUnpack) { src_pixels.get()); texSubImageExpected.pixel_store_i.Init( GL_UNPACK_ALIGNMENT, alignment); + texSubImageExpected.pixel_store_i2.Init( + GL_UNPACK_FLIP_Y_CHROMIUM, flip_y); texSubImageExpected.tex_image_2d.Init( GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder, kFormat, kType, 0, 0); @@ -2187,6 +2193,8 @@ TEST_F(GLES2ImplementationTest, SubImageUnpack) { kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType, src_pixels.get()); texImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment); + texImageExpected.pixel_store_i2.Init( + GL_UNPACK_FLIP_Y_CHROMIUM, flip_y); texImageExpected.tex_image_2d.Init( GL_TEXTURE_2D, kLevel, kFormat, kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType, mem.id, mem.offset); diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index f69981f..8128e9c 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -1634,6 +1634,17 @@ TEST_F(GLES2ImplementationTest, TexImageIOSurface2DCHROMIUM) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, CopyTextureCHROMIUM) { + struct Cmds { + CopyTextureCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2, 3, 4); + + gl_->CopyTextureCHROMIUM(1, 2, 3, 4); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, DrawArraysInstancedANGLE) { struct Cmds { DrawArraysInstancedANGLE cmd; diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index 688a9d3..9676d02 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt @@ -178,6 +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 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 f227dee..3e93516 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -9524,6 +9524,54 @@ COMPILE_ASSERT(offsetof(TexImageIOSurface2DCHROMIUM, ioSurfaceId) == 16, COMPILE_ASSERT(offsetof(TexImageIOSurface2DCHROMIUM, plane) == 20, OffsetOf_TexImageIOSurface2DCHROMIUM_plane_not_20); +struct CopyTextureCHROMIUM { + typedef CopyTextureCHROMIUM ValueType; + static const CommandId kCmdId = kCopyTextureCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _target, GLenum _source_id, GLenum _dest_id, GLint _level) { + SetHeader(); + target = _target; + source_id = _source_id; + dest_id = _dest_id; + level = _level; + } + + 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); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32 target; + uint32 source_id; + uint32 dest_id; + int32 level; +}; + +COMPILE_ASSERT(sizeof(CopyTextureCHROMIUM) == 20, + Sizeof_CopyTextureCHROMIUM_is_not_20); +COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, header) == 0, + OffsetOf_CopyTextureCHROMIUM_header_not_0); +COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, target) == 4, + OffsetOf_CopyTextureCHROMIUM_target_not_4); +COMPILE_ASSERT(offsetof(CopyTextureCHROMIUM, source_id) == 8, + OffsetOf_CopyTextureCHROMIUM_source_id_not_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); + struct DrawArraysInstancedANGLE { typedef DrawArraysInstancedANGLE ValueType; static const CommandId kCmdId = kDrawArraysInstancedANGLE; diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index fa73330..4a5d29d 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -3701,6 +3701,25 @@ TEST_F(GLES2FormatTest, TexImageIOSurface2DCHROMIUM) { next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, CopyTextureCHROMIUM) { + CopyTextureCHROMIUM& cmd = *GetBufferAs<CopyTextureCHROMIUM>(); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<GLenum>(13), + static_cast<GLint>(14)); + EXPECT_EQ(static_cast<uint32>(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); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, DrawArraysInstancedANGLE) { DrawArraysInstancedANGLE& cmd = *GetBufferAs<DrawArraysInstancedANGLE>(); void* next_cmd = cmd.Set( diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 37859a7..ac95b0c 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -218,9 +218,10 @@ OP(GetTranslatedShaderSourceANGLE) /* 461 */ \ OP(PostSubBufferCHROMIUM) /* 462 */ \ OP(TexImageIOSurface2DCHROMIUM) /* 463 */ \ - OP(DrawArraysInstancedANGLE) /* 464 */ \ - OP(DrawElementsInstancedANGLE) /* 465 */ \ - OP(VertexAttribDivisorANGLE) /* 466 */ \ + OP(CopyTextureCHROMIUM) /* 464 */ \ + OP(DrawArraysInstancedANGLE) /* 465 */ \ + OP(DrawElementsInstancedANGLE) /* 466 */ \ + OP(VertexAttribDivisorANGLE) /* 467 */ \ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index 2d725d0..d99da6d 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h @@ -289,9 +289,11 @@ static GLES2Util::EnumToString enum_to_string_table[] = { { 0x8DF2, "GL_HIGH_FLOAT", }, { 0x8826, "GL_DRAW_BUFFER1_NV", }, { 0x8827, "GL_DRAW_BUFFER2_NV", }, + { 0x9243, "GL_UNPACK_COLORSPACE_CONVERSION_CHROMIUM", }, { 0x8DF3, "GL_LOW_INT", }, { 0x8B53, "GL_INT_VEC2", }, { 0x0C02, "GL_READ_BUFFER_NV", }, + { 0x9241, "GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM", }, { 0x8B52, "GL_FLOAT_VEC4", }, { 0x9240, "GL_UNPACK_FLIP_Y_CHROMIUM", }, { 0x8B51, "GL_FLOAT_VEC3", }, @@ -887,6 +889,9 @@ std::string GLES2Util::GetStringPixelStore(uint32 value) { static EnumToString string_table[] = { { GL_PACK_ALIGNMENT, "GL_PACK_ALIGNMENT" }, { GL_UNPACK_ALIGNMENT, "GL_UNPACK_ALIGNMENT" }, + { GL_UNPACK_FLIP_Y_CHROMIUM, "GL_UNPACK_FLIP_Y_CHROMIUM" }, + { GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, + "GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM" }, }; return GLES2Util::GetQualifiedEnumString( string_table, arraysize(string_table), value); diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 9e83d97..fff10fc 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -120,6 +120,7 @@ void FeatureInfo::AddFeatures(const char* desired_features) { AddExtensionString("GL_CHROMIUM_gpu_memory_manager"); AddExtensionString("GL_CHROMIUM_discard_framebuffer"); AddExtensionString("GL_CHROMIUM_command_buffer_query"); + AddExtensionString("GL_CHROMIUM_copy_texture"); AddExtensionString("GL_ANGLE_translated_shader_source"); if (ext.Have("GL_ANGLE_translated_shader_source")) { diff --git a/gpu/command_buffer/service/gl_utils.h b/gpu/command_buffer/service/gl_utils.h index 64495b3..d0d8411 100644 --- a/gpu/command_buffer/service/gl_utils.h +++ b/gpu/command_buffer/service/gl_utils.h @@ -42,6 +42,12 @@ // GL_ANGLE_translated_shader_source #define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 +// GL_CHROMIUM_flipy +#define GL_UNPACK_FLIP_Y_CHROMIUM 0x9240 + +#define GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM 0x9241 +#define GL_UNPACK_COLORSPACE_CONVERSION_CHROMIUM 0x9243 + // GL_ANGLE_pack_reverse_row_order #define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc new file mode 100644 index 0000000..adf9b51 --- /dev/null +++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc @@ -0,0 +1,250 @@ +// 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. + +#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" + +#include "base/basictypes.h" +#include "gpu/command_buffer/common/types.h" +#include "gpu/command_buffer/service/gl_utils.h" + +#define SHADER0(Src) #Src +#define SHADER(Src) SHADER0(Src) + +namespace { + +const GLfloat kQuadVertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 1.0f, + -1.0f, 1.0f, 0.0f, 1.0f }; + +const GLfloat kTextureCoords[] = { 0.0f, 0.0f, + 1.0f, 0.0f, + 1.0f, 1.0f, + 0.0f, 1.0f }; + +const int kNumShaders = 5; +enum ShaderId { + VERTEX_SHADER_POS_TEX, + FRAGMENT_SHADER_TEX, + FRAGMENT_SHADER_TEX_FLIP_Y, + FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA, + FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y +}; + +enum ProgramId { + PROGRAM_COPY_TEXTURE, + PROGRAM_COPY_TEXTURE_FLIP_Y, + PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA, + PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY +}; + +// Returns the correct program to evaluate the copy operation for +// the CHROMIUM_flipy and premultiply alpha pixel store settings. +ProgramId GetProgram(bool flip_y, bool premultiply_alpha) { + if (flip_y && premultiply_alpha) + return PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY; + + if (flip_y) + return PROGRAM_COPY_TEXTURE_FLIP_Y; + + if (premultiply_alpha) + return PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA; + + return PROGRAM_COPY_TEXTURE; +} + +const char* GetShaderSource(ShaderId shader) { + switch (shader) { + case VERTEX_SHADER_POS_TEX: + return SHADER( + precision mediump float; + attribute vec4 a_position; + attribute vec2 a_texCoord; + varying vec2 v_uv; + void main(void) { + gl_Position = a_position; + v_uv = a_texCoord; + }); + case FRAGMENT_SHADER_TEX: + return SHADER( + precision mediump float; + uniform sampler2D u_texSampler; + varying vec2 v_uv; + void main(void) { + gl_FragColor = texture2D(u_texSampler, v_uv.st); + }); + case FRAGMENT_SHADER_TEX_FLIP_Y: + return SHADER( + precision mediump float; + uniform sampler2D u_texSampler; + varying vec2 v_uv; + void main(void) { + gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); + }); + case FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA: + return SHADER( + precision mediump float; + uniform sampler2D u_texSampler; + varying vec2 v_uv; + void main(void) { + gl_FragColor = texture2D(u_texSampler, v_uv.st); + gl_FragColor.rgb *= gl_FragColor.a; + }); + case FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y: + return SHADER( + precision mediump float; + uniform sampler2D u_texSampler; + varying vec2 v_uv; + void main(void) { + gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); + gl_FragColor.rgb *= gl_FragColor.a; + }); + default: + return 0; + } +} + +} // namespace + +void CopyTextureCHROMIUMResourceManager::Initialize() { + COMPILE_ASSERT( + kVertexPositionAttrib == 0u || kVertexTextureAttrib == 0u, + CopyTexture_One_of_these_attribs_must_be_0); + + // Initialize all of the GPU resources required to perform the copy. + glGenBuffersARB(2, buffer_ids_); + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, + GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); + glBufferData(GL_ARRAY_BUFFER, sizeof(kTextureCoords), kTextureCoords, + GL_STATIC_DRAW); + + glGenFramebuffersEXT(1, &framebuffer_); + + GLuint shaders[kNumShaders]; + for (int shader = 0; shader < kNumShaders; ++shader) { + shaders[shader] = glCreateShader( + shader == 0 ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); + const char* shader_source = GetShaderSource(static_cast<ShaderId>(shader)); + glShaderSource(shaders[shader], 1, &shader_source, 0); + glCompileShader(shaders[shader]); +#ifndef NDEBUG + GLint compile_status; + glGetShaderiv(shaders[shader], GL_COMPILE_STATUS, &compile_status); + if (GL_TRUE != compile_status) + DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; +#endif + } + + for (int program = 0; program < kNumPrograms; ++program) { + programs_[program] = glCreateProgram(); + glAttachShader(programs_[program], shaders[0]); + glAttachShader(programs_[program], shaders[program + 1]); + + glBindAttribLocation(programs_[program], kVertexPositionAttrib, + "a_position"); + glBindAttribLocation(programs_[program], kVertexTextureAttrib, + "a_texCoord"); + + glLinkProgram(programs_[program]); +#ifndef NDEBUG + GLint linked; + glGetProgramiv(programs_[program], GL_LINK_STATUS, &linked); + if (!linked) + DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; +#endif + + sampler_locations_[program] = glGetUniformLocation(programs_[program], + "u_texSampler"); + + } + + for (int shader = 0; shader < kNumShaders; ++shader) + glDeleteShader(shaders[shader]); + + initialized_ = true; +} + +void CopyTextureCHROMIUMResourceManager::Destroy() { + if (!initialized_) + return; + + glDeleteFramebuffersEXT(1, &framebuffer_); + + for (int program = 0; program < kNumPrograms; ++program) + glDeleteProgram(programs_[program]); + + glDeleteBuffersARB(2, buffer_ids_); +} + +void CopyTextureCHROMIUMResourceManager::DoCopyTexture( + GLenum target, + GLuint source_id, + GLuint dest_id, + GLint level, + bool flip_y, + bool premultiply_alpha) { + if (!initialized_) { + DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; + return; + } + + GLuint program = GetProgram(flip_y, premultiply_alpha); + glUseProgram(programs_[program]); + +#ifndef NDEBUG + glValidateProgram(programs_[program]); + GLint validation_status; + glGetProgramiv(programs_[program], GL_VALIDATE_STATUS, &validation_status); + if (GL_TRUE != validation_status) { + DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; + return; + } +#endif + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, + dest_id, level); + +#ifndef NDEBUG + GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); + if (GL_FRAMEBUFFER_COMPLETE != fb_status) { + DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; + return; + } +#endif + + glEnableVertexAttribArray(kVertexPositionAttrib); + glEnableVertexAttribArray(kVertexTextureAttrib); + + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); + glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE, + 4 * sizeof(GLfloat), 0); + + glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); + glVertexAttribPointer(kVertexTextureAttrib, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(GLfloat), 0); + + glActiveTexture(GL_TEXTURE0); + glUniform1i(sampler_locations_[program], 0); + + glBindTexture(GL_TEXTURE_2D, source_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); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthMask(GL_FALSE); + glDisable(GL_BLEND); + + 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 new file mode 100644 index 0000000..d207fca --- /dev/null +++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h @@ -0,0 +1,41 @@ +// 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 GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_COPY_TEXTURE_CHROMIUM_H_ +#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_COPY_TEXTURE_CHROMIUM_H_ + +#include "gpu/command_buffer/service/gl_utils.h" + +// This class encapsulates the resources required to implement the +// GL_CHROMIUM_copy_texture extension. The copy operation is performed +// via a blit to a framebuffer object. +class CopyTextureCHROMIUMResourceManager { + public: + CopyTextureCHROMIUMResourceManager() : initialized_(false) {} + + void Initialize(); + void Destroy(); + + void DoCopyTexture(GLenum target, GLuint source_id, GLuint dest_id, + GLint level, bool flip_y, bool premultiply_alpha); + + // The attributes used during invocation of the extension. + static const GLuint kVertexPositionAttrib = 0; + static const GLuint kVertexTextureAttrib = 1; + + private: + bool initialized_; + + static const int kNumPrograms = 4; + GLuint programs_[kNumPrograms]; + GLuint buffer_ids_[2]; + GLuint framebuffer_; + GLuint sampler_locations_[kNumPrograms]; + + DISALLOW_COPY_AND_ASSIGN(CopyTextureCHROMIUMResourceManager); +}; + +#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_COPY_TEXTURE_CHROMIUM_H_ + + diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index d4fd8af..79f2c04 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -33,6 +33,7 @@ #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/framebuffer_manager.h" #include "gpu/command_buffer/service/gl_utils.h" +#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" #include "gpu/command_buffer/service/gles2_cmd_validation.h" #include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/program_manager.h" @@ -726,6 +727,12 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, GLuint io_surface_id, GLuint plane); + void DoCopyTextureCHROMIUM( + GLenum target, + GLuint source_id, + GLuint target_id, + GLint level); + // Wrapper for TexStorage2DEXT. void DoTexStorage2DEXT( GLenum target, @@ -1132,6 +1139,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, void DoVertexAttrib3fv(GLuint index, const GLfloat *v); void DoVertexAttrib4fv(GLuint index, const GLfloat *v); + // Wrapper for glViewport + void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height); + // Wrapper for glUseProgram void DoUseProgram(GLuint program); @@ -1166,7 +1176,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // simulated. bool SimulateAttrib0( GLuint max_vertex_accessed, bool* simulated); - void RestoreStateForSimulatedAttrib0(); + void RestoreStateForAttrib(GLuint attrib); // Returns true if textures were set. bool SetBlackTextureForNonRenderableTextures(); @@ -1332,6 +1342,12 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // unpack alignment as last set by glPixelStorei GLint unpack_alignment_; + // unpack flip y as last set by glPixelStorei + bool unpack_flip_y_; + + // unpack premultiply alpha as last set by glPixelStorei + bool unpack_premultiply_alpha_; + // The currently bound array buffer. If this is 0 it is illegal to call // glVertexAttribPointer. BufferManager::BufferInfo::Ref bound_array_buffer_; @@ -1384,6 +1400,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, GLuint mask_stencil_back_; GLclampf clear_depth_; GLboolean mask_depth_; + bool enable_cull_face_; bool enable_scissor_test_; bool enable_depth_test_; bool enable_stencil_test_; @@ -1487,6 +1504,13 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, typedef std::vector<GLES2DecoderImpl*> ChildList; ChildList children_; + scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_; + + // Cached values of the currently assigned viewport dimensions. + GLint viewport_x_, viewport_y_; + GLsizei viewport_width_, viewport_height_; + GLsizei viewport_max_width_, viewport_max_height_; + DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); }; @@ -1830,6 +1854,8 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) error_bits_(0), pack_alignment_(4), unpack_alignment_(4), + unpack_flip_y_(false), + unpack_premultiply_alpha_(false), attrib_0_buffer_id_(0), attrib_0_buffer_matches_value_(true), attrib_0_size_(0), @@ -1849,6 +1875,7 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) mask_stencil_back_(-1), clear_depth_(1.0f), mask_depth_(true), + enable_cull_face_(false), enable_scissor_test_(false), enable_depth_test_(false), enable_stencil_test_(false), @@ -1877,7 +1904,13 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) needs_glsl_built_in_function_emulation_(false), force_webgl_glsl_validation_(false), derivatives_explicitly_enabled_(false), - compile_shader_always_succeeds_(false) { + compile_shader_always_succeeds_(false), + viewport_x_(0), + viewport_y_(0), + viewport_width_(0), + viewport_height_(0), + viewport_max_width_(0), + viewport_max_height_(0) { DCHECK(group); attrib_0_value_.v[0] = 0.0f; @@ -1959,8 +1992,12 @@ bool GLES2DecoderImpl::Initialize( Destroy(); return false; } + CHECK_GL_ERROR(); + copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); + copy_texture_CHROMIUM_->Initialize(); CHECK_GL_ERROR(); + disallowed_features_ = disallowed_features; vertex_attrib_manager_.reset(new VertexAttribManager()); @@ -2180,6 +2217,17 @@ bool GLES2DecoderImpl::Initialize( return false; } + GLint viewport_params[4]; + glGetIntegerv(GL_VIEWPORT, viewport_params); + viewport_x_ = viewport_params[0]; + viewport_y_ = viewport_params[1]; + viewport_width_ = viewport_params[2]; + viewport_height_ = viewport_params[3]; + + glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params); + viewport_max_width_ = viewport_params[0]; + viewport_max_height_ = viewport_params[0]; + return true; } @@ -2686,6 +2734,8 @@ void GLES2DecoderImpl::Destroy() { bound_renderbuffer_ = NULL; if (have_context) { + copy_texture_CHROMIUM_->Destroy(); + if (current_program_) { program_manager()->UnuseProgram(shader_manager(), current_program_); current_program_ = NULL; @@ -2736,6 +2786,7 @@ void GLES2DecoderImpl::Destroy() { if (offscreen_resolved_color_texture_.get()) offscreen_resolved_color_texture_->Invalidate(); } + copy_texture_CHROMIUM_.reset(); if (query_manager_.get()) { query_manager_->Destroy(have_context); @@ -3206,6 +3257,8 @@ void GLES2DecoderImpl::ApplyDirtyState() { glStencilMaskSeparate(GL_FRONT, have_stencil ? mask_stencil_front_ : 0); glStencilMaskSeparate(GL_BACK, have_stencil ? mask_stencil_back_ : 0); EnableDisable(GL_STENCIL_TEST, enable_stencil_test_ && have_stencil); + EnableDisable(GL_CULL_FACE, enable_cull_face_); + EnableDisable(GL_SCISSOR_TEST, enable_scissor_test_); state_dirty_ = false; } } @@ -4016,6 +4069,9 @@ void GLES2DecoderImpl::DoFramebufferRenderbuffer( bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) { switch (cap) { + case GL_CULL_FACE: + enable_cull_face_ = enabled; + return true; case GL_SCISSOR_TEST: enable_scissor_test_ = enabled; return true; @@ -5004,19 +5060,25 @@ bool GLES2DecoderImpl::SimulateAttrib0( return true; } -void GLES2DecoderImpl::RestoreStateForSimulatedAttrib0() { +void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib) { const VertexAttribManager::VertexAttribInfo* info = - vertex_attrib_manager_->GetVertexAttribInfo(0); + vertex_attrib_manager_->GetVertexAttribInfo(attrib); const void* ptr = reinterpret_cast<const void*>(info->offset()); BufferManager::BufferInfo* buffer_info = info->buffer(); glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0); glVertexAttribPointer( - 0, info->size(), info->type(), info->normalized(), info->gl_stride(), + attrib, info->size(), info->type(), info->normalized(), info->gl_stride(), ptr); if (info->divisor()) - glVertexAttribDivisorANGLE(0, info->divisor()); + glVertexAttribDivisorANGLE(attrib, info->divisor()); glBindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_ ? bound_array_buffer_->service_id() : 0); + + if (info->enabled()) { + glEnableVertexAttribArray(attrib); + } else { + glDisableVertexAttribArray(attrib); + } } bool GLES2DecoderImpl::SimulateFixedAttribs( @@ -5189,7 +5251,7 @@ error::Error GLES2DecoderImpl::DoDrawArrays(bool instanced, } } if (simulated_attrib_0) { - RestoreStateForSimulatedAttrib0(); + RestoreStateForAttrib(0); } if (WasContextLost()) { LOG(ERROR) << " GLES2DecoderImpl: Context lost during DrawArrays."; @@ -5300,7 +5362,7 @@ error::Error GLES2DecoderImpl::DoDrawElements(bool instanced, } } if (simulated_attrib_0) { - RestoreStateForSimulatedAttrib0(); + RestoreStateForAttrib(0); } if (WasContextLost()) { LOG(ERROR) << " GLES2DecoderImpl: Context lost during DrawElements."; @@ -5940,6 +6002,15 @@ error::Error GLES2DecoderImpl::HandleVertexAttribPointer( return error::kNoError; } +void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width, + GLsizei height) { + viewport_x_ = x; + viewport_y_ = y; + viewport_width_ = std::min(width, viewport_max_width_); + viewport_height_ = std::min(height, viewport_max_height_); + glViewport(x, y, width, height); +} + error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE( uint32 immediate_data_size, const gles2::VertexAttribDivisorANGLE& c) { if (!feature_info_->feature_flags().angle_instanced_arrays) { @@ -6138,6 +6209,12 @@ 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(); @@ -8252,6 +8329,89 @@ static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) { } } +void GLES2DecoderImpl::DoCopyTextureCHROMIUM( + GLenum target, GLuint source_id, GLuint dest_id, GLint level) { + TextureManager::TextureInfo* dest_info = GetTextureInfo(dest_id); + TextureManager::TextureInfo* source_info = GetTextureInfo(source_id); + + if (!source_info || !dest_info) { + SetGLError(GL_INVALID_VALUE, "glCopyTextureCHROMIUM: unknown texture id"); + return; + } + + if (GL_TEXTURE_2D != target) { + SetGLError(GL_INVALID_VALUE, + "glCopyTextureCHROMIUM: invalid texture target"); + return; + } + + 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: source texture has no level 0"); + return; + } + + if (!dest_info->GetLevelSize(GL_TEXTURE_2D, level, &dest_width, + &dest_height)) { + SetGLError(GL_INVALID_VALUE, + "glCopyTextureChromium: destination texture level does not exist"); + return; + } + + // Check that this type of texture is allowed. + if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width, + source_height, 1)) { + SetGLError(GL_INVALID_VALUE, + "glCopyTextureCHROMIUM: Bad dimensions"); + 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); + + // Ensure that the glTexImage2D succeeds. + CopyRealGLErrorsToWrapper(); + WrappedTexImage2D( + GL_TEXTURE_2D, level, internal_format, source_width, source_height, + 0, internal_format, type, NULL); + GLenum error = PeekGLError(); + if (error != GL_NO_ERROR) + return; + + texture_manager()->SetLevelInfo( + dest_info, GL_TEXTURE_2D, level, internal_format, source_width, + source_height, 1, 0, internal_format, type, true); + } + + state_dirty_ = true; + glViewport(0, 0, dest_width, dest_height); + copy_texture_CHROMIUM_->DoCopyTexture(target, source_info->service_id(), + dest_info->service_id(), level, + unpack_flip_y_, + unpack_premultiply_alpha_); + glViewport(viewport_x_, viewport_y_, viewport_width_, viewport_height_); + + // Restore all of the state touched by the extension. + if (current_program_) + glUseProgram(current_program_->service_id()); + else + glUseProgram(0); + + RestoreCurrentFramebufferBindings(); + RestoreCurrentTexture2DBindings(); + RestoreStateForAttrib( + CopyTextureCHROMIUMResourceManager::kVertexPositionAttrib); + RestoreStateForAttrib( + CopyTextureCHROMIUMResourceManager::kVertexTextureAttrib); + + ApplyDirtyState(); +} + static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { switch (internalformat) { case GL_RGB565: diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index d0815dd..01fc027 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -2509,7 +2509,7 @@ error::Error GLES2DecoderImpl::HandleViewport( SetGLError(GL_INVALID_VALUE, "glViewport: height < 0"); return error::kNoError; } - glViewport(x, y, width, height); + DoViewport(x, y, width, height); return error::kNoError; } @@ -2726,5 +2726,15 @@ error::Error GLES2DecoderImpl::HandleTexImageIOSurface2DCHROMIUM( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleCopyTextureCHROMIUM( + uint32 immediate_data_size, const gles2::CopyTextureCHROMIUM& 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 level = static_cast<GLint>(c.level); + DoCopyTextureCHROMIUM(target, source_id, dest_id, level); + return error::kNoError; +} + #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 053fcde..9f08a9e 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -3525,7 +3525,9 @@ TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMask) { false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -3579,7 +3581,9 @@ TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferDepthMask) { false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -3631,7 +3635,10 @@ TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferStencilMask) { false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled + EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) .RetiresOnSaturation(); @@ -3683,7 +3690,9 @@ TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMaskFBO) { false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -3729,7 +3738,10 @@ TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMaskFBO) { false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled + EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) .RetiresOnSaturation(); @@ -3755,7 +3767,9 @@ TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMaskFBO) { false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -3978,7 +3992,10 @@ TEST_F(GLES2DecoderManualInitTest, DepthEnableWithDepth) { true, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled + EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) .RetiresOnSaturation(); @@ -4035,7 +4052,10 @@ TEST_F(GLES2DecoderManualInitTest, DepthEnableWithoutRequestedDepth) { false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled + EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) .RetiresOnSaturation(); @@ -4092,7 +4112,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 + EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) .RetiresOnSaturation(); @@ -4149,7 +4172,10 @@ TEST_F(GLES2DecoderManualInitTest, StencilEnableWithoutRequestedStencil) { false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled + EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) .RetiresOnSaturation(); @@ -5901,7 +5927,10 @@ TEST_F(GLES2DecoderWithShaderTest, DrawClearsAfterTexImage2DNULLInFBO) { false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled + EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) .RetiresOnSaturation(); @@ -6063,7 +6092,10 @@ TEST_F(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnClear) { false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled + EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT)) .Times(1) .RetiresOnSaturation(); @@ -6216,7 +6248,10 @@ TEST_F(GLES2DecoderWithShaderTest, DrawClearsAfterRenderbufferStorageInFBO) { false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled + EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) .RetiresOnSaturation(); @@ -6328,7 +6363,10 @@ TEST_F(GLES2DecoderWithShaderTest, false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled + EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) .RetiresOnSaturation(); @@ -6545,7 +6583,10 @@ TEST_F(GLES2DecoderWithShaderTest, false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled + EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) .RetiresOnSaturation(); 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 56f5195..8e2df7a 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 @@ -30,6 +30,7 @@ // TODO(gman): GetTranslatedShaderSourceANGLE // TODO(gman): PostSubBufferCHROMIUM // TODO(gman): TexImageIOSurface2DCHROMIUM +// TODO(gman): CopyTextureCHROMIUM // TODO(gman): DrawArraysInstancedANGLE // TODO(gman): DrawElementsInstancedANGLE // TODO(gman): VertexAttribDivisorANGLE 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 5754406..94858ef 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -26,6 +26,7 @@ using ::testing::MatcherCast; using ::testing::Pointee; using ::testing::Return; using ::testing::SetArrayArgument; +using ::testing::SetArgPointee; using ::testing::SetArgumentPointee; using ::testing::StrEq; using ::testing::StrictMock; @@ -63,6 +64,125 @@ void GLES2DecoderTestBase::SetUp() { true); // bind generates resource } +// Setup the expectations required for the inialiazation of the resources +// used by the GL_CHROMIUM_copy_texture extension. +void GLES2DecoderTestBase::AddExpectationsForCopyTextureCHROMIUM() { + static GLuint copy_texture_chromium_buffer_ids[] = { + kServiceCopyTextureChromiumVertexBufferId, + kServiceCopyTextureChromiumTextureBufferId + }; + EXPECT_CALL(*gl_, GenBuffersARB(arraysize(copy_texture_chromium_buffer_ids), + _)) + .WillOnce(SetArrayArgument<1>(copy_texture_chromium_buffer_ids, + copy_texture_chromium_buffer_ids + arraysize( + copy_texture_chromium_buffer_ids))) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, + kServiceCopyTextureChromiumVertexBufferId)) + .Times(1) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLfloat), _, + GL_STATIC_DRAW)) + .Times(1) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, + kServiceCopyTextureChromiumTextureBufferId)) + .Times(1) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), _, + GL_STATIC_DRAW)) + .Times(1) + .RetiresOnSaturation(); + + static GLuint copy_texture_chromium_fbo_ids[] = { + kServiceCopyTextureChromiumFBOId + }; + EXPECT_CALL(*gl_, GenFramebuffersEXT(arraysize(copy_texture_chromium_fbo_ids), + _)) + .WillOnce(SetArrayArgument<1>(copy_texture_chromium_fbo_ids, + copy_texture_chromium_fbo_ids + arraysize( + copy_texture_chromium_fbo_ids))) + .RetiresOnSaturation(); + + for (int shader = 0; shader < 5; ++shader) { + EXPECT_CALL(*gl_, CreateShader( + shader == 0 ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER)) + .WillOnce(Return(kServiceCopyTextureChromiumShaderId + shader)) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, ShaderSource(kServiceCopyTextureChromiumShaderId + shader, + 1, _, 0)) + .Times(1) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, CompileShader( + kServiceCopyTextureChromiumShaderId + shader)) + .Times(1) + .RetiresOnSaturation(); +#ifndef NDEBUG + EXPECT_CALL(*gl_, GetShaderiv(kServiceCopyTextureChromiumShaderId + shader, + GL_COMPILE_STATUS, _)) + .WillOnce(SetArgPointee<2>(GL_TRUE)) + .RetiresOnSaturation(); +#endif + } + + for (int program = 0; program < 4; ++program) { + EXPECT_CALL(*gl_, CreateProgram()) + .WillOnce(Return(kServiceCopyTextureChromiumProgramId + program)) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, AttachShader( + kServiceCopyTextureChromiumProgramId + program, + kServiceCopyTextureChromiumShaderId)) + .Times(1) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, AttachShader( + kServiceCopyTextureChromiumProgramId + program, + kServiceCopyTextureChromiumShaderId + program + 1)) + .Times(1) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, BindAttribLocation( + kServiceCopyTextureChromiumProgramId + program, 0, _)) + .Times(1) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, BindAttribLocation( + kServiceCopyTextureChromiumProgramId + program, 1, _)) + .Times(1) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, LinkProgram( + kServiceCopyTextureChromiumProgramId + program)) + .Times(1) + .RetiresOnSaturation(); + +#ifndef NDEBUG + EXPECT_CALL(*gl_, GetProgramiv( + kServiceCopyTextureChromiumProgramId + program, GL_LINK_STATUS, _)) + .WillOnce(SetArgPointee<2>(true)) + .RetiresOnSaturation(); +#endif + + EXPECT_CALL(*gl_, GetUniformLocation( + kServiceCopyTextureChromiumProgramId + program, _)) + .WillOnce(Return(kServiceCopyTextureChromiumSamplerLocation)) + .RetiresOnSaturation(); + } + + for (int shader = 0; shader < 5; ++shader) + EXPECT_CALL(*gl_, + DeleteShader(kServiceCopyTextureChromiumShaderId + shader)) + .Times(1) + .RetiresOnSaturation(); +} + void GLES2DecoderTestBase::InitDecoder( const char* extensions, bool has_alpha, @@ -83,6 +203,8 @@ void GLES2DecoderTestBase::InitDecoder( EXPECT_TRUE(group_->Initialize(DisallowedFeatures(), NULL)); + AddExpectationsForCopyTextureCHROMIUM(); + EXPECT_CALL(*gl_, EnableVertexAttribArray(0)) .Times(1) .RetiresOnSaturation(); @@ -171,6 +293,26 @@ void GLES2DecoderTestBase::InitDecoder( .RetiresOnSaturation(); #endif + static GLint viewport_dims[] = { + kViewportX, + kViewportY, + kViewportWidth, + kViewportHeight, + }; + EXPECT_CALL(*gl_, GetIntegerv(GL_VIEWPORT, _)) + .WillOnce(SetArrayArgument<1>(viewport_dims, + viewport_dims + arraysize(viewport_dims))) + .RetiresOnSaturation(); + + static GLint max_viewport_dims[] = { + kMaxViewportWidth, + kMaxViewportHeight + }; + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VIEWPORT_DIMS, _)) + .WillOnce(SetArrayArgument<1>( + max_viewport_dims, max_viewport_dims + arraysize(max_viewport_dims))) + .RetiresOnSaturation(); + engine_.reset(new StrictMock<MockCommandBufferEngine>()); Buffer buffer = engine_->GetSharedMemoryBuffer(kSharedMemoryId); shared_memory_offset_ = kSharedMemoryOffset; @@ -231,11 +373,27 @@ void GLES2DecoderTestBase::InitDecoder( } void GLES2DecoderTestBase::TearDown() { + InSequence sequence; + // All Tests should have read all their GLErrors before getting here. EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, + Pointee(kServiceCopyTextureChromiumFBOId))) + .Times(1) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, DeleteProgram(_)) + .Times(4) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, DeleteBuffersARB(2, _)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, DeleteBuffersARB(1, _)) .Times(2) .RetiresOnSaturation(); + decoder_->Destroy(); decoder_.reset(); group_->Destroy(false); @@ -505,7 +663,9 @@ void GLES2DecoderTestBase::SetupExpectationsForApplyingDirtyState( bool depth_enabled, GLuint front_stencil_mask, GLuint back_stencil_mask, - bool stencil_enabled) { + bool stencil_enabled, + bool cull_face_enabled, + bool scissor_test_enabled) { EXPECT_CALL(*gl_, ColorMask( (color_bits & 0x1000) != 0, (color_bits & 0x0100) != 0, @@ -540,6 +700,24 @@ void GLES2DecoderTestBase::SetupExpectationsForApplyingDirtyState( .Times(1) .RetiresOnSaturation(); } + if (cull_face_enabled) { + EXPECT_CALL(*gl_, Enable(GL_CULL_FACE)) + .Times(1) + .RetiresOnSaturation(); + } else { + EXPECT_CALL(*gl_, Disable(GL_CULL_FACE)) + .Times(1) + .RetiresOnSaturation(); + } + if (scissor_test_enabled) { + EXPECT_CALL(*gl_, Enable(GL_SCISSOR_TEST)) + .Times(1) + .RetiresOnSaturation(); + } else { + EXPECT_CALL(*gl_, Disable(GL_SCISSOR_TEST)) + .Times(1) + .RetiresOnSaturation(); + } } void GLES2DecoderTestBase::SetupExpectationsForApplyingDefaultDirtyState() { @@ -552,7 +730,9 @@ void GLES2DecoderTestBase::SetupExpectationsForApplyingDefaultDirtyState() { false, // depth enabled 0, // front stencil mask 0, // back stencil mask - false); // stencil enabled + false, // stencil enabled + false, // cull_face_enabled + false); // scissor_test_enabled } void GLES2DecoderTestBase::DoBindFramebuffer( @@ -776,6 +956,9 @@ void GLES2DecoderTestBase::DoVertexAttribDivisorANGLE( // GCC requires these declarations, but MSVC requires they not be present #ifndef COMPILER_MSVC +const int GLES2DecoderTestBase::kBackBufferWidth; +const int GLES2DecoderTestBase::kBackBufferHeight; + const GLint GLES2DecoderTestBase::kMaxTextureSize; const GLint GLES2DecoderTestBase::kMaxCubeMapTextureSize; const GLint GLES2DecoderTestBase::kNumVertexAttribs; @@ -785,6 +968,13 @@ const GLint GLES2DecoderTestBase::kMaxVertexTextureImageUnits; const GLint GLES2DecoderTestBase::kMaxFragmentUniformVectors; const GLint GLES2DecoderTestBase::kMaxVaryingVectors; const GLint GLES2DecoderTestBase::kMaxVertexUniformVectors; +const GLint GLES2DecoderTestBase::kMaxViewportWidth; +const GLint GLES2DecoderTestBase::kMaxViewportHeight; + +const GLint GLES2DecoderTestBase::kViewportX; +const GLint GLES2DecoderTestBase::kViewportY; +const GLint GLES2DecoderTestBase::kViewportWidth; +const GLint GLES2DecoderTestBase::kViewportHeight; const GLuint GLES2DecoderTestBase::kServiceAttrib0BufferId; const GLuint GLES2DecoderTestBase::kServiceFixedAttribBufferId; @@ -810,12 +1000,19 @@ const uint32 GLES2DecoderTestBase::kNewClientId; const uint32 GLES2DecoderTestBase::kNewServiceId; const uint32 GLES2DecoderTestBase::kInvalidClientId; -const int GLES2DecoderTestBase::kBackBufferWidth; -const int GLES2DecoderTestBase::kBackBufferHeight; - const GLuint GLES2DecoderTestBase::kServiceVertexShaderId; const GLuint GLES2DecoderTestBase::kServiceFragmentShaderId; +const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumShaderId; +const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumProgramId; + +const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumTextureBufferId; +const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumVertexBufferId; +const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumFBOId; +const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumPositionAttrib; +const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumTexAttrib; +const GLuint GLES2DecoderTestBase::kServiceCopyTextureChromiumSamplerLocation; + const GLsizei GLES2DecoderTestBase::kNumVertices; const GLsizei GLES2DecoderTestBase::kNumIndices; const int GLES2DecoderTestBase::kValidIndexRangeStart; @@ -1174,6 +1371,10 @@ void GLES2DecoderTestBase::AddExpectationsForSimulatedAttrib0WithError( EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, buffer_id)) .Times(1) .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, DisableVertexAttribArray(0)) + .Times(1) + .RetiresOnSaturation(); } } 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 c73fb0a..85bfe1d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -300,7 +300,9 @@ class GLES2DecoderTestBase : public testing::Test { bool depth_enabled, GLuint front_stencil_mask, GLuint back_stencil_mask, - bool stencil_enabled); + bool stencil_enabled, + bool cull_face_enabled, + bool scissor_test_enabled); void SetupExpectationsForApplyingDefaultDirtyState(); @@ -326,6 +328,9 @@ class GLES2DecoderTestBase : public testing::Test { } protected: + static const int kBackBufferWidth = 128; + static const int kBackBufferHeight = 64; + static const GLint kMaxTextureSize = 2048; static const GLint kMaxCubeMapTextureSize = 256; static const GLint kNumVertexAttribs = 16; @@ -335,6 +340,13 @@ class GLES2DecoderTestBase : public testing::Test { static const GLint kMaxFragmentUniformVectors = 16; static const GLint kMaxVaryingVectors = 8; static const GLint kMaxVertexUniformVectors = 128; + static const GLint kMaxViewportWidth = 8192; + static const GLint kMaxViewportHeight = 8192; + + static const GLint kViewportX = 0; + static const GLint kViewportY = 0; + static const GLint kViewportWidth = kBackBufferWidth; + static const GLint kViewportHeight = kBackBufferHeight; static const GLuint kServiceAttrib0BufferId = 801; static const GLuint kServiceFixedAttribBufferId = 802; @@ -360,12 +372,19 @@ class GLES2DecoderTestBase : public testing::Test { static const uint32 kNewServiceId = 502; static const uint32 kInvalidClientId = 601; - static const int kBackBufferWidth = 128; - static const int kBackBufferHeight = 64; - static const GLuint kServiceVertexShaderId = 321; static const GLuint kServiceFragmentShaderId = 322; + static const GLuint kServiceCopyTextureChromiumShaderId = 701; + static const GLuint kServiceCopyTextureChromiumProgramId = 721; + + static const GLuint kServiceCopyTextureChromiumTextureBufferId = 751; + static const GLuint kServiceCopyTextureChromiumVertexBufferId = 752; + static const GLuint kServiceCopyTextureChromiumFBOId = 753; + static const GLuint kServiceCopyTextureChromiumPositionAttrib = 761; + static const GLuint kServiceCopyTextureChromiumTexAttrib = 762; + static const GLuint kServiceCopyTextureChromiumSamplerLocation = 763; + static const GLsizei kNumVertices = 100; static const GLsizei kNumIndices = 10; static const int kValidIndexRangeStart = 1; @@ -485,6 +504,8 @@ class GLES2DecoderTestBase : public testing::Test { Buffer invalid_buffer_; }; + void AddExpectationsForCopyTextureCHROMIUM(); + scoped_ptr< ::testing::StrictMock<MockCommandBufferEngine> > engine_; ContextGroup::Ref group_; }; diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index 2d00da9..44cee12 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -239,6 +239,8 @@ static GLenum valid_index_type_table[] = { static GLenum valid_pixel_store_table[] = { GL_PACK_ALIGNMENT, GL_UNPACK_ALIGNMENT, + GL_UNPACK_FLIP_Y_CHROMIUM, + GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, }; static GLint valid_pixel_store_alignment_table[] = { diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi index ae3d569..a1988ad 100644 --- a/gpu/command_buffer_service.gypi +++ b/gpu/command_buffer_service.gypi @@ -36,6 +36,8 @@ 'command_buffer/service/context_group.cc', 'command_buffer/service/feature_info.h', 'command_buffer/service/feature_info.cc', + 'command_buffer/service/gles2_cmd_copy_texture_chromium.cc', + 'command_buffer/service/gles2_cmd_copy_texture_chromium.h', 'command_buffer/service/gles2_cmd_decoder.h', 'command_buffer/service/gles2_cmd_decoder_autogen.h', 'command_buffer/service/gles2_cmd_decoder.cc', |