Home | History | Annotate | Download | only in service
      1 // Copyright (c) 2011 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 "base/message_loop/message_loop.h"
      6 #include "gpu/command_buffer/common/command_buffer_mock.h"
      7 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
      8 #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
      9 #include "gpu/command_buffer/service/gpu_scheduler.h"
     10 #include "gpu/command_buffer/service/mocks.h"
     11 #include "testing/gmock/include/gmock/gmock.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 #if defined(OS_MACOSX)
     15 #include "base/mac/scoped_nsautorelease_pool.h"
     16 #endif
     17 
     18 using testing::_;
     19 using testing::DoAll;
     20 using testing::Invoke;
     21 using testing::NiceMock;
     22 using testing::Return;
     23 using testing::SetArgumentPointee;
     24 using testing::StrictMock;
     25 
     26 namespace gpu {
     27 
     28 const size_t kRingBufferSize = 1024;
     29 const size_t kRingBufferEntries = kRingBufferSize / sizeof(CommandBufferEntry);
     30 
     31 class GpuSchedulerTest : public testing::Test {
     32  protected:
     33   static const int32 kTransferBufferId = 123;
     34 
     35   virtual void SetUp() {
     36     scoped_ptr<base::SharedMemory> shared_memory(new ::base::SharedMemory);
     37     shared_memory->CreateAndMapAnonymous(kRingBufferSize);
     38     buffer_ = static_cast<int32*>(shared_memory->memory());
     39     shared_memory_buffer_ =
     40         MakeBufferFromSharedMemory(shared_memory.Pass(), kRingBufferSize);
     41     memset(buffer_, 0, kRingBufferSize);
     42 
     43     command_buffer_.reset(new MockCommandBuffer);
     44 
     45     CommandBuffer::State default_state;
     46     default_state.num_entries = kRingBufferEntries;
     47     ON_CALL(*command_buffer_.get(), GetLastState())
     48         .WillByDefault(Return(default_state));
     49 
     50     decoder_.reset(new gles2::MockGLES2Decoder());
     51     scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(),
     52                                            decoder_.get(),
     53                                            decoder_.get()));
     54     EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId))
     55        .WillOnce(Return(shared_memory_buffer_));
     56     EXPECT_CALL(*command_buffer_, SetGetOffset(0));
     57     EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId));
     58   }
     59 
     60   virtual void TearDown() {
     61     // Ensure that any unexpected tasks posted by the GPU scheduler are executed
     62     // in order to fail the test.
     63     base::MessageLoop::current()->RunUntilIdle();
     64   }
     65 
     66   error::Error GetError() {
     67     return command_buffer_->GetLastState().error;
     68   }
     69 
     70 #if defined(OS_MACOSX)
     71   base::mac::ScopedNSAutoreleasePool autorelease_pool_;
     72 #endif
     73   base::MessageLoop message_loop;
     74   scoped_ptr<MockCommandBuffer> command_buffer_;
     75   scoped_refptr<Buffer> shared_memory_buffer_;
     76   int32* buffer_;
     77   scoped_ptr<gles2::MockGLES2Decoder> decoder_;
     78   scoped_ptr<GpuScheduler> scheduler_;
     79 };
     80 
     81 TEST_F(GpuSchedulerTest, SchedulerDoesNothingIfRingBufferIsEmpty) {
     82   CommandBuffer::State state;
     83 
     84   state.put_offset = 0;
     85   EXPECT_CALL(*command_buffer_, GetLastState())
     86     .WillRepeatedly(Return(state));
     87 
     88   EXPECT_CALL(*command_buffer_, SetParseError(_))
     89     .Times(0);
     90 
     91   scheduler_->PutChanged();
     92 }
     93 
     94 TEST_F(GpuSchedulerTest, GetSetBuffer) {
     95   CommandBuffer::State state;
     96 
     97   // Set the get offset to something not 0.
     98   EXPECT_CALL(*command_buffer_, SetGetOffset(2));
     99   scheduler_->SetGetOffset(2);
    100   EXPECT_EQ(2, scheduler_->GetGetOffset());
    101 
    102   // Set the buffer.
    103   EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId))
    104      .WillOnce(Return(shared_memory_buffer_));
    105   EXPECT_CALL(*command_buffer_, SetGetOffset(0));
    106   EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId));
    107 
    108   // Check the get offset was reset.
    109   EXPECT_EQ(0, scheduler_->GetGetOffset());
    110 }
    111 
    112 TEST_F(GpuSchedulerTest, ProcessesOneCommand) {
    113   CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
    114   header[0].command = 7;
    115   header[0].size = 2;
    116   buffer_[1] = 123;
    117 
    118   CommandBuffer::State state;
    119 
    120   state.put_offset = 2;
    121   EXPECT_CALL(*command_buffer_, GetLastState())
    122     .WillRepeatedly(Return(state));
    123   EXPECT_CALL(*command_buffer_, SetGetOffset(2));
    124 
    125   EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0]))
    126     .WillOnce(Return(error::kNoError));
    127 
    128   EXPECT_CALL(*command_buffer_, SetParseError(_))
    129     .Times(0);
    130 
    131   scheduler_->PutChanged();
    132 }
    133 
    134 TEST_F(GpuSchedulerTest, ProcessesTwoCommands) {
    135   CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
    136   header[0].command = 7;
    137   header[0].size = 2;
    138   buffer_[1] = 123;
    139   header[2].command = 8;
    140   header[2].size = 1;
    141 
    142   CommandBuffer::State state;
    143 
    144   state.put_offset = 3;
    145   EXPECT_CALL(*command_buffer_, GetLastState())
    146     .WillRepeatedly(Return(state));
    147 
    148   EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0]))
    149     .WillOnce(Return(error::kNoError));
    150   EXPECT_CALL(*command_buffer_, SetGetOffset(2));
    151 
    152   EXPECT_CALL(*decoder_, DoCommand(8, 0, &buffer_[2]))
    153     .WillOnce(Return(error::kNoError));
    154   EXPECT_CALL(*command_buffer_, SetGetOffset(3));
    155 
    156   scheduler_->PutChanged();
    157 }
    158 
    159 TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) {
    160   CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
    161   header[0].command = 7;
    162   header[0].size = 1;
    163 
    164   CommandBuffer::State state;
    165 
    166   state.put_offset = 1;
    167   EXPECT_CALL(*command_buffer_, GetLastState())
    168     .WillRepeatedly(Return(state));
    169 
    170   EXPECT_CALL(*decoder_, DoCommand(7, 0, &buffer_[0]))
    171     .WillOnce(Return(
    172         error::kUnknownCommand));
    173   EXPECT_CALL(*command_buffer_, SetGetOffset(1));
    174 
    175   EXPECT_CALL(*command_buffer_, SetContextLostReason(_));
    176   EXPECT_CALL(*decoder_, GetContextLostReason())
    177     .WillOnce(Return(error::kUnknown));
    178   EXPECT_CALL(*command_buffer_,
    179       SetParseError(error::kUnknownCommand));
    180 
    181   scheduler_->PutChanged();
    182 }
    183 
    184 TEST_F(GpuSchedulerTest, ProcessCommandsDoesNothingAfterError) {
    185   CommandBuffer::State state;
    186   state.error = error::kGenericError;
    187 
    188   EXPECT_CALL(*command_buffer_, GetLastState())
    189     .WillRepeatedly(Return(state));
    190 
    191   scheduler_->PutChanged();
    192 }
    193 
    194 TEST_F(GpuSchedulerTest, CanGetAddressOfSharedMemory) {
    195   EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7))
    196     .WillOnce(Return(shared_memory_buffer_));
    197 
    198   EXPECT_EQ(&buffer_[0], scheduler_->GetSharedMemoryBuffer(7)->memory());
    199 }
    200 
    201 ACTION_P2(SetPointee, address, value) {
    202   *address = value;
    203 }
    204 
    205 TEST_F(GpuSchedulerTest, CanGetSizeOfSharedMemory) {
    206   EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7))
    207     .WillOnce(Return(shared_memory_buffer_));
    208 
    209   EXPECT_EQ(kRingBufferSize, scheduler_->GetSharedMemoryBuffer(7)->size());
    210 }
    211 
    212 TEST_F(GpuSchedulerTest, SetTokenForwardsToCommandBuffer) {
    213   EXPECT_CALL(*command_buffer_, SetToken(7));
    214   scheduler_->set_token(7);
    215 }
    216 
    217 }  // namespace gpu
    218