Home | History | Annotate | Download | only in service
      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 "gpu/command_buffer/service/gles2_cmd_decoder.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/strings/string_number_conversions.h"
      9 #include "gpu/command_buffer/common/gles2_cmd_format.h"
     10 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
     11 #include "gpu/command_buffer/common/id_allocator.h"
     12 #include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
     13 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
     14 #include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
     15 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
     16 #include "gpu/command_buffer/service/context_group.h"
     17 #include "gpu/command_buffer/service/context_state.h"
     18 #include "gpu/command_buffer/service/gl_surface_mock.h"
     19 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
     20 
     21 #include "gpu/command_buffer/service/gpu_switches.h"
     22 #include "gpu/command_buffer/service/image_manager.h"
     23 #include "gpu/command_buffer/service/mailbox_manager.h"
     24 #include "gpu/command_buffer/service/mocks.h"
     25 #include "gpu/command_buffer/service/program_manager.h"
     26 #include "gpu/command_buffer/service/test_helper.h"
     27 #include "testing/gtest/include/gtest/gtest.h"
     28 #include "ui/gl/gl_implementation.h"
     29 #include "ui/gl/gl_mock.h"
     30 #include "ui/gl/gl_surface_stub.h"
     31 
     32 #if !defined(GL_DEPTH24_STENCIL8)
     33 #define GL_DEPTH24_STENCIL8 0x88F0
     34 #endif
     35 
     36 using ::gfx::MockGLInterface;
     37 using ::testing::_;
     38 using ::testing::DoAll;
     39 using ::testing::InSequence;
     40 using ::testing::Invoke;
     41 using ::testing::MatcherCast;
     42 using ::testing::Mock;
     43 using ::testing::Pointee;
     44 using ::testing::Return;
     45 using ::testing::SaveArg;
     46 using ::testing::SetArrayArgument;
     47 using ::testing::SetArgumentPointee;
     48 using ::testing::SetArgPointee;
     49 using ::testing::StrEq;
     50 using ::testing::StrictMock;
     51 
     52 namespace gpu {
     53 namespace gles2 {
     54 
     55 using namespace cmds;
     56 
     57 TEST_P(GLES2DecoderWithShaderTest, GetVertexAttribPointervSucceeds) {
     58   const float dummy = 0;
     59   const GLuint kOffsetToTestFor = sizeof(dummy) * 4;
     60   const GLuint kIndexToTest = 1;
     61   GetVertexAttribPointerv::Result* result =
     62       static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_);
     63   result->size = 0;
     64   const GLuint* result_value = result->GetData();
     65   // Test that initial value is 0.
     66   GetVertexAttribPointerv cmd;
     67   cmd.Init(kIndexToTest,
     68            GL_VERTEX_ATTRIB_ARRAY_POINTER,
     69            shared_memory_id_,
     70            shared_memory_offset_);
     71   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
     72   EXPECT_EQ(sizeof(*result_value), result->size);
     73   EXPECT_EQ(0u, *result_value);
     74   EXPECT_EQ(GL_NO_ERROR, GetGLError());
     75 
     76   // Set the value and see that we get it.
     77   SetupVertexBuffer();
     78   DoVertexAttribPointer(kIndexToTest, 2, GL_FLOAT, 0, kOffsetToTestFor);
     79   result->size = 0;
     80   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
     81   EXPECT_EQ(sizeof(*result_value), result->size);
     82   EXPECT_EQ(kOffsetToTestFor, *result_value);
     83   EXPECT_EQ(GL_NO_ERROR, GetGLError());
     84 }
     85 
     86 TEST_P(GLES2DecoderWithShaderTest, GetVertexAttribPointervBadArgsFails) {
     87   const GLuint kIndexToTest = 1;
     88   GetVertexAttribPointerv::Result* result =
     89       static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_);
     90   result->size = 0;
     91   const GLuint* result_value = result->GetData();
     92   // Test pname invalid fails.
     93   GetVertexAttribPointerv cmd;
     94   cmd.Init(kIndexToTest,
     95            GL_VERTEX_ATTRIB_ARRAY_POINTER + 1,
     96            shared_memory_id_,
     97            shared_memory_offset_);
     98   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
     99   EXPECT_EQ(0u, result->size);
    100   EXPECT_EQ(kInitialResult, *result_value);
    101   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
    102 
    103   // Test index out of range fails.
    104   result->size = 0;
    105   cmd.Init(kNumVertexAttribs,
    106            GL_VERTEX_ATTRIB_ARRAY_POINTER,
    107            shared_memory_id_,
    108            shared_memory_offset_);
    109   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    110   EXPECT_EQ(0u, result->size);
    111   EXPECT_EQ(kInitialResult, *result_value);
    112   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
    113 
    114   // Test memory id bad fails.
    115   cmd.Init(kIndexToTest,
    116            GL_VERTEX_ATTRIB_ARRAY_POINTER,
    117            kInvalidSharedMemoryId,
    118            shared_memory_offset_);
    119   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    120 
    121   // Test memory offset bad fails.
    122   cmd.Init(kIndexToTest,
    123            GL_VERTEX_ATTRIB_ARRAY_POINTER,
    124            shared_memory_id_,
    125            kInvalidSharedMemoryOffset);
    126   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    127 }
    128 
    129 TEST_P(GLES2DecoderWithShaderTest, BindBufferToDifferentTargetFails) {
    130   // Bind the buffer to GL_ARRAY_BUFFER
    131   DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
    132   // Attempt to rebind to GL_ELEMENT_ARRAY_BUFFER
    133   // NOTE: Real GLES2 does not have this restriction but WebGL and we do.
    134   // This can be restriction can be removed at runtime.
    135   EXPECT_CALL(*gl_, BindBuffer(_, _)).Times(0);
    136   BindBuffer cmd;
    137   cmd.Init(GL_ELEMENT_ARRAY_BUFFER, client_buffer_id_);
    138   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    139   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
    140 }
    141 
    142 TEST_P(GLES2DecoderWithShaderTest, VertexAttribPointer) {
    143   SetupVertexBuffer();
    144   static const GLenum types[] = {
    145       GL_BYTE,  GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT,
    146       GL_FLOAT, GL_FIXED,         GL_INT,   GL_UNSIGNED_INT,
    147   };
    148   static const GLsizei sizes[] = {
    149       1, 1, 2, 2, 4, 4, 4, 4,
    150   };
    151   static const GLuint indices[] = {
    152       0, 1, kNumVertexAttribs - 1, kNumVertexAttribs,
    153   };
    154   static const GLsizei offset_mult[] = {
    155       0, 0, 1, 1, 2, 1000,
    156   };
    157   static const GLsizei offset_offset[] = {
    158       0, 1, 0, 1, 0, 0,
    159   };
    160   static const GLsizei stride_mult[] = {
    161       -1, 0, 0, 1, 1, 2, 1000,
    162   };
    163   static const GLsizei stride_offset[] = {
    164       0, 0, 1, 0, 1, 0, 0,
    165   };
    166   for (size_t tt = 0; tt < arraysize(types); ++tt) {
    167     GLenum type = types[tt];
    168     GLsizei num_bytes = sizes[tt];
    169     for (size_t ii = 0; ii < arraysize(indices); ++ii) {
    170       GLuint index = indices[ii];
    171       for (GLint size = 0; size < 5; ++size) {
    172         for (size_t oo = 0; oo < arraysize(offset_mult); ++oo) {
    173           GLuint offset = num_bytes * offset_mult[oo] + offset_offset[oo];
    174           for (size_t ss = 0; ss < arraysize(stride_mult); ++ss) {
    175             GLsizei stride = num_bytes * stride_mult[ss] + stride_offset[ss];
    176             for (int normalize = 0; normalize < 2; ++normalize) {
    177               bool index_good = index < static_cast<GLuint>(kNumVertexAttribs);
    178               bool size_good = (size > 0 && size < 5);
    179               bool offset_good = (offset % num_bytes == 0);
    180               bool stride_good =
    181                   (stride % num_bytes == 0) && stride >= 0 && stride <= 255;
    182               bool type_good = (type != GL_INT && type != GL_UNSIGNED_INT &&
    183                                 type != GL_FIXED);
    184               bool good = size_good && offset_good && stride_good &&
    185                           type_good && index_good;
    186               bool call = good && (type != GL_FIXED);
    187               if (call) {
    188                 EXPECT_CALL(*gl_,
    189                             VertexAttribPointer(index,
    190                                                 size,
    191                                                 type,
    192                                                 normalize,
    193                                                 stride,
    194                                                 BufferOffset(offset)));
    195               }
    196               VertexAttribPointer cmd;
    197               cmd.Init(index, size, type, normalize, stride, offset);
    198               EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    199               if (good) {
    200                 EXPECT_EQ(GL_NO_ERROR, GetGLError());
    201               } else if (size_good && offset_good && stride_good && type_good &&
    202                          !index_good) {
    203                 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
    204               } else if (size_good && offset_good && stride_good &&
    205                          !type_good && index_good) {
    206                 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
    207               } else if (size_good && offset_good && !stride_good &&
    208                          type_good && index_good) {
    209                 if (stride < 0 || stride > 255) {
    210                   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
    211                 } else {
    212                   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
    213                 }
    214               } else if (size_good && !offset_good && stride_good &&
    215                          type_good && index_good) {
    216                 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
    217               } else if (!size_good && offset_good && stride_good &&
    218                          type_good && index_good) {
    219                 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
    220               } else {
    221                 EXPECT_NE(GL_NO_ERROR, GetGLError());
    222               }
    223             }
    224           }
    225         }
    226       }
    227     }
    228   }
    229 }
    230 
    231 class GLES2DecoderVertexArraysOESTest : public GLES2DecoderWithShaderTest {
    232  public:
    233   GLES2DecoderVertexArraysOESTest() {}
    234 
    235   bool vertex_array_deleted_manually_;
    236 
    237   virtual void SetUp() {
    238     InitState init;
    239     init.gl_version = "opengl es 2.0";
    240     init.bind_generates_resource = true;
    241     InitDecoder(init);
    242     SetupDefaultProgram();
    243 
    244     AddExpectationsForGenVertexArraysOES();
    245     GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
    246 
    247     vertex_array_deleted_manually_ = false;
    248   }
    249 
    250   virtual void TearDown() {
    251     // This should only be set if the test handled deletion of the vertex array
    252     // itself. Necessary because vertex_array_objects are not sharable, and thus
    253     // not managed in the ContextGroup, meaning they will be destroyed during
    254     // test tear down
    255     if (!vertex_array_deleted_manually_) {
    256       AddExpectationsForDeleteVertexArraysOES();
    257     }
    258 
    259     GLES2DecoderWithShaderTest::TearDown();
    260   }
    261 
    262   void GenVertexArraysOESImmediateValidArgs() {
    263     AddExpectationsForGenVertexArraysOES();
    264     GenVertexArraysOESImmediate* cmd =
    265         GetImmediateAs<GenVertexArraysOESImmediate>();
    266     GLuint temp = kNewClientId;
    267     cmd->Init(1, &temp);
    268     EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*cmd, sizeof(temp)));
    269     EXPECT_EQ(GL_NO_ERROR, GetGLError());
    270     EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
    271     AddExpectationsForDeleteVertexArraysOES();
    272   }
    273 
    274   void GenVertexArraysOESImmediateInvalidArgs() {
    275     EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
    276     GenVertexArraysOESImmediate* cmd =
    277         GetImmediateAs<GenVertexArraysOESImmediate>();
    278     cmd->Init(1, &client_vertexarray_id_);
    279     EXPECT_EQ(error::kInvalidArguments,
    280               ExecuteImmediateCmd(*cmd, sizeof(&client_vertexarray_id_)));
    281   }
    282 
    283   void DeleteVertexArraysOESImmediateValidArgs() {
    284     AddExpectationsForDeleteVertexArraysOES();
    285     DeleteVertexArraysOESImmediate& cmd =
    286         *GetImmediateAs<DeleteVertexArraysOESImmediate>();
    287     cmd.Init(1, &client_vertexarray_id_);
    288     EXPECT_EQ(error::kNoError,
    289               ExecuteImmediateCmd(cmd, sizeof(client_vertexarray_id_)));
    290     EXPECT_EQ(GL_NO_ERROR, GetGLError());
    291     EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_) == NULL);
    292     vertex_array_deleted_manually_ = true;
    293   }
    294 
    295   void DeleteVertexArraysOESImmediateInvalidArgs() {
    296     DeleteVertexArraysOESImmediate& cmd =
    297         *GetImmediateAs<DeleteVertexArraysOESImmediate>();
    298     GLuint temp = kInvalidClientId;
    299     cmd.Init(1, &temp);
    300     EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
    301   }
    302 
    303   void DeleteBoundVertexArraysOESImmediateValidArgs() {
    304     BindVertexArrayOESValidArgs();
    305 
    306     AddExpectationsForDeleteBoundVertexArraysOES();
    307     DeleteVertexArraysOESImmediate& cmd =
    308         *GetImmediateAs<DeleteVertexArraysOESImmediate>();
    309     cmd.Init(1, &client_vertexarray_id_);
    310     EXPECT_EQ(error::kNoError,
    311               ExecuteImmediateCmd(cmd, sizeof(client_vertexarray_id_)));
    312     EXPECT_EQ(GL_NO_ERROR, GetGLError());
    313     EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_) == NULL);
    314     vertex_array_deleted_manually_ = true;
    315   }
    316 
    317   void IsVertexArrayOESValidArgs() {
    318     IsVertexArrayOES cmd;
    319     cmd.Init(client_vertexarray_id_, shared_memory_id_, shared_memory_offset_);
    320     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    321     EXPECT_EQ(GL_NO_ERROR, GetGLError());
    322   }
    323 
    324   void IsVertexArrayOESInvalidArgsBadSharedMemoryId() {
    325     IsVertexArrayOES cmd;
    326     cmd.Init(
    327         client_vertexarray_id_, kInvalidSharedMemoryId, shared_memory_offset_);
    328     EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
    329     cmd.Init(
    330         client_vertexarray_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
    331     EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
    332   }
    333 
    334   void BindVertexArrayOESValidArgs() {
    335     AddExpectationsForBindVertexArrayOES();
    336     BindVertexArrayOES cmd;
    337     cmd.Init(client_vertexarray_id_);
    338     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    339     EXPECT_EQ(GL_NO_ERROR, GetGLError());
    340   }
    341 
    342   void BindVertexArrayOESValidArgsNewId() {
    343     BindVertexArrayOES cmd;
    344     cmd.Init(kNewClientId);
    345     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    346     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
    347   }
    348 };
    349 
    350 INSTANTIATE_TEST_CASE_P(Service,
    351                         GLES2DecoderVertexArraysOESTest,
    352                         ::testing::Bool());
    353 
    354 class GLES2DecoderEmulatedVertexArraysOESTest
    355     : public GLES2DecoderVertexArraysOESTest {
    356  public:
    357   GLES2DecoderEmulatedVertexArraysOESTest() {}
    358 
    359   virtual void SetUp() {
    360     InitState init;
    361     init.gl_version = "3.0";
    362     init.bind_generates_resource = true;
    363     init.use_native_vao = false;
    364     InitDecoder(init);
    365     SetupDefaultProgram();
    366 
    367     AddExpectationsForGenVertexArraysOES();
    368     GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
    369 
    370     vertex_array_deleted_manually_ = false;
    371   }
    372 };
    373 
    374 INSTANTIATE_TEST_CASE_P(Service,
    375                         GLES2DecoderEmulatedVertexArraysOESTest,
    376                         ::testing::Bool());
    377 
    378 // Test vertex array objects with native support
    379 TEST_P(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESImmediateValidArgs) {
    380   GenVertexArraysOESImmediateValidArgs();
    381 }
    382 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
    383        GenVertexArraysOESImmediateValidArgs) {
    384   GenVertexArraysOESImmediateValidArgs();
    385 }
    386 
    387 TEST_P(GLES2DecoderVertexArraysOESTest,
    388        GenVertexArraysOESImmediateInvalidArgs) {
    389   GenVertexArraysOESImmediateInvalidArgs();
    390 }
    391 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
    392        GenVertexArraysOESImmediateInvalidArgs) {
    393   GenVertexArraysOESImmediateInvalidArgs();
    394 }
    395 
    396 TEST_P(GLES2DecoderVertexArraysOESTest,
    397        DeleteVertexArraysOESImmediateValidArgs) {
    398   DeleteVertexArraysOESImmediateValidArgs();
    399 }
    400 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
    401        DeleteVertexArraysOESImmediateValidArgs) {
    402   DeleteVertexArraysOESImmediateValidArgs();
    403 }
    404 
    405 TEST_P(GLES2DecoderVertexArraysOESTest,
    406        DeleteVertexArraysOESImmediateInvalidArgs) {
    407   DeleteVertexArraysOESImmediateInvalidArgs();
    408 }
    409 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
    410        DeleteVertexArraysOESImmediateInvalidArgs) {
    411   DeleteVertexArraysOESImmediateInvalidArgs();
    412 }
    413 
    414 TEST_P(GLES2DecoderVertexArraysOESTest,
    415        DeleteBoundVertexArraysOESImmediateValidArgs) {
    416   DeleteBoundVertexArraysOESImmediateValidArgs();
    417 }
    418 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
    419        DeleteBoundVertexArraysOESImmediateValidArgs) {
    420   DeleteBoundVertexArraysOESImmediateValidArgs();
    421 }
    422 
    423 TEST_P(GLES2DecoderVertexArraysOESTest, IsVertexArrayOESValidArgs) {
    424   IsVertexArrayOESValidArgs();
    425 }
    426 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, IsVertexArrayOESValidArgs) {
    427   IsVertexArrayOESValidArgs();
    428 }
    429 
    430 TEST_P(GLES2DecoderVertexArraysOESTest,
    431        IsVertexArrayOESInvalidArgsBadSharedMemoryId) {
    432   IsVertexArrayOESInvalidArgsBadSharedMemoryId();
    433 }
    434 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
    435        IsVertexArrayOESInvalidArgsBadSharedMemoryId) {
    436   IsVertexArrayOESInvalidArgsBadSharedMemoryId();
    437 }
    438 
    439 TEST_P(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgs) {
    440   BindVertexArrayOESValidArgs();
    441 }
    442 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, BindVertexArrayOESValidArgs) {
    443   BindVertexArrayOESValidArgs();
    444 }
    445 
    446 TEST_P(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgsNewId) {
    447   BindVertexArrayOESValidArgsNewId();
    448 }
    449 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
    450        BindVertexArrayOESValidArgsNewId) {
    451   BindVertexArrayOESValidArgsNewId();
    452 }
    453 
    454 TEST_P(GLES2DecoderTest, BufferDataGLError) {
    455   GLenum target = GL_ARRAY_BUFFER;
    456   GLsizeiptr size = 4;
    457   DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
    458   BufferManager* manager = group().buffer_manager();
    459   Buffer* buffer = manager->GetBuffer(client_buffer_id_);
    460   ASSERT_TRUE(buffer != NULL);
    461   EXPECT_EQ(0, buffer->size());
    462   EXPECT_CALL(*gl_, GetError())
    463       .WillOnce(Return(GL_NO_ERROR))
    464       .WillOnce(Return(GL_OUT_OF_MEMORY))
    465       .RetiresOnSaturation();
    466   EXPECT_CALL(*gl_, BufferData(target, size, _, GL_STREAM_DRAW))
    467       .Times(1)
    468       .RetiresOnSaturation();
    469   BufferData cmd;
    470   cmd.Init(target, size, 0, 0, GL_STREAM_DRAW);
    471   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    472   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
    473   EXPECT_EQ(0, buffer->size());
    474 }
    475 
    476 // TODO(gman): BufferData
    477 
    478 // TODO(gman): BufferDataImmediate
    479 
    480 // TODO(gman): BufferSubData
    481 
    482 // TODO(gman): BufferSubDataImmediate
    483 
    484 }  // namespace gles2
    485 }  // namespace gpu
    486