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