From 03786d77a6e91408517e5c6507cbd4695d4b5175 Mon Sep 17 00:00:00 2001 From: Minmin Gong Date: Wed, 27 May 2015 11:22:30 -0700 Subject: [PATCH] After a create-on-bind, the subsequent glGen* should not waste handle space. Consider this calling sequence: glBindTexture(GL_TEXTURE_2D, 3); // create-on-bind glGenTextures(1, tex); Before this fix, mUnallocatedList in HandleAllocator is in reverse sorted order. It's split into (4, MAX_UINT) and (1, 3). The glGen gets tex = 4, and handles 1 and 2 will not be allocated until it reaches MAX_UINT. With this fix, the elements in mUnallocatedList is in sorted order (1, 3) and (4, MAX_UINT). So tex is 1, and we can have all rest handles. Change-Id: If408ea92f7c243791119fe386e3e0ea27954e55c Reviewed-on: https://chromium-review.googlesource.com/273886 Reviewed-by: Jamie Madill Tested-by: Minmin Gong --- src/libANGLE/HandleAllocator.cpp | 12 ++++++------ src/libANGLE/HandleAllocator_unittest.cpp | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/libANGLE/HandleAllocator.cpp b/src/libANGLE/HandleAllocator.cpp index 1b9162aeb..16365dc99 100644 --- a/src/libANGLE/HandleAllocator.cpp +++ b/src/libANGLE/HandleAllocator.cpp @@ -20,7 +20,7 @@ struct HandleAllocator::HandleRangeComparator { bool operator()(const HandleRange &range, GLuint handle) const { - return (handle < range.begin); + return (range.end < handle); } }; @@ -120,13 +120,13 @@ void HandleAllocator::reserve(GLuint handle) // need to split the range auto placementIt = mUnallocatedList.erase(boundIt); - if (begin != handle) - { - placementIt = mUnallocatedList.insert(placementIt, HandleRange(begin, handle)); - } if (handle + 1 != end) { - mUnallocatedList.insert(placementIt, HandleRange(handle + 1, end)); + placementIt = mUnallocatedList.insert(placementIt, HandleRange(handle + 1, end)); + } + if (begin != handle) + { + mUnallocatedList.insert(placementIt, HandleRange(begin, handle)); } } diff --git a/src/libANGLE/HandleAllocator_unittest.cpp b/src/libANGLE/HandleAllocator_unittest.cpp index 196b346ac..726b64bab 100644 --- a/src/libANGLE/HandleAllocator_unittest.cpp +++ b/src/libANGLE/HandleAllocator_unittest.cpp @@ -103,4 +103,24 @@ TEST(HandleAllocatorTest, ReserveMaxUintHandle) EXPECT_EQ(1u, normalHandle); } +// To test if the allocator keep the handle in a sorted order. +TEST(HandleAllocatorTest, SortedOrderHandle) +{ + gl::HandleAllocator allocator; + + allocator.reserve(3); + + GLuint allocatedList[5]; + for (GLuint count = 0; count < 5; count++) + { + allocatedList[count] = allocator.allocate(); + } + + EXPECT_EQ(1u, allocatedList[0]); + EXPECT_EQ(2u, allocatedList[1]); + EXPECT_EQ(4u, allocatedList[2]); + EXPECT_EQ(5u, allocatedList[3]); + EXPECT_EQ(6u, allocatedList[4]); +} + }