1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef GL_GLEXT_PROTOTYPES
6 #define GL_GLEXT_PROTOTYPES
10 #include <GLES2/gl2ext.h>
11 #include <GLES2/gl2extchromium.h>
13 #include "gpu/command_buffer/tests/gl_manager.h"
14 #include "gpu/command_buffer/tests/gl_test_utils.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
20 // A collection of tests that exercise the GL_CHROMIUM_copy_texture extension.
21 class GLCopyTextureCHROMIUMTest : public testing::Test {
23 virtual void SetUp() {
24 gl_.Initialize(GLManager::Options());
26 glGenTextures(2, textures_);
27 glBindTexture(GL_TEXTURE_2D, textures_[1]);
29 // Some drivers (NVidia/SGX) require texture settings to be a certain way or
30 // they won't report FRAMEBUFFER_COMPLETE.
31 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
32 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
33 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
34 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
36 glGenFramebuffers(1, &framebuffer_id_);
37 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
38 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
42 virtual void TearDown() {
43 glDeleteTextures(2, textures_);
44 glDeleteFramebuffers(1, &framebuffer_id_);
50 GLuint framebuffer_id_;
53 // Test to ensure that the basic functionality of the extension works.
54 TEST_F(GLCopyTextureCHROMIUMTest, Basic) {
55 uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
57 glBindTexture(GL_TEXTURE_2D, textures_[0]);
58 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
61 glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
63 EXPECT_TRUE(glGetError() == GL_NO_ERROR);
65 // Check the FB is still bound.
67 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
69 EXPECT_EQ(framebuffer_id_, fb_id);
71 // Check that FB is complete.
72 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
73 glCheckFramebufferStatus(GL_FRAMEBUFFER));
75 GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels);
76 EXPECT_TRUE(GL_NO_ERROR == glGetError());
79 // Test that the extension respects the flip-y pixel storage setting.
80 TEST_F(GLCopyTextureCHROMIUMTest, FlipY) {
81 uint8 pixels[2][2][4];
82 for (int x = 0; x < 2; ++x) {
83 for (int y = 0; y < 2; ++y) {
84 pixels[y][x][0] = x + y;
85 pixels[y][x][1] = x + y;
86 pixels[y][x][2] = x + y;
87 pixels[y][x][3] = 255u;
91 glBindTexture(GL_TEXTURE_2D, textures_[0]);
92 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
95 glPixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
96 glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
98 EXPECT_TRUE(GL_NO_ERROR == glGetError());
100 uint8 copied_pixels[2][2][4] = {{{0}}};
101 glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels);
102 for (int x = 0; x < 2; ++x) {
103 for (int y = 0; y < 2; ++y) {
104 EXPECT_EQ(pixels[1-y][x][0], copied_pixels[y][x][0]);
105 EXPECT_EQ(pixels[1-y][x][1], copied_pixels[y][x][1]);
106 EXPECT_EQ(pixels[1-y][x][2], copied_pixels[y][x][2]);
107 EXPECT_EQ(pixels[1-y][x][3], copied_pixels[y][x][3]);
111 EXPECT_TRUE(GL_NO_ERROR == glGetError());
114 // Test that the extension respects the GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM
116 TEST_F(GLCopyTextureCHROMIUMTest, PremultiplyAlpha) {
117 uint8 pixels[1 * 4] = { 2, 2, 2, 128 };
119 glBindTexture(GL_TEXTURE_2D, textures_[0]);
120 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
123 glPixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
124 glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
126 EXPECT_TRUE(GL_NO_ERROR == glGetError());
128 uint8 copied_pixels[1 * 4] = {0};
129 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels);
130 EXPECT_EQ(1u, copied_pixels[0]);
131 EXPECT_EQ(1u, copied_pixels[1]);
132 EXPECT_EQ(1u, copied_pixels[2]);
133 EXPECT_EQ(128u, copied_pixels[3]);
135 EXPECT_TRUE(GL_NO_ERROR == glGetError());
138 // Test that the extension respects the GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM
140 TEST_F(GLCopyTextureCHROMIUMTest, UnpremultiplyAlpha) {
141 uint8 pixels[1 * 4] = { 16, 16, 16, 128 };
143 glBindTexture(GL_TEXTURE_2D, textures_[0]);
144 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
147 glPixelStorei(GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
148 glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
150 EXPECT_TRUE(GL_NO_ERROR == glGetError());
152 uint8 copied_pixels[1 * 4] = {0};
153 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels);
154 EXPECT_EQ(32u, copied_pixels[0]);
155 EXPECT_EQ(32u, copied_pixels[1]);
156 EXPECT_EQ(32u, copied_pixels[2]);
157 EXPECT_EQ(128u, copied_pixels[3]);
159 EXPECT_TRUE(GL_NO_ERROR == glGetError());
162 TEST_F(GLCopyTextureCHROMIUMTest, FlipYAndPremultiplyAlpha) {
163 uint8 pixels[2][2][4];
164 for (int x = 0; x < 2; ++x) {
165 for (int y = 0; y < 2; ++y) {
166 uint8 color = 16 * x + 16 * y;
167 pixels[y][x][0] = color;
168 pixels[y][x][1] = color;
169 pixels[y][x][2] = color;
170 pixels[y][x][3] = 128u;
174 glBindTexture(GL_TEXTURE_2D, textures_[0]);
175 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
178 glPixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
179 glPixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
180 glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
182 EXPECT_TRUE(GL_NO_ERROR == glGetError());
184 uint8 copied_pixels[2][2][4] = {{{0}}};
185 glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels);
186 for (int x = 0; x < 2; ++x) {
187 for (int y = 0; y < 2; ++y) {
188 EXPECT_EQ(pixels[1-y][x][0] / 2, copied_pixels[y][x][0]);
189 EXPECT_EQ(pixels[1-y][x][1] / 2, copied_pixels[y][x][1]);
190 EXPECT_EQ(pixels[1-y][x][2] / 2, copied_pixels[y][x][2]);
191 EXPECT_EQ(pixels[1-y][x][3], copied_pixels[y][x][3]);
195 EXPECT_TRUE(GL_NO_ERROR == glGetError());
198 TEST_F(GLCopyTextureCHROMIUMTest, FlipYAndUnpremultiplyAlpha) {
199 uint8 pixels[2][2][4];
200 for (int x = 0; x < 2; ++x) {
201 for (int y = 0; y < 2; ++y) {
202 uint8 color = 16 * x + 16 * y;
203 pixels[y][x][0] = color;
204 pixels[y][x][1] = color;
205 pixels[y][x][2] = color;
206 pixels[y][x][3] = 128u;
210 glBindTexture(GL_TEXTURE_2D, textures_[0]);
211 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
214 glPixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
215 glPixelStorei(GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
216 glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
218 EXPECT_TRUE(GL_NO_ERROR == glGetError());
220 uint8 copied_pixels[2][2][4] = {{{0}}};
221 glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels);
222 for (int x = 0; x < 2; ++x) {
223 for (int y = 0; y < 2; ++y) {
224 EXPECT_EQ(pixels[1-y][x][0] * 2, copied_pixels[y][x][0]);
225 EXPECT_EQ(pixels[1-y][x][1] * 2, copied_pixels[y][x][1]);
226 EXPECT_EQ(pixels[1-y][x][2] * 2, copied_pixels[y][x][2]);
227 EXPECT_EQ(pixels[1-y][x][3], copied_pixels[y][x][3]);
231 EXPECT_TRUE(GL_NO_ERROR == glGetError());
236 void glEnableDisable(GLint param, GLboolean value) {
243 } // unnamed namespace
245 // Validate that some basic GL state is not touched upon execution of
247 TEST_F(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
248 uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
250 glBindFramebuffer(GL_FRAMEBUFFER, 0);
252 glBindTexture(GL_TEXTURE_2D, textures_[0]);
253 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
256 GLboolean reference_settings[2] = { GL_TRUE, GL_FALSE };
257 for (int x = 0; x < 2; ++x) {
258 GLboolean setting = reference_settings[x];
259 glEnableDisable(GL_DEPTH_TEST, setting);
260 glEnableDisable(GL_SCISSOR_TEST, setting);
261 glEnableDisable(GL_STENCIL_TEST, setting);
262 glEnableDisable(GL_CULL_FACE, setting);
263 glEnableDisable(GL_BLEND, setting);
264 glColorMask(setting, setting, setting, setting);
265 glDepthMask(setting);
267 glActiveTexture(GL_TEXTURE1 + x);
269 glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
270 GL_RGBA, GL_UNSIGNED_BYTE);
271 EXPECT_TRUE(GL_NO_ERROR == glGetError());
273 EXPECT_EQ(setting, glIsEnabled(GL_DEPTH_TEST));
274 EXPECT_EQ(setting, glIsEnabled(GL_SCISSOR_TEST));
275 EXPECT_EQ(setting, glIsEnabled(GL_STENCIL_TEST));
276 EXPECT_EQ(setting, glIsEnabled(GL_CULL_FACE));
277 EXPECT_EQ(setting, glIsEnabled(GL_BLEND));
279 GLboolean bool_array[4] = { GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE };
280 glGetBooleanv(GL_DEPTH_WRITEMASK, bool_array);
281 EXPECT_EQ(setting, bool_array[0]);
283 bool_array[0] = GL_FALSE;
284 glGetBooleanv(GL_COLOR_WRITEMASK, bool_array);
285 EXPECT_EQ(setting, bool_array[0]);
286 EXPECT_EQ(setting, bool_array[1]);
287 EXPECT_EQ(setting, bool_array[2]);
288 EXPECT_EQ(setting, bool_array[3]);
290 GLint active_texture = 0;
291 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
292 EXPECT_EQ(GL_TEXTURE1 + x, active_texture);
295 EXPECT_TRUE(GL_NO_ERROR == glGetError());
298 // Verify that invocation of the extension does not modify the bound
300 TEST_F(GLCopyTextureCHROMIUMTest, TextureStatePreserved) {
301 // Setup the texture used for the extension invocation.
302 uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
303 glBindTexture(GL_TEXTURE_2D, textures_[0]);
304 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
307 GLuint texture_ids[2];
308 glGenTextures(2, texture_ids);
310 glActiveTexture(GL_TEXTURE0);
311 glBindTexture(GL_TEXTURE_2D, texture_ids[0]);
313 glActiveTexture(GL_TEXTURE1);
314 glBindTexture(GL_TEXTURE_2D, texture_ids[1]);
316 glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
317 GL_RGBA, GL_UNSIGNED_BYTE);
318 EXPECT_TRUE(GL_NO_ERROR == glGetError());
320 GLint active_texture = 0;
321 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
322 EXPECT_EQ(GL_TEXTURE1, active_texture);
324 GLint bound_texture = 0;
325 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
326 EXPECT_EQ(texture_ids[1], static_cast<GLuint>(bound_texture));
327 glBindTexture(GL_TEXTURE_2D, 0);
330 glActiveTexture(GL_TEXTURE0);
331 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
332 EXPECT_EQ(texture_ids[0], static_cast<GLuint>(bound_texture));
333 glBindTexture(GL_TEXTURE_2D, 0);
335 glDeleteTextures(2, texture_ids);
337 EXPECT_TRUE(GL_NO_ERROR == glGetError());
340 // Verify that invocation of the extension does not perturb the currently
342 TEST_F(GLCopyTextureCHROMIUMTest, FBOStatePreserved) {
343 // Setup the texture used for the extension invocation.
344 uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
345 glBindTexture(GL_TEXTURE_2D, textures_[0]);
346 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
350 glGenTextures(1, &texture_id);
351 glBindTexture(GL_TEXTURE_2D, texture_id);
352 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
355 GLuint renderbuffer_id;
356 glGenRenderbuffers(1, &renderbuffer_id);
357 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_id);
358 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 1, 1);
360 GLuint framebuffer_id;
361 glGenFramebuffers(1, &framebuffer_id);
362 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id);
363 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
365 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
366 GL_RENDERBUFFER, renderbuffer_id);
368 GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER));
370 // Test that we can write to the bound framebuffer
371 uint8 expected_color[4] = { 255u, 255u, 0, 255u };
372 glClearColor(1.0, 1.0, 0, 1.0);
373 glClear(GL_COLOR_BUFFER_BIT);
374 GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color);
376 glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
377 GL_RGBA, GL_UNSIGNED_BYTE);
378 EXPECT_TRUE(GL_NO_ERROR == glGetError());
380 EXPECT_TRUE(glIsFramebuffer(framebuffer_id));
382 // Ensure that reading from the framebuffer produces correct pixels.
383 GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color);
385 uint8 expected_color2[4] = { 255u, 0, 255u, 255u };
386 glClearColor(1.0, 0, 1.0, 1.0);
387 glClear(GL_COLOR_BUFFER_BIT);
388 GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color2);
391 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
392 EXPECT_EQ(framebuffer_id, static_cast<GLuint>(bound_fbo));
394 GLint fbo_params = 0;
395 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
396 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
398 EXPECT_EQ(GL_TEXTURE, fbo_params);
401 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
402 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
404 EXPECT_EQ(texture_id, static_cast<GLuint>(fbo_params));
407 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
408 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
410 EXPECT_EQ(GL_RENDERBUFFER, fbo_params);
413 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
414 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
416 EXPECT_EQ(renderbuffer_id, static_cast<GLuint>(fbo_params));
418 glDeleteRenderbuffers(1, &renderbuffer_id);
419 glDeleteTextures(1, &texture_id);
420 glDeleteFramebuffers(1, &framebuffer_id);
422 EXPECT_TRUE(GL_NO_ERROR == glGetError());
425 TEST_F(GLCopyTextureCHROMIUMTest, ProgramStatePreservation) {
426 // unbind the one created in setup.
427 glBindFramebuffer(GL_FRAMEBUFFER, 0);
428 glBindTexture(GL_TEXTURE_2D, 0);
431 GLManager::Options options;
432 options.size = gfx::Size(16, 16);
433 options.share_group_manager = &gl_;
434 gl2.Initialize(options);
437 static const char* v_shader_str =
438 "attribute vec4 g_Position;\n"
441 " gl_Position = g_Position;\n"
443 static const char* f_shader_str =
444 "precision mediump float;\n"
447 " gl_FragColor = vec4(0,1,0,1);\n"
450 GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
451 glUseProgram(program);
452 GLuint position_loc = glGetAttribLocation(program, "g_Position");
455 // Delete program from other context.
457 glDeleteProgram(program);
458 EXPECT_TRUE(GL_NO_ERROR == glGetError());
461 // Program should still be usable on this context.
464 GLTestHelper::SetupUnitQuad(position_loc);
466 // test using program before
467 uint8 expected[] = { 0, 255, 0, 255, };
468 uint8 zero[] = { 0, 0, 0, 0, };
469 glClear(GL_COLOR_BUFFER_BIT);
470 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero));
471 glDrawArrays(GL_TRIANGLES, 0, 6);
472 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected));
474 // Call copyTextureCHROMIUM
475 uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
476 glBindTexture(GL_TEXTURE_2D, textures_[0]);
477 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
479 glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
482 // test using program after
483 glClear(GL_COLOR_BUFFER_BIT);
484 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero));
485 glDrawArrays(GL_TRIANGLES, 0, 6);
486 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected));
488 EXPECT_TRUE(GL_NO_ERROR == glGetError());
495 // Test that glCopyTextureCHROMIUM doesn't leak uninitialized textures.
496 TEST_F(GLCopyTextureCHROMIUMTest, UninitializedSource) {
497 const GLsizei kWidth = 64, kHeight = 64;
498 glBindTexture(GL_TEXTURE_2D, textures_[0]);
499 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight,
500 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
502 glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
504 EXPECT_TRUE(GL_NO_ERROR == glGetError());
506 uint8 pixels[kHeight][kWidth][4] = {{{1}}};
507 glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
508 for (int x = 0; x < kWidth; ++x) {
509 for (int y = 0; y < kHeight; ++y) {
510 EXPECT_EQ(0, pixels[y][x][0]);
511 EXPECT_EQ(0, pixels[y][x][1]);
512 EXPECT_EQ(0, pixels[y][x][2]);
513 EXPECT_EQ(0, pixels[y][x][3]);
517 EXPECT_TRUE(GL_NO_ERROR == glGetError());