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

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

Issue 1154393003: cc: Use CheckedNumeric for resource size calculations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 months 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/prioritized_resource_manager.h" 5 #include "cc/resources/prioritized_resource_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
10 #include "cc/resources/prioritized_resource.h" 10 #include "cc/resources/prioritized_resource.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 // statistics. 63 // statistics.
64 memory_visible_bytes_ = 0; 64 memory_visible_bytes_ = 0;
65 memory_visible_and_nearby_bytes_ = 0; 65 memory_visible_and_nearby_bytes_ = 0;
66 for (TextureSet::iterator it = textures_.begin(); it != textures_.end(); 66 for (TextureSet::iterator it = textures_.begin(); it != textures_.end();
67 ++it) { 67 ++it) {
68 PrioritizedResource* texture = (*it); 68 PrioritizedResource* texture = (*it);
69 sorted_textures.push_back(texture); 69 sorted_textures.push_back(texture);
70 if (PriorityCalculator::priority_is_higher( 70 if (PriorityCalculator::priority_is_higher(
71 texture->request_priority(), 71 texture->request_priority(),
72 PriorityCalculator::AllowVisibleOnlyCutoff())) 72 PriorityCalculator::AllowVisibleOnlyCutoff()))
73 memory_visible_bytes_ += texture->bytes(); 73 memory_visible_bytes_ += Resource::UncheckedMemorySizeBytes(
74 texture->size(), texture->format());
74 if (PriorityCalculator::priority_is_higher( 75 if (PriorityCalculator::priority_is_higher(
75 texture->request_priority(), 76 texture->request_priority(),
76 PriorityCalculator::AllowVisibleAndNearbyCutoff())) 77 PriorityCalculator::AllowVisibleAndNearbyCutoff()))
77 memory_visible_and_nearby_bytes_ += texture->bytes(); 78 memory_visible_and_nearby_bytes_ += Resource::UncheckedMemorySizeBytes(
79 texture->size(), texture->format());
78 } 80 }
79 std::sort(sorted_textures.begin(), sorted_textures.end(), CompareTextures); 81 std::sort(sorted_textures.begin(), sorted_textures.end(), CompareTextures);
80 82
81 // Compute a priority cutoff based on memory pressure 83 // Compute a priority cutoff based on memory pressure
82 memory_available_bytes_ = max_memory_limit_bytes_; 84 memory_available_bytes_ = max_memory_limit_bytes_;
83 priority_cutoff_ = external_priority_cutoff_; 85 priority_cutoff_ = external_priority_cutoff_;
84 size_t memory_bytes = 0; 86 size_t memory_bytes = 0;
85 for (TextureVector::iterator it = sorted_textures.begin(); 87 for (TextureVector::iterator it = sorted_textures.begin();
86 it != sorted_textures.end(); 88 it != sorted_textures.end();
87 ++it) { 89 ++it) {
90 size_t texture_bytes =
91 Resource::UncheckedMemorySizeBytes((*it)->size(), (*it)->format());
88 if ((*it)->is_self_managed()) { 92 if ((*it)->is_self_managed()) {
89 // Account for self-managed memory immediately by reducing the memory 93 // Account for self-managed memory immediately by reducing the memory
90 // available (since it never gets acquired). 94 // available (since it never gets acquired).
91 size_t new_memory_bytes = memory_bytes + (*it)->bytes(); 95 size_t new_memory_bytes = memory_bytes + texture_bytes;
92 if (new_memory_bytes > memory_available_bytes_) { 96 if (new_memory_bytes > memory_available_bytes_) {
93 priority_cutoff_ = (*it)->request_priority(); 97 priority_cutoff_ = (*it)->request_priority();
94 memory_available_bytes_ = memory_bytes; 98 memory_available_bytes_ = memory_bytes;
95 break; 99 break;
96 } 100 }
97 memory_available_bytes_ -= (*it)->bytes(); 101 memory_available_bytes_ -= texture_bytes;
98 } else { 102 } else {
99 size_t new_memory_bytes = memory_bytes + (*it)->bytes(); 103 size_t new_memory_bytes = memory_bytes + texture_bytes;
100 if (new_memory_bytes > memory_available_bytes_) { 104 if (new_memory_bytes > memory_available_bytes_) {
101 priority_cutoff_ = (*it)->request_priority(); 105 priority_cutoff_ = (*it)->request_priority();
102 break; 106 break;
103 } 107 }
104 memory_bytes = new_memory_bytes; 108 memory_bytes = new_memory_bytes;
105 } 109 }
106 } 110 }
107 111
108 // Disallow any textures with priority below the external cutoff to have 112 // Disallow any textures with priority below the external cutoff to have
109 // backings. 113 // backings.
(...skipping 13 matching lines...) Expand all
123 max_memory_needed_bytes_ = 0; 127 max_memory_needed_bytes_ = 0;
124 memory_above_cutoff_bytes_ = 0; 128 memory_above_cutoff_bytes_ = 0;
125 for (TextureVector::iterator it = sorted_textures.begin(); 129 for (TextureVector::iterator it = sorted_textures.begin();
126 it != sorted_textures.end(); 130 it != sorted_textures.end();
127 ++it) { 131 ++it) {
128 PrioritizedResource* resource = *it; 132 PrioritizedResource* resource = *it;
129 bool is_above_priority_cutoff = PriorityCalculator::priority_is_higher( 133 bool is_above_priority_cutoff = PriorityCalculator::priority_is_higher(
130 resource->request_priority(), priority_cutoff_); 134 resource->request_priority(), priority_cutoff_);
131 resource->set_above_priority_cutoff(is_above_priority_cutoff); 135 resource->set_above_priority_cutoff(is_above_priority_cutoff);
132 if (!resource->is_self_managed()) { 136 if (!resource->is_self_managed()) {
133 max_memory_needed_bytes_ += resource->bytes(); 137 size_t resource_bytes = Resource::UncheckedMemorySizeBytes(
138 resource->size(), resource->format());
139 max_memory_needed_bytes_ += resource_bytes;
134 if (is_above_priority_cutoff) 140 if (is_above_priority_cutoff)
135 memory_above_cutoff_bytes_ += resource->bytes(); 141 memory_above_cutoff_bytes_ += resource_bytes;
136 } 142 }
137 } 143 }
138 sorted_textures.clear(); 144 sorted_textures.clear();
139 145
140 DCHECK_LE(memory_above_cutoff_bytes_, memory_available_bytes_); 146 DCHECK_LE(memory_above_cutoff_bytes_, memory_available_bytes_);
141 DCHECK_LE(MemoryAboveCutoffBytes(), MaxMemoryLimitBytes()); 147 DCHECK_LE(MemoryAboveCutoffBytes(), MaxMemoryLimitBytes());
142 } 148 }
143 149
144 void PrioritizedResourceManager::PushTexturePrioritiesToBackings() { 150 void PrioritizedResourceManager::PushTexturePrioritiesToBackings() {
145 TRACE_EVENT0("cc", 151 TRACE_EVENT0("cc",
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 if (PriorityCalculator::priority_is_lower(texture->request_priority(), 215 if (PriorityCalculator::priority_is_lower(texture->request_priority(),
210 priority_cutoff_)) 216 priority_cutoff_))
211 return false; 217 return false;
212 218
213 // Disallow textures that do not have a priority strictly higher than the 219 // Disallow textures that do not have a priority strictly higher than the
214 // external cutoff. 220 // external cutoff.
215 if (!PriorityCalculator::priority_is_higher(texture->request_priority(), 221 if (!PriorityCalculator::priority_is_higher(texture->request_priority(),
216 external_priority_cutoff_)) 222 external_priority_cutoff_))
217 return false; 223 return false;
218 224
219 size_t new_memory_bytes = memory_above_cutoff_bytes_ + texture->bytes(); 225 size_t new_memory_bytes =
226 memory_above_cutoff_bytes_ +
227 Resource::UncheckedMemorySizeBytes(texture->size(), texture->format());
220 if (new_memory_bytes > memory_available_bytes_) 228 if (new_memory_bytes > memory_available_bytes_)
221 return false; 229 return false;
222 230
223 memory_above_cutoff_bytes_ = new_memory_bytes; 231 memory_above_cutoff_bytes_ = new_memory_bytes;
224 texture->set_above_priority_cutoff(true); 232 texture->set_above_priority_cutoff(true);
225 return true; 233 return true;
226 } 234 }
227 235
228 void PrioritizedResourceManager::AcquireBackingTextureIfNeeded( 236 void PrioritizedResourceManager::AcquireBackingTextureIfNeeded(
229 PrioritizedResource* texture, 237 PrioritizedResource* texture,
(...skipping 17 matching lines...) Expand all
247 if ((*it)->size() == texture->size() && 255 if ((*it)->size() == texture->size() &&
248 (*it)->format() == texture->format()) { 256 (*it)->format() == texture->format()) {
249 backing = (*it); 257 backing = (*it);
250 backings_.erase(it); 258 backings_.erase(it);
251 break; 259 break;
252 } 260 }
253 } 261 }
254 262
255 // Otherwise reduce memory and just allocate a new backing texures. 263 // Otherwise reduce memory and just allocate a new backing texures.
256 if (!backing) { 264 if (!backing) {
257 EvictBackingsToReduceMemory(memory_available_bytes_ - texture->bytes(), 265 EvictBackingsToReduceMemory(
258 PriorityCalculator::AllowEverythingCutoff(), 266 memory_available_bytes_ - Resource::UncheckedMemorySizeBytes(
259 EVICT_ONLY_RECYCLABLE, 267 texture->size(), texture->format()),
260 DO_NOT_UNLINK_BACKINGS, 268 PriorityCalculator::AllowEverythingCutoff(), EVICT_ONLY_RECYCLABLE,
261 resource_provider); 269 DO_NOT_UNLINK_BACKINGS, resource_provider);
262 backing = 270 backing =
263 CreateBacking(texture->size(), texture->format(), resource_provider); 271 CreateBacking(texture->size(), texture->format(), resource_provider);
264 } 272 }
265 273
266 // Move the used backing to the end of the eviction list, and note that 274 // Move the used backing to the end of the eviction list, and note that
267 // the tail is not sorted. 275 // the tail is not sorted.
268 if (backing->owner()) 276 if (backing->owner())
269 backing->owner()->Unlink(); 277 backing->owner()->Unlink();
270 texture->Link(backing); 278 texture->Link(backing);
271 backings_.push_back(backing); 279 backings_.push_back(backing);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 // we really need very little memory. This should probably be solved by 324 // we really need very little memory. This should probably be solved by
317 // reducing the limit externally, but until then this just does some "clean 325 // reducing the limit externally, but until then this just does some "clean
318 // up" of unused backing textures (any more than 10%). 326 // up" of unused backing textures (any more than 10%).
319 size_t wasted_memory = 0; 327 size_t wasted_memory = 0;
320 for (BackingList::iterator it = backings_.begin(); it != backings_.end(); 328 for (BackingList::iterator it = backings_.begin(); it != backings_.end();
321 ++it) { 329 ++it) {
322 if ((*it)->owner()) 330 if ((*it)->owner())
323 break; 331 break;
324 if ((*it)->in_parent_compositor()) 332 if ((*it)->in_parent_compositor())
325 continue; 333 continue;
326 wasted_memory += (*it)->bytes(); 334 wasted_memory +=
335 Resource::UncheckedMemorySizeBytes((*it)->size(), (*it)->format());
327 } 336 }
328 size_t wasted_memory_to_allow = memory_available_bytes_ / 10; 337 size_t wasted_memory_to_allow = memory_available_bytes_ / 10;
329 // If the external priority cutoff indicates that unused memory should be 338 // If the external priority cutoff indicates that unused memory should be
330 // freed, then do not allow any memory for texture recycling. 339 // freed, then do not allow any memory for texture recycling.
331 if (external_priority_cutoff_ != PriorityCalculator::AllowEverythingCutoff()) 340 if (external_priority_cutoff_ != PriorityCalculator::AllowEverythingCutoff())
332 wasted_memory_to_allow = 0; 341 wasted_memory_to_allow = 0;
333 if (wasted_memory > wasted_memory_to_allow) 342 if (wasted_memory > wasted_memory_to_allow)
334 EvictBackingsToReduceMemory(MemoryUseBytes() - 343 EvictBackingsToReduceMemory(MemoryUseBytes() -
335 (wasted_memory - wasted_memory_to_allow), 344 (wasted_memory - wasted_memory_to_allow),
336 PriorityCalculator::AllowEverythingCutoff(), 345 PriorityCalculator::AllowEverythingCutoff(),
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 const gfx::Size& size, 456 const gfx::Size& size,
448 ResourceFormat format, 457 ResourceFormat format,
449 ResourceProvider* resource_provider) { 458 ResourceProvider* resource_provider) {
450 DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked()); 459 DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked());
451 DCHECK(resource_provider); 460 DCHECK(resource_provider);
452 ResourceId resource_id = resource_provider->CreateManagedResource( 461 ResourceId resource_id = resource_provider->CreateManagedResource(
453 size, GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, 462 size, GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
454 ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); 463 ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
455 PrioritizedResource::Backing* backing = new PrioritizedResource::Backing( 464 PrioritizedResource::Backing* backing = new PrioritizedResource::Backing(
456 resource_id, resource_provider, size, format); 465 resource_id, resource_provider, size, format);
457 memory_use_bytes_ += backing->bytes(); 466 memory_use_bytes_ +=
467 Resource::UncheckedMemorySizeBytes(backing->size(), backing->format());
458 return backing; 468 return backing;
459 } 469 }
460 470
461 void PrioritizedResourceManager::EvictFirstBackingResource( 471 void PrioritizedResourceManager::EvictFirstBackingResource(
462 ResourceProvider* resource_provider) { 472 ResourceProvider* resource_provider) {
463 DCHECK(proxy_->IsImplThread()); 473 DCHECK(proxy_->IsImplThread());
464 DCHECK(resource_provider); 474 DCHECK(resource_provider);
465 DCHECK(!backings_.empty()); 475 DCHECK(!backings_.empty());
466 PrioritizedResource::Backing* backing = backings_.front(); 476 PrioritizedResource::Backing* backing = backings_.front();
467 477
468 // Note that we create a backing and its resource at the same time, but we 478 // Note that we create a backing and its resource at the same time, but we
469 // delete the backing structure and its resource in two steps. This is because 479 // delete the backing structure and its resource in two steps. This is because
470 // we can delete the resource while the main thread is running, but we cannot 480 // we can delete the resource while the main thread is running, but we cannot
471 // unlink backings while the main thread is running. 481 // unlink backings while the main thread is running.
472 backing->DeleteResource(resource_provider); 482 backing->DeleteResource(resource_provider);
473 memory_use_bytes_ -= backing->bytes(); 483 memory_use_bytes_ -=
484 Resource::UncheckedMemorySizeBytes(backing->size(), backing->format());
474 backings_.pop_front(); 485 backings_.pop_front();
475 base::AutoLock scoped_lock(evicted_backings_lock_); 486 base::AutoLock scoped_lock(evicted_backings_lock_);
476 evicted_backings_.push_back(backing); 487 evicted_backings_.push_back(backing);
477 } 488 }
478 489
479 void PrioritizedResourceManager::AssertInvariants() { 490 void PrioritizedResourceManager::AssertInvariants() {
480 #if DCHECK_IS_ON() 491 #if DCHECK_IS_ON()
481 DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked()); 492 DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked());
482 493
483 // If we hit any of these asserts, there is a bug in this class. To see 494 // If we hit any of these asserts, there is a bug in this class. To see
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 previous_backing = backing; 548 previous_backing = backing;
538 } 549 }
539 #endif // DCHECK_IS_ON() 550 #endif // DCHECK_IS_ON()
540 } 551 }
541 552
542 const Proxy* PrioritizedResourceManager::ProxyForDebug() const { 553 const Proxy* PrioritizedResourceManager::ProxyForDebug() const {
543 return proxy_; 554 return proxy_;
544 } 555 }
545 556
546 } // namespace cc 557 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698