• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
7 #include "test_utils/ANGLETest.h"
8 #include "test_utils/gl_raii.h"
9 #include "util/EGLWindow.h"
10 
11 using namespace angle;
12 
13 class PbufferTest : public ANGLETest
14 {
15   protected:
PbufferTest()16     PbufferTest()
17     {
18         setWindowWidth(512);
19         setWindowHeight(512);
20         setConfigRedBits(8);
21         setConfigGreenBits(8);
22         setConfigBlueBits(8);
23         setConfigAlphaBits(8);
24     }
25 
testSetUp()26     void testSetUp() override
27     {
28         constexpr char kVS[] =
29             R"(precision highp float;
30             attribute vec4 position;
31             varying vec2 texcoord;
32 
33             void main()
34             {
35                 gl_Position = position;
36                 texcoord = (position.xy * 0.5) + 0.5;
37                 texcoord.y = 1.0 - texcoord.y;
38             })";
39 
40         constexpr char kFS[] =
41             R"(precision highp float;
42             uniform sampler2D tex;
43             varying vec2 texcoord;
44 
45             void main()
46             {
47                 gl_FragColor = texture2D(tex, texcoord);
48             })";
49 
50         mTextureProgram = CompileProgram(kVS, kFS);
51         if (mTextureProgram == 0)
52         {
53             FAIL() << "shader compilation failed.";
54         }
55 
56         mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
57 
58         EGLWindow *window = getEGLWindow();
59 
60         EGLint surfaceType = 0;
61         eglGetConfigAttrib(window->getDisplay(), window->getConfig(), EGL_SURFACE_TYPE,
62                            &surfaceType);
63         mSupportsPbuffers = (surfaceType & EGL_PBUFFER_BIT) != 0;
64 
65         EGLint bindToTextureRGBA = 0;
66         eglGetConfigAttrib(window->getDisplay(), window->getConfig(), EGL_BIND_TO_TEXTURE_RGBA,
67                            &bindToTextureRGBA);
68         mSupportsBindTexImage = (bindToTextureRGBA == EGL_TRUE);
69 
70         const EGLint pBufferAttributes[] = {
71             EGL_WIDTH,          static_cast<EGLint>(mPbufferSize),
72             EGL_HEIGHT,         static_cast<EGLint>(mPbufferSize),
73             EGL_TEXTURE_FORMAT, mSupportsBindTexImage ? EGL_TEXTURE_RGBA : EGL_NO_TEXTURE,
74             EGL_TEXTURE_TARGET, mSupportsBindTexImage ? EGL_TEXTURE_2D : EGL_NO_TEXTURE,
75             EGL_NONE,           EGL_NONE,
76         };
77 
78         mPbuffer =
79             eglCreatePbufferSurface(window->getDisplay(), window->getConfig(), pBufferAttributes);
80         if (mSupportsPbuffers)
81         {
82             ASSERT_NE(mPbuffer, EGL_NO_SURFACE);
83             ASSERT_EGL_SUCCESS();
84         }
85         else
86         {
87             ASSERT_EQ(mPbuffer, EGL_NO_SURFACE);
88             ASSERT_EGL_ERROR(EGL_BAD_MATCH);
89         }
90 
91         ASSERT_GL_NO_ERROR();
92     }
93 
testTearDown()94     void testTearDown() override
95     {
96         glDeleteProgram(mTextureProgram);
97 
98         if (mPbuffer)
99         {
100             EGLWindow *window = getEGLWindow();
101             eglDestroySurface(window->getDisplay(), mPbuffer);
102         }
103     }
104 
recreatePbufferInSrgbColorspace()105     void recreatePbufferInSrgbColorspace()
106     {
107         EGLWindow *window = getEGLWindow();
108 
109         if (mPbuffer)
110         {
111             eglDestroySurface(window->getDisplay(), mPbuffer);
112         }
113 
114         const EGLint pBufferSrgbAttributes[] = {
115             EGL_WIDTH,
116             static_cast<EGLint>(mPbufferSize),
117             EGL_HEIGHT,
118             static_cast<EGLint>(mPbufferSize),
119             EGL_TEXTURE_FORMAT,
120             mSupportsBindTexImage ? EGL_TEXTURE_RGBA : EGL_NO_TEXTURE,
121             EGL_TEXTURE_TARGET,
122             mSupportsBindTexImage ? EGL_TEXTURE_2D : EGL_NO_TEXTURE,
123             EGL_GL_COLORSPACE_KHR,
124             EGL_GL_COLORSPACE_SRGB_KHR,
125             EGL_NONE,
126             EGL_NONE,
127         };
128 
129         mPbuffer = eglCreatePbufferSurface(window->getDisplay(), window->getConfig(),
130                                            pBufferSrgbAttributes);
131     }
132 
133     GLuint mTextureProgram;
134     GLint mTextureUniformLocation;
135 
136     const size_t mPbufferSize = 32;
137     EGLSurface mPbuffer       = EGL_NO_SURFACE;
138     bool mSupportsPbuffers;
139     bool mSupportsBindTexImage;
140 };
141 
142 // Test clearing a Pbuffer and checking the color is correct
TEST_P(PbufferTest,Clearing)143 TEST_P(PbufferTest, Clearing)
144 {
145     ANGLE_SKIP_TEST_IF(!mSupportsPbuffers);
146 
147     EGLWindow *window = getEGLWindow();
148 
149     // Clear the window surface to blue and verify
150     window->makeCurrent();
151     ASSERT_EGL_SUCCESS();
152 
153     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
154     glClear(GL_COLOR_BUFFER_BIT);
155     ASSERT_GL_NO_ERROR();
156     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue);
157 
158     // Apply the Pbuffer and clear it to purple and verify
159     eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
160     ASSERT_EGL_SUCCESS();
161 
162     glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
163     glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
164     glClear(GL_COLOR_BUFFER_BIT);
165     ASSERT_GL_NO_ERROR();
166     EXPECT_PIXEL_EQ(static_cast<GLint>(mPbufferSize) / 2, static_cast<GLint>(mPbufferSize) / 2, 255,
167                     0, 255, 255);
168 
169     // Rebind the window surface and verify that it is still blue
170     window->makeCurrent();
171     ASSERT_EGL_SUCCESS();
172     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 255, 255);
173 }
174 
175 // Bind the Pbuffer to a texture and verify it renders correctly
TEST_P(PbufferTest,BindTexImage)176 TEST_P(PbufferTest, BindTexImage)
177 {
178     // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
179     // textures.
180     ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
181 
182     EGLWindow *window = getEGLWindow();
183 
184     // Apply the Pbuffer and clear it to purple
185     eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
186     ASSERT_EGL_SUCCESS();
187 
188     glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
189     glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
190     glClear(GL_COLOR_BUFFER_BIT);
191     ASSERT_GL_NO_ERROR();
192 
193     EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(mPbufferSize) / 2,
194                           static_cast<GLint>(mPbufferSize) / 2, GLColor::magenta);
195 
196     // Apply the window surface
197     window->makeCurrent();
198 
199     // Create a texture and bind the Pbuffer to it
200     GLuint texture = 0;
201     glGenTextures(1, &texture);
202     glBindTexture(GL_TEXTURE_2D, texture);
203     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
204     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
205     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
206     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
207     EXPECT_GL_NO_ERROR();
208 
209     eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
210     glViewport(0, 0, getWindowWidth(), getWindowHeight());
211     ASSERT_EGL_SUCCESS();
212 
213     // Draw a quad and verify that it is purple
214     glUseProgram(mTextureProgram);
215     glUniform1i(mTextureUniformLocation, 0);
216 
217     drawQuad(mTextureProgram, "position", 0.5f);
218     EXPECT_GL_NO_ERROR();
219 
220     // Unbind the texture
221     eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
222     ASSERT_EGL_SUCCESS();
223 
224     // Verify that purple was drawn
225     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 255, 255);
226 
227     glDeleteTextures(1, &texture);
228 }
229 
230 // Test clearing a Pbuffer in sRGB colorspace and checking the color is correct.
231 // Then bind the Pbuffer to a texture and verify it renders correctly
TEST_P(PbufferTest,ClearAndBindTexImageSrgb)232 TEST_P(PbufferTest, ClearAndBindTexImageSrgb)
233 {
234     EGLWindow *window = getEGLWindow();
235 
236     // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
237     // textures.
238     ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
239     ANGLE_SKIP_TEST_IF(
240         !IsEGLDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_colorspace"));
241     // Possible GLES driver bug on Pixel2 devices: http://anglebug.com/5321
242     ANGLE_SKIP_TEST_IF(IsPixel2() && IsOpenGLES());
243 
244     GLubyte kLinearColor[] = {132, 55, 219, 255};
245     GLubyte kSrgbColor[]   = {190, 128, 238, 255};
246 
247     // Switch to sRGB
248     recreatePbufferInSrgbColorspace();
249     EGLint colorspace = 0;
250     eglQuerySurface(window->getDisplay(), mPbuffer, EGL_GL_COLORSPACE, &colorspace);
251     EXPECT_EQ(colorspace, EGL_GL_COLORSPACE_SRGB_KHR);
252 
253     // Clear the Pbuffer surface with `kLinearColor`
254     eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
255     ASSERT_EGL_SUCCESS();
256 
257     glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
258     glClearColor(kLinearColor[0] / 255.0f, kLinearColor[1] / 255.0f, kLinearColor[2] / 255.0f,
259                  kLinearColor[3] / 255.0f);
260     glClear(GL_COLOR_BUFFER_BIT);
261     ASSERT_GL_NO_ERROR();
262 
263     // Expect glReadPixels to be `kSrgbColor` with a tolerance of 1
264     EXPECT_PIXEL_NEAR(static_cast<GLint>(mPbufferSize) / 2, static_cast<GLint>(mPbufferSize) / 2,
265                       kSrgbColor[0], kSrgbColor[1], kSrgbColor[2], kSrgbColor[3], 1);
266 
267     window->makeCurrent();
268 
269     // Create a texture and bind the Pbuffer to it
270     GLuint texture = 0;
271     glGenTextures(1, &texture);
272     glBindTexture(GL_TEXTURE_2D, texture);
273     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
274     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
275     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
276     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
277     EXPECT_GL_NO_ERROR();
278 
279     eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
280     glViewport(0, 0, getWindowWidth(), getWindowHeight());
281     ASSERT_EGL_SUCCESS();
282 
283     // Sample from a texture with `kSrgbColor` data and render into a surface in linear colorspace.
284     glUseProgram(mTextureProgram);
285     glUniform1i(mTextureUniformLocation, 0);
286 
287     drawQuad(mTextureProgram, "position", 0.5f);
288     EXPECT_GL_NO_ERROR();
289 
290     // Unbind the texture
291     eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
292     ASSERT_EGL_SUCCESS();
293 
294     // Expect glReadPixels to be `kLinearColor` with a tolerance of 1
295     EXPECT_PIXEL_NEAR(getWindowWidth() / 2, getWindowHeight() / 2, kLinearColor[0], kLinearColor[1],
296                       kLinearColor[2], kLinearColor[3], 1);
297 
298     glDeleteTextures(1, &texture);
299 }
300 
301 // Test clearing a Pbuffer in sRGB colorspace and checking the color is correct.
302 // Then bind the Pbuffer to a texture and verify it renders correctly.
303 // Then change texture state to skip decode and verify it renders correctly.
TEST_P(PbufferTest,ClearAndBindTexImageSrgbSkipDecode)304 TEST_P(PbufferTest, ClearAndBindTexImageSrgbSkipDecode)
305 {
306     EGLWindow *window = getEGLWindow();
307 
308     // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
309     // textures.
310     ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
311     ANGLE_SKIP_TEST_IF(
312         !IsEGLDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_colorspace"));
313     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode"));
314     // Possible GLES driver bug on Pixel devices: http://anglebug.com/5321
315     ANGLE_SKIP_TEST_IF((IsPixel2() || IsPixel4()) && IsOpenGLES());
316 
317     GLubyte kLinearColor[] = {132, 55, 219, 255};
318     GLubyte kSrgbColor[]   = {190, 128, 238, 255};
319 
320     // Switch to sRGB
321     recreatePbufferInSrgbColorspace();
322     EGLint colorspace = 0;
323     eglQuerySurface(window->getDisplay(), mPbuffer, EGL_GL_COLORSPACE, &colorspace);
324     EXPECT_EQ(colorspace, EGL_GL_COLORSPACE_SRGB_KHR);
325 
326     // Clear the Pbuffer surface with `kLinearColor`
327     eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
328     ASSERT_EGL_SUCCESS();
329 
330     glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
331     glClearColor(kLinearColor[0] / 255.0f, kLinearColor[1] / 255.0f, kLinearColor[2] / 255.0f,
332                  kLinearColor[3] / 255.0f);
333     glClear(GL_COLOR_BUFFER_BIT);
334     ASSERT_GL_NO_ERROR();
335 
336     // Expect glReadPixels to be `kSrgbColor` with a tolerance of 1
337     EXPECT_PIXEL_NEAR(static_cast<GLint>(mPbufferSize) / 2, static_cast<GLint>(mPbufferSize) / 2,
338                       kSrgbColor[0], kSrgbColor[1], kSrgbColor[2], kSrgbColor[3], 1);
339 
340     window->makeCurrent();
341 
342     // Create a texture and bind the Pbuffer to it
343     GLuint texture = 0;
344     glGenTextures(1, &texture);
345     glBindTexture(GL_TEXTURE_2D, texture);
346     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
347     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
348     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
349     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
350     EXPECT_GL_NO_ERROR();
351 
352     eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
353     glViewport(0, 0, getWindowWidth(), getWindowHeight());
354     ASSERT_EGL_SUCCESS();
355 
356     // Sample from a texture with `kSrgbColor` data and render into a surface in linear colorspace.
357     glUseProgram(mTextureProgram);
358     glUniform1i(mTextureUniformLocation, 0);
359 
360     drawQuad(mTextureProgram, "position", 0.5f);
361     EXPECT_GL_NO_ERROR();
362 
363     // Expect glReadPixels to be `kLinearColor` with a tolerance of 1
364     EXPECT_PIXEL_NEAR(getWindowWidth() / 2, getWindowHeight() / 2, kLinearColor[0], kLinearColor[1],
365                       kLinearColor[2], kLinearColor[3], 1);
366 
367     // Set skip decode for the texture
368     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
369     drawQuad(mTextureProgram, "position", 0.5f);
370 
371     // Texture is in skip decode mode, expect glReadPixels to be `kSrgbColor` with tolerance of 1
372     EXPECT_PIXEL_NEAR(getWindowWidth() / 2, getWindowHeight() / 2, kSrgbColor[0], kSrgbColor[1],
373                       kSrgbColor[2], kSrgbColor[3], 1);
374 
375     // Unbind the texture
376     eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
377     ASSERT_EGL_SUCCESS();
378 
379     glDeleteTextures(1, &texture);
380 }
381 
382 // Verify that when eglBind/ReleaseTexImage are called, the texture images are freed and their
383 // size information is correctly updated.
TEST_P(PbufferTest,TextureSizeReset)384 TEST_P(PbufferTest, TextureSizeReset)
385 {
386     ANGLE_SKIP_TEST_IF(!mSupportsPbuffers);
387     ANGLE_SKIP_TEST_IF(!mSupportsBindTexImage);
388     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
389 
390     GLTexture texture;
391     glBindTexture(GL_TEXTURE_2D, texture);
392     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
393     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
394     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
395     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
396     EXPECT_GL_NO_ERROR();
397 
398     glUseProgram(mTextureProgram);
399     glUniform1i(mTextureUniformLocation, 0);
400 
401     // Fill the texture with white pixels
402     std::vector<GLColor> whitePixels(mPbufferSize * mPbufferSize, GLColor::white);
403     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<GLsizei>(mPbufferSize),
404                  static_cast<GLsizei>(mPbufferSize), 0, GL_RGBA, GL_UNSIGNED_BYTE,
405                  whitePixels.data());
406     EXPECT_GL_NO_ERROR();
407 
408     // Draw the white texture and verify that the pixels are correct
409     drawQuad(mTextureProgram, "position", 0.5f);
410     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
411 
412     // Bind the EGL surface and draw with it, results are undefined since nothing has
413     // been written to it
414     EGLWindow *window = getEGLWindow();
415     eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
416     drawQuad(mTextureProgram, "position", 0.5f);
417     EXPECT_GL_NO_ERROR();
418 
419     // Clear the back buffer to a unique color (green)
420     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
421     glClear(GL_COLOR_BUFFER_BIT);
422     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
423 
424     // Unbind the EGL surface and try to draw with the texture again, the texture's size should
425     // now be zero and incomplete so the back buffer should be black
426     eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
427     drawQuad(mTextureProgram, "position", 0.5f);
428     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
429 }
430 
431 // Bind a Pbuffer, redefine the texture, and verify it renders correctly
TEST_P(PbufferTest,BindTexImageAndRedefineTexture)432 TEST_P(PbufferTest, BindTexImageAndRedefineTexture)
433 {
434     // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
435     // textures.
436     ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
437 
438     EGLWindow *window = getEGLWindow();
439 
440     // Apply the Pbuffer and clear it to purple
441     eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
442     ASSERT_EGL_SUCCESS();
443 
444     glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
445     glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
446     glClear(GL_COLOR_BUFFER_BIT);
447     ASSERT_GL_NO_ERROR();
448 
449     EXPECT_PIXEL_EQ(static_cast<GLint>(mPbufferSize) / 2, static_cast<GLint>(mPbufferSize) / 2, 255,
450                     0, 255, 255);
451 
452     // Apply the window surface
453     window->makeCurrent();
454 
455     // Create a texture and bind the Pbuffer to it
456     GLuint texture = 0;
457     glGenTextures(1, &texture);
458     glBindTexture(GL_TEXTURE_2D, texture);
459     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
460     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
461     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
462     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
463     EXPECT_GL_NO_ERROR();
464 
465     eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
466     glViewport(0, 0, getWindowWidth(), getWindowHeight());
467     ASSERT_EGL_SUCCESS();
468 
469     // Redefine the texture
470     unsigned int pixelValue = 0xFFFF00FF;
471     std::vector<unsigned int> pixelData(getWindowWidth() * getWindowHeight(), pixelValue);
472     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
473                  GL_UNSIGNED_BYTE, &pixelData[0]);
474 
475     // Draw a quad and verify that it is magenta
476     glUseProgram(mTextureProgram);
477     glUniform1i(mTextureUniformLocation, 0);
478 
479     drawQuad(mTextureProgram, "position", 0.5f);
480     EXPECT_GL_NO_ERROR();
481 
482     // Verify that magenta was drawn
483     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 255, 255);
484 
485     glDeleteTextures(1, &texture);
486 }
487 
488 ANGLE_INSTANTIATE_TEST_ES2(PbufferTest);
489