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