• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // CopyTextureTest.cpp: Tests of the GL_CHROMIUM_copy_texture extension
8 
9 #include "test_utils/ANGLETest.h"
10 
11 #include "test_utils/gl_raii.h"
12 
13 namespace angle
14 {
15 
16 class CopyTextureTest : public ANGLETest
17 {
18   protected:
CopyTextureTest()19     CopyTextureTest()
20     {
21         setWindowWidth(256);
22         setWindowHeight(256);
23         setConfigRedBits(8);
24         setConfigGreenBits(8);
25         setConfigBlueBits(8);
26         setConfigAlphaBits(8);
27     }
28 
testSetUp()29     void testSetUp() override
30     {
31         glGenTextures(2, mTextures);
32         glBindTexture(GL_TEXTURE_2D, mTextures[1]);
33 
34         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
35         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
36         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
37         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
38 
39         glGenFramebuffers(1, &mFramebuffer);
40         glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
41         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
42                                0);
43     }
44 
testTearDown()45     void testTearDown() override
46     {
47         glDeleteTextures(2, mTextures);
48         glDeleteFramebuffers(1, &mFramebuffer);
49     }
50 
checkExtensions() const51     bool checkExtensions() const
52     {
53         if (!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"))
54         {
55             std::cout << "Test skipped because GL_CHROMIUM_copy_texture is not available."
56                       << std::endl;
57             return false;
58         }
59 
60         EXPECT_NE(nullptr, glCopyTextureCHROMIUM);
61         EXPECT_NE(nullptr, glCopySubTextureCHROMIUM);
62         return true;
63     }
64 
testGradientDownsampleUniqueValues(GLenum destFormat,GLenum destType,const std::array<size_t,4> & expectedUniqueValues)65     void testGradientDownsampleUniqueValues(GLenum destFormat,
66                                             GLenum destType,
67                                             const std::array<size_t, 4> &expectedUniqueValues)
68     {
69         std::array<GLColor, 256> sourceGradient;
70         for (size_t i = 0; i < sourceGradient.size(); i++)
71         {
72             GLubyte value     = static_cast<GLubyte>(i);
73             sourceGradient[i] = GLColor(value, value, value, value);
74         }
75         GLTexture sourceTexture;
76         glBindTexture(GL_TEXTURE_2D, sourceTexture);
77         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
78                      sourceGradient.data());
79 
80         GLTexture destTexture;
81         glBindTexture(GL_TEXTURE_2D, destTexture);
82         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destFormat, destType,
83                               GL_FALSE, GL_FALSE, GL_FALSE);
84         EXPECT_GL_NO_ERROR();
85 
86         GLFramebuffer fbo;
87         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
88         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destTexture, 0);
89 
90         std::array<GLColor, 256> destData;
91         glReadPixels(0, 0, 256, 1, GL_RGBA, GL_UNSIGNED_BYTE, destData.data());
92         EXPECT_GL_NO_ERROR();
93 
94         std::set<GLubyte> uniqueValues[4];
95         for (size_t i = 0; i < destData.size(); i++)
96         {
97             GLColor color = destData[i];
98             uniqueValues[0].insert(color.R);
99             uniqueValues[1].insert(color.G);
100             uniqueValues[2].insert(color.B);
101             uniqueValues[3].insert(color.A);
102         }
103 
104         EXPECT_EQ(expectedUniqueValues[0], uniqueValues[0].size());
105         EXPECT_EQ(expectedUniqueValues[1], uniqueValues[1].size());
106         EXPECT_EQ(expectedUniqueValues[2], uniqueValues[2].size());
107         EXPECT_EQ(expectedUniqueValues[3], uniqueValues[3].size());
108     }
109 
110     GLuint mTextures[2] = {
111         0,
112         0,
113     };
114     GLuint mFramebuffer = 0;
115 };
116 
117 using CopyTextureVariationsTestParams =
118     std::tuple<angle::PlatformParameters, GLenum, GLenum, bool, bool, bool>;
119 
CopyTextureVariationsTestPrint(const::testing::TestParamInfo<CopyTextureVariationsTestParams> & paramsInfo)120 std::string CopyTextureVariationsTestPrint(
121     const ::testing::TestParamInfo<CopyTextureVariationsTestParams> &paramsInfo)
122 {
123     const CopyTextureVariationsTestParams &params = paramsInfo.param;
124     std::ostringstream out;
125 
126     out << std::get<0>(params) << '_';
127 
128     switch (std::get<1>(params))
129     {
130         case GL_ALPHA:
131             out << "A";
132             break;
133         case GL_RGB:
134             out << "RGB";
135             break;
136         case GL_RGBA:
137             out << "RGBA";
138             break;
139         case GL_LUMINANCE:
140             out << "L";
141             break;
142         case GL_LUMINANCE_ALPHA:
143             out << "LA";
144             break;
145         case GL_BGRA_EXT:
146             out << "BGRA";
147             break;
148         default:
149             out << "UPDATE_THIS_SWITCH";
150     }
151 
152     out << "To";
153 
154     switch (std::get<2>(params))
155     {
156         case GL_RGB:
157             out << "RGB";
158             break;
159         case GL_RGBA:
160             out << "RGBA";
161             break;
162         case GL_BGRA_EXT:
163             out << "BGRA";
164             break;
165         default:
166             out << "UPDATE_THIS_SWITCH";
167     }
168 
169     if (std::get<3>(params))
170     {
171         out << "FlipY";
172     }
173     if (std::get<4>(params))
174     {
175         out << "PremultiplyAlpha";
176     }
177     if (std::get<5>(params))
178     {
179         out << "UnmultiplyAlpha";
180     }
181 
182     return out.str();
183 }
184 
185 class CopyTextureVariationsTest : public ANGLETestWithParam<CopyTextureVariationsTestParams>
186 {
187   protected:
CopyTextureVariationsTest()188     CopyTextureVariationsTest()
189     {
190         setWindowWidth(256);
191         setWindowHeight(256);
192         setConfigRedBits(8);
193         setConfigGreenBits(8);
194         setConfigBlueBits(8);
195         setConfigAlphaBits(8);
196     }
197 
testSetUp()198     void testSetUp() override
199     {
200         glGenTextures(2, mTextures);
201         glBindTexture(GL_TEXTURE_2D, mTextures[1]);
202 
203         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
204         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
205         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
206         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
207 
208         glGenFramebuffers(1, &mFramebuffer);
209         glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
210         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
211                                0);
212     }
213 
testTearDown()214     void testTearDown() override
215     {
216         glDeleteTextures(2, mTextures);
217         glDeleteFramebuffers(1, &mFramebuffer);
218     }
219 
checkExtensions(GLenum sourceFormat,GLenum destFormat) const220     bool checkExtensions(GLenum sourceFormat, GLenum destFormat) const
221     {
222         if (!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"))
223         {
224             std::cout << "Test skipped because GL_CHROMIUM_copy_texture is not available."
225                       << std::endl;
226             return false;
227         }
228 
229         if ((sourceFormat == GL_BGRA_EXT || destFormat == GL_BGRA_EXT) &&
230             !IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
231         {
232             return false;
233         }
234 
235         return true;
236     }
237 
calculateCopyTextureResults(GLenum sourceFormat,GLenum destFormat,bool premultiplyAlpha,bool unmultiplyAlpha,const uint8_t * sourceColor,GLColor * destColor)238     void calculateCopyTextureResults(GLenum sourceFormat,
239                                      GLenum destFormat,
240                                      bool premultiplyAlpha,
241                                      bool unmultiplyAlpha,
242                                      const uint8_t *sourceColor,
243                                      GLColor *destColor)
244     {
245         GLColor color;
246 
247         switch (sourceFormat)
248         {
249             case GL_RGB:
250                 color = GLColor(sourceColor[0], sourceColor[1], sourceColor[2], 255);
251                 break;
252             case GL_RGBA:
253                 color = GLColor(sourceColor[0], sourceColor[1], sourceColor[2], sourceColor[3]);
254                 break;
255             case GL_LUMINANCE:
256                 color = GLColor(sourceColor[0], sourceColor[0], sourceColor[0], 255);
257                 break;
258             case GL_ALPHA:
259                 color = GLColor(0, 0, 0, sourceColor[0]);
260                 break;
261             case GL_LUMINANCE_ALPHA:
262                 color = GLColor(sourceColor[0], sourceColor[0], sourceColor[0], sourceColor[1]);
263                 break;
264             case GL_BGRA_EXT:
265                 color = GLColor(sourceColor[2], sourceColor[1], sourceColor[0], sourceColor[3]);
266                 break;
267             default:
268                 EXPECT_EQ(true, false);
269         }
270 
271         if (premultiplyAlpha != unmultiplyAlpha)
272         {
273             float alpha = color.A / 255.0f;
274             if (premultiplyAlpha)
275             {
276                 color.R = static_cast<GLubyte>(static_cast<float>(color.R) * alpha);
277                 color.G = static_cast<GLubyte>(static_cast<float>(color.G) * alpha);
278                 color.B = static_cast<GLubyte>(static_cast<float>(color.B) * alpha);
279             }
280             else if (unmultiplyAlpha && color.A != 0)
281             {
282                 color.R = static_cast<GLubyte>(static_cast<float>(color.R) / alpha);
283                 color.G = static_cast<GLubyte>(static_cast<float>(color.G) / alpha);
284                 color.B = static_cast<GLubyte>(static_cast<float>(color.B) / alpha);
285             }
286         }
287 
288         switch (destFormat)
289         {
290             case GL_RGB:
291                 color.A = 255;
292                 break;
293             case GL_RGBA:
294             case GL_BGRA_EXT:
295                 break;
296             default:
297                 EXPECT_EQ(true, false);
298         }
299 
300         *destColor = color;
301     }
302 
getSourceColors(GLenum sourceFormat,size_t * colorCount,uint8_t * componentCount)303     const uint8_t *getSourceColors(GLenum sourceFormat, size_t *colorCount, uint8_t *componentCount)
304     {
305         // Note: in all the following values, alpha is larger than RGB so unmultiply alpha doesn't
306         // overflow
307         constexpr static uint8_t kRgbaColors[7 * 4] = {
308             255u, 127u, 63u,  255u,  // 0
309             31u,  127u, 63u,  127u,  // 1
310             31u,  63u,  127u, 255u,  // 2
311             15u,  127u, 31u,  127u,  // 3
312             127u, 255u, 63u,  0u,    // 4
313             31u,  63u,  127u, 0u,    // 5
314             15u,  31u,  63u,  63u,   // 6
315         };
316 
317         constexpr static uint8_t kRgbColors[7 * 3] = {
318             255u, 127u, 63u,   // 0
319             31u,  127u, 63u,   // 1
320             31u,  63u,  127u,  // 2
321             15u,  127u, 31u,   // 3
322             127u, 255u, 63u,   // 4
323             31u,  63u,  127u,  // 5
324             15u,  31u,  63u,   // 6
325         };
326 
327         constexpr static uint8_t kLumColors[7 * 1] = {
328             255u,  // 0
329             163u,  // 1
330             78u,   // 2
331             114u,  // 3
332             51u,   // 4
333             0u,    // 5
334             217u,  // 6
335         };
336 
337         constexpr static uint8_t kLumaColors[7 * 2] = {
338             255u, 255u,  // 0
339             67u,  163u,  // 1
340             78u,  231u,  // 2
341             8u,   114u,  // 3
342             51u,  199u,  // 4
343             0u,   173u,  // 5
344             34u,  217u,  // 6
345         };
346 
347         constexpr static uint8_t kAlphaColors[7 * 1] = {
348             255u,  // 0
349             67u,   // 1
350             231u,  // 2
351             8u,    // 3
352             199u,  // 4
353             173u,  // 5
354             34u,   // 6
355         };
356 
357         *colorCount = 7;
358 
359         switch (sourceFormat)
360         {
361             case GL_RGB:
362                 *componentCount = 3;
363                 return kRgbColors;
364             case GL_RGBA:
365             case GL_BGRA_EXT:
366                 *componentCount = 4;
367                 return kRgbaColors;
368             case GL_LUMINANCE:
369                 *componentCount = 1;
370                 return kLumColors;
371             case GL_ALPHA:
372                 *componentCount = 1;
373                 return kAlphaColors;
374             case GL_LUMINANCE_ALPHA:
375                 *componentCount = 2;
376                 return kLumaColors;
377             default:
378                 EXPECT_EQ(true, false);
379                 return nullptr;
380         }
381     }
382 
initializeSourceTexture(GLenum target,GLenum sourceFormat,const uint8_t * srcColors,uint8_t componentCount)383     void initializeSourceTexture(GLenum target,
384                                  GLenum sourceFormat,
385                                  const uint8_t *srcColors,
386                                  uint8_t componentCount)
387     {
388         // The texture is initialized as 2x2.  If the componentCount is 1 or 3, then the input data
389         // will have a row pitch of 2 or 6, which needs to be padded to 4 or 8 respectively.
390         uint8_t srcColorsPadded[4 * 4];
391         size_t srcRowPitch =
392             2 * componentCount + (componentCount == 1 || componentCount == 3 ? 2 : 0);
393         size_t inputRowPitch = 2 * componentCount;
394         for (size_t row = 0; row < 2; ++row)
395         {
396             memcpy(&srcColorsPadded[row * srcRowPitch], &srcColors[row * inputRowPitch],
397                    inputRowPitch);
398             memset(&srcColorsPadded[row * srcRowPitch + inputRowPitch], 0,
399                    srcRowPitch - inputRowPitch);
400         }
401 
402         glBindTexture(target, mTextures[0]);
403         glTexImage2D(target, 0, sourceFormat, 2, 2, 0, sourceFormat, GL_UNSIGNED_BYTE,
404                      srcColorsPadded);
405     }
406 
testCopyTexture(GLenum sourceTarget,GLenum sourceFormat,GLenum destFormat,bool flipY,bool premultiplyAlpha,bool unmultiplyAlpha)407     void testCopyTexture(GLenum sourceTarget,
408                          GLenum sourceFormat,
409                          GLenum destFormat,
410                          bool flipY,
411                          bool premultiplyAlpha,
412                          bool unmultiplyAlpha)
413     {
414         if (!checkExtensions(sourceFormat, destFormat))
415         {
416             return;
417         }
418 
419         size_t colorCount;
420         uint8_t componentCount;
421         const uint8_t *srcColors = getSourceColors(sourceFormat, &colorCount, &componentCount);
422 
423         std::vector<GLColor> destColors(colorCount);
424         for (size_t i = 0; i < colorCount; ++i)
425         {
426             calculateCopyTextureResults(sourceFormat, destFormat, premultiplyAlpha, unmultiplyAlpha,
427                                         &srcColors[i * componentCount], &destColors[i]);
428         }
429 
430         for (size_t i = 0; i < colorCount - 3; ++i)
431         {
432             initializeSourceTexture(sourceTarget, sourceFormat, &srcColors[i * componentCount],
433                                     componentCount);
434 
435             glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, destFormat,
436                                   GL_UNSIGNED_BYTE, flipY, premultiplyAlpha, unmultiplyAlpha);
437 
438             EXPECT_GL_NO_ERROR();
439 
440             // Check that FB is complete.
441             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
442 
443             if (flipY)
444             {
445                 EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 2], 1.0);
446                 EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 3], 1.0);
447                 EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 0], 1.0);
448                 EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 1], 1.0);
449             }
450             else
451             {
452                 EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 0], 1.0);
453                 EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 1], 1.0);
454                 EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 2], 1.0);
455                 EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 3], 1.0);
456             }
457 
458             EXPECT_GL_NO_ERROR();
459         }
460     }
461 
testCopySubTexture(GLenum sourceTarget,GLenum sourceFormat,GLenum destFormat,bool flipY,bool premultiplyAlpha,bool unmultiplyAlpha)462     void testCopySubTexture(GLenum sourceTarget,
463                             GLenum sourceFormat,
464                             GLenum destFormat,
465                             bool flipY,
466                             bool premultiplyAlpha,
467                             bool unmultiplyAlpha)
468     {
469         if (!checkExtensions(sourceFormat, destFormat))
470         {
471             return;
472         }
473 
474         size_t colorCount;
475         uint8_t componentCount;
476         const uint8_t *srcColors = getSourceColors(sourceFormat, &colorCount, &componentCount);
477 
478         std::vector<GLColor> destColors(colorCount);
479         for (size_t i = 0; i < colorCount; ++i)
480         {
481             calculateCopyTextureResults(sourceFormat, destFormat, premultiplyAlpha, unmultiplyAlpha,
482                                         &srcColors[i * componentCount], &destColors[i]);
483         }
484 
485         for (size_t i = 0; i < colorCount - 3; ++i)
486         {
487             initializeSourceTexture(sourceTarget, sourceFormat, &srcColors[i * componentCount],
488                                     componentCount);
489 
490             glBindTexture(GL_TEXTURE_2D, mTextures[1]);
491             glTexImage2D(GL_TEXTURE_2D, 0, destFormat, 2, 2, 0, destFormat, GL_UNSIGNED_BYTE,
492                          nullptr);
493 
494             glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 2,
495                                      2, flipY, premultiplyAlpha, unmultiplyAlpha);
496 
497             EXPECT_GL_NO_ERROR();
498 
499             if (sourceFormat != GL_LUMINANCE && sourceFormat != GL_LUMINANCE_ALPHA &&
500                 sourceFormat != GL_ALPHA)
501             {
502                 // Check that FB is complete.
503                 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
504             }
505 
506             if (flipY)
507             {
508                 EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 2], 1.0);
509                 EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 3], 1.0);
510                 EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 0], 1.0);
511                 EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 1], 1.0);
512             }
513             else
514             {
515                 EXPECT_PIXEL_COLOR_NEAR(0, 0, destColors[i + 0], 1.0);
516                 EXPECT_PIXEL_COLOR_NEAR(1, 0, destColors[i + 1], 1.0);
517                 EXPECT_PIXEL_COLOR_NEAR(0, 1, destColors[i + 2], 1.0);
518                 EXPECT_PIXEL_COLOR_NEAR(1, 1, destColors[i + 3], 1.0);
519             }
520 
521             EXPECT_GL_NO_ERROR();
522         }
523     }
524 
525     GLuint mTextures[2] = {
526         0,
527         0,
528     };
529     GLuint mFramebuffer = 0;
530 };
531 
532 class CopyTextureTestDest : public CopyTextureTest
533 {};
534 
535 class CopyTextureTestWebGL : public CopyTextureTest
536 {
537   protected:
CopyTextureTestWebGL()538     CopyTextureTestWebGL() : CopyTextureTest() { setWebGLCompatibilityEnabled(true); }
539 };
540 
541 class CopyTextureTestES3 : public CopyTextureTest
542 {};
543 
544 // Test that CopyTexture cannot redefine an immutable texture and CopySubTexture can copy data to
545 // immutable textures
TEST_P(CopyTextureTest,ImmutableTexture)546 TEST_P(CopyTextureTest, ImmutableTexture)
547 {
548     if (!checkExtensions())
549     {
550         return;
551     }
552 
553     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
554                        (!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
555                         !IsGLExtensionEnabled("GL_OES_rgb8_rgba8")));
556 
557     GLColor pixels = GLColor::red;
558 
559     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
560     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
561     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
562 
563     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
564     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
565     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0);
566     EXPECT_GL_NO_ERROR();
567 
568     // Should generate an error when the texture is redefined
569     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
570                           GL_UNSIGNED_BYTE, false, false, false);
571     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
572 
573     // Should succeed when using CopySubTexture
574     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 1, 1,
575                              false, false, false);
576     EXPECT_GL_NO_ERROR();
577 
578     // Check that FB is complete.
579     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
580 
581     EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
582 
583     EXPECT_GL_NO_ERROR();
584 }
585 
586 // Test validation of internal formats in CopyTexture and CopySubTexture
TEST_P(CopyTextureTest,InternalFormat)587 TEST_P(CopyTextureTest, InternalFormat)
588 {
589     if (!checkExtensions())
590     {
591         return;
592     }
593 
594     std::vector<GLint> sourceFormats;
595     sourceFormats.push_back(GL_ALPHA);
596     sourceFormats.push_back(GL_RGB);
597     sourceFormats.push_back(GL_RGBA);
598     sourceFormats.push_back(GL_LUMINANCE);
599     sourceFormats.push_back(GL_LUMINANCE_ALPHA);
600 
601     std::vector<GLint> destFormats;
602     destFormats.push_back(GL_RGB);
603     destFormats.push_back(GL_RGBA);
604 
605     if (IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
606     {
607         sourceFormats.push_back(GL_BGRA_EXT);
608         destFormats.push_back(GL_BGRA_EXT);
609     }
610 
611     // Test with glCopyTexture
612     for (GLint sourceFormat : sourceFormats)
613     {
614         for (GLint destFormat : destFormats)
615         {
616             glBindTexture(GL_TEXTURE_2D, mTextures[0]);
617             glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, 1, 1, 0, sourceFormat, GL_UNSIGNED_BYTE,
618                          nullptr);
619             EXPECT_GL_NO_ERROR();
620 
621             glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, destFormat,
622                                   GL_UNSIGNED_BYTE, false, false, false);
623 
624             EXPECT_GL_NO_ERROR();
625         }
626     }
627 
628     // Test with glCopySubTexture
629     for (GLint sourceFormat : sourceFormats)
630     {
631         for (GLint destFormat : destFormats)
632         {
633             glBindTexture(GL_TEXTURE_2D, mTextures[0]);
634             glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, 1, 1, 0, sourceFormat, GL_UNSIGNED_BYTE,
635                          nullptr);
636             EXPECT_GL_NO_ERROR();
637 
638             glBindTexture(GL_TEXTURE_2D, mTextures[1]);
639             glTexImage2D(GL_TEXTURE_2D, 0, destFormat, 1, 1, 0, destFormat, GL_UNSIGNED_BYTE,
640                          nullptr);
641             EXPECT_GL_NO_ERROR();
642 
643             glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 1,
644                                      1, false, false, false);
645 
646             EXPECT_GL_NO_ERROR();
647         }
648     }
649 }
650 
651 // Test to ensure that the destination texture is redefined if the properties are different.
TEST_P(CopyTextureTest,RedefineDestinationTexture)652 TEST_P(CopyTextureTest, RedefineDestinationTexture)
653 {
654     ANGLE_SKIP_TEST_IF(!checkExtensions());
655     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"));
656 
657     GLColor pixels[4] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red};
658 
659     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
660     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
661 
662     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
663     glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
664     EXPECT_GL_NO_ERROR();
665 
666     // GL_INVALID_OPERATION due to "intrinsic format" != "internal format".
667     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
668     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
669     // GL_INVALID_VALUE due to bad dimensions.
670     glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
671     EXPECT_GL_ERROR(GL_INVALID_VALUE);
672 
673     // If the dest texture has different properties, glCopyTextureCHROMIUM()
674     // redefines them.
675     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
676                           GL_UNSIGNED_BYTE, false, false, false);
677     EXPECT_GL_NO_ERROR();
678 
679     // glTexSubImage2D() succeeds because mTextures[1] is redefined into 2x2
680     // dimension and GL_RGBA format.
681     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
682     glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
683     EXPECT_GL_NO_ERROR();
684 
685     // Check that FB is complete.
686     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
687 
688     EXPECT_PIXEL_COLOR_EQ(1, 1, pixels[3]);
689     EXPECT_GL_NO_ERROR();
690 }
691 
692 // Test that invalid dimensions in CopySubTexture are validated
TEST_P(CopyTextureTest,CopySubTextureDimension)693 TEST_P(CopyTextureTest, CopySubTextureDimension)
694 {
695     if (!checkExtensions())
696     {
697         return;
698     }
699 
700     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
701     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
702 
703     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
704     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
705 
706     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
707                              false, false, false);
708     EXPECT_GL_NO_ERROR();
709 
710     // xoffset < 0
711     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, -1, 1, 0, 0, 1, 1,
712                              false, false, false);
713     EXPECT_GL_ERROR(GL_INVALID_VALUE);
714 
715     // x < 0
716     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, -1, 0, 1, 1,
717                              false, false, false);
718     EXPECT_GL_ERROR(GL_INVALID_VALUE);
719 
720     // xoffset + width > dest_width
721     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 2, 2, 0, 0, 2, 2,
722                              false, false, false);
723     EXPECT_GL_ERROR(GL_INVALID_VALUE);
724 
725     // x + width > source_width
726     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 1, 1, 2, 2,
727                              false, false, false);
728     EXPECT_GL_ERROR(GL_INVALID_VALUE);
729 }
730 
731 // Test that invalid IDs in CopyTexture are validated
TEST_P(CopyTextureTest,CopyTextureInvalidTextureIds)732 TEST_P(CopyTextureTest, CopyTextureInvalidTextureIds)
733 {
734     if (!checkExtensions())
735     {
736         return;
737     }
738 
739     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
740     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
741 
742     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
743     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
744 
745     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, 99993, 0, GL_RGBA, GL_UNSIGNED_BYTE,
746                           false, false, false);
747     EXPECT_GL_ERROR(GL_INVALID_VALUE);
748 
749     glCopyTextureCHROMIUM(99994, 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA, GL_UNSIGNED_BYTE,
750                           false, false, false);
751     EXPECT_GL_ERROR(GL_INVALID_VALUE);
752 
753     glCopyTextureCHROMIUM(99995, 0, GL_TEXTURE_2D, 99996, 0, GL_RGBA, GL_UNSIGNED_BYTE, false,
754                           false, false);
755     EXPECT_GL_ERROR(GL_INVALID_VALUE);
756 
757     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
758                           GL_UNSIGNED_BYTE, false, false, false);
759     EXPECT_GL_NO_ERROR();
760 }
761 
762 // Test that invalid IDs in CopySubTexture are validated
TEST_P(CopyTextureTest,CopySubTextureInvalidTextureIds)763 TEST_P(CopyTextureTest, CopySubTextureInvalidTextureIds)
764 {
765     if (!checkExtensions())
766     {
767         return;
768     }
769 
770     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
771     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
772 
773     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
774     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
775 
776     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, 99993, 0, 1, 1, 0, 0, 1, 1, false,
777                              false, false);
778     EXPECT_GL_ERROR(GL_INVALID_VALUE);
779 
780     glCopySubTextureCHROMIUM(99994, 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1, false,
781                              false, false);
782     EXPECT_GL_ERROR(GL_INVALID_VALUE);
783 
784     glCopySubTextureCHROMIUM(99995, 0, GL_TEXTURE_2D, 99996, 0, 1, 1, 0, 0, 1, 1, false, false,
785                              false);
786     EXPECT_GL_ERROR(GL_INVALID_VALUE);
787 
788     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
789                              false, false, false);
790     EXPECT_GL_NO_ERROR();
791 }
792 
TEST_P(CopyTextureTest,InvalidTarget)793 TEST_P(CopyTextureTest, InvalidTarget)
794 {
795     ANGLE_SKIP_TEST_IF(!checkExtensions());
796 
797     GLTexture textures[2];
798 
799     glBindTexture(GL_TEXTURE_2D, textures[0]);
800     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
801 
802     glBindTexture(GL_TEXTURE_2D, textures[1]);
803     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
804 
805     // Invalid enum for a completely invalid target
806     glCopySubTextureCHROMIUM(textures[0], 0, GL_INVALID_VALUE, textures[1], 0, 1, 1, 0, 0, 1, 1,
807                              false, false, false);
808     EXPECT_GL_ERROR(GL_INVALID_ENUM);
809 
810     // Invalid value for a valid target enum but is not valid for the destination texture
811     glCopySubTextureCHROMIUM(textures[0], 0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, textures[1], 0, 1, 1,
812                              0, 0, 1, 1, false, false, false);
813     EXPECT_GL_ERROR(GL_INVALID_VALUE);
814 }
815 
816 // Test that using an offset in CopySubTexture works correctly
TEST_P(CopyTextureTest,CopySubTextureOffset)817 TEST_P(CopyTextureTest, CopySubTextureOffset)
818 {
819     if (!checkExtensions())
820     {
821         return;
822     }
823 
824     GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
825     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
826     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
827 
828     GLColor transparentPixels[4 * 4] = {GLColor::transparentBlack, GLColor::transparentBlack,
829                                         GLColor::transparentBlack, GLColor::transparentBlack};
830     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
831     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, transparentPixels);
832 
833     // Check that FB is complete.
834     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
835 
836     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
837                              false, false, false);
838     EXPECT_GL_NO_ERROR();
839     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
840 
841     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 0, 1, 0, 1, 1,
842                              false, false, false);
843     EXPECT_GL_NO_ERROR();
844     EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::green);
845 
846     glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 1, 0, 1, 1, 1,
847                              false, false, false);
848     EXPECT_GL_NO_ERROR();
849     EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::blue);
850 
851     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
852     EXPECT_GL_NO_ERROR();
853 }
854 
855 // Test every combination of copy [sub]texture parameters:
856 // source: ALPHA, RGB, RGBA, LUMINANCE, LUMINANCE_ALPHA, BGRA_EXT
857 // destination: RGB, RGBA, BGRA_EXT
858 // flipY: false, true
859 // premultiplyAlpha: false, true
860 // unmultiplyAlpha: false, true
861 namespace
862 {
863 constexpr GLenum kCopyTextureVariationsSrcFormats[] = {
864     GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGRA_EXT};
865 constexpr GLenum kCopyTextureVariationsDstFormats[] = {GL_RGB, GL_RGBA, GL_BGRA_EXT};
866 }  // anonymous namespace
867 
TEST_P(CopyTextureVariationsTest,CopyTexture)868 TEST_P(CopyTextureVariationsTest, CopyTexture)
869 {
870     // http://anglebug.com/4092
871     ANGLE_SKIP_TEST_IF(IsVulkan());
872     testCopyTexture(GL_TEXTURE_2D, std::get<1>(GetParam()), std::get<2>(GetParam()),
873                     std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
874 }
875 
TEST_P(CopyTextureVariationsTest,CopySubTexture)876 TEST_P(CopyTextureVariationsTest, CopySubTexture)
877 {
878     testCopySubTexture(GL_TEXTURE_2D, std::get<1>(GetParam()), std::get<2>(GetParam()),
879                        std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
880 }
881 
TEST_P(CopyTextureVariationsTest,CopyTextureRectangle)882 TEST_P(CopyTextureVariationsTest, CopyTextureRectangle)
883 {
884     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_texture_rectangle"));
885 
886     testCopyTexture(GL_TEXTURE_RECTANGLE_ANGLE, std::get<1>(GetParam()), std::get<2>(GetParam()),
887                     std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
888 }
889 
TEST_P(CopyTextureVariationsTest,CopySubTextureRectangle)890 TEST_P(CopyTextureVariationsTest, CopySubTextureRectangle)
891 {
892     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_texture_rectangle"));
893 
894     testCopySubTexture(GL_TEXTURE_RECTANGLE_ANGLE, std::get<1>(GetParam()), std::get<2>(GetParam()),
895                        std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
896 }
897 
898 // Test that copying to cube maps works
TEST_P(CopyTextureTest,CubeMapTarget)899 TEST_P(CopyTextureTest, CubeMapTarget)
900 {
901     if (!checkExtensions())
902     {
903         return;
904     }
905 
906     // http://anglebug.com/1932
907     ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsDesktopOpenGL());
908 
909     // http://anglebug.com/3145
910     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
911 
912     GLColor pixels[7] = {
913         GLColor(10u, 13u, 16u, 19u), GLColor(20u, 23u, 26u, 29u), GLColor(30u, 33u, 36u, 39u),
914         GLColor(40u, 43u, 46u, 49u), GLColor(50u, 53u, 56u, 59u), GLColor(60u, 63u, 66u, 69u),
915         GLColor(70u, 73u, 76u, 79u),
916     };
917 
918     GLTexture textures[2];
919 
920     glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
921     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
922          face++)
923     {
924         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
925     }
926 
927     for (size_t i = 0; i < 2; ++i)
928     {
929         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
930              face++)
931         {
932             glBindTexture(GL_TEXTURE_2D, textures[0]);
933             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
934                          &pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
935 
936             glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 1, 1, false,
937                                      false, false);
938         }
939 
940         EXPECT_GL_NO_ERROR();
941 
942         GLFramebuffer fbo;
943         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
944 
945         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
946              face++)
947         {
948             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
949 
950             // Check that FB is complete.
951             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
952 
953             EXPECT_PIXEL_COLOR_EQ(0, 0, pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
954 
955             EXPECT_GL_NO_ERROR();
956         }
957     }
958 }
959 
960 // Test that we can successfully copy into incomplete cube maps. Regression test for
961 // http://anglebug.com/3384
TEST_P(CopyTextureTest,IncompleteCubeMap)962 TEST_P(CopyTextureTest, IncompleteCubeMap)
963 {
964     if (!checkExtensions())
965     {
966         return;
967     }
968 
969     GLTexture texture2D;
970     GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
971     glBindTexture(GL_TEXTURE_2D, texture2D);
972     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
973 
974     GLTexture textureCube;
975     glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
976     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
977          face++)
978     {
979         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
980     }
981 
982     // Set one face to 2x2
983     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
984                  rgbaPixels);
985 
986     // Copy into the incomplete face
987     glCopySubTextureCHROMIUM(texture2D, 0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, textureCube, 0, 0, 0, 0,
988                              0, 2, 2, false, false, false);
989     EXPECT_GL_NO_ERROR();
990 }
991 
992 // Test BGRA to RGBA cube map copy
TEST_P(CopyTextureTest,CubeMapTargetBGRA)993 TEST_P(CopyTextureTest, CubeMapTargetBGRA)
994 {
995     if (!checkExtensions())
996     {
997         return;
998     }
999 
1000     if (!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
1001     {
1002         return;
1003     }
1004 
1005     // http://anglebug.com/3145
1006     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1007 
1008     GLColor pixels[7] = {
1009         GLColor(10u, 13u, 16u, 19u), GLColor(20u, 23u, 26u, 29u), GLColor(30u, 33u, 36u, 39u),
1010         GLColor(40u, 43u, 46u, 49u), GLColor(50u, 53u, 56u, 59u), GLColor(60u, 63u, 66u, 69u),
1011         GLColor(70u, 73u, 76u, 79u),
1012     };
1013 
1014     GLTexture textures[2];
1015 
1016     glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1017     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1018          face++)
1019     {
1020         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1021     }
1022 
1023     for (size_t i = 0; i < 2; ++i)
1024     {
1025         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1026              face++)
1027         {
1028             glBindTexture(GL_TEXTURE_2D, textures[0]);
1029             glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
1030                          &pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
1031 
1032             glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 1, 1, false,
1033                                      false, false);
1034         }
1035 
1036         EXPECT_GL_NO_ERROR();
1037 
1038         GLFramebuffer fbo;
1039         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1040 
1041         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1042              face++)
1043         {
1044             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1045 
1046             // Check that FB is complete.
1047             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1048 
1049             GLColor converted = pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i];
1050             std::swap(converted.R, converted.B);
1051             EXPECT_PIXEL_COLOR_EQ(0, 0, converted);
1052 
1053             EXPECT_GL_NO_ERROR();
1054         }
1055     }
1056 }
1057 
1058 // Test cube map copies with RGB format
TEST_P(CopyTextureTest,CubeMapTargetRGB)1059 TEST_P(CopyTextureTest, CubeMapTargetRGB)
1060 {
1061     if (!checkExtensions())
1062     {
1063         return;
1064     }
1065 
1066     // http://anglebug.com/1932
1067     ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsDesktopOpenGL());
1068 
1069     // http://anglebug.com/3145
1070     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1071 
1072     constexpr uint8_t pixels[16 * 7] = {
1073         0u,   3u,   6u,   10u,  13u,  16u,  0, 0, 20u,  23u,  26u,  30u,  33u,  36u,  0, 0,  // 2x2
1074         40u,  43u,  46u,  50u,  53u,  56u,  0, 0, 60u,  63u,  66u,  70u,  73u,  76u,  0, 0,  // 2x2
1075         80u,  83u,  86u,  90u,  93u,  96u,  0, 0, 100u, 103u, 106u, 110u, 113u, 116u, 0, 0,  // 2x2
1076         120u, 123u, 126u, 130u, 133u, 136u, 0, 0, 140u, 143u, 146u, 160u, 163u, 166u, 0, 0,  // 2x2
1077         170u, 173u, 176u, 180u, 183u, 186u, 0, 0, 190u, 193u, 196u, 200u, 203u, 206u, 0, 0,  // 2x2
1078         210u, 213u, 216u, 220u, 223u, 226u, 0, 0, 230u, 233u, 236u, 240u, 243u, 246u, 0, 0,  // 2x2
1079         10u,  50u,  100u, 30u,  80u,  130u, 0, 0, 60u,  110u, 160u, 90u,  140u, 200u, 0, 0,  // 2x2
1080     };
1081 
1082     GLTexture textures[2];
1083 
1084     glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1085     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1086          face++)
1087     {
1088         glTexImage2D(face, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1089     }
1090 
1091     for (size_t i = 0; i < 2; ++i)
1092     {
1093         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1094              face++)
1095         {
1096             glBindTexture(GL_TEXTURE_2D, textures[0]);
1097             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
1098                          &pixels[(face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) * 16]);
1099 
1100             glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 2, 2, false,
1101                                      false, false);
1102         }
1103 
1104         EXPECT_GL_NO_ERROR();
1105 
1106         GLFramebuffer fbo;
1107         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1108 
1109         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1110              face++)
1111         {
1112             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1113 
1114             // Check that FB is complete.
1115             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1116 
1117             const uint8_t *faceData = &pixels[(face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) * 16];
1118             EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(faceData[0], faceData[1], faceData[2], 255));
1119             EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor(faceData[3], faceData[4], faceData[5], 255));
1120             EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor(faceData[8], faceData[9], faceData[10], 255));
1121             EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor(faceData[11], faceData[12], faceData[13], 255));
1122 
1123             EXPECT_GL_NO_ERROR();
1124         }
1125     }
1126 }
1127 
1128 // Test that copying to non-zero mipmaps works
TEST_P(CopyTextureTest,CopyToMipmap)1129 TEST_P(CopyTextureTest, CopyToMipmap)
1130 {
1131     if (!checkExtensions())
1132     {
1133         return;
1134     }
1135 
1136     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
1137                        !IsGLExtensionEnabled("GL_OES_fbo_render_mipmap"));
1138 
1139     ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel());
1140 
1141     GLColor pixels[] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red};
1142 
1143     GLTexture textures[2];
1144 
1145     glBindTexture(GL_TEXTURE_2D, textures[0]);
1146     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1147     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1148 
1149     glBindTexture(GL_TEXTURE_2D, textures[1]);
1150     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1151     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1152     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1153 
1154     std::vector<std::pair<GLint, GLint>> soureDestPairs;
1155     soureDestPairs.push_back(std::make_pair(0, 1));
1156 
1157     // ES3 allows copying from non-zero mips
1158     if (getClientMajorVersion() >= 3)
1159     {
1160         soureDestPairs.push_back(std::make_pair(1, 2));
1161     }
1162 
1163     for (const auto &sourceDestPair : soureDestPairs)
1164     {
1165         const GLint sourceLevel = sourceDestPair.first;
1166         const GLint destLevel   = sourceDestPair.second;
1167 
1168         glCopyTextureCHROMIUM(textures[0], sourceLevel, GL_TEXTURE_2D, textures[1], destLevel,
1169                               GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1170 
1171         EXPECT_GL_NO_ERROR();
1172 
1173         GLFramebuffer fbo;
1174         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1175         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],
1176                                destLevel);
1177 
1178         // Check that FB is complete.
1179         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1180 
1181         EXPECT_PIXEL_COLOR_EQ(0, 0, pixels[0]);
1182 
1183         EXPECT_GL_NO_ERROR();
1184     }
1185 }
1186 
1187 // Test that copying from an RGBA8 texture to RGBA4 results in exactly 4-bit precision in the result
TEST_P(CopyTextureTest,DownsampleRGBA4444)1188 TEST_P(CopyTextureTest, DownsampleRGBA4444)
1189 {
1190     // Downsampling on copy is only guarenteed on D3D11
1191     ANGLE_SKIP_TEST_IF(!IsD3D11());
1192 
1193     GLTexture textures[2];
1194 
1195     GLColor pixels[] = {GLColor(0, 5, 6, 7), GLColor(17, 22, 25, 24), GLColor(34, 35, 36, 36),
1196                         GLColor(51, 53, 55, 55)};
1197 
1198     glBindTexture(GL_TEXTURE_2D, textures[0]);
1199     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1200 
1201     glBindTexture(GL_TEXTURE_2D, textures[1]);
1202     glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGBA,
1203                           GL_UNSIGNED_SHORT_4_4_4_4, GL_FALSE, GL_FALSE, GL_FALSE);
1204 
1205     GLFramebuffer fbo;
1206     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1207     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1208 
1209     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 0), 1.0);
1210     EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(17, 17, 17, 17), 1.0);
1211     EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(34, 34, 34, 34), 1.0);
1212     EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(51, 51, 51, 51), 1.0);
1213 
1214     testGradientDownsampleUniqueValues(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, {16, 16, 16, 16});
1215 }
1216 
1217 // Test that copying from an RGBA8 texture to RGB565 results in exactly 4-bit precision in the
1218 // result
TEST_P(CopyTextureTest,DownsampleRGB565)1219 TEST_P(CopyTextureTest, DownsampleRGB565)
1220 {
1221     // Downsampling on copy is only guarenteed on D3D11
1222     ANGLE_SKIP_TEST_IF(!IsD3D11());
1223 
1224     GLTexture textures[2];
1225 
1226     GLColor pixels[] = {GLColor(0, 5, 2, 14), GLColor(17, 22, 25, 30), GLColor(34, 33, 36, 46),
1227                         GLColor(50, 54, 49, 60)};
1228 
1229     glBindTexture(GL_TEXTURE_2D, textures[0]);
1230     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1231 
1232     glBindTexture(GL_TEXTURE_2D, textures[1]);
1233     glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGB,
1234                           GL_UNSIGNED_SHORT_5_6_5, GL_FALSE, GL_FALSE, GL_FALSE);
1235 
1236     GLFramebuffer fbo;
1237     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1238     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1239 
1240     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 4, 0, 255), 1.0);
1241     EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(16, 20, 25, 255), 1.0);
1242     EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(33, 32, 33, 255), 1.0);
1243     EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(49, 53, 49, 255), 1.0);
1244 
1245     testGradientDownsampleUniqueValues(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, {32, 64, 32, 1});
1246 }
1247 
1248 // Test that copying from an RGBA8 texture to RGBA5551 results in exactly 4-bit precision in the
1249 // result
TEST_P(CopyTextureTest,DownsampleRGBA5551)1250 TEST_P(CopyTextureTest, DownsampleRGBA5551)
1251 {
1252     // Downsampling on copy is only guarenteed on D3D11
1253     ANGLE_SKIP_TEST_IF(!IsD3D11());
1254 
1255     GLTexture textures[2];
1256 
1257     GLColor pixels[] = {GLColor(0, 1, 2, 3), GLColor(14, 16, 17, 18), GLColor(33, 34, 36, 46),
1258                         GLColor(50, 51, 52, 255)};
1259 
1260     glBindTexture(GL_TEXTURE_2D, textures[0]);
1261     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1262 
1263     glBindTexture(GL_TEXTURE_2D, textures[1]);
1264     glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGBA,
1265                           GL_UNSIGNED_SHORT_5_5_5_1, GL_FALSE, GL_FALSE, GL_FALSE);
1266 
1267     GLFramebuffer fbo;
1268     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1269     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1270 
1271     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 0), 1.0);
1272     EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(16, 16, 16, 0), 1.0);
1273     EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(33, 33, 33, 0), 1.0);
1274     EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(49, 49, 49, 255), 1.0);
1275 
1276     testGradientDownsampleUniqueValues(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, {32, 32, 32, 2});
1277 }
1278 
1279 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination
TEST_P(CopyTextureTestDest,Luminance)1280 TEST_P(CopyTextureTestDest, Luminance)
1281 {
1282     if (!checkExtensions())
1283     {
1284         return;
1285     }
1286 
1287     GLColor originalPixels(50u, 100u, 150u, 200u);
1288     GLColor expectedPixels(50u, 50u, 50u, 255u);
1289 
1290     // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1291     // texture to verify contents.
1292     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1293     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1294     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1295     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1296 
1297     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1298                           GL_UNSIGNED_BYTE, false, false, false);
1299 
1300     EXPECT_GL_NO_ERROR();
1301 
1302     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1303                           GL_UNSIGNED_BYTE, false, false, false);
1304 
1305     EXPECT_GL_NO_ERROR();
1306 
1307     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1308 }
1309 
1310 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
1311 // UnpackPremultiply parameter
TEST_P(CopyTextureTestDest,LuminanceMultiply)1312 TEST_P(CopyTextureTestDest, LuminanceMultiply)
1313 {
1314     if (!checkExtensions())
1315     {
1316         return;
1317     }
1318 
1319     GLColor originalPixels(50u, 100u, 150u, 200u);
1320     GLColor expectedPixels(39u, 39u, 39u, 255u);
1321 
1322     // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1323     // texture to verify contents.
1324     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1325     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1326     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1327     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1328 
1329     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1330                           GL_UNSIGNED_BYTE, false, true, false);
1331 
1332     EXPECT_GL_NO_ERROR();
1333 
1334     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1335                           GL_UNSIGNED_BYTE, false, false, false);
1336 
1337     EXPECT_GL_NO_ERROR();
1338 
1339     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1340 }
1341 
1342 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
1343 // UnpackUnmultiply parameter
TEST_P(CopyTextureTestDest,LuminanceUnmultiply)1344 TEST_P(CopyTextureTestDest, LuminanceUnmultiply)
1345 {
1346     if (!checkExtensions())
1347     {
1348         return;
1349     }
1350 
1351     GLColor originalPixels(50u, 100u, 150u, 200u);
1352     GLColor expectedPixels(64u, 64u, 64u, 255u);
1353 
1354     // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1355     // texture to verify contents.
1356     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1357     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1358     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1359     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1360 
1361     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1362                           GL_UNSIGNED_BYTE, false, false, true);
1363 
1364     EXPECT_GL_NO_ERROR();
1365 
1366     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1367                           GL_UNSIGNED_BYTE, false, false, false);
1368 
1369     EXPECT_GL_NO_ERROR();
1370 
1371     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1372 }
1373 
1374 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination
TEST_P(CopyTextureTestDest,LuminanceAlpha)1375 TEST_P(CopyTextureTestDest, LuminanceAlpha)
1376 {
1377     if (!checkExtensions())
1378     {
1379         return;
1380     }
1381 
1382     GLColor originalPixels(50u, 100u, 150u, 200u);
1383     GLColor expectedPixels(50u, 50u, 50u, 200u);
1384 
1385     // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1386     // RGBA texture to verify contents.
1387     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1388     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1389     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1390     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1391                  GL_UNSIGNED_BYTE, nullptr);
1392 
1393     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1394                           GL_UNSIGNED_BYTE, false, false, false);
1395 
1396     EXPECT_GL_NO_ERROR();
1397 
1398     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1399                           GL_UNSIGNED_BYTE, false, false, false);
1400 
1401     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1402 }
1403 
1404 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
1405 // UnpackPremultiply parameter
TEST_P(CopyTextureTestDest,LuminanceAlphaMultiply)1406 TEST_P(CopyTextureTestDest, LuminanceAlphaMultiply)
1407 {
1408     if (!checkExtensions())
1409     {
1410         return;
1411     }
1412 
1413     GLColor originalPixels(50u, 100u, 150u, 200u);
1414     GLColor expectedPixels(39u, 39u, 39u, 200u);
1415 
1416     // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1417     // RGBA texture to verify contents.
1418     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1419     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1420     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1421     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1422                  GL_UNSIGNED_BYTE, nullptr);
1423 
1424     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1425                           GL_UNSIGNED_BYTE, false, true, false);
1426 
1427     EXPECT_GL_NO_ERROR();
1428 
1429     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1430                           GL_UNSIGNED_BYTE, false, false, false);
1431 
1432     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1433 }
1434 
1435 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
1436 // UnpackUnmultiplyAlpha parameter
TEST_P(CopyTextureTestDest,LuminanceAlphaUnmultiply)1437 TEST_P(CopyTextureTestDest, LuminanceAlphaUnmultiply)
1438 {
1439     if (!checkExtensions())
1440     {
1441         return;
1442     }
1443 
1444     GLColor originalPixels(50u, 100u, 150u, 200u);
1445     GLColor expectedPixels(64u, 64u, 64u, 200u);
1446 
1447     // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1448     // RGBA texture to verify contents.
1449     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1450     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1451     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1452     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1453                  GL_UNSIGNED_BYTE, nullptr);
1454 
1455     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1456                           GL_UNSIGNED_BYTE, false, false, true);
1457 
1458     EXPECT_GL_NO_ERROR();
1459 
1460     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1461                           GL_UNSIGNED_BYTE, false, false, false);
1462 
1463     EXPECT_GL_NO_ERROR();
1464 
1465     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1466 }
1467 
1468 // Test to ensure that CopyTexture works with ALPHA texture as a destination
TEST_P(CopyTextureTestDest,Alpha)1469 TEST_P(CopyTextureTestDest, Alpha)
1470 {
1471     if (!checkExtensions())
1472     {
1473         return;
1474     }
1475 
1476     GLColor originalPixels(50u, 100u, 150u, 155u);
1477     GLColor expectedPixels(0u, 0u, 0u, 155u);
1478 
1479     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1480     // texture to verify contents.
1481     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1482     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1483     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1484     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1485 
1486     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1487                           GL_UNSIGNED_BYTE, false, false, false);
1488 
1489     EXPECT_GL_NO_ERROR();
1490 
1491     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1492                           GL_UNSIGNED_BYTE, false, false, false);
1493 
1494     EXPECT_GL_NO_ERROR();
1495 
1496     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1497 }
1498 
1499 // Test to ensure that CopyTexture works with ALPHA texture as a destination with
1500 // UnpackPremultiplyAlpha parameter
TEST_P(CopyTextureTestDest,AlphaMultiply)1501 TEST_P(CopyTextureTestDest, AlphaMultiply)
1502 {
1503     if (!checkExtensions())
1504     {
1505         return;
1506     }
1507 
1508     GLColor originalPixels(50u, 100u, 150u, 155u);
1509     GLColor expectedPixels(0u, 0u, 0u, 155u);
1510 
1511     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1512     // texture to verify contents.
1513     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1514     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1515     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1516     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1517 
1518     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1519                           GL_UNSIGNED_BYTE, false, true, false);
1520 
1521     EXPECT_GL_NO_ERROR();
1522 
1523     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1524                           GL_UNSIGNED_BYTE, false, false, false);
1525 
1526     EXPECT_GL_NO_ERROR();
1527 
1528     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1529 }
1530 
1531 // Test to ensure that CopyTexture works with ALPHA texture as a destination with
1532 // UnpackUnmultiplyAlpha parameter
TEST_P(CopyTextureTestDest,AlphaUnmultiply)1533 TEST_P(CopyTextureTestDest, AlphaUnmultiply)
1534 {
1535     if (!checkExtensions())
1536     {
1537         return;
1538     }
1539 
1540     GLColor originalPixels(50u, 100u, 150u, 155u);
1541     GLColor expectedPixels(0u, 0u, 0u, 155u);
1542 
1543     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1544     // texture to verify contents.
1545     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1546     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1547     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1548     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1549 
1550     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1551                           GL_UNSIGNED_BYTE, false, false, true);
1552 
1553     EXPECT_GL_NO_ERROR();
1554 
1555     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1556                           GL_UNSIGNED_BYTE, false, false, false);
1557 
1558     EXPECT_GL_NO_ERROR();
1559 
1560     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1561 }
1562 
1563 // Test to ensure that CopyTexture uses the correct ALPHA passthrough shader to ensure RGB channels
1564 // are set to 0.
TEST_P(CopyTextureTestDest,AlphaCopyWithRGB)1565 TEST_P(CopyTextureTestDest, AlphaCopyWithRGB)
1566 {
1567     // http://anglebug.com/4121
1568     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGLES());
1569     ANGLE_SKIP_TEST_IF(!checkExtensions());
1570 
1571     GLColor originalPixels(50u, 100u, 150u, 155u);
1572     GLColor expectedPixels(0u, 0u, 0u, 155u);
1573 
1574     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1575     // texture to verify contents.
1576     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1577     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1578     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1579     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_HALF_FLOAT_OES, nullptr);
1580 
1581     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1582                           GL_HALF_FLOAT_OES, false, false, false);
1583 
1584     EXPECT_GL_NO_ERROR();
1585 
1586     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1587                           GL_UNSIGNED_BYTE, false, false, false);
1588 
1589     EXPECT_GL_NO_ERROR();
1590 
1591     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1592 }
1593 
1594 // Bug where TEXTURE_SWIZZLE_RGBA was not reset after the Luminance workaround. (crbug.com/1022080)
TEST_P(CopyTextureTestES3,LuminanceWorkaroundTextureSwizzleBug)1595 TEST_P(CopyTextureTestES3, LuminanceWorkaroundTextureSwizzleBug)
1596 {
1597 
1598     {
1599         GLColor pixels(50u, 20u, 100u, 150u);
1600 
1601         // Hit BlitGL::copySubImageToLUMAWorkaroundTexture by copying an ALPHA texture
1602         GLTexture srcTexture;
1603         glBindTexture(GL_TEXTURE_2D, srcTexture);
1604         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
1605 
1606         GLFramebuffer srcFBO;
1607         glBindFramebuffer(GL_FRAMEBUFFER, srcFBO);
1608         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture, 0);
1609 
1610         GLTexture dstTexture;
1611         glBindTexture(GL_TEXTURE_2D, dstTexture);
1612         glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1613 
1614         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
1615         EXPECT_GL_NO_ERROR();
1616     }
1617 
1618     {
1619         // This time hit BlitGL::blitColorBufferWithShader by copying an SRGB texture
1620         GLColor pixels(100u, 200u, 50u, 210u);
1621 
1622         GLTexture srcTexture;
1623         glBindTexture(GL_TEXTURE_2D, srcTexture);
1624         glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
1625                      GL_UNSIGNED_BYTE, &pixels);
1626 
1627         GLFramebuffer srcFBO;
1628         glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
1629         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture,
1630                                0);
1631 
1632         GLTexture dstTexture;
1633         glBindTexture(GL_TEXTURE_2D, dstTexture);
1634         glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
1635                      GL_UNSIGNED_BYTE, nullptr);
1636 
1637         GLFramebuffer dstFBO;
1638         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFBO);
1639         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTexture,
1640                                0);
1641 
1642         glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1643 
1644         // The previous workaround should not affect this copy
1645         glBindFramebuffer(GL_FRAMEBUFFER, dstFBO);
1646         EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
1647     }
1648 }
1649 
1650 // Test to ensure that CopyTexture will fail with a non-zero level and NPOT texture in WebGL
TEST_P(CopyTextureTestWebGL,NPOT)1651 TEST_P(CopyTextureTestWebGL, NPOT)
1652 {
1653     if (IsGLExtensionRequestable("GL_CHROMIUM_copy_texture"))
1654     {
1655         glRequestExtensionANGLE("GL_CHROMIUM_copy_texture");
1656     }
1657     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"));
1658 
1659     std::vector<GLColor> pixelData(10 * 10, GLColor::red);
1660 
1661     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1662     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 10, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
1663 
1664     // Do a basic copy to make sure things work
1665     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1666                           GL_UNSIGNED_BYTE, false, false, false);
1667 
1668     EXPECT_GL_NO_ERROR();
1669 
1670     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1671 
1672     // Do the same operation with destLevel 1, which should fail
1673     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 1, GL_RGBA,
1674                           GL_UNSIGNED_BYTE, false, false, false);
1675 
1676     EXPECT_GL_ERROR(GL_INVALID_VALUE);
1677 }
1678 
1679 // Test the newly added ES3 unorm formats
TEST_P(CopyTextureTestES3,ES3UnormFormats)1680 TEST_P(CopyTextureTestES3, ES3UnormFormats)
1681 {
1682     if (!checkExtensions())
1683     {
1684         return;
1685     }
1686     // http://anglebug.com/4092
1687     ANGLE_SKIP_TEST_IF(IsAndroid() || IsVulkan());
1688 
1689     auto testOutput = [this](GLuint texture, const GLColor &expectedColor) {
1690         constexpr char kVS[] =
1691             "#version 300 es\n"
1692             "in vec4 position;\n"
1693             "out vec2 texcoord;\n"
1694             "void main()\n"
1695             "{\n"
1696             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1697             "    texcoord = (position.xy * 0.5) + 0.5;\n"
1698             "}\n";
1699 
1700         constexpr char kFS[] =
1701             "#version 300 es\n"
1702             "precision mediump float;\n"
1703             "uniform sampler2D tex;\n"
1704             "in vec2 texcoord;\n"
1705             "out vec4 color;\n"
1706             "void main()\n"
1707             "{\n"
1708             "    color = texture(tex, texcoord);\n"
1709             "}\n";
1710 
1711         ANGLE_GL_PROGRAM(program, kVS, kFS);
1712         glUseProgram(program);
1713 
1714         GLRenderbuffer rbo;
1715         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1716         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
1717 
1718         GLFramebuffer fbo;
1719         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1720         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1721 
1722         glActiveTexture(GL_TEXTURE0);
1723         glBindTexture(GL_TEXTURE_2D, texture);
1724         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1725         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1726         glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1727 
1728         drawQuad(program, "position", 0.5f, 1.0f, true);
1729 
1730         EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, 1.0);
1731     };
1732 
1733     auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1734                                             GLenum sourceType, const GLColor &sourceColor,
1735                                             GLenum destInternalFormat, GLenum destType, bool flipY,
1736                                             bool premultiplyAlpha, bool unmultiplyAlpha,
1737                                             const GLColor &expectedColor) {
1738         GLTexture sourceTexture;
1739         glBindTexture(GL_TEXTURE_2D, sourceTexture);
1740         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1741                      &sourceColor);
1742 
1743         GLTexture destTexture;
1744         glBindTexture(GL_TEXTURE_2D, destTexture);
1745 
1746         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
1747                               destType, flipY, premultiplyAlpha, unmultiplyAlpha);
1748         ASSERT_GL_NO_ERROR();
1749 
1750         testOutput(destTexture, expectedColor);
1751     };
1752 
1753     auto testSubCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1754                                                GLenum sourceType, const GLColor &sourceColor,
1755                                                GLenum destInternalFormat, GLenum destFormat,
1756                                                GLenum destType, bool flipY, bool premultiplyAlpha,
1757                                                bool unmultiplyAlpha, const GLColor &expectedColor) {
1758         GLTexture sourceTexture;
1759         glBindTexture(GL_TEXTURE_2D, sourceTexture);
1760         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1761                      &sourceColor);
1762 
1763         GLTexture destTexture;
1764         glBindTexture(GL_TEXTURE_2D, destTexture);
1765 
1766         glTexImage2D(GL_TEXTURE_2D, 0, destInternalFormat, 1, 1, 0, destFormat, destType, nullptr);
1767         glCopySubTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 0, 1, 1,
1768                                  flipY, premultiplyAlpha, unmultiplyAlpha);
1769         ASSERT_GL_NO_ERROR();
1770 
1771         testOutput(destTexture, expectedColor);
1772     };
1773 
1774     // New LUMA source formats
1775     testCopyCombination(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGB,
1776                         GL_UNSIGNED_BYTE, false, false, false, GLColor(128, 128, 128, 255));
1777     testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1778                         GLColor(128, 64, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, false, false,
1779                         GLColor(128, 128, 128, 255));
1780     testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1781                         GLColor(128, 64, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, true, false,
1782                         GLColor(32, 32, 32, 255));
1783     testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1784                         GLColor(128, 128, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, false, true,
1785                         GLColor(255, 255, 255, 255));
1786     testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1787                         GL_UNSIGNED_BYTE, false, false, false, GLColor(0, 0, 0, 128));
1788     testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1789                         GL_UNSIGNED_BYTE, false, false, true, GLColor(0, 0, 0, 128));
1790     testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1791                         GL_UNSIGNED_BYTE, false, true, false, GLColor(0, 0, 0, 128));
1792 
1793     // New sRGB dest formats
1794     if (IsGLExtensionEnabled("GL_EXT_sRGB"))
1795     {
1796         testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
1797                             GL_UNSIGNED_BYTE, false, false, false, GLColor(55, 13, 4, 255));
1798         testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
1799                             GL_UNSIGNED_BYTE, false, true, false, GLColor(13, 4, 1, 255));
1800         testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1801                             GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false, false,
1802                             GLColor(55, 13, 4, 128));
1803 
1804         testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1805                                GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, false, false,
1806                                GLColor(55, 13, 4, 255));
1807         testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1808                                GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, true, false,
1809                                GLColor(13, 4, 1, 255));
1810         testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1811                                GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false,
1812                                false, GLColor(55, 13, 4, 128));
1813     }
1814 }
1815 
1816 // Test the newly added ES3 float formats
TEST_P(CopyTextureTestES3,ES3FloatFormats)1817 TEST_P(CopyTextureTestES3, ES3FloatFormats)
1818 {
1819     if (!checkExtensions())
1820     {
1821         return;
1822     }
1823 
1824     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
1825     // http://anglebug.com/4092
1826     ANGLE_SKIP_TEST_IF(IsVulkan());
1827 
1828     auto testOutput = [this](GLuint texture, const GLColor32F &expectedColor) {
1829         constexpr char kVS[] =
1830             "#version 300 es\n"
1831             "in vec4 position;\n"
1832             "out vec2 texcoord;\n"
1833             "void main()\n"
1834             "{\n"
1835             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1836             "    texcoord = (position.xy * 0.5) + 0.5;\n"
1837             "}\n";
1838 
1839         constexpr char kFS[] =
1840             "#version 300 es\n"
1841             "precision mediump float;\n"
1842             "uniform sampler2D tex;\n"
1843             "in vec2 texcoord;\n"
1844             "out vec4 color;\n"
1845             "void main()\n"
1846             "{\n"
1847             "    color = texture(tex, texcoord);\n"
1848             "}\n";
1849 
1850         ANGLE_GL_PROGRAM(program, kVS, kFS);
1851         glUseProgram(program);
1852 
1853         GLRenderbuffer rbo;
1854         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1855         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
1856 
1857         GLFramebuffer fbo;
1858         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1859         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1860 
1861         glActiveTexture(GL_TEXTURE0);
1862         glBindTexture(GL_TEXTURE_2D, texture);
1863         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1864         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1865         glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1866 
1867         drawQuad(program, "position", 0.5f, 1.0f, true);
1868 
1869         EXPECT_PIXEL_COLOR32F_NEAR(0, 0, expectedColor, 0.05);
1870     };
1871 
1872     auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1873                                             GLenum sourceType, const GLColor &sourceColor,
1874                                             GLenum destInternalFormat, GLenum destType, bool flipY,
1875                                             bool premultiplyAlpha, bool unmultiplyAlpha,
1876                                             const GLColor32F &expectedColor) {
1877         GLTexture sourceTexture;
1878         glBindTexture(GL_TEXTURE_2D, sourceTexture);
1879         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1880                      &sourceColor);
1881 
1882         GLTexture destTexture;
1883         glBindTexture(GL_TEXTURE_2D, destTexture);
1884 
1885         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
1886                               destType, flipY, premultiplyAlpha, unmultiplyAlpha);
1887         ASSERT_GL_NO_ERROR();
1888 
1889         testOutput(destTexture, expectedColor);
1890     };
1891 
1892     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
1893                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 0.5f));
1894     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
1895                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 0.5f));
1896     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
1897                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 0.5f));
1898 
1899     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
1900                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.0f, 0.0f, 1.0f));
1901     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
1902                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.0f, 0.0f, 1.0f));
1903     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
1904                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.0f, 0.0f, 1.0f));
1905 
1906     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
1907                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.0f, 1.0f));
1908     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
1909                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0f, 1.0f));
1910     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
1911                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.0f, 1.0f));
1912 
1913     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
1914                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
1915     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
1916                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
1917     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
1918                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
1919 
1920     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1921                         GL_R11F_G11F_B10F, GL_FLOAT, false, false, false,
1922                         GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
1923     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1924                         GL_R11F_G11F_B10F, GL_FLOAT, false, true, false,
1925                         GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
1926     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1927                         GL_R11F_G11F_B10F, GL_FLOAT, false, false, true,
1928                         GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
1929 
1930     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
1931                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
1932     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
1933                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
1934     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
1935                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
1936 }
1937 
1938 // Test the newly added ES3 unsigned integer formats
TEST_P(CopyTextureTestES3,ES3UintFormats)1939 TEST_P(CopyTextureTestES3, ES3UintFormats)
1940 {
1941     ANGLE_SKIP_TEST_IF(IsLinux() && IsOpenGL() && IsIntel());
1942     // http://anglebug.com/4092
1943     ANGLE_SKIP_TEST_IF(IsVulkan());
1944 
1945     if (!checkExtensions())
1946     {
1947         return;
1948     }
1949 
1950     using GLColor32U = std::tuple<GLuint, GLuint, GLuint, GLuint>;
1951 
1952     auto testOutput = [this](GLuint texture, const GLColor32U &expectedColor) {
1953         constexpr char kVS[] =
1954             "#version 300 es\n"
1955             "in vec4 position;\n"
1956             "out vec2 texcoord;\n"
1957             "void main()\n"
1958             "{\n"
1959             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1960             "    texcoord = (position.xy * 0.5) + 0.5;\n"
1961             "}\n";
1962 
1963         constexpr char kFS[] =
1964             "#version 300 es\n"
1965             "precision mediump float;\n"
1966             "precision mediump usampler2D;\n"
1967             "in vec2 texcoord;\n"
1968             "uniform usampler2D tex;\n"
1969             "out uvec4 color;\n"
1970             "void main()\n"
1971             "{\n"
1972             "    color = texture(tex, texcoord);\n"
1973             "}\n";
1974 
1975         ANGLE_GL_PROGRAM(program, kVS, kFS);
1976         glUseProgram(program);
1977 
1978         GLRenderbuffer rbo;
1979         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1980         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8UI, 1, 1);
1981 
1982         GLFramebuffer fbo;
1983         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1984         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1985 
1986         glActiveTexture(GL_TEXTURE0);
1987         glBindTexture(GL_TEXTURE_2D, texture);
1988         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1989         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1990         glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1991 
1992         drawQuad(program, "position", 0.5f, 1.0f, true);
1993         ASSERT_GL_NO_ERROR();
1994 
1995         GLuint pixel[4] = {0};
1996         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, pixel);
1997         ASSERT_GL_NO_ERROR();
1998         EXPECT_NEAR(std::get<0>(expectedColor), pixel[0], 1);
1999         EXPECT_NEAR(std::get<1>(expectedColor), pixel[1], 1);
2000         EXPECT_NEAR(std::get<2>(expectedColor), pixel[2], 1);
2001         EXPECT_NEAR(std::get<3>(expectedColor), pixel[3], 1);
2002     };
2003 
2004     auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
2005                                             GLenum sourceType, const GLColor &sourceColor,
2006                                             GLenum destInternalFormat, GLenum destType, bool flipY,
2007                                             bool premultiplyAlpha, bool unmultiplyAlpha,
2008                                             const GLColor32U &expectedColor) {
2009         GLTexture sourceTexture;
2010         glBindTexture(GL_TEXTURE_2D, sourceTexture);
2011         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
2012                      &sourceColor);
2013 
2014         GLTexture destTexture;
2015         glBindTexture(GL_TEXTURE_2D, destTexture);
2016 
2017         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
2018                               destType, flipY, premultiplyAlpha, unmultiplyAlpha);
2019         ASSERT_GL_NO_ERROR();
2020 
2021         testOutput(destTexture, expectedColor);
2022     };
2023 
2024     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2025                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 128));
2026     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2027                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 128));
2028     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2029                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 128));
2030 
2031     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2032                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 1));
2033     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2034                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 1));
2035     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2036                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 1));
2037 
2038     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2039                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 0, 1));
2040     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2041                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 0, 1));
2042     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2043                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 0, 1));
2044 
2045     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R8UI,
2046                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 0, 0, 1));
2047     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R8UI,
2048                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 0, 0, 1));
2049     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(120, 64, 32, 128), GL_R8UI,
2050                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(240, 0, 0, 1));
2051 }
2052 
2053 #ifdef Bool
2054 // X11 craziness.
2055 #    undef Bool
2056 #endif
2057 
2058 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
2059 // tests should be run against.
2060 ANGLE_INSTANTIATE_TEST_ES2(CopyTextureTest);
2061 ANGLE_INSTANTIATE_TEST_COMBINE_5(CopyTextureVariationsTest,
2062                                  CopyTextureVariationsTestPrint,
2063                                  testing::ValuesIn(kCopyTextureVariationsSrcFormats),
2064                                  testing::ValuesIn(kCopyTextureVariationsDstFormats),
2065                                  testing::Bool(),  // flipY
2066                                  testing::Bool(),  // premultiplyAlpha
2067                                  testing::Bool(),  // unmultiplyAlpha
2068                                  ES2_D3D9(),
2069                                  ES2_D3D11(),
2070                                  ES2_OPENGL(),
2071                                  ES2_OPENGLES(),
2072                                  ES2_VULKAN());
2073 ANGLE_INSTANTIATE_TEST_ES2(CopyTextureTestWebGL);
2074 ANGLE_INSTANTIATE_TEST(CopyTextureTestDest,
2075                        ES2_D3D11(),
2076                        ES2_OPENGL(),
2077                        ES2_OPENGLES(),
2078                        ES2_VULKAN());
2079 ANGLE_INSTANTIATE_TEST_ES3(CopyTextureTestES3);
2080 
2081 }  // namespace angle
2082