Home | History | Annotate | Download | only in tests
      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.
      4 
      5 #ifndef GL_GLEXT_PROTOTYPES
      6 #define GL_GLEXT_PROTOTYPES
      7 #endif
      8 
      9 #include <GLES2/gl2.h>
     10 #include <GLES2/gl2ext.h>
     11 #include <GLES2/gl2extchromium.h>
     12 
     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"
     17 
     18 namespace gpu {
     19 
     20 // A collection of tests that exercise the GL_CHROMIUM_copy_texture extension.
     21 class GLCopyTextureCHROMIUMTest : public testing::Test {
     22  protected:
     23   virtual void SetUp() {
     24     gl_.Initialize(GLManager::Options());
     25 
     26     glGenTextures(2, textures_);
     27     glBindTexture(GL_TEXTURE_2D, textures_[1]);
     28 
     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);
     35 
     36     glGenFramebuffers(1, &framebuffer_id_);
     37     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
     38     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
     39                            textures_[1], 0);
     40   }
     41 
     42   virtual void TearDown() {
     43     glDeleteTextures(2, textures_);
     44     glDeleteFramebuffers(1, &framebuffer_id_);
     45     gl_.Destroy();
     46   }
     47 
     48   GLManager gl_;
     49   GLuint textures_[2];
     50   GLuint framebuffer_id_;
     51 };
     52 
     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 };
     56 
     57   glBindTexture(GL_TEXTURE_2D, textures_[0]);
     58   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
     59                pixels);
     60 
     61   glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
     62                         GL_UNSIGNED_BYTE);
     63   EXPECT_TRUE(glGetError() == GL_NO_ERROR);
     64 
     65   // Check the FB is still bound.
     66   GLint value = 0;
     67   glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
     68   GLuint fb_id = value;
     69   EXPECT_EQ(framebuffer_id_, fb_id);
     70 
     71   // Check that FB is complete.
     72   EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
     73             glCheckFramebufferStatus(GL_FRAMEBUFFER));
     74 
     75   GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels);
     76   EXPECT_TRUE(GL_NO_ERROR == glGetError());
     77 }
     78 
     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;
     88     }
     89   }
     90 
     91   glBindTexture(GL_TEXTURE_2D, textures_[0]);
     92   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
     93                pixels);
     94 
     95   glPixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
     96   glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
     97                         GL_UNSIGNED_BYTE);
     98   EXPECT_TRUE(GL_NO_ERROR == glGetError());
     99 
    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]);
    108     }
    109   }
    110 
    111   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    112 }
    113 
    114 // Test that the extension respects the GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM
    115 // storage setting.
    116 TEST_F(GLCopyTextureCHROMIUMTest, PremultiplyAlpha) {
    117   uint8 pixels[1 * 4] = { 2, 2, 2, 128 };
    118 
    119   glBindTexture(GL_TEXTURE_2D, textures_[0]);
    120   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
    121                pixels);
    122 
    123   glPixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
    124   glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
    125                        GL_UNSIGNED_BYTE);
    126   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    127 
    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]);
    134 
    135   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    136 }
    137 
    138 // Test that the extension respects the GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM
    139 // storage setting.
    140 TEST_F(GLCopyTextureCHROMIUMTest, UnpremultiplyAlpha) {
    141   uint8 pixels[1 * 4] = { 16, 16, 16, 128 };
    142 
    143   glBindTexture(GL_TEXTURE_2D, textures_[0]);
    144   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
    145                pixels);
    146 
    147   glPixelStorei(GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
    148   glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
    149                         GL_UNSIGNED_BYTE);
    150   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    151 
    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]);
    158 
    159   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    160 }
    161 
    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;
    171     }
    172   }
    173 
    174   glBindTexture(GL_TEXTURE_2D, textures_[0]);
    175   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
    176                pixels);
    177 
    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,
    181                         GL_UNSIGNED_BYTE);
    182   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    183 
    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]);
    192     }
    193   }
    194 
    195   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    196 }
    197 
    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;
    207     }
    208   }
    209 
    210   glBindTexture(GL_TEXTURE_2D, textures_[0]);
    211   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
    212                pixels);
    213 
    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,
    217                         GL_UNSIGNED_BYTE);
    218   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    219 
    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]);
    228     }
    229   }
    230 
    231   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    232 }
    233 
    234 namespace {
    235 
    236 void glEnableDisable(GLint param, GLboolean value) {
    237   if (value)
    238     glEnable(param);
    239   else
    240     glDisable(param);
    241 }
    242 
    243 }  // unnamed namespace
    244 
    245 // Validate that some basic GL state is not touched upon execution of
    246 // the extension.
    247 TEST_F(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
    248   uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
    249 
    250   glBindFramebuffer(GL_FRAMEBUFFER, 0);
    251 
    252   glBindTexture(GL_TEXTURE_2D, textures_[0]);
    253   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
    254                pixels);
    255 
    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);
    266 
    267     glActiveTexture(GL_TEXTURE1 + x);
    268 
    269     glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
    270                           GL_RGBA, GL_UNSIGNED_BYTE);
    271     EXPECT_TRUE(GL_NO_ERROR == glGetError());
    272 
    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));
    278 
    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]);
    282 
    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]);
    289 
    290     GLint active_texture = 0;
    291     glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
    292     EXPECT_EQ(GL_TEXTURE1 + x, active_texture);
    293   }
    294 
    295   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    296 };
    297 
    298 // Verify that invocation of the extension does not modify the bound
    299 // texture state.
    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,
    305                pixels);
    306 
    307   GLuint texture_ids[2];
    308   glGenTextures(2, texture_ids);
    309 
    310   glActiveTexture(GL_TEXTURE0);
    311   glBindTexture(GL_TEXTURE_2D, texture_ids[0]);
    312 
    313   glActiveTexture(GL_TEXTURE1);
    314   glBindTexture(GL_TEXTURE_2D, texture_ids[1]);
    315 
    316   glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
    317                         GL_RGBA, GL_UNSIGNED_BYTE);
    318   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    319 
    320   GLint active_texture = 0;
    321   glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
    322   EXPECT_EQ(GL_TEXTURE1, active_texture);
    323 
    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);
    328 
    329   bound_texture = 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);
    334 
    335   glDeleteTextures(2, texture_ids);
    336 
    337   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    338 }
    339 
    340 // Verify that invocation of the extension does not perturb the currently
    341 // bound FBO state.
    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,
    347                pixels);
    348 
    349   GLuint texture_id;
    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,
    353                0);
    354 
    355   GLuint renderbuffer_id;
    356   glGenRenderbuffers(1, &renderbuffer_id);
    357   glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_id);
    358   glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 1, 1);
    359 
    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,
    364                          texture_id, 0);
    365   glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
    366                             GL_RENDERBUFFER, renderbuffer_id);
    367   EXPECT_TRUE(
    368       GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER));
    369 
    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);
    375 
    376   glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
    377                         GL_RGBA, GL_UNSIGNED_BYTE);
    378   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    379 
    380   EXPECT_TRUE(glIsFramebuffer(framebuffer_id));
    381 
    382   // Ensure that reading from the framebuffer produces correct pixels.
    383   GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color);
    384 
    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);
    389 
    390   GLint bound_fbo = 0;
    391   glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
    392   EXPECT_EQ(framebuffer_id, static_cast<GLuint>(bound_fbo));
    393 
    394   GLint fbo_params = 0;
    395   glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
    396                                         GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
    397                                         &fbo_params);
    398   EXPECT_EQ(GL_TEXTURE, fbo_params);
    399 
    400   fbo_params = 0;
    401   glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
    402                                         GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
    403                                         &fbo_params);
    404   EXPECT_EQ(texture_id, static_cast<GLuint>(fbo_params));
    405 
    406   fbo_params = 0;
    407   glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
    408                                         GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
    409                                         &fbo_params);
    410   EXPECT_EQ(GL_RENDERBUFFER, fbo_params);
    411 
    412   fbo_params = 0;
    413   glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
    414                                         GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
    415                                         &fbo_params);
    416   EXPECT_EQ(renderbuffer_id, static_cast<GLuint>(fbo_params));
    417 
    418   glDeleteRenderbuffers(1, &renderbuffer_id);
    419   glDeleteTextures(1, &texture_id);
    420   glDeleteFramebuffers(1, &framebuffer_id);
    421 
    422   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    423 }
    424 
    425 TEST_F(GLCopyTextureCHROMIUMTest, ProgramStatePreservation) {
    426   // unbind the one created in setup.
    427   glBindFramebuffer(GL_FRAMEBUFFER, 0);
    428   glBindTexture(GL_TEXTURE_2D, 0);
    429 
    430   GLManager gl2;
    431   GLManager::Options options;
    432   options.size = gfx::Size(16, 16);
    433   options.share_group_manager = &gl_;
    434   gl2.Initialize(options);
    435   gl_.MakeCurrent();
    436 
    437   static const char* v_shader_str =
    438       "attribute vec4 g_Position;\n"
    439       "void main()\n"
    440       "{\n"
    441       "   gl_Position = g_Position;\n"
    442       "}\n";
    443   static const char* f_shader_str =
    444       "precision mediump float;\n"
    445       "void main()\n"
    446       "{\n"
    447       "  gl_FragColor = vec4(0,1,0,1);\n"
    448       "}\n";
    449 
    450   GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
    451   glUseProgram(program);
    452   GLuint position_loc = glGetAttribLocation(program, "g_Position");
    453   glFlush();
    454 
    455   // Delete program from other context.
    456   gl2.MakeCurrent();
    457   glDeleteProgram(program);
    458   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    459   glFlush();
    460 
    461   // Program should still be usable on this context.
    462   gl_.MakeCurrent();
    463 
    464   GLTestHelper::SetupUnitQuad(position_loc);
    465 
    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));
    473 
    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,
    478                pixels);
    479   glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
    480                         GL_UNSIGNED_BYTE);
    481 
    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));
    487 
    488   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    489 
    490   gl2.MakeCurrent();
    491   gl2.Destroy();
    492   gl_.MakeCurrent();
    493 }
    494 
    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);
    501 
    502   glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
    503                         GL_UNSIGNED_BYTE);
    504   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    505 
    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]);
    514     }
    515   }
    516 
    517   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    518 }
    519 
    520 }  // namespace gpu
    521