1 #include "ANGLETest.h" 2 3 class ReadPixelsTest : public ANGLETest 4 { 5 protected: 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 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 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 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 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 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 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