summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authordongseong.hwang@intel.com <dongseong.hwang@intel.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-22 22:20:44 +0000
committerdongseong.hwang@intel.com <dongseong.hwang@intel.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-22 22:27:16 +0000
commita6e3d28b21d70ba984bc810f0705b3339805c61a (patch)
tree3fc31e7a0db6b976f55ec144e3ad843853d4d1c2 /gpu
parentcb81131b553176b309d89610f06d2b0534964d3b (diff)
downloadchromium_src-a6e3d28b21d70ba984bc810f0705b3339805c61a.zip
chromium_src-a6e3d28b21d70ba984bc810f0705b3339805c61a.tar.gz
chromium_src-a6e3d28b21d70ba984bc810f0705b3339805c61a.tar.bz2
gpu: glCopyTextureCHROMIUM() checks dest internal format incorrectly.
|internal_format| which a client passes as argument and dest internal format which is the format of current destination texture can be different. If different, glCopyTextureCHROMIUM redefines the destination texture. So we should check dest internal format using |internal_format| argument. In addition, some platforms reports error when |internal_format| is GL_ALPHA, GL_LUMINANCE or GL_LUMINANCE_ALPHA, because those formats can not attached as color attachment of FBO on some platforms. So we restrict |internal_format| to GL_RGB and GL_RGBA. TEST=GLCopyTextureCHROMIUMTest.InternalFormat, GLCopyTextureCHROMIUMTest.RedefineDestinationTexture Review URL: https://codereview.chromium.org/481913005 Cr-Commit-Position: refs/heads/master@{#291528} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@291528 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt12
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc42
-rw-r--r--gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc112
3 files changed, 146 insertions, 20 deletions
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt
index fdaa7d6..ad9ca68 100644
--- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_copy_texture.txt
@@ -48,7 +48,10 @@ New Procedures and Functions
The internal format of the destination texture is converted to that
specified by <internal_format>. Must be one of the following symbolic
- constants: GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA
+ constants: GL_RGB, GL_RGBA
+ The internal format of <source_id> texture must be one of the following
+ symbolic constants: GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB,
+ GL_RGBA, GL_BGRA_EXT
When <source_id> texture doens't contain a superset of the component
required by <internal_format>, fill the components by following rules.
@@ -59,12 +62,19 @@ New Procedures and Functions
GL_LUMINANCE_ALPHA (L, L, L, A)
GL_RGB (R, G, B, 1)
GL_RGBA (R, G, B, A)
+ GL_BGRA_EXT (R, G, B, A)
The format type of the destination texture is converted to that specified
by <dest_type>.
<target> uses the same parameters as TexImage2D.
+ INVALID_OPERATION is generated if <internal_format> is not one of the valid formats
+ described above.
+
+ INVALID_OPERATION is generated if the internal format of <source_id> is not one of
+ formats from the table above.
+
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
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 5e26477..ac33e69 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -10047,6 +10047,29 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
return;
}
+ GLenum source_type = 0;
+ GLenum source_internal_format = 0;
+ source_texture->GetLevelType(
+ source_texture->target(), 0, &source_type, &source_internal_format);
+
+ // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
+ // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
+ // renderable on some platforms.
+ bool valid_dest_format =
+ internal_format == GL_RGB || internal_format == GL_RGBA;
+ bool valid_source_format = source_internal_format == GL_ALPHA ||
+ source_internal_format == GL_RGB ||
+ source_internal_format == GL_RGBA ||
+ source_internal_format == GL_LUMINANCE ||
+ source_internal_format == GL_LUMINANCE_ALPHA ||
+ source_internal_format == GL_BGRA_EXT;
+ if (!valid_source_format || !valid_dest_format) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
+ "glCopyTextureCHROMIUM",
+ "invalid internal format");
+ return;
+ }
+
// Defer initializing the CopyTextureCHROMIUMResourceManager until it is
// needed because it takes 10s of milliseconds to initialize.
if (!copy_texture_CHROMIUM_.get()) {
@@ -10058,11 +10081,6 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
return;
}
- GLenum source_type = 0;
- GLenum source_internal_format = 0;
- source_texture->GetLevelType(
- source_texture->target(), 0, &source_type, &source_internal_format);
-
GLenum dest_type_previous = dest_type;
GLenum dest_internal_format = internal_format;
bool dest_level_defined = dest_texture->GetLevelSize(
@@ -10073,20 +10091,6 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
&dest_internal_format);
}
- // The destination format should be GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE,
- // or GL_LUMINANCE_ALPHA.
- bool valid_dest_format = dest_internal_format >= GL_ALPHA &&
- dest_internal_format <= GL_LUMINANCE_ALPHA;
- // The source format can be GL_BGRA_EXT.
- bool valid_source_format = (source_internal_format >= GL_ALPHA &&
- source_internal_format <= GL_LUMINANCE_ALPHA) ||
- source_internal_format == GL_BGRA_EXT;
- if (!valid_source_format || !valid_dest_format) {
- LOCAL_SET_GL_ERROR(
- GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid internal format");
- return;
- }
-
// Resize the destination texture to the dimensions of the source texture.
if (!dest_level_defined || dest_width != source_width ||
dest_height != source_height ||
diff --git a/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc b/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc
index b6f82e7..e637f74 100644
--- a/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc
+++ b/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc
@@ -76,6 +76,118 @@ TEST_F(GLCopyTextureCHROMIUMTest, Basic) {
EXPECT_TRUE(GL_NO_ERROR == glGetError());
}
+TEST_F(GLCopyTextureCHROMIUMTest, InternalFormat) {
+ GLint src_formats[] = {GL_ALPHA, GL_RGB, GL_RGBA,
+ GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGRA_EXT};
+ GLint dest_formats[] = {GL_RGB, GL_RGBA};
+
+ for (size_t src_index = 0; src_index < arraysize(src_formats); src_index++) {
+ for (size_t dest_index = 0; dest_index < arraysize(dest_formats);
+ dest_index++) {
+ glBindTexture(GL_TEXTURE_2D, textures_[0]);
+ glTexImage2D(GL_TEXTURE_2D,
+ 0,
+ src_formats[src_index],
+ 1,
+ 1,
+ 0,
+ src_formats[src_index],
+ GL_UNSIGNED_BYTE,
+ NULL);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D,
+ textures_[0],
+ textures_[1],
+ 0,
+ dest_formats[dest_index],
+ GL_UNSIGNED_BYTE);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError()) << "src_index:" << src_index
+ << " dest_index:" << dest_index;
+ }
+ }
+}
+
+TEST_F(GLCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
+ glBindTexture(GL_TEXTURE_2D, textures_[0]);
+ glTexImage2D(
+ GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+
+ // Check unsupported format reports error.
+ GLint unsupported_dest_formats[] = {GL_ALPHA, GL_LUMINANCE,
+ GL_LUMINANCE_ALPHA, GL_BGRA_EXT};
+ for (size_t dest_index = 0; dest_index < arraysize(unsupported_dest_formats);
+ dest_index++) {
+ glCopyTextureCHROMIUM(GL_TEXTURE_2D,
+ textures_[0],
+ textures_[1],
+ 0,
+ unsupported_dest_formats[dest_index],
+ GL_UNSIGNED_BYTE);
+ EXPECT_TRUE(GL_INVALID_OPERATION == glGetError())
+ << "dest_index:" << dest_index;
+ }
+}
+
+// Test to ensure that the destination texture is redefined if the properties
+// are different.
+TEST_F(GLCopyTextureCHROMIUMTest, RedefineDestinationTexture) {
+ uint8 pixels[4 * 4] = {255u, 0u, 0u, 255u, 255u, 0u, 0u, 255u,
+ 255u, 0u, 0u, 255u, 255u, 0u, 0u, 255u};
+
+ glBindTexture(GL_TEXTURE_2D, textures_[0]);
+ glTexImage2D(
+ GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexImage2D(GL_TEXTURE_2D,
+ 0,
+ GL_BGRA_EXT,
+ 1,
+ 1,
+ 0,
+ GL_BGRA_EXT,
+ GL_UNSIGNED_BYTE,
+ pixels);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+
+ // GL_INVALID_OPERATION due to "intrinsic format" != "internal format".
+ glTexSubImage2D(
+ GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ EXPECT_TRUE(GL_INVALID_OPERATION == glGetError());
+ // GL_INVALID_VALUE due to bad dimensions.
+ glTexSubImage2D(
+ GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
+ EXPECT_TRUE(GL_INVALID_VALUE == glGetError());
+
+ // If the dest texture has different properties, glCopyTextureCHROMIUM()
+ // redefines them.
+ glCopyTextureCHROMIUM(
+ GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA, GL_UNSIGNED_BYTE);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+
+ // glTexSubImage2D() succeeds because textures_[1] is redefined into 2x2
+ // dimension and GL_RGBA format.
+ glBindTexture(GL_TEXTURE_2D, textures_[1]);
+ glTexSubImage2D(
+ GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+
+ // Check the FB is still bound.
+ GLint value = 0;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
+ GLuint fb_id = value;
+ EXPECT_EQ(framebuffer_id_, fb_id);
+
+ // Check that FB is complete.
+ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
+ glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ GLTestHelper::CheckPixels(1, 1, 1, 1, 0, &pixels[12]);
+ EXPECT_TRUE(GL_NO_ERROR == glGetError());
+}
+
// Test that the extension respects the flip-y pixel storage setting.
TEST_F(GLCopyTextureCHROMIUMTest, FlipY) {
uint8 pixels[2][2][4];