Index: cc/resources/resource_pool.cc |
diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc |
index 0ec24005a49e8e40af31fc771f559a69fbd83845..469f790f28c0ecdc40447f11cbd06a765366c896 100644 |
--- a/cc/resources/resource_pool.cc |
+++ b/cc/resources/resource_pool.cc |
@@ -133,36 +133,85 @@ Resource* ResourcePool::AcquireResource(const gfx::Size& size, |
pool_resource->size(), pool_resource->format()); |
++total_resource_count_; |
+ // Clear the invalidated rect and content ID, as we are about to raster new |
+ // content. These will be re-set when rasterization completes successfully. |
+ pool_resource->set_invalidated_rect(gfx::Rect()); |
+ pool_resource->set_content_id(0); |
+ |
Resource* resource = pool_resource.get(); |
in_use_resources_[resource->id()] = std::move(pool_resource); |
in_use_memory_usage_bytes_ += ResourceUtil::UncheckedSizeInBytes<size_t>( |
resource->size(), resource->format()); |
+ |
return resource; |
} |
-Resource* ResourcePool::TryAcquireResourceWithContentId(uint64_t content_id) { |
- DCHECK(content_id); |
- |
- auto it = std::find_if( |
+Resource* ResourcePool::TryAcquireResourceForPartialRaster( |
+ uint64_t new_content_id, |
+ const gfx::Rect& new_invalidated_rect, |
+ uint64_t previous_content_id, |
+ gfx::Rect* total_invalidated_rect) { |
+ DCHECK(new_content_id); |
+ DCHECK(previous_content_id); |
+ *total_invalidated_rect = gfx::Rect(); |
+ |
+ // Try to find |previous_content_id| in |unused_resources_|. |
+ auto found_unused = std::find_if( |
unused_resources_.begin(), unused_resources_.end(), |
- [content_id](const std::unique_ptr<PoolResource>& pool_resource) { |
- return pool_resource->content_id() == content_id; |
+ [previous_content_id](const ResourceDeque::value_type& pool_resource) { |
+ return pool_resource->content_id() == previous_content_id; |
}); |
- if (it == unused_resources_.end()) |
- return nullptr; |
+ if (found_unused != unused_resources_.end()) { |
+ PoolResource* found_resource = found_unused->get(); |
+ DCHECK(resource_provider_->CanLockForWrite(found_resource->id())); |
- Resource* resource = it->get(); |
- DCHECK(resource_provider_->CanLockForWrite(resource->id())); |
+ // Transfer resource to |in_use_resources_|. |
+ in_use_resources_[found_resource->id()] = std::move(*found_unused); |
+ unused_resources_.erase(found_unused); |
+ in_use_memory_usage_bytes_ += ResourceUtil::UncheckedSizeInBytes<size_t>( |
+ found_resource->size(), found_resource->format()); |
- // Transfer resource to |in_use_resources_|. |
- in_use_resources_[resource->id()] = std::move(*it); |
- unused_resources_.erase(it); |
- in_use_memory_usage_bytes_ += ResourceUtil::UncheckedSizeInBytes<size_t>( |
- resource->size(), resource->format()); |
- return resource; |
+ *total_invalidated_rect = new_invalidated_rect; |
+ if (!found_resource->invalidated_rect().IsEmpty()) |
+ total_invalidated_rect->Union(found_resource->invalidated_rect()); |
+ |
+ // Clear the invalidated rect and content ID on the resource being retunred. |
+ // These will be updated when raster completes successfully. |
+ found_resource->set_invalidated_rect(gfx::Rect()); |
+ found_resource->set_content_id(0); |
+ |
+ return found_resource; |
+ } |
+ |
+ // Couldn't find an unused previous resource. If possible, update the |
+ // invalidation on the in-use resource to allow for future partial raster. |
+ // |
+ // We could update all in-use resources (rather than just the first one we |
+ // find), however the latency on resources being returned by the browser |
+ // is typically one frame, so this extra searching would be largely wasted. |
+ // |
+ // Skipping any additional resources is not a correctness risk, as the |
+ // un-updated resources will have their old content ID, and will not be found |
+ // by future partial raster searches, which will use the new content ID. |
+ auto found_in_use = std::find_if( |
+ in_use_resources_.begin(), in_use_resources_.end(), |
+ [previous_content_id](const InUseResourceMap::value_type& in_use_entry) { |
+ return in_use_entry.second->content_id() == previous_content_id; |
+ }); |
+ if (found_in_use != in_use_resources_.end()) { |
+ PoolResource* found_resource = found_in_use->second.get(); |
+ gfx::Rect updated_invalidated_rect = new_invalidated_rect; |
+ if (!found_resource->invalidated_rect().IsEmpty()) |
+ updated_invalidated_rect.Union(found_resource->invalidated_rect()); |
+ |
+ found_resource->set_content_id(new_content_id); |
+ found_resource->set_invalidated_rect(updated_invalidated_rect); |
+ } |
+ |
+ return nullptr; |
} |
-void ResourcePool::ReleaseResource(Resource* resource, uint64_t content_id) { |
+void ResourcePool::ReleaseResource(Resource* resource) { |
// Ensure that the provided resource is valid. |
// TODO(ericrk): Remove this once we've investigated further. |
// crbug.com/598286. |
@@ -202,7 +251,6 @@ void ResourcePool::ReleaseResource(Resource* resource, uint64_t content_id) { |
CHECK(it->second.get()); |
PoolResource* pool_resource = it->second.get(); |
- pool_resource->set_content_id(content_id); |
pool_resource->set_last_usage(base::TimeTicks::Now()); |
// Transfer resource to |busy_resources_|. |
@@ -216,6 +264,14 @@ void ResourcePool::ReleaseResource(Resource* resource, uint64_t content_id) { |
ScheduleEvictExpiredResourcesIn(resource_expiration_delay_); |
} |
+void ResourcePool::OnContentReplaced(ResourceId resource_id, |
+ uint64_t content_id) { |
+ auto found = in_use_resources_.find(resource_id); |
+ DCHECK(found != in_use_resources_.end()); |
+ found->second->set_content_id(content_id); |
+ found->second->set_invalidated_rect(gfx::Rect()); |
+} |
+ |
void ResourcePool::SetResourceUsageLimits(size_t max_memory_usage_bytes, |
size_t max_resource_count) { |
max_memory_usage_bytes_ = max_memory_usage_bytes; |