• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "ANGLETest.h"
2 
3 class ReadPixelsTest : public ANGLETest
4 {
5 protected:
ReadPixelsTest()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 
SetUp()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 
TearDown()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 
TEST_F(ReadPixelsTest,out_of_bounds)87 TEST_F(ReadPixelsTest, out_of_bounds)
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 
TEST_F(ReadPixelsTest,pbo_with_other_target)120 TEST_F(ReadPixelsTest, pbo_with_other_target)
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 
TEST_F(ReadPixelsTest,pbo_with_existing_data)145 TEST_F(ReadPixelsTest, pbo_with_existing_data)
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 
TEST_F(ReadPixelsTest,pbo_and_sub_data)183 TEST_F(ReadPixelsTest, pbo_and_sub_data)
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 
TEST_F(ReadPixelsTest,pbo_and_sub_data_offset)211 TEST_F(ReadPixelsTest, pbo_and_sub_data_offset)
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 
TEST_F(ReadPixelsTest,draw_with_pbo)244 TEST_F(ReadPixelsTest, draw_with_pbo)
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