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(); |
} |