Index: cc/resources/resource_provider.cc |
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc |
index 4e7b2c416de288d5ec5afa53bedb7121c619ebd1..1e7c9d783de800b4a776122ed7d97e1f2fe116ab 100644 |
--- a/cc/resources/resource_provider.cc |
+++ b/cc/resources/resource_provider.cc |
@@ -799,12 +799,11 @@ void ResourceProvider::DeleteResource(ResourceId id) { |
ResourceMap::iterator it = resources_.find(id); |
CHECK(it != resources_.end()); |
Resource* resource = &it->second; |
- DCHECK(!resource->lock_for_read_count); |
DCHECK(!resource->marked_for_deletion); |
DCHECK_EQ(resource->imported_count, 0); |
DCHECK(resource->pending_set_pixels || !resource->locked_for_write); |
- if (resource->exported_count > 0) { |
+ if (resource->exported_count > 0 || resource->lock_for_read_count > 0) { |
resource->marked_for_deletion = true; |
return; |
} else { |
@@ -1087,10 +1086,25 @@ const ResourceProvider::Resource* ResourceProvider::LockForRead(ResourceId id) { |
} |
void ResourceProvider::UnlockForRead(ResourceId id) { |
- Resource* resource = GetResource(id); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ ResourceMap::iterator it = resources_.find(id); |
+ CHECK(it != resources_.end()); |
+ |
+ Resource* resource = &it->second; |
DCHECK_GT(resource->lock_for_read_count, 0); |
DCHECK_EQ(resource->exported_count, 0); |
resource->lock_for_read_count--; |
+ if (resource->marked_for_deletion && !resource->lock_for_read_count) { |
+ if (!resource->child_id) { |
+ // The resource belongs to this ResourceProvider, so it can be destroyed. |
+ DeleteResourceInternal(it, Normal); |
+ } else { |
+ ChildMap::iterator child_it = children_.find(resource->child_id); |
+ ResourceIdArray unused; |
+ unused.push_back(id); |
+ DeleteAndReturnUnusedResourcesToChild(child_it, Normal, unused); |
+ } |
+ } |
} |
const ResourceProvider::Resource* ResourceProvider::LockForWrite( |
@@ -1647,7 +1661,6 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild( |
Resource& resource = it->second; |
DCHECK(!resource.locked_for_write); |
- DCHECK(!resource.lock_for_read_count); |
DCHECK_EQ(0u, child_info->in_use_resources.count(local_id)); |
DCHECK(child_info->parent_to_child_map.count(local_id)); |
@@ -1656,9 +1669,10 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild( |
bool is_lost = |
resource.lost || (resource.type == GLTexture && lost_output_surface_); |
- if (resource.exported_count > 0) { |
+ if (resource.exported_count > 0 || resource.lock_for_read_count > 0) { |
if (style != ForShutdown) { |
- // Defer this until we receive the resource back from the parent. |
+ // Defer this until we receive the resource back from the parent or |
+ // the read lock is released. |
resource.marked_for_deletion = true; |
continue; |
} |