1#include "ANGLETest.h"
2
3class ReadPixelsTest : public ANGLETest
4{
5protected:
6    ReadPixelsTest()
7    {
8        setClientVersion(3);
9        setWindowWidth(32);
10        setWindowHeight(32);
11        setConfigRedBits(8);
12        setConfigGreenBits(8);
13        setConfigBlueBits(8);
14        setConfigAlphaBits(8);
15    }
16
17    virtual void SetUp()
18    {
19        ANGLETest::SetUp();
20
21        glGenBuffers(1, &mPBO);
22        glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
23        glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), NULL, GL_STATIC_DRAW);
24        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
25
26        const char *vertexShaderSrc = SHADER_SOURCE
27        (
28            attribute vec4 aTest;
29            attribute vec2 aPosition;
30            varying vec4 vTest;
31
32            void main()
33            {
34                vTest = aTest;
35                gl_Position = vec4(aPosition, 0.0, 1.0);
36                gl_PointSize = 1.0;
37            }
38        );
39
40        const char *fragmentShaderSrc = SHADER_SOURCE
41        (
42            precision mediump float;
43            varying vec4 vTest;
44
45            void main()
46            {
47                gl_FragColor = vTest;
48            }
49        );
50
51        mProgram = CompileProgram(vertexShaderSrc, fragmentShaderSrc);
52
53        glGenTextures(1, &mTexture);
54        glBindTexture(GL_TEXTURE_2D, mTexture);
55        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 1);
56
57        glGenFramebuffers(1, &mFBO);
58        glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
59        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
60        glBindFramebuffer(GL_FRAMEBUFFER, 0);
61
62        glGenBuffers(1, &mPositionVBO);
63        glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
64        glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW);
65        glBindBuffer(GL_ARRAY_BUFFER, 0);
66
67        ASSERT_GL_NO_ERROR();
68    }
69
70    virtual void TearDown()
71    {
72        ANGLETest::TearDown();
73
74        glDeleteBuffers(1, &mPBO);
75        glDeleteProgram(mProgram);
76        glDeleteTextures(1, &mTexture);
77        glDeleteFramebuffers(1, &mFBO);
78    }
79
80    GLuint mPBO;
81    GLuint mProgram;
82    GLuint mTexture;
83    GLuint mFBO;
84    GLuint mPositionVBO;
85};
86
87TEST_F(ReadPixelsTest, OutOfBounds)
88{
89    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
90    glClear(GL_COLOR_BUFFER_BIT);
91    EXPECT_GL_NO_ERROR();
92
93    GLsizei pixelsWidth = 32;
94    GLsizei pixelsHeight = 32;
95    GLint offset = 16;
96    std::vector<GLubyte> pixels((pixelsWidth + offset) * (pixelsHeight + offset) * 4);
97
98    glReadPixels(-offset, -offset, pixelsWidth + offset, pixelsHeight + offset, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
99    EXPECT_GL_NO_ERROR();
100
101    for (int y = pixelsHeight / 2; y < pixelsHeight; y++)
102    {
103        for (int x = pixelsWidth / 2; x < pixelsWidth; x++)
104        {
105            const GLubyte* pixel = pixels.data() + ((y * (pixelsWidth + offset) + x) * 4);
106            unsigned int r = static_cast<unsigned int>(pixel[0]);
107            unsigned int g = static_cast<unsigned int>(pixel[1]);
108            unsigned int b = static_cast<unsigned int>(pixel[2]);
109            unsigned int a = static_cast<unsigned int>(pixel[3]);
110
111            // Expect that all pixels which fell within the framebuffer are red
112            EXPECT_EQ(255, r);
113            EXPECT_EQ(0,   g);
114            EXPECT_EQ(0,   b);
115            EXPECT_EQ(255, a);
116        }
117    }
118}
119
120TEST_F(ReadPixelsTest, PBOWithOtherTarget)
121{
122    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
123    glClear(GL_COLOR_BUFFER_BIT);
124    EXPECT_GL_NO_ERROR();
125
126    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
127    glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
128
129    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
130    glBindBuffer(GL_ARRAY_BUFFER, mPBO);
131
132    GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
133    unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
134    EXPECT_GL_NO_ERROR();
135
136    EXPECT_EQ(255, dataPtr[0]);
137    EXPECT_EQ(0,   dataPtr[1]);
138    EXPECT_EQ(0,   dataPtr[2]);
139    EXPECT_EQ(255, dataPtr[3]);
140
141    glUnmapBuffer(GL_ARRAY_BUFFER);
142    EXPECT_GL_NO_ERROR();
143}
144
145TEST_F(ReadPixelsTest, PBOWithExistingData)
146{
147    // Clear backbuffer to red
148    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
149    glClear(GL_COLOR_BUFFER_BIT);
150    EXPECT_GL_NO_ERROR();
151
152    // Read 16x16 region from red backbuffer to PBO
153    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
154    glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
155
156    // Clear backbuffer to green
157    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
158    glClear(GL_COLOR_BUFFER_BIT);
159    EXPECT_GL_NO_ERROR();
160
161    // Read 16x16 region from green backbuffer to PBO at offset 16
162    glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(16));
163    GLvoid * mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
164    unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
165    EXPECT_GL_NO_ERROR();
166
167    // Test pixel 0 is red (existing data)
168    EXPECT_EQ(255, dataPtr[0]);
169    EXPECT_EQ(0, dataPtr[1]);
170    EXPECT_EQ(0, dataPtr[2]);
171    EXPECT_EQ(255, dataPtr[3]);
172
173    // Test pixel 16 is green (new data)
174    EXPECT_EQ(0, dataPtr[16 * 4 + 0]);
175    EXPECT_EQ(255, dataPtr[16 * 4 + 1]);
176    EXPECT_EQ(0, dataPtr[16 * 4 + 2]);
177    EXPECT_EQ(255, dataPtr[16 * 4 + 3]);
178
179    glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
180    EXPECT_GL_NO_ERROR();
181}
182
183TEST_F(ReadPixelsTest, PBOAndSubData)
184{
185    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
186    glClear(GL_COLOR_BUFFER_BIT);
187    EXPECT_GL_NO_ERROR();
188
189    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
190    glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
191
192    unsigned char data[4] = { 1, 2, 3, 4 };
193
194    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
195    glBindBuffer(GL_ARRAY_BUFFER, mPBO);
196    glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
197
198    GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
199    unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
200    EXPECT_GL_NO_ERROR();
201
202    EXPECT_EQ(1, dataPtr[0]);
203    EXPECT_EQ(2, dataPtr[1]);
204    EXPECT_EQ(3, dataPtr[2]);
205    EXPECT_EQ(4, dataPtr[3]);
206
207    glUnmapBuffer(GL_ARRAY_BUFFER);
208    EXPECT_GL_NO_ERROR();
209}
210
211TEST_F(ReadPixelsTest, PBOAndSubDataOffset)
212{
213    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
214    glClear(GL_COLOR_BUFFER_BIT);
215    EXPECT_GL_NO_ERROR();
216
217    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
218    glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
219
220    unsigned char data[4] = { 1, 2, 3, 4 };
221
222    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
223    glBindBuffer(GL_ARRAY_BUFFER, mPBO);
224    glBufferSubData(GL_ARRAY_BUFFER, 16, 4, data);
225
226    GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
227    unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
228    EXPECT_GL_NO_ERROR();
229
230    EXPECT_EQ(255, dataPtr[0]);
231    EXPECT_EQ(0, dataPtr[1]);
232    EXPECT_EQ(0, dataPtr[2]);
233    EXPECT_EQ(255, dataPtr[3]);
234
235    EXPECT_EQ(1, dataPtr[16]);
236    EXPECT_EQ(2, dataPtr[17]);
237    EXPECT_EQ(3, dataPtr[18]);
238    EXPECT_EQ(4, dataPtr[19]);
239
240    glUnmapBuffer(GL_ARRAY_BUFFER);
241    EXPECT_GL_NO_ERROR();
242}
243
244TEST_F(ReadPixelsTest, DrawWithPBO)
245{
246    unsigned char data[4] = { 1, 2, 3, 4 };
247
248    glBindTexture(GL_TEXTURE_2D, mTexture);
249    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
250    EXPECT_GL_NO_ERROR();
251
252    // glReadBuffer(GL_COLOR_ATTACHMENT0); // FIXME: currently UNIMPLEMENTED
253    glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO);
254    EXPECT_GL_NO_ERROR();
255
256    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
257    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
258    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
259    EXPECT_GL_NO_ERROR();
260
261    float positionData[] = { 0.5f, 0.5f };
262
263    glUseProgram(mProgram);
264    glViewport(0, 0, 1, 1);
265    glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
266    glBufferSubData(GL_ARRAY_BUFFER, 0, 1 * 2 * 4, positionData);
267    EXPECT_GL_NO_ERROR();
268
269    GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
270    EXPECT_NE(-1, positionLocation);
271
272    GLint testLocation = glGetAttribLocation(mProgram, "aTest");
273    EXPECT_NE(-1, testLocation);
274
275    glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
276    glEnableVertexAttribArray(positionLocation);
277    EXPECT_GL_NO_ERROR();
278
279    glBindBuffer(GL_ARRAY_BUFFER, mPBO);
280    glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
281    glEnableVertexAttribArray(testLocation);
282    EXPECT_GL_NO_ERROR();
283
284    glDrawArrays(GL_POINTS, 0, 1);
285    EXPECT_GL_NO_ERROR();
286
287    memset(data, 0, 4);
288    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
289    EXPECT_GL_NO_ERROR();
290
291    EXPECT_EQ(1, data[0]);
292    EXPECT_EQ(2, data[1]);
293    EXPECT_EQ(3, data[2]);
294    EXPECT_EQ(4, data[3]);
295}
296
297TEST_F(ReadPixelsTest, MultisampledPBO)
298{
299    GLuint fbo;
300    glGenFramebuffers(1, &fbo);
301    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
302
303    GLuint rbo;
304    glGenRenderbuffers(1, &rbo);
305    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
306    glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
307
308    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
309
310    ASSERT_GL_NO_ERROR();
311
312    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
313    glClear(GL_COLOR_BUFFER_BIT);
314
315    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
316
317    EXPECT_GL_NO_ERROR();
318
319    glReadPixels(0, 0, 1, 1, GL_RGBA8, GL_UNSIGNED_BYTE, NULL);
320
321    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
322
323    glDeleteRenderbuffers(1, &rbo);
324    glDeleteFramebuffers(1, &fbo);
325}
326