15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file has the unit tests for the IdAllocator class.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/id_allocator.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IdAllocatorTest : public testing::Test {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {}
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {}
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IdAllocator* id_allocator() { return &id_allocator_; }
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IdAllocator id_allocator_;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks basic functionality: AllocateID, FreeID, InUse.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IdAllocatorTest, TestBasic) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IdAllocator *allocator = id_allocator();
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that resource 1 is not in use
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(allocator->InUse(1));
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allocate an ID, check that it's in use.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id1 = allocator->AllocateID();
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(allocator->InUse(id1));
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allocate another ID, check that it's in use, and different from the first
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id2 = allocator->AllocateID();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(allocator->InUse(id2));
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(id1, id2);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Free one of the IDs, check that it's not in use any more.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allocator->FreeID(id1);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(allocator->InUse(id1));
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Frees the other ID, check that it's not in use any more.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allocator->FreeID(id2);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(allocator->InUse(id2));
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that the resource IDs are re-used after being freed.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IdAllocatorTest, TestAdvanced) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IdAllocator *allocator = id_allocator();
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allocate the highest possible ID, to make life awkward.
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  allocator->AllocateIDAtOrAbove(~static_cast<ResourceId>(0));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allocate a significant number of resources.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned int kNumResources = 100;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId ids[kNumResources];
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned int i = 0; i < kNumResources; ++i) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ids[i] = allocator->AllocateID();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(allocator->InUse(ids[i]));
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that a new allocation re-uses the resource we just freed.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id1 = ids[kNumResources / 2];
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allocator->FreeID(id1);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(allocator->InUse(id1));
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id2 = allocator->AllocateID();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(allocator->InUse(id2));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(id1, id2);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that we can choose our own ids and they won't be reused.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IdAllocatorTest, MarkAsUsed) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IdAllocator* allocator = id_allocator();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id = allocator->AllocateID();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allocator->FreeID(id);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(allocator->InUse(id));
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(allocator->MarkAsUsed(id));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(allocator->InUse(id));
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id2 = allocator->AllocateID();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(id, id2);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(allocator->MarkAsUsed(id2 + 1));
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id3 = allocator->AllocateID();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks our algorithm. If the algorithm changes this check should be
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // changed.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(id3, id2 + 2);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks AllocateIdAtOrAbove.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IdAllocatorTest, AllocateIdAtOrAbove) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ResourceId kOffset = 123456;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IdAllocator* allocator = id_allocator();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id1 = allocator->AllocateIDAtOrAbove(kOffset);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kOffset, id1);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id2 = allocator->AllocateIDAtOrAbove(kOffset);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(id2, kOffset);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id3 = allocator->AllocateIDAtOrAbove(kOffset);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(id3, kOffset);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Checks that AllocateIdAtOrAbove wraps around at the maximum value.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IdAllocatorTest, AllocateIdAtOrAboveWrapsAround) {
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const ResourceId kMaxPossibleOffset = ~static_cast<ResourceId>(0);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IdAllocator* allocator = id_allocator();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id1 = allocator->AllocateIDAtOrAbove(kMaxPossibleOffset);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kMaxPossibleOffset, id1);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id2 = allocator->AllocateIDAtOrAbove(kMaxPossibleOffset);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, id2);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id3 = allocator->AllocateIDAtOrAbove(kMaxPossibleOffset);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, id3);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IdAllocatorTest, RedundantFreeIsIgnored) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IdAllocator* allocator = id_allocator();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id1 = allocator->AllocateID();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allocator->FreeID(0);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allocator->FreeID(id1);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allocator->FreeID(id1);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allocator->FreeID(id1 + 1);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id2 = allocator->AllocateID();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceId id3 = allocator->AllocateID();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(id2, id3);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(kInvalidResource, id2);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(kInvalidResource, id3);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
129