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     shared_memory_.reset(new ::base::SharedMemory);
     37     shared_memory_->CreateAndMapAnonymous(kRingBufferSize);
     38     buffer_ = static_cast<int32*>(shared_memory_->memory());
     39     shared_memory_buffer_.ptr = buffer_;
     40     shared_memory_buffer_.size = 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(), GetState())
     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_->GetState().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_ptr<base::SharedMemory> shared_memory_;
     76   Buffer shared_memory_buffer_;
     77   int32* buffer_;
     78   scoped_ptr<gles2::MockGLES2Decoder> decoder_;
     79   scoped_ptr<GpuScheduler> scheduler_;
     80 };
     81 
     82 TEST_F(GpuSchedulerTest, SchedulerDoesNothingIfRingBufferIsEmpty) {
     83   CommandBuffer::State state;
     84 
     85   state.put_offset = 0;
     86   EXPECT_CALL(*command_buffer_, GetState())
     87     .WillRepeatedly(Return(state));
     88 
     89   EXPECT_CALL(*command_buffer_, SetParseError(_))
     90     .Times(0);
     91 
     92   scheduler_->PutChanged();
     93 }
     94 
     95 TEST_F(GpuSchedulerTest, GetSetBuffer) {
     96   CommandBuffer::State state;
     97 
     98   // Set the get offset to something not 0.
     99   EXPECT_CALL(*command_buffer_, SetGetOffset(2));
    100   scheduler_->SetGetOffset(2);
    101   EXPECT_EQ(2, scheduler_->GetGetOffset());
    102 
    103   // Set the buffer.
    104   EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId))
    105      .WillOnce(Return(shared_memory_buffer_));
    106   EXPECT_CALL(*command_buffer_, SetGetOffset(0));
    107   EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId));
    108 
    109   // Check the get offset was reset.
    110   EXPECT_EQ(0, scheduler_->GetGetOffset());
    111 }
    112 
    113 TEST_F(GpuSchedulerTest, ProcessesOneCommand) {
    114   CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
    115   header[0].command = 7;
    116   header[0].size = 2;
    117   buffer_[1] = 123;
    118 
    119   CommandBuffer::State state;
    120 
    121   state.put_offset = 2;
    122   EXPECT_CALL(*command_buffer_, GetState())
    123     .WillRepeatedly(Return(state));
    124   EXPECT_CALL(*command_buffer_, SetGetOffset(2));
    125 
    126   EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0]))
    127     .WillOnce(Return(error::kNoError));
    128 
    129   EXPECT_CALL(*command_buffer_, SetParseError(_))
    130     .Times(0);
    131 
    132   scheduler_->PutChanged();
    133 }
    134 
    135 TEST_F(GpuSchedulerTest, ProcessesTwoCommands) {
    136   CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
    137   header[0].command = 7;
    138   header[0].size = 2;
    139   buffer_[1] = 123;
    140   header[2].command = 8;
    141   header[2].size = 1;
    142 
    143   CommandBuffer::State state;
    144 
    145   state.put_offset = 3;
    146   EXPECT_CALL(*command_buffer_, GetState())
    147     .WillRepeatedly(Return(state));
    148 
    149   EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0]))
    150     .WillOnce(Return(error::kNoError));
    151   EXPECT_CALL(*command_buffer_, SetGetOffset(2));
    152 
    153   EXPECT_CALL(*decoder_, DoCommand(8, 0, &buffer_[2]))
    154     .WillOnce(Return(error::kNoError));
    155   EXPECT_CALL(*command_buffer_, SetGetOffset(3));
    156 
    157   scheduler_->PutChanged();
    158 }
    159 
    160 TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) {
    161   CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
    162   header[0].command = 7;
    163   header[0].size = 1;
    164 
    165   CommandBuffer::State state;
    166 
    167   state.put_offset = 1;
    168   EXPECT_CALL(*command_buffer_, GetState())
    169     .WillRepeatedly(Return(state));
    170 
    171   EXPECT_CALL(*decoder_, DoCommand(7, 0, &buffer_[0]))
    172     .WillOnce(Return(
    173         error::kUnknownCommand));
    174   EXPECT_CALL(*command_buffer_, SetGetOffset(1));
    175 
    176   EXPECT_CALL(*command_buffer_, SetContextLostReason(_));
    177   EXPECT_CALL(*decoder_, GetContextLostReason())
    178     .WillOnce(Return(error::kUnknown));
    179   EXPECT_CALL(*command_buffer_,
    180       SetParseError(error::kUnknownCommand));
    181 
    182   scheduler_->PutChanged();
    183 }
    184 
    185 TEST_F(GpuSchedulerTest, ProcessCommandsDoesNothingAfterError) {
    186   CommandBuffer::State state;
    187   state.error = error::kGenericError;
    188 
    189   EXPECT_CALL(*command_buffer_, GetState())
    190     .WillRepeatedly(Return(state));
    191 
    192   scheduler_->PutChanged();
    193 }
    194 
    195 TEST_F(GpuSchedulerTest, CanGetAddressOfSharedMemory) {
    196   EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7))
    197     .WillOnce(Return(shared_memory_buffer_));
    198 
    199   EXPECT_EQ(&buffer_[0], scheduler_->GetSharedMemoryBuffer(7).ptr);
    200 }
    201 
    202 ACTION_P2(SetPointee, address, value) {
    203   *address = value;
    204 }
    205 
    206 TEST_F(GpuSchedulerTest, CanGetSizeOfSharedMemory) {
    207   EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7))
    208     .WillOnce(Return(shared_memory_buffer_));
    209 
    210   EXPECT_EQ(kRingBufferSize, scheduler_->GetSharedMemoryBuffer(7).size);
    211 }
    212 
    213 TEST_F(GpuSchedulerTest, SetTokenForwardsToCommandBuffer) {
    214   EXPECT_CALL(*command_buffer_, SetToken(7));
    215   scheduler_->set_token(7);
    216 }
    217 
    218 }  // namespace gpu
    219