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"
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"
19 int kMagicNumberToUseForDrawQuadOne
= 42;
20 int kMagicNumberToUseForDrawQuadTwo
= 314;
22 bool isConstSharedQuadStatePointer(const SharedQuadState
* ptr
) {
26 bool isConstSharedQuadStatePointer(SharedQuadState
* ptr
) {
30 class SimpleDrawQuad
: public DrawQuad
{
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
{}
43 class SimpleDrawQuadConstructMagicNumberOne
: public SimpleDrawQuad
{
45 SimpleDrawQuadConstructMagicNumberOne() : SimpleDrawQuad() {
46 set_value(kMagicNumberToUseForDrawQuadOne
);
50 class SimpleDrawQuadConstructMagicNumberTwo
: public SimpleDrawQuad
{
52 SimpleDrawQuadConstructMagicNumberTwo() : SimpleDrawQuad() {
53 set_value(kMagicNumberToUseForDrawQuadTwo
);
57 class MockDrawQuad
: public SimpleDrawQuadConstructMagicNumberOne
{
59 ~MockDrawQuad() override
{ Destruct(); }
60 MOCK_METHOD0(Destruct
, void());
63 class MockDrawQuadSubclass
: public MockDrawQuad
{
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
);
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
);
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
);
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
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);
121 TEST(ListContainerTest
, ReplaceExistingElement
) {
122 ListContainer
<DrawQuad
> list(kLargestQuadSize
);
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
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());
143 EXPECT_CALL(*dq_1
, Destruct());
147 TEST(ListContainerTest
, DestructorCalledOnceWhenErase
) {
148 ListContainer
<DrawQuad
> list(kLargestQuadSize
);
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
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());
169 TEST(ListContainerTest
, SimpleIndexAccessSharedQuadState
) {
170 ListContainer
<SharedQuadState
> list
;
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
;
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());
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());
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());
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());
233 EXPECT_TRUE(list
.empty());
234 EXPECT_EQ(0u, list
.size());
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
;
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
=
262 sqs_iter
!= sqs_list
.end();
264 EXPECT_EQ(*sqs_iter
, *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
;
277 for (size_t i
= 0; i
< size
; ++i
) {
278 // Before asking for a new element, space available without another
279 // allocation follows.
283 EXPECT_EQ(0u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
287 EXPECT_EQ(1u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
291 EXPECT_EQ(2u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
294 EXPECT_EQ(3u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
297 EXPECT_EQ(5u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
300 EXPECT_EQ(6u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
303 EXPECT_EQ(7u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
308 sqs_list
.push_back(list
.AllocateAndConstruct
<SharedQuadState
>());
309 // After asking for a new element, space available without another
310 // allocation follows.
314 EXPECT_EQ(0u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
318 EXPECT_EQ(1u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
321 EXPECT_EQ(2u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
324 EXPECT_EQ(3u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
327 EXPECT_EQ(4u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
330 EXPECT_EQ(5u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
333 EXPECT_EQ(6u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
336 EXPECT_EQ(7u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
342 EXPECT_EQ(size
, list
.size());
344 ListContainer
<SharedQuadState
>::Iterator iter
= list
.begin();
345 for (std::vector
<SharedQuadState
*>::const_iterator sqs_iter
=
347 sqs_iter
!= sqs_list
.end();
349 EXPECT_EQ(*sqs_iter
, *iter
);
354 TEST(ListContainerTest
, SimpleIterationSharedQuadState
) {
355 ListContainer
<SharedQuadState
> list
;
356 std::vector
<SharedQuadState
*> sqs_list
;
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();
369 EXPECT_EQ(*sqs_iter
, *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
=
380 sqs_iter
!= sqs_list
.end();
382 EXPECT_EQ(*sqs_iter
, *iter
);
383 ++num_iters_in_vector
;
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
;
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
=
403 for (ListContainer
<SharedQuadState
>::ConstIterator iter
= list
.begin();
406 EXPECT_TRUE(isConstSharedQuadStatePointer(*iter
));
407 EXPECT_EQ(*sqs_iter
, *iter
);
413 std::vector
<const SharedQuadState
*>::const_iterator sqs_iter
=
415 for (ListContainer
<SharedQuadState
>::Iterator iter
= list
.begin();
418 EXPECT_FALSE(isConstSharedQuadStatePointer(*iter
));
419 EXPECT_EQ(*sqs_iter
, *iter
);
425 ListContainer
<SharedQuadState
>::ConstIterator iter
= list
.begin();
426 for (std::vector
<const SharedQuadState
*>::const_iterator sqs_iter
=
428 sqs_iter
!= sqs_list
.end();
430 EXPECT_EQ(*sqs_iter
, *iter
);
436 TEST(ListContainerTest
, SimpleReverseInsertionSharedQuadState
) {
437 ListContainer
<SharedQuadState
> list
;
438 std::vector
<SharedQuadState
*> sqs_list
;
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
=
448 for (ListContainer
<SharedQuadState
>::ReverseIterator iter
= list
.rbegin();
451 EXPECT_EQ(*sqs_iter
, *iter
);
457 ListContainer
<SharedQuadState
>::ReverseIterator iter
= list
.rbegin();
458 for (std::vector
<SharedQuadState
*>::reverse_iterator sqs_iter
=
460 sqs_iter
!= sqs_list
.rend();
462 EXPECT_EQ(*sqs_iter
, *iter
);
468 TEST(ListContainerTest
, SimpleDeletion
) {
469 ListContainer
<DrawQuad
> list(kLargestQuadSize
);
470 std::vector
<SimpleDrawQuad
*> sdq_list
;
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());
480 EXPECT_EQ(size
, list
.size());
482 for (ListContainer
<DrawQuad
>::Iterator iter
= list
.begin();
485 EXPECT_EQ(i
, static_cast<SimpleDrawQuad
*>(*iter
)->get_value());
490 TEST(ListContainerTest
, DeletionAllInAllocation
) {
491 const size_t kReserve
= 10;
492 ListContainer
<DrawQuad
> list(kLargestQuadSize
, kReserve
);
493 std::vector
<SimpleDrawQuad
*> sdq_list
;
494 // Add enough quads to cause another allocation.
495 for (size_t i
= 0; i
< kReserve
+ 1; ++i
) {
496 sdq_list
.push_back(list
.AllocateAndConstruct
<SimpleDrawQuad
>());
497 sdq_list
.back()->set_value(static_cast<int>(i
));
499 EXPECT_EQ(kReserve
+ 1, list
.size());
501 // Remove everything in the first allocation.
502 for (size_t i
= 0; i
< kReserve
; ++i
)
503 list
.EraseAndInvalidateAllPointers(list
.begin());
504 EXPECT_EQ(1u, list
.size());
506 // The last quad is left.
507 SimpleDrawQuad
* quad
= static_cast<SimpleDrawQuad
*>(*list
.begin());
508 EXPECT_EQ(static_cast<int>(kReserve
), quad
->get_value());
510 // Remove the quad from the 2nd allocation.
511 list
.EraseAndInvalidateAllPointers(list
.begin());
512 EXPECT_EQ(0u, list
.size());
515 TEST(ListContainerTest
, DeletionAllInAllocationReversed
) {
516 const size_t kReserve
= 10;
517 ListContainer
<DrawQuad
> list(kLargestQuadSize
, kReserve
);
518 std::vector
<SimpleDrawQuad
*> sdq_list
;
519 // Add enough quads to cause another allocation.
520 for (size_t i
= 0; i
< kReserve
+ 1; ++i
) {
521 sdq_list
.push_back(list
.AllocateAndConstruct
<SimpleDrawQuad
>());
522 sdq_list
.back()->set_value(static_cast<int>(i
));
524 EXPECT_EQ(kReserve
+ 1, list
.size());
526 // Remove everything in the 2nd allocation.
527 auto it
= list
.begin();
528 for (size_t i
= 0; i
< kReserve
; ++i
)
530 list
.EraseAndInvalidateAllPointers(it
);
532 // The 2nd-last quad is next, and the rest of the quads exist.
533 size_t i
= kReserve
- 1;
534 for (auto it
= list
.rbegin(); it
!= list
.rend(); ++it
) {
535 SimpleDrawQuad
* quad
= static_cast<SimpleDrawQuad
*>(*it
);
536 EXPECT_EQ(static_cast<int>(i
), quad
->get_value());
540 // Can forward iterate too.
542 for (auto it
= list
.begin(); it
!= list
.end(); ++it
) {
543 SimpleDrawQuad
* quad
= static_cast<SimpleDrawQuad
*>(*it
);
544 EXPECT_EQ(static_cast<int>(i
), quad
->get_value());
548 // Remove the last thing from the 1st allocation.
550 for (size_t i
= 0; i
< kReserve
- 1; ++i
)
552 list
.EraseAndInvalidateAllPointers(it
);
554 // The 2nd-last quad is next, and the rest of the quads exist.
556 for (auto it
= list
.rbegin(); it
!= list
.rend(); ++it
) {
557 SimpleDrawQuad
* quad
= static_cast<SimpleDrawQuad
*>(*it
);
558 EXPECT_EQ(static_cast<int>(i
), quad
->get_value());
562 // Can forward iterate too.
564 for (auto it
= list
.begin(); it
!= list
.end(); ++it
) {
565 SimpleDrawQuad
* quad
= static_cast<SimpleDrawQuad
*>(*it
);
566 EXPECT_EQ(static_cast<int>(i
), quad
->get_value());
571 TEST(ListContainerTest
, SimpleIterationAndManipulation
) {
572 ListContainer
<DrawQuad
> list(kLargestQuadSize
);
573 std::vector
<SimpleDrawQuad
*> sdq_list
;
575 for (size_t i
= 0; i
< size
; ++i
) {
576 SimpleDrawQuad
* simple_dq
= list
.AllocateAndConstruct
<SimpleDrawQuad
>();
577 sdq_list
.push_back(simple_dq
);
579 EXPECT_EQ(size
, list
.size());
581 ListContainer
<DrawQuad
>::Iterator iter
= list
.begin();
582 for (int i
= 0; i
< 10; ++i
) {
583 static_cast<SimpleDrawQuad
*>(*iter
)->set_value(i
);
588 for (std::vector
<SimpleDrawQuad
*>::const_iterator sdq_iter
= sdq_list
.begin();
589 sdq_iter
< sdq_list
.end();
591 EXPECT_EQ(i
, (*sdq_iter
)->get_value());
596 TEST(ListContainerTest
, SimpleManipulationWithIndexSimpleDrawQuad
) {
597 ListContainer
<DrawQuad
> list(kLargestQuadSize
);
598 std::vector
<SimpleDrawQuad
*> dq_list
;
600 for (size_t i
= 0; i
< size
; ++i
) {
601 dq_list
.push_back(list
.AllocateAndConstruct
<SimpleDrawQuad
>());
603 EXPECT_EQ(size
, list
.size());
605 for (size_t i
= 0; i
< size
; ++i
) {
606 static_cast<SimpleDrawQuad
*>(list
.ElementAt(i
))->set_value(i
);
610 for (std::vector
<SimpleDrawQuad
*>::const_iterator dq_iter
= dq_list
.begin();
611 dq_iter
!= dq_list
.end();
613 EXPECT_EQ(i
, (*dq_iter
)->get_value());
617 TEST(ListContainerTest
,
618 SimpleManipulationWithIndexMoreThanOneAllocationSimpleDrawQuad
) {
619 ListContainer
<DrawQuad
> list(LargestDrawQuadSize(), 2);
620 std::vector
<SimpleDrawQuad
*> dq_list
;
622 for (size_t i
= 0; i
< size
; ++i
) {
623 dq_list
.push_back(list
.AllocateAndConstruct
<SimpleDrawQuad
>());
625 EXPECT_EQ(size
, list
.size());
627 for (size_t i
= 0; i
< size
; ++i
) {
628 static_cast<SimpleDrawQuad
*>(list
.ElementAt(i
))->set_value(i
);
632 for (std::vector
<SimpleDrawQuad
*>::const_iterator dq_iter
= dq_list
.begin();
633 dq_iter
!= dq_list
.end();
635 EXPECT_EQ(i
, (*dq_iter
)->get_value());
639 TEST(ListContainerTest
,
640 SimpleIterationAndReverseIterationWithIndexSharedQuadState
) {
641 ListContainer
<SharedQuadState
> list
;
642 std::vector
<SharedQuadState
*> sqs_list
;
644 for (size_t i
= 0; i
< size
; ++i
) {
645 sqs_list
.push_back(list
.AllocateAndConstruct
<SharedQuadState
>());
647 EXPECT_EQ(size
, list
.size());
650 for (ListContainer
<SharedQuadState
>::Iterator iter
= list
.begin();
653 EXPECT_EQ(i
, iter
.index());
658 for (ListContainer
<SharedQuadState
>::ReverseIterator iter
= list
.rbegin();
661 EXPECT_EQ(i
, iter
.index());