blob: ffe9c31b2f29c2ad20ac425eafad072d8437dda4 [file] [log] [blame]
Michael Ludwig45191342020-03-24 12:29:39 -04001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "src/gpu/GrTAllocator.h"
9#include "tests/Test.h"
10
11namespace {
12struct C {
13 C() : fID(-1) { ++gInstCnt; }
14 C(int id) : fID(id) { ++gInstCnt; }
Michael Ludwiga291b372020-07-16 14:20:49 -040015 C(C&& c) : C(c.fID) {}
Michael Ludwigc97ebe02020-07-17 08:39:46 -040016 C(const C& c) : C(c.fID) {}
17
Ben Wagner14ba58f2020-03-30 17:53:53 -040018 C& operator=(C&&) = default;
Michael Ludwigc97ebe02020-07-17 08:39:46 -040019 C& operator=(const C&) = default;
20
Michael Ludwig45191342020-03-24 12:29:39 -040021 ~C() { --gInstCnt; }
Michael Ludwigc97ebe02020-07-17 08:39:46 -040022
Michael Ludwig45191342020-03-24 12:29:39 -040023 int fID;
24
25 static int gInstCnt;
26};
27
28int C::gInstCnt = 0;
29}
30
31// Checks that the allocator has the correct count, etc and that the element IDs are correct.
32// Then pops popCnt items and checks again.
33template<int N>
34static void check_allocator_helper(GrTAllocator<C, N>* allocator, int cnt, int popCnt,
35 skiatest::Reporter* reporter) {
36 REPORTER_ASSERT(reporter, (0 == cnt) == allocator->empty());
37 REPORTER_ASSERT(reporter, cnt == allocator->count());
38 REPORTER_ASSERT(reporter, cnt == C::gInstCnt);
39
40 int i = 0;
41 for (const C& c : allocator->items()) {
42 REPORTER_ASSERT(reporter, i == c.fID);
43 REPORTER_ASSERT(reporter, allocator->item(i).fID == i);
44 ++i;
45 }
46 REPORTER_ASSERT(reporter, i == cnt);
47
48 if (cnt > 0) {
49 REPORTER_ASSERT(reporter, cnt-1 == allocator->back().fID);
50 }
51
52 if (popCnt > 0) {
53 for (int i = 0; i < popCnt; ++i) {
54 allocator->pop_back();
55 }
56 check_allocator_helper(allocator, cnt - popCnt, 0, reporter);
57 }
58}
59
Michael Ludwig26b4ffd2020-07-15 12:36:44 -040060template<int N>
61static void check_iterator_helper(GrTAllocator<C, N>* allocator, const std::vector<C*>& expected,
62 skiatest::Reporter* reporter) {
63 const GrTAllocator<C, N>* cAlloc = allocator;
64 REPORTER_ASSERT(reporter, (size_t) allocator->count() == expected.size());
65 // Forward+const
66 int i = 0;
67 for (const C& c : cAlloc->items()) {
68 REPORTER_ASSERT(reporter, (uintptr_t) &c == (uintptr_t) expected[i]);
69 ++i;
70 }
71 REPORTER_ASSERT(reporter, (size_t) i == expected.size());
72
73 // Forward+non-const
74 i = 0;
75 for (C& c : allocator->items()) {
76 REPORTER_ASSERT(reporter, (uintptr_t) &c == (uintptr_t) expected[i]);
77 ++i;
78 }
79 REPORTER_ASSERT(reporter, (size_t) i == expected.size());
80
81 // Reverse+const
82 i = (int) expected.size() - 1;
83 for (const C& c : cAlloc->ritems()) {
84 REPORTER_ASSERT(reporter, (uintptr_t) &c == (uintptr_t) expected[i]);
85 --i;
86 }
87 REPORTER_ASSERT(reporter, i == -1);
88
89 // Reverse+non-const
90 i = (int) expected.size() - 1;
91 for (C& c : allocator->ritems()) {
92 REPORTER_ASSERT(reporter, (uintptr_t) &c == (uintptr_t) expected[i]);
93 --i;
94 }
95 REPORTER_ASSERT(reporter, i == -1);
96
97 // Also test random access
98 for (int i = 0; i < allocator->count(); ++i) {
99 REPORTER_ASSERT(reporter, (uintptr_t) &allocator->item(i) == (uintptr_t) expected[i]);
100 REPORTER_ASSERT(reporter, (uintptr_t) &cAlloc->item(i) == (uintptr_t) expected[i]);
101 }
102}
103
Michael Ludwig45191342020-03-24 12:29:39 -0400104// Adds cnt items to the allocator, tests the cnts and iterators, pops popCnt items and checks
105// again. Finally it resets the allocator and checks again.
106template<int N>
107static void check_allocator(GrTAllocator<C, N>* allocator, int cnt, int popCnt,
108 skiatest::Reporter* reporter) {
Michael Ludwigc97ebe02020-07-17 08:39:46 -0400109 enum ItemInitializer : int {
110 kCopyCtor,
111 kMoveCtor,
112 kCopyAssign,
113 kMoveAssign,
114 kEmplace,
115 };
116 static constexpr int kInitCount = (int) kEmplace + 1;
117
Michael Ludwig45191342020-03-24 12:29:39 -0400118 SkASSERT(allocator);
119 SkASSERT(allocator->empty());
Michael Ludwig26b4ffd2020-07-15 12:36:44 -0400120 std::vector<C*> items;
Michael Ludwig45191342020-03-24 12:29:39 -0400121 for (int i = 0; i < cnt; ++i) {
Michael Ludwigc97ebe02020-07-17 08:39:46 -0400122 switch((ItemInitializer) (i % kInitCount)) {
123 case kCopyCtor:
124 allocator->push_back(C(i));
125 break;
126 case kMoveCtor:
127 allocator->push_back(std::move(C(i)));
128 break;
129 case kCopyAssign:
130 allocator->push_back() = C(i);
131 break;
132 case kMoveAssign:
133 allocator->push_back() = std::move(C(i));
134 break;
135 case kEmplace:
136 allocator->emplace_back(i);
137 break;
Michael Ludwig45191342020-03-24 12:29:39 -0400138 }
Michael Ludwig26b4ffd2020-07-15 12:36:44 -0400139 items.push_back(&allocator->back());
Michael Ludwig45191342020-03-24 12:29:39 -0400140 }
Michael Ludwig26b4ffd2020-07-15 12:36:44 -0400141 check_iterator_helper(allocator, items, reporter);
Michael Ludwig45191342020-03-24 12:29:39 -0400142 check_allocator_helper(allocator, cnt, popCnt, reporter);
143 allocator->reset();
Michael Ludwig26b4ffd2020-07-15 12:36:44 -0400144 check_iterator_helper(allocator, {}, reporter);
Michael Ludwig45191342020-03-24 12:29:39 -0400145 check_allocator_helper(allocator, 0, 0, reporter);
146}
147
148template<int N>
149static void run_allocator_test(GrTAllocator<C, N>* allocator, skiatest::Reporter* reporter) {
150 check_allocator(allocator, 0, 0, reporter);
151 check_allocator(allocator, 1, 1, reporter);
152 check_allocator(allocator, 2, 2, reporter);
153 check_allocator(allocator, 10, 1, reporter);
154 check_allocator(allocator, 10, 5, reporter);
155 check_allocator(allocator, 10, 10, reporter);
156 check_allocator(allocator, 100, 10, reporter);
157}
158
159DEF_TEST(GrTAllocator, reporter) {
Michael Ludwigc97ebe02020-07-17 08:39:46 -0400160 // Test combinations of allocators with and without stack storage and with different block sizes
Michael Ludwig45191342020-03-24 12:29:39 -0400161 GrTAllocator<C> a1(1);
162 run_allocator_test(&a1, reporter);
163
164 GrTAllocator<C> a2(2);
165 run_allocator_test(&a2, reporter);
166
167 GrTAllocator<C> a5(5);
168 run_allocator_test(&a5, reporter);
169
170 GrTAllocator<C, 1> sa1;
171 run_allocator_test(&sa1, reporter);
172
173 GrTAllocator<C, 3> sa3;
174 run_allocator_test(&sa3, reporter);
175
176 GrTAllocator<C, 4> sa4;
177 run_allocator_test(&sa4, reporter);
178}