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.
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"
14 #if defined(OS_MACOSX)
15 #include "base/mac/scoped_nsautorelease_pool.h"
20 using testing::Invoke
;
21 using testing::NiceMock
;
22 using testing::Return
;
23 using testing::SetArgumentPointee
;
24 using testing::StrictMock
;
28 const size_t kRingBufferSize
= 1024;
30 class GpuSchedulerTest
: public testing::Test
{
32 static const int32 kTransferBufferId
= 123;
34 void SetUp() override
{
35 scoped_ptr
<base::SharedMemory
> shared_memory(new ::base::SharedMemory
);
36 shared_memory
->CreateAndMapAnonymous(kRingBufferSize
);
37 buffer_
= static_cast<int32
*>(shared_memory
->memory());
38 shared_memory_buffer_
=
39 MakeBufferFromSharedMemory(shared_memory
.Pass(), kRingBufferSize
);
40 memset(buffer_
, 0, kRingBufferSize
);
42 command_buffer_
.reset(new MockCommandBuffer
);
44 CommandBuffer::State default_state
;
45 ON_CALL(*command_buffer_
.get(), GetLastState())
46 .WillByDefault(Return(default_state
));
47 ON_CALL(*command_buffer_
.get(), GetPutOffset())
48 .WillByDefault(Return(0));
50 decoder_
.reset(new gles2::MockGLES2Decoder());
51 // Install FakeDoCommands handler so we can use individual DoCommand()
53 EXPECT_CALL(*decoder_
, DoCommands(_
, _
, _
, _
)).WillRepeatedly(
54 Invoke(decoder_
.get(), &gles2::MockGLES2Decoder::FakeDoCommands
));
56 scheduler_
.reset(new gpu::GpuScheduler(command_buffer_
.get(),
59 EXPECT_CALL(*command_buffer_
, GetTransferBuffer(kTransferBufferId
))
60 .WillOnce(Return(shared_memory_buffer_
));
61 EXPECT_CALL(*command_buffer_
, SetGetOffset(0));
62 EXPECT_TRUE(scheduler_
->SetGetBuffer(kTransferBufferId
));
65 void TearDown() override
{
66 // Ensure that any unexpected tasks posted by the GPU scheduler are executed
67 // in order to fail the test.
68 base::MessageLoop::current()->RunUntilIdle();
71 error::Error
GetError() {
72 return command_buffer_
->GetLastState().error
;
75 #if defined(OS_MACOSX)
76 base::mac::ScopedNSAutoreleasePool autorelease_pool_
;
78 base::MessageLoop message_loop
;
79 scoped_ptr
<MockCommandBuffer
> command_buffer_
;
80 scoped_refptr
<Buffer
> shared_memory_buffer_
;
82 scoped_ptr
<gles2::MockGLES2Decoder
> decoder_
;
83 scoped_ptr
<GpuScheduler
> scheduler_
;
86 TEST_F(GpuSchedulerTest
, SchedulerDoesNothingIfRingBufferIsEmpty
) {
87 CommandBuffer::State state
;
89 EXPECT_CALL(*command_buffer_
, GetLastState())
90 .WillRepeatedly(Return(state
));
92 EXPECT_CALL(*command_buffer_
, SetParseError(_
))
95 scheduler_
->PutChanged();
98 TEST_F(GpuSchedulerTest
, GetSetBuffer
) {
99 CommandBuffer::State state
;
101 // Set the get offset to something not 0.
102 EXPECT_CALL(*command_buffer_
, SetGetOffset(2));
103 scheduler_
->SetGetOffset(2);
104 EXPECT_EQ(2, scheduler_
->GetGetOffset());
107 EXPECT_CALL(*command_buffer_
, GetTransferBuffer(kTransferBufferId
))
108 .WillOnce(Return(shared_memory_buffer_
));
109 EXPECT_CALL(*command_buffer_
, SetGetOffset(0));
110 EXPECT_TRUE(scheduler_
->SetGetBuffer(kTransferBufferId
));
112 // Check the get offset was reset.
113 EXPECT_EQ(0, scheduler_
->GetGetOffset());
116 TEST_F(GpuSchedulerTest
, ProcessesOneCommand
) {
117 CommandHeader
* header
= reinterpret_cast<CommandHeader
*>(&buffer_
[0]);
118 header
[0].command
= 7;
122 CommandBuffer::State state
;
124 EXPECT_CALL(*command_buffer_
, GetLastState())
125 .WillRepeatedly(Return(state
));
126 EXPECT_CALL(*command_buffer_
, GetPutOffset())
127 .WillRepeatedly(Return(2));
128 EXPECT_CALL(*command_buffer_
, SetGetOffset(2));
130 EXPECT_CALL(*decoder_
, DoCommand(7, 1, &buffer_
[0]))
131 .WillOnce(Return(error::kNoError
));
133 EXPECT_CALL(*command_buffer_
, SetParseError(_
))
136 scheduler_
->PutChanged();
139 TEST_F(GpuSchedulerTest
, ProcessesTwoCommands
) {
140 CommandHeader
* header
= reinterpret_cast<CommandHeader
*>(&buffer_
[0]);
141 header
[0].command
= 7;
144 header
[2].command
= 8;
147 CommandBuffer::State state
;
149 EXPECT_CALL(*command_buffer_
, GetLastState())
150 .WillRepeatedly(Return(state
));
151 EXPECT_CALL(*command_buffer_
, GetPutOffset())
152 .WillRepeatedly(Return(3));
154 EXPECT_CALL(*decoder_
, DoCommand(7, 1, &buffer_
[0]))
155 .WillOnce(Return(error::kNoError
));
157 EXPECT_CALL(*decoder_
, DoCommand(8, 0, &buffer_
[2]))
158 .WillOnce(Return(error::kNoError
));
159 EXPECT_CALL(*command_buffer_
, SetGetOffset(3));
161 scheduler_
->PutChanged();
164 TEST_F(GpuSchedulerTest
, SetsErrorCodeOnCommandBuffer
) {
165 CommandHeader
* header
= reinterpret_cast<CommandHeader
*>(&buffer_
[0]);
166 header
[0].command
= 7;
169 CommandBuffer::State state
;
171 EXPECT_CALL(*command_buffer_
, GetLastState())
172 .WillRepeatedly(Return(state
));
173 EXPECT_CALL(*command_buffer_
, GetPutOffset())
174 .WillRepeatedly(Return(1));
176 EXPECT_CALL(*decoder_
, DoCommand(7, 0, &buffer_
[0]))
178 error::kUnknownCommand
));
179 EXPECT_CALL(*command_buffer_
, SetGetOffset(1));
181 EXPECT_CALL(*command_buffer_
, SetContextLostReason(_
));
182 EXPECT_CALL(*decoder_
, GetContextLostReason())
183 .WillOnce(Return(error::kUnknown
));
184 EXPECT_CALL(*command_buffer_
,
185 SetParseError(error::kUnknownCommand
));
187 scheduler_
->PutChanged();
190 TEST_F(GpuSchedulerTest
, ProcessCommandsDoesNothingAfterError
) {
191 CommandBuffer::State state
;
192 state
.error
= error::kGenericError
;
194 EXPECT_CALL(*command_buffer_
, GetLastState())
195 .WillRepeatedly(Return(state
));
197 scheduler_
->PutChanged();
200 TEST_F(GpuSchedulerTest
, CanGetAddressOfSharedMemory
) {
201 EXPECT_CALL(*command_buffer_
.get(), GetTransferBuffer(7))
202 .WillOnce(Return(shared_memory_buffer_
));
204 EXPECT_EQ(&buffer_
[0], scheduler_
->GetSharedMemoryBuffer(7)->memory());
207 ACTION_P2(SetPointee
, address
, value
) {
211 TEST_F(GpuSchedulerTest
, CanGetSizeOfSharedMemory
) {
212 EXPECT_CALL(*command_buffer_
.get(), GetTransferBuffer(7))
213 .WillOnce(Return(shared_memory_buffer_
));
215 EXPECT_EQ(kRingBufferSize
, scheduler_
->GetSharedMemoryBuffer(7)->size());
218 TEST_F(GpuSchedulerTest
, SetTokenForwardsToCommandBuffer
) {
219 EXPECT_CALL(*command_buffer_
, SetToken(7));
220 scheduler_
->set_token(7);