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.
4
5// This file has the unit tests for the IdAllocator class.
6
7#include "gpu/command_buffer/common/id_allocator.h"
8#include "testing/gtest/include/gtest/gtest.h"
9
10namespace gpu {
11
12class IdAllocatorTest : public testing::Test {
13 protected:
14  virtual void SetUp() {}
15  virtual void TearDown() {}
16
17  IdAllocator* id_allocator() { return &id_allocator_; }
18
19 private:
20  IdAllocator id_allocator_;
21};
22
23// Checks basic functionality: AllocateID, FreeID, InUse.
24TEST_F(IdAllocatorTest, TestBasic) {
25  IdAllocator *allocator = id_allocator();
26  // Check that resource 1 is not in use
27  EXPECT_FALSE(allocator->InUse(1));
28
29  // Allocate an ID, check that it's in use.
30  ResourceId id1 = allocator->AllocateID();
31  EXPECT_TRUE(allocator->InUse(id1));
32
33  // Allocate another ID, check that it's in use, and different from the first
34  // one.
35  ResourceId id2 = allocator->AllocateID();
36  EXPECT_TRUE(allocator->InUse(id2));
37  EXPECT_NE(id1, id2);
38
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));
42
43  // Frees the other ID, check that it's not in use any more.
44  allocator->FreeID(id2);
45  EXPECT_FALSE(allocator->InUse(id2));
46}
47
48// Checks that the resource IDs are re-used after being freed.
49TEST_F(IdAllocatorTest, TestAdvanced) {
50  IdAllocator *allocator = id_allocator();
51
52  // Allocate the highest possible ID, to make life awkward.
53  allocator->AllocateIDAtOrAbove(~static_cast<ResourceId>(0));
54
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]));
61  }
62
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));
69  EXPECT_EQ(id1, id2);
70}
71
72// Checks that we can choose our own ids and they won't be reused.
73TEST_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();
81  EXPECT_NE(id, id2);
82  EXPECT_TRUE(allocator->MarkAsUsed(id2 + 1));
83  ResourceId id3 = allocator->AllocateID();
84  // Checks our algorithm. If the algorithm changes this check should be
85  // changed.
86  EXPECT_EQ(id3, id2 + 2);
87}
88
89// Checks AllocateIdAtOrAbove.
90TEST_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);
99}
100
101// Checks that AllocateIdAtOrAbove wraps around at the maximum value.
102TEST_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);
108  EXPECT_EQ(1u, id2);
109  ResourceId id3 = allocator->AllocateIDAtOrAbove(kMaxPossibleOffset);
110  EXPECT_EQ(2u, id3);
111}
112
113TEST_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);
120
121  ResourceId id2 = allocator->AllocateID();
122  ResourceId id3 = allocator->AllocateID();
123  EXPECT_NE(id2, id3);
124  EXPECT_NE(kInvalidResource, id2);
125  EXPECT_NE(kInvalidResource, id3);
126}
127
128}  // namespace gpu
129