1 // Copyright (c) 2012 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 // Tests for the Command Buffer Helper.
7 #include "gpu/command_buffer/client/transfer_buffer.h"
9 #include "gpu/command_buffer/client/client_test_helper.h"
10 #include "gpu/command_buffer/client/cmd_buffer_helper.h"
11 #include "gpu/command_buffer/common/command_buffer.h"
12 #include "gpu/command_buffer/common/compiler_specific.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "testing/gmock/include/gmock/gmock.h"
17 using ::testing::AtMost
;
18 using ::testing::Invoke
;
19 using ::testing::Return
;
20 using ::testing::SetArgPointee
;
21 using ::testing::StrictMock
;
26 class TransferBufferTest
: public testing::Test
{
28 static const int32 kNumCommandEntries
= 400;
29 static const int32 kCommandBufferSizeBytes
=
30 kNumCommandEntries
* sizeof(CommandBufferEntry
);
31 static const unsigned int kStartingOffset
= 64;
32 static const unsigned int kAlignment
= 4;
33 static const size_t kTransferBufferSize
= 256;
36 : transfer_buffer_id_(0) {
39 virtual void SetUp() OVERRIDE
;
40 virtual void TearDown() OVERRIDE
;
42 virtual void Initialize(unsigned int size_to_flush
) {
43 ASSERT_TRUE(transfer_buffer_
->Initialize(
52 MockClientCommandBufferMockFlush
* command_buffer() const {
53 return command_buffer_
.get();
56 scoped_ptr
<MockClientCommandBufferMockFlush
> command_buffer_
;
57 scoped_ptr
<CommandBufferHelper
> helper_
;
58 scoped_ptr
<TransferBuffer
> transfer_buffer_
;
59 int32 transfer_buffer_id_
;
62 void TransferBufferTest::SetUp() {
63 command_buffer_
.reset(new StrictMock
<MockClientCommandBufferMockFlush
>());
64 ASSERT_TRUE(command_buffer_
->Initialize());
66 helper_
.reset(new CommandBufferHelper(command_buffer()));
67 ASSERT_TRUE(helper_
->Initialize(kCommandBufferSizeBytes
));
69 transfer_buffer_id_
= command_buffer()->GetNextFreeTransferBufferId();
71 transfer_buffer_
.reset(new TransferBuffer(helper_
.get()));
74 void TransferBufferTest::TearDown() {
75 if (transfer_buffer_
->HaveBuffer()) {
76 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
78 .RetiresOnSaturation();
80 // For command buffer.
81 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
83 .RetiresOnSaturation();
84 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AtMost(1));
85 transfer_buffer_
.reset();
88 // GCC requires these declarations, but MSVC requires they not be present
90 const int32
TransferBufferTest::kNumCommandEntries
;
91 const int32
TransferBufferTest::kCommandBufferSizeBytes
;
92 const unsigned int TransferBufferTest::kStartingOffset
;
93 const unsigned int TransferBufferTest::kAlignment
;
94 const size_t TransferBufferTest::kTransferBufferSize
;
97 TEST_F(TransferBufferTest
, Basic
) {
99 EXPECT_TRUE(transfer_buffer_
->HaveBuffer());
100 EXPECT_EQ(transfer_buffer_id_
, transfer_buffer_
->GetShmId());
102 kTransferBufferSize
- kStartingOffset
,
103 transfer_buffer_
->GetCurrentMaxAllocationWithoutRealloc());
106 TEST_F(TransferBufferTest
, Free
) {
108 EXPECT_TRUE(transfer_buffer_
->HaveBuffer());
109 EXPECT_EQ(transfer_buffer_id_
, transfer_buffer_
->GetShmId());
112 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
114 .RetiresOnSaturation();
115 transfer_buffer_
->Free();
117 EXPECT_FALSE(transfer_buffer_
->HaveBuffer());
118 // See that it gets reallocated.
119 EXPECT_EQ(transfer_buffer_id_
, transfer_buffer_
->GetShmId());
120 EXPECT_TRUE(transfer_buffer_
->HaveBuffer());
123 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
125 .RetiresOnSaturation();
126 transfer_buffer_
->Free();
128 EXPECT_FALSE(transfer_buffer_
->HaveBuffer());
129 // See that it gets reallocated.
130 EXPECT_TRUE(transfer_buffer_
->GetResultBuffer() != NULL
);
131 EXPECT_TRUE(transfer_buffer_
->HaveBuffer());
134 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
136 .RetiresOnSaturation();
137 transfer_buffer_
->Free();
139 EXPECT_FALSE(transfer_buffer_
->HaveBuffer());
140 // See that it gets reallocated.
141 unsigned int size
= 0;
142 void* data
= transfer_buffer_
->AllocUpTo(1, &size
);
143 EXPECT_TRUE(data
!= NULL
);
144 EXPECT_TRUE(transfer_buffer_
->HaveBuffer());
145 transfer_buffer_
->FreePendingToken(data
, 1);
148 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
150 .RetiresOnSaturation();
151 transfer_buffer_
->Free();
153 EXPECT_FALSE(transfer_buffer_
->HaveBuffer());
154 // See that it gets reallocated.
155 transfer_buffer_
->GetResultOffset();
156 EXPECT_TRUE(transfer_buffer_
->HaveBuffer());
159 kTransferBufferSize
- kStartingOffset
,
160 transfer_buffer_
->GetCurrentMaxAllocationWithoutRealloc());
162 // Test freeing twice.
163 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
165 .RetiresOnSaturation();
166 transfer_buffer_
->Free();
167 transfer_buffer_
->Free();
170 TEST_F(TransferBufferTest
, TooLargeAllocation
) {
172 // Check that we can't allocate large than max size.
173 void* ptr
= transfer_buffer_
->Alloc(kTransferBufferSize
+ 1);
174 EXPECT_TRUE(ptr
== NULL
);
175 // Check we if we try to allocate larger than max we get max.
176 unsigned int size_allocated
= 0;
177 ptr
= transfer_buffer_
->AllocUpTo(
178 kTransferBufferSize
+ 1, &size_allocated
);
179 ASSERT_TRUE(ptr
!= NULL
);
180 EXPECT_EQ(kTransferBufferSize
- kStartingOffset
, size_allocated
);
181 transfer_buffer_
->FreePendingToken(ptr
, 1);
184 TEST_F(TransferBufferTest
, Flush
) {
186 unsigned int size_allocated
= 0;
187 for (int i
= 0; i
< 8; ++i
) {
188 void* ptr
= transfer_buffer_
->AllocUpTo(8u, &size_allocated
);
189 ASSERT_TRUE(ptr
!= NULL
);
190 EXPECT_EQ(8u, size_allocated
);
192 EXPECT_CALL(*command_buffer(), Flush(_
))
194 .RetiresOnSaturation();
196 transfer_buffer_
->FreePendingToken(ptr
, helper_
->InsertToken());
198 for (int i
= 0; i
< 8; ++i
) {
199 void* ptr
= transfer_buffer_
->Alloc(8u);
200 ASSERT_TRUE(ptr
!= NULL
);
202 EXPECT_CALL(*command_buffer(), Flush(_
))
204 .RetiresOnSaturation();
206 transfer_buffer_
->FreePendingToken(ptr
, helper_
->InsertToken());
210 class MockClientCommandBufferCanFail
: public MockClientCommandBufferMockFlush
{
212 MockClientCommandBufferCanFail() {
214 virtual ~MockClientCommandBufferCanFail() {
217 MOCK_METHOD2(CreateTransferBuffer
, Buffer(size_t size
, int32
* id
));
219 Buffer
RealCreateTransferBuffer(size_t size
, int32
* id
) {
220 return MockCommandBufferBase::CreateTransferBuffer(size
, id
);
224 class TransferBufferExpandContractTest
: public testing::Test
{
226 static const int32 kNumCommandEntries
= 400;
227 static const int32 kCommandBufferSizeBytes
=
228 kNumCommandEntries
* sizeof(CommandBufferEntry
);
229 static const unsigned int kStartingOffset
= 64;
230 static const unsigned int kAlignment
= 4;
231 static const size_t kStartTransferBufferSize
= 256;
232 static const size_t kMaxTransferBufferSize
= 1024;
233 static const size_t kMinTransferBufferSize
= 128;
235 TransferBufferExpandContractTest()
236 : transfer_buffer_id_(0) {
239 virtual void SetUp() OVERRIDE
;
240 virtual void TearDown() OVERRIDE
;
242 MockClientCommandBufferCanFail
* command_buffer() const {
243 return command_buffer_
.get();
246 scoped_ptr
<MockClientCommandBufferCanFail
> command_buffer_
;
247 scoped_ptr
<CommandBufferHelper
> helper_
;
248 scoped_ptr
<TransferBuffer
> transfer_buffer_
;
249 int32 transfer_buffer_id_
;
252 void TransferBufferExpandContractTest::SetUp() {
253 command_buffer_
.reset(new StrictMock
<MockClientCommandBufferCanFail
>());
254 ASSERT_TRUE(command_buffer_
->Initialize());
256 EXPECT_CALL(*command_buffer(),
257 CreateTransferBuffer(kCommandBufferSizeBytes
, _
))
260 &MockClientCommandBufferCanFail::RealCreateTransferBuffer
))
261 .RetiresOnSaturation();
263 helper_
.reset(new CommandBufferHelper(command_buffer()));
264 ASSERT_TRUE(helper_
->Initialize(kCommandBufferSizeBytes
));
266 transfer_buffer_id_
= command_buffer()->GetNextFreeTransferBufferId();
268 EXPECT_CALL(*command_buffer(),
269 CreateTransferBuffer(kStartTransferBufferSize
, _
))
272 &MockClientCommandBufferCanFail::RealCreateTransferBuffer
))
273 .RetiresOnSaturation();
275 transfer_buffer_
.reset(new TransferBuffer(helper_
.get()));
276 ASSERT_TRUE(transfer_buffer_
->Initialize(
277 kStartTransferBufferSize
,
279 kMinTransferBufferSize
,
280 kMaxTransferBufferSize
,
285 void TransferBufferExpandContractTest::TearDown() {
286 if (transfer_buffer_
->HaveBuffer()) {
287 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
289 .RetiresOnSaturation();
291 // For command buffer.
292 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
294 .RetiresOnSaturation();
295 transfer_buffer_
.reset();
298 // GCC requires these declarations, but MSVC requires they not be present
300 const int32
TransferBufferExpandContractTest::kNumCommandEntries
;
301 const int32
TransferBufferExpandContractTest::kCommandBufferSizeBytes
;
302 const unsigned int TransferBufferExpandContractTest::kStartingOffset
;
303 const unsigned int TransferBufferExpandContractTest::kAlignment
;
304 const size_t TransferBufferExpandContractTest::kStartTransferBufferSize
;
305 const size_t TransferBufferExpandContractTest::kMaxTransferBufferSize
;
306 const size_t TransferBufferExpandContractTest::kMinTransferBufferSize
;
309 TEST_F(TransferBufferExpandContractTest
, Expand
) {
310 // Check it starts at starting size.
312 kStartTransferBufferSize
- kStartingOffset
,
313 transfer_buffer_
->GetCurrentMaxAllocationWithoutRealloc());
315 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
317 .RetiresOnSaturation();
318 EXPECT_CALL(*command_buffer(),
319 CreateTransferBuffer(kStartTransferBufferSize
* 2, _
))
322 &MockClientCommandBufferCanFail::RealCreateTransferBuffer
))
323 .RetiresOnSaturation();
325 // Try next power of 2.
326 const size_t kSize1
= 512 - kStartingOffset
;
327 unsigned int size_allocated
= 0;
328 void* ptr
= transfer_buffer_
->AllocUpTo(kSize1
, &size_allocated
);
329 ASSERT_TRUE(ptr
!= NULL
);
330 EXPECT_EQ(kSize1
, size_allocated
);
331 EXPECT_EQ(kSize1
, transfer_buffer_
->GetCurrentMaxAllocationWithoutRealloc());
332 transfer_buffer_
->FreePendingToken(ptr
, 1);
334 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
336 .RetiresOnSaturation();
337 EXPECT_CALL(*command_buffer(),
338 CreateTransferBuffer(kMaxTransferBufferSize
, _
))
341 &MockClientCommandBufferCanFail::RealCreateTransferBuffer
))
342 .RetiresOnSaturation();
344 // Try next power of 2.
345 const size_t kSize2
= 1024 - kStartingOffset
;
346 ptr
= transfer_buffer_
->AllocUpTo(kSize2
, &size_allocated
);
347 ASSERT_TRUE(ptr
!= NULL
);
348 EXPECT_EQ(kSize2
, size_allocated
);
349 EXPECT_EQ(kSize2
, transfer_buffer_
->GetCurrentMaxAllocationWithoutRealloc());
350 transfer_buffer_
->FreePendingToken(ptr
, 1);
352 // Try next one more. Should not go past max.
354 const size_t kSize3
= kSize2
+ 1;
355 ptr
= transfer_buffer_
->AllocUpTo(kSize3
, &size_allocated
);
356 EXPECT_EQ(kSize2
, size_allocated
);
357 EXPECT_EQ(kSize2
, transfer_buffer_
->GetCurrentMaxAllocationWithoutRealloc());
358 transfer_buffer_
->FreePendingToken(ptr
, 1);
361 TEST_F(TransferBufferExpandContractTest
, Contract
) {
362 // Check it starts at starting size.
364 kStartTransferBufferSize
- kStartingOffset
,
365 transfer_buffer_
->GetCurrentMaxAllocationWithoutRealloc());
368 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
370 .RetiresOnSaturation();
371 transfer_buffer_
->Free();
373 EXPECT_FALSE(transfer_buffer_
->HaveBuffer());
375 // Try to allocate again, fail first request
376 EXPECT_CALL(*command_buffer(),
377 CreateTransferBuffer(kStartTransferBufferSize
, _
))
378 .WillOnce(DoAll(SetArgPointee
<1>(-1), Return(Buffer())))
379 .RetiresOnSaturation();
380 EXPECT_CALL(*command_buffer(),
381 CreateTransferBuffer(kMinTransferBufferSize
, _
))
384 &MockClientCommandBufferCanFail::RealCreateTransferBuffer
))
385 .RetiresOnSaturation();
387 const size_t kSize1
= 256 - kStartingOffset
;
388 const size_t kSize2
= 128 - kStartingOffset
;
389 unsigned int size_allocated
= 0;
390 void* ptr
= transfer_buffer_
->AllocUpTo(kSize1
, &size_allocated
);
391 ASSERT_TRUE(ptr
!= NULL
);
392 EXPECT_EQ(kSize2
, size_allocated
);
393 EXPECT_EQ(kSize2
, transfer_buffer_
->GetCurrentMaxAllocationWithoutRealloc());
394 transfer_buffer_
->FreePendingToken(ptr
, 1);
397 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
399 .RetiresOnSaturation();
400 transfer_buffer_
->Free();
402 EXPECT_FALSE(transfer_buffer_
->HaveBuffer());
404 // Try to allocate again,
405 EXPECT_CALL(*command_buffer(),
406 CreateTransferBuffer(kMinTransferBufferSize
, _
))
409 &MockClientCommandBufferCanFail::RealCreateTransferBuffer
))
410 .RetiresOnSaturation();
412 ptr
= transfer_buffer_
->AllocUpTo(kSize1
, &size_allocated
);
413 ASSERT_TRUE(ptr
!= NULL
);
414 EXPECT_EQ(kSize2
, size_allocated
);
415 EXPECT_EQ(kSize2
, transfer_buffer_
->GetCurrentMaxAllocationWithoutRealloc());
416 transfer_buffer_
->FreePendingToken(ptr
, 1);
419 TEST_F(TransferBufferExpandContractTest
, OutOfMemory
) {
421 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
423 .RetiresOnSaturation();
424 transfer_buffer_
->Free();
426 EXPECT_FALSE(transfer_buffer_
->HaveBuffer());
428 // Try to allocate again, fail both requests.
429 EXPECT_CALL(*command_buffer(), CreateTransferBuffer(_
, _
))
430 .WillOnce(DoAll(SetArgPointee
<1>(-1), Return(Buffer())))
431 .WillOnce(DoAll(SetArgPointee
<1>(-1), Return(Buffer())))
432 .WillOnce(DoAll(SetArgPointee
<1>(-1), Return(Buffer())))
433 .RetiresOnSaturation();
435 const size_t kSize1
= 512 - kStartingOffset
;
436 unsigned int size_allocated
= 0;
437 void* ptr
= transfer_buffer_
->AllocUpTo(kSize1
, &size_allocated
);
438 ASSERT_TRUE(ptr
== NULL
);
439 EXPECT_FALSE(transfer_buffer_
->HaveBuffer());
442 TEST_F(TransferBufferExpandContractTest
, ReallocsToDefault
) {
444 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
446 .RetiresOnSaturation();
447 transfer_buffer_
->Free();
449 EXPECT_FALSE(transfer_buffer_
->HaveBuffer());
451 // See that it gets reallocated.
452 EXPECT_CALL(*command_buffer(),
453 CreateTransferBuffer(kStartTransferBufferSize
, _
))
456 &MockClientCommandBufferCanFail::RealCreateTransferBuffer
))
457 .RetiresOnSaturation();
458 EXPECT_EQ(transfer_buffer_id_
, transfer_buffer_
->GetShmId());
459 EXPECT_TRUE(transfer_buffer_
->HaveBuffer());
461 // Check it's the default size.
463 kStartTransferBufferSize
- kStartingOffset
,
464 transfer_buffer_
->GetCurrentMaxAllocationWithoutRealloc());