Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / gpu / command_buffer / client / transfer_buffer_unittest.cc
blob1a2a4b07dd177c7155d61e84c463d77b3113dff5
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 "base/compiler_specific.h"
10 #include "gpu/command_buffer/client/client_test_helper.h"
11 #include "gpu/command_buffer/client/cmd_buffer_helper.h"
12 #include "gpu/command_buffer/common/command_buffer.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "testing/gmock/include/gmock/gmock.h"
16 using ::testing::_;
17 using ::testing::AtMost;
18 using ::testing::Invoke;
19 using ::testing::Return;
20 using ::testing::SetArgPointee;
21 using ::testing::StrictMock;
23 namespace gpu {
26 class TransferBufferTest : public testing::Test {
27 protected:
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;
35 TransferBufferTest()
36 : transfer_buffer_id_(0) {
39 void SetUp() override;
40 void TearDown() override;
42 virtual void Initialize(unsigned int size_to_flush) {
43 ASSERT_TRUE(transfer_buffer_->Initialize(
44 kTransferBufferSize,
45 kStartingOffset,
46 kTransferBufferSize,
47 kTransferBufferSize,
48 kAlignment,
49 size_to_flush));
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(_))
77 .Times(1)
78 .RetiresOnSaturation();
80 // For command buffer.
81 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
82 .Times(1)
83 .RetiresOnSaturation();
84 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AtMost(1));
85 EXPECT_CALL(*command_buffer(), Flush(_)).Times(AtMost(1));
86 transfer_buffer_.reset();
89 // GCC requires these declarations, but MSVC requires they not be present
90 #ifndef _MSC_VER
91 const int32 TransferBufferTest::kNumCommandEntries;
92 const int32 TransferBufferTest::kCommandBufferSizeBytes;
93 const unsigned int TransferBufferTest::kStartingOffset;
94 const unsigned int TransferBufferTest::kAlignment;
95 const size_t TransferBufferTest::kTransferBufferSize;
96 #endif
98 TEST_F(TransferBufferTest, Basic) {
99 Initialize(0);
100 EXPECT_TRUE(transfer_buffer_->HaveBuffer());
101 EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
102 EXPECT_EQ(
103 kTransferBufferSize - kStartingOffset,
104 transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
107 TEST_F(TransferBufferTest, Free) {
108 Initialize(0);
109 EXPECT_TRUE(transfer_buffer_->HaveBuffer());
110 EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
112 // Free buffer.
113 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
114 .Times(1)
115 .RetiresOnSaturation();
116 transfer_buffer_->Free();
117 // See it's freed.
118 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
119 // See that it gets reallocated.
120 EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
121 EXPECT_TRUE(transfer_buffer_->HaveBuffer());
123 // Free buffer.
124 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
125 .Times(1)
126 .RetiresOnSaturation();
127 transfer_buffer_->Free();
128 // See it's freed.
129 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
130 // See that it gets reallocated.
131 EXPECT_TRUE(transfer_buffer_->GetResultBuffer() != NULL);
132 EXPECT_TRUE(transfer_buffer_->HaveBuffer());
134 // Free buffer.
135 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
136 .Times(1)
137 .RetiresOnSaturation();
138 transfer_buffer_->Free();
139 // See it's freed.
140 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
141 // See that it gets reallocated.
142 unsigned int size = 0;
143 void* data = transfer_buffer_->AllocUpTo(1, &size);
144 EXPECT_TRUE(data != NULL);
145 EXPECT_TRUE(transfer_buffer_->HaveBuffer());
146 transfer_buffer_->FreePendingToken(data, 1);
148 // Free buffer.
149 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
150 .Times(1)
151 .RetiresOnSaturation();
152 transfer_buffer_->Free();
153 // See it's freed.
154 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
155 // See that it gets reallocated.
156 transfer_buffer_->GetResultOffset();
157 EXPECT_TRUE(transfer_buffer_->HaveBuffer());
159 EXPECT_EQ(
160 kTransferBufferSize - kStartingOffset,
161 transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
163 // Test freeing twice.
164 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
165 .Times(1)
166 .RetiresOnSaturation();
167 transfer_buffer_->Free();
168 transfer_buffer_->Free();
171 TEST_F(TransferBufferTest, TooLargeAllocation) {
172 Initialize(0);
173 // Check that we can't allocate large than max size.
174 void* ptr = transfer_buffer_->Alloc(kTransferBufferSize + 1);
175 EXPECT_TRUE(ptr == NULL);
176 // Check we if we try to allocate larger than max we get max.
177 unsigned int size_allocated = 0;
178 ptr = transfer_buffer_->AllocUpTo(
179 kTransferBufferSize + 1, &size_allocated);
180 ASSERT_TRUE(ptr != NULL);
181 EXPECT_EQ(kTransferBufferSize - kStartingOffset, size_allocated);
182 transfer_buffer_->FreePendingToken(ptr, 1);
185 TEST_F(TransferBufferTest, MemoryAlignmentAfterZeroAllocation) {
186 Initialize(32u);
187 void* ptr = transfer_buffer_->Alloc(0);
188 EXPECT_EQ((reinterpret_cast<uintptr_t>(ptr) & (kAlignment - 1)), 0u);
189 transfer_buffer_->FreePendingToken(ptr, static_cast<unsigned int>(-1));
190 // Check that the pointer is aligned on the following allocation.
191 ptr = transfer_buffer_->Alloc(4);
192 EXPECT_EQ((reinterpret_cast<uintptr_t>(ptr) & (kAlignment - 1)), 0u);
193 transfer_buffer_->FreePendingToken(ptr, 1);
196 TEST_F(TransferBufferTest, Flush) {
197 Initialize(16u);
198 unsigned int size_allocated = 0;
199 for (int i = 0; i < 8; ++i) {
200 void* ptr = transfer_buffer_->AllocUpTo(8u, &size_allocated);
201 ASSERT_TRUE(ptr != NULL);
202 EXPECT_EQ(8u, size_allocated);
203 if (i % 2) {
204 EXPECT_CALL(*command_buffer(), Flush(_))
205 .Times(1)
206 .RetiresOnSaturation();
208 transfer_buffer_->FreePendingToken(ptr, helper_->InsertToken());
210 for (int i = 0; i < 8; ++i) {
211 void* ptr = transfer_buffer_->Alloc(8u);
212 ASSERT_TRUE(ptr != NULL);
213 if (i % 2) {
214 EXPECT_CALL(*command_buffer(), Flush(_))
215 .Times(1)
216 .RetiresOnSaturation();
218 transfer_buffer_->FreePendingToken(ptr, helper_->InsertToken());
222 class MockClientCommandBufferCanFail : public MockClientCommandBufferMockFlush {
223 public:
224 MockClientCommandBufferCanFail() {
226 virtual ~MockClientCommandBufferCanFail() {
229 MOCK_METHOD2(CreateTransferBuffer,
230 scoped_refptr<Buffer>(size_t size, int32* id));
232 scoped_refptr<gpu::Buffer> RealCreateTransferBuffer(size_t size, int32* id) {
233 return MockCommandBufferBase::CreateTransferBuffer(size, id);
237 class TransferBufferExpandContractTest : public testing::Test {
238 protected:
239 static const int32 kNumCommandEntries = 400;
240 static const int32 kCommandBufferSizeBytes =
241 kNumCommandEntries * sizeof(CommandBufferEntry);
242 static const unsigned int kStartingOffset = 64;
243 static const unsigned int kAlignment = 4;
244 static const size_t kStartTransferBufferSize = 256;
245 static const size_t kMaxTransferBufferSize = 1024;
246 static const size_t kMinTransferBufferSize = 128;
248 TransferBufferExpandContractTest()
249 : transfer_buffer_id_(0) {
252 void SetUp() override;
253 void TearDown() override;
255 MockClientCommandBufferCanFail* command_buffer() const {
256 return command_buffer_.get();
259 scoped_ptr<MockClientCommandBufferCanFail> command_buffer_;
260 scoped_ptr<CommandBufferHelper> helper_;
261 scoped_ptr<TransferBuffer> transfer_buffer_;
262 int32 transfer_buffer_id_;
265 void TransferBufferExpandContractTest::SetUp() {
266 command_buffer_.reset(new StrictMock<MockClientCommandBufferCanFail>());
267 ASSERT_TRUE(command_buffer_->Initialize());
269 EXPECT_CALL(*command_buffer(),
270 CreateTransferBuffer(kCommandBufferSizeBytes, _))
271 .WillOnce(Invoke(
272 command_buffer(),
273 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
274 .RetiresOnSaturation();
276 helper_.reset(new CommandBufferHelper(command_buffer()));
277 ASSERT_TRUE(helper_->Initialize(kCommandBufferSizeBytes));
279 transfer_buffer_id_ = command_buffer()->GetNextFreeTransferBufferId();
281 EXPECT_CALL(*command_buffer(),
282 CreateTransferBuffer(kStartTransferBufferSize, _))
283 .WillOnce(Invoke(
284 command_buffer(),
285 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
286 .RetiresOnSaturation();
288 transfer_buffer_.reset(new TransferBuffer(helper_.get()));
289 ASSERT_TRUE(transfer_buffer_->Initialize(
290 kStartTransferBufferSize,
291 kStartingOffset,
292 kMinTransferBufferSize,
293 kMaxTransferBufferSize,
294 kAlignment,
295 0));
298 void TransferBufferExpandContractTest::TearDown() {
299 if (transfer_buffer_->HaveBuffer()) {
300 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
301 .Times(1)
302 .RetiresOnSaturation();
304 // For command buffer.
305 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
306 .Times(1)
307 .RetiresOnSaturation();
308 transfer_buffer_.reset();
311 // GCC requires these declarations, but MSVC requires they not be present
312 #ifndef _MSC_VER
313 const int32 TransferBufferExpandContractTest::kNumCommandEntries;
314 const int32 TransferBufferExpandContractTest::kCommandBufferSizeBytes;
315 const unsigned int TransferBufferExpandContractTest::kStartingOffset;
316 const unsigned int TransferBufferExpandContractTest::kAlignment;
317 const size_t TransferBufferExpandContractTest::kStartTransferBufferSize;
318 const size_t TransferBufferExpandContractTest::kMaxTransferBufferSize;
319 const size_t TransferBufferExpandContractTest::kMinTransferBufferSize;
320 #endif
322 TEST_F(TransferBufferExpandContractTest, Expand) {
323 // Check it starts at starting size.
324 EXPECT_EQ(
325 kStartTransferBufferSize - kStartingOffset,
326 transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
328 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
329 .Times(1)
330 .RetiresOnSaturation();
331 EXPECT_CALL(*command_buffer(),
332 CreateTransferBuffer(kStartTransferBufferSize * 2, _))
333 .WillOnce(Invoke(
334 command_buffer(),
335 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
336 .RetiresOnSaturation();
338 // Try next power of 2.
339 const size_t kSize1 = 512 - kStartingOffset;
340 unsigned int size_allocated = 0;
341 void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
342 ASSERT_TRUE(ptr != NULL);
343 EXPECT_EQ(kSize1, size_allocated);
344 EXPECT_EQ(kSize1, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
345 transfer_buffer_->FreePendingToken(ptr, 1);
347 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
348 .Times(1)
349 .RetiresOnSaturation();
350 EXPECT_CALL(*command_buffer(),
351 CreateTransferBuffer(kMaxTransferBufferSize, _))
352 .WillOnce(Invoke(
353 command_buffer(),
354 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
355 .RetiresOnSaturation();
357 // Try next power of 2.
358 const size_t kSize2 = 1024 - kStartingOffset;
359 ptr = transfer_buffer_->AllocUpTo(kSize2, &size_allocated);
360 ASSERT_TRUE(ptr != NULL);
361 EXPECT_EQ(kSize2, size_allocated);
362 EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
363 transfer_buffer_->FreePendingToken(ptr, 1);
365 // Try next one more. Should not go past max.
366 size_allocated = 0;
367 const size_t kSize3 = kSize2 + 1;
368 ptr = transfer_buffer_->AllocUpTo(kSize3, &size_allocated);
369 EXPECT_EQ(kSize2, size_allocated);
370 EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
371 transfer_buffer_->FreePendingToken(ptr, 1);
374 TEST_F(TransferBufferExpandContractTest, Contract) {
375 // Check it starts at starting size.
376 EXPECT_EQ(
377 kStartTransferBufferSize - kStartingOffset,
378 transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
380 // Free buffer.
381 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
382 .Times(1)
383 .RetiresOnSaturation();
384 transfer_buffer_->Free();
385 // See it's freed.
386 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
388 // Try to allocate again, fail first request
389 EXPECT_CALL(*command_buffer(),
390 CreateTransferBuffer(kStartTransferBufferSize, _))
391 .WillOnce(
392 DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>())))
393 .RetiresOnSaturation();
394 EXPECT_CALL(*command_buffer(),
395 CreateTransferBuffer(kMinTransferBufferSize, _))
396 .WillOnce(Invoke(
397 command_buffer(),
398 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
399 .RetiresOnSaturation();
401 const size_t kSize1 = 256 - kStartingOffset;
402 const size_t kSize2 = 128 - kStartingOffset;
403 unsigned int size_allocated = 0;
404 void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
405 ASSERT_TRUE(ptr != NULL);
406 EXPECT_EQ(kSize2, size_allocated);
407 EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
408 transfer_buffer_->FreePendingToken(ptr, 1);
410 // Free buffer.
411 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
412 .Times(1)
413 .RetiresOnSaturation();
414 transfer_buffer_->Free();
415 // See it's freed.
416 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
418 // Try to allocate again,
419 EXPECT_CALL(*command_buffer(),
420 CreateTransferBuffer(kMinTransferBufferSize, _))
421 .WillOnce(Invoke(
422 command_buffer(),
423 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
424 .RetiresOnSaturation();
426 ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
427 ASSERT_TRUE(ptr != NULL);
428 EXPECT_EQ(kSize2, size_allocated);
429 EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
430 transfer_buffer_->FreePendingToken(ptr, 1);
433 TEST_F(TransferBufferExpandContractTest, OutOfMemory) {
434 // Free buffer.
435 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
436 .Times(1)
437 .RetiresOnSaturation();
438 transfer_buffer_->Free();
439 // See it's freed.
440 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
442 // Try to allocate again, fail both requests.
443 EXPECT_CALL(*command_buffer(), CreateTransferBuffer(_, _))
444 .WillOnce(
445 DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>())))
446 .WillOnce(
447 DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>())))
448 .WillOnce(
449 DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>())))
450 .RetiresOnSaturation();
452 const size_t kSize1 = 512 - kStartingOffset;
453 unsigned int size_allocated = 0;
454 void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
455 ASSERT_TRUE(ptr == NULL);
456 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
459 TEST_F(TransferBufferExpandContractTest, ReallocsToDefault) {
460 // Free buffer.
461 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
462 .Times(1)
463 .RetiresOnSaturation();
464 transfer_buffer_->Free();
465 // See it's freed.
466 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
468 // See that it gets reallocated.
469 EXPECT_CALL(*command_buffer(),
470 CreateTransferBuffer(kStartTransferBufferSize, _))
471 .WillOnce(Invoke(
472 command_buffer(),
473 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
474 .RetiresOnSaturation();
475 EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
476 EXPECT_TRUE(transfer_buffer_->HaveBuffer());
478 // Check it's the default size.
479 EXPECT_EQ(
480 kStartTransferBufferSize - kStartingOffset,
481 transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
484 } // namespace gpu