1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef GL_GLEXT_PROTOTYPES
6 #define GL_GLEXT_PROTOTYPES
7 #endif
8
9 #include <GLES2/gl2.h>
10 #include <GLES2/gl2ext.h>
11 #include <GLES2/gl2extchromium.h>
12 #include <GLES3/gl3.h>
13 #include <stddef.h>
14 #include <stdint.h>
15
16 #include "base/logging.h"
17 #include "base/stl_util.h"
18 #include "build/build_config.h"
19 #include "gpu/command_buffer/tests/gl_manager.h"
20 #include "gpu/command_buffer/tests/gl_test_utils.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/gl/gl_enums.h"
24 #include "ui/gl/gl_version_info.h"
25
26 namespace gpu {
27
28 namespace {
29
30 enum CopyType { TexImage, TexSubImage };
31 const CopyType kCopyTypes[] = {
32 TexImage,
33 TexSubImage,
34 };
35
36 struct FormatType {
37 GLenum internal_format;
38 GLenum format;
39 GLenum type;
40 };
41
42 static const char* kSimpleVertexShaderES2 =
43 "attribute vec2 a_position;\n"
44 "varying vec2 v_texCoord;\n"
45 "void main() {\n"
46 " gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0);\n"
47 " v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5;\n"
48 "}\n";
49
50 static const char* kSimpleVertexShaderES3 =
51 "#version 300 es\n"
52 "in vec2 a_position;\n"
53 "out vec2 v_texCoord;\n"
54 "void main() {\n"
55 " gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0);\n"
56 " v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5;\n"
57 "}\n";
58
GetFragmentShaderSource(GLenum target,GLenum format,bool is_es3)59 std::string GetFragmentShaderSource(GLenum target, GLenum format, bool is_es3) {
60 std::string source;
61 if (is_es3) {
62 source +=
63 "#version 300 es\n"
64 "#define VARYING in\n"
65 "#define FRAGCOLOR frag_color\n"
66 "#define TextureLookup texture\n";
67 } else {
68 source +=
69 "#define VARYING varying\n"
70 "#define FRAGCOLOR gl_FragColor\n";
71 if (target == GL_TEXTURE_CUBE_MAP) {
72 source += "#define TextureLookup textureCube\n";
73 } else {
74 source += "#define TextureLookup texture2D\n";
75 }
76 }
77 source += "precision mediump float;\n";
78
79 if (gles2::GLES2Util::IsSignedIntegerFormat(format)) {
80 if (target == GL_TEXTURE_CUBE_MAP) {
81 source += "#define SamplerType isamplerCube\n";
82 } else {
83 source += "#define SamplerType isampler2D\n";
84 }
85 source += "#define TextureType ivec4\n";
86 source += "#define ScaleValue 255.0\n";
87 } else if (gles2::GLES2Util::IsUnsignedIntegerFormat(format)) {
88 if (target == GL_TEXTURE_CUBE_MAP) {
89 source += "#define SamplerType usamplerCube\n";
90 } else {
91 source += "#define SamplerType usampler2D\n";
92 }
93 source += "#define TextureType uvec4\n";
94 source += "#define ScaleValue 255.0\n";
95 } else {
96 if (target == GL_TEXTURE_CUBE_MAP) {
97 source += "#define SamplerType samplerCube\n";
98 } else {
99 source += "#define SamplerType sampler2D\n";
100 }
101 source += "#define TextureType vec4\n";
102 source += "#define ScaleValue 1.0\n";
103 }
104
105 if (is_es3)
106 source += "out vec4 frag_color;\n";
107
108 if (target == GL_TEXTURE_CUBE_MAP)
109 source += "uniform highp int u_face;\n";
110
111 source +=
112 "uniform mediump SamplerType u_texture;\n"
113 "VARYING vec2 v_texCoord;\n"
114 "void main() {\n";
115
116 if (target == GL_TEXTURE_CUBE_MAP) {
117 source +=
118 " vec3 texCube;\n"
119 // Transform [0, 1] to [-1, 1].
120 " vec2 texCoord = (v_texCoord * 2.0) - 1.0;\n"
121 // Transform 2d tex coord to each face of TEXTURE_CUBE_MAP coord.
122 // TEXTURE_CUBE_MAP_POSITIVE_X
123 " if (u_face == 34069) {\n"
124 " texCube = vec3(1.0, -texCoord.y, -texCoord.x);\n"
125 // TEXTURE_CUBE_MAP_NEGATIVE_X
126 " } else if (u_face == 34070) {\n"
127 " texCube = vec3(-1.0, -texCoord.y, texCoord.x);\n"
128 // TEXTURE_CUBE_MAP_POSITIVE_Y
129 " } else if (u_face == 34071) {\n"
130 " texCube = vec3(texCoord.x, 1.0, texCoord.y);\n"
131 // TEXTURE_CUBE_MAP_NEGATIVE_Y
132 " } else if (u_face == 34072) {\n"
133 " texCube = vec3(texCoord.x, -1.0, -texCoord.y);\n"
134 // TEXTURE_CUBE_MAP_POSITIVE_Z
135 " } else if (u_face == 34073) {\n"
136 " texCube = vec3(texCoord.x, -texCoord.y, 1.0);\n"
137 // TEXTURE_CUBE_MAP_NEGATIVE_Z
138 " } else if (u_face == 34074) {\n"
139 " texCube = vec3(-texCoord.x, -texCoord.y, -1.0);\n"
140 " }\n"
141 " TextureType color = TextureLookup(u_texture, texCube);\n";
142 } else {
143 source += " TextureType color = TextureLookup(u_texture, v_texCoord);\n";
144 }
145
146 source +=
147 " FRAGCOLOR = vec4(color) / ScaleValue;\n"
148 "}\n";
149 return source;
150 }
151
setColor(uint8_t r,uint8_t g,uint8_t b,uint8_t a,uint8_t * color)152 void setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a, uint8_t* color) {
153 color[0] = r;
154 color[1] = g;
155 color[2] = b;
156 color[3] = a;
157 }
158
getExpectedColorAndMask(GLenum src_internal_format,GLenum dest_internal_format,const uint8_t * color,uint8_t * expected_color,uint8_t * expected_mask)159 void getExpectedColorAndMask(GLenum src_internal_format,
160 GLenum dest_internal_format,
161 const uint8_t* color,
162 uint8_t* expected_color,
163 uint8_t* expected_mask) {
164 uint8_t adjusted_color[4];
165 switch (src_internal_format) {
166 case GL_ALPHA:
167 setColor(0, 0, 0, color[0], adjusted_color);
168 break;
169 case GL_R8:
170 case GL_R16_EXT:
171 setColor(color[0], 0, 0, 255, adjusted_color);
172 break;
173 case GL_LUMINANCE:
174 setColor(color[0], color[0], color[0], 255, adjusted_color);
175 break;
176 case GL_LUMINANCE_ALPHA:
177 setColor(color[0], color[0], color[0], color[1], adjusted_color);
178 break;
179 case GL_RG16_EXT:
180 setColor(color[0], color[1], 0, 255, adjusted_color);
181 break;
182 case GL_RGB:
183 case GL_RGB8:
184 case GL_RGB_YCBCR_420V_CHROMIUM:
185 case GL_RGB_YCBCR_422_CHROMIUM:
186 setColor(color[0], color[1], color[2], 255, adjusted_color);
187 break;
188 case GL_RGBA:
189 case GL_RGBA8:
190 case GL_RGBA16_EXT:
191 setColor(color[0], color[1], color[2], color[3], adjusted_color);
192 break;
193 case GL_BGRA_EXT:
194 case GL_BGRA8_EXT:
195 setColor(color[2], color[1], color[0], color[3], adjusted_color);
196 break;
197 case GL_RGB10_A2: {
198 // Map the source 2-bit Alpha to 8-bits.
199 const uint8_t alpha_value = (color[3] & 0x3) * 255 / 3;
200 setColor(color[0] >> 2, color[1] >> 2, color[2] >> 2, alpha_value,
201 adjusted_color);
202 break;
203 }
204 default:
205 NOTREACHED() << gl::GLEnums::GetStringEnum(src_internal_format);
206 break;
207 }
208
209 switch (dest_internal_format) {
210 // TODO(crbug.com/577144): Enable GL_ALPHA, GL_LUMINANCE and
211 // GL_LUMINANCE_ALPHA.
212 case GL_R8:
213 case GL_R16F:
214 case GL_R32F:
215 case GL_R8UI:
216 setColor(adjusted_color[0], 0, 0, 0, expected_color);
217 setColor(1, 0, 0, 0, expected_mask);
218 break;
219 case GL_RG8:
220 case GL_RG16F:
221 case GL_RG32F:
222 case GL_RG8UI:
223 setColor(adjusted_color[0], adjusted_color[1], 0, 0, expected_color);
224 setColor(1, 1, 0, 0, expected_mask);
225 break;
226 case GL_RGB:
227 case GL_RGB8:
228 case GL_SRGB_EXT:
229 case GL_SRGB8:
230 case GL_RGB565:
231 case GL_R11F_G11F_B10F:
232 case GL_RGB9_E5:
233 case GL_RGB16F:
234 case GL_RGB32F:
235 case GL_RGB8UI:
236 setColor(adjusted_color[0], adjusted_color[1], adjusted_color[2], 0,
237 expected_color);
238 setColor(1, 1, 1, 0, expected_mask);
239 break;
240 case GL_RGBA:
241 case GL_RGBA8:
242 case GL_BGRA_EXT:
243 case GL_BGRA8_EXT:
244 case GL_SRGB_ALPHA_EXT:
245 case GL_SRGB8_ALPHA8:
246 case GL_RGBA4:
247 case GL_RGBA16F:
248 case GL_RGBA32F:
249 case GL_RGBA8UI:
250 setColor(adjusted_color[0], adjusted_color[1], adjusted_color[2],
251 adjusted_color[3], expected_color);
252 setColor(1, 1, 1, 1, expected_mask);
253 break;
254 case GL_RGB10_A2: {
255 // Map the 2-bit Alpha values back to full bytes.
256 constexpr uint8_t step = 0x55;
257 const uint8_t alpha_value = (adjusted_color[3] + step / 2) / step * step;
258
259 setColor(adjusted_color[0], adjusted_color[1], adjusted_color[2],
260 alpha_value, expected_color);
261 #if defined(OS_MAC) || defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
262 // The alpha channel values for LUMINANCE_ALPHA source don't work OK
263 // on Mac or Linux, so skip comparison of those, see crbug.com/926579
264 setColor(1, 1, 1, src_internal_format != GL_LUMINANCE_ALPHA,
265 expected_mask);
266 #else
267 setColor(1, 1, 1, 1, expected_mask);
268 #endif
269 break;
270 }
271 case GL_RGB5_A1:
272 setColor(adjusted_color[0], adjusted_color[1], adjusted_color[2],
273 (adjusted_color[3] >> 7) ? 0xFF : 0x0, expected_color);
274 // TODO(qiankun.miao@intel.com): On some Windows platforms, the alpha
275 // channel of expected color is the source alpha value other than 255.
276 // This should be wrong. Skip the alpha channel check and revisit this in
277 // future.
278 setColor(1, 1, 1, 0, expected_mask);
279 break;
280 default:
281 NOTREACHED() << gl::GLEnums::GetStringEnum(dest_internal_format);
282 break;
283 }
284 }
285
getTextureDataAndExpectedRGBAs(FormatType src_format_type,FormatType dest_format_type,GLsizei width,GLsizei height,std::vector<uint8_t> * texture_data,std::vector<uint8_t> * expected_rgba_pixels,uint8_t * expected_mask)286 void getTextureDataAndExpectedRGBAs(FormatType src_format_type,
287 FormatType dest_format_type,
288 GLsizei width,
289 GLsizei height,
290 std::vector<uint8_t>* texture_data,
291 std::vector<uint8_t>* expected_rgba_pixels,
292 uint8_t* expected_mask) {
293 DCHECK(texture_data);
294 DCHECK(expected_rgba_pixels);
295
296 const uint32_t src_channel_count = gles2::GLES2Util::ElementsPerGroup(
297 src_format_type.format, src_format_type.type);
298 constexpr uint8_t color[4] = {1u, 63u, 127u, 255u};
299 uint8_t expected_color[4];
300 constexpr uint8_t alt_color[4] = {200u, 100u, 0u, 255u};
301
302 getExpectedColorAndMask(src_format_type.internal_format,
303 dest_format_type.internal_format, color,
304 expected_color, expected_mask);
305
306 const size_t num_pixels = width * height;
307 expected_rgba_pixels->resize(num_pixels * 4, 0);
308
309 if (src_format_type.type == GL_UNSIGNED_BYTE) {
310 uint8_t alt_expected_color[4];
311 getExpectedColorAndMask(src_format_type.internal_format,
312 dest_format_type.internal_format, alt_color,
313 alt_expected_color, expected_mask);
314
315 texture_data->resize(num_pixels * src_channel_count, 0);
316 // Generate a simple diagonal pattern to be able to catch UV mapping errors.
317 for (int y = 0; y < height; ++y) {
318 for (int x = 0; x < width; ++x) {
319 bool alt = !((y + x) % 11);
320 for (uint32_t j = 0; j < 4; ++j) {
321 if (j < src_channel_count) {
322 texture_data->at((width * y + x) * src_channel_count + j) =
323 (alt ? alt_color : color)[j];
324 }
325 expected_rgba_pixels->at((width * y + x) * 4 + j) =
326 (alt ? alt_expected_color : expected_color)[j];
327 }
328 }
329 }
330
331 return;
332 } else if (src_format_type.type == GL_UNSIGNED_SHORT) {
333 constexpr uint16_t color_16bit[4] = {color[0] << 8, color[1] << 8,
334 color[2] << 8, color[3] << 8};
335
336 texture_data->resize(num_pixels * src_channel_count * sizeof(uint16_t));
337 uint16_t* texture_data16 =
338 reinterpret_cast<uint16_t*>(texture_data->data());
339 int16_t flip_sign = -1;
340 for (uint32_t i = 0; i < num_pixels * src_channel_count;
341 i += src_channel_count) {
342 for (uint32_t j = 0; j < src_channel_count; ++j) {
343 // Introduce an offset to the value to check. Expected value should be
344 // the same as without the offset.
345 flip_sign *= -1;
346 int16_t offset = flip_sign * ((i + j) % 0x7F);
347 texture_data16[i + j] = color_16bit[j] + offset;
348 }
349 }
350 for (uint32_t i = 0; i < num_pixels * 4; i += 4) {
351 for (int c = 0; c < 4; ++c) {
352 expected_rgba_pixels->at(i + c) = expected_color[c];
353 }
354 }
355
356 return;
357 } else if (src_format_type.type == GL_UNSIGNED_INT_2_10_10_10_REV) {
358 DCHECK_EQ(src_channel_count, 1u);
359 constexpr uint32_t color_rgb10_a2 = ((color[3] & 0x3) << 30) +
360 (color[2] << 20) + (color[1] << 10) +
361 color[0];
362 texture_data->resize(num_pixels * sizeof(uint32_t));
363 uint32_t* texture_data32 =
364 reinterpret_cast<uint32_t*>(texture_data->data());
365 for (uint32_t p = 0; p < num_pixels; ++p) {
366 texture_data32[p] = color_rgb10_a2;
367 memcpy(expected_rgba_pixels->data() + p * 4, expected_color, 4);
368 }
369 return;
370 }
371 NOTREACHED() << gl::GLEnums::GetStringEnum(src_format_type.type);
372 return;
373 }
374
375 } // namespace
376
377 // A collection of tests that exercise the GL_CHROMIUM_copy_texture extension.
378 class GLCopyTextureCHROMIUMTest
379 : public testing::Test,
380 public ::testing::WithParamInterface<CopyType> {
381 protected:
CreateAndBindDestinationTextureAndFBO(GLenum target)382 void CreateAndBindDestinationTextureAndFBO(GLenum target) {
383 glGenTextures(2, textures_);
384 glBindTexture(target, textures_[1]);
385
386 // Some drivers (NVidia/SGX) require texture settings to be a certain way or
387 // they won't report FRAMEBUFFER_COMPLETE.
388 glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
389 glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
390 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
391 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
392
393 glGenFramebuffers(1, &framebuffer_id_);
394 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
395 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target,
396 textures_[1], 0);
397 }
398
SetUp()399 void SetUp() override {
400 GLManager::Options options;
401 options.size = gfx::Size(64, 64);
402 gl_.Initialize(options);
403
404 width_ = 8;
405 height_ = 8;
406 }
407
TearDown()408 void TearDown() override { gl_.Destroy(); }
409
CreateBackingForTexture(GLenum target,GLsizei width,GLsizei height)410 void CreateBackingForTexture(GLenum target, GLsizei width, GLsizei height) {
411 if (target == GL_TEXTURE_RECTANGLE_ARB) {
412 std::unique_ptr<gfx::GpuMemoryBuffer> buffer(gl_.CreateGpuMemoryBuffer(
413 gfx::Size(width, height), gfx::BufferFormat::RGBA_8888));
414 GLuint image_id = glCreateImageCHROMIUM(buffer->AsClientBuffer(), width,
415 height, GL_RGBA);
416 glBindTexImage2DCHROMIUM(target, image_id);
417 } else {
418 glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_RGBA,
419 GL_UNSIGNED_BYTE, nullptr);
420 }
421 }
422
CreateDrawingTexture(GLenum target,GLsizei width,GLsizei height)423 GLuint CreateDrawingTexture(GLenum target, GLsizei width, GLsizei height) {
424 GLuint texture = 0;
425 glGenTextures(1, &texture);
426 glBindTexture(target, texture);
427 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
428 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
429 CreateBackingForTexture(target, width, height);
430 return texture;
431 }
432
CreateDrawingFBO(GLenum target,GLuint texture)433 GLuint CreateDrawingFBO(GLenum target, GLuint texture) {
434 GLuint framebuffer = 0;
435 glGenFramebuffers(1, &framebuffer);
436 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
437 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target,
438 texture, 0);
439 return framebuffer;
440 }
441
ExtractFormatFrom(GLenum internalformat)442 GLenum ExtractFormatFrom(GLenum internalformat) {
443 switch (internalformat) {
444 case GL_RGBA8_OES:
445 return GL_RGBA;
446 case GL_RGB8_OES:
447 return GL_RGB;
448 case GL_BGRA8_EXT:
449 return GL_BGRA_EXT;
450 default:
451 NOTREACHED();
452 return GL_NONE;
453 }
454 }
455
RunCopyTexture(GLenum dest_target,CopyType copy_type,FormatType src_format_type,GLint source_level,FormatType dest_format_type,GLint dest_level,bool is_es3)456 void RunCopyTexture(GLenum dest_target,
457 CopyType copy_type,
458 FormatType src_format_type,
459 GLint source_level,
460 FormatType dest_format_type,
461 GLint dest_level,
462 bool is_es3) {
463 std::vector<uint8_t> expected_pixels;
464 std::vector<uint8_t> texture_data;
465 uint8_t mask[4];
466 getTextureDataAndExpectedRGBAs(src_format_type, dest_format_type, width_,
467 height_, &texture_data, &expected_pixels,
468 mask);
469 GLenum source_target = GL_TEXTURE_2D;
470 glGenTextures(2, textures_);
471 glBindTexture(source_target, textures_[0]);
472 glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
473 glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
474 #if defined(OS_MAC)
475 // TODO(qiankun.miao@intel.com): Remove this workaround for Mac OSX, once
476 // integer texture rendering bug is fixed on Mac OSX: crbug.com/679639.
477 glTexImage2D(source_target, 0, src_format_type.internal_format,
478 width_ << source_level, height_ << source_level, 0,
479 src_format_type.format, src_format_type.type, nullptr);
480 #endif
481 glTexImage2D(source_target, source_level, src_format_type.internal_format,
482 width_, height_, 0, src_format_type.format,
483 src_format_type.type, texture_data.data());
484 EXPECT_TRUE(glGetError() == GL_NO_ERROR);
485 GLenum dest_binding_target =
486 gles2::GLES2Util::GLFaceTargetToTextureTarget(dest_target);
487 glBindTexture(dest_binding_target, textures_[1]);
488 glTexParameterf(dest_binding_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
489 glTexParameterf(dest_binding_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
490 glTexParameteri(dest_binding_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
491 // This hack makes dest texture complete in ES2 and ES3 context
492 // respectively. With this, sampling from the dest texture is correct.
493 if (is_es3) {
494 glTexParameteri(dest_binding_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
495 glTexParameteri(dest_binding_target, GL_TEXTURE_BASE_LEVEL, dest_level);
496 // For cube map textures, make the texture cube complete.
497 if (dest_binding_target == GL_TEXTURE_CUBE_MAP) {
498 for (int i = 0; i < 6; ++i) {
499 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
500 glTexImage2D(face, dest_level, dest_format_type.internal_format,
501 width_, height_, 0, dest_format_type.format,
502 dest_format_type.type, nullptr);
503 }
504 }
505 #if defined(OS_MAC)
506 // TODO(qiankun.miao@intel.com): Remove this workaround for Mac OSX, once
507 // framebuffer complete bug is fixed on Mac OSX: crbug.com/678526.
508 glTexImage2D(dest_target, 0, dest_format_type.internal_format,
509 width_ << dest_level, height_ << dest_level, 0,
510 dest_format_type.format, dest_format_type.type, nullptr);
511 #endif
512 } else {
513 glTexParameteri(dest_binding_target, GL_TEXTURE_MIN_FILTER,
514 GL_NEAREST_MIPMAP_NEAREST);
515 // For cube map textures, make the texture cube complete.
516 if (dest_binding_target == GL_TEXTURE_CUBE_MAP) {
517 for (int i = 0; i < 6; ++i) {
518 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
519 glTexImage2D(face, 0, dest_format_type.internal_format,
520 width_ << dest_level, height_ << dest_level, 0,
521 dest_format_type.format, dest_format_type.type, nullptr);
522 }
523 } else {
524 glTexImage2D(dest_target, 0, dest_format_type.internal_format,
525 width_ << dest_level, height_ << dest_level, 0,
526 dest_format_type.format, dest_format_type.type, nullptr);
527 }
528 glGenerateMipmap(dest_binding_target);
529 }
530 EXPECT_TRUE(glGetError() == GL_NO_ERROR);
531
532 if (copy_type == TexImage) {
533 glCopyTextureCHROMIUM(textures_[0], source_level, dest_target,
534 textures_[1], dest_level,
535 dest_format_type.internal_format,
536 dest_format_type.type, false, false, false);
537 } else {
538 glBindTexture(dest_binding_target, textures_[1]);
539 glTexImage2D(dest_target, dest_level, dest_format_type.internal_format,
540 width_, height_, 0, dest_format_type.format,
541 dest_format_type.type, nullptr);
542
543 // Split large blits into two in order to expose bugs at lower levels.
544 constexpr int sub_rect_width = 8;
545 if (width_ <= sub_rect_width) {
546 glCopySubTextureCHROMIUM(textures_[0], source_level, dest_target,
547 textures_[1], dest_level, 0, 0, 0, 0, width_,
548 height_, false, false, false);
549 } else {
550 glCopySubTextureCHROMIUM(
551 textures_[0], source_level, dest_target, textures_[1], dest_level,
552 0, 0, 0, 0, width_ - sub_rect_width, height_, false, false, false);
553 glCopySubTextureCHROMIUM(
554 textures_[0], source_level, dest_target, textures_[1], dest_level,
555 width_ - sub_rect_width, 0, width_ - sub_rect_width, 0,
556 sub_rect_width, height_, false, false, false);
557 }
558 }
559 const GLenum last_error = glGetError();
560 EXPECT_TRUE(last_error == GL_NO_ERROR)
561 << gl::GLEnums::GetStringError(last_error);
562
563 // Draw destination texture to a fbo with a TEXTURE_2D texture attachment
564 // in RGBA format.
565 GLuint texture = CreateDrawingTexture(GL_TEXTURE_2D, width_, height_);
566 GLuint framebuffer = CreateDrawingFBO(GL_TEXTURE_2D, texture);
567 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
568 glCheckFramebufferStatus(GL_FRAMEBUFFER));
569 glViewport(0, 0, width_, height_);
570
571 glBindTexture(dest_binding_target, textures_[1]);
572 std::string fragment_shader_source = GetFragmentShaderSource(
573 dest_binding_target, dest_format_type.internal_format, is_es3);
574 GLTestHelper::DrawTextureQuad(
575 dest_target, is_es3 ? kSimpleVertexShaderES3 : kSimpleVertexShaderES2,
576 fragment_shader_source.c_str(), "a_position", "u_texture", "u_face");
577 EXPECT_TRUE(GL_NO_ERROR == glGetError());
578
579 uint8_t tolerance = dest_format_type.internal_format == GL_RGBA4 ? 20 : 7;
580 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, width_, height_, tolerance,
581 expected_pixels, mask))
582 << " dest_target : " << gles2::GLES2Util::GetStringEnum(dest_target)
583 << " src_internal_format: "
584 << gles2::GLES2Util::GetStringEnum(src_format_type.internal_format)
585 << " source_level: " << source_level << " dest_internal_format: "
586 << gles2::GLES2Util::GetStringEnum(dest_format_type.internal_format)
587 << " dest_level: " << dest_level;
588
589 glDeleteTextures(1, &texture);
590 glDeleteFramebuffers(1, &framebuffer);
591 glDeleteTextures(2, textures_);
592 }
593
594 GLManager gl_;
595 GLuint textures_[2];
596 GLsizei width_;
597 GLsizei height_;
598 GLuint framebuffer_id_;
599 };
600
601 class GLCopyTextureCHROMIUMES3Test : public GLCopyTextureCHROMIUMTest {
602 protected:
SetUp()603 void SetUp() override {
604 GLManager::Options options;
605 options.context_type = CONTEXT_TYPE_OPENGLES3;
606 options.size = gfx::Size(64, 64);
607 gl_.Initialize(options);
608
609 width_ = 8;
610 height_ = 8;
611 }
612
613 // If a driver isn't capable of supporting ES3 context, creating
614 // ContextGroup will fail. Just skip the test.
ShouldSkipTest() const615 bool ShouldSkipTest() const {
616 return (!gl_.decoder() || !gl_.decoder()->GetContextGroup());
617 }
618
619 // If EXT_color_buffer_float isn't available, float format isn't supported.
ShouldSkipFloatFormat() const620 bool ShouldSkipFloatFormat() const {
621 DCHECK(!ShouldSkipTest());
622 return !gl_.decoder()->GetFeatureInfo()->ext_color_buffer_float_available();
623 }
624
ShouldSkipBGRA() const625 bool ShouldSkipBGRA() const {
626 DCHECK(!ShouldSkipTest());
627 return !gl_.decoder()
628 ->GetFeatureInfo()
629 ->feature_flags()
630 .ext_texture_format_bgra8888;
631 }
632
ShouldSkipSRGBEXT() const633 bool ShouldSkipSRGBEXT() const {
634 DCHECK(!ShouldSkipTest());
635 return !gl_.decoder()->GetFeatureInfo()->feature_flags().ext_srgb;
636 }
637
ShouldSkipNorm16() const638 bool ShouldSkipNorm16() const {
639 DCHECK(!ShouldSkipTest());
640 #if (defined(OS_MAC) || defined(OS_WIN) || defined(OS_LINUX) || defined(OS_BSD) || \
641 defined(OS_CHROMEOS)) && \
642 (defined(ARCH_CPU_X86) || defined(ARCH_CPU_X86_64))
643 // Make sure it's tested; it is safe to assume that the flag is always true
644 // on desktop.
645 EXPECT_TRUE(
646 gl_.decoder()->GetFeatureInfo()->feature_flags().ext_texture_norm16);
647 #endif
648 return !gl_.decoder()->GetFeatureInfo()->feature_flags().ext_texture_norm16;
649 }
650
ShouldSkipRGBA16ToRGB10A2() const651 bool ShouldSkipRGBA16ToRGB10A2() const {
652 DCHECK(!ShouldSkipTest());
653 #if (defined(OS_MAC) || defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)) && \
654 (defined(ARCH_CPU_X86) || defined(ARCH_CPU_X86_64))
655 // // TODO(crbug.com/1046873): Fails on mac and linux intel.
656 return true;
657 #else
658 return false;
659 #endif
660 }
661
ShouldSkipRGB10A2() const662 bool ShouldSkipRGB10A2() const {
663 DCHECK(!ShouldSkipTest());
664 const gl::GLVersionInfo& gl_version_info =
665 gl_.decoder()->GetFeatureInfo()->gl_version_info();
666 // XB30 support was introduced in GLES 3.0/ OpenGL 3.3, before that it was
667 // signalled via a specific extension.
668 const bool supports_rgb10_a2 =
669 gl_version_info.IsAtLeastGL(3, 3) ||
670 gl_version_info.IsAtLeastGLES(3, 0) ||
671 GLTestHelper::HasExtension("GL_EXT_texture_type_2_10_10_10_REV");
672 EXPECT_TRUE(supports_rgb10_a2);
673 return !supports_rgb10_a2;
674 }
675
IsMacArm64() const676 bool IsMacArm64() const {
677 DCHECK(!ShouldSkipTest());
678 #if defined(OS_MAC) && defined(ARCH_CPU_ARM_FAMILY)
679 return true;
680 #else
681 return false;
682 #endif
683 }
684 };
685
686 INSTANTIATE_TEST_SUITE_P(CopyType,
687 GLCopyTextureCHROMIUMTest,
688 ::testing::ValuesIn(kCopyTypes));
689
690 INSTANTIATE_TEST_SUITE_P(CopyType,
691 GLCopyTextureCHROMIUMES3Test,
692 ::testing::ValuesIn(kCopyTypes));
693
694 // Test to ensure that the basic functionality of the extension works.
TEST_P(GLCopyTextureCHROMIUMTest,Basic)695 TEST_P(GLCopyTextureCHROMIUMTest, Basic) {
696 CopyType copy_type = GetParam();
697 uint8_t pixels[1 * 4] = {255u, 0u, 0u, 255u};
698
699 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
700 glBindTexture(GL_TEXTURE_2D, textures_[0]);
701 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
702 pixels);
703
704 if (copy_type == TexImage) {
705 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
706 GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
707 } else {
708 glBindTexture(GL_TEXTURE_2D, textures_[1]);
709 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
710 nullptr);
711
712 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 0,
713 0, 0, 0, 1, 1, false, false, false);
714 }
715 EXPECT_TRUE(glGetError() == GL_NO_ERROR);
716
717 // Check the FB is still bound.
718 GLint value = 0;
719 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
720 GLuint fb_id = value;
721 EXPECT_EQ(framebuffer_id_, fb_id);
722
723 // Check that FB is complete.
724 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
725 glCheckFramebufferStatus(GL_FRAMEBUFFER));
726
727 GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels, nullptr);
728 EXPECT_TRUE(GL_NO_ERROR == glGetError());
729 }
730
TEST_P(GLCopyTextureCHROMIUMES3Test,BigTexture)731 TEST_P(GLCopyTextureCHROMIUMES3Test, BigTexture) {
732 if (ShouldSkipTest() || ShouldSkipBGRA())
733 return;
734 width_ = 1080;
735 height_ = 1080;
736 const CopyType copy_type = GetParam();
737 FormatType src_format{GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE};
738 FormatType dest_format{GL_RGB, GL_RGB, GL_UNSIGNED_BYTE};
739 RunCopyTexture(GL_TEXTURE_2D, copy_type, src_format, 0, dest_format, 0, true);
740 }
741
TEST_P(GLCopyTextureCHROMIUMES3Test,FormatCombinations)742 TEST_P(GLCopyTextureCHROMIUMES3Test, FormatCombinations) {
743 if (ShouldSkipTest())
744 return;
745 if (IsMacArm64()) {
746 LOG(INFO) << "TODO(crbug.com/1135372): fails on Apple DTK. Skipping.";
747 return;
748 }
749 if (gl_.gpu_preferences().use_passthrough_cmd_decoder) {
750 // TODO(geofflang): anglebug.com/1932
751 LOG(INFO)
752 << "Passthrough command decoder expected failure. Skipping test...";
753 return;
754 }
755 const CopyType copy_type = GetParam();
756
757 FormatType src_format_types[] = {
758 {GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE},
759 {GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE},
760 {GL_RGB, GL_RGB, GL_UNSIGNED_BYTE},
761 {GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE},
762 {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE},
763 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE},
764 {GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE},
765 {GL_BGRA8_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE},
766 {GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT},
767 {GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT},
768 {GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT},
769 {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV},
770 };
771
772 FormatType dest_format_types[] = {
773 // TODO(qiankun.miao@intel.com): ALPHA and LUMINANCE formats have bug on
774 // GL core profile. See crbug.com/577144. Enable these formats after
775 // using workaround in gles2_cmd_copy_tex_image.cc.
776 // {GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE},
777 // {GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE},
778 // {GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE},
779
780 {GL_RGB, GL_RGB, GL_UNSIGNED_BYTE},
781 {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE},
782 {GL_SRGB_EXT, GL_SRGB_EXT, GL_UNSIGNED_BYTE},
783 {GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE},
784 {GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE},
785 {GL_BGRA8_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE},
786 {GL_R8, GL_RED, GL_UNSIGNED_BYTE},
787 {GL_R16F, GL_RED, GL_HALF_FLOAT},
788 {GL_R16F, GL_RED, GL_FLOAT},
789 {GL_R32F, GL_RED, GL_FLOAT},
790 {GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE},
791 {GL_RG8, GL_RG, GL_UNSIGNED_BYTE},
792 {GL_RG16F, GL_RG, GL_HALF_FLOAT},
793 {GL_RG16F, GL_RG, GL_FLOAT},
794 {GL_RG32F, GL_RG, GL_FLOAT},
795 {GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE},
796 {GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE},
797 {GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE},
798 {GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE},
799 {GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT},
800 {GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT},
801 {GL_RGB9_E5, GL_RGB, GL_FLOAT},
802 {GL_RGB16F, GL_RGB, GL_HALF_FLOAT},
803 {GL_RGB16F, GL_RGB, GL_FLOAT},
804 {GL_RGB32F, GL_RGB, GL_FLOAT},
805 {GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE},
806 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE},
807 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE},
808 {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE},
809 {GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE},
810 {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT},
811 {GL_RGBA16F, GL_RGBA, GL_FLOAT},
812 {GL_RGBA32F, GL_RGBA, GL_FLOAT},
813 {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE},
814 {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV},
815 };
816
817 for (auto src_format_type : src_format_types) {
818 for (auto dest_format_type : dest_format_types) {
819 if ((src_format_type.internal_format == GL_BGRA_EXT ||
820 src_format_type.internal_format == GL_BGRA8_EXT ||
821 dest_format_type.internal_format == GL_BGRA_EXT ||
822 dest_format_type.internal_format == GL_BGRA8_EXT) &&
823 ShouldSkipBGRA()) {
824 continue;
825 }
826 if (gles2::GLES2Util::IsFloatFormat(dest_format_type.internal_format) &&
827 ShouldSkipFloatFormat()) {
828 continue;
829 }
830 if ((dest_format_type.internal_format == GL_SRGB_EXT ||
831 dest_format_type.internal_format == GL_SRGB_ALPHA_EXT) &&
832 ShouldSkipSRGBEXT()) {
833 continue;
834 }
835 if ((src_format_type.internal_format == GL_R16_EXT ||
836 src_format_type.internal_format == GL_RG16_EXT ||
837 src_format_type.internal_format == GL_RGBA16_EXT) &&
838 ShouldSkipNorm16())
839 continue;
840 if (src_format_type.internal_format == GL_RGB10_A2 && ShouldSkipRGB10A2())
841 continue;
842 if (src_format_type.internal_format == GL_RGBA16_EXT &&
843 dest_format_type.internal_format == GL_RGB10_A2 &&
844 ShouldSkipRGBA16ToRGB10A2())
845 continue;
846
847 RunCopyTexture(GL_TEXTURE_2D, copy_type, src_format_type, 0,
848 dest_format_type, 0, true);
849 }
850 }
851 }
852
TEST_P(GLCopyTextureCHROMIUMTest,ImmutableTexture)853 TEST_P(GLCopyTextureCHROMIUMTest, ImmutableTexture) {
854 if (!GLTestHelper::HasExtension("GL_EXT_texture_storage")) {
855 LOG(INFO) << "GL_EXT_texture_storage not supported. Skipping test...";
856 return;
857 }
858 CopyType copy_type = GetParam();
859 GLenum src_internal_formats[] = {GL_RGB8_OES, GL_RGBA8_OES, GL_BGRA8_EXT};
860 GLenum dest_internal_formats[] = {GL_RGB8_OES, GL_RGBA8_OES, GL_BGRA8_EXT};
861
862 uint8_t pixels[1 * 4] = {255u, 0u, 255u, 255u};
863
864 for (auto src_internal_format : src_internal_formats) {
865 for (auto dest_internal_format : dest_internal_formats) {
866 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
867 glBindTexture(GL_TEXTURE_2D, textures_[0]);
868 glTexStorage2DEXT(GL_TEXTURE_2D, 1, src_internal_format, 1, 1);
869 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1,
870 ExtractFormatFrom(src_internal_format), GL_UNSIGNED_BYTE,
871 pixels);
872
873 glBindTexture(GL_TEXTURE_2D, textures_[1]);
874 glTexStorage2DEXT(GL_TEXTURE_2D, 1, dest_internal_format, 1, 1);
875 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
876 GL_TEXTURE_2D, textures_[1], 0);
877 EXPECT_TRUE(glGetError() == GL_NO_ERROR);
878
879 if (copy_type == TexImage) {
880 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
881 ExtractFormatFrom(dest_internal_format),
882 GL_UNSIGNED_BYTE, false, false, false);
883 EXPECT_TRUE(glGetError() == GL_INVALID_OPERATION);
884 } else {
885 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1],
886 0, 0, 0, 0, 0, 1, 1, false, false, false);
887 EXPECT_TRUE(glGetError() == GL_NO_ERROR);
888
889 // Check the FB is still bound.
890 GLint value = 0;
891 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
892 GLuint fb_id = value;
893 EXPECT_EQ(framebuffer_id_, fb_id);
894
895 // Check that FB is complete.
896 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
897 glCheckFramebufferStatus(GL_FRAMEBUFFER));
898
899 GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels, nullptr);
900 EXPECT_TRUE(GL_NO_ERROR == glGetError());
901 }
902 glDeleteTextures(2, textures_);
903 glDeleteFramebuffers(1, &framebuffer_id_);
904 }
905 }
906 }
907
TEST_P(GLCopyTextureCHROMIUMTest,InternalFormat)908 TEST_P(GLCopyTextureCHROMIUMTest, InternalFormat) {
909 CopyType copy_type = GetParam();
910 constexpr GLint src_formats[] = {
911 GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGRA_EXT};
912 constexpr GLint dest_formats[] = {GL_RGB, GL_RGBA, GL_BGRA_EXT};
913
914 for (const auto src_format : src_formats) {
915 for (const auto dst_format : dest_formats) {
916 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
917 glBindTexture(GL_TEXTURE_2D, textures_[0]);
918 glTexImage2D(GL_TEXTURE_2D, 0, src_format, 1, 1, 0, src_format,
919 GL_UNSIGNED_BYTE, nullptr);
920 EXPECT_TRUE(GL_NO_ERROR == glGetError());
921
922 if (copy_type == TexImage) {
923 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
924 dst_format, GL_UNSIGNED_BYTE, false, false,
925 false);
926 } else {
927 glBindTexture(GL_TEXTURE_2D, textures_[1]);
928 glTexImage2D(GL_TEXTURE_2D, 0, dst_format, 1, 1, 0, dst_format,
929 GL_UNSIGNED_BYTE, nullptr);
930 EXPECT_TRUE(GL_NO_ERROR == glGetError());
931
932 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1],
933 0, 0, 0, 0, 0, 1, 1, false, false, false);
934 }
935
936 EXPECT_TRUE(GL_NO_ERROR == glGetError())
937 << "src_format: " << gl::GLEnums::GetStringEnum(src_format)
938 << " dst_format: " << gl::GLEnums::GetStringEnum(dst_format);
939 glDeleteTextures(2, textures_);
940 glDeleteFramebuffers(1, &framebuffer_id_);
941 }
942 }
943 }
944
TEST_P(GLCopyTextureCHROMIUMTest,InternalFormatRGBFloat)945 TEST_P(GLCopyTextureCHROMIUMTest, InternalFormatRGBFloat) {
946 if (!GLTestHelper::HasExtension("GL_CHROMIUM_color_buffer_float_rgb")) {
947 LOG(INFO)
948 << "GL_CHROMIUM_color_buffer_float_rgb not supported. Skipping test...";
949 return;
950 }
951 // TODO(qiankun.miao@intel.com): since RunCopyTexture requires dest texture to
952 // be texture complete, skip this test if float texture is not color
953 // filterable. We should remove this limitation when we find a way doesn't
954 // require dest texture to be texture complete in RunCopyTexture.
955 if (!gl_.decoder()
956 ->GetFeatureInfo()
957 ->feature_flags()
958 .enable_texture_float_linear) {
959 LOG(INFO) << "RGB32F texture is not filterable. Skipping test...";
960 return;
961 }
962 CopyType copy_type = GetParam();
963 FormatType src_format_type = {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE};
964 FormatType dest_format_type = {GL_RGB32F, GL_RGB, GL_FLOAT};
965
966 RunCopyTexture(GL_TEXTURE_2D, copy_type, src_format_type, 0, dest_format_type,
967 0, false);
968 }
969
TEST_P(GLCopyTextureCHROMIUMTest,InternalFormatRGBAFloat)970 TEST_P(GLCopyTextureCHROMIUMTest, InternalFormatRGBAFloat) {
971 if (!GLTestHelper::HasExtension("GL_CHROMIUM_color_buffer_float_rgba")) {
972 LOG(INFO) << "GL_CHROMIUM_color_buffer_float_rgba not supported. Skipping "
973 "test...";
974 return;
975 }
976 // TODO(qiankun.miao@intel.com): since RunCopyTexture requires dest texture to
977 // be texture complete, skip this test if float texture is not color
978 // filterable. We should remove this limitation when we find a way doesn't
979 // require dest texture to be texture complete in RunCopyTexture.
980 if (!gl_.decoder()
981 ->GetFeatureInfo()
982 ->feature_flags()
983 .enable_texture_float_linear) {
984 LOG(INFO) << "RGBA32F texture is not filterable. Skipping test...";
985 return;
986 }
987 CopyType copy_type = GetParam();
988 FormatType src_format_type = {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE};
989 FormatType dest_format_type = {GL_RGBA32F, GL_RGBA, GL_FLOAT};
990
991 RunCopyTexture(GL_TEXTURE_2D, copy_type, src_format_type, 0, dest_format_type,
992 0, false);
993 }
994
TEST_P(GLCopyTextureCHROMIUMTest,InternalFormatNotSupported)995 TEST_P(GLCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
996 CopyType copy_type = GetParam();
997 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
998 glBindTexture(GL_TEXTURE_2D, textures_[0]);
999 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1000 nullptr);
1001 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1002
1003 // Check unsupported format reports error.
1004 GLint unsupported_dest_formats[] = {GL_RED, GL_RG};
1005 for (size_t dest_index = 0; dest_index < base::size(unsupported_dest_formats);
1006 dest_index++) {
1007 if (copy_type == TexImage) {
1008 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
1009 unsupported_dest_formats[dest_index],
1010 GL_UNSIGNED_BYTE, false, false, false);
1011 EXPECT_THAT(glGetError(),
1012 testing::AnyOf(GL_INVALID_VALUE, GL_INVALID_OPERATION))
1013 << "dest_index:" << dest_index;
1014 } else {
1015 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1016 glTexImage2D(GL_TEXTURE_2D, 0, unsupported_dest_formats[dest_index], 1, 1,
1017 0, unsupported_dest_formats[dest_index], GL_UNSIGNED_BYTE,
1018 nullptr);
1019 // clear GL_INVALID_ENUM error from glTexImage2D on ES2 devices
1020 glGetError();
1021 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
1022 0, 0, 0, 0, 1, 1, false, false, false);
1023 EXPECT_TRUE(GL_INVALID_OPERATION == glGetError())
1024 << "dest_index:" << dest_index;
1025 }
1026 }
1027 glDeleteTextures(2, textures_);
1028 glDeleteFramebuffers(1, &framebuffer_id_);
1029 }
1030
TEST_F(GLCopyTextureCHROMIUMTest,InternalFormatTypeCombinationNotSupported)1031 TEST_F(GLCopyTextureCHROMIUMTest, InternalFormatTypeCombinationNotSupported) {
1032 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1033 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1034 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1035 nullptr);
1036 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1037
1038 // Check unsupported internal_format/type combination reports error.
1039 struct FormatType { GLenum format, type; };
1040 FormatType unsupported_format_types[] = {
1041 {GL_RGB, GL_UNSIGNED_SHORT_4_4_4_4},
1042 {GL_RGB, GL_UNSIGNED_SHORT_5_5_5_1},
1043 {GL_RGBA, GL_UNSIGNED_SHORT_5_6_5},
1044 };
1045 for (size_t dest_index = 0; dest_index < base::size(unsupported_format_types);
1046 dest_index++) {
1047 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
1048 unsupported_format_types[dest_index].format,
1049 unsupported_format_types[dest_index].type, false,
1050 false, false);
1051 EXPECT_TRUE(GL_INVALID_OPERATION == glGetError())
1052 << "dest_index:" << dest_index;
1053 }
1054 glDeleteTextures(2, textures_);
1055 glDeleteFramebuffers(1, &framebuffer_id_);
1056 }
1057
TEST_P(GLCopyTextureCHROMIUMTest,CopyTextureLevel)1058 TEST_P(GLCopyTextureCHROMIUMTest, CopyTextureLevel) {
1059 CopyType copy_type = GetParam();
1060
1061 // Copy from RGB source texture to dest texture.
1062 FormatType src_format_type = {GL_RGB, GL_RGB, GL_UNSIGNED_BYTE};
1063 FormatType dest_format_types[] = {
1064 {GL_RGB, GL_RGB, GL_UNSIGNED_BYTE},
1065 {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE},
1066 };
1067 // Source level must be 0 in ES2 context.
1068 GLint source_level = 0;
1069
1070 for (GLint dest_level = 0; dest_level < 3; dest_level++) {
1071 for (auto dest_format_type : dest_format_types) {
1072 RunCopyTexture(GL_TEXTURE_2D, copy_type, src_format_type, source_level,
1073 dest_format_type, dest_level, false);
1074 }
1075 }
1076 }
1077
TEST_P(GLCopyTextureCHROMIUMES3Test,CopyTextureLevel)1078 TEST_P(GLCopyTextureCHROMIUMES3Test, CopyTextureLevel) {
1079 if (ShouldSkipTest())
1080 return;
1081 if (gl_.gpu_preferences().use_passthrough_cmd_decoder) {
1082 // TODO(geofflang): anglebug.com/1932
1083 LOG(INFO)
1084 << "Passthrough command decoder expected failure. Skipping test...";
1085 return;
1086 }
1087 CopyType copy_type = GetParam();
1088
1089 // Copy from RGBA source texture to dest texture.
1090 FormatType src_format_type = {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE};
1091 FormatType dest_format_types[] = {
1092 {GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE},
1093 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE},
1094 {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE},
1095 };
1096
1097 for (GLint source_level = 0; source_level < 3; source_level++) {
1098 for (GLint dest_level = 0; dest_level < 3; dest_level++) {
1099 for (auto dest_format_type : dest_format_types) {
1100 #if defined(OS_WIN) || defined(OS_ANDROID)
1101 // TODO(qiankun.miao@intel.com): source_level > 0 or dest_level > 0
1102 // isn't available due to renderinig bug for non-zero base level in
1103 // NVIDIA Windows: crbug.com/679639 and Android: crbug.com/680460.
1104 if (dest_level > 0)
1105 continue;
1106 #endif
1107 RunCopyTexture(GL_TEXTURE_2D, copy_type, src_format_type, source_level,
1108 dest_format_type, dest_level, true);
1109 }
1110 }
1111 }
1112 }
1113
TEST_P(GLCopyTextureCHROMIUMTest,CopyTextureCubeMap)1114 TEST_P(GLCopyTextureCHROMIUMTest, CopyTextureCubeMap) {
1115 CopyType copy_type = GetParam();
1116
1117 GLenum dest_targets[] = {
1118 GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
1119 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
1120 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
1121 FormatType src_format_type = {GL_RGB, GL_RGB, GL_UNSIGNED_BYTE};
1122 FormatType dest_format_types[] = {
1123 {GL_RGB, GL_RGB, GL_UNSIGNED_BYTE}, {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE},
1124 };
1125 GLint source_level = 0;
1126 GLint dest_level = 0;
1127
1128 for (auto dest_format_type : dest_format_types) {
1129 for (auto dest_target : dest_targets) {
1130 RunCopyTexture(dest_target, copy_type, src_format_type, source_level,
1131 dest_format_type, dest_level, false);
1132 }
1133 }
1134 }
1135
TEST_P(GLCopyTextureCHROMIUMES3Test,CopyTextureCubeMap)1136 TEST_P(GLCopyTextureCHROMIUMES3Test, CopyTextureCubeMap) {
1137 if (ShouldSkipTest())
1138 return;
1139 CopyType copy_type = GetParam();
1140
1141 GLenum dest_targets[] = {
1142 GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
1143 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
1144 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
1145 FormatType src_format_type = {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE};
1146 FormatType dest_format_types[] = {
1147 {GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE},
1148 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE},
1149 {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE},
1150 };
1151 GLint source_level = 0;
1152 GLint dest_level = 0;
1153
1154 for (auto dest_format_type : dest_format_types) {
1155 for (auto dest_target : dest_targets) {
1156 RunCopyTexture(dest_target, copy_type, src_format_type, source_level,
1157 dest_format_type, dest_level, true);
1158 }
1159 }
1160 }
1161
1162 // Test to ensure that the destination texture is redefined if the properties
1163 // are different.
TEST_F(GLCopyTextureCHROMIUMTest,RedefineDestinationTexture)1164 TEST_F(GLCopyTextureCHROMIUMTest, RedefineDestinationTexture) {
1165 uint8_t pixels[4 * 4] = {255u, 0u, 0u, 255u, 255u, 0u, 0u, 255u,
1166 255u, 0u, 0u, 255u, 255u, 0u, 0u, 255u};
1167
1168 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1169 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1170 glTexImage2D(
1171 GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1172
1173 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1174 glTexImage2D(GL_TEXTURE_2D,
1175 0,
1176 GL_BGRA_EXT,
1177 1,
1178 1,
1179 0,
1180 GL_BGRA_EXT,
1181 GL_UNSIGNED_BYTE,
1182 pixels);
1183 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1184
1185 // GL_INVALID_OPERATION due to "intrinsic format" != "internal format".
1186 glTexSubImage2D(
1187 GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1188 EXPECT_TRUE(GL_INVALID_OPERATION == glGetError());
1189 // GL_INVALID_VALUE due to bad dimensions.
1190 glTexSubImage2D(
1191 GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
1192 EXPECT_TRUE(GL_INVALID_VALUE == glGetError());
1193
1194 // If the dest texture has different properties, glCopyTextureCHROMIUM()
1195 // redefines them.
1196 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
1197 GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1198 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1199
1200 // glTexSubImage2D() succeeds because textures_[1] is redefined into 2x2
1201 // dimension and GL_RGBA format.
1202 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1203 glTexSubImage2D(
1204 GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1205 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1206
1207 // Check the FB is still bound.
1208 GLint value = 0;
1209 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
1210 GLuint fb_id = value;
1211 EXPECT_EQ(framebuffer_id_, fb_id);
1212
1213 // Check that FB is complete.
1214 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
1215 glCheckFramebufferStatus(GL_FRAMEBUFFER));
1216
1217 GLTestHelper::CheckPixels(1, 1, 1, 1, 0, &pixels[12], nullptr);
1218
1219 glDeleteTextures(2, textures_);
1220 glDeleteFramebuffers(1, &framebuffer_id_);
1221
1222 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1223 }
1224
1225 namespace {
1226
glEnableDisable(GLint param,GLboolean value)1227 void glEnableDisable(GLint param, GLboolean value) {
1228 if (value)
1229 glEnable(param);
1230 else
1231 glDisable(param);
1232 }
1233
1234 } // unnamed namespace
1235
1236 // Validate that some basic GL state is not touched upon execution of
1237 // the extension.
TEST_P(GLCopyTextureCHROMIUMTest,BasicStatePreservation)1238 TEST_P(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
1239 CopyType copy_type = GetParam();
1240 uint8_t pixels[1 * 4] = {255u, 0u, 0u, 255u};
1241
1242 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1243 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1244
1245 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1246 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1247 pixels);
1248
1249 if (copy_type == TexSubImage) {
1250 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1251 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1252 nullptr);
1253 }
1254
1255 GLboolean reference_settings[2] = { GL_TRUE, GL_FALSE };
1256 for (int x = 0; x < 2; ++x) {
1257 GLboolean setting = reference_settings[x];
1258 glEnableDisable(GL_DEPTH_TEST, setting);
1259 glEnableDisable(GL_SCISSOR_TEST, setting);
1260 glEnableDisable(GL_STENCIL_TEST, setting);
1261 glEnableDisable(GL_CULL_FACE, setting);
1262 glEnableDisable(GL_BLEND, setting);
1263 glColorMask(setting, setting, setting, setting);
1264 glDepthMask(setting);
1265
1266 glActiveTexture(GL_TEXTURE1 + x);
1267
1268 if (copy_type == TexImage) {
1269 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
1270 GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1271 } else {
1272 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
1273 0, 0, 0, 0, 1, 1, false, false, false);
1274 }
1275 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1276
1277 EXPECT_EQ(setting, glIsEnabled(GL_DEPTH_TEST));
1278 EXPECT_EQ(setting, glIsEnabled(GL_SCISSOR_TEST));
1279 EXPECT_EQ(setting, glIsEnabled(GL_STENCIL_TEST));
1280 EXPECT_EQ(setting, glIsEnabled(GL_CULL_FACE));
1281 EXPECT_EQ(setting, glIsEnabled(GL_BLEND));
1282
1283 GLboolean bool_array[4] = { GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE };
1284 glGetBooleanv(GL_DEPTH_WRITEMASK, bool_array);
1285 EXPECT_EQ(setting, bool_array[0]);
1286
1287 bool_array[0] = GL_FALSE;
1288 glGetBooleanv(GL_COLOR_WRITEMASK, bool_array);
1289 EXPECT_EQ(setting, bool_array[0]);
1290 EXPECT_EQ(setting, bool_array[1]);
1291 EXPECT_EQ(setting, bool_array[2]);
1292 EXPECT_EQ(setting, bool_array[3]);
1293
1294 GLint active_texture = 0;
1295 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
1296 EXPECT_EQ(GL_TEXTURE1 + x, active_texture);
1297 }
1298
1299 glDeleteTextures(2, textures_);
1300 glDeleteFramebuffers(1, &framebuffer_id_);
1301
1302 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1303 }
1304
TEST_P(GLCopyTextureCHROMIUMES3Test,SamplerStatePreserved)1305 TEST_P(GLCopyTextureCHROMIUMES3Test, SamplerStatePreserved) {
1306 if (ShouldSkipTest())
1307 return;
1308
1309 CopyType copy_type = GetParam();
1310 // Setup the texture used for the extension invocation.
1311 uint8_t pixels[1 * 4] = {255u, 0u, 0u, 255u};
1312 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1313 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1314 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1315 pixels);
1316
1317 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1318 if (copy_type == TexSubImage) {
1319 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1320 nullptr);
1321 }
1322
1323 GLuint sampler_id;
1324 glGenSamplers(1, &sampler_id);
1325 glBindSampler(0, sampler_id);
1326
1327 if (copy_type == TexImage) {
1328 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
1329 GL_RGBA, GL_UNSIGNED_BYTE, false, false, true);
1330 } else {
1331 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 0,
1332 0, 0, 0, 1, 1, false, false, true);
1333 }
1334 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1335
1336 GLint bound_sampler = 0;
1337 glGetIntegerv(GL_SAMPLER_BINDING, &bound_sampler);
1338 EXPECT_EQ(sampler_id, static_cast<GLuint>(bound_sampler));
1339
1340 glDeleteSamplers(1, &sampler_id);
1341 }
1342
1343 // Verify that invocation of the extension does not modify the bound
1344 // texture state.
TEST_P(GLCopyTextureCHROMIUMTest,TextureStatePreserved)1345 TEST_P(GLCopyTextureCHROMIUMTest, TextureStatePreserved) {
1346 CopyType copy_type = GetParam();
1347 // Setup the texture used for the extension invocation.
1348 uint8_t pixels[1 * 4] = {255u, 0u, 0u, 255u};
1349 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1350 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1351 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1352 pixels);
1353
1354 if (copy_type == TexSubImage) {
1355 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1356 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1357 nullptr);
1358 }
1359
1360 GLuint texture_ids[2];
1361 glGenTextures(2, texture_ids);
1362
1363 glActiveTexture(GL_TEXTURE0);
1364 glBindTexture(GL_TEXTURE_2D, texture_ids[0]);
1365
1366 glActiveTexture(GL_TEXTURE1);
1367 glBindTexture(GL_TEXTURE_2D, texture_ids[1]);
1368
1369 if (copy_type == TexImage) {
1370 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
1371 GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1372 } else {
1373 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 0,
1374 0, 0, 0, 1, 1, false, false, false);
1375 }
1376 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1377
1378 GLint active_texture = 0;
1379 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
1380 EXPECT_EQ(GL_TEXTURE1, active_texture);
1381
1382 GLint bound_texture = 0;
1383 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
1384 EXPECT_EQ(texture_ids[1], static_cast<GLuint>(bound_texture));
1385 glBindTexture(GL_TEXTURE_2D, 0);
1386
1387 bound_texture = 0;
1388 glActiveTexture(GL_TEXTURE0);
1389 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
1390 EXPECT_EQ(texture_ids[0], static_cast<GLuint>(bound_texture));
1391 glBindTexture(GL_TEXTURE_2D, 0);
1392
1393 glDeleteTextures(2, texture_ids);
1394 glDeleteTextures(2, textures_);
1395 glDeleteFramebuffers(1, &framebuffer_id_);
1396
1397 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1398 }
1399
1400 // Verify that invocation of the extension does not perturb the currently
1401 // bound FBO state.
TEST_P(GLCopyTextureCHROMIUMTest,FBOStatePreserved)1402 TEST_P(GLCopyTextureCHROMIUMTest, FBOStatePreserved) {
1403 CopyType copy_type = GetParam();
1404 // Setup the texture used for the extension invocation.
1405 uint8_t pixels[1 * 4] = {255u, 0u, 0u, 255u};
1406 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1407 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1408 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1409 pixels);
1410
1411 if (copy_type == TexSubImage) {
1412 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1413 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1414 nullptr);
1415 }
1416
1417 GLuint texture_id;
1418 glGenTextures(1, &texture_id);
1419 glBindTexture(GL_TEXTURE_2D, texture_id);
1420 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1421 0);
1422
1423 GLuint renderbuffer_id;
1424 glGenRenderbuffers(1, &renderbuffer_id);
1425 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_id);
1426 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 1, 1);
1427
1428 GLuint framebuffer_id;
1429 glGenFramebuffers(1, &framebuffer_id);
1430 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id);
1431 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1432 texture_id, 0);
1433 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
1434 GL_RENDERBUFFER, renderbuffer_id);
1435 EXPECT_TRUE(
1436 GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER));
1437
1438 // Test that we can write to the bound framebuffer
1439 uint8_t expected_color[4] = {255u, 255u, 0, 255u};
1440 glClearColor(1.0, 1.0, 0, 1.0);
1441 glClear(GL_COLOR_BUFFER_BIT);
1442 GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color, nullptr);
1443
1444 if (copy_type == TexImage) {
1445 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
1446 GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1447 } else {
1448 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 0,
1449 0, 0, 0, 1, 1, false, false, false);
1450 }
1451 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1452
1453 EXPECT_TRUE(glIsFramebuffer(framebuffer_id));
1454
1455 // Ensure that reading from the framebuffer produces correct pixels.
1456 GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color, nullptr);
1457
1458 uint8_t expected_color2[4] = {255u, 0, 255u, 255u};
1459 glClearColor(1.0, 0, 1.0, 1.0);
1460 glClear(GL_COLOR_BUFFER_BIT);
1461 GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color2, nullptr);
1462
1463 GLint bound_fbo = 0;
1464 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
1465 EXPECT_EQ(framebuffer_id, static_cast<GLuint>(bound_fbo));
1466
1467 GLint fbo_params = 0;
1468 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1469 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
1470 &fbo_params);
1471 EXPECT_EQ(GL_TEXTURE, fbo_params);
1472
1473 fbo_params = 0;
1474 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1475 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
1476 &fbo_params);
1477 EXPECT_EQ(texture_id, static_cast<GLuint>(fbo_params));
1478
1479 fbo_params = 0;
1480 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
1481 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
1482 &fbo_params);
1483 EXPECT_EQ(GL_RENDERBUFFER, fbo_params);
1484
1485 fbo_params = 0;
1486 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
1487 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
1488 &fbo_params);
1489 EXPECT_EQ(renderbuffer_id, static_cast<GLuint>(fbo_params));
1490
1491 glDeleteRenderbuffers(1, &renderbuffer_id);
1492 glDeleteTextures(1, &texture_id);
1493 glDeleteFramebuffers(1, &framebuffer_id);
1494 glDeleteTextures(2, textures_);
1495 glDeleteFramebuffers(1, &framebuffer_id_);
1496
1497 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1498 }
1499
TEST_P(GLCopyTextureCHROMIUMTest,ProgramStatePreservation)1500 TEST_P(GLCopyTextureCHROMIUMTest, ProgramStatePreservation) {
1501 CopyType copy_type = GetParam();
1502 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1503 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1504 glBindTexture(GL_TEXTURE_2D, 0);
1505
1506 GLManager gl2;
1507 GLManager::Options options;
1508 options.size = gfx::Size(16, 16);
1509 options.share_group_manager = &gl_;
1510 gl2.Initialize(options);
1511 gl_.MakeCurrent();
1512
1513 static const char* v_shader_str =
1514 "attribute vec4 g_Position;\n"
1515 "void main()\n"
1516 "{\n"
1517 " gl_Position = g_Position;\n"
1518 "}\n";
1519 static const char* f_shader_str =
1520 "precision mediump float;\n"
1521 "void main()\n"
1522 "{\n"
1523 " gl_FragColor = vec4(0,1,0,1);\n"
1524 "}\n";
1525
1526 GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
1527 glUseProgram(program);
1528 GLuint position_loc = glGetAttribLocation(program, "g_Position");
1529 glFlush();
1530
1531 // Delete program from other context.
1532 gl2.MakeCurrent();
1533 glDeleteProgram(program);
1534 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1535 glFlush();
1536
1537 // Program should still be usable on this context.
1538 gl_.MakeCurrent();
1539
1540 GLTestHelper::SetupUnitQuad(position_loc);
1541
1542 // test using program before
1543 uint8_t expected[] = {
1544 0, 255, 0, 255,
1545 };
1546 uint8_t zero[] = {
1547 0, 0, 0, 0,
1548 };
1549 glClear(GL_COLOR_BUFFER_BIT);
1550 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero, nullptr));
1551 glDrawArrays(GL_TRIANGLES, 0, 6);
1552 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected, nullptr));
1553
1554 // Call copyTextureCHROMIUM
1555 uint8_t pixels[1 * 4] = {255u, 0u, 0u, 255u};
1556 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1557 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1558 pixels);
1559 if (copy_type == TexImage) {
1560 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
1561 GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1562 } else {
1563 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1564 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1565 nullptr);
1566 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 0,
1567 0, 0, 0, 1, 1, false, false, false);
1568 }
1569
1570 // test using program after
1571 glClear(GL_COLOR_BUFFER_BIT);
1572 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero, nullptr));
1573 glDrawArrays(GL_TRIANGLES, 0, 6);
1574 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected, nullptr));
1575
1576 glDeleteTextures(2, textures_);
1577 glDeleteFramebuffers(1, &framebuffer_id_);
1578
1579 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1580
1581 gl2.MakeCurrent();
1582 gl2.Destroy();
1583 gl_.MakeCurrent();
1584 }
1585
1586 // Test that glCopyTextureCHROMIUM doesn't leak uninitialized textures.
TEST_P(GLCopyTextureCHROMIUMTest,UninitializedSource)1587 TEST_P(GLCopyTextureCHROMIUMTest, UninitializedSource) {
1588 CopyType copy_type = GetParam();
1589 const GLsizei kWidth = 64, kHeight = 64;
1590 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1591 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1592 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
1593 GL_UNSIGNED_BYTE, nullptr);
1594
1595 if (copy_type == TexImage) {
1596 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
1597 GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1598 } else {
1599 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1600 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
1601 GL_UNSIGNED_BYTE, nullptr);
1602 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 0,
1603 0, 0, 0, kWidth, kHeight, false, false, false);
1604 }
1605 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1606
1607 uint8_t pixels[kHeight][kWidth][4] = {{{1}}};
1608 glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1609 for (int x = 0; x < kWidth; ++x) {
1610 for (int y = 0; y < kHeight; ++y) {
1611 EXPECT_EQ(0, pixels[y][x][0]);
1612 EXPECT_EQ(0, pixels[y][x][1]);
1613 EXPECT_EQ(0, pixels[y][x][2]);
1614 EXPECT_EQ(0, pixels[y][x][3]);
1615 }
1616 }
1617
1618 glDeleteTextures(2, textures_);
1619 glDeleteFramebuffers(1, &framebuffer_id_);
1620
1621 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1622 }
1623
TEST_F(GLCopyTextureCHROMIUMTest,CopySubTextureDimension)1624 TEST_F(GLCopyTextureCHROMIUMTest, CopySubTextureDimension) {
1625 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1626 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1627 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1628 nullptr);
1629
1630 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1631 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1632 nullptr);
1633
1634 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 1,
1635 1, 0, 0, 1, 1, false, false, false);
1636 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1637
1638 // xoffset < 0
1639 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, -1,
1640 1, 0, 0, 1, 1, false, false, false);
1641 EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
1642
1643 // x < 0
1644 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 1,
1645 1, -1, 0, 1, 1, false, false, false);
1646 EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
1647
1648 // xoffset + width > dest_width
1649 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 2,
1650 2, 0, 0, 2, 2, false, false, false);
1651 EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
1652
1653 // x + width > source_width
1654 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 0,
1655 0, 1, 1, 2, 2, false, false, false);
1656 EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
1657
1658 glDeleteTextures(2, textures_);
1659 glDeleteFramebuffers(1, &framebuffer_id_);
1660 }
1661
TEST_F(GLCopyTextureCHROMIUMTest,CopyTextureInvalidTextureIds)1662 TEST_F(GLCopyTextureCHROMIUMTest, CopyTextureInvalidTextureIds) {
1663 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1664 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1665 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1666 nullptr);
1667
1668 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1669 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1670 nullptr);
1671
1672 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, 99993, 0, GL_RGBA,
1673 GL_UNSIGNED_BYTE, false, false, false);
1674 EXPECT_TRUE(GL_INVALID_VALUE == glGetError());
1675
1676 glCopyTextureCHROMIUM(99994, 0, GL_TEXTURE_2D, textures_[1], 0, GL_RGBA,
1677 GL_UNSIGNED_BYTE, false, false, false);
1678 EXPECT_TRUE(GL_INVALID_VALUE == glGetError());
1679
1680 glCopyTextureCHROMIUM(99995, 0, GL_TEXTURE_2D, 99996, 0, GL_RGBA,
1681 GL_UNSIGNED_BYTE, false, false, false);
1682 EXPECT_TRUE(GL_INVALID_VALUE == glGetError());
1683
1684 glCopyTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0,
1685 GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1686 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1687
1688 glDeleteTextures(2, textures_);
1689 glDeleteFramebuffers(1, &framebuffer_id_);
1690 }
1691
TEST_F(GLCopyTextureCHROMIUMTest,CopySubTextureInvalidTextureIds)1692 TEST_F(GLCopyTextureCHROMIUMTest, CopySubTextureInvalidTextureIds) {
1693 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1694 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1695 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1696 nullptr);
1697
1698 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1699 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1700 nullptr);
1701
1702 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, 99993, 0, 1, 1, 0, 0,
1703 1, 1, false, false, false);
1704 EXPECT_TRUE(GL_INVALID_VALUE == glGetError());
1705
1706 glCopySubTextureCHROMIUM(99994, 0, GL_TEXTURE_2D, textures_[1], 0, 1, 1, 0, 0,
1707 1, 1, false, false, false);
1708 EXPECT_TRUE(GL_INVALID_VALUE == glGetError());
1709
1710 glCopySubTextureCHROMIUM(99995, 0, GL_TEXTURE_2D, 99996, 0, 1, 1, 0, 0, 1, 1,
1711 false, false, false);
1712 EXPECT_TRUE(GL_INVALID_VALUE == glGetError());
1713
1714 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 1,
1715 1, 0, 0, 1, 1, false, false, false);
1716 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1717
1718 glDeleteTextures(2, textures_);
1719 glDeleteFramebuffers(1, &framebuffer_id_);
1720 }
1721
TEST_F(GLCopyTextureCHROMIUMTest,CopySubTextureOffset)1722 TEST_F(GLCopyTextureCHROMIUMTest, CopySubTextureOffset) {
1723 uint8_t rgba_pixels[4 * 4] = {255u, 0u, 0u, 255u, 0u, 255u, 0u, 255u,
1724 0u, 0u, 255u, 255u, 0u, 0u, 0u, 255u};
1725 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1726 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1727 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1728 rgba_pixels);
1729
1730 uint8_t transparent_pixels[4 * 4] = {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
1731 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u};
1732 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1733 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1734 transparent_pixels);
1735
1736 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 1,
1737 1, 0, 0, 1, 1, false, false, false);
1738 EXPECT_TRUE(glGetError() == GL_NO_ERROR);
1739 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 1,
1740 0, 1, 0, 1, 1, false, false, false);
1741 EXPECT_TRUE(glGetError() == GL_NO_ERROR);
1742 glCopySubTextureCHROMIUM(textures_[0], 0, GL_TEXTURE_2D, textures_[1], 0, 0,
1743 1, 0, 1, 1, 1, false, false, false);
1744 EXPECT_TRUE(glGetError() == GL_NO_ERROR);
1745
1746 // Check the FB is still bound.
1747 GLint value = 0;
1748 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
1749 GLuint fb_id = value;
1750 EXPECT_EQ(framebuffer_id_, fb_id);
1751
1752 // Check that FB is complete.
1753 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
1754 glCheckFramebufferStatus(GL_FRAMEBUFFER));
1755
1756 uint8_t transparent[1 * 4] = {0u, 0u, 0u, 0u};
1757 uint8_t red[1 * 4] = {255u, 0u, 0u, 255u};
1758 uint8_t green[1 * 4] = {0u, 255u, 0u, 255u};
1759 uint8_t blue[1 * 4] = {0u, 0u, 255u, 255u};
1760 GLTestHelper::CheckPixels(0, 0, 1, 1, 0, transparent, nullptr);
1761 GLTestHelper::CheckPixels(1, 1, 1, 1, 0, red, nullptr);
1762 GLTestHelper::CheckPixels(1, 0, 1, 1, 0, green, nullptr);
1763 GLTestHelper::CheckPixels(0, 1, 1, 1, 0, blue, nullptr);
1764 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1765
1766 glDeleteTextures(2, textures_);
1767 glDeleteFramebuffers(1, &framebuffer_id_);
1768 }
1769
TEST_F(GLCopyTextureCHROMIUMTest,CopyTextureBetweenTexture2DAndRectangleArb)1770 TEST_F(GLCopyTextureCHROMIUMTest, CopyTextureBetweenTexture2DAndRectangleArb) {
1771 if (!GLTestHelper::HasExtension("GL_ARB_texture_rectangle")) {
1772 LOG(INFO) <<
1773 "GL_ARB_texture_rectangle not supported. Skipping test...";
1774 return;
1775 }
1776
1777 GLenum src_targets[] = {GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_2D};
1778 GLenum dest_targets[] = {GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_2D};
1779 GLsizei src_width = 30;
1780 GLsizei src_height = 14;
1781 GLsizei dest_width = 15;
1782 GLsizei dest_height = 13;
1783 GLsizei copy_region_x = 1;
1784 GLsizei copy_region_y = 1;
1785 GLsizei copy_region_width = 5;
1786 GLsizei copy_region_height = 3;
1787 uint8_t red[1 * 4] = {255u, 0u, 0u, 255u};
1788 uint8_t blue[1 * 4] = {0u, 0u, 255u, 255u};
1789 uint8_t green[1 * 4] = {0u, 255u, 0, 255u};
1790 uint8_t white[1 * 4] = {255u, 255u, 255u, 255u};
1791 uint8_t grey[1 * 4] = {199u, 199u, 199u, 255u};
1792
1793 for (size_t src_index = 0; src_index < base::size(src_targets); src_index++) {
1794 GLenum src_target = src_targets[src_index];
1795 for (size_t dest_index = 0; dest_index < base::size(dest_targets);
1796 dest_index++) {
1797 GLenum dest_target = dest_targets[dest_index];
1798
1799 CreateAndBindDestinationTextureAndFBO(dest_target);
1800
1801 // Allocate source and destination textures.
1802 glBindTexture(src_target, textures_[0]);
1803 CreateBackingForTexture(src_target, src_width, src_height);
1804
1805 glBindTexture(dest_target, textures_[1]);
1806 CreateBackingForTexture(dest_target, dest_width, dest_height);
1807
1808 // The bottom left is red, bottom right is blue, top left is green, top
1809 // right is white.
1810 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, src_target,
1811 textures_[0], 0);
1812 glBindTexture(src_target, textures_[0]);
1813 for (GLint x = 0; x < src_width; ++x) {
1814 for (GLint y = 0; y < src_height; ++y) {
1815 uint8_t* data;
1816 if (x < src_width / 2) {
1817 data = y < src_height / 2 ? red : green;
1818 } else {
1819 data = y < src_height / 2 ? blue : white;
1820 }
1821 glTexSubImage2D(src_target, 0, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1822 data);
1823 }
1824 }
1825
1826 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target,
1827 textures_[1], 0);
1828 glBindTexture(dest_target, textures_[1]);
1829
1830 // Copy the subtexture x=[13,18) y=[6,9) to the destination.
1831 glClearColor(grey[0] / 255.f, grey[1] / 255.f, grey[2] / 255.f, 1.0);
1832 glClear(GL_COLOR_BUFFER_BIT);
1833 glCopySubTextureCHROMIUM(textures_[0], 0, dest_target, textures_[1], 0,
1834 copy_region_x, copy_region_y, 13, 6,
1835 copy_region_width, copy_region_height, false,
1836 false, false);
1837 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1838
1839 for (GLint x = 0; x < dest_width; ++x) {
1840 for (GLint y = 0; y < dest_height; ++y) {
1841 if (x < copy_region_x || x >= copy_region_x + copy_region_width ||
1842 y < copy_region_y || y >= copy_region_y + copy_region_height) {
1843 GLTestHelper::CheckPixels(x, y, 1, 1, 0, grey, nullptr);
1844 continue;
1845 }
1846
1847 uint8_t* expected_color;
1848 if (x < copy_region_x + 2) {
1849 expected_color = y < copy_region_y + 1 ? red : green;
1850 } else {
1851 expected_color = y < copy_region_y + 1 ? blue : white;
1852 }
1853 GLTestHelper::CheckPixels(x, y, 1, 1, 0, expected_color, nullptr);
1854 }
1855 }
1856
1857 glDeleteTextures(2, textures_);
1858 glDeleteFramebuffers(1, &framebuffer_id_);
1859 }
1860 }
1861 }
1862
TEST_F(GLCopyTextureCHROMIUMTest,UnpremultiplyAndDitherCopy)1863 TEST_F(GLCopyTextureCHROMIUMTest, UnpremultiplyAndDitherCopy) {
1864 if (gl_.gpu_preferences().use_passthrough_cmd_decoder) {
1865 // UnpremultiplyAndDitherCopyCHROMIUM is not supported on passthrough.
1866 return;
1867 }
1868
1869 uint8_t premul_undithered_rgba_pixels[4 * 4] = {
1870 64u, 0u, 0u, 128u, 0u, 128u, 0u, 255u,
1871 0u, 0u, 64u, 255u, 0u, 0u, 0u, 128u};
1872 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1873 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1874 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1875 premul_undithered_rgba_pixels);
1876
1877 uint16_t transparent_pixels[4] = {0u, 0u, 0u, 0u};
1878 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1879 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA,
1880 GL_UNSIGNED_SHORT_4_4_4_4, transparent_pixels);
1881
1882 glUnpremultiplyAndDitherCopyCHROMIUM(textures_[0], textures_[1], 0, 0, 2, 2);
1883 EXPECT_TRUE(glGetError() == GL_NO_ERROR);
1884
1885 uint8_t pixel_0_0[4] = {135u, 8u, 8u, 136u};
1886 GLTestHelper::CheckPixels(0, 0, 1, 1, 17, pixel_0_0, nullptr);
1887 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1888
1889 uint8_t pixel_1_0[4] = {0u, 127u, 0u, 255u};
1890 GLTestHelper::CheckPixels(1, 0, 1, 1, 17, pixel_1_0, nullptr);
1891 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1892
1893 uint8_t pixel_0_1[4] = {4u, 4u, 68u, 255u};
1894 GLTestHelper::CheckPixels(0, 1, 1, 1, 17, pixel_0_1, nullptr);
1895 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1896
1897 uint8_t pixel_1_1[4] = {0u, 0u, 0u, 123u};
1898 GLTestHelper::CheckPixels(1, 1, 1, 1, 17, pixel_1_1, nullptr);
1899 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1900
1901 glDeleteTextures(2, textures_);
1902 glDeleteFramebuffers(1, &framebuffer_id_);
1903 }
1904
TEST_F(GLCopyTextureCHROMIUMTest,UnpremultiplyAndDitherCopySubrect)1905 TEST_F(GLCopyTextureCHROMIUMTest, UnpremultiplyAndDitherCopySubrect) {
1906 if (gl_.gpu_preferences().use_passthrough_cmd_decoder) {
1907 // UnpremultiplyAndDitherCopyCHROMIUM is not supported on passthrough.
1908 return;
1909 }
1910
1911 uint8_t premul_undithered_rgba_pixels[4 * 4] = {
1912 64u, 0u, 0u, 128u, 0u, 128u, 0u, 255u,
1913 0u, 0u, 64u, 255u, 0u, 0u, 0u, 128u};
1914 CreateAndBindDestinationTextureAndFBO(GL_TEXTURE_2D);
1915 glBindTexture(GL_TEXTURE_2D, textures_[0]);
1916 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1917 premul_undithered_rgba_pixels);
1918
1919 uint16_t transparent_pixels[4] = {0u, 0u, 0u, 0u};
1920 glBindTexture(GL_TEXTURE_2D, textures_[1]);
1921 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA,
1922 GL_UNSIGNED_SHORT_4_4_4_4, transparent_pixels);
1923
1924 glUnpremultiplyAndDitherCopyCHROMIUM(textures_[0], textures_[1], 1, 0, 1, 2);
1925 EXPECT_TRUE(glGetError() == GL_NO_ERROR);
1926
1927 uint8_t pixel_0_0[4] = {0u, 0u, 0u, 0u};
1928 GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixel_0_0, nullptr);
1929 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1930
1931 uint8_t pixel_1_0[4] = {0u, 127u, 0u, 255u};
1932 GLTestHelper::CheckPixels(1, 0, 1, 1, 17, pixel_1_0, nullptr);
1933 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1934
1935 uint8_t pixel_0_1[4] = {0u, 0u, 0u, 0u};
1936 GLTestHelper::CheckPixels(0, 1, 1, 1, 0, pixel_0_1, nullptr);
1937 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1938
1939 uint8_t pixel_1_1[4] = {0u, 0u, 0u, 123u};
1940 GLTestHelper::CheckPixels(1, 1, 1, 1, 17, pixel_1_1, nullptr);
1941 EXPECT_TRUE(GL_NO_ERROR == glGetError());
1942
1943 glDeleteTextures(2, textures_);
1944 glDeleteFramebuffers(1, &framebuffer_id_);
1945 }
1946
1947 } // namespace gpu
1948