From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../checkout/src/libANGLE/HandleAllocator.cpp | 184 +++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp (limited to 'gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp') diff --git a/gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp b/gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp new file mode 100644 index 0000000000..ff49233e1d --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp @@ -0,0 +1,184 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// HandleAllocator.cpp: Implements the gl::HandleAllocator class, which is used +// to allocate GL handles. + +#include "libANGLE/HandleAllocator.h" + +#include +#include +#include + +#include "common/debug.h" + +namespace gl +{ + +struct HandleAllocator::HandleRangeComparator +{ + bool operator()(const HandleRange &range, GLuint handle) const { return (range.end < handle); } +}; + +HandleAllocator::HandleAllocator() : mBaseValue(1), mNextValue(1), mLoggingEnabled(false) +{ + mUnallocatedList.push_back(HandleRange(1, std::numeric_limits::max())); +} + +HandleAllocator::HandleAllocator(GLuint maximumHandleValue) + : mBaseValue(1), mNextValue(1), mLoggingEnabled(false) +{ + mUnallocatedList.push_back(HandleRange(1, maximumHandleValue)); +} + +HandleAllocator::~HandleAllocator() {} + +void HandleAllocator::setBaseHandle(GLuint value) +{ + ASSERT(mBaseValue == mNextValue); + mBaseValue = value; + mNextValue = value; +} + +GLuint HandleAllocator::allocate() +{ + ASSERT(!mUnallocatedList.empty() || !mReleasedList.empty()); + + // Allocate from released list, logarithmic time for pop_heap. + if (!mReleasedList.empty()) + { + std::pop_heap(mReleasedList.begin(), mReleasedList.end(), std::greater()); + GLuint reusedHandle = mReleasedList.back(); + mReleasedList.pop_back(); + + if (mLoggingEnabled) + { + WARN() << "HandleAllocator::allocate reusing " << reusedHandle << std::endl; + } + + return reusedHandle; + } + + // Allocate from unallocated list, constant time. + auto listIt = mUnallocatedList.begin(); + + GLuint freeListHandle = listIt->begin; + ASSERT(freeListHandle > 0); + + if (listIt->begin == listIt->end) + { + mUnallocatedList.erase(listIt); + } + else + { + listIt->begin++; + } + + if (mLoggingEnabled) + { + WARN() << "HandleAllocator::allocate allocating " << freeListHandle << std::endl; + } + + return freeListHandle; +} + +void HandleAllocator::release(GLuint handle) +{ + if (mLoggingEnabled) + { + WARN() << "HandleAllocator::release releasing " << handle << std::endl; + } + + // Try consolidating the ranges first. + for (HandleRange &handleRange : mUnallocatedList) + { + if (handleRange.begin - 1 == handle) + { + handleRange.begin--; + return; + } + + if (handleRange.end == handle - 1) + { + handleRange.end++; + return; + } + } + + // Add to released list, logarithmic time for push_heap. + mReleasedList.push_back(handle); + std::push_heap(mReleasedList.begin(), mReleasedList.end(), std::greater()); +} + +void HandleAllocator::reserve(GLuint handle) +{ + if (mLoggingEnabled) + { + WARN() << "HandleAllocator::reserve reserving " << handle << std::endl; + } + + // Clear from released list -- might be a slow operation. + if (!mReleasedList.empty()) + { + auto releasedIt = std::find(mReleasedList.begin(), mReleasedList.end(), handle); + if (releasedIt != mReleasedList.end()) + { + mReleasedList.erase(releasedIt); + std::make_heap(mReleasedList.begin(), mReleasedList.end(), std::greater()); + return; + } + } + + // Not in released list, reserve in the unallocated list. + auto boundIt = std::lower_bound(mUnallocatedList.begin(), mUnallocatedList.end(), handle, + HandleRangeComparator()); + + ASSERT(boundIt != mUnallocatedList.end()); + + GLuint begin = boundIt->begin; + GLuint end = boundIt->end; + + if (handle == begin || handle == end) + { + if (begin == end) + { + mUnallocatedList.erase(boundIt); + } + else if (handle == begin) + { + boundIt->begin++; + } + else + { + ASSERT(handle == end); + boundIt->end--; + } + return; + } + + ASSERT(begin < handle && handle < end); + + // need to split the range + auto placementIt = mUnallocatedList.erase(boundIt); + placementIt = mUnallocatedList.insert(placementIt, HandleRange(handle + 1, end)); + mUnallocatedList.insert(placementIt, HandleRange(begin, handle - 1)); +} + +void HandleAllocator::reset() +{ + mUnallocatedList.clear(); + mUnallocatedList.push_back(HandleRange(1, std::numeric_limits::max())); + mReleasedList.clear(); + mBaseValue = 1; + mNextValue = 1; +} + +void HandleAllocator::enableLogging(bool enabled) +{ + mLoggingEnabled = enabled; +} + +} // namespace gl -- cgit v1.2.3