Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: cc/resources/resource_pool.cc

Issue 43753002: cc: Keep track of busy resources in ResourcePool (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/resources/resource_pool.h" 5 #include "cc/resources/resource_pool.h"
6 6
7 #include "cc/resources/resource_provider.h" 7 #include "cc/resources/resource_provider.h"
8 8
9 namespace cc { 9 namespace cc {
10 10
(...skipping 11 matching lines...) Expand all
22 DCHECK(id()); 22 DCHECK(id());
23 } 23 }
24 24
25 ResourcePool::Resource::~Resource() { 25 ResourcePool::Resource::~Resource() {
26 DCHECK(id()); 26 DCHECK(id());
27 DCHECK(resource_provider_); 27 DCHECK(resource_provider_);
28 resource_provider_->DeleteResource(id()); 28 resource_provider_->DeleteResource(id());
29 } 29 }
30 30
31 ResourcePool::ResourcePool(ResourceProvider* resource_provider) 31 ResourcePool::ResourcePool(ResourceProvider* resource_provider)
32 : resource_provider_(resource_provider), 32 : resource_provider_(resource_provider->AsWeakPtr()),
33 max_memory_usage_bytes_(0), 33 max_memory_usage_bytes_(0),
34 max_unused_memory_usage_bytes_(0), 34 max_unused_memory_usage_bytes_(0),
35 max_resource_count_(0), 35 max_resource_count_(0),
36 memory_usage_bytes_(0), 36 memory_usage_bytes_(0),
37 unused_memory_usage_bytes_(0), 37 unused_memory_usage_bytes_(0),
38 resource_count_(0) { 38 resource_count_(0) {
39 resource_provider_->SetClient(this);
39 } 40 }
40 41
41 ResourcePool::~ResourcePool() { 42 ResourcePool::~ResourcePool() {
43 if (resource_provider_.get())
piman 2013/10/25 21:51:11 Can this be NULL? Below we SetResourceUsageLimits
jadahl 2013/10/28 09:59:30 I couldn't see any clearly structured order of whi
44 resource_provider_->SetClient(NULL);
42 SetResourceUsageLimits(0, 0, 0); 45 SetResourceUsageLimits(0, 0, 0);
43 } 46 }
44 47
45 scoped_ptr<ResourcePool::Resource> ResourcePool::AcquireResource( 48 scoped_ptr<ResourcePool::Resource> ResourcePool::AcquireResource(
46 gfx::Size size, ResourceFormat format) { 49 gfx::Size size, ResourceFormat format) {
47 for (ResourceList::iterator it = unused_resources_.begin(); 50 for (ResourceList::iterator it = unused_resources_.begin();
48 it != unused_resources_.end(); ++it) { 51 it != unused_resources_.end(); ++it) {
49 Resource* resource = *it; 52 Resource* resource = *it;
50 53
51 if (!resource_provider_->CanLockForWrite(resource->id())) 54 if (!resource_provider_->CanLockForWrite(resource->id()))
52 continue; 55 continue;
53 if (resource->size() != size) 56 if (resource->size() != size)
54 continue; 57 continue;
55 if (resource->format() != format) 58 if (resource->format() != format)
56 continue; 59 continue;
57 60
58 unused_resources_.erase(it); 61 unused_resources_.erase(it);
59 unused_memory_usage_bytes_ -= resource->bytes(); 62 unused_memory_usage_bytes_ -= resource->bytes();
60 return make_scoped_ptr(resource); 63 return make_scoped_ptr(resource);
61 } 64 }
62 65
63 // Create new resource. 66 // Create new resource.
64 Resource* resource = new Resource(resource_provider_, size, format); 67 Resource* resource = new Resource(resource_provider_.get(), size, format);
65 68
66 // Extend all read locks on all resources until the resource is 69 // Extend all read locks on all resources until the resource is
67 // finished being used, such that we know when resources are 70 // finished being used, such that we know when resources are
68 // truly safe to recycle. 71 // truly safe to recycle.
69 resource_provider_->EnableReadLockFences(resource->id(), true); 72 resource_provider_->EnableReadLockFences(resource->id(), true);
70 73
71 memory_usage_bytes_ += resource->bytes(); 74 memory_usage_bytes_ += resource->bytes();
72 ++resource_count_; 75 ++resource_count_;
73 return make_scoped_ptr(resource); 76 return make_scoped_ptr(resource);
74 } 77 }
75 78
76 void ResourcePool::ReleaseResource( 79 void ResourcePool::ReleaseResource(
77 scoped_ptr<ResourcePool::Resource> resource) { 80 scoped_ptr<ResourcePool::Resource> resource) {
78 if (ResourceUsageTooHigh()) { 81 if (ResourceUsageTooHigh()) {
79 memory_usage_bytes_ -= resource->bytes(); 82 memory_usage_bytes_ -= resource->bytes();
80 --resource_count_; 83 --resource_count_;
81 return; 84 return;
82 } 85 }
83 86
84 unused_memory_usage_bytes_ += resource->bytes(); 87 unused_memory_usage_bytes_ += resource->bytes();
85 unused_resources_.push_back(resource.release()); 88
89 if (resource_provider_->IsExported(resource->id()))
piman 2013/10/25 21:51:11 In PrioritizedResourceManager, we use InUseByConsu
jadahl 2013/10/28 09:59:30 As mentioned by reveman we can probably use CanLoc
90 exported_resources_.push_back(resource.release());
91 else
92 unused_resources_.push_back(resource.release());
86 } 93 }
87 94
88 void ResourcePool::SetResourceUsageLimits( 95 void ResourcePool::SetResourceUsageLimits(
89 size_t max_memory_usage_bytes, 96 size_t max_memory_usage_bytes,
90 size_t max_unused_memory_usage_bytes, 97 size_t max_unused_memory_usage_bytes,
91 size_t max_resource_count) { 98 size_t max_resource_count) {
92 max_memory_usage_bytes_ = max_memory_usage_bytes; 99 max_memory_usage_bytes_ = max_memory_usage_bytes;
93 max_unused_memory_usage_bytes_ = max_unused_memory_usage_bytes; 100 max_unused_memory_usage_bytes_ = max_unused_memory_usage_bytes;
94 max_resource_count_ = max_resource_count; 101 max_resource_count_ = max_resource_count;
95 102
96 ReduceResourceUsage(); 103 ReduceResourceUsage();
97 } 104 }
98 105
99 void ResourcePool::ReduceResourceUsage() { 106 void ResourcePool::ReduceResourceUsage() {
100 while (!unused_resources_.empty()) { 107 while (!unused_resources_.empty() && !exported_resources_.empty()) {
101 if (!ResourceUsageTooHigh()) 108 if (!ResourceUsageTooHigh())
102 break; 109 break;
103 110
104 // LRU eviction pattern. Most recently used might be blocked by 111 // LRU eviction pattern. Most recently used might be blocked by
105 // a read lock fence but it's still better to evict the least 112 // a read lock fence but it's still better to evict the least
106 // recently used as it prevents a resource that is hard to reuse 113 // recently used as it prevents a resource that is hard to reuse
107 // because of unique size from being kept around. Resources that 114 // because of unique size from being kept around. Resources that
108 // can't be locked for write might also not be truly free-able. 115 // can't be locked for write might also not be truly free-able.
109 // We can free the resource here but it doesn't mean that the 116 // We can free the resource here but it doesn't mean that the
110 // memory is necessarily returned to the OS. 117 // memory is necessarily returned to the OS.
111 Resource* resource = unused_resources_.front(); 118 //
112 unused_resources_.pop_front(); 119 // Start with non-exported resources first, as they are more likely
120 // to actually free up memory.
121 Resource* resource;
122 if (unused_resources_.empty()) {
123 resource = exported_resources_.front();
124 exported_resources_.pop_front();
125 } else {
126 resource = unused_resources_.front();
127 unused_resources_.pop_front();
128 }
113 memory_usage_bytes_ -= resource->bytes(); 129 memory_usage_bytes_ -= resource->bytes();
114 unused_memory_usage_bytes_ -= resource->bytes(); 130 unused_memory_usage_bytes_ -= resource->bytes();
115 --resource_count_; 131 --resource_count_;
116 delete resource; 132 delete resource;
117 } 133 }
118 } 134 }
119 135
120 bool ResourcePool::ResourceUsageTooHigh() { 136 bool ResourcePool::ResourceUsageTooHigh() {
121 if (resource_count_ > max_resource_count_) 137 if (resource_count_ > max_resource_count_)
122 return true; 138 return true;
123 if (memory_usage_bytes_ > max_memory_usage_bytes_) 139 if (memory_usage_bytes_ > max_memory_usage_bytes_)
124 return true; 140 return true;
125 if (unused_memory_usage_bytes_ > max_unused_memory_usage_bytes_) 141 if (unused_memory_usage_bytes_ > max_unused_memory_usage_bytes_)
126 return true; 142 return true;
127 return false; 143 return false;
128 } 144 }
129 145
146 void ResourcePool::ResourceExported(ResourceProvider::ResourceId id) {
piman 2013/10/25 21:51:11 I'm not a big fan of this. We'll pay that cost for
jadahl 2013/10/28 09:59:30 As mentioned before, we could probably rebuild the
147 for (ResourceList::iterator it = unused_resources_.begin();
148 it != unused_resources_.end();
149 ++it) {
150 if ((*it)->id() == id) {
151 exported_resources_.push_back(*it);
152 unused_resources_.erase(it);
153 break;
154 }
155 }
156 }
157
158 void ResourcePool::ResourceReturned(ResourceProvider::ResourceId id) {
159 for (ResourceList::iterator it = unused_resources_.begin();
160 it != unused_resources_.end();
161 ++it) {
162 if ((*it)->id() == id) {
163 unused_resources_.push_back(*it);
164 exported_resources_.erase(it);
165 break;
166 }
167 }
168 }
169
130 } // namespace cc 170 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698