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

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

Issue 1441613002: cc: Remove ScopedPtrDeque. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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 <algorithm> 7 #include <algorithm>
8 8
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
11 #include "base/thread_task_runner_handle.h" 11 #include "base/thread_task_runner_handle.h"
12 #include "base/trace_event/memory_dump_manager.h" 12 #include "base/trace_event/memory_dump_manager.h"
13 #include "cc/base/container_util.h"
13 #include "cc/resources/resource_provider.h" 14 #include "cc/resources/resource_provider.h"
14 #include "cc/resources/resource_util.h" 15 #include "cc/resources/resource_util.h"
15 #include "cc/resources/scoped_resource.h" 16 #include "cc/resources/scoped_resource.h"
16 17
17 namespace cc { 18 namespace cc {
18 namespace { 19 namespace {
19 20
20 // Delay before a resource is considered expired. 21 // Delay before a resource is considered expired.
21 const int kResourceExpirationDelayMs = 1000; 22 const int kResourceExpirationDelayMs = 1000;
22 23
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 this, "cc::ResourcePool", task_runner_.get()); 73 this, "cc::ResourcePool", task_runner_.get());
73 } 74 }
74 75
75 ResourcePool::~ResourcePool() { 76 ResourcePool::~ResourcePool() {
76 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( 77 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
77 this); 78 this);
78 79
79 DCHECK_EQ(0u, in_use_resources_.size()); 80 DCHECK_EQ(0u, in_use_resources_.size());
80 81
81 while (!busy_resources_.empty()) { 82 while (!busy_resources_.empty()) {
82 DidFinishUsingResource(busy_resources_.take_back()); 83 DidFinishUsingResource(TakeBack(&busy_resources_));
83 } 84 }
84 85
85 SetResourceUsageLimits(0, 0); 86 SetResourceUsageLimits(0, 0);
86 DCHECK_EQ(0u, unused_resources_.size()); 87 DCHECK_EQ(0u, unused_resources_.size());
87 DCHECK_EQ(0u, in_use_memory_usage_bytes_); 88 DCHECK_EQ(0u, in_use_memory_usage_bytes_);
88 DCHECK_EQ(0u, total_memory_usage_bytes_); 89 DCHECK_EQ(0u, total_memory_usage_bytes_);
89 DCHECK_EQ(0u, total_resource_count_); 90 DCHECK_EQ(0u, total_resource_count_);
90 } 91 }
91 92
92 Resource* ResourcePool::AcquireResource(const gfx::Size& size, 93 Resource* ResourcePool::AcquireResource(const gfx::Size& size,
93 ResourceFormat format) { 94 ResourceFormat format) {
94 // Finding resources in |unused_resources_| from MRU to LRU direction, touches 95 // Finding resources in |unused_resources_| from MRU to LRU direction, touches
95 // LRU resources only if needed, which increases possibility of expiring more 96 // LRU resources only if needed, which increases possibility of expiring more
96 // LRU resources within kResourceExpirationDelayMs. 97 // LRU resources within kResourceExpirationDelayMs.
97 for (ResourceDeque::iterator it = unused_resources_.begin(); 98 for (ResourceDeque::iterator it = unused_resources_.begin();
98 it != unused_resources_.end(); ++it) { 99 it != unused_resources_.end(); ++it) {
99 ScopedResource* resource = *it; 100 ScopedResource* resource = it->get();
100 DCHECK(resource_provider_->CanLockForWrite(resource->id())); 101 DCHECK(resource_provider_->CanLockForWrite(resource->id()));
101 102
102 if (resource->format() != format) 103 if (resource->format() != format)
103 continue; 104 continue;
104 if (resource->size() != size) 105 if (resource->size() != size)
105 continue; 106 continue;
106 107
107 // Transfer resource to |in_use_resources_|. 108 // Transfer resource to |in_use_resources_|.
108 in_use_resources_.set(resource->id(), unused_resources_.take(it)); 109 in_use_resources_.set(resource->id(), it->Pass());
110 unused_resources_.erase(it);
109 in_use_memory_usage_bytes_ += ResourceUtil::UncheckedSizeInBytes<size_t>( 111 in_use_memory_usage_bytes_ += ResourceUtil::UncheckedSizeInBytes<size_t>(
110 resource->size(), resource->format()); 112 resource->size(), resource->format());
111 return resource; 113 return resource;
112 } 114 }
113 115
114 scoped_ptr<PoolResource> pool_resource = 116 scoped_ptr<PoolResource> pool_resource =
115 PoolResource::Create(resource_provider_); 117 PoolResource::Create(resource_provider_);
116 118
117 if (use_image_texture_target_) { 119 if (use_image_texture_target_) {
118 pool_resource->AllocateWithImageTextureTarget(size, format); 120 pool_resource->AllocateWithImageTextureTarget(size, format);
(...skipping 11 matching lines...) Expand all
130 Resource* resource = pool_resource.get(); 132 Resource* resource = pool_resource.get();
131 in_use_resources_.set(resource->id(), pool_resource.Pass()); 133 in_use_resources_.set(resource->id(), pool_resource.Pass());
132 in_use_memory_usage_bytes_ += ResourceUtil::UncheckedSizeInBytes<size_t>( 134 in_use_memory_usage_bytes_ += ResourceUtil::UncheckedSizeInBytes<size_t>(
133 resource->size(), resource->format()); 135 resource->size(), resource->format());
134 return resource; 136 return resource;
135 } 137 }
136 138
137 Resource* ResourcePool::TryAcquireResourceWithContentId(uint64_t content_id) { 139 Resource* ResourcePool::TryAcquireResourceWithContentId(uint64_t content_id) {
138 DCHECK(content_id); 140 DCHECK(content_id);
139 141
140 auto it = std::find_if(unused_resources_.begin(), unused_resources_.end(), 142 auto it =
141 [content_id](const PoolResource* pool_resource) { 143 std::find_if(unused_resources_.begin(), unused_resources_.end(),
142 return pool_resource->content_id() == content_id; 144 [content_id](const scoped_ptr<PoolResource>& pool_resource) {
143 }); 145 return pool_resource->content_id() == content_id;
146 });
144 if (it == unused_resources_.end()) 147 if (it == unused_resources_.end())
145 return nullptr; 148 return nullptr;
146 149
147 Resource* resource = *it; 150 Resource* resource = it->get();
148 DCHECK(resource_provider_->CanLockForWrite(resource->id())); 151 DCHECK(resource_provider_->CanLockForWrite(resource->id()));
149 152
150 // Transfer resource to |in_use_resources_|. 153 // Transfer resource to |in_use_resources_|.
151 in_use_resources_.set(resource->id(), unused_resources_.take(it)); 154 in_use_resources_.set(resource->id(), it->Pass());
155 unused_resources_.erase(it);
152 in_use_memory_usage_bytes_ += ResourceUtil::UncheckedSizeInBytes<size_t>( 156 in_use_memory_usage_bytes_ += ResourceUtil::UncheckedSizeInBytes<size_t>(
153 resource->size(), resource->format()); 157 resource->size(), resource->format());
154 return resource; 158 return resource;
155 } 159 }
156 160
157 void ResourcePool::ReleaseResource(Resource* resource, uint64_t content_id) { 161 void ResourcePool::ReleaseResource(Resource* resource, uint64_t content_id) {
158 auto it = in_use_resources_.find(resource->id()); 162 auto it = in_use_resources_.find(resource->id());
159 DCHECK(it != in_use_resources_.end()); 163 DCHECK(it != in_use_resources_.end());
160 164
161 PoolResource* pool_resource = it->second; 165 PoolResource* pool_resource = it->second;
(...skipping 23 matching lines...) Expand all
185 if (!ResourceUsageTooHigh()) 189 if (!ResourceUsageTooHigh())
186 break; 190 break;
187 191
188 // LRU eviction pattern. Most recently used might be blocked by 192 // LRU eviction pattern. Most recently used might be blocked by
189 // a read lock fence but it's still better to evict the least 193 // a read lock fence but it's still better to evict the least
190 // recently used as it prevents a resource that is hard to reuse 194 // recently used as it prevents a resource that is hard to reuse
191 // because of unique size from being kept around. Resources that 195 // because of unique size from being kept around. Resources that
192 // can't be locked for write might also not be truly free-able. 196 // can't be locked for write might also not be truly free-able.
193 // We can free the resource here but it doesn't mean that the 197 // We can free the resource here but it doesn't mean that the
194 // memory is necessarily returned to the OS. 198 // memory is necessarily returned to the OS.
195 DeleteResource(unused_resources_.take_back()); 199 DeleteResource(TakeBack(&unused_resources_));
196 } 200 }
197 } 201 }
198 202
199 bool ResourcePool::ResourceUsageTooHigh() { 203 bool ResourcePool::ResourceUsageTooHigh() {
200 if (total_resource_count_ > max_resource_count_) 204 if (total_resource_count_ > max_resource_count_)
201 return true; 205 return true;
202 if (total_memory_usage_bytes_ > max_memory_usage_bytes_) 206 if (total_memory_usage_bytes_ > max_memory_usage_bytes_)
203 return true; 207 return true;
204 return false; 208 return false;
205 } 209 }
206 210
207 void ResourcePool::DeleteResource(scoped_ptr<PoolResource> resource) { 211 void ResourcePool::DeleteResource(scoped_ptr<PoolResource> resource) {
208 size_t resource_bytes = ResourceUtil::UncheckedSizeInBytes<size_t>( 212 size_t resource_bytes = ResourceUtil::UncheckedSizeInBytes<size_t>(
209 resource->size(), resource->format()); 213 resource->size(), resource->format());
210 total_memory_usage_bytes_ -= resource_bytes; 214 total_memory_usage_bytes_ -= resource_bytes;
211 --total_resource_count_; 215 --total_resource_count_;
212 } 216 }
213 217
214 void ResourcePool::CheckBusyResources() { 218 void ResourcePool::CheckBusyResources() {
215 for (size_t i = 0; i < busy_resources_.size();) { 219 for (size_t i = 0; i < busy_resources_.size();) {
216 ResourceDeque::iterator it(busy_resources_.begin() + i); 220 ResourceDeque::iterator it(busy_resources_.begin() + i);
217 PoolResource* resource = *it; 221 PoolResource* resource = it->get();
218 222
219 if (resource_provider_->CanLockForWrite(resource->id())) { 223 if (resource_provider_->CanLockForWrite(resource->id())) {
220 DidFinishUsingResource(busy_resources_.take(it)); 224 DidFinishUsingResource(it->Pass());
225 busy_resources_.erase(it);
221 } else if (resource_provider_->IsLost(resource->id())) { 226 } else if (resource_provider_->IsLost(resource->id())) {
222 // Remove lost resources from pool. 227 // Remove lost resources from pool.
223 DeleteResource(busy_resources_.take(it)); 228 DeleteResource(it->Pass());
229 busy_resources_.erase(it);
224 } else { 230 } else {
225 ++i; 231 ++i;
226 } 232 }
227 } 233 }
228 } 234 }
229 235
230 void ResourcePool::DidFinishUsingResource(scoped_ptr<PoolResource> resource) { 236 void ResourcePool::DidFinishUsingResource(scoped_ptr<PoolResource> resource) {
231 unused_resources_.push_front(resource.Pass()); 237 unused_resources_.push_front(resource.Pass());
232 } 238 }
233 239
(...skipping 29 matching lines...) Expand all
263 269
264 void ResourcePool::EvictResourcesNotUsedSince(base::TimeTicks time_limit) { 270 void ResourcePool::EvictResourcesNotUsedSince(base::TimeTicks time_limit) {
265 while (!unused_resources_.empty()) { 271 while (!unused_resources_.empty()) {
266 // |unused_resources_| is not strictly ordered with regards to last_usage, 272 // |unused_resources_| is not strictly ordered with regards to last_usage,
267 // as this may not exactly line up with the time a resource became non-busy. 273 // as this may not exactly line up with the time a resource became non-busy.
268 // However, this should be roughly ordered, and will only introduce slight 274 // However, this should be roughly ordered, and will only introduce slight
269 // delays in freeing expired resources. 275 // delays in freeing expired resources.
270 if (unused_resources_.back()->last_usage() > time_limit) 276 if (unused_resources_.back()->last_usage() > time_limit)
271 return; 277 return;
272 278
273 DeleteResource(unused_resources_.take_back()); 279 DeleteResource(TakeBack(&unused_resources_));
274 } 280 }
275 281
276 // Also free busy resources older than the delay. With a sufficiently large 282 // Also free busy resources older than the delay. With a sufficiently large
277 // delay, such as the 1 second used here, any "busy" resources which have 283 // delay, such as the 1 second used here, any "busy" resources which have
278 // expired are not likely to be busy. Additionally, freeing a "busy" resource 284 // expired are not likely to be busy. Additionally, freeing a "busy" resource
279 // has no downside other than incorrect accounting. 285 // has no downside other than incorrect accounting.
280 while (!busy_resources_.empty()) { 286 while (!busy_resources_.empty()) {
281 if (busy_resources_.back()->last_usage() > time_limit) 287 if (busy_resources_.back()->last_usage() > time_limit)
282 return; 288 return;
283 289
284 DeleteResource(busy_resources_.take_back()); 290 DeleteResource(TakeBack(&busy_resources_));
285 } 291 }
286 } 292 }
287 293
288 base::TimeTicks ResourcePool::GetUsageTimeForLRUResource() const { 294 base::TimeTicks ResourcePool::GetUsageTimeForLRUResource() const {
289 if (!unused_resources_.empty()) { 295 if (!unused_resources_.empty()) {
290 return unused_resources_.back()->last_usage(); 296 return unused_resources_.back()->last_usage();
291 } 297 }
292 298
293 // This is only called when we have at least one evictable resource. 299 // This is only called when we have at least one evictable resource.
294 DCHECK(!busy_resources_.empty()); 300 DCHECK(!busy_resources_.empty());
295 return busy_resources_.back()->last_usage(); 301 return busy_resources_.back()->last_usage();
296 } 302 }
297 303
298 bool ResourcePool::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, 304 bool ResourcePool::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
299 base::trace_event::ProcessMemoryDump* pmd) { 305 base::trace_event::ProcessMemoryDump* pmd) {
300 for (const auto& resource : unused_resources_) { 306 for (const auto& resource : unused_resources_) {
301 resource->OnMemoryDump(pmd, resource_provider_, true /* is_free */); 307 resource->OnMemoryDump(pmd, resource_provider_, true /* is_free */);
302 } 308 }
303 for (const auto& resource : busy_resources_) { 309 for (const auto& resource : busy_resources_) {
304 resource->OnMemoryDump(pmd, resource_provider_, false /* is_free */); 310 resource->OnMemoryDump(pmd, resource_provider_, false /* is_free */);
305 } 311 }
306 for (const auto& entry : in_use_resources_) { 312 for (const auto& entry : in_use_resources_) {
307 entry.second->OnMemoryDump(pmd, resource_provider_, false /* is_free */); 313 entry.second->OnMemoryDump(pmd, resource_provider_, false /* is_free */);
308 } 314 }
309 return true; 315 return true;
310 } 316 }
311 317
312 } // namespace cc 318 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698