xref: /aosp_15_r20/external/angle/src/tests/gl_tests/ReadPixelsTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2015 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 // ReadPixelsTest:
7 //   Tests calls related to glReadPixels.
8 //
9 
10 #include "test_utils/ANGLETest.h"
11 
12 #include <array>
13 
14 #include "test_utils/gl_raii.h"
15 #include "util/random_utils.h"
16 
17 using namespace angle;
18 
19 namespace
20 {
21 
22 class ReadPixelsTest : public ANGLETest<>
23 {
24   protected:
ReadPixelsTest()25     ReadPixelsTest()
26     {
27         setWindowWidth(32);
28         setWindowHeight(32);
29         setConfigRedBits(8);
30         setConfigGreenBits(8);
31         setConfigBlueBits(8);
32         setConfigAlphaBits(8);
33     }
34 };
35 
36 // Test out of bounds framebuffer reads.
TEST_P(ReadPixelsTest,OutOfBounds)37 TEST_P(ReadPixelsTest, OutOfBounds)
38 {
39     // TODO: re-enable once root cause of http://anglebug.com/42260408 is fixed
40     ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
41 
42     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
43     glClear(GL_COLOR_BUFFER_BIT);
44     EXPECT_GL_NO_ERROR();
45 
46     GLsizei pixelsWidth  = 32;
47     GLsizei pixelsHeight = 32;
48     GLint offset         = 16;
49     std::vector<GLColor> pixels((pixelsWidth + offset) * (pixelsHeight + offset));
50 
51     glReadPixels(-offset, -offset, pixelsWidth + offset, pixelsHeight + offset, GL_RGBA,
52                  GL_UNSIGNED_BYTE, &pixels[0]);
53     EXPECT_GL_NO_ERROR();
54 
55     // Expect that all pixels which fell within the framebuffer are red
56     for (int y = pixelsHeight / 2; y < pixelsHeight; y++)
57     {
58         for (int x = pixelsWidth / 2; x < pixelsWidth; x++)
59         {
60             EXPECT_EQ(GLColor::red, pixels[y * (pixelsWidth + offset) + x]);
61         }
62     }
63 }
64 
65 class ReadPixelsPBONVTest : public ReadPixelsTest
66 {
67   protected:
ReadPixelsPBONVTest()68     ReadPixelsPBONVTest() : mPBO(0), mTexture(0), mFBO(0) {}
69 
testSetUp()70     void testSetUp() override
71     {
72         glGenBuffers(1, &mPBO);
73         glGenFramebuffers(1, &mFBO);
74 
75         reset(4 * getWindowWidth() * getWindowHeight(), 4, 4);
76     }
77 
reset(GLuint bufferSize,GLuint fboWidth,GLuint fboHeight)78     virtual void reset(GLuint bufferSize, GLuint fboWidth, GLuint fboHeight)
79     {
80         ANGLE_SKIP_TEST_IF(!hasPBOExts());
81 
82         mPBOBufferSize = bufferSize;
83         glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
84         glBufferData(GL_PIXEL_PACK_BUFFER, mPBOBufferSize, nullptr, GL_STATIC_DRAW);
85         glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
86 
87         glDeleteTextures(1, &mTexture);
88         glGenTextures(1, &mTexture);
89         glBindTexture(GL_TEXTURE_2D, mTexture);
90         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, fboWidth, fboHeight);
91         mFBOWidth  = fboWidth;
92         mFBOHeight = fboHeight;
93 
94         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
95         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
96         glBindFramebuffer(GL_FRAMEBUFFER, 0);
97 
98         ASSERT_GL_NO_ERROR();
99     }
100 
testTearDown()101     void testTearDown() override
102     {
103         glDeleteBuffers(1, &mPBO);
104         glDeleteTextures(1, &mTexture);
105         glDeleteFramebuffers(1, &mFBO);
106     }
107 
hasPBOExts() const108     bool hasPBOExts() const
109     {
110         return IsGLExtensionEnabled("GL_NV_pixel_buffer_object") &&
111                IsGLExtensionEnabled("GL_EXT_texture_storage");
112     }
113 
114     GLuint mPBO           = 0;
115     GLuint mTexture       = 0;
116     GLuint mFBO           = 0;
117     GLuint mFBOWidth      = 0;
118     GLuint mFBOHeight     = 0;
119     GLuint mPBOBufferSize = 0;
120 };
121 
122 // Test basic usage of PBOs.
TEST_P(ReadPixelsPBONVTest,Basic)123 TEST_P(ReadPixelsPBONVTest, Basic)
124 {
125     ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
126                        !IsGLExtensionEnabled("GL_OES_mapbuffer"));
127 
128     // http://anglebug.com/42263593
129     ANGLE_SKIP_TEST_IF(IsWindows() && IsDesktopOpenGL());
130     // http://anglebug.com/42263926
131     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
132 
133     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
134     glClear(GL_COLOR_BUFFER_BIT);
135     // Clear last pixel to green
136     glScissor(15, 15, 1, 1);
137     glEnable(GL_SCISSOR_TEST);
138     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
139     glClear(GL_COLOR_BUFFER_BIT);
140     EXPECT_GL_NO_ERROR();
141 
142     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
143     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
144 
145     void *mappedPtr = glMapBufferRangeEXT(GL_PIXEL_PACK_BUFFER, 0, mPBOBufferSize, GL_MAP_READ_BIT);
146     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
147     EXPECT_GL_NO_ERROR();
148 
149     EXPECT_EQ(GLColor::red, dataColor[0]);
150     EXPECT_EQ(GLColor::red, dataColor[16 * 16 - 2]);
151     EXPECT_EQ(GLColor::green, dataColor[16 * 16 - 1]);
152 
153     glUnmapBufferOES(GL_PIXEL_PACK_BUFFER);
154     EXPECT_GL_NO_ERROR();
155 }
156 
157 // Test that calling SubData preserves PBO data.
TEST_P(ReadPixelsPBONVTest,SubDataPreservesContents)158 TEST_P(ReadPixelsPBONVTest, SubDataPreservesContents)
159 {
160     ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
161                        !IsGLExtensionEnabled("GL_OES_mapbuffer"));
162 
163     // anglebug.com/40096466
164     ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA() && IsDesktopOpenGL());
165 
166     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
167     glClear(GL_COLOR_BUFFER_BIT);
168     EXPECT_GL_NO_ERROR();
169 
170     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
171     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
172 
173     unsigned char data[4] = {1, 2, 3, 4};
174 
175     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
176     glBindBuffer(GL_ARRAY_BUFFER, mPBO);
177     glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
178 
179     void *mappedPtr    = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
180     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
181     EXPECT_GL_NO_ERROR();
182 
183     EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[0]);
184     EXPECT_EQ(GLColor::red, dataColor[1]);
185 
186     glUnmapBufferOES(GL_ARRAY_BUFFER);
187     EXPECT_GL_NO_ERROR();
188 }
189 
190 // Test that calling ReadPixels with GL_DYNAMIC_DRAW buffer works
TEST_P(ReadPixelsPBONVTest,DynamicPBO)191 TEST_P(ReadPixelsPBONVTest, DynamicPBO)
192 {
193     ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
194                        !IsGLExtensionEnabled("GL_OES_mapbuffer"));
195 
196     // anglebug.com/40096466
197     ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA() && IsDesktopOpenGL());
198 
199     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
200     glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), nullptr,
201                  GL_DYNAMIC_DRAW);
202 
203     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
204     glClear(GL_COLOR_BUFFER_BIT);
205     EXPECT_GL_NO_ERROR();
206 
207     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
208 
209     unsigned char data[4] = {1, 2, 3, 4};
210 
211     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
212     glBindBuffer(GL_ARRAY_BUFFER, mPBO);
213     glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
214 
215     void *mappedPtr    = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
216     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
217     EXPECT_GL_NO_ERROR();
218 
219     EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[0]);
220     EXPECT_EQ(GLColor::red, dataColor[1]);
221 
222     glUnmapBufferOES(GL_ARRAY_BUFFER);
223     EXPECT_GL_NO_ERROR();
224 }
225 
TEST_P(ReadPixelsPBONVTest,ReadFromFBO)226 TEST_P(ReadPixelsPBONVTest, ReadFromFBO)
227 {
228     ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
229                        !IsGLExtensionEnabled("GL_OES_mapbuffer"));
230 
231     glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
232     glViewport(0, 0, mFBOWidth, mFBOHeight);
233     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
234     glClear(GL_COLOR_BUFFER_BIT);
235     // Clear last pixel to green
236     glScissor(mFBOWidth - 1, mFBOHeight - 1, 1, 1);
237     glEnable(GL_SCISSOR_TEST);
238     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
239     glClear(GL_COLOR_BUFFER_BIT);
240     EXPECT_GL_NO_ERROR();
241 
242     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
243     glReadPixels(0, 0, mFBOWidth, mFBOHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0);
244 
245     void *mappedPtr =
246         glMapBufferRangeEXT(GL_PIXEL_PACK_BUFFER, 0, 4 * mFBOWidth * mFBOHeight, GL_MAP_READ_BIT);
247     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
248     EXPECT_GL_NO_ERROR();
249 
250     EXPECT_EQ(GLColor::red, dataColor[0]);
251     EXPECT_EQ(GLColor::red, dataColor[mFBOWidth * mFBOHeight - 2]);
252     EXPECT_EQ(GLColor::green, dataColor[mFBOWidth * mFBOHeight - 1]);
253 
254     glUnmapBufferOES(GL_PIXEL_PACK_BUFFER);
255     EXPECT_GL_NO_ERROR();
256 }
257 
258 // Test calling ReadPixels with a non-zero "data" param into a PBO
TEST_P(ReadPixelsPBONVTest,ReadFromFBOWithDataOffset)259 TEST_P(ReadPixelsPBONVTest, ReadFromFBOWithDataOffset)
260 {
261     ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
262                        !IsGLExtensionEnabled("GL_OES_mapbuffer"));
263 
264     glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
265     glViewport(0, 0, mFBOWidth, mFBOHeight);
266     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
267     glClear(GL_COLOR_BUFFER_BIT);
268     // Clear first pixel to green
269     glScissor(0, 0, 1, 1);
270     glEnable(GL_SCISSOR_TEST);
271     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
272     glClear(GL_COLOR_BUFFER_BIT);
273     EXPECT_GL_NO_ERROR();
274 
275     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
276 
277     // Read (height - 1) rows offset by width * 4.
278     glReadPixels(0, 0, mFBOWidth, mFBOHeight - 1, GL_RGBA, GL_UNSIGNED_BYTE,
279                  reinterpret_cast<void *>(mFBOWidth * static_cast<uintptr_t>(4)));
280 
281     void *mappedPtr =
282         glMapBufferRangeEXT(GL_PIXEL_PACK_BUFFER, 0, 4 * mFBOWidth * mFBOHeight, GL_MAP_READ_BIT);
283     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
284     EXPECT_GL_NO_ERROR();
285 
286     EXPECT_EQ(GLColor::green, dataColor[mFBOWidth]);
287     EXPECT_EQ(GLColor::red, dataColor[mFBOWidth + 1]);
288     EXPECT_EQ(GLColor::red, dataColor[mFBOWidth * mFBOHeight - 1]);
289 
290     glUnmapBufferOES(GL_PIXEL_PACK_BUFFER);
291     EXPECT_GL_NO_ERROR();
292 }
293 
294 class ReadPixelsPBOTest : public ReadPixelsPBONVTest
295 {
296   protected:
ReadPixelsPBOTest()297     ReadPixelsPBOTest() : ReadPixelsPBONVTest() {}
298 
testSetUp()299     void testSetUp() override
300     {
301         glGenBuffers(1, &mPBO);
302         glGenFramebuffers(1, &mFBO);
303 
304         reset(4 * getWindowWidth() * getWindowHeight(), 4, 1);
305     }
306 
reset(GLuint bufferSize,GLuint fboWidth,GLuint fboHeight)307     void reset(GLuint bufferSize, GLuint fboWidth, GLuint fboHeight) override
308     {
309         glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
310         glBufferData(GL_PIXEL_PACK_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
311         glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
312 
313         glDeleteTextures(1, &mTexture);
314         glGenTextures(1, &mTexture);
315         glBindTexture(GL_TEXTURE_2D, mTexture);
316         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, fboWidth, fboHeight);
317 
318         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
319         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
320         glBindFramebuffer(GL_FRAMEBUFFER, 0);
321 
322         mFBOWidth  = fboWidth;
323         mFBOHeight = fboHeight;
324 
325         mPBOBufferSize = bufferSize;
326 
327         ASSERT_GL_NO_ERROR();
328     }
329 };
330 
331 // Test basic usage of PBOs.
TEST_P(ReadPixelsPBOTest,Basic)332 TEST_P(ReadPixelsPBOTest, Basic)
333 {
334     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
335     glClear(GL_COLOR_BUFFER_BIT);
336     EXPECT_GL_NO_ERROR();
337 
338     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
339     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
340 
341     void *mappedPtr    = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
342     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
343     EXPECT_GL_NO_ERROR();
344 
345     EXPECT_EQ(GLColor::red, dataColor[0]);
346 
347     glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
348     EXPECT_GL_NO_ERROR();
349 }
350 
351 // Test copy to snorm
TEST_P(ReadPixelsPBOTest,Snorm)352 TEST_P(ReadPixelsPBOTest, Snorm)
353 {
354     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
355 
356     constexpr GLsizei kSize = 6;
357 
358     GLRenderbuffer rbo;
359     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
360     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_SNORM, kSize, kSize);
361     ASSERT_GL_NO_ERROR();
362 
363     GLFramebuffer fbo;
364     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
365     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
366     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
367     ASSERT_GL_NO_ERROR();
368 
369     glEnable(GL_SCISSOR_TEST);
370     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
371     glScissor(0, 0, kSize / 2, kSize / 2);
372     glClear(GL_COLOR_BUFFER_BIT);
373 
374     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
375     glScissor(kSize / 2, 0, kSize / 2, kSize / 2);
376     glClear(GL_COLOR_BUFFER_BIT);
377 
378     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
379     glScissor(0, kSize / 2, kSize / 2, kSize / 2);
380     glClear(GL_COLOR_BUFFER_BIT);
381 
382     glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
383     glScissor(kSize / 2, kSize / 2, kSize / 2, kSize / 2);
384     glClear(GL_COLOR_BUFFER_BIT);
385     EXPECT_GL_NO_ERROR();
386 
387     glDisable(GL_SCISSOR_TEST);
388 
389     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
390     glReadPixels(0, 0, kSize, kSize, GL_RGBA, GL_BYTE, 0);
391 
392     std::vector<GLColor> result(kSize * kSize);
393     void *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, kSize * kSize * 4, GL_MAP_READ_BIT);
394     memcpy(result.data(), mappedPtr, kSize * kSize * 4);
395     glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
396     EXPECT_GL_NO_ERROR();
397 
398     auto verify = [&](const GLColor expect[4]) {
399         for (size_t i = 0; i < kSize; ++i)
400         {
401             for (size_t j = 0; j < kSize; ++j)
402             {
403                 uint32_t index = (i < kSize / 2 ? 0 : 1) << 1 | (j < kSize / 2 ? 0 : 1);
404                 EXPECT_EQ(result[i * kSize + j], expect[index]) << i << " " << j;
405             }
406         }
407     };
408 
409     // The image should have the following colors
410     //
411     //     +---+---+
412     //     | R | G |
413     //     +---+---+
414     //     | B | Y |
415     //     +---+---+
416     //
417     const GLColor kColors[4] = {
418         GLColor(127, 0, 0, 127),
419         GLColor(0, 127, 0, 127),
420         GLColor(0, 0, 127, 127),
421         GLColor(127, 127, 0, 127),
422     };
423     verify(kColors);
424 
425     // Test again, but this time with reverse order
426     if (EnsureGLExtensionEnabled("GL_ANGLE_pack_reverse_row_order"))
427     {
428         glPixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, GL_TRUE);
429         glReadPixels(0, 0, kSize, kSize, GL_RGBA, GL_BYTE, 0);
430 
431         mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, kSize * kSize * 4, GL_MAP_READ_BIT);
432         memcpy(result.data(), mappedPtr, kSize * kSize * 4);
433         glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
434         EXPECT_GL_NO_ERROR();
435 
436         const GLColor kReversedColors[4] = {
437             GLColor(0, 0, 127, 127),
438             GLColor(127, 127, 0, 127),
439             GLColor(127, 0, 0, 127),
440             GLColor(0, 127, 0, 127),
441         };
442         verify(kReversedColors);
443     }
444 }
445 
446 // Test read pixel to PBO of an sRGB unorm renderbuffer
TEST_P(ReadPixelsPBOTest,SrgbUnorm)447 TEST_P(ReadPixelsPBOTest, SrgbUnorm)
448 {
449     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_pack_reverse_row_order"));
450 
451     constexpr GLsizei kSize = 1;
452     constexpr angle::GLColor clearColor(64, 0, 0, 255);
453     constexpr angle::GLColor encodedToSrgbColor(136, 0, 0, 255);
454 
455     GLRenderbuffer rbo;
456     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
457     glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8_ALPHA8, kSize, kSize);
458     ASSERT_GL_NO_ERROR();
459 
460     GLFramebuffer fbo;
461     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
462     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
463     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
464     ASSERT_GL_NO_ERROR();
465 
466     glClearColor(clearColor[0] / 255.0f, 0.0f, 0.0f, 1.0f);
467     glClear(GL_COLOR_BUFFER_BIT);
468 
469     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
470     glPixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, GL_TRUE);
471     glReadPixels(0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
472 
473     GLColor result;
474     void *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, kSize * kSize * 4, GL_MAP_READ_BIT);
475     memcpy(result.data(), mappedPtr, kSize * kSize * 4);
476     glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
477     EXPECT_GL_NO_ERROR();
478 
479     EXPECT_NEAR(result[0], encodedToSrgbColor[0], 1);
480 }
481 
482 // Test an error is generated when the PBO is too small.
TEST_P(ReadPixelsPBOTest,PBOTooSmall)483 TEST_P(ReadPixelsPBOTest, PBOTooSmall)
484 {
485     reset(4 * 16 * 16 - 1, 16, 16);
486 
487     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
488     glClear(GL_COLOR_BUFFER_BIT);
489     EXPECT_GL_NO_ERROR();
490 
491     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
492     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
493 
494     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
495 }
496 
497 // Test an error is generated when the PBO is mapped.
TEST_P(ReadPixelsPBOTest,PBOMapped)498 TEST_P(ReadPixelsPBOTest, PBOMapped)
499 {
500     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
501     glClear(GL_COLOR_BUFFER_BIT);
502     EXPECT_GL_NO_ERROR();
503 
504     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
505     glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
506     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
507 
508     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
509 }
510 
511 // Test that binding a PBO to ARRAY_BUFFER works as expected.
TEST_P(ReadPixelsPBOTest,ArrayBufferTarget)512 TEST_P(ReadPixelsPBOTest, ArrayBufferTarget)
513 {
514     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
515     glClear(GL_COLOR_BUFFER_BIT);
516     EXPECT_GL_NO_ERROR();
517 
518     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
519     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
520 
521     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
522     glBindBuffer(GL_ARRAY_BUFFER, mPBO);
523 
524     void *mappedPtr    = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
525     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
526     EXPECT_GL_NO_ERROR();
527 
528     EXPECT_EQ(GLColor::red, dataColor[0]);
529 
530     glUnmapBuffer(GL_ARRAY_BUFFER);
531     EXPECT_GL_NO_ERROR();
532 }
533 
534 // Test that using a PBO does not overwrite existing data.
TEST_P(ReadPixelsPBOTest,ExistingDataPreserved)535 TEST_P(ReadPixelsPBOTest, ExistingDataPreserved)
536 {
537     // Clear backbuffer to red
538     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
539     glClear(GL_COLOR_BUFFER_BIT);
540     EXPECT_GL_NO_ERROR();
541 
542     // Read 16x16 region from red backbuffer to PBO
543     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
544     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
545 
546     // Clear backbuffer to green
547     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
548     glClear(GL_COLOR_BUFFER_BIT);
549     EXPECT_GL_NO_ERROR();
550 
551     // Read 16x16 region from green backbuffer to PBO at offset 16
552     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<void *>(16));
553     void *mappedPtr =
554         glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 17 * sizeof(GLColor), GL_MAP_READ_BIT);
555     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
556     EXPECT_GL_NO_ERROR();
557 
558     // Test pixel 0 is red (existing data)
559     EXPECT_EQ(GLColor::red, dataColor[0]);
560 
561     // Test pixel 16 is green (new data)
562     EXPECT_EQ(GLColor::green, dataColor[16]);
563 
564     glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
565     EXPECT_GL_NO_ERROR();
566 }
567 
568 // Test that calling SubData preserves PBO data.
TEST_P(ReadPixelsPBOTest,SubDataPreservesContents)569 TEST_P(ReadPixelsPBOTest, SubDataPreservesContents)
570 {
571     // anglebug.com/40096466
572     ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA() && IsDesktopOpenGL());
573 
574     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
575     glClear(GL_COLOR_BUFFER_BIT);
576     EXPECT_GL_NO_ERROR();
577 
578     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
579     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
580 
581     unsigned char data[4] = {1, 2, 3, 4};
582 
583     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
584     glBindBuffer(GL_ARRAY_BUFFER, mPBO);
585     glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
586 
587     void *mappedPtr    = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
588     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
589     EXPECT_GL_NO_ERROR();
590 
591     EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[0]);
592 
593     glUnmapBuffer(GL_ARRAY_BUFFER);
594     EXPECT_GL_NO_ERROR();
595 }
596 
597 // Same as the prior test, but with an offset.
TEST_P(ReadPixelsPBOTest,SubDataOffsetPreservesContents)598 TEST_P(ReadPixelsPBOTest, SubDataOffsetPreservesContents)
599 {
600     // anglebug.com/42260410
601     ANGLE_SKIP_TEST_IF(IsNexus5X() && IsAdreno() && IsOpenGLES());
602     // anglebug.com/40096466
603     ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA() && IsDesktopOpenGL());
604 
605     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
606     glClear(GL_COLOR_BUFFER_BIT);
607     EXPECT_GL_NO_ERROR();
608 
609     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
610     glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
611 
612     unsigned char data[4] = {1, 2, 3, 4};
613 
614     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
615     glBindBuffer(GL_ARRAY_BUFFER, mPBO);
616     glBufferSubData(GL_ARRAY_BUFFER, 16, 4, data);
617 
618     void *mappedPtr    = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
619     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
620     EXPECT_GL_NO_ERROR();
621 
622     EXPECT_EQ(GLColor::red, dataColor[0]);
623     EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[4]);
624 
625     glUnmapBuffer(GL_ARRAY_BUFFER);
626     EXPECT_GL_NO_ERROR();
627 }
628 
629 // Test that uploading data to buffer that's in use then writing to it as PBO works.
TEST_P(ReadPixelsPBOTest,UseAsUBOThenUpdateThenReadFromFBO)630 TEST_P(ReadPixelsPBOTest, UseAsUBOThenUpdateThenReadFromFBO)
631 {
632     glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
633     glViewport(0, 0, mFBOWidth, mFBOHeight);
634 
635     const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
636                                                  GLColor::red};
637     const std::array<GLColor, 4> kUpdateData  = {GLColor::white, GLColor::white, GLColor::white,
638                                                  GLColor::white};
639 
640     GLBuffer buffer;
641     glBindBuffer(GL_UNIFORM_BUFFER, buffer);
642     glBufferData(GL_UNIFORM_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_COPY);
643     glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
644     EXPECT_GL_NO_ERROR();
645 
646     constexpr char kVerifyUBO[] = R"(#version 300 es
647 precision mediump float;
648 uniform block {
649     uvec4 data;
650 } ubo;
651 out vec4 colorOut;
652 void main()
653 {
654     if (all(equal(ubo.data, uvec4(0xFF0000FFu))))
655         colorOut = vec4(0, 1.0, 0, 1.0);
656     else
657         colorOut = vec4(1.0, 0, 0, 1.0);
658 })";
659 
660     ANGLE_GL_PROGRAM(verifyUbo, essl3_shaders::vs::Simple(), kVerifyUBO);
661     drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5);
662     EXPECT_GL_NO_ERROR();
663 
664     // Update buffer data
665     glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(kInitialData), kUpdateData.data());
666     EXPECT_GL_NO_ERROR();
667 
668     // Clear first pixel to blue
669     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
670     glScissor(0, 0, 1, 1);
671     glEnable(GL_SCISSOR_TEST);
672     glClear(GL_COLOR_BUFFER_BIT);
673     EXPECT_GL_NO_ERROR();
674 
675     glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
676 
677     // Read the framebuffer pixels
678     glReadPixels(0, 0, mFBOWidth, mFBOHeight, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
679 
680     void *mappedPtr =
681         glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, sizeof(kInitialData), GL_MAP_READ_BIT);
682     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
683     EXPECT_GL_NO_ERROR();
684 
685     EXPECT_EQ(GLColor::blue, dataColor[0]);
686     EXPECT_EQ(GLColor::green, dataColor[1]);
687     EXPECT_EQ(GLColor::green, dataColor[2]);
688     EXPECT_EQ(GLColor::green, dataColor[3]);
689 
690     glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
691     EXPECT_GL_NO_ERROR();
692 
693     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
694     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
695     EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::green);
696     EXPECT_PIXEL_COLOR_EQ(2, 0, GLColor::green);
697     EXPECT_PIXEL_COLOR_EQ(3, 0, GLColor::green);
698 }
699 
700 // Test PBO readback with row length smaller than area width.
TEST_P(ReadPixelsPBOTest,SmallRowLength)701 TEST_P(ReadPixelsPBOTest, SmallRowLength)
702 {
703     constexpr int kSize = 2;
704     reset(kSize * kSize * 4, kSize, kSize);
705     std::vector<GLColor> texData(kSize * kSize);
706     texData[0] = GLColor::red;
707     texData[1] = GLColor::green;
708     texData[2] = GLColor::blue;
709     texData[3] = GLColor::white;
710     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE,
711                     texData.data());
712     ASSERT_GL_NO_ERROR();
713 
714     glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
715     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
716 
717     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
718     std::vector<GLColor> bufData(kSize * kSize, GLColor::black);
719     glBufferData(GL_PIXEL_PACK_BUFFER, mPBOBufferSize, bufData.data(), GL_STATIC_DRAW);
720 
721     glPixelStorei(GL_PACK_ROW_LENGTH, 1);
722     glReadPixels(0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
723     ASSERT_GL_NO_ERROR();
724 
725     void *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, mPBOBufferSize, GL_MAP_READ_BIT);
726     ASSERT_NE(nullptr, mappedPtr);
727     ASSERT_GL_NO_ERROR();
728 
729     // TODO(anglebug.com/354005999)
730     // Metal compute path may produce flaky results
731     // Suppressed until a fallback is implemented
732     if (!IsMetal())
733     {
734         GLColor *colorPtr = static_cast<GLColor *>(mappedPtr);
735         EXPECT_EQ(colorPtr[0], GLColor::red);
736         EXPECT_EQ(colorPtr[1], GLColor::blue);
737         EXPECT_EQ(colorPtr[2], GLColor::white);
738         EXPECT_EQ(colorPtr[3], GLColor::black);
739     }
740     ASSERT_TRUE(glUnmapBuffer(GL_PIXEL_PACK_BUFFER));
741     ASSERT_GL_NO_ERROR();
742 }
743 
744 class ReadPixelsPBODrawTest : public ReadPixelsPBOTest
745 {
746   protected:
ReadPixelsPBODrawTest()747     ReadPixelsPBODrawTest() : mProgram(0), mPositionVBO(0) {}
748 
testSetUp()749     void testSetUp() override
750     {
751         ReadPixelsPBOTest::testSetUp();
752 
753         constexpr char kVS[] =
754             "attribute vec4 aTest; attribute vec2 aPosition; varying vec4 vTest;\n"
755             "void main()\n"
756             "{\n"
757             "    vTest        = aTest;\n"
758             "    gl_Position  = vec4(aPosition, 0.0, 1.0);\n"
759             "    gl_PointSize = 1.0;\n"
760             "}";
761 
762         constexpr char kFS[] =
763             "precision mediump float; varying vec4 vTest;\n"
764             "void main()\n"
765             "{\n"
766             "    gl_FragColor = vTest;\n"
767             "}";
768 
769         mProgram = CompileProgram(kVS, kFS);
770         ASSERT_NE(0u, mProgram);
771 
772         glGenBuffers(1, &mPositionVBO);
773         glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
774         glBufferData(GL_ARRAY_BUFFER, 128, nullptr, GL_DYNAMIC_DRAW);
775         glBindBuffer(GL_ARRAY_BUFFER, 0);
776     }
777 
testTearDown()778     void testTearDown() override
779     {
780         glDeleteProgram(mProgram);
781         glDeleteBuffers(1, &mPositionVBO);
782         ReadPixelsPBOTest::testTearDown();
783     }
784 
785     GLuint mProgram;
786     GLuint mPositionVBO;
787 };
788 
789 // Test that we can draw with PBO data.
TEST_P(ReadPixelsPBODrawTest,DrawWithPBO)790 TEST_P(ReadPixelsPBODrawTest, DrawWithPBO)
791 {
792     GLColor color(1, 2, 3, 4);
793     glBindTexture(GL_TEXTURE_2D, mTexture);
794     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
795     EXPECT_GL_NO_ERROR();
796 
797     glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO);
798     EXPECT_GL_NO_ERROR();
799 
800     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
801     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
802     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
803     EXPECT_GL_NO_ERROR();
804 
805     float positionData[] = {0.5f, 0.5f};
806 
807     glUseProgram(mProgram);
808     glViewport(0, 0, 1, 1);
809     glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
810     glBufferSubData(GL_ARRAY_BUFFER, 0, 1 * 2 * 4, positionData);
811     EXPECT_GL_NO_ERROR();
812 
813     GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
814     EXPECT_NE(-1, positionLocation);
815 
816     GLint testLocation = glGetAttribLocation(mProgram, "aTest");
817     EXPECT_NE(-1, testLocation);
818 
819     glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
820     glEnableVertexAttribArray(positionLocation);
821     EXPECT_GL_NO_ERROR();
822 
823     glBindBuffer(GL_ARRAY_BUFFER, mPBO);
824     glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
825     glEnableVertexAttribArray(testLocation);
826     EXPECT_GL_NO_ERROR();
827 
828     glDrawArrays(GL_POINTS, 0, 1);
829     EXPECT_GL_NO_ERROR();
830 
831     color = GLColor(0, 0, 0, 0);
832     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
833     EXPECT_GL_NO_ERROR();
834 
835     EXPECT_EQ(GLColor(1, 2, 3, 4), color);
836 }
837 
838 // Test that we can correctly update a buffer bound to the vertex stage with PBO.
TEST_P(ReadPixelsPBODrawTest,UpdateVertexArrayWithPixelPack)839 TEST_P(ReadPixelsPBODrawTest, UpdateVertexArrayWithPixelPack)
840 {
841     glUseProgram(mProgram);
842     glViewport(0, 0, 1, 1);
843     glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
844     ASSERT_GL_NO_ERROR();
845 
846     // First draw with pre-defined data.
847     std::array<float, 2> positionData = {0.5f, 0.5f};
848 
849     glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
850     glBufferSubData(GL_ARRAY_BUFFER, 0, positionData.size() * sizeof(positionData[0]),
851                     positionData.data());
852     ASSERT_GL_NO_ERROR();
853 
854     GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
855     EXPECT_NE(-1, positionLocation);
856 
857     GLint testLocation = glGetAttribLocation(mProgram, "aTest");
858     EXPECT_NE(-1, testLocation);
859 
860     glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
861     glEnableVertexAttribArray(positionLocation);
862     ASSERT_GL_NO_ERROR();
863 
864     glBindBuffer(GL_ARRAY_BUFFER, mPBO);
865     glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLColor), &GLColor::red);
866     glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
867     glEnableVertexAttribArray(testLocation);
868     ASSERT_GL_NO_ERROR();
869 
870     glDrawArrays(GL_POINTS, 0, 1);
871     ASSERT_GL_NO_ERROR();
872 
873     // Update the buffer bound to the VAO with a PBO.
874     glBindTexture(GL_TEXTURE_2D, mTexture);
875     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
876     ASSERT_GL_NO_ERROR();
877 
878     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
879     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
880     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
881     ASSERT_GL_NO_ERROR();
882 
883     // Draw again and verify the VAO has the updated data.
884     glDrawArrays(GL_POINTS, 0, 1);
885 
886     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
887 }
888 
889 class ReadPixelsTextureNorm16PBOTest : public ReadPixelsTest
890 {
891   protected:
testSetUp()892     void testSetUp() override
893     {
894         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
895         glBindTexture(GL_TEXTURE_2D, mTex);
896         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTex, 0);
897         glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
898         ASSERT_GL_NO_ERROR();
899     }
900 
901     template <typename T>
test(GLenum format,GLenum internalFormat,GLenum readFormat)902     void test(GLenum format, GLenum internalFormat, GLenum readFormat)
903     {
904         const bool isSigned = std::is_same<T, GLshort>::value;
905         const GLenum type   = isSigned ? GL_SHORT : GL_UNSIGNED_SHORT;
906 
907         T data[4] = {};
908         data[0]   = isSigned ? -32767 : 32767;
909         data[1]   = isSigned ? -16383 : 16383;
910         data[2]   = isSigned ? -8191 : 8191;
911         data[3]   = isSigned ? -4095 : 4095;
912 
913         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, data);
914         ASSERT_GL_NO_ERROR();
915         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
916 
917         bool supportedCombination = true;
918         if (readFormat != GL_RGBA)
919         {
920             GLenum implementationFormat, implementationType;
921             glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT,
922                           reinterpret_cast<GLint *>(&implementationFormat));
923             glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE,
924                           reinterpret_cast<GLint *>(&implementationType));
925             ASSERT_GL_NO_ERROR();
926 
927             supportedCombination = implementationFormat == readFormat && implementationType == type;
928         }
929 
930         glBufferData(GL_PIXEL_PACK_BUFFER, 12, nullptr, GL_STATIC_COPY);
931         ASSERT_GL_NO_ERROR();
932 
933         // Use non-zero offset for better code coverage
934         constexpr GLint offset = 4;
935         glReadPixels(0, 0, 1, 1, readFormat, type, reinterpret_cast<void *>(offset));
936         if (supportedCombination)
937         {
938             ASSERT_GL_NO_ERROR();
939         }
940         else
941         {
942             EXPECT_GL_ERROR(GL_INVALID_OPERATION);
943             ANGLE_SKIP_TEST_IF(!supportedCombination);
944         }
945 
946         T *dataRead =
947             static_cast<T *>(glMapBufferRange(GL_PIXEL_PACK_BUFFER, offset, 8, GL_MAP_READ_BIT));
948         ASSERT_GL_NO_ERROR();
949 
950         EXPECT_EQ(dataRead[0], data[0]);
951         if (readFormat == GL_RGBA || readFormat == GL_RG)
952         {
953             EXPECT_EQ(dataRead[1], format != GL_RED ? data[1] : 0);
954         }
955         if (readFormat == GL_RGBA)
956         {
957             EXPECT_EQ(dataRead[2], format == GL_RGBA ? data[2] : 0);
958             EXPECT_EQ(dataRead[3], format == GL_RGBA ? data[3] : (isSigned ? 32767 : 65535));
959         }
960         glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
961     }
962 
testUnsigned(GLenum format,GLenum internalFormat,GLenum readFormat)963     void testUnsigned(GLenum format, GLenum internalFormat, GLenum readFormat)
964     {
965         ASSERT(internalFormat == GL_RGBA16_EXT || internalFormat == GL_RG16_EXT ||
966                internalFormat == GL_R16_EXT);
967         test<GLushort>(format, internalFormat, readFormat);
968     }
969 
testSigned(GLenum format,GLenum internalFormat,GLenum readFormat)970     void testSigned(GLenum format, GLenum internalFormat, GLenum readFormat)
971     {
972         ASSERT(internalFormat == GL_RGBA16_SNORM_EXT || internalFormat == GL_RG16_SNORM_EXT ||
973                internalFormat == GL_R16_SNORM_EXT);
974         test<GLshort>(format, internalFormat, readFormat);
975     }
976 
977     GLFramebuffer mFBO;
978     GLTexture mTex;
979     GLBuffer mPBO;
980 };
981 
982 // Test PBO RGBA readback for RGBA16 color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,RGBA16_RGBA)983 TEST_P(ReadPixelsTextureNorm16PBOTest, RGBA16_RGBA)
984 {
985     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
986     testUnsigned(GL_RGBA, GL_RGBA16_EXT, GL_RGBA);
987 }
988 
989 // Test PBO RGBA readback for RG16 color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,RG16_RGBA)990 TEST_P(ReadPixelsTextureNorm16PBOTest, RG16_RGBA)
991 {
992     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
993     testUnsigned(GL_RG, GL_RG16_EXT, GL_RGBA);
994 }
995 
996 // Test PBO RG readback for RG16 color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,RG16_RG)997 TEST_P(ReadPixelsTextureNorm16PBOTest, RG16_RG)
998 {
999     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1000     testUnsigned(GL_RG, GL_RG16_EXT, GL_RG);
1001 }
1002 
1003 // Test PBO RGBA readback for R16 color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,R16_RGBA)1004 TEST_P(ReadPixelsTextureNorm16PBOTest, R16_RGBA)
1005 {
1006     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1007     testUnsigned(GL_RED, GL_R16_EXT, GL_RGBA);
1008 }
1009 
1010 // Test PBO RED readback for R16 color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,R16_RED)1011 TEST_P(ReadPixelsTextureNorm16PBOTest, R16_RED)
1012 {
1013     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1014     testUnsigned(GL_RED, GL_R16_EXT, GL_RED);
1015 }
1016 
1017 // Test PBO RGBA readback for RGBA16_SNORM color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,RGBA16_SNORM_RGBA)1018 TEST_P(ReadPixelsTextureNorm16PBOTest, RGBA16_SNORM_RGBA)
1019 {
1020     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1021     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1022     testSigned(GL_RGBA, GL_RGBA16_SNORM_EXT, GL_RGBA);
1023 }
1024 
1025 // Test PBO RGBA readback for RG16_SNORM color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,RG16_SNORM_RGBA)1026 TEST_P(ReadPixelsTextureNorm16PBOTest, RG16_SNORM_RGBA)
1027 {
1028     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1029     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1030     testSigned(GL_RG, GL_RG16_SNORM_EXT, GL_RGBA);
1031 }
1032 
1033 // Test PBO RG readback for RG16_SNORM color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,RG16_SNORM_RG)1034 TEST_P(ReadPixelsTextureNorm16PBOTest, RG16_SNORM_RG)
1035 {
1036     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1037     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1038     testSigned(GL_RG, GL_RG16_SNORM_EXT, GL_RG);
1039 }
1040 
1041 // Test PBO RGBA readback for R16_SNORM color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,R16_SNORM_RGBA)1042 TEST_P(ReadPixelsTextureNorm16PBOTest, R16_SNORM_RGBA)
1043 {
1044     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1045     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1046     testSigned(GL_RED, GL_R16_SNORM_EXT, GL_RGBA);
1047 }
1048 
1049 // Test PBO RED readback for R16_SNORM color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,R16_SNORM_RED)1050 TEST_P(ReadPixelsTextureNorm16PBOTest, R16_SNORM_RED)
1051 {
1052     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1053     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1054     testSigned(GL_RED, GL_R16_SNORM_EXT, GL_RED);
1055 }
1056 
1057 class ReadPixelsMultisampleTest : public ReadPixelsTest
1058 {
1059   protected:
ReadPixelsMultisampleTest()1060     ReadPixelsMultisampleTest() : mFBO(0), mRBO(0), mPBO(0)
1061     {
1062         setSamples(4);
1063         setMultisampleEnabled(true);
1064     }
1065 
testSetUp()1066     void testSetUp() override
1067     {
1068         glGenFramebuffers(1, &mFBO);
1069         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1070 
1071         glGenRenderbuffers(1, &mRBO);
1072         glBindRenderbuffer(GL_RENDERBUFFER, mRBO);
1073 
1074         glGenBuffers(1, &mPBO);
1075         glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
1076         glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), nullptr,
1077                      GL_STATIC_DRAW);
1078         glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
1079 
1080         ASSERT_GL_NO_ERROR();
1081     }
1082 
testTearDown()1083     void testTearDown() override
1084     {
1085         glDeleteFramebuffers(1, &mFBO);
1086         glDeleteRenderbuffers(1, &mRBO);
1087         glDeleteBuffers(1, &mPBO);
1088     }
1089 
1090     GLuint mFBO;
1091     GLuint mRBO;
1092     GLuint mPBO;
1093 };
1094 
1095 // Test ReadPixels from a multisampled framebuffer.
TEST_P(ReadPixelsMultisampleTest,BasicClear)1096 TEST_P(ReadPixelsMultisampleTest, BasicClear)
1097 {
1098     if (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_ANGLE_framebuffer_multisample"))
1099     {
1100         std::cout
1101             << "Test skipped because ES3 or GL_ANGLE_framebuffer_multisample is not available."
1102             << std::endl;
1103         return;
1104     }
1105 
1106     if (IsGLExtensionEnabled("GL_ANGLE_framebuffer_multisample"))
1107     {
1108         glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
1109     }
1110     else
1111     {
1112         glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
1113     }
1114 
1115     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRBO);
1116     ASSERT_GL_NO_ERROR();
1117 
1118     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1119     glClear(GL_COLOR_BUFFER_BIT);
1120 
1121     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
1122     EXPECT_GL_NO_ERROR();
1123 
1124     glReadPixels(0, 0, 1, 1, GL_RGBA8, GL_UNSIGNED_BYTE, nullptr);
1125     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1126 }
1127 
1128 // Test ReadPixels from a multisampled swapchain.
TEST_P(ReadPixelsMultisampleTest,DefaultFramebuffer)1129 TEST_P(ReadPixelsMultisampleTest, DefaultFramebuffer)
1130 {
1131     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1132 
1133     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1134     glClear(GL_COLOR_BUFFER_BIT);
1135 
1136     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
1137     EXPECT_GL_NO_ERROR();
1138 }
1139 
1140 // Test ReadPixels from a multisampled swapchain into a PBO.
TEST_P(ReadPixelsMultisampleTest,DefaultFramebufferPBO)1141 TEST_P(ReadPixelsMultisampleTest, DefaultFramebufferPBO)
1142 {
1143     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1144 
1145     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1146     glClear(GL_COLOR_BUFFER_BIT);
1147 
1148     glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
1149 
1150     const int w = getWindowWidth();
1151     const int h = getWindowHeight();
1152     glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1153     EXPECT_GL_NO_ERROR();
1154 
1155     const std::vector<angle::GLColor> expectedColor(w * h, GLColor::red);
1156     std::vector<angle::GLColor> actualColor(w * h);
1157     const void *mapPointer =
1158         glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, sizeof(angle::GLColor) * w * h, GL_MAP_READ_BIT);
1159     ASSERT_NE(nullptr, mapPointer);
1160     memcpy(actualColor.data(), mapPointer, sizeof(angle::GLColor) * w * h);
1161     glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
1162 
1163     EXPECT_EQ(expectedColor, actualColor);
1164 }
1165 
1166 class ReadPixelsTextureTest : public ANGLETest<>
1167 {
1168   public:
ReadPixelsTextureTest()1169     ReadPixelsTextureTest() : mFBO(0), mTextureRGBA(0), mTextureBGRA(0)
1170     {
1171         setWindowWidth(32);
1172         setWindowHeight(32);
1173         setConfigRedBits(8);
1174         setConfigGreenBits(8);
1175         setConfigBlueBits(8);
1176         setConfigAlphaBits(8);
1177     }
1178 
testSetUp()1179     void testSetUp() override
1180     {
1181         glGenTextures(1, &mTextureRGBA);
1182         glGenTextures(1, &mTextureBGRA);
1183         glGenFramebuffers(1, &mFBO);
1184         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1185     }
1186 
testTearDown()1187     void testTearDown() override
1188     {
1189         glDeleteFramebuffers(1, &mFBO);
1190         glDeleteTextures(1, &mTextureRGBA);
1191         glDeleteTextures(1, &mTextureBGRA);
1192     }
1193 
initTextureRGBA(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)1194     void initTextureRGBA(GLenum textureTarget,
1195                          GLint levels,
1196                          GLint attachmentLevel,
1197                          GLint attachmentLayer)
1198     {
1199         glBindTexture(textureTarget, mTextureRGBA);
1200         glTexStorage3D(textureTarget, levels, GL_RGBA8, kSize, kSize, kSize);
1201         glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTextureRGBA,
1202                                   attachmentLevel, attachmentLayer);
1203         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1204         ASSERT_GL_NO_ERROR();
1205         initializeTextureData(textureTarget, levels, GL_RGBA);
1206     }
1207 
initTextureBGRA(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)1208     void initTextureBGRA(GLenum textureTarget,
1209                          GLint levels,
1210                          GLint attachmentLevel,
1211                          GLint attachmentLayer)
1212     {
1213         glBindTexture(textureTarget, mTextureBGRA);
1214         for (GLint level = 0; level < levels; ++level)
1215         {
1216             glTexImage3D(textureTarget, level, GL_BGRA_EXT, kSize >> level, kSize >> level,
1217                          textureTarget == GL_TEXTURE_3D ? kSize >> level : kSize, 0, GL_BGRA_EXT,
1218                          GL_UNSIGNED_BYTE, nullptr);
1219         }
1220         glTexParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, 0);
1221         glTexParameteri(textureTarget, GL_TEXTURE_MAX_LEVEL, levels - 1);
1222         glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTextureBGRA,
1223                                   attachmentLevel, attachmentLayer);
1224         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1225         ASSERT_GL_NO_ERROR();
1226         initializeTextureData(textureTarget, levels, GL_BGRA_EXT);
1227     }
1228 
testRead(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)1229     void testRead(GLenum textureTarget, GLint levels, GLint attachmentLevel, GLint attachmentLayer)
1230     {
1231         initTextureRGBA(textureTarget, levels, attachmentLevel, attachmentLayer);
1232         verifyColor(attachmentLevel, attachmentLayer);
1233 
1234         // Skip BGRA test on GL/Nvidia, leading to internal incomplete framebuffer error.
1235         // http://anglebug.com/42266676
1236         ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsOpenGL());
1237 
1238         if (IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
1239         {
1240             initTextureBGRA(textureTarget, levels, attachmentLevel, attachmentLayer);
1241             verifyColor(attachmentLevel, attachmentLayer);
1242         }
1243     }
1244 
initPBO()1245     void initPBO()
1246     {
1247         // Create a buffer big enough to hold mip 0 + allow some offset during readback.
1248         glGenBuffers(1, &mBuffer);
1249         glBindBuffer(GL_PIXEL_PACK_BUFFER, mBuffer);
1250         glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(angle::GLColor) * 16 * 2, nullptr,
1251                      GL_STREAM_COPY);
1252         ASSERT_GL_NO_ERROR();
1253     }
1254 
testPBORead(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)1255     void testPBORead(GLenum textureTarget,
1256                      GLint levels,
1257                      GLint attachmentLevel,
1258                      GLint attachmentLayer)
1259     {
1260         initPBO();
1261         initTextureRGBA(textureTarget, levels, attachmentLevel, attachmentLayer);
1262         verifyPBO(attachmentLevel, attachmentLayer);
1263 
1264         // Skip BGRA test on GL/Nvidia, leading to internal incomplete framebuffer error.
1265         // http://anglebug.com/42266676
1266         ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsOpenGL());
1267 
1268         if (IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
1269         {
1270             initTextureBGRA(textureTarget, levels, attachmentLevel, attachmentLayer);
1271             verifyPBO(attachmentLevel, attachmentLayer);
1272         }
1273     }
1274 
1275     // Give each {level,layer} pair a (probably) unique color via random.
getColorValue(GLint level,GLint layer)1276     GLuint getColorValue(GLint level, GLint layer)
1277     {
1278         mRNG.reseed(level + layer * 32);
1279         return mRNG.randomUInt();
1280     }
1281 
verifyColor(GLint level,GLint layer)1282     void verifyColor(GLint level, GLint layer)
1283     {
1284         const angle::GLColor colorValue(getColorValue(level, layer));
1285         const GLint size = kSize >> level;
1286         EXPECT_PIXEL_RECT_EQ(0, 0, size, size, colorValue);
1287     }
1288 
verifyPBO(GLint level,GLint layer)1289     void verifyPBO(GLint level, GLint layer)
1290     {
1291         const GLint size     = kSize >> level;
1292         const GLsizei offset = kSize * (level + layer);
1293         glReadPixels(0, 0, size, size, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<void *>(offset));
1294 
1295         const std::vector<angle::GLColor> expectedColor(size * size, getColorValue(level, layer));
1296         std::vector<angle::GLColor> actualColor(size * size);
1297 
1298         void *mapPointer = glMapBufferRange(GL_PIXEL_PACK_BUFFER, offset,
1299                                             sizeof(angle::GLColor) * size * size, GL_MAP_READ_BIT);
1300         ASSERT_NE(nullptr, mapPointer);
1301         memcpy(actualColor.data(), mapPointer, sizeof(angle::GLColor) * size * size);
1302         glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
1303 
1304         ASSERT_GL_NO_ERROR();
1305         EXPECT_EQ(expectedColor, actualColor);
1306     }
1307 
initializeTextureData(GLenum textureTarget,GLint levels,GLenum format)1308     void initializeTextureData(GLenum textureTarget, GLint levels, GLenum format)
1309     {
1310         for (GLint level = 0; level < levels; ++level)
1311         {
1312             GLint mipSize = kSize >> level;
1313             GLint layers  = (textureTarget == GL_TEXTURE_3D ? mipSize : kSize);
1314 
1315             size_t layerSize = mipSize * mipSize;
1316             std::vector<GLuint> textureData(layers * layerSize);
1317 
1318             for (GLint layer = 0; layer < layers; ++layer)
1319             {
1320                 GLuint colorValue = getColorValue(level, layer);
1321                 size_t offset     = (layer * layerSize);
1322 
1323                 if (format == GL_BGRA_EXT)
1324                 {
1325                     const GLuint rb = colorValue & 0x00FF00FF;
1326                     const GLuint br = (rb & 0xFF) << 16 | rb >> 16;
1327                     const GLuint ga = colorValue & 0xFF00FF00;
1328                     colorValue      = ga | br;
1329                 }
1330 
1331                 std::fill(textureData.begin() + offset, textureData.begin() + offset + layerSize,
1332                           colorValue);
1333             }
1334 
1335             glTexSubImage3D(textureTarget, level, 0, 0, 0, mipSize, mipSize, layers, format,
1336                             GL_UNSIGNED_BYTE, textureData.data());
1337         }
1338     }
1339 
1340     static constexpr GLint kSize = 4;
1341 
1342     angle::RNG mRNG;
1343     GLuint mFBO;
1344     GLuint mTextureRGBA;
1345     GLuint mTextureBGRA;
1346     GLuint mBuffer;
1347 };
1348 
1349 // Test 3D attachment readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment3D)1350 TEST_P(ReadPixelsTextureTest, BasicAttachment3D)
1351 {
1352     testRead(GL_TEXTURE_3D, 1, 0, 0);
1353 }
1354 
1355 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment3D)1356 TEST_P(ReadPixelsTextureTest, MipAttachment3D)
1357 {
1358     testRead(GL_TEXTURE_3D, 2, 1, 0);
1359 }
1360 
1361 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment3D)1362 TEST_P(ReadPixelsTextureTest, LayerAttachment3D)
1363 {
1364     testRead(GL_TEXTURE_3D, 1, 0, 1);
1365 }
1366 
1367 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment3D)1368 TEST_P(ReadPixelsTextureTest, MipLayerAttachment3D)
1369 {
1370     testRead(GL_TEXTURE_3D, 2, 1, 1);
1371 }
1372 
1373 // Test 2D array attachment readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment2DArray)1374 TEST_P(ReadPixelsTextureTest, BasicAttachment2DArray)
1375 {
1376     testRead(GL_TEXTURE_2D_ARRAY, 1, 0, 0);
1377 }
1378 
1379 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment2DArray)1380 TEST_P(ReadPixelsTextureTest, MipAttachment2DArray)
1381 {
1382     testRead(GL_TEXTURE_2D_ARRAY, 2, 1, 0);
1383 }
1384 
1385 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment2DArray)1386 TEST_P(ReadPixelsTextureTest, LayerAttachment2DArray)
1387 {
1388     testRead(GL_TEXTURE_2D_ARRAY, 1, 0, 1);
1389 }
1390 
1391 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment2DArray)1392 TEST_P(ReadPixelsTextureTest, MipLayerAttachment2DArray)
1393 {
1394     testRead(GL_TEXTURE_2D_ARRAY, 2, 1, 1);
1395 }
1396 
1397 // Test 3D attachment PBO readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment3DPBO)1398 TEST_P(ReadPixelsTextureTest, BasicAttachment3DPBO)
1399 {
1400     testPBORead(GL_TEXTURE_3D, 1, 0, 0);
1401 }
1402 
1403 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment3DPBO)1404 TEST_P(ReadPixelsTextureTest, MipAttachment3DPBO)
1405 {
1406     testPBORead(GL_TEXTURE_3D, 2, 1, 0);
1407 }
1408 
1409 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment3DPBO)1410 TEST_P(ReadPixelsTextureTest, LayerAttachment3DPBO)
1411 {
1412     // http://anglebug.com/40644770
1413     ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
1414 
1415     testPBORead(GL_TEXTURE_3D, 1, 0, 1);
1416 }
1417 
1418 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment3DPBO)1419 TEST_P(ReadPixelsTextureTest, MipLayerAttachment3DPBO)
1420 {
1421     // http://anglebug.com/40644770
1422     ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
1423 
1424     testPBORead(GL_TEXTURE_3D, 2, 1, 1);
1425 }
1426 
1427 // Test 2D array attachment readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment2DArrayPBO)1428 TEST_P(ReadPixelsTextureTest, BasicAttachment2DArrayPBO)
1429 {
1430     testPBORead(GL_TEXTURE_2D_ARRAY, 1, 0, 0);
1431 }
1432 
1433 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment2DArrayPBO)1434 TEST_P(ReadPixelsTextureTest, MipAttachment2DArrayPBO)
1435 {
1436     testPBORead(GL_TEXTURE_2D_ARRAY, 2, 1, 0);
1437 }
1438 
1439 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment2DArrayPBO)1440 TEST_P(ReadPixelsTextureTest, LayerAttachment2DArrayPBO)
1441 {
1442     // http://anglebug.com/40644770
1443     ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
1444 
1445     testPBORead(GL_TEXTURE_2D_ARRAY, 1, 0, 1);
1446 }
1447 
1448 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment2DArrayPBO)1449 TEST_P(ReadPixelsTextureTest, MipLayerAttachment2DArrayPBO)
1450 {
1451     // http://anglebug.com/40644770
1452     ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
1453 
1454     testPBORead(GL_TEXTURE_2D_ARRAY, 2, 1, 1);
1455 }
1456 
1457 // a test class to be used for error checking of glReadPixels
1458 class ReadPixelsErrorTest : public ReadPixelsTest
1459 {
1460   protected:
ReadPixelsErrorTest()1461     ReadPixelsErrorTest() : mTexture(0), mFBO(0) {}
1462 
testSetUp()1463     void testSetUp() override
1464     {
1465         glGenTextures(1, &mTexture);
1466         glBindTexture(GL_TEXTURE_2D, mTexture);
1467         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 1);
1468 
1469         glGenFramebuffers(1, &mFBO);
1470         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1471         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
1472         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1473 
1474         ASSERT_GL_NO_ERROR();
1475     }
1476 
testTearDown()1477     void testTearDown() override
1478     {
1479         glDeleteTextures(1, &mTexture);
1480         glDeleteFramebuffers(1, &mFBO);
1481     }
1482 
testUnsupportedTypeConversions(std::vector<GLenum> internalFormats,std::vector<GLenum> unsupportedTypes)1483     void testUnsupportedTypeConversions(std::vector<GLenum> internalFormats,
1484                                         std::vector<GLenum> unsupportedTypes)
1485     {
1486         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1487         for (GLenum internalFormat : internalFormats)
1488         {
1489             GLRenderbuffer rbo;
1490             glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1491             glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1);
1492             ASSERT_GL_NO_ERROR();
1493 
1494             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1495             ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1496 
1497             GLenum implementationFormat, implementationType;
1498             glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT,
1499                           reinterpret_cast<GLint *>(&implementationFormat));
1500             ASSERT_GL_NO_ERROR();
1501             glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE,
1502                           reinterpret_cast<GLint *>(&implementationType));
1503             ASSERT_GL_NO_ERROR();
1504 
1505             for (GLenum type : unsupportedTypes)
1506             {
1507                 uint8_t pixel[8] = {};
1508                 if (implementationFormat != GL_RGBA || implementationType != type)
1509                 {
1510                     glReadPixels(0, 0, 1, 1, GL_RGBA, type, pixel);
1511                     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1512                 }
1513             }
1514         }
1515     }
1516 
1517     GLuint mTexture;
1518     GLuint mFBO;
1519 };
1520 
1521 //  The test verifies that glReadPixels generates a GL_INVALID_OPERATION error
1522 //  when the read buffer is GL_NONE.
1523 //  Reference: GLES 3.0.4, Section 4.3.2 Reading Pixels
TEST_P(ReadPixelsErrorTest,ReadBufferIsNone)1524 TEST_P(ReadPixelsErrorTest, ReadBufferIsNone)
1525 {
1526     glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1527     glReadBuffer(GL_NONE);
1528     std::vector<GLubyte> pixels(4);
1529     EXPECT_GL_NO_ERROR();
1530     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1531     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1532 }
1533 
1534 // The test verifies that glReadPixels generates a GL_INVALID_OPERATION
1535 // error when reading signed 8-bit color buffers using incompatible types.
TEST_P(ReadPixelsErrorTest,ColorBufferSnorm8)1536 TEST_P(ReadPixelsErrorTest, ColorBufferSnorm8)
1537 {
1538     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1539 
1540     testUnsupportedTypeConversions({GL_R8_SNORM, GL_RG8_SNORM, GL_RGBA8_SNORM},
1541                                    {GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT});
1542 }
1543 
1544 // The test verifies that glReadPixels generates a GL_INVALID_OPERATION
1545 // error when reading signed 16-bit color buffers using incompatible types.
TEST_P(ReadPixelsErrorTest,ColorBufferSnorm16)1546 TEST_P(ReadPixelsErrorTest, ColorBufferSnorm16)
1547 {
1548     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1549     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1550 
1551     testUnsupportedTypeConversions({GL_R16_SNORM_EXT, GL_RG16_SNORM_EXT, GL_RGBA16_SNORM_EXT},
1552                                    {GL_BYTE, GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT});
1553 }
1554 
1555 // a test class to be used for error checking of glReadPixels with WebGLCompatibility
1556 class ReadPixelsWebGLErrorTest : public ReadPixelsTest
1557 {
1558   protected:
ReadPixelsWebGLErrorTest()1559     ReadPixelsWebGLErrorTest() : mTexture(0), mFBO(0) { setWebGLCompatibilityEnabled(true); }
1560 
testSetUp()1561     void testSetUp() override
1562     {
1563         glGenTextures(1, &mTexture);
1564         glBindTexture(GL_TEXTURE_2D, mTexture);
1565         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 1);
1566 
1567         glGenFramebuffers(1, &mFBO);
1568         glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1569         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
1570         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1571 
1572         ASSERT_GL_NO_ERROR();
1573     }
1574 
testTearDown()1575     void testTearDown() override
1576     {
1577         glDeleteTextures(1, &mTexture);
1578         glDeleteFramebuffers(1, &mFBO);
1579     }
1580 
1581     GLuint mTexture;
1582     GLuint mFBO;
1583 };
1584 
1585 // Test that WebGL context readpixels generates an error when reading GL_UNSIGNED_INT_24_8 type.
TEST_P(ReadPixelsWebGLErrorTest,TypeIsUnsignedInt24_8)1586 TEST_P(ReadPixelsWebGLErrorTest, TypeIsUnsignedInt24_8)
1587 {
1588     glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1589     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
1590     glReadBuffer(GL_COLOR_ATTACHMENT0);
1591     std::vector<GLuint> pixels(4);
1592     EXPECT_GL_NO_ERROR();
1593     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_INT_24_8, pixels.data());
1594     EXPECT_GL_ERROR(GL_INVALID_ENUM);
1595 }
1596 
1597 // Test that WebGL context readpixels generates an error when reading GL_DEPTH_COMPONENT format.
TEST_P(ReadPixelsWebGLErrorTest,FormatIsDepthComponent)1598 TEST_P(ReadPixelsWebGLErrorTest, FormatIsDepthComponent)
1599 {
1600     glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1601     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
1602     glReadBuffer(GL_COLOR_ATTACHMENT0);
1603     std::vector<GLubyte> pixels(4);
1604     EXPECT_GL_NO_ERROR();
1605     glReadPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, pixels.data());
1606     EXPECT_GL_ERROR(GL_INVALID_ENUM);
1607 }
1608 
1609 }  // anonymous namespace
1610 
1611 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
1612 // tests should be run against.
1613 ANGLE_INSTANTIATE_TEST_ES2(ReadPixelsTest);
1614 ANGLE_INSTANTIATE_TEST_ES2(ReadPixelsPBONVTest);
1615 
1616 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsPBOTest);
1617 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsPBOTest);
1618 
1619 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsPBODrawTest);
1620 ANGLE_INSTANTIATE_TEST_ES3_AND(ReadPixelsPBODrawTest,
1621                                ES3_VULKAN().enable(Feature::ForceFallbackFormat));
1622 
1623 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsTextureNorm16PBOTest);
1624 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsTextureNorm16PBOTest);
1625 
1626 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsMultisampleTest);
1627 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsMultisampleTest);
1628 
1629 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsTextureTest);
1630 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsTextureTest);
1631 
1632 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsErrorTest);
1633 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsErrorTest);
1634 
1635 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsWebGLErrorTest);
1636 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsWebGLErrorTest);
1637