Home | History | Annotate | Download | only in tests
      1 // Copyright 2014 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 #include <GLES2/gl2.h>
      6 #include <GLES2/gl2ext.h>
      7 #include <GLES2/gl2extchromium.h>
      8 
      9 #include "gpu/command_buffer/client/gles2_lib.h"
     10 #include "gpu/command_buffer/common/mailbox.h"
     11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
     12 #include "gpu/command_buffer/service/mailbox_manager.h"
     13 #include "gpu/command_buffer/tests/gl_manager.h"
     14 #include "testing/gmock/include/gmock/gmock.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 #include "ui/gl/gl_share_group.h"
     17 
     18 namespace gpu {
     19 
     20 namespace {
     21 uint32 ReadTexel(GLuint id, GLint x, GLint y) {
     22   GLint old_fbo = 0;
     23   glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_fbo);
     24 
     25   GLuint fbo;
     26   glGenFramebuffers(1, &fbo);
     27   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
     28   glFramebufferTexture2D(GL_FRAMEBUFFER,
     29                          GL_COLOR_ATTACHMENT0,
     30                          GL_TEXTURE_2D,
     31                          id,
     32                          0);
     33   // Some drivers (NVidia/SGX) require texture settings to be a certain way or
     34   // they won't report FRAMEBUFFER_COMPLETE.
     35   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     36   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     37   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     38   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     39 
     40   EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
     41             glCheckFramebufferStatus(GL_FRAMEBUFFER));
     42 
     43   uint32 texel = 0;
     44   glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &texel);
     45   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
     46 
     47   glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
     48 
     49   glDeleteFramebuffers(1, &fbo);
     50 
     51   return texel;
     52 }
     53 }
     54 
     55 class GLTextureMailboxTest : public testing::Test {
     56  protected:
     57   virtual void SetUp() {
     58     gl1_.Initialize(GLManager::Options());
     59     GLManager::Options options;
     60     options.share_mailbox_manager = &gl1_;
     61     gl2_.Initialize(options);
     62   }
     63 
     64   virtual void TearDown() {
     65     gl1_.Destroy();
     66     gl2_.Destroy();
     67   }
     68 
     69   GLManager gl1_;
     70   GLManager gl2_;
     71 };
     72 
     73 TEST_F(GLTextureMailboxTest, ProduceAndConsumeTexture) {
     74   gl1_.MakeCurrent();
     75 
     76   GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
     77   glGenMailboxCHROMIUM(mailbox1);
     78 
     79   GLbyte mailbox2[GL_MAILBOX_SIZE_CHROMIUM];
     80   glGenMailboxCHROMIUM(mailbox2);
     81 
     82   GLuint tex1;
     83   glGenTextures(1, &tex1);
     84 
     85   glBindTexture(GL_TEXTURE_2D, tex1);
     86   uint32 source_pixel = 0xFF0000FF;
     87   glTexImage2D(GL_TEXTURE_2D,
     88                0,
     89                GL_RGBA,
     90                1, 1,
     91                0,
     92                GL_RGBA,
     93                GL_UNSIGNED_BYTE,
     94                &source_pixel);
     95 
     96   glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
     97   glFlush();
     98 
     99   gl2_.MakeCurrent();
    100 
    101   GLuint tex2;
    102   glGenTextures(1, &tex2);
    103 
    104   glBindTexture(GL_TEXTURE_2D, tex2);
    105   glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
    106   EXPECT_EQ(source_pixel, ReadTexel(tex2, 0, 0));
    107   glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
    108   glFlush();
    109 
    110   gl1_.MakeCurrent();
    111 
    112   glBindTexture(GL_TEXTURE_2D, tex1);
    113   glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
    114   EXPECT_EQ(source_pixel, ReadTexel(tex1, 0, 0));
    115 }
    116 
    117 TEST_F(GLTextureMailboxTest, ProduceAndConsumeTextureRGB) {
    118   gl1_.MakeCurrent();
    119 
    120   GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
    121   glGenMailboxCHROMIUM(mailbox1);
    122 
    123   GLbyte mailbox2[GL_MAILBOX_SIZE_CHROMIUM];
    124   glGenMailboxCHROMIUM(mailbox2);
    125 
    126   GLuint tex1;
    127   glGenTextures(1, &tex1);
    128 
    129   glBindTexture(GL_TEXTURE_2D, tex1);
    130   uint32 source_pixel = 0xFF000000;
    131   glTexImage2D(GL_TEXTURE_2D,
    132                0,
    133                GL_RGB,
    134                1, 1,
    135                0,
    136                GL_RGB,
    137                GL_UNSIGNED_BYTE,
    138                &source_pixel);
    139 
    140   glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
    141   glFlush();
    142 
    143   gl2_.MakeCurrent();
    144 
    145   GLuint tex2;
    146   glGenTextures(1, &tex2);
    147 
    148   glBindTexture(GL_TEXTURE_2D, tex2);
    149   glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
    150   EXPECT_EQ(source_pixel, ReadTexel(tex2, 0, 0));
    151   glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
    152   glFlush();
    153 
    154   gl1_.MakeCurrent();
    155 
    156   glBindTexture(GL_TEXTURE_2D, tex1);
    157   glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
    158   EXPECT_EQ(source_pixel, ReadTexel(tex1, 0, 0));
    159 }
    160 
    161 TEST_F(GLTextureMailboxTest, ProduceAndConsumeTextureDirect) {
    162   gl1_.MakeCurrent();
    163 
    164   GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
    165   glGenMailboxCHROMIUM(mailbox1);
    166 
    167   GLbyte mailbox2[GL_MAILBOX_SIZE_CHROMIUM];
    168   glGenMailboxCHROMIUM(mailbox2);
    169 
    170   GLuint tex1;
    171   glGenTextures(1, &tex1);
    172 
    173   glBindTexture(GL_TEXTURE_2D, tex1);
    174   uint32 source_pixel = 0xFF0000FF;
    175   glTexImage2D(GL_TEXTURE_2D,
    176                0,
    177                GL_RGBA,
    178                1, 1,
    179                0,
    180                GL_RGBA,
    181                GL_UNSIGNED_BYTE,
    182                &source_pixel);
    183 
    184   glProduceTextureDirectCHROMIUM(tex1, GL_TEXTURE_2D, mailbox1);
    185   glFlush();
    186 
    187   gl2_.MakeCurrent();
    188 
    189   GLuint tex2 = glCreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
    190   glBindTexture(GL_TEXTURE_2D, tex2);
    191   EXPECT_EQ(source_pixel, ReadTexel(tex2, 0, 0));
    192   glProduceTextureDirectCHROMIUM(tex2, GL_TEXTURE_2D, mailbox2);
    193   glFlush();
    194 
    195   gl1_.MakeCurrent();
    196 
    197   GLuint tex3 = glCreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
    198   glBindTexture(GL_TEXTURE_2D, tex3);
    199   EXPECT_EQ(source_pixel, ReadTexel(tex3, 0, 0));
    200 }
    201 
    202 TEST_F(GLTextureMailboxTest, ConsumeTextureValidatesKey) {
    203   GLuint tex;
    204   glGenTextures(1, &tex);
    205 
    206   glBindTexture(GL_TEXTURE_2D, tex);
    207   uint32 source_pixel = 0xFF0000FF;
    208   glTexImage2D(GL_TEXTURE_2D,
    209                0,
    210                GL_RGBA,
    211                1, 1,
    212                0,
    213                GL_RGBA,
    214                GL_UNSIGNED_BYTE,
    215                &source_pixel);
    216 
    217   GLbyte invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM];
    218   glGenMailboxCHROMIUM(invalid_mailbox);
    219 
    220   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    221   glConsumeTextureCHROMIUM(GL_TEXTURE_2D, invalid_mailbox);
    222   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
    223 
    224   // Ensure level 0 is still intact after glConsumeTextureCHROMIUM fails.
    225   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    226   EXPECT_EQ(source_pixel, ReadTexel(tex, 0, 0));
    227   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    228 }
    229 
    230 TEST_F(GLTextureMailboxTest, SharedTextures) {
    231   gl1_.MakeCurrent();
    232   GLuint tex1;
    233   glGenTextures(1, &tex1);
    234 
    235   glBindTexture(GL_TEXTURE_2D, tex1);
    236   uint32 source_pixel = 0xFF0000FF;
    237   glTexImage2D(GL_TEXTURE_2D,
    238                0,
    239                GL_RGBA,
    240                1, 1,
    241                0,
    242                GL_RGBA,
    243                GL_UNSIGNED_BYTE,
    244                &source_pixel);
    245   GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
    246   glGenMailboxCHROMIUM(mailbox);
    247 
    248   glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
    249   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    250   glFlush();
    251 
    252   gl2_.MakeCurrent();
    253   GLuint tex2;
    254   glGenTextures(1, &tex2);
    255 
    256   glBindTexture(GL_TEXTURE_2D, tex2);
    257   glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
    258   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    259 
    260   // Change texture in context 2.
    261   source_pixel = 0xFF00FF00;
    262   glTexSubImage2D(GL_TEXTURE_2D,
    263                   0,
    264                   0, 0,
    265                   1, 1,
    266                   GL_RGBA,
    267                   GL_UNSIGNED_BYTE,
    268                   &source_pixel);
    269   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    270   glFlush();
    271 
    272   // Check it in context 1.
    273   gl1_.MakeCurrent();
    274   EXPECT_EQ(source_pixel, ReadTexel(tex1, 0, 0));
    275   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    276 
    277   // Change parameters (note: ReadTexel will reset those).
    278   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    279   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    280   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
    281                   GL_LINEAR_MIPMAP_NEAREST);
    282   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    283   glFlush();
    284 
    285   // Check in context 2.
    286   gl2_.MakeCurrent();
    287   GLint parameter = 0;
    288   glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, &parameter);
    289   EXPECT_EQ(GL_REPEAT, parameter);
    290   parameter = 0;
    291   glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &parameter);
    292   EXPECT_EQ(GL_LINEAR, parameter);
    293   parameter = 0;
    294   glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &parameter);
    295   EXPECT_EQ(GL_LINEAR_MIPMAP_NEAREST, parameter);
    296 
    297   // Delete texture in context 1.
    298   gl1_.MakeCurrent();
    299   glDeleteTextures(1, &tex1);
    300   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    301 
    302   // Check texture still exists in context 2.
    303   gl2_.MakeCurrent();
    304   EXPECT_EQ(source_pixel, ReadTexel(tex2, 0, 0));
    305   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    306 
    307   // The mailbox should still exist too.
    308   GLuint tex3;
    309   glGenTextures(1, &tex3);
    310   glBindTexture(GL_TEXTURE_2D, tex3);
    311   glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
    312   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    313 
    314   // Delete both textures.
    315   glDeleteTextures(1, &tex2);
    316   glDeleteTextures(1, &tex3);
    317   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    318 
    319   // Mailbox should be gone now.
    320   glGenTextures(1, &tex2);
    321   glBindTexture(GL_TEXTURE_2D, tex2);
    322   glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
    323   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
    324   glDeleteTextures(1, &tex2);
    325   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    326 }
    327 
    328 TEST_F(GLTextureMailboxTest, ProduceFrontBuffer) {
    329   gl1_.MakeCurrent();
    330   Mailbox mailbox;
    331   glGenMailboxCHROMIUM(mailbox.name);
    332 
    333   gl2_.MakeCurrent();
    334   gl2_.decoder()->ProduceFrontBuffer(mailbox);
    335 
    336   gl1_.MakeCurrent();
    337   GLuint tex1;
    338   glGenTextures(1, &tex1);
    339   glBindTexture(GL_TEXTURE_2D, tex1);
    340   glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
    341   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    342 
    343   gl2_.MakeCurrent();
    344   glResizeCHROMIUM(10, 10, 1);
    345   glClearColor(1, 0, 0, 1);
    346   glClear(GL_COLOR_BUFFER_BIT);
    347   ::gles2::GetGLContext()->SwapBuffers();
    348 
    349   gl1_.MakeCurrent();
    350   EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 0, 0));
    351   EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 9, 9));
    352   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    353 
    354   gl2_.MakeCurrent();
    355   glClearColor(0, 1, 0, 1);
    356   glClear(GL_COLOR_BUFFER_BIT);
    357   glFlush();
    358 
    359   gl1_.MakeCurrent();
    360   EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 0, 0));
    361 
    362   gl2_.MakeCurrent();
    363   ::gles2::GetGLContext()->SwapBuffers();
    364 
    365   gl1_.MakeCurrent();
    366   EXPECT_EQ(0xFF00FF00u, ReadTexel(tex1, 0, 0));
    367 
    368   gl2_.MakeCurrent();
    369   gl2_.Destroy();
    370 
    371   gl1_.MakeCurrent();
    372   EXPECT_EQ(0xFF00FF00u, ReadTexel(tex1, 0, 0));
    373   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    374   glDeleteTextures(1, &tex1);
    375 }
    376 
    377 TEST_F(GLTextureMailboxTest, ProduceTextureDirectInvalidTarget) {
    378   gl1_.MakeCurrent();
    379 
    380   GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
    381   glGenMailboxCHROMIUM(mailbox1);
    382 
    383   GLuint tex1;
    384   glGenTextures(1, &tex1);
    385 
    386   glBindTexture(GL_TEXTURE_CUBE_MAP, tex1);
    387   uint32 source_pixel = 0xFF0000FF;
    388   glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X,
    389                0,
    390                GL_RGBA,
    391                1, 1,
    392                0,
    393                GL_RGBA,
    394                GL_UNSIGNED_BYTE,
    395                &source_pixel);
    396 
    397   glProduceTextureDirectCHROMIUM(tex1, GL_TEXTURE_2D, mailbox1);
    398   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
    399 }
    400 
    401 // http://crbug.com/281565
    402 #if !defined(OS_ANDROID)
    403 TEST_F(GLTextureMailboxTest, ProduceFrontBufferMultipleContexts) {
    404   gl1_.MakeCurrent();
    405   Mailbox mailbox[2];
    406   glGenMailboxCHROMIUM(mailbox[0].name);
    407   glGenMailboxCHROMIUM(mailbox[1].name);
    408   GLuint tex[2];
    409   glGenTextures(2, tex);
    410 
    411   GLManager::Options options;
    412   options.share_mailbox_manager = &gl1_;
    413   GLManager other_gl[2];
    414   for (size_t i = 0; i < 2; ++i) {
    415     other_gl[i].Initialize(options);
    416     other_gl[i].MakeCurrent();
    417     other_gl[i].decoder()->ProduceFrontBuffer(mailbox[i]);
    418     // Make sure both "other gl" are in the same share group.
    419     if (!options.share_group_manager)
    420       options.share_group_manager = other_gl+i;
    421   }
    422 
    423 
    424   gl1_.MakeCurrent();
    425   for (size_t i = 0; i < 2; ++i) {
    426     glBindTexture(GL_TEXTURE_2D, tex[i]);
    427     glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox[i].name);
    428     EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
    429   }
    430 
    431   for (size_t i = 0; i < 2; ++i) {
    432     other_gl[i].MakeCurrent();
    433     glResizeCHROMIUM(10, 10, 1);
    434     glClearColor(1-i%2, i%2, 0, 1);
    435     glClear(GL_COLOR_BUFFER_BIT);
    436     ::gles2::GetGLContext()->SwapBuffers();
    437   }
    438 
    439   gl1_.MakeCurrent();
    440   EXPECT_EQ(0xFF0000FFu, ReadTexel(tex[0], 0, 0));
    441   EXPECT_EQ(0xFF00FF00u, ReadTexel(tex[1], 9, 9));
    442 
    443   for (size_t i = 0; i < 2; ++i) {
    444     other_gl[i].MakeCurrent();
    445     other_gl[i].Destroy();
    446   }
    447 
    448   gl1_.MakeCurrent();
    449   glDeleteTextures(2, tex);
    450 }
    451 #endif
    452 
    453 }  // namespace gpu
    454 
    455