1 // Copyright (c) 2011 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 // This file has the unit tests for the IdAllocator class.
7 #include "gpu/command_buffer/common/id_allocator.h"
8 #include "testing/gtest/include/gtest/gtest.h"
12 class IdAllocatorTest
: public testing::Test
{
14 void SetUp() override
{}
15 void TearDown() override
{}
17 IdAllocator
* id_allocator() { return &id_allocator_
; }
20 IdAllocator id_allocator_
;
23 // Checks basic functionality: AllocateID, FreeID, InUse.
24 TEST_F(IdAllocatorTest
, TestBasic
) {
25 IdAllocator
*allocator
= id_allocator();
26 // Check that resource 1 is not in use
27 EXPECT_FALSE(allocator
->InUse(1));
29 // Allocate an ID, check that it's in use.
30 ResourceId id1
= allocator
->AllocateID();
31 EXPECT_TRUE(allocator
->InUse(id1
));
33 // Allocate another ID, check that it's in use, and different from the first
35 ResourceId id2
= allocator
->AllocateID();
36 EXPECT_TRUE(allocator
->InUse(id2
));
39 // Free one of the IDs, check that it's not in use any more.
40 allocator
->FreeID(id1
);
41 EXPECT_FALSE(allocator
->InUse(id1
));
43 // Frees the other ID, check that it's not in use any more.
44 allocator
->FreeID(id2
);
45 EXPECT_FALSE(allocator
->InUse(id2
));
48 // Checks that the resource IDs are re-used after being freed.
49 TEST_F(IdAllocatorTest
, TestAdvanced
) {
50 IdAllocator
*allocator
= id_allocator();
52 // Allocate the highest possible ID, to make life awkward.
53 allocator
->AllocateIDAtOrAbove(~static_cast<ResourceId
>(0));
55 // Allocate a significant number of resources.
56 const unsigned int kNumResources
= 100;
57 ResourceId ids
[kNumResources
];
58 for (unsigned int i
= 0; i
< kNumResources
; ++i
) {
59 ids
[i
] = allocator
->AllocateID();
60 EXPECT_TRUE(allocator
->InUse(ids
[i
]));
63 // Check that a new allocation re-uses the resource we just freed.
64 ResourceId id1
= ids
[kNumResources
/ 2];
65 allocator
->FreeID(id1
);
66 EXPECT_FALSE(allocator
->InUse(id1
));
67 ResourceId id2
= allocator
->AllocateID();
68 EXPECT_TRUE(allocator
->InUse(id2
));
72 // Checks that we can choose our own ids and they won't be reused.
73 TEST_F(IdAllocatorTest
, MarkAsUsed
) {
74 IdAllocator
* allocator
= id_allocator();
75 ResourceId id
= allocator
->AllocateID();
76 allocator
->FreeID(id
);
77 EXPECT_FALSE(allocator
->InUse(id
));
78 EXPECT_TRUE(allocator
->MarkAsUsed(id
));
79 EXPECT_TRUE(allocator
->InUse(id
));
80 ResourceId id2
= allocator
->AllocateID();
82 EXPECT_TRUE(allocator
->MarkAsUsed(id2
+ 1));
83 ResourceId id3
= allocator
->AllocateID();
84 // Checks our algorithm. If the algorithm changes this check should be
86 EXPECT_EQ(id3
, id2
+ 2);
89 // Checks AllocateIdAtOrAbove.
90 TEST_F(IdAllocatorTest
, AllocateIdAtOrAbove
) {
91 const ResourceId kOffset
= 123456;
92 IdAllocator
* allocator
= id_allocator();
93 ResourceId id1
= allocator
->AllocateIDAtOrAbove(kOffset
);
94 EXPECT_EQ(kOffset
, id1
);
95 ResourceId id2
= allocator
->AllocateIDAtOrAbove(kOffset
);
96 EXPECT_GT(id2
, kOffset
);
97 ResourceId id3
= allocator
->AllocateIDAtOrAbove(kOffset
);
98 EXPECT_GT(id3
, kOffset
);
101 // Checks that AllocateIdAtOrAbove wraps around at the maximum value.
102 TEST_F(IdAllocatorTest
, AllocateIdAtOrAboveWrapsAround
) {
103 const ResourceId kMaxPossibleOffset
= ~static_cast<ResourceId
>(0);
104 IdAllocator
* allocator
= id_allocator();
105 ResourceId id1
= allocator
->AllocateIDAtOrAbove(kMaxPossibleOffset
);
106 EXPECT_EQ(kMaxPossibleOffset
, id1
);
107 ResourceId id2
= allocator
->AllocateIDAtOrAbove(kMaxPossibleOffset
);
109 ResourceId id3
= allocator
->AllocateIDAtOrAbove(kMaxPossibleOffset
);
113 TEST_F(IdAllocatorTest
, RedundantFreeIsIgnored
) {
114 IdAllocator
* allocator
= id_allocator();
115 ResourceId id1
= allocator
->AllocateID();
116 allocator
->FreeID(0);
117 allocator
->FreeID(id1
);
118 allocator
->FreeID(id1
);
119 allocator
->FreeID(id1
+ 1);
121 ResourceId id2
= allocator
->AllocateID();
122 ResourceId id3
= allocator
->AllocateID();
124 EXPECT_NE(kInvalidResource
, id2
);
125 EXPECT_NE(kInvalidResource
, id3
);
128 TEST_F(IdAllocatorTest
, AllocateIDRange
) {
129 const ResourceId kMaxPossibleOffset
= std::numeric_limits
<ResourceId
>::max();
131 IdAllocator
* allocator
= id_allocator();
133 ResourceId id1
= allocator
->AllocateIDRange(1);
135 ResourceId id2
= allocator
->AllocateIDRange(2);
137 ResourceId id3
= allocator
->AllocateIDRange(3);
139 ResourceId id4
= allocator
->AllocateID();
141 allocator
->FreeID(3);
142 ResourceId id5
= allocator
->AllocateIDRange(1);
144 allocator
->FreeID(5);
145 allocator
->FreeID(2);
146 allocator
->FreeID(4);
147 ResourceId id6
= allocator
->AllocateIDRange(2);
149 ResourceId id7
= allocator
->AllocateIDAtOrAbove(kMaxPossibleOffset
);
150 EXPECT_EQ(kMaxPossibleOffset
, id7
);
151 ResourceId id8
= allocator
->AllocateIDAtOrAbove(kMaxPossibleOffset
);
153 ResourceId id9
= allocator
->AllocateIDRange(50);
155 ResourceId id10
= allocator
->AllocateIDRange(50);
156 EXPECT_EQ(58u, id10
);
157 // Remove all the low-numbered ids.
158 allocator
->FreeID(1);
159 allocator
->FreeID(15);
160 allocator
->FreeIDRange(2, 107);
161 ResourceId id11
= allocator
->AllocateIDRange(100);
163 allocator
->FreeID(kMaxPossibleOffset
);
164 ResourceId id12
= allocator
->AllocateIDRange(100);
165 EXPECT_EQ(101u, id12
);
167 ResourceId id13
= allocator
->AllocateIDAtOrAbove(kMaxPossibleOffset
- 2u);
168 EXPECT_EQ(kMaxPossibleOffset
- 2u, id13
);
169 ResourceId id14
= allocator
->AllocateIDRange(3);
170 EXPECT_EQ(201u, id14
);
173 TEST_F(IdAllocatorTest
, AllocateIDRangeEndNoEffect
) {
174 const ResourceId kMaxPossibleOffset
= std::numeric_limits
<ResourceId
>::max();
176 IdAllocator
* allocator
= id_allocator();
177 ResourceId id1
= allocator
->AllocateIDAtOrAbove(kMaxPossibleOffset
- 2u);
178 EXPECT_EQ(kMaxPossibleOffset
- 2u, id1
);
179 ResourceId id3
= allocator
->AllocateIDRange(3);
181 ResourceId id2
= allocator
->AllocateIDRange(2);
185 TEST_F(IdAllocatorTest
, AllocateFullIDRange
) {
186 const uint32_t kMaxPossibleRange
= std::numeric_limits
<uint32_t>::max();
187 const ResourceId kFreedId
= 555u;
188 IdAllocator
* allocator
= id_allocator();
190 ResourceId id1
= allocator
->AllocateIDRange(kMaxPossibleRange
);
192 ResourceId id2
= allocator
->AllocateID();
194 allocator
->FreeID(kFreedId
);
195 ResourceId id3
= allocator
->AllocateID();
196 EXPECT_EQ(kFreedId
, id3
);
197 ResourceId id4
= allocator
->AllocateID();
199 allocator
->FreeID(kFreedId
+ 1u);
200 allocator
->FreeID(kFreedId
+ 4u);
201 allocator
->FreeID(kFreedId
+ 3u);
202 allocator
->FreeID(kFreedId
+ 5u);
203 allocator
->FreeID(kFreedId
+ 2u);
204 ResourceId id5
= allocator
->AllocateIDRange(5);
205 EXPECT_EQ(kFreedId
+ 1u, id5
);
208 TEST_F(IdAllocatorTest
, AllocateIDRangeNoWrapInRange
) {
209 const uint32_t kMaxPossibleRange
= std::numeric_limits
<uint32_t>::max();
210 const ResourceId kAllocId
= 10u;
211 IdAllocator
* allocator
= id_allocator();
213 ResourceId id1
= allocator
->AllocateIDAtOrAbove(kAllocId
);
214 EXPECT_EQ(kAllocId
, id1
);
215 ResourceId id2
= allocator
->AllocateIDRange(kMaxPossibleRange
- 5u);
217 ResourceId id3
= allocator
->AllocateIDRange(kMaxPossibleRange
- kAllocId
);
218 EXPECT_EQ(kAllocId
+ 1u, id3
);
221 TEST_F(IdAllocatorTest
, AllocateIdMax
) {
222 const uint32_t kMaxPossibleRange
= std::numeric_limits
<uint32_t>::max();
224 IdAllocator
* allocator
= id_allocator();
225 ResourceId id
= allocator
->AllocateIDRange(kMaxPossibleRange
);
227 allocator
->FreeIDRange(id
, kMaxPossibleRange
- 1u);
228 ResourceId id2
= allocator
->AllocateIDRange(kMaxPossibleRange
);
230 allocator
->FreeIDRange(id
, kMaxPossibleRange
);
231 ResourceId id3
= allocator
->AllocateIDRange(kMaxPossibleRange
);
235 TEST_F(IdAllocatorTest
, ZeroIdCases
) {
236 IdAllocator
* allocator
= id_allocator();
237 EXPECT_FALSE(allocator
->InUse(0));
238 ResourceId id1
= allocator
->AllocateIDAtOrAbove(0);
240 EXPECT_FALSE(allocator
->InUse(0));
241 allocator
->FreeID(0);
242 EXPECT_FALSE(allocator
->InUse(0));
243 EXPECT_TRUE(allocator
->InUse(id1
));
244 allocator
->FreeID(id1
);
245 EXPECT_FALSE(allocator
->InUse(id1
));