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 |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "ui/gl/gl_helper.h" | 21 #include "ui/gl/gl_helper.h" |
22 #include "ui/gl/gl_image.h" | 22 #include "ui/gl/gl_image.h" |
23 #include "ui/gl/gl_implementation.h" | 23 #include "ui/gl/gl_implementation.h" |
24 #include "ui/gl/gl_surface.h" | 24 #include "ui/gl/gl_surface.h" |
25 #include "ui/gl/test/gl_image_test_support.h" | 25 #include "ui/gl/test/gl_image_test_support.h" |
26 #include "ui/gl/test/gl_test_helper.h" | 26 #include "ui/gl/test/gl_test_helper.h" |
27 | 27 |
28 namespace gl { | 28 namespace gl { |
29 namespace { | 29 namespace { |
30 | 30 |
31 std::string PrependFragmentSamplerType(unsigned target, | 31 // Compiles a fragment shader for sampling out of a texture of |size| bound to |
32 std::string shader_string) { | 32 // |target| and checks for compilation errors. |
| 33 GLuint LoadFragmentShader(unsigned target, const gfx::Size& size) { |
| 34 // clang-format off |
| 35 const char kFragmentShader[] = STRINGIZE( |
| 36 uniform SamplerType a_texture; |
| 37 varying vec2 v_texCoord; |
| 38 void main() { |
| 39 gl_FragColor = TextureLookup(a_texture, v_texCoord * TextureScale); |
| 40 } |
| 41 ); |
| 42 const char kShaderFloatPrecision[] = STRINGIZE( |
| 43 precision mediump float; |
| 44 ); |
| 45 // clang-format on |
| 46 |
| 47 bool is_gles = gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; |
33 switch (target) { | 48 switch (target) { |
34 case GL_TEXTURE_2D: | 49 case GL_TEXTURE_2D: |
35 DCHECK_NE(shader_string.find("SamplerType"), std::string::npos); | 50 return gfx::GLHelper::LoadShader( |
36 DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos); | 51 GL_FRAGMENT_SHADER, |
37 return "#define SamplerType sampler2D\n" | 52 base::StringPrintf("%s\n" |
38 "#define TextureLookup texture2D\n" + | 53 "#define SamplerType sampler2D\n" |
39 shader_string; | 54 "#define TextureLookup texture2D\n" |
| 55 "#define TextureScale vec2(1.0, 1.0)\n" |
| 56 "%s", |
| 57 is_gles ? kShaderFloatPrecision : "", |
| 58 kFragmentShader) |
| 59 .c_str()); |
40 case GL_TEXTURE_RECTANGLE_ARB: | 60 case GL_TEXTURE_RECTANGLE_ARB: |
41 DCHECK_NE(shader_string.find("SamplerType"), std::string::npos); | 61 return gfx::GLHelper::LoadShader( |
42 DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos); | 62 GL_FRAGMENT_SHADER, |
43 return "#extension GL_ARB_texture_rectangle : require\n" | 63 base::StringPrintf("%s\n" |
44 "#define SamplerType sampler2DRect\n" | 64 "#extension GL_ARB_texture_rectangle : require\n" |
45 "#define TextureLookup texture2DRect\n" + | 65 "#define SamplerType sampler2DRect\n" |
46 shader_string; | 66 "#define TextureLookup texture2DRect\n" |
| 67 "#define TextureScale vec2(%f, %f)\n" |
| 68 "%s", |
| 69 is_gles ? kShaderFloatPrecision : "", |
| 70 static_cast<double>(size.width()), |
| 71 static_cast<double>(size.height()), |
| 72 kFragmentShader) |
| 73 .c_str()); |
47 default: | 74 default: |
48 NOTREACHED(); | 75 NOTREACHED(); |
49 break; | 76 return 0; |
50 } | 77 } |
51 return shader_string; | |
52 } | 78 } |
53 | 79 |
54 struct ProgramAndShaders { | 80 // Draws texture bound to |target| of texture unit 0 to the currently bound |
55 GLuint program; | 81 // frame buffer. |
56 GLuint vertex_shader; | 82 void DrawTextureQuad(GLenum target, const gfx::Size& size) { |
57 GLuint fragment_shader; | |
58 }; | |
59 | |
60 // Creates a shader that reads from a texture. | |
61 // Returns the newly created programs and shaders. | |
62 void SetUpVertexAndFragmentShader(GLenum target, ProgramAndShaders* pas) { | |
63 // clang-format off | 83 // clang-format off |
64 const char kVertexShader[] = STRINGIZE( | 84 const char kVertexShader[] = STRINGIZE( |
65 attribute vec2 a_position; | 85 attribute vec2 a_position; |
66 varying vec2 v_texCoord; | 86 varying vec2 v_texCoord; |
67 void main() { | 87 void main() { |
68 gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0); | 88 gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0); |
69 v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5; | 89 v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5; |
70 } | 90 } |
71 ); | 91 ); |
72 const char kFragmentShader[] = STRINGIZE( | |
73 uniform SamplerType a_texture; | |
74 varying vec2 v_texCoord; | |
75 void main() { | |
76 gl_FragColor = TextureLookup(a_texture, v_texCoord); | |
77 } | |
78 ); | |
79 const char kShaderFloatPrecision[] = STRINGIZE( | |
80 precision mediump float; | |
81 ); | |
82 // clang-format on | 92 // clang-format on |
83 | 93 |
84 GLuint vertex_shader = | 94 GLuint vertex_shader = |
85 gfx::GLHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader); | 95 gfx::GLHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader); |
86 bool is_gles = gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; | 96 GLuint fragment_shader = LoadFragmentShader(target, size); |
87 GLuint fragment_shader = gfx::GLHelper::LoadShader( | |
88 GL_FRAGMENT_SHADER, | |
89 base::StringPrintf( | |
90 "%s\n%s", is_gles ? kShaderFloatPrecision : "", | |
91 PrependFragmentSamplerType(target, kFragmentShader).c_str()) | |
92 .c_str()); | |
93 GLuint program = gfx::GLHelper::SetupProgram(vertex_shader, fragment_shader); | 97 GLuint program = gfx::GLHelper::SetupProgram(vertex_shader, fragment_shader); |
94 EXPECT_NE(program, 0u); | 98 EXPECT_NE(program, 0u); |
95 glUseProgram(program); | 99 glUseProgram(program); |
96 | 100 |
97 GLint sampler_location = glGetUniformLocation(program, "a_texture"); | 101 GLint sampler_location = glGetUniformLocation(program, "a_texture"); |
98 ASSERT_NE(sampler_location, -1); | 102 ASSERT_NE(sampler_location, -1); |
99 glUniform1i(sampler_location, 0); | 103 glUniform1i(sampler_location, 0); |
100 | 104 |
101 pas->program = program; | 105 GLuint vertex_buffer = gfx::GLHelper::SetupQuadVertexBuffer(); |
102 pas->vertex_shader = vertex_shader; | 106 gfx::GLHelper::DrawQuad(vertex_buffer); |
103 pas->fragment_shader = fragment_shader; | 107 |
| 108 glDeleteShader(vertex_shader); |
| 109 glDeleteShader(fragment_shader); |
| 110 glDeleteProgram(program); |
| 111 glDeleteBuffersARB(1, &vertex_buffer); |
104 } | 112 } |
105 | 113 |
106 } // namespace | 114 } // namespace |
107 | 115 |
108 template <typename GLImageTestDelegate> | 116 template <typename GLImageTestDelegate> |
109 class GLImageTest : public testing::Test { | 117 class GLImageTest : public testing::Test { |
110 protected: | 118 protected: |
111 // Overridden from testing::Test: | 119 // Overridden from testing::Test: |
112 void SetUp() override { | 120 void SetUp() override { |
113 GLImageTestSupport::InitializeGL(); | 121 GLImageTestSupport::InitializeGL(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 class GLImageZeroInitializeTest : public GLImageTest<GLImageTestDelegate> {}; | 174 class GLImageZeroInitializeTest : public GLImageTest<GLImageTestDelegate> {}; |
167 | 175 |
168 // This test verifies that if an uninitialized image is bound to a texture, the | 176 // This test verifies that if an uninitialized image is bound to a texture, the |
169 // result is zero-initialized. | 177 // result is zero-initialized. |
170 TYPED_TEST_CASE_P(GLImageZeroInitializeTest); | 178 TYPED_TEST_CASE_P(GLImageZeroInitializeTest); |
171 | 179 |
172 // TODO(erikchen): Enable this test when it actually passes on Mac. | 180 // TODO(erikchen): Enable this test when it actually passes on Mac. |
173 // https://crbug.com/584760. | 181 // https://crbug.com/584760. |
174 TYPED_TEST_P(GLImageZeroInitializeTest, DISABLED_ZeroInitialize) { | 182 TYPED_TEST_P(GLImageZeroInitializeTest, DISABLED_ZeroInitialize) { |
175 const gfx::Size image_size(256, 256); | 183 const gfx::Size image_size(256, 256); |
176 scoped_refptr<gl::GLImage> image = this->delegate_.CreateImage(image_size); | |
177 GLenum target = this->delegate_.GetTextureTarget(); | |
178 GLuint uninitialized_texture = GLTestHelper::CreateTexture(target); | |
179 | 184 |
180 glBindTexture(target, uninitialized_texture); | |
181 ASSERT_TRUE(image->BindTexImage(target)); | |
182 GLuint framebuffer = | 185 GLuint framebuffer = |
183 GLTestHelper::SetupFramebuffer(image_size.width(), image_size.height()); | 186 GLTestHelper::SetupFramebuffer(image_size.width(), image_size.height()); |
184 ASSERT_TRUE(framebuffer); | 187 ASSERT_TRUE(framebuffer); |
185 glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer); | 188 glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer); |
186 glViewport(0, 0, image_size.width(), image_size.height()); | 189 glViewport(0, 0, image_size.width(), image_size.height()); |
187 GLuint vertex_buffer = gfx::GLHelper::SetupQuadVertexBuffer(); | |
188 | 190 |
189 ProgramAndShaders pas; | 191 // Create an uninitialized image of preferred format. |
190 SetUpVertexAndFragmentShader(target, &pas); | 192 scoped_refptr<gl::GLImage> image = this->delegate_.CreateImage(image_size); |
191 gfx::GLHelper::DrawQuad(vertex_buffer); | |
192 | 193 |
| 194 // Create a texture that |image| will be bound to. |
| 195 GLenum target = this->delegate_.GetTextureTarget(); |
| 196 GLuint texture = GLTestHelper::CreateTexture(target); |
| 197 glBindTexture(target, texture); |
| 198 |
| 199 // Bind |image| to |texture|. |
| 200 bool rv = image->BindTexImage(target); |
| 201 EXPECT_TRUE(rv); |
| 202 |
| 203 // Draw |texture| to viewport. |
| 204 DrawTextureQuad(target, image_size); |
| 205 |
| 206 // Release |image| from |texture|. |
| 207 image->ReleaseTexImage(target); |
| 208 |
| 209 // Read back pixels to check expectations. |
193 const uint8_t zero_color[] = {0, 0, 0, 0}; | 210 const uint8_t zero_color[] = {0, 0, 0, 0}; |
194 GLTestHelper::CheckPixels(0, 0, image_size.width(), image_size.height(), | 211 GLTestHelper::CheckPixels(0, 0, image_size.width(), image_size.height(), |
195 zero_color); | 212 zero_color); |
196 | 213 |
197 glDeleteProgram(pas.program); | 214 // Clean up. |
198 glDeleteShader(pas.vertex_shader); | 215 glDeleteTextures(1, &texture); |
199 glDeleteShader(pas.fragment_shader); | |
200 glDeleteBuffersARB(1, &vertex_buffer); | |
201 glDeleteFramebuffersEXT(1, &framebuffer); | 216 glDeleteFramebuffersEXT(1, &framebuffer); |
202 | 217 image->Destroy(true /* have_context */); |
203 image->ReleaseTexImage(target); | |
204 image->Destroy(true); | |
205 glDeleteTextures(1, &uninitialized_texture); | |
206 } | 218 } |
207 | 219 |
208 REGISTER_TYPED_TEST_CASE_P(GLImageZeroInitializeTest, DISABLED_ZeroInitialize); | 220 REGISTER_TYPED_TEST_CASE_P(GLImageZeroInitializeTest, DISABLED_ZeroInitialize); |
209 | 221 |
210 template <typename GLImageTestDelegate> | 222 template <typename GLImageTestDelegate> |
211 class GLImageCopyTest : public GLImageTest<GLImageTestDelegate> {}; | 223 class GLImageCopyTest : public GLImageTest<GLImageTestDelegate> {}; |
212 | 224 |
213 TYPED_TEST_CASE_P(GLImageCopyTest); | 225 TYPED_TEST_CASE_P(GLImageCopyTest); |
214 | 226 |
215 TYPED_TEST_P(GLImageCopyTest, CopyTexImage) { | 227 TYPED_TEST_P(GLImageCopyTest, CopyTexImage) { |
(...skipping 25 matching lines...) Expand all Loading... |
241 image_size.width(), image_size.height(), | 253 image_size.width(), image_size.height(), |
242 static_cast<int>(RowSizeForBufferFormat(image_size.width(), | 254 static_cast<int>(RowSizeForBufferFormat(image_size.width(), |
243 gfx::BufferFormat::RGBA_8888, 0)), | 255 gfx::BufferFormat::RGBA_8888, 0)), |
244 0, gfx::BufferFormat::RGBA_8888, texture_color, pixels.get()); | 256 0, gfx::BufferFormat::RGBA_8888, texture_color, pixels.get()); |
245 glBindTexture(target, texture); | 257 glBindTexture(target, texture); |
246 glTexImage2D(target, 0, GL_RGBA, image_size.width(), image_size.height(), 0, | 258 glTexImage2D(target, 0, GL_RGBA, image_size.width(), image_size.height(), 0, |
247 GL_RGBA, GL_UNSIGNED_BYTE, pixels.get()); | 259 GL_RGBA, GL_UNSIGNED_BYTE, pixels.get()); |
248 | 260 |
249 // Copy |image| to |texture|. | 261 // Copy |image| to |texture|. |
250 bool rv = image->CopyTexImage(target); | 262 bool rv = image->CopyTexImage(target); |
251 | |
252 EXPECT_TRUE(rv); | 263 EXPECT_TRUE(rv); |
253 | 264 |
254 ProgramAndShaders pas; | 265 // Draw |texture| to viewport. |
255 SetUpVertexAndFragmentShader(target, &pas); | 266 DrawTextureQuad(target, image_size); |
256 | 267 |
257 GLuint vertex_buffer = gfx::GLHelper::SetupQuadVertexBuffer(); | 268 // Read back pixels to check expectations. |
258 // Draw |texture| to viewport and read back pixels to check expectations. | |
259 gfx::GLHelper::DrawQuad(vertex_buffer); | |
260 | |
261 GLTestHelper::CheckPixels(0, 0, image_size.width(), image_size.height(), | 269 GLTestHelper::CheckPixels(0, 0, image_size.width(), image_size.height(), |
262 image_color); | 270 image_color); |
263 | 271 |
264 // Clean up. | 272 // Clean up. |
265 glDeleteProgram(pas.program); | |
266 glDeleteShader(pas.vertex_shader); | |
267 glDeleteShader(pas.fragment_shader); | |
268 glDeleteBuffersARB(1, &vertex_buffer); | |
269 glDeleteTextures(1, &texture); | 273 glDeleteTextures(1, &texture); |
270 glDeleteFramebuffersEXT(1, &framebuffer); | 274 glDeleteFramebuffersEXT(1, &framebuffer); |
271 image->Destroy(true); | 275 image->Destroy(true /* have_context */); |
272 } | 276 } |
273 | 277 |
274 // The GLImageCopyTest test case verifies that the GLImage implementation | 278 // The GLImageCopyTest test case verifies that the GLImage implementation |
275 // handles CopyTexImage correctly. | 279 // handles CopyTexImage correctly. |
276 REGISTER_TYPED_TEST_CASE_P(GLImageCopyTest, CopyTexImage); | 280 REGISTER_TYPED_TEST_CASE_P(GLImageCopyTest, CopyTexImage); |
277 | 281 |
278 } // namespace gl | 282 } // namespace gl |
279 | 283 |
280 #endif // UI_GL_TEST_GL_IMAGE_TEST_TEMPLATE_H_ | 284 #endif // UI_GL_TEST_GL_IMAGE_TEST_TEMPLATE_H_ |
OLD | NEW |