| Index: gpu/command_buffer/common/id_allocator.cc
|
| diff --git a/gpu/command_buffer/common/id_allocator.cc b/gpu/command_buffer/common/id_allocator.cc
|
| index 507b14e9af19bfdd298f5b93362dc099f428c5f2..61d2c4a91135381921171a4d1fd0f418fbf77d06 100644
|
| --- a/gpu/command_buffer/common/id_allocator.cc
|
| +++ b/gpu/command_buffer/common/id_allocator.cc
|
| @@ -48,6 +48,71 @@ ResourceId IdAllocator::AllocateIDAtOrAbove(ResourceId desired_id) {
|
| return id;
|
| }
|
|
|
| +ResourceId IdAllocator::AllocateIDRange(uint32_t range) {
|
| + DCHECK(range > 0);
|
| + if (range == 1) {
|
| + return AllocateID();
|
| + }
|
| +
|
| + ResourceId first_id = kInvalidResource;
|
| +
|
| + {
|
| + // Try to re-use ids from free_ids.
|
| + ResourceIdSet::const_iterator iter = free_ids_.begin();
|
| + ResourceIdSet::const_iterator end = free_ids_.end();
|
| + const ResourceIdSet::size_type size = free_ids_.size();
|
| + if (iter != end && size >= range) {
|
| + ResourceId first = *iter;
|
| + ResourceIdSet::size_type needed_size = range;
|
| + ResourceId prev = first;
|
| + ++iter;
|
| + for (; iter != end && size >= needed_size; ++iter) {
|
| + if (prev + 1 == *iter) {
|
| + if (first + range - 1 == *iter) {
|
| + first_id = first;
|
| + break;
|
| + }
|
| + } else {
|
| + needed_size += prev - first + 1;
|
| + first = *iter;
|
| + }
|
| + prev = *iter;
|
| + }
|
| + }
|
| + }
|
| +
|
| + if (first_id == kInvalidResource) {
|
| + // Allocate after the last id.
|
| + ResourceId first = LastUsedId() + 1;
|
| + if (first != 0) {
|
| + ResourceId last = first + range - 1;
|
| + if (first < last) {
|
| + first_id = first;
|
| + }
|
| + }
|
| + }
|
| +
|
| + if (first_id == kInvalidResource) {
|
| + // Scan the gaps between used ids.
|
| + ResourceId prev = 0;
|
| + for (auto id : used_ids_) {
|
| + if (id - prev > range) {
|
| + first_id = prev + 1;
|
| + break;
|
| + }
|
| + prev = id;
|
| + }
|
| + }
|
| +
|
| + if (first_id != kInvalidResource) {
|
| + for (uint32 ii = 0; ii < range; ++ii) {
|
| + MarkAsUsed(first_id + ii);
|
| + }
|
| + }
|
| +
|
| + return first_id;
|
| +}
|
| +
|
| bool IdAllocator::MarkAsUsed(ResourceId id) {
|
| DCHECK(id);
|
| free_ids_.erase(id);
|
| @@ -62,6 +127,12 @@ void IdAllocator::FreeID(ResourceId id) {
|
| }
|
| }
|
|
|
| +void IdAllocator::FreeIDRange(ResourceId first_id, uint32 range) {
|
| + for (uint32 ii = 0; ii < range; ++ii) {
|
| + FreeID(first_id + ii);
|
| + }
|
| +}
|
| +
|
| bool IdAllocator::InUse(ResourceId id) const {
|
| return id == kInvalidResource || used_ids_.find(id) != used_ids_.end();
|
| }
|
|
|