GPU workaround to simulate Out of Memory errors with large textures
[chromium-blink-merge.git] / cc / quads / list_container_unittest.cc
blob68e60610ea2938f81da1af412f827e51942afe6c
1 // Copyright 2014 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 "cc/quads/list_container.h"
7 #include <vector>
8 #include "cc/quads/draw_quad.h"
9 #include "cc/quads/largest_draw_quad.h"
10 #include "cc/quads/render_pass_draw_quad.h"
11 #include "cc/quads/shared_quad_state.h"
12 #include "cc/quads/stream_video_draw_quad.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace cc {
17 namespace {
19 int kMagicNumberToUseForDrawQuadOne = 42;
20 int kMagicNumberToUseForDrawQuadTwo = 314;
22 bool isConstSharedQuadStatePointer(const SharedQuadState* ptr) {
23 return true;
26 bool isConstSharedQuadStatePointer(SharedQuadState* ptr) {
27 return false;
30 class SimpleDrawQuad : public DrawQuad {
31 public:
32 ~SimpleDrawQuad() override {}
33 void IterateResources(const ResourceIteratorCallback& callback) override {}
35 void set_value(int val) { value = val; }
36 int get_value() { return value; }
37 void ExtendValue(base::trace_event::TracedValue* value) const override {}
39 private:
40 int value;
43 class SimpleDrawQuadConstructMagicNumberOne : public SimpleDrawQuad {
44 public:
45 SimpleDrawQuadConstructMagicNumberOne() : SimpleDrawQuad() {
46 set_value(kMagicNumberToUseForDrawQuadOne);
50 class SimpleDrawQuadConstructMagicNumberTwo : public SimpleDrawQuad {
51 public:
52 SimpleDrawQuadConstructMagicNumberTwo() : SimpleDrawQuad() {
53 set_value(kMagicNumberToUseForDrawQuadTwo);
57 class MockDrawQuad : public SimpleDrawQuadConstructMagicNumberOne {
58 public:
59 ~MockDrawQuad() override { Destruct(); }
60 MOCK_METHOD0(Destruct, void());
63 class MockDrawQuadSubclass : public MockDrawQuad {
64 public:
65 MockDrawQuadSubclass() { set_value(kMagicNumberToUseForDrawQuadTwo); }
68 const size_t kLargestQuadSize =
69 std::max(LargestDrawQuadSize(), sizeof(MockDrawQuadSubclass));
71 TEST(ListContainerTest, ConstructorCalledInAllocateAndConstruct) {
72 ListContainer<DrawQuad> list(kLargestQuadSize);
74 size_t size = 2;
75 SimpleDrawQuadConstructMagicNumberOne* dq_1 =
76 list.AllocateAndConstruct<SimpleDrawQuadConstructMagicNumberOne>();
77 SimpleDrawQuadConstructMagicNumberTwo* dq_2 =
78 list.AllocateAndConstruct<SimpleDrawQuadConstructMagicNumberTwo>();
80 EXPECT_EQ(size, list.size());
81 EXPECT_EQ(dq_1, list.front());
82 EXPECT_EQ(dq_2, list.back());
84 EXPECT_EQ(kMagicNumberToUseForDrawQuadOne, dq_1->get_value());
85 EXPECT_EQ(kMagicNumberToUseForDrawQuadTwo, dq_2->get_value());
88 TEST(ListContainerTest, DestructorCalled) {
89 ListContainer<DrawQuad> list(kLargestQuadSize);
91 size_t size = 1;
92 MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
94 EXPECT_CALL(*dq_1, Destruct());
95 EXPECT_EQ(size, list.size());
96 EXPECT_EQ(dq_1, list.front());
99 TEST(ListContainerTest, DestructorCalledOnceWhenClear) {
100 ListContainer<DrawQuad> list(kLargestQuadSize);
101 size_t size = 1;
102 MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
104 EXPECT_EQ(size, list.size());
105 EXPECT_EQ(dq_1, list.front());
107 // Make sure destructor is called once during clear, and won't be called
108 // again.
109 testing::MockFunction<void()> separator;
111 testing::InSequence s;
112 EXPECT_CALL(*dq_1, Destruct());
113 EXPECT_CALL(separator, Call());
114 EXPECT_CALL(*dq_1, Destruct()).Times(0);
117 list.clear();
118 separator.Call();
121 TEST(ListContainerTest, ReplaceExistingElement) {
122 ListContainer<DrawQuad> list(kLargestQuadSize);
123 size_t size = 1;
124 MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
126 EXPECT_EQ(size, list.size());
127 EXPECT_EQ(dq_1, list.front());
129 // Make sure destructor is called once during clear, and won't be called
130 // again.
131 testing::MockFunction<void()> separator;
133 testing::InSequence s;
134 EXPECT_CALL(*dq_1, Destruct());
135 EXPECT_CALL(separator, Call());
136 EXPECT_CALL(*dq_1, Destruct()).Times(0);
139 list.ReplaceExistingElement<MockDrawQuadSubclass>(list.begin());
140 EXPECT_EQ(kMagicNumberToUseForDrawQuadTwo, dq_1->get_value());
141 separator.Call();
143 EXPECT_CALL(*dq_1, Destruct());
144 list.clear();
147 TEST(ListContainerTest, DestructorCalledOnceWhenErase) {
148 ListContainer<DrawQuad> list(kLargestQuadSize);
149 size_t size = 1;
150 MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
152 EXPECT_EQ(size, list.size());
153 EXPECT_EQ(dq_1, list.front());
155 // Make sure destructor is called once during clear, and won't be called
156 // again.
157 testing::MockFunction<void()> separator;
159 testing::InSequence s;
160 EXPECT_CALL(*dq_1, Destruct());
161 EXPECT_CALL(separator, Call());
162 EXPECT_CALL(*dq_1, Destruct()).Times(0);
165 list.EraseAndInvalidateAllPointers(list.begin());
166 separator.Call();
169 TEST(ListContainerTest, SimpleIndexAccessSharedQuadState) {
170 ListContainer<SharedQuadState> list;
172 size_t size = 3;
173 SharedQuadState* sqs_1 = list.AllocateAndConstruct<SharedQuadState>();
174 SharedQuadState* sqs_2 = list.AllocateAndConstruct<SharedQuadState>();
175 SharedQuadState* sqs_3 = list.AllocateAndConstruct<SharedQuadState>();
177 EXPECT_EQ(size, list.size());
178 EXPECT_EQ(sqs_1, list.front());
179 EXPECT_EQ(sqs_3, list.back());
180 EXPECT_EQ(list.front(), list.ElementAt(0));
181 EXPECT_EQ(sqs_2, list.ElementAt(1));
182 EXPECT_EQ(list.back(), list.ElementAt(2));
185 TEST(ListContainerTest, SimpleInsertionSharedQuadState) {
186 ListContainer<SharedQuadState> list;
188 size_t size = 3;
189 SharedQuadState* sqs_1 = list.AllocateAndConstruct<SharedQuadState>();
190 list.AllocateAndConstruct<SharedQuadState>();
191 SharedQuadState* sqs_3 = list.AllocateAndConstruct<SharedQuadState>();
193 EXPECT_EQ(size, list.size());
194 EXPECT_EQ(sqs_1, list.front());
195 EXPECT_EQ(sqs_3, list.back());
198 TEST(ListContainerTest, SimpleInsertionAndClearSharedQuadState) {
199 ListContainer<SharedQuadState> list;
200 EXPECT_TRUE(list.empty());
201 EXPECT_EQ(0u, list.size());
203 size_t size = 3;
204 SharedQuadState* sqs_1 = list.AllocateAndConstruct<SharedQuadState>();
205 list.AllocateAndConstruct<SharedQuadState>();
206 SharedQuadState* sqs_3 = list.AllocateAndConstruct<SharedQuadState>();
208 EXPECT_EQ(size, list.size());
209 EXPECT_EQ(sqs_1, list.front());
210 EXPECT_EQ(sqs_3, list.back());
211 EXPECT_FALSE(list.empty());
213 list.clear();
214 EXPECT_TRUE(list.empty());
215 EXPECT_EQ(0u, list.size());
218 TEST(ListContainerTest, SimpleInsertionClearAndInsertAgainSharedQuadState) {
219 ListContainer<SharedQuadState> list;
220 EXPECT_TRUE(list.empty());
221 EXPECT_EQ(0u, list.size());
223 size_t size = 2;
224 SharedQuadState* sqs_front = list.AllocateAndConstruct<SharedQuadState>();
225 SharedQuadState* sqs_back = list.AllocateAndConstruct<SharedQuadState>();
227 EXPECT_EQ(size, list.size());
228 EXPECT_EQ(sqs_front, list.front());
229 EXPECT_EQ(sqs_back, list.back());
230 EXPECT_FALSE(list.empty());
232 list.clear();
233 EXPECT_TRUE(list.empty());
234 EXPECT_EQ(0u, list.size());
236 size = 3;
237 sqs_front = list.AllocateAndConstruct<SharedQuadState>();
238 list.AllocateAndConstruct<SharedQuadState>();
239 sqs_back = list.AllocateAndConstruct<SharedQuadState>();
241 EXPECT_EQ(size, list.size());
242 EXPECT_EQ(sqs_front, list.front());
243 EXPECT_EQ(sqs_back, list.back());
244 EXPECT_FALSE(list.empty());
247 // This test is used to test when there is more than one allocation needed
248 // for, ListContainer can still perform like normal vector.
249 TEST(ListContainerTest,
250 SimpleInsertionTriggerMoreThanOneAllocationSharedQuadState) {
251 ListContainer<SharedQuadState> list(sizeof(SharedQuadState), 2);
252 std::vector<SharedQuadState*> sqs_list;
253 size_t size = 10;
254 for (size_t i = 0; i < size; ++i) {
255 sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
257 EXPECT_EQ(size, list.size());
259 ListContainer<SharedQuadState>::Iterator iter = list.begin();
260 for (std::vector<SharedQuadState*>::const_iterator sqs_iter =
261 sqs_list.begin();
262 sqs_iter != sqs_list.end();
263 ++sqs_iter) {
264 EXPECT_EQ(*sqs_iter, *iter);
265 ++iter;
269 TEST(ListContainerTest,
270 CorrectAllocationSizeForMoreThanOneAllocationSharedQuadState) {
271 // Constructor sets the allocation size to 2. Every time ListContainer needs
272 // to allocate again, it doubles allocation size. In this test, 10 elements is
273 // needed, thus ListContainerShould allocate spaces 2, 4 and 8 elements.
274 ListContainer<SharedQuadState> list(sizeof(SharedQuadState), 2);
275 std::vector<SharedQuadState*> sqs_list;
276 size_t size = 10;
277 for (size_t i = 0; i < size; ++i) {
278 // Before asking for a new element, space available without another
279 // allocation follows.
280 switch (i) {
281 case 2:
282 case 6:
283 EXPECT_EQ(0u, list.AvailableSizeWithoutAnotherAllocationForTesting());
284 break;
285 case 1:
286 case 5:
287 EXPECT_EQ(1u, list.AvailableSizeWithoutAnotherAllocationForTesting());
288 break;
289 case 0:
290 case 4:
291 EXPECT_EQ(2u, list.AvailableSizeWithoutAnotherAllocationForTesting());
292 break;
293 case 3:
294 EXPECT_EQ(3u, list.AvailableSizeWithoutAnotherAllocationForTesting());
295 break;
296 case 9:
297 EXPECT_EQ(5u, list.AvailableSizeWithoutAnotherAllocationForTesting());
298 break;
299 case 8:
300 EXPECT_EQ(6u, list.AvailableSizeWithoutAnotherAllocationForTesting());
301 break;
302 case 7:
303 EXPECT_EQ(7u, list.AvailableSizeWithoutAnotherAllocationForTesting());
304 break;
305 default:
306 break;
308 sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
309 // After asking for a new element, space available without another
310 // allocation follows.
311 switch (i) {
312 case 1:
313 case 5:
314 EXPECT_EQ(0u, list.AvailableSizeWithoutAnotherAllocationForTesting());
315 break;
316 case 0:
317 case 4:
318 EXPECT_EQ(1u, list.AvailableSizeWithoutAnotherAllocationForTesting());
319 break;
320 case 3:
321 EXPECT_EQ(2u, list.AvailableSizeWithoutAnotherAllocationForTesting());
322 break;
323 case 2:
324 EXPECT_EQ(3u, list.AvailableSizeWithoutAnotherAllocationForTesting());
325 break;
326 case 9:
327 EXPECT_EQ(4u, list.AvailableSizeWithoutAnotherAllocationForTesting());
328 break;
329 case 8:
330 EXPECT_EQ(5u, list.AvailableSizeWithoutAnotherAllocationForTesting());
331 break;
332 case 7:
333 EXPECT_EQ(6u, list.AvailableSizeWithoutAnotherAllocationForTesting());
334 break;
335 case 6:
336 EXPECT_EQ(7u, list.AvailableSizeWithoutAnotherAllocationForTesting());
337 break;
338 default:
339 break;
342 EXPECT_EQ(size, list.size());
344 ListContainer<SharedQuadState>::Iterator iter = list.begin();
345 for (std::vector<SharedQuadState*>::const_iterator sqs_iter =
346 sqs_list.begin();
347 sqs_iter != sqs_list.end();
348 ++sqs_iter) {
349 EXPECT_EQ(*sqs_iter, *iter);
350 ++iter;
354 TEST(ListContainerTest, SimpleIterationSharedQuadState) {
355 ListContainer<SharedQuadState> list;
356 std::vector<SharedQuadState*> sqs_list;
357 size_t size = 10;
358 for (size_t i = 0; i < size; ++i) {
359 sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
361 EXPECT_EQ(size, list.size());
363 size_t num_iters_in_list = 0;
365 std::vector<SharedQuadState*>::const_iterator sqs_iter = sqs_list.begin();
366 for (ListContainer<SharedQuadState>::Iterator iter = list.begin();
367 iter != list.end();
368 ++iter) {
369 EXPECT_EQ(*sqs_iter, *iter);
370 ++num_iters_in_list;
371 ++sqs_iter;
375 size_t num_iters_in_vector = 0;
377 ListContainer<SharedQuadState>::Iterator iter = list.begin();
378 for (std::vector<SharedQuadState*>::const_iterator sqs_iter =
379 sqs_list.begin();
380 sqs_iter != sqs_list.end();
381 ++sqs_iter) {
382 EXPECT_EQ(*sqs_iter, *iter);
383 ++num_iters_in_vector;
384 ++iter;
388 EXPECT_EQ(num_iters_in_vector, num_iters_in_list);
391 TEST(ListContainerTest, SimpleConstIteratorIterationSharedQuadState) {
392 ListContainer<SharedQuadState> list;
393 std::vector<const SharedQuadState*> sqs_list;
394 size_t size = 10;
395 for (size_t i = 0; i < size; ++i) {
396 sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
398 EXPECT_EQ(size, list.size());
401 std::vector<const SharedQuadState*>::const_iterator sqs_iter =
402 sqs_list.begin();
403 for (ListContainer<SharedQuadState>::ConstIterator iter = list.begin();
404 iter != list.end();
405 ++iter) {
406 EXPECT_TRUE(isConstSharedQuadStatePointer(*iter));
407 EXPECT_EQ(*sqs_iter, *iter);
408 ++sqs_iter;
413 std::vector<const SharedQuadState*>::const_iterator sqs_iter =
414 sqs_list.begin();
415 for (ListContainer<SharedQuadState>::Iterator iter = list.begin();
416 iter != list.end();
417 ++iter) {
418 EXPECT_FALSE(isConstSharedQuadStatePointer(*iter));
419 EXPECT_EQ(*sqs_iter, *iter);
420 ++sqs_iter;
425 ListContainer<SharedQuadState>::ConstIterator iter = list.begin();
426 for (std::vector<const SharedQuadState*>::const_iterator sqs_iter =
427 sqs_list.begin();
428 sqs_iter != sqs_list.end();
429 ++sqs_iter) {
430 EXPECT_EQ(*sqs_iter, *iter);
431 ++iter;
436 TEST(ListContainerTest, SimpleReverseInsertionSharedQuadState) {
437 ListContainer<SharedQuadState> list;
438 std::vector<SharedQuadState*> sqs_list;
439 size_t size = 10;
440 for (size_t i = 0; i < size; ++i) {
441 sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
443 EXPECT_EQ(size, list.size());
446 std::vector<SharedQuadState*>::const_reverse_iterator sqs_iter =
447 sqs_list.rbegin();
448 for (ListContainer<SharedQuadState>::ReverseIterator iter = list.rbegin();
449 iter != list.rend();
450 ++iter) {
451 EXPECT_EQ(*sqs_iter, *iter);
452 ++sqs_iter;
457 ListContainer<SharedQuadState>::ReverseIterator iter = list.rbegin();
458 for (std::vector<SharedQuadState*>::reverse_iterator sqs_iter =
459 sqs_list.rbegin();
460 sqs_iter != sqs_list.rend();
461 ++sqs_iter) {
462 EXPECT_EQ(*sqs_iter, *iter);
463 ++iter;
468 TEST(ListContainerTest, SimpleDeletion) {
469 ListContainer<DrawQuad> list(kLargestQuadSize);
470 std::vector<SimpleDrawQuad*> sdq_list;
471 size_t size = 10;
472 for (size_t i = 0; i < size; ++i) {
473 sdq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
474 sdq_list.back()->set_value(i);
476 EXPECT_EQ(size, list.size());
478 list.EraseAndInvalidateAllPointers(list.begin());
479 --size;
480 EXPECT_EQ(size, list.size());
481 int i = 1;
482 for (ListContainer<DrawQuad>::Iterator iter = list.begin();
483 iter != list.end();
484 ++iter) {
485 EXPECT_EQ(i, static_cast<SimpleDrawQuad*>(*iter)->get_value());
486 ++i;
490 TEST(ListContainerTest, SimpleIterationAndManipulation) {
491 ListContainer<DrawQuad> list(kLargestQuadSize);
492 std::vector<SimpleDrawQuad*> sdq_list;
493 size_t size = 10;
494 for (size_t i = 0; i < size; ++i) {
495 SimpleDrawQuad* simple_dq = list.AllocateAndConstruct<SimpleDrawQuad>();
496 sdq_list.push_back(simple_dq);
498 EXPECT_EQ(size, list.size());
500 ListContainer<DrawQuad>::Iterator iter = list.begin();
501 for (int i = 0; i < 10; ++i) {
502 static_cast<SimpleDrawQuad*>(*iter)->set_value(i);
503 ++iter;
506 int i = 0;
507 for (std::vector<SimpleDrawQuad*>::const_iterator sdq_iter = sdq_list.begin();
508 sdq_iter < sdq_list.end();
509 ++sdq_iter) {
510 EXPECT_EQ(i, (*sdq_iter)->get_value());
511 ++i;
515 TEST(ListContainerTest, SimpleManipulationWithIndexSimpleDrawQuad) {
516 ListContainer<DrawQuad> list(kLargestQuadSize);
517 std::vector<SimpleDrawQuad*> dq_list;
518 size_t size = 10;
519 for (size_t i = 0; i < size; ++i) {
520 dq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
522 EXPECT_EQ(size, list.size());
524 for (size_t i = 0; i < size; ++i) {
525 static_cast<SimpleDrawQuad*>(list.ElementAt(i))->set_value(i);
528 int i = 0;
529 for (std::vector<SimpleDrawQuad*>::const_iterator dq_iter = dq_list.begin();
530 dq_iter != dq_list.end();
531 ++dq_iter, ++i) {
532 EXPECT_EQ(i, (*dq_iter)->get_value());
536 TEST(ListContainerTest,
537 SimpleManipulationWithIndexMoreThanOneAllocationSimpleDrawQuad) {
538 ListContainer<DrawQuad> list(LargestDrawQuadSize(), 2);
539 std::vector<SimpleDrawQuad*> dq_list;
540 size_t size = 10;
541 for (size_t i = 0; i < size; ++i) {
542 dq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
544 EXPECT_EQ(size, list.size());
546 for (size_t i = 0; i < size; ++i) {
547 static_cast<SimpleDrawQuad*>(list.ElementAt(i))->set_value(i);
550 int i = 0;
551 for (std::vector<SimpleDrawQuad*>::const_iterator dq_iter = dq_list.begin();
552 dq_iter != dq_list.end();
553 ++dq_iter, ++i) {
554 EXPECT_EQ(i, (*dq_iter)->get_value());
558 TEST(ListContainerTest,
559 SimpleIterationAndReverseIterationWithIndexSharedQuadState) {
560 ListContainer<SharedQuadState> list;
561 std::vector<SharedQuadState*> sqs_list;
562 size_t size = 10;
563 for (size_t i = 0; i < size; ++i) {
564 sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
566 EXPECT_EQ(size, list.size());
568 size_t i = 0;
569 for (ListContainer<SharedQuadState>::Iterator iter = list.begin();
570 iter != list.end();
571 ++iter) {
572 EXPECT_EQ(i, iter.index());
573 ++i;
576 i = 0;
577 for (ListContainer<SharedQuadState>::ReverseIterator iter = list.rbegin();
578 iter != list.rend();
579 ++iter) {
580 EXPECT_EQ(i, iter.index());
581 ++i;
585 } // namespace
586 } // namespace cc