Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 // This file defines tests that implementations of GLImage should pass in order | 5 // This file defines tests that implementations of GLImage should pass in order | 
| 6 // to be conformant. | 6 // to be conformant. | 
| 7 | 7 | 
| 8 #ifndef UI_GL_TEST_GL_IMAGE_TEST_TEMPLATE_H_ | 8 #ifndef UI_GL_TEST_GL_IMAGE_TEST_TEMPLATE_H_ | 
| 9 #define UI_GL_TEST_GL_IMAGE_TEST_TEMPLATE_H_ | 9 #define UI_GL_TEST_GL_IMAGE_TEST_TEMPLATE_H_ | 
| 10 | 10 | 
| 11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" | 
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" | 
| 13 #include "base/strings/stringize_macros.h" | |
| 14 #include "base/strings/stringprintf.h" | |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" | 
| 16 #include "ui/gfx/buffer_format_util.h" | 14 #include "ui/gfx/buffer_format_util.h" | 
| 17 #include "ui/gfx/buffer_types.h" | 15 #include "ui/gfx/buffer_types.h" | 
| 18 #include "ui/gl/gl_bindings.h" | 16 #include "ui/gl/gl_bindings.h" | 
| 19 #include "ui/gl/gl_context.h" | 17 #include "ui/gl/gl_context.h" | 
| 20 #include "ui/gl/gl_helper.h" | 18 #include "ui/gl/gl_helper.h" | 
| 21 #include "ui/gl/gl_image.h" | 19 #include "ui/gl/gl_image.h" | 
| 22 #include "ui/gl/gl_implementation.h" | 20 #include "ui/gl/gl_implementation.h" | 
| 23 #include "ui/gl/gl_surface.h" | 21 #include "ui/gl/gl_surface.h" | 
| 24 #include "ui/gl/test/gl_image_test_support.h" | 22 #include "ui/gl/test/gl_image_test_support.h" | 
| (...skipping 25 matching lines...) Expand all Loading... | |
| 50 GLImageTestDelegate delegate_; | 48 GLImageTestDelegate delegate_; | 
| 51 }; | 49 }; | 
| 52 | 50 | 
| 53 TYPED_TEST_CASE_P(GLImageTest); | 51 TYPED_TEST_CASE_P(GLImageTest); | 
| 54 | 52 | 
| 55 TYPED_TEST_P(GLImageTest, CreateAndDestroy) { | 53 TYPED_TEST_P(GLImageTest, CreateAndDestroy) { | 
| 56 const gfx::Size small_image_size(4, 4); | 54 const gfx::Size small_image_size(4, 4); | 
| 57 const gfx::Size large_image_size(512, 512); | 55 const gfx::Size large_image_size(512, 512); | 
| 58 const uint8_t image_color[] = {0, 0xff, 0, 0xff}; | 56 const uint8_t image_color[] = {0, 0xff, 0, 0xff}; | 
| 59 | 57 | 
| 60 // Create a small solid color green image of preferred format. This must | 58 for (auto format : gfx::GetBufferFormatsForTesting()) { | 
| 61 // succeed in order for a GLImage to be conformant. | 59 if (!TypeParam::IsSupported(format)) { | 
| 
 
reveman
2015/12/18 21:51:04
can we keep requiring each implementation to decid
 
dshwang
2016/01/11 15:31:10
I agree, but we cannot.
each ozone backend support
 
 | |
| 62 scoped_refptr<gl::GLImage> small_image = | 60 continue; | 
| 63 this->delegate_.CreateSolidColorImage(small_image_size, image_color); | 61 } | 
| 64 ASSERT_TRUE(small_image); | |
| 65 | 62 | 
| 66 // Create a large solid color green image of preferred format. This must | 63 // Create a small solid color green image of preferred format. This must | 
| 67 // succeed in order for a GLImage to be conformant. | 64 // succeed in order for a GLImage to be conformant. | 
| 68 scoped_refptr<gl::GLImage> large_image = | 65 scoped_refptr<gl::GLImage> small_image = | 
| 69 this->delegate_.CreateSolidColorImage(large_image_size, image_color); | 66 this->delegate_.CreateSolidColorImage(small_image_size, format, | 
| 70 ASSERT_TRUE(large_image); | 67 image_color); | 
| 68 ASSERT_TRUE(small_image); | |
| 71 | 69 | 
| 72 // Verify that image size is correct. | 70 // Create a large solid color green image of preferred format. This must | 
| 73 EXPECT_EQ(small_image->GetSize().ToString(), small_image_size.ToString()); | 71 // succeed in order for a GLImage to be conformant. | 
| 74 EXPECT_EQ(large_image->GetSize().ToString(), large_image_size.ToString()); | 72 scoped_refptr<gl::GLImage> large_image = | 
| 73 this->delegate_.CreateSolidColorImage(large_image_size, format, | |
| 74 image_color); | |
| 75 ASSERT_TRUE(large_image); | |
| 75 | 76 | 
| 76 // Verify that destruction of images work correctly both when we have a | 77 // Verify that image size is correct. | 
| 77 // context and when we don't. | 78 EXPECT_EQ(small_image->GetSize().ToString(), small_image_size.ToString()); | 
| 78 small_image->Destroy(true /* have_context */); | 79 EXPECT_EQ(large_image->GetSize().ToString(), large_image_size.ToString()); | 
| 79 large_image->Destroy(false /* have_context */); | 80 | 
| 81 // Verify that destruction of images work correctly both when we have a | |
| 82 // context and when we don't. | |
| 83 small_image->Destroy(true /* have_context */); | |
| 84 large_image->Destroy(false /* have_context */); | |
| 85 } | |
| 80 } | 86 } | 
| 81 | 87 | 
| 82 // The GLImageTest test case verifies the behaviour that is expected from a | 88 // The GLImageTest test case verifies the behaviour that is expected from a | 
| 83 // GLImage in order to be conformant. | 89 // GLImage in order to be conformant. | 
| 84 REGISTER_TYPED_TEST_CASE_P(GLImageTest, CreateAndDestroy); | 90 REGISTER_TYPED_TEST_CASE_P(GLImageTest, CreateAndDestroy); | 
| 85 | 91 | 
| 86 template <typename GLImageTestDelegate> | 92 template <typename GLImageTestDelegate> | 
| 87 class GLImageCopyTest : public GLImageTest<GLImageTestDelegate> {}; | 93 class GLImageCopyTest : public GLImageTest<GLImageTestDelegate> {}; | 
| 88 | 94 | 
| 89 TYPED_TEST_CASE_P(GLImageCopyTest); | 95 TYPED_TEST_CASE_P(GLImageCopyTest); | 
| 90 | 96 | 
| 91 TYPED_TEST_P(GLImageCopyTest, CopyTexImage) { | 97 TYPED_TEST_P(GLImageCopyTest, CopyTexImage) { | 
| 92 const gfx::Size image_size(256, 256); | 98 const gfx::Size image_size(256, 256); | 
| 93 // These values are picked so that RGB -> YUV on the CPU converted | 99 // These values are picked so that RGB -> YUV on the CPU converted | 
| 94 // back to RGB on the GPU produces the original RGB values without | 100 // back to RGB on the GPU produces the original RGB values without | 
| 95 // any error. | 101 // any error. | 
| 96 const uint8_t image_color[] = {0x10, 0x20, 0, 0xff}; | 102 const uint8_t image_color[] = {0x10, 0x20, 0, 0xff}; | 
| 97 const uint8_t texture_color[] = {0, 0, 0xff, 0xff}; | 103 const uint8_t texture_color[] = {0, 0, 0xff, 0xff}; | 
| 98 | 104 | 
| 99 GLuint framebuffer = | 105 GLuint framebuffer = | 
| 100 GLTestHelper::SetupFramebuffer(image_size.width(), image_size.height()); | 106 GLTestHelper::SetupFramebuffer(image_size.width(), image_size.height()); | 
| 101 ASSERT_TRUE(framebuffer); | 107 ASSERT_TRUE(framebuffer); | 
| 102 glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer); | 108 glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer); | 
| 103 glViewport(0, 0, image_size.width(), image_size.height()); | 109 glViewport(0, 0, image_size.width(), image_size.height()); | 
| 104 | 110 | 
| 105 // Create a solid color green image of preferred format. This must succeed | 111 GLuint program = GLImageTestSupport::CreateSingleTextureProgram(); | 
| 106 // in order for a GLImage to be conformant. | 112 GLuint vertex_buffer = gfx::GLHelper::SetupQuadVertexBuffer(); | 
| 107 scoped_refptr<gl::GLImage> image = | |
| 108 this->delegate_.CreateSolidColorImage(image_size, image_color); | |
| 109 ASSERT_TRUE(image); | |
| 110 | 113 | 
| 111 // Create a solid color blue texture of the same size as |image|. | 114 for (auto format : gfx::GetBufferFormatsForTesting()) { | 
| 112 GLuint texture = GLTestHelper::CreateTexture(GL_TEXTURE_2D); | 115 if (!TypeParam::IsSupported(format)) { | 
| 113 scoped_ptr<uint8_t[]> pixels(new uint8_t[BufferSizeForBufferFormat( | 116 continue; | 
| 114 image_size, gfx::BufferFormat::RGBA_8888)]); | 117 } | 
| 115 GLImageTestSupport::SetBufferDataToColor( | |
| 116 image_size.width(), image_size.height(), | |
| 117 static_cast<int>(RowSizeForBufferFormat(image_size.width(), | |
| 118 gfx::BufferFormat::RGBA_8888, 0)), | |
| 119 0, gfx::BufferFormat::RGBA_8888, texture_color, pixels.get()); | |
| 120 // Note: This test assume that |image| can be used with GL_TEXTURE_2D but | |
| 121 // that might not be the case for some GLImage implementations. | |
| 122 glBindTexture(GL_TEXTURE_2D, texture); | |
| 123 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_size.width(), | |
| 124 image_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get()); | |
| 125 | 118 | 
| 126 // Copy |image| to |texture|. | 119 // Create a solid color green image of preferred format. This must succeed | 
| 127 bool rv = image->CopyTexImage(GL_TEXTURE_2D); | 120 // in order for a GLImage to be conformant. | 
| 128 EXPECT_TRUE(rv); | 121 scoped_refptr<gl::GLImage> image = | 
| 122 this->delegate_.CreateSolidColorImage(image_size, format, image_color); | |
| 123 ASSERT_TRUE(image); | |
| 129 | 124 | 
| 130 // clang-format off | 125 // Create a solid color blue texture of the same size as |image|. | 
| 131 const char kVertexShader[] = STRINGIZE( | 126 GLuint texture = GLTestHelper::CreateTexture(GL_TEXTURE_2D); | 
| 132 attribute vec2 a_position; | 127 scoped_ptr<uint8_t[]> pixels(new uint8_t[BufferSizeForBufferFormat( | 
| 133 varying vec2 v_texCoord; | 128 image_size, gfx::BufferFormat::RGBA_8888)]); | 
| 134 void main() { | 129 GLImageTestSupport::SetBufferDataToColor( | 
| 135 gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0); | 130 image_size.width(), image_size.height(), | 
| 136 v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5; | 131 static_cast<int>(RowSizeForBufferFormat( | 
| 137 } | 132 image_size.width(), gfx::BufferFormat::RGBA_8888, 0)), | 
| 138 ); | 133 0, gfx::BufferFormat::RGBA_8888, texture_color, pixels.get()); | 
| 139 const char kFragmentShader[] = STRINGIZE( | 134 // Note: This test assume that |image| can be used with GL_TEXTURE_2D but | 
| 140 uniform sampler2D a_texture; | 135 // that might not be the case for some GLImage implementations. | 
| 141 varying vec2 v_texCoord; | 136 glBindTexture(GL_TEXTURE_2D, texture); | 
| 142 void main() { | 137 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_size.width(), | 
| 143 gl_FragColor = texture2D(a_texture, v_texCoord); | 138 image_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, | 
| 144 } | 139 pixels.get()); | 
| 145 ); | |
| 146 const char kShaderFloatPrecision[] = STRINGIZE( | |
| 147 precision mediump float; | |
| 148 ); | |
| 149 // clang-format on | |
| 150 | 140 | 
| 151 GLuint vertex_shader = | 141 // Copy |image| to |texture|. | 
| 152 gfx::GLHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader); | 142 bool rv = image->CopyTexImage(GL_TEXTURE_2D); | 
| 153 bool is_gles = gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; | 143 EXPECT_TRUE(rv); | 
| 154 GLuint fragment_shader = gfx::GLHelper::LoadShader( | |
| 155 GL_FRAGMENT_SHADER, | |
| 156 base::StringPrintf("%s%s", is_gles ? kShaderFloatPrecision : "", | |
| 157 kFragmentShader) | |
| 158 .c_str()); | |
| 159 GLuint program = gfx::GLHelper::SetupProgram(vertex_shader, fragment_shader); | |
| 160 EXPECT_NE(program, 0u); | |
| 161 glUseProgram(program); | |
| 162 | 144 | 
| 163 GLint sampler_location = glGetUniformLocation(program, "a_texture"); | 145 // Draw |texture| to viewport and read back pixels to check expectations. | 
| 164 ASSERT_NE(sampler_location, -1); | 146 gfx::GLHelper::DrawQuad(vertex_buffer); | 
| 165 glUniform1i(sampler_location, 0); | |
| 166 | 147 | 
| 167 GLuint vertex_buffer = gfx::GLHelper::SetupQuadVertexBuffer(); | 148 GLTestHelper::CheckPixels(0, 0, image_size.width(), image_size.height(), | 
| 168 // Draw |texture| to viewport and read back pixels to check expectations. | 149 image_color); | 
| 169 gfx::GLHelper::DrawQuad(vertex_buffer); | |
| 170 | 150 | 
| 171 GLTestHelper::CheckPixels(0, 0, image_size.width(), image_size.height(), | 151 // Clean up. | 
| 172 image_color); | 152 glDeleteTextures(1, &texture); | 
| 173 | 153 image->Destroy(true); | 
| 174 // Clean up. | 154 } | 
| 175 glDeleteProgram(program); | 155 glDeleteProgram(program); | 
| 176 glDeleteShader(vertex_shader); | |
| 177 glDeleteShader(fragment_shader); | |
| 178 glDeleteBuffersARB(1, &vertex_buffer); | 156 glDeleteBuffersARB(1, &vertex_buffer); | 
| 179 glDeleteTextures(1, &texture); | |
| 180 glDeleteFramebuffersEXT(1, &framebuffer); | 157 glDeleteFramebuffersEXT(1, &framebuffer); | 
| 181 image->Destroy(true); | |
| 182 } | 158 } | 
| 183 | 159 | 
| 184 // The GLImageCopyTest test case verifies that the GLImage implementation | 160 // The GLImageCopyTest test case verifies that the GLImage implementation | 
| 185 // handles CopyTexImage correctly. | 161 // handles CopyTexImage correctly. | 
| 186 REGISTER_TYPED_TEST_CASE_P(GLImageCopyTest, CopyTexImage); | 162 REGISTER_TYPED_TEST_CASE_P(GLImageCopyTest, CopyTexImage); | 
| 187 | 163 | 
| 164 template <typename GLImageTestDelegate> | |
| 165 class GLImageBindTest : public GLImageTest<GLImageTestDelegate> {}; | |
| 166 | |
| 167 TYPED_TEST_CASE_P(GLImageBindTest); | |
| 168 | |
| 169 TYPED_TEST_P(GLImageBindTest, BindTexImage) { | |
| 170 const gfx::Size image_size(256, 256); | |
| 171 const uint8_t image_color[] = {0x10, 0x20, 0, 0xff}; | |
| 172 | |
| 173 GLuint framebuffer = | |
| 174 GLTestHelper::SetupFramebuffer(image_size.width(), image_size.height()); | |
| 175 ASSERT_TRUE(framebuffer); | |
| 176 glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer); | |
| 177 glViewport(0, 0, image_size.width(), image_size.height()); | |
| 178 | |
| 179 GLuint program = GLImageTestSupport::CreateSingleTextureProgram(); | |
| 180 GLuint vertex_buffer = gfx::GLHelper::SetupQuadVertexBuffer(); | |
| 181 | |
| 182 for (auto format : gfx::GetBufferFormatsForTesting()) { | |
| 183 if (!TypeParam::IsSupported(format)) { | |
| 184 continue; | |
| 185 } | |
| 186 | |
| 187 // Create a solid color green image of preferred format. This must succeed | |
| 188 // in order for a GLImage to be conformant. | |
| 189 scoped_refptr<gl::GLImage> image = | |
| 190 this->delegate_.CreateSolidColorImage(image_size, format, image_color); | |
| 191 ASSERT_TRUE(image); | |
| 192 | |
| 193 GLuint texture = GLTestHelper::CreateTexture(GL_TEXTURE_2D); | |
| 194 | |
| 195 // Bind |image| to |texture|. | |
| 196 bool rv = image->BindTexImage(GL_TEXTURE_2D); | |
| 197 EXPECT_TRUE(rv); | |
| 198 | |
| 199 // Draw |texture| to viewport and read back pixels to check expectations. | |
| 200 gfx::GLHelper::DrawQuad(vertex_buffer); | |
| 201 | |
| 202 GLTestHelper::CheckPixels(0, 0, image_size.width(), image_size.height(), | |
| 203 image_color); | |
| 204 | |
| 205 // Clean up. | |
| 206 glDeleteTextures(1, &texture); | |
| 207 image->Destroy(true); | |
| 208 } | |
| 209 glDeleteProgram(program); | |
| 210 glDeleteBuffersARB(1, &vertex_buffer); | |
| 211 glDeleteFramebuffersEXT(1, &framebuffer); | |
| 212 } | |
| 213 | |
| 214 // The GLImageBindTest test case verifies that the GLImage implementation | |
| 215 // handles BindTexImage correctly. | |
| 216 REGISTER_TYPED_TEST_CASE_P(GLImageBindTest, BindTexImage); | |
| 217 | |
| 188 } // namespace gl | 218 } // namespace gl | 
| 189 | 219 | 
| 190 #endif // UI_GL_TEST_GL_IMAGE_TEST_TEMPLATE_H_ | 220 #endif // UI_GL_TEST_GL_IMAGE_TEST_TEMPLATE_H_ | 
| OLD | NEW |