Handle account removal correctly on all platforms.
[chromium-blink-merge.git] / gpu / command_buffer / client / transfer_buffer_unittest.cc
blobcb8558fe4f34f00d9a75627b7914517ae3143584
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 virtual void SetUp() OVERRIDE;
40 virtual 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 transfer_buffer_.reset();
88 // GCC requires these declarations, but MSVC requires they not be present
89 #ifndef _MSC_VER
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;
95 #endif
97 TEST_F(TransferBufferTest, Basic) {
98 Initialize(0);
99 EXPECT_TRUE(transfer_buffer_->HaveBuffer());
100 EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
101 EXPECT_EQ(
102 kTransferBufferSize - kStartingOffset,
103 transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
106 TEST_F(TransferBufferTest, Free) {
107 Initialize(0);
108 EXPECT_TRUE(transfer_buffer_->HaveBuffer());
109 EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
111 // Free buffer.
112 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
113 .Times(1)
114 .RetiresOnSaturation();
115 transfer_buffer_->Free();
116 // See it's freed.
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());
122 // Free buffer.
123 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
124 .Times(1)
125 .RetiresOnSaturation();
126 transfer_buffer_->Free();
127 // See it's freed.
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());
133 // Free buffer.
134 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
135 .Times(1)
136 .RetiresOnSaturation();
137 transfer_buffer_->Free();
138 // See it's freed.
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);
147 // Free buffer.
148 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
149 .Times(1)
150 .RetiresOnSaturation();
151 transfer_buffer_->Free();
152 // See it's freed.
153 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
154 // See that it gets reallocated.
155 transfer_buffer_->GetResultOffset();
156 EXPECT_TRUE(transfer_buffer_->HaveBuffer());
158 EXPECT_EQ(
159 kTransferBufferSize - kStartingOffset,
160 transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
162 // Test freeing twice.
163 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
164 .Times(1)
165 .RetiresOnSaturation();
166 transfer_buffer_->Free();
167 transfer_buffer_->Free();
170 TEST_F(TransferBufferTest, TooLargeAllocation) {
171 Initialize(0);
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, MemoryAlignmentAfterZeroAllocation) {
185 Initialize(32u);
186 void* ptr = transfer_buffer_->Alloc(0);
187 EXPECT_EQ((reinterpret_cast<uintptr_t>(ptr) & (kAlignment - 1)), 0u);
188 transfer_buffer_->FreePendingToken(ptr, static_cast<unsigned int>(-1));
189 // Check that the pointer is aligned on the following allocation.
190 ptr = transfer_buffer_->Alloc(4);
191 EXPECT_EQ((reinterpret_cast<uintptr_t>(ptr) & (kAlignment - 1)), 0u);
192 transfer_buffer_->FreePendingToken(ptr, 1);
195 TEST_F(TransferBufferTest, Flush) {
196 Initialize(16u);
197 unsigned int size_allocated = 0;
198 for (int i = 0; i < 8; ++i) {
199 void* ptr = transfer_buffer_->AllocUpTo(8u, &size_allocated);
200 ASSERT_TRUE(ptr != NULL);
201 EXPECT_EQ(8u, size_allocated);
202 if (i % 2) {
203 EXPECT_CALL(*command_buffer(), Flush(_))
204 .Times(1)
205 .RetiresOnSaturation();
207 transfer_buffer_->FreePendingToken(ptr, helper_->InsertToken());
209 for (int i = 0; i < 8; ++i) {
210 void* ptr = transfer_buffer_->Alloc(8u);
211 ASSERT_TRUE(ptr != NULL);
212 if (i % 2) {
213 EXPECT_CALL(*command_buffer(), Flush(_))
214 .Times(1)
215 .RetiresOnSaturation();
217 transfer_buffer_->FreePendingToken(ptr, helper_->InsertToken());
221 class MockClientCommandBufferCanFail : public MockClientCommandBufferMockFlush {
222 public:
223 MockClientCommandBufferCanFail() {
225 virtual ~MockClientCommandBufferCanFail() {
228 MOCK_METHOD2(CreateTransferBuffer,
229 scoped_refptr<Buffer>(size_t size, int32* id));
231 scoped_refptr<gpu::Buffer> RealCreateTransferBuffer(size_t size, int32* id) {
232 return MockCommandBufferBase::CreateTransferBuffer(size, id);
236 class TransferBufferExpandContractTest : public testing::Test {
237 protected:
238 static const int32 kNumCommandEntries = 400;
239 static const int32 kCommandBufferSizeBytes =
240 kNumCommandEntries * sizeof(CommandBufferEntry);
241 static const unsigned int kStartingOffset = 64;
242 static const unsigned int kAlignment = 4;
243 static const size_t kStartTransferBufferSize = 256;
244 static const size_t kMaxTransferBufferSize = 1024;
245 static const size_t kMinTransferBufferSize = 128;
247 TransferBufferExpandContractTest()
248 : transfer_buffer_id_(0) {
251 virtual void SetUp() OVERRIDE;
252 virtual void TearDown() OVERRIDE;
254 MockClientCommandBufferCanFail* command_buffer() const {
255 return command_buffer_.get();
258 scoped_ptr<MockClientCommandBufferCanFail> command_buffer_;
259 scoped_ptr<CommandBufferHelper> helper_;
260 scoped_ptr<TransferBuffer> transfer_buffer_;
261 int32 transfer_buffer_id_;
264 void TransferBufferExpandContractTest::SetUp() {
265 command_buffer_.reset(new StrictMock<MockClientCommandBufferCanFail>());
266 ASSERT_TRUE(command_buffer_->Initialize());
268 EXPECT_CALL(*command_buffer(),
269 CreateTransferBuffer(kCommandBufferSizeBytes, _))
270 .WillOnce(Invoke(
271 command_buffer(),
272 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
273 .RetiresOnSaturation();
275 helper_.reset(new CommandBufferHelper(command_buffer()));
276 ASSERT_TRUE(helper_->Initialize(kCommandBufferSizeBytes));
278 transfer_buffer_id_ = command_buffer()->GetNextFreeTransferBufferId();
280 EXPECT_CALL(*command_buffer(),
281 CreateTransferBuffer(kStartTransferBufferSize, _))
282 .WillOnce(Invoke(
283 command_buffer(),
284 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
285 .RetiresOnSaturation();
287 transfer_buffer_.reset(new TransferBuffer(helper_.get()));
288 ASSERT_TRUE(transfer_buffer_->Initialize(
289 kStartTransferBufferSize,
290 kStartingOffset,
291 kMinTransferBufferSize,
292 kMaxTransferBufferSize,
293 kAlignment,
294 0));
297 void TransferBufferExpandContractTest::TearDown() {
298 if (transfer_buffer_->HaveBuffer()) {
299 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
300 .Times(1)
301 .RetiresOnSaturation();
303 // For command buffer.
304 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
305 .Times(1)
306 .RetiresOnSaturation();
307 transfer_buffer_.reset();
310 // GCC requires these declarations, but MSVC requires they not be present
311 #ifndef _MSC_VER
312 const int32 TransferBufferExpandContractTest::kNumCommandEntries;
313 const int32 TransferBufferExpandContractTest::kCommandBufferSizeBytes;
314 const unsigned int TransferBufferExpandContractTest::kStartingOffset;
315 const unsigned int TransferBufferExpandContractTest::kAlignment;
316 const size_t TransferBufferExpandContractTest::kStartTransferBufferSize;
317 const size_t TransferBufferExpandContractTest::kMaxTransferBufferSize;
318 const size_t TransferBufferExpandContractTest::kMinTransferBufferSize;
319 #endif
321 TEST_F(TransferBufferExpandContractTest, Expand) {
322 // Check it starts at starting size.
323 EXPECT_EQ(
324 kStartTransferBufferSize - kStartingOffset,
325 transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
327 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
328 .Times(1)
329 .RetiresOnSaturation();
330 EXPECT_CALL(*command_buffer(),
331 CreateTransferBuffer(kStartTransferBufferSize * 2, _))
332 .WillOnce(Invoke(
333 command_buffer(),
334 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
335 .RetiresOnSaturation();
337 // Try next power of 2.
338 const size_t kSize1 = 512 - kStartingOffset;
339 unsigned int size_allocated = 0;
340 void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
341 ASSERT_TRUE(ptr != NULL);
342 EXPECT_EQ(kSize1, size_allocated);
343 EXPECT_EQ(kSize1, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
344 transfer_buffer_->FreePendingToken(ptr, 1);
346 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
347 .Times(1)
348 .RetiresOnSaturation();
349 EXPECT_CALL(*command_buffer(),
350 CreateTransferBuffer(kMaxTransferBufferSize, _))
351 .WillOnce(Invoke(
352 command_buffer(),
353 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
354 .RetiresOnSaturation();
356 // Try next power of 2.
357 const size_t kSize2 = 1024 - kStartingOffset;
358 ptr = transfer_buffer_->AllocUpTo(kSize2, &size_allocated);
359 ASSERT_TRUE(ptr != NULL);
360 EXPECT_EQ(kSize2, size_allocated);
361 EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
362 transfer_buffer_->FreePendingToken(ptr, 1);
364 // Try next one more. Should not go past max.
365 size_allocated = 0;
366 const size_t kSize3 = kSize2 + 1;
367 ptr = transfer_buffer_->AllocUpTo(kSize3, &size_allocated);
368 EXPECT_EQ(kSize2, size_allocated);
369 EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
370 transfer_buffer_->FreePendingToken(ptr, 1);
373 TEST_F(TransferBufferExpandContractTest, Contract) {
374 // Check it starts at starting size.
375 EXPECT_EQ(
376 kStartTransferBufferSize - kStartingOffset,
377 transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
379 // Free buffer.
380 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
381 .Times(1)
382 .RetiresOnSaturation();
383 transfer_buffer_->Free();
384 // See it's freed.
385 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
387 // Try to allocate again, fail first request
388 EXPECT_CALL(*command_buffer(),
389 CreateTransferBuffer(kStartTransferBufferSize, _))
390 .WillOnce(
391 DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>())))
392 .RetiresOnSaturation();
393 EXPECT_CALL(*command_buffer(),
394 CreateTransferBuffer(kMinTransferBufferSize, _))
395 .WillOnce(Invoke(
396 command_buffer(),
397 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
398 .RetiresOnSaturation();
400 const size_t kSize1 = 256 - kStartingOffset;
401 const size_t kSize2 = 128 - kStartingOffset;
402 unsigned int size_allocated = 0;
403 void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
404 ASSERT_TRUE(ptr != NULL);
405 EXPECT_EQ(kSize2, size_allocated);
406 EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
407 transfer_buffer_->FreePendingToken(ptr, 1);
409 // Free buffer.
410 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
411 .Times(1)
412 .RetiresOnSaturation();
413 transfer_buffer_->Free();
414 // See it's freed.
415 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
417 // Try to allocate again,
418 EXPECT_CALL(*command_buffer(),
419 CreateTransferBuffer(kMinTransferBufferSize, _))
420 .WillOnce(Invoke(
421 command_buffer(),
422 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
423 .RetiresOnSaturation();
425 ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
426 ASSERT_TRUE(ptr != NULL);
427 EXPECT_EQ(kSize2, size_allocated);
428 EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
429 transfer_buffer_->FreePendingToken(ptr, 1);
432 TEST_F(TransferBufferExpandContractTest, OutOfMemory) {
433 // Free buffer.
434 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
435 .Times(1)
436 .RetiresOnSaturation();
437 transfer_buffer_->Free();
438 // See it's freed.
439 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
441 // Try to allocate again, fail both requests.
442 EXPECT_CALL(*command_buffer(), CreateTransferBuffer(_, _))
443 .WillOnce(
444 DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>())))
445 .WillOnce(
446 DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>())))
447 .WillOnce(
448 DoAll(SetArgPointee<1>(-1), Return(scoped_refptr<gpu::Buffer>())))
449 .RetiresOnSaturation();
451 const size_t kSize1 = 512 - kStartingOffset;
452 unsigned int size_allocated = 0;
453 void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated);
454 ASSERT_TRUE(ptr == NULL);
455 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
458 TEST_F(TransferBufferExpandContractTest, ReallocsToDefault) {
459 // Free buffer.
460 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
461 .Times(1)
462 .RetiresOnSaturation();
463 transfer_buffer_->Free();
464 // See it's freed.
465 EXPECT_FALSE(transfer_buffer_->HaveBuffer());
467 // See that it gets reallocated.
468 EXPECT_CALL(*command_buffer(),
469 CreateTransferBuffer(kStartTransferBufferSize, _))
470 .WillOnce(Invoke(
471 command_buffer(),
472 &MockClientCommandBufferCanFail::RealCreateTransferBuffer))
473 .RetiresOnSaturation();
474 EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
475 EXPECT_TRUE(transfer_buffer_->HaveBuffer());
477 // Check it's the default size.
478 EXPECT_EQ(
479 kStartTransferBufferSize - kStartingOffset,
480 transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc());
483 } // namespace gpu