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;
29 const size_t kRingBufferEntries
= kRingBufferSize
/ sizeof(CommandBufferEntry
);
31 class GpuSchedulerTest
: public testing::Test
{
33 static const int32 kTransferBufferId
= 123;
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
);
43 command_buffer_
.reset(new MockCommandBuffer
);
45 CommandBuffer::State default_state
;
46 default_state
.num_entries
= kRingBufferEntries
;
47 ON_CALL(*command_buffer_
.get(), GetLastState())
48 .WillByDefault(Return(default_state
));
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 virtual void TearDown() {
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
;
90 EXPECT_CALL(*command_buffer_
, GetLastState())
91 .WillRepeatedly(Return(state
));
93 EXPECT_CALL(*command_buffer_
, SetParseError(_
))
96 scheduler_
->PutChanged();
99 TEST_F(GpuSchedulerTest
, GetSetBuffer
) {
100 CommandBuffer::State state
;
102 // Set the get offset to something not 0.
103 EXPECT_CALL(*command_buffer_
, SetGetOffset(2));
104 scheduler_
->SetGetOffset(2);
105 EXPECT_EQ(2, scheduler_
->GetGetOffset());
108 EXPECT_CALL(*command_buffer_
, GetTransferBuffer(kTransferBufferId
))
109 .WillOnce(Return(shared_memory_buffer_
));
110 EXPECT_CALL(*command_buffer_
, SetGetOffset(0));
111 EXPECT_TRUE(scheduler_
->SetGetBuffer(kTransferBufferId
));
113 // Check the get offset was reset.
114 EXPECT_EQ(0, scheduler_
->GetGetOffset());
117 TEST_F(GpuSchedulerTest
, ProcessesOneCommand
) {
118 CommandHeader
* header
= reinterpret_cast<CommandHeader
*>(&buffer_
[0]);
119 header
[0].command
= 7;
123 CommandBuffer::State state
;
125 state
.put_offset
= 2;
126 EXPECT_CALL(*command_buffer_
, GetLastState())
127 .WillRepeatedly(Return(state
));
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 state
.put_offset
= 3;
150 EXPECT_CALL(*command_buffer_
, GetLastState())
151 .WillRepeatedly(Return(state
));
153 EXPECT_CALL(*decoder_
, DoCommand(7, 1, &buffer_
[0]))
154 .WillOnce(Return(error::kNoError
));
156 EXPECT_CALL(*decoder_
, DoCommand(8, 0, &buffer_
[2]))
157 .WillOnce(Return(error::kNoError
));
158 EXPECT_CALL(*command_buffer_
, SetGetOffset(3));
160 scheduler_
->PutChanged();
163 TEST_F(GpuSchedulerTest
, SetsErrorCodeOnCommandBuffer
) {
164 CommandHeader
* header
= reinterpret_cast<CommandHeader
*>(&buffer_
[0]);
165 header
[0].command
= 7;
168 CommandBuffer::State state
;
170 state
.put_offset
= 1;
171 EXPECT_CALL(*command_buffer_
, GetLastState())
172 .WillRepeatedly(Return(state
));
174 EXPECT_CALL(*decoder_
, DoCommand(7, 0, &buffer_
[0]))
176 error::kUnknownCommand
));
177 EXPECT_CALL(*command_buffer_
, SetGetOffset(1));
179 EXPECT_CALL(*command_buffer_
, SetContextLostReason(_
));
180 EXPECT_CALL(*decoder_
, GetContextLostReason())
181 .WillOnce(Return(error::kUnknown
));
182 EXPECT_CALL(*command_buffer_
,
183 SetParseError(error::kUnknownCommand
));
185 scheduler_
->PutChanged();
188 TEST_F(GpuSchedulerTest
, ProcessCommandsDoesNothingAfterError
) {
189 CommandBuffer::State state
;
190 state
.error
= error::kGenericError
;
192 EXPECT_CALL(*command_buffer_
, GetLastState())
193 .WillRepeatedly(Return(state
));
195 scheduler_
->PutChanged();
198 TEST_F(GpuSchedulerTest
, CanGetAddressOfSharedMemory
) {
199 EXPECT_CALL(*command_buffer_
.get(), GetTransferBuffer(7))
200 .WillOnce(Return(shared_memory_buffer_
));
202 EXPECT_EQ(&buffer_
[0], scheduler_
->GetSharedMemoryBuffer(7)->memory());
205 ACTION_P2(SetPointee
, address
, value
) {
209 TEST_F(GpuSchedulerTest
, CanGetSizeOfSharedMemory
) {
210 EXPECT_CALL(*command_buffer_
.get(), GetTransferBuffer(7))
211 .WillOnce(Return(shared_memory_buffer_
));
213 EXPECT_EQ(kRingBufferSize
, scheduler_
->GetSharedMemoryBuffer(7)->size());
216 TEST_F(GpuSchedulerTest
, SetTokenForwardsToCommandBuffer
) {
217 EXPECT_CALL(*command_buffer_
, SetToken(7));
218 scheduler_
->set_token(7);