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 scheduler_
.reset(new gpu::GpuScheduler(command_buffer_
.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
));
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();
66 error::Error
GetError() {
67 return command_buffer_
->GetLastState().error
;
70 #if defined(OS_MACOSX)
71 base::mac::ScopedNSAutoreleasePool autorelease_pool_
;
73 base::MessageLoop message_loop
;
74 scoped_ptr
<MockCommandBuffer
> command_buffer_
;
75 scoped_refptr
<Buffer
> shared_memory_buffer_
;
77 scoped_ptr
<gles2::MockGLES2Decoder
> decoder_
;
78 scoped_ptr
<GpuScheduler
> scheduler_
;
81 TEST_F(GpuSchedulerTest
, SchedulerDoesNothingIfRingBufferIsEmpty
) {
82 CommandBuffer::State state
;
85 EXPECT_CALL(*command_buffer_
, GetLastState())
86 .WillRepeatedly(Return(state
));
88 EXPECT_CALL(*command_buffer_
, SetParseError(_
))
91 scheduler_
->PutChanged();
94 TEST_F(GpuSchedulerTest
, GetSetBuffer
) {
95 CommandBuffer::State state
;
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());
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
));
108 // Check the get offset was reset.
109 EXPECT_EQ(0, scheduler_
->GetGetOffset());
112 TEST_F(GpuSchedulerTest
, ProcessesOneCommand
) {
113 CommandHeader
* header
= reinterpret_cast<CommandHeader
*>(&buffer_
[0]);
114 header
[0].command
= 7;
118 CommandBuffer::State state
;
120 state
.put_offset
= 2;
121 EXPECT_CALL(*command_buffer_
, GetLastState())
122 .WillRepeatedly(Return(state
));
123 EXPECT_CALL(*command_buffer_
, SetGetOffset(2));
125 EXPECT_CALL(*decoder_
, DoCommand(7, 1, &buffer_
[0]))
126 .WillOnce(Return(error::kNoError
));
128 EXPECT_CALL(*command_buffer_
, SetParseError(_
))
131 scheduler_
->PutChanged();
134 TEST_F(GpuSchedulerTest
, ProcessesTwoCommands
) {
135 CommandHeader
* header
= reinterpret_cast<CommandHeader
*>(&buffer_
[0]);
136 header
[0].command
= 7;
139 header
[2].command
= 8;
142 CommandBuffer::State state
;
144 state
.put_offset
= 3;
145 EXPECT_CALL(*command_buffer_
, GetLastState())
146 .WillRepeatedly(Return(state
));
148 EXPECT_CALL(*decoder_
, DoCommand(7, 1, &buffer_
[0]))
149 .WillOnce(Return(error::kNoError
));
150 EXPECT_CALL(*command_buffer_
, SetGetOffset(2));
152 EXPECT_CALL(*decoder_
, DoCommand(8, 0, &buffer_
[2]))
153 .WillOnce(Return(error::kNoError
));
154 EXPECT_CALL(*command_buffer_
, SetGetOffset(3));
156 scheduler_
->PutChanged();
159 TEST_F(GpuSchedulerTest
, SetsErrorCodeOnCommandBuffer
) {
160 CommandHeader
* header
= reinterpret_cast<CommandHeader
*>(&buffer_
[0]);
161 header
[0].command
= 7;
164 CommandBuffer::State state
;
166 state
.put_offset
= 1;
167 EXPECT_CALL(*command_buffer_
, GetLastState())
168 .WillRepeatedly(Return(state
));
170 EXPECT_CALL(*decoder_
, DoCommand(7, 0, &buffer_
[0]))
172 error::kUnknownCommand
));
173 EXPECT_CALL(*command_buffer_
, SetGetOffset(1));
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
));
181 scheduler_
->PutChanged();
184 TEST_F(GpuSchedulerTest
, ProcessCommandsDoesNothingAfterError
) {
185 CommandBuffer::State state
;
186 state
.error
= error::kGenericError
;
188 EXPECT_CALL(*command_buffer_
, GetLastState())
189 .WillRepeatedly(Return(state
));
191 scheduler_
->PutChanged();
194 TEST_F(GpuSchedulerTest
, CanGetAddressOfSharedMemory
) {
195 EXPECT_CALL(*command_buffer_
.get(), GetTransferBuffer(7))
196 .WillOnce(Return(shared_memory_buffer_
));
198 EXPECT_EQ(&buffer_
[0], scheduler_
->GetSharedMemoryBuffer(7)->memory());
201 ACTION_P2(SetPointee
, address
, value
) {
205 TEST_F(GpuSchedulerTest
, CanGetSizeOfSharedMemory
) {
206 EXPECT_CALL(*command_buffer_
.get(), GetTransferBuffer(7))
207 .WillOnce(Return(shared_memory_buffer_
));
209 EXPECT_EQ(kRingBufferSize
, scheduler_
->GetSharedMemoryBuffer(7)->size());
212 TEST_F(GpuSchedulerTest
, SetTokenForwardsToCommandBuffer
) {
213 EXPECT_CALL(*command_buffer_
, SetToken(7));
214 scheduler_
->set_token(7);