summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authortwiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-19 03:20:27 +0000
committertwiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-19 03:20:27 +0000
commitb64c2495b3b3ac66edcb31667e17942dd7888b1a (patch)
tree1c18d654caa67a8d99cbd81a16679c2ee36f9ba9 /gpu
parent7e1942af8a3fd104735e9c3b7b8800772b8c13b6 (diff)
downloadchromium_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')
-rw-r--r--gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt66
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py11
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h5
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h8
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc2
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h7
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest.cc18
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest_autogen.h11
-rw-r--r--gpu/command_buffer/cmd_buffer_functions.txt1
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_autogen.h48
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_test_autogen.h19
-rw-r--r--gpu/command_buffer/common/gles2_cmd_ids_autogen.h7
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h5
-rw-r--r--gpu/command_buffer/service/feature_info.cc1
-rw-r--r--gpu/command_buffer/service/gl_utils.h6
-rw-r--r--gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc250
-rw-r--r--gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h41
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc176
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h12
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc71
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc211
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h29
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h2
-rw-r--r--gpu/command_buffer_service.gypi2
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',