• 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     testCopyTexture(GL_TEXTURE_2D, std::get<1>(GetParam()), std::get<2>(GetParam()),
871                     std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
872 }
873 
TEST_P(CopyTextureVariationsTest,CopySubTexture)874 TEST_P(CopyTextureVariationsTest, CopySubTexture)
875 {
876     testCopySubTexture(GL_TEXTURE_2D, std::get<1>(GetParam()), std::get<2>(GetParam()),
877                        std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
878 }
879 
TEST_P(CopyTextureVariationsTest,CopyTextureRectangle)880 TEST_P(CopyTextureVariationsTest, CopyTextureRectangle)
881 {
882     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_texture_rectangle"));
883 
884     testCopyTexture(GL_TEXTURE_RECTANGLE_ANGLE, std::get<1>(GetParam()), std::get<2>(GetParam()),
885                     std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
886 }
887 
TEST_P(CopyTextureVariationsTest,CopySubTextureRectangle)888 TEST_P(CopyTextureVariationsTest, CopySubTextureRectangle)
889 {
890     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_texture_rectangle"));
891 
892     testCopySubTexture(GL_TEXTURE_RECTANGLE_ANGLE, std::get<1>(GetParam()), std::get<2>(GetParam()),
893                        std::get<3>(GetParam()), std::get<4>(GetParam()), std::get<5>(GetParam()));
894 }
895 
896 // Test that copying to cube maps works
TEST_P(CopyTextureTest,CubeMapTarget)897 TEST_P(CopyTextureTest, CubeMapTarget)
898 {
899     if (!checkExtensions())
900     {
901         return;
902     }
903 
904     // http://anglebug.com/1932
905     ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsDesktopOpenGL());
906 
907     // http://anglebug.com/3145
908     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
909 
910     GLColor pixels[7] = {
911         GLColor(10u, 13u, 16u, 19u), GLColor(20u, 23u, 26u, 29u), GLColor(30u, 33u, 36u, 39u),
912         GLColor(40u, 43u, 46u, 49u), GLColor(50u, 53u, 56u, 59u), GLColor(60u, 63u, 66u, 69u),
913         GLColor(70u, 73u, 76u, 79u),
914     };
915 
916     GLTexture textures[2];
917 
918     glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
919     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
920          face++)
921     {
922         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
923     }
924 
925     for (size_t i = 0; i < 2; ++i)
926     {
927         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
928              face++)
929         {
930             glBindTexture(GL_TEXTURE_2D, textures[0]);
931             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
932                          &pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
933 
934             glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 1, 1, false,
935                                      false, false);
936         }
937 
938         EXPECT_GL_NO_ERROR();
939 
940         GLFramebuffer fbo;
941         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
942 
943         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
944              face++)
945         {
946             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
947 
948             // Check that FB is complete.
949             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
950 
951             EXPECT_PIXEL_COLOR_EQ(0, 0, pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
952 
953             EXPECT_GL_NO_ERROR();
954         }
955     }
956 }
957 
958 // Test that we can successfully copy into incomplete cube maps. Regression test for
959 // http://anglebug.com/3384
TEST_P(CopyTextureTest,IncompleteCubeMap)960 TEST_P(CopyTextureTest, IncompleteCubeMap)
961 {
962     if (!checkExtensions())
963     {
964         return;
965     }
966 
967     GLTexture texture2D;
968     GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
969     glBindTexture(GL_TEXTURE_2D, texture2D);
970     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
971 
972     GLTexture textureCube;
973     glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
974     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
975          face++)
976     {
977         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
978     }
979 
980     // Set one face to 2x2
981     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
982                  rgbaPixels);
983 
984     // Copy into the incomplete face
985     glCopySubTextureCHROMIUM(texture2D, 0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, textureCube, 0, 0, 0, 0,
986                              0, 2, 2, false, false, false);
987     EXPECT_GL_NO_ERROR();
988 }
989 
990 // Test BGRA to RGBA cube map copy
TEST_P(CopyTextureTest,CubeMapTargetBGRA)991 TEST_P(CopyTextureTest, CubeMapTargetBGRA)
992 {
993     if (!checkExtensions())
994     {
995         return;
996     }
997 
998     if (!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
999     {
1000         return;
1001     }
1002 
1003     // http://anglebug.com/3145
1004     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1005 
1006     GLColor pixels[7] = {
1007         GLColor(10u, 13u, 16u, 19u), GLColor(20u, 23u, 26u, 29u), GLColor(30u, 33u, 36u, 39u),
1008         GLColor(40u, 43u, 46u, 49u), GLColor(50u, 53u, 56u, 59u), GLColor(60u, 63u, 66u, 69u),
1009         GLColor(70u, 73u, 76u, 79u),
1010     };
1011 
1012     GLTexture textures[2];
1013 
1014     glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1015     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1016          face++)
1017     {
1018         glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1019     }
1020 
1021     for (size_t i = 0; i < 2; ++i)
1022     {
1023         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1024              face++)
1025         {
1026             glBindTexture(GL_TEXTURE_2D, textures[0]);
1027             glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
1028                          &pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i]);
1029 
1030             glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 1, 1, false,
1031                                      false, false);
1032         }
1033 
1034         EXPECT_GL_NO_ERROR();
1035 
1036         GLFramebuffer fbo;
1037         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1038 
1039         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1040              face++)
1041         {
1042             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1043 
1044             // Check that FB is complete.
1045             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1046 
1047             GLColor converted = pixels[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i];
1048             std::swap(converted.R, converted.B);
1049             EXPECT_PIXEL_COLOR_EQ(0, 0, converted);
1050 
1051             EXPECT_GL_NO_ERROR();
1052         }
1053     }
1054 }
1055 
1056 // Test cube map copies with RGB format
TEST_P(CopyTextureTest,CubeMapTargetRGB)1057 TEST_P(CopyTextureTest, CubeMapTargetRGB)
1058 {
1059     if (!checkExtensions())
1060     {
1061         return;
1062     }
1063 
1064     // http://anglebug.com/1932
1065     ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsDesktopOpenGL());
1066 
1067     // http://anglebug.com/3145
1068     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
1069 
1070     constexpr uint8_t pixels[16 * 7] = {
1071         0u,   3u,   6u,   10u,  13u,  16u,  0, 0, 20u,  23u,  26u,  30u,  33u,  36u,  0, 0,  // 2x2
1072         40u,  43u,  46u,  50u,  53u,  56u,  0, 0, 60u,  63u,  66u,  70u,  73u,  76u,  0, 0,  // 2x2
1073         80u,  83u,  86u,  90u,  93u,  96u,  0, 0, 100u, 103u, 106u, 110u, 113u, 116u, 0, 0,  // 2x2
1074         120u, 123u, 126u, 130u, 133u, 136u, 0, 0, 140u, 143u, 146u, 160u, 163u, 166u, 0, 0,  // 2x2
1075         170u, 173u, 176u, 180u, 183u, 186u, 0, 0, 190u, 193u, 196u, 200u, 203u, 206u, 0, 0,  // 2x2
1076         210u, 213u, 216u, 220u, 223u, 226u, 0, 0, 230u, 233u, 236u, 240u, 243u, 246u, 0, 0,  // 2x2
1077         10u,  50u,  100u, 30u,  80u,  130u, 0, 0, 60u,  110u, 160u, 90u,  140u, 200u, 0, 0,  // 2x2
1078     };
1079 
1080     GLTexture textures[2];
1081 
1082     glBindTexture(GL_TEXTURE_CUBE_MAP, textures[1]);
1083     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1084          face++)
1085     {
1086         glTexImage2D(face, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1087     }
1088 
1089     for (size_t i = 0; i < 2; ++i)
1090     {
1091         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1092              face++)
1093         {
1094             glBindTexture(GL_TEXTURE_2D, textures[0]);
1095             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
1096                          &pixels[(face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) * 16]);
1097 
1098             glCopySubTextureCHROMIUM(textures[0], 0, face, textures[1], 0, 0, 0, 0, 0, 2, 2, false,
1099                                      false, false);
1100         }
1101 
1102         EXPECT_GL_NO_ERROR();
1103 
1104         GLFramebuffer fbo;
1105         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1106 
1107         for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1108              face++)
1109         {
1110             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, textures[1], 0);
1111 
1112             // Check that FB is complete.
1113             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1114 
1115             const uint8_t *faceData = &pixels[(face - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) * 16];
1116             EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(faceData[0], faceData[1], faceData[2], 255));
1117             EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor(faceData[3], faceData[4], faceData[5], 255));
1118             EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor(faceData[8], faceData[9], faceData[10], 255));
1119             EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor(faceData[11], faceData[12], faceData[13], 255));
1120 
1121             EXPECT_GL_NO_ERROR();
1122         }
1123     }
1124 }
1125 
1126 // Test that copying to non-zero mipmaps works
TEST_P(CopyTextureTest,CopyToMipmap)1127 TEST_P(CopyTextureTest, CopyToMipmap)
1128 {
1129     if (!checkExtensions())
1130     {
1131         return;
1132     }
1133 
1134     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
1135                        !IsGLExtensionEnabled("GL_OES_fbo_render_mipmap"));
1136 
1137     ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel());
1138 
1139     GLColor pixels[] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red};
1140 
1141     GLTexture textures[2];
1142 
1143     glBindTexture(GL_TEXTURE_2D, textures[0]);
1144     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1145     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1146 
1147     glBindTexture(GL_TEXTURE_2D, textures[1]);
1148     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1149     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1150     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1151 
1152     std::vector<std::pair<GLint, GLint>> soureDestPairs;
1153     soureDestPairs.push_back(std::make_pair(0, 1));
1154 
1155     // ES3 allows copying from non-zero mips
1156     if (getClientMajorVersion() >= 3)
1157     {
1158         soureDestPairs.push_back(std::make_pair(1, 2));
1159     }
1160 
1161     for (const auto &sourceDestPair : soureDestPairs)
1162     {
1163         const GLint sourceLevel = sourceDestPair.first;
1164         const GLint destLevel   = sourceDestPair.second;
1165 
1166         glCopyTextureCHROMIUM(textures[0], sourceLevel, GL_TEXTURE_2D, textures[1], destLevel,
1167                               GL_RGBA, GL_UNSIGNED_BYTE, false, false, false);
1168 
1169         EXPECT_GL_NO_ERROR();
1170 
1171         GLFramebuffer fbo;
1172         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1173         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],
1174                                destLevel);
1175 
1176         // Check that FB is complete.
1177         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1178 
1179         EXPECT_PIXEL_COLOR_EQ(0, 0, pixels[0]);
1180 
1181         EXPECT_GL_NO_ERROR();
1182     }
1183 }
1184 
1185 // Test that copying from an RGBA8 texture to RGBA4 results in exactly 4-bit precision in the result
TEST_P(CopyTextureTest,DownsampleRGBA4444)1186 TEST_P(CopyTextureTest, DownsampleRGBA4444)
1187 {
1188     // Downsampling on copy is only guarenteed on D3D11
1189     ANGLE_SKIP_TEST_IF(!IsD3D11());
1190 
1191     GLTexture textures[2];
1192 
1193     GLColor pixels[] = {GLColor(0, 5, 6, 7), GLColor(17, 22, 25, 24), GLColor(34, 35, 36, 36),
1194                         GLColor(51, 53, 55, 55)};
1195 
1196     glBindTexture(GL_TEXTURE_2D, textures[0]);
1197     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1198 
1199     glBindTexture(GL_TEXTURE_2D, textures[1]);
1200     glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGBA,
1201                           GL_UNSIGNED_SHORT_4_4_4_4, GL_FALSE, GL_FALSE, GL_FALSE);
1202 
1203     GLFramebuffer fbo;
1204     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1205     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1206 
1207     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 0), 1.0);
1208     EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(17, 17, 17, 17), 1.0);
1209     EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(34, 34, 34, 34), 1.0);
1210     EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(51, 51, 51, 51), 1.0);
1211 
1212     testGradientDownsampleUniqueValues(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, {16, 16, 16, 16});
1213 }
1214 
1215 // Test that copying from an RGBA8 texture to RGB565 results in exactly 4-bit precision in the
1216 // result
TEST_P(CopyTextureTest,DownsampleRGB565)1217 TEST_P(CopyTextureTest, DownsampleRGB565)
1218 {
1219     // Downsampling on copy is only guarenteed on D3D11
1220     ANGLE_SKIP_TEST_IF(!IsD3D11());
1221 
1222     GLTexture textures[2];
1223 
1224     GLColor pixels[] = {GLColor(0, 5, 2, 14), GLColor(17, 22, 25, 30), GLColor(34, 33, 36, 46),
1225                         GLColor(50, 54, 49, 60)};
1226 
1227     glBindTexture(GL_TEXTURE_2D, textures[0]);
1228     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1229 
1230     glBindTexture(GL_TEXTURE_2D, textures[1]);
1231     glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGB,
1232                           GL_UNSIGNED_SHORT_5_6_5, GL_FALSE, GL_FALSE, GL_FALSE);
1233 
1234     GLFramebuffer fbo;
1235     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1236     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1237 
1238     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 4, 0, 255), 1.0);
1239     EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(16, 20, 25, 255), 1.0);
1240     EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(33, 32, 33, 255), 1.0);
1241     EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(49, 53, 49, 255), 1.0);
1242 
1243     testGradientDownsampleUniqueValues(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, {32, 64, 32, 1});
1244 }
1245 
1246 // Test that copying from an RGBA8 texture to RGBA5551 results in exactly 4-bit precision in the
1247 // result
TEST_P(CopyTextureTest,DownsampleRGBA5551)1248 TEST_P(CopyTextureTest, DownsampleRGBA5551)
1249 {
1250     // Downsampling on copy is only guarenteed on D3D11
1251     ANGLE_SKIP_TEST_IF(!IsD3D11());
1252 
1253     GLTexture textures[2];
1254 
1255     GLColor pixels[] = {GLColor(0, 1, 2, 3), GLColor(14, 16, 17, 18), GLColor(33, 34, 36, 46),
1256                         GLColor(50, 51, 52, 255)};
1257 
1258     glBindTexture(GL_TEXTURE_2D, textures[0]);
1259     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1260 
1261     glBindTexture(GL_TEXTURE_2D, textures[1]);
1262     glCopyTextureCHROMIUM(textures[0], 0, GL_TEXTURE_2D, textures[1], 0, GL_RGBA,
1263                           GL_UNSIGNED_SHORT_5_5_5_1, GL_FALSE, GL_FALSE, GL_FALSE);
1264 
1265     GLFramebuffer fbo;
1266     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1267     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1268 
1269     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 0), 1.0);
1270     EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(16, 16, 16, 0), 1.0);
1271     EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(33, 33, 33, 0), 1.0);
1272     EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(49, 49, 49, 255), 1.0);
1273 
1274     testGradientDownsampleUniqueValues(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, {32, 32, 32, 2});
1275 }
1276 
1277 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination
TEST_P(CopyTextureTestDest,Luminance)1278 TEST_P(CopyTextureTestDest, Luminance)
1279 {
1280     if (!checkExtensions())
1281     {
1282         return;
1283     }
1284 
1285     GLColor originalPixels(50u, 100u, 150u, 200u);
1286     GLColor expectedPixels(50u, 50u, 50u, 255u);
1287 
1288     // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1289     // texture to verify contents.
1290     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1291     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1292     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1293     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1294 
1295     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1296                           GL_UNSIGNED_BYTE, false, false, false);
1297 
1298     EXPECT_GL_NO_ERROR();
1299 
1300     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1301                           GL_UNSIGNED_BYTE, false, false, false);
1302 
1303     EXPECT_GL_NO_ERROR();
1304 
1305     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1306 }
1307 
1308 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
1309 // UnpackPremultiply parameter
TEST_P(CopyTextureTestDest,LuminanceMultiply)1310 TEST_P(CopyTextureTestDest, LuminanceMultiply)
1311 {
1312     if (!checkExtensions())
1313     {
1314         return;
1315     }
1316 
1317     GLColor originalPixels(50u, 100u, 150u, 200u);
1318     GLColor expectedPixels(39u, 39u, 39u, 255u);
1319 
1320     // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1321     // texture to verify contents.
1322     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1323     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1324     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1325     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1326 
1327     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1328                           GL_UNSIGNED_BYTE, false, true, false);
1329 
1330     EXPECT_GL_NO_ERROR();
1331 
1332     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1333                           GL_UNSIGNED_BYTE, false, false, false);
1334 
1335     EXPECT_GL_NO_ERROR();
1336 
1337     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1338 }
1339 
1340 // Test to ensure that CopyTexture works with LUMINANCE texture as a destination with
1341 // UnpackUnmultiply parameter
TEST_P(CopyTextureTestDest,LuminanceUnmultiply)1342 TEST_P(CopyTextureTestDest, LuminanceUnmultiply)
1343 {
1344     if (!checkExtensions())
1345     {
1346         return;
1347     }
1348 
1349     GLColor originalPixels(50u, 100u, 150u, 200u);
1350     GLColor expectedPixels(64u, 64u, 64u, 255u);
1351 
1352     // ReadPixels doesn't work with LUMINANCE (non-renderable), so we copy again back to an RGBA
1353     // texture to verify contents.
1354     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1355     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1356     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1357     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
1358 
1359     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE,
1360                           GL_UNSIGNED_BYTE, false, false, true);
1361 
1362     EXPECT_GL_NO_ERROR();
1363 
1364     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1365                           GL_UNSIGNED_BYTE, false, false, false);
1366 
1367     EXPECT_GL_NO_ERROR();
1368 
1369     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1370 }
1371 
1372 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination
TEST_P(CopyTextureTestDest,LuminanceAlpha)1373 TEST_P(CopyTextureTestDest, LuminanceAlpha)
1374 {
1375     if (!checkExtensions())
1376     {
1377         return;
1378     }
1379 
1380     GLColor originalPixels(50u, 100u, 150u, 200u);
1381     GLColor expectedPixels(50u, 50u, 50u, 200u);
1382 
1383     // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1384     // RGBA texture to verify contents.
1385     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1386     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1387     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1388     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1389                  GL_UNSIGNED_BYTE, nullptr);
1390 
1391     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1392                           GL_UNSIGNED_BYTE, false, false, false);
1393 
1394     EXPECT_GL_NO_ERROR();
1395 
1396     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1397                           GL_UNSIGNED_BYTE, false, false, false);
1398 
1399     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1400 }
1401 
1402 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
1403 // UnpackPremultiply parameter
TEST_P(CopyTextureTestDest,LuminanceAlphaMultiply)1404 TEST_P(CopyTextureTestDest, LuminanceAlphaMultiply)
1405 {
1406     if (!checkExtensions())
1407     {
1408         return;
1409     }
1410 
1411     GLColor originalPixels(50u, 100u, 150u, 200u);
1412     GLColor expectedPixels(39u, 39u, 39u, 200u);
1413 
1414     // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1415     // RGBA texture to verify contents.
1416     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1417     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1418     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1419     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1420                  GL_UNSIGNED_BYTE, nullptr);
1421 
1422     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1423                           GL_UNSIGNED_BYTE, false, true, false);
1424 
1425     EXPECT_GL_NO_ERROR();
1426 
1427     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1428                           GL_UNSIGNED_BYTE, false, false, false);
1429 
1430     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1431 }
1432 
1433 // Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture as a destination with
1434 // UnpackUnmultiplyAlpha parameter
TEST_P(CopyTextureTestDest,LuminanceAlphaUnmultiply)1435 TEST_P(CopyTextureTestDest, LuminanceAlphaUnmultiply)
1436 {
1437     if (!checkExtensions())
1438     {
1439         return;
1440     }
1441 
1442     GLColor originalPixels(50u, 100u, 150u, 200u);
1443     GLColor expectedPixels(64u, 64u, 64u, 200u);
1444 
1445     // ReadPixels doesn't work with LUMINANCE_ALPHA (non-renderable), so we copy again back to an
1446     // RGBA texture to verify contents.
1447     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1448     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1449     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1450     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
1451                  GL_UNSIGNED_BYTE, nullptr);
1452 
1453     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_LUMINANCE_ALPHA,
1454                           GL_UNSIGNED_BYTE, false, false, true);
1455 
1456     EXPECT_GL_NO_ERROR();
1457 
1458     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1459                           GL_UNSIGNED_BYTE, false, false, false);
1460 
1461     EXPECT_GL_NO_ERROR();
1462 
1463     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1464 }
1465 
1466 // Test to ensure that CopyTexture works with ALPHA texture as a destination
TEST_P(CopyTextureTestDest,Alpha)1467 TEST_P(CopyTextureTestDest, Alpha)
1468 {
1469     if (!checkExtensions())
1470     {
1471         return;
1472     }
1473 
1474     GLColor originalPixels(50u, 100u, 150u, 155u);
1475     GLColor expectedPixels(0u, 0u, 0u, 155u);
1476 
1477     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1478     // texture to verify contents.
1479     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1480     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1481     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1482     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1483 
1484     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1485                           GL_UNSIGNED_BYTE, false, false, false);
1486 
1487     EXPECT_GL_NO_ERROR();
1488 
1489     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1490                           GL_UNSIGNED_BYTE, false, false, false);
1491 
1492     EXPECT_GL_NO_ERROR();
1493 
1494     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1495 }
1496 
1497 // Test to ensure that CopyTexture works with ALPHA texture as a destination with
1498 // UnpackPremultiplyAlpha parameter
TEST_P(CopyTextureTestDest,AlphaMultiply)1499 TEST_P(CopyTextureTestDest, AlphaMultiply)
1500 {
1501     if (!checkExtensions())
1502     {
1503         return;
1504     }
1505 
1506     GLColor originalPixels(50u, 100u, 150u, 155u);
1507     GLColor expectedPixels(0u, 0u, 0u, 155u);
1508 
1509     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1510     // texture to verify contents.
1511     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1512     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1513     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1514     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1515 
1516     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1517                           GL_UNSIGNED_BYTE, false, true, false);
1518 
1519     EXPECT_GL_NO_ERROR();
1520 
1521     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1522                           GL_UNSIGNED_BYTE, false, false, false);
1523 
1524     EXPECT_GL_NO_ERROR();
1525 
1526     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1527 }
1528 
1529 // Test to ensure that CopyTexture works with ALPHA texture as a destination with
1530 // UnpackUnmultiplyAlpha parameter
TEST_P(CopyTextureTestDest,AlphaUnmultiply)1531 TEST_P(CopyTextureTestDest, AlphaUnmultiply)
1532 {
1533     if (!checkExtensions())
1534     {
1535         return;
1536     }
1537 
1538     GLColor originalPixels(50u, 100u, 150u, 155u);
1539     GLColor expectedPixels(0u, 0u, 0u, 155u);
1540 
1541     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1542     // texture to verify contents.
1543     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1544     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1545     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1546     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1547 
1548     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1549                           GL_UNSIGNED_BYTE, false, false, true);
1550 
1551     EXPECT_GL_NO_ERROR();
1552 
1553     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1554                           GL_UNSIGNED_BYTE, false, false, false);
1555 
1556     EXPECT_GL_NO_ERROR();
1557 
1558     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1559 }
1560 
1561 // Test to ensure that CopyTexture uses the correct ALPHA passthrough shader to ensure RGB channels
1562 // are set to 0.
TEST_P(CopyTextureTestDest,AlphaCopyWithRGB)1563 TEST_P(CopyTextureTestDest, AlphaCopyWithRGB)
1564 {
1565     // http://anglebug.com/4121
1566     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGLES());
1567     ANGLE_SKIP_TEST_IF(!checkExtensions());
1568 
1569     GLColor originalPixels(50u, 100u, 150u, 155u);
1570     GLColor expectedPixels(0u, 0u, 0u, 155u);
1571 
1572     // ReadPixels doesn't work with ALPHA (non-renderable), so we copy again back to an RGBA
1573     // texture to verify contents.
1574     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
1575     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &originalPixels);
1576     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1577     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_HALF_FLOAT_OES, nullptr);
1578 
1579     glCopyTextureCHROMIUM(mTextures[1], 0, GL_TEXTURE_2D, mTextures[0], 0, GL_ALPHA,
1580                           GL_HALF_FLOAT_OES, false, false, false);
1581 
1582     EXPECT_GL_NO_ERROR();
1583 
1584     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1585                           GL_UNSIGNED_BYTE, false, false, false);
1586 
1587     EXPECT_GL_NO_ERROR();
1588 
1589     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
1590 }
1591 
1592 // Bug where TEXTURE_SWIZZLE_RGBA was not reset after the Luminance workaround. (crbug.com/1022080)
TEST_P(CopyTextureTestES3,LuminanceWorkaroundTextureSwizzleBug)1593 TEST_P(CopyTextureTestES3, LuminanceWorkaroundTextureSwizzleBug)
1594 {
1595 
1596     {
1597         GLColor pixels(50u, 20u, 100u, 150u);
1598 
1599         // Hit BlitGL::copySubImageToLUMAWorkaroundTexture by copying an ALPHA texture
1600         GLTexture srcTexture;
1601         glBindTexture(GL_TEXTURE_2D, srcTexture);
1602         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
1603 
1604         GLFramebuffer srcFBO;
1605         glBindFramebuffer(GL_FRAMEBUFFER, srcFBO);
1606         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture, 0);
1607 
1608         GLTexture dstTexture;
1609         glBindTexture(GL_TEXTURE_2D, dstTexture);
1610         glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
1611 
1612         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
1613         EXPECT_GL_NO_ERROR();
1614     }
1615 
1616     {
1617         // This time hit BlitGL::blitColorBufferWithShader by copying an SRGB texture
1618         GLColor pixels(100u, 200u, 50u, 210u);
1619 
1620         GLTexture srcTexture;
1621         glBindTexture(GL_TEXTURE_2D, srcTexture);
1622         glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
1623                      GL_UNSIGNED_BYTE, &pixels);
1624 
1625         GLFramebuffer srcFBO;
1626         glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
1627         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexture,
1628                                0);
1629 
1630         GLTexture dstTexture;
1631         glBindTexture(GL_TEXTURE_2D, dstTexture);
1632         glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
1633                      GL_UNSIGNED_BYTE, nullptr);
1634 
1635         GLFramebuffer dstFBO;
1636         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFBO);
1637         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTexture,
1638                                0);
1639 
1640         glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1641 
1642         // The previous workaround should not affect this copy
1643         glBindFramebuffer(GL_FRAMEBUFFER, dstFBO);
1644         EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
1645     }
1646 }
1647 
1648 // Test to ensure that CopyTexture will fail with a non-zero level and NPOT texture in WebGL
TEST_P(CopyTextureTestWebGL,NPOT)1649 TEST_P(CopyTextureTestWebGL, NPOT)
1650 {
1651     if (IsGLExtensionRequestable("GL_CHROMIUM_copy_texture"))
1652     {
1653         glRequestExtensionANGLE("GL_CHROMIUM_copy_texture");
1654     }
1655     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"));
1656 
1657     std::vector<GLColor> pixelData(10 * 10, GLColor::red);
1658 
1659     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1660     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 10, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
1661 
1662     // Do a basic copy to make sure things work
1663     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
1664                           GL_UNSIGNED_BYTE, false, false, false);
1665 
1666     EXPECT_GL_NO_ERROR();
1667 
1668     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1669 
1670     // Do the same operation with destLevel 1, which should fail
1671     glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 1, GL_RGBA,
1672                           GL_UNSIGNED_BYTE, false, false, false);
1673 
1674     EXPECT_GL_ERROR(GL_INVALID_VALUE);
1675 }
1676 
1677 // Test the newly added ES3 unorm formats
TEST_P(CopyTextureTestES3,ES3UnormFormats)1678 TEST_P(CopyTextureTestES3, ES3UnormFormats)
1679 {
1680     if (!checkExtensions())
1681     {
1682         return;
1683     }
1684     // http://anglebug.com/4092
1685     ANGLE_SKIP_TEST_IF(IsAndroid());
1686 
1687     auto testOutput = [this](GLuint texture, const GLColor &expectedColor) {
1688         constexpr char kVS[] =
1689             "#version 300 es\n"
1690             "in vec4 position;\n"
1691             "out vec2 texcoord;\n"
1692             "void main()\n"
1693             "{\n"
1694             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1695             "    texcoord = (position.xy * 0.5) + 0.5;\n"
1696             "}\n";
1697 
1698         constexpr char kFS[] =
1699             "#version 300 es\n"
1700             "precision mediump float;\n"
1701             "uniform sampler2D tex;\n"
1702             "in vec2 texcoord;\n"
1703             "out vec4 color;\n"
1704             "void main()\n"
1705             "{\n"
1706             "    color = texture(tex, texcoord);\n"
1707             "}\n";
1708 
1709         ANGLE_GL_PROGRAM(program, kVS, kFS);
1710         glUseProgram(program);
1711 
1712         GLRenderbuffer rbo;
1713         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1714         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
1715 
1716         GLFramebuffer fbo;
1717         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1718         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1719 
1720         glActiveTexture(GL_TEXTURE0);
1721         glBindTexture(GL_TEXTURE_2D, texture);
1722         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1723         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1724         glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1725 
1726         drawQuad(program, "position", 0.5f, 1.0f, true);
1727 
1728         EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, 1.0);
1729     };
1730 
1731     auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1732                                             GLenum sourceType, const GLColor &sourceColor,
1733                                             GLenum destInternalFormat, GLenum destType, bool flipY,
1734                                             bool premultiplyAlpha, bool unmultiplyAlpha,
1735                                             const GLColor &expectedColor) {
1736         GLTexture sourceTexture;
1737         glBindTexture(GL_TEXTURE_2D, sourceTexture);
1738         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1739                      &sourceColor);
1740 
1741         GLTexture destTexture;
1742         glBindTexture(GL_TEXTURE_2D, destTexture);
1743 
1744         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
1745                               destType, flipY, premultiplyAlpha, unmultiplyAlpha);
1746         ASSERT_GL_NO_ERROR();
1747 
1748         testOutput(destTexture, expectedColor);
1749     };
1750 
1751     auto testSubCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1752                                                GLenum sourceType, const GLColor &sourceColor,
1753                                                GLenum destInternalFormat, GLenum destFormat,
1754                                                GLenum destType, bool flipY, bool premultiplyAlpha,
1755                                                bool unmultiplyAlpha, const GLColor &expectedColor) {
1756         GLTexture sourceTexture;
1757         glBindTexture(GL_TEXTURE_2D, sourceTexture);
1758         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1759                      &sourceColor);
1760 
1761         GLTexture destTexture;
1762         glBindTexture(GL_TEXTURE_2D, destTexture);
1763 
1764         glTexImage2D(GL_TEXTURE_2D, 0, destInternalFormat, 1, 1, 0, destFormat, destType, nullptr);
1765         glCopySubTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 0, 1, 1,
1766                                  flipY, premultiplyAlpha, unmultiplyAlpha);
1767         ASSERT_GL_NO_ERROR();
1768 
1769         testOutput(destTexture, expectedColor);
1770     };
1771 
1772     // New LUMA source formats
1773     testCopyCombination(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGB,
1774                         GL_UNSIGNED_BYTE, false, false, false, GLColor(128, 128, 128, 255));
1775     testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1776                         GLColor(128, 64, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, false, false,
1777                         GLColor(128, 128, 128, 255));
1778     testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1779                         GLColor(128, 64, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, true, false,
1780                         GLColor(32, 32, 32, 255));
1781     testCopyCombination(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
1782                         GLColor(128, 128, 0, 0), GL_RGB, GL_UNSIGNED_BYTE, false, false, true,
1783                         GLColor(255, 255, 255, 255));
1784     testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1785                         GL_UNSIGNED_BYTE, false, false, false, GLColor(0, 0, 0, 128));
1786     testCopyCombination(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, GLColor(128, 0, 0, 0), GL_RGBA,
1787                         GL_UNSIGNED_BYTE, false, false, true, 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, true, false, GLColor(0, 0, 0, 128));
1790 
1791     // New sRGB dest formats
1792     if (IsGLExtensionEnabled("GL_EXT_sRGB"))
1793     {
1794         testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
1795                             GL_UNSIGNED_BYTE, false, false, false, GLColor(55, 13, 4, 255));
1796         testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_SRGB,
1797                             GL_UNSIGNED_BYTE, false, true, false, GLColor(13, 4, 1, 255));
1798         testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1799                             GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false, false,
1800                             GLColor(55, 13, 4, 128));
1801 
1802         testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1803                                GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, false, false,
1804                                GLColor(55, 13, 4, 255));
1805         testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1806                                GL_SRGB, GL_SRGB, GL_UNSIGNED_BYTE, false, true, false,
1807                                GLColor(13, 4, 1, 255));
1808         testSubCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1809                                GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, false, false,
1810                                false, GLColor(55, 13, 4, 128));
1811     }
1812 }
1813 
1814 // Test the newly added ES3 float formats
TEST_P(CopyTextureTestES3,ES3FloatFormats)1815 TEST_P(CopyTextureTestES3, ES3FloatFormats)
1816 {
1817     if (!checkExtensions())
1818     {
1819         return;
1820     }
1821 
1822     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
1823 
1824     auto testOutput = [this](GLuint texture, const GLColor32F &expectedColor) {
1825         constexpr char kVS[] =
1826             "#version 300 es\n"
1827             "in vec4 position;\n"
1828             "out vec2 texcoord;\n"
1829             "void main()\n"
1830             "{\n"
1831             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1832             "    texcoord = (position.xy * 0.5) + 0.5;\n"
1833             "}\n";
1834 
1835         constexpr char kFS[] =
1836             "#version 300 es\n"
1837             "precision mediump float;\n"
1838             "uniform sampler2D tex;\n"
1839             "in vec2 texcoord;\n"
1840             "out vec4 color;\n"
1841             "void main()\n"
1842             "{\n"
1843             "    color = texture(tex, texcoord);\n"
1844             "}\n";
1845 
1846         ANGLE_GL_PROGRAM(program, kVS, kFS);
1847         glUseProgram(program);
1848 
1849         GLRenderbuffer rbo;
1850         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1851         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
1852 
1853         GLFramebuffer fbo;
1854         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1855         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1856 
1857         glActiveTexture(GL_TEXTURE0);
1858         glBindTexture(GL_TEXTURE_2D, texture);
1859         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1860         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1861         glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1862 
1863         drawQuad(program, "position", 0.5f, 1.0f, true);
1864 
1865         EXPECT_PIXEL_COLOR32F_NEAR(0, 0, expectedColor, 0.05);
1866     };
1867 
1868     auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1869                                             GLenum sourceType, const GLColor &sourceColor,
1870                                             GLenum destInternalFormat, GLenum destType, bool flipY,
1871                                             bool premultiplyAlpha, bool unmultiplyAlpha,
1872                                             const GLColor32F &expectedColor) {
1873         GLTexture sourceTexture;
1874         glBindTexture(GL_TEXTURE_2D, sourceTexture);
1875         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
1876                      &sourceColor);
1877 
1878         GLTexture destTexture;
1879         glBindTexture(GL_TEXTURE_2D, destTexture);
1880 
1881         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
1882                               destType, flipY, premultiplyAlpha, unmultiplyAlpha);
1883         ASSERT_GL_NO_ERROR();
1884 
1885         testOutput(destTexture, expectedColor);
1886     };
1887 
1888     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
1889                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 0.5f));
1890     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
1891                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 0.5f));
1892     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA32F,
1893                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 0.5f));
1894 
1895     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
1896                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.0f, 0.0f, 1.0f));
1897     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
1898                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.0f, 0.0f, 1.0f));
1899     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R16F,
1900                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.0f, 0.0f, 1.0f));
1901 
1902     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
1903                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.0f, 1.0f));
1904     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
1905                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0f, 1.0f));
1906     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG16F,
1907                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.0f, 1.0f));
1908 
1909     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
1910                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
1911     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
1912                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
1913     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB16F,
1914                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
1915 
1916     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1917                         GL_R11F_G11F_B10F, GL_FLOAT, false, false, false,
1918                         GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
1919     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1920                         GL_R11F_G11F_B10F, GL_FLOAT, false, true, false,
1921                         GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
1922     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
1923                         GL_R11F_G11F_B10F, GL_FLOAT, false, false, true,
1924                         GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
1925 
1926     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
1927                         GL_FLOAT, false, false, false, GLColor32F(0.5f, 0.25f, 0.125f, 1.0f));
1928     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
1929                         GL_FLOAT, false, true, false, GLColor32F(0.25f, 0.125f, 0.0625f, 1.0f));
1930     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB9_E5,
1931                         GL_FLOAT, false, false, true, GLColor32F(1.0f, 0.5f, 0.25f, 1.0f));
1932 }
1933 
1934 // Test the newly added ES3 unsigned integer formats
TEST_P(CopyTextureTestES3,ES3UintFormats)1935 TEST_P(CopyTextureTestES3, ES3UintFormats)
1936 {
1937     ANGLE_SKIP_TEST_IF(IsLinux() && IsOpenGL() && IsIntel());
1938 
1939     if (!checkExtensions())
1940     {
1941         return;
1942     }
1943 
1944     using GLColor32U = std::tuple<GLuint, GLuint, GLuint, GLuint>;
1945 
1946     auto testOutput = [this](GLuint texture, const GLColor32U &expectedColor) {
1947         constexpr char kVS[] =
1948             "#version 300 es\n"
1949             "in vec4 position;\n"
1950             "out vec2 texcoord;\n"
1951             "void main()\n"
1952             "{\n"
1953             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
1954             "    texcoord = (position.xy * 0.5) + 0.5;\n"
1955             "}\n";
1956 
1957         constexpr char kFS[] =
1958             "#version 300 es\n"
1959             "precision mediump float;\n"
1960             "precision mediump usampler2D;\n"
1961             "in vec2 texcoord;\n"
1962             "uniform usampler2D tex;\n"
1963             "out uvec4 color;\n"
1964             "void main()\n"
1965             "{\n"
1966             "    color = texture(tex, texcoord);\n"
1967             "}\n";
1968 
1969         ANGLE_GL_PROGRAM(program, kVS, kFS);
1970         glUseProgram(program);
1971 
1972         GLRenderbuffer rbo;
1973         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1974         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8UI, 1, 1);
1975 
1976         GLFramebuffer fbo;
1977         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1978         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1979 
1980         glActiveTexture(GL_TEXTURE0);
1981         glBindTexture(GL_TEXTURE_2D, texture);
1982         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1983         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1984         glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
1985 
1986         drawQuad(program, "position", 0.5f, 1.0f, true);
1987         ASSERT_GL_NO_ERROR();
1988 
1989         GLuint pixel[4] = {0};
1990         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, pixel);
1991         ASSERT_GL_NO_ERROR();
1992         EXPECT_NEAR(std::get<0>(expectedColor), pixel[0], 1);
1993         EXPECT_NEAR(std::get<1>(expectedColor), pixel[1], 1);
1994         EXPECT_NEAR(std::get<2>(expectedColor), pixel[2], 1);
1995         EXPECT_NEAR(std::get<3>(expectedColor), pixel[3], 1);
1996     };
1997 
1998     auto testCopyCombination = [testOutput](GLenum sourceInternalFormat, GLenum sourceFormat,
1999                                             GLenum sourceType, const GLColor &sourceColor,
2000                                             GLenum destInternalFormat, GLenum destType, bool flipY,
2001                                             bool premultiplyAlpha, bool unmultiplyAlpha,
2002                                             const GLColor32U &expectedColor) {
2003         GLTexture sourceTexture;
2004         glBindTexture(GL_TEXTURE_2D, sourceTexture);
2005         glTexImage2D(GL_TEXTURE_2D, 0, sourceInternalFormat, 1, 1, 0, sourceFormat, sourceType,
2006                      &sourceColor);
2007 
2008         GLTexture destTexture;
2009         glBindTexture(GL_TEXTURE_2D, destTexture);
2010 
2011         glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, destInternalFormat,
2012                               destType, flipY, premultiplyAlpha, unmultiplyAlpha);
2013         ASSERT_GL_NO_ERROR();
2014 
2015         testOutput(destTexture, expectedColor);
2016     };
2017 
2018     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2019                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 128));
2020     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2021                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 128));
2022     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
2023                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 128));
2024 
2025     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2026                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 1));
2027     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2028                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 1));
2029     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
2030                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 1));
2031 
2032     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2033                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 0, 1));
2034     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2035                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 0, 1));
2036     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
2037                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 0, 1));
2038 
2039     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R8UI,
2040                         GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 0, 0, 1));
2041     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_R8UI,
2042                         GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 0, 0, 1));
2043     testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(120, 64, 32, 128), GL_R8UI,
2044                         GL_UNSIGNED_BYTE, false, false, true, GLColor32U(240, 0, 0, 1));
2045 }
2046 
2047 // Test that using an offset in CopySubTexture works correctly for non-renderable float targets
TEST_P(CopyTextureTestES3,CopySubTextureOffsetNonRenderableFloat)2048 TEST_P(CopyTextureTestES3, CopySubTextureOffsetNonRenderableFloat)
2049 {
2050     if (!checkExtensions())
2051     {
2052         return;
2053     }
2054 
2055     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
2056 
2057     auto testOutput = [this](GLuint texture, const GLColor32F &expectedColor) {
2058         constexpr char kVS[] =
2059             "#version 300 es\n"
2060             "in vec4 position;\n"
2061             "out vec2 texcoord;\n"
2062             "void main()\n"
2063             "{\n"
2064             "    gl_Position = vec4(position.xy, 0.0, 1.0);\n"
2065             "    texcoord = (position.xy * 0.5) + 0.5;\n"
2066             "}\n";
2067 
2068         constexpr char kFS[] =
2069             "#version 300 es\n"
2070             "precision mediump float;\n"
2071             "uniform sampler2D tex;\n"
2072             "in vec2 texcoord;\n"
2073             "out vec4 color;\n"
2074             "void main()\n"
2075             "{\n"
2076             "    color = texture(tex, texcoord);\n"
2077             "}\n";
2078 
2079         ANGLE_GL_PROGRAM(program, kVS, kFS);
2080         glUseProgram(program);
2081 
2082         GLRenderbuffer rbo;
2083         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
2084         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
2085 
2086         GLFramebuffer fbo;
2087         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2088         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
2089 
2090         glActiveTexture(GL_TEXTURE0);
2091         glBindTexture(GL_TEXTURE_2D, texture);
2092         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2093         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2094         glUniform1i(glGetUniformLocation(program.get(), "tex"), 0);
2095 
2096         drawQuad(program, "position", 0.5f, 1.0f, true);
2097 
2098         EXPECT_PIXEL_COLOR32F_NEAR(0, 0, expectedColor, 0.05);
2099     };
2100 
2101     auto testCopy = [this, testOutput](GLenum destInternalFormat, GLenum destFormat,
2102                                        GLenum destType) {
2103         GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
2104         glBindTexture(GL_TEXTURE_2D, mTextures[0]);
2105         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
2106 
2107         GLTexture destTexture;
2108         glBindTexture(GL_TEXTURE_2D, destTexture);
2109         glTexImage2D(GL_TEXTURE_2D, 0, destInternalFormat, 1, 1, 0, destFormat, destType, nullptr);
2110 
2111         glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 0, 1, 1,
2112                                  false, false, false);
2113         EXPECT_GL_NO_ERROR();
2114         testOutput(destTexture, kFloatRed);
2115 
2116         glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 1, 0, 1, 1,
2117                                  false, false, false);
2118         EXPECT_GL_NO_ERROR();
2119         testOutput(destTexture, kFloatGreen);
2120 
2121         glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 0, 1, 1, 1,
2122                                  false, false, false);
2123         EXPECT_GL_NO_ERROR();
2124         testOutput(destTexture, kFloatBlue);
2125 
2126         glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, destTexture, 0, 0, 0, 1, 1, 1, 1,
2127                                  false, false, false);
2128         EXPECT_GL_NO_ERROR();
2129         testOutput(destTexture, kFloatBlack);
2130     };
2131 
2132     testCopy(GL_RGB9_E5, GL_RGB, GL_FLOAT);
2133 }
2134 
2135 #ifdef Bool
2136 // X11 craziness.
2137 #    undef Bool
2138 #endif
2139 
2140 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
2141 // tests should be run against.
2142 ANGLE_INSTANTIATE_TEST_ES2(CopyTextureTest);
2143 ANGLE_INSTANTIATE_TEST_COMBINE_5(CopyTextureVariationsTest,
2144                                  CopyTextureVariationsTestPrint,
2145                                  testing::ValuesIn(kCopyTextureVariationsSrcFormats),
2146                                  testing::ValuesIn(kCopyTextureVariationsDstFormats),
2147                                  testing::Bool(),  // flipY
2148                                  testing::Bool(),  // premultiplyAlpha
2149                                  testing::Bool(),  // unmultiplyAlpha
2150                                  ES2_D3D9(),
2151                                  ES2_D3D11(),
2152                                  ES2_OPENGL(),
2153                                  ES2_OPENGLES(),
2154                                  ES2_VULKAN());
2155 ANGLE_INSTANTIATE_TEST_ES2(CopyTextureTestWebGL);
2156 ANGLE_INSTANTIATE_TEST(CopyTextureTestDest,
2157                        ES2_D3D11(),
2158                        ES2_OPENGL(),
2159                        ES2_OPENGLES(),
2160                        ES2_VULKAN());
2161 ANGLE_INSTANTIATE_TEST_ES3(CopyTextureTestES3);
2162 
2163 }  // namespace angle
2164