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

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

Issue 23231002: cc: Prevent the tile manager from allocating more memory than allowed. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 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 | Annotate | Revision Log
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 13 matching lines...) Expand all
24 ResourcePool::Resource::~Resource() { 24 ResourcePool::Resource::~Resource() {
25 DCHECK(id()); 25 DCHECK(id());
26 DCHECK(resource_provider_); 26 DCHECK(resource_provider_);
27 resource_provider_->DeleteResource(id()); 27 resource_provider_->DeleteResource(id());
28 } 28 }
29 29
30 ResourcePool::ResourcePool(ResourceProvider* resource_provider) 30 ResourcePool::ResourcePool(ResourceProvider* resource_provider)
31 : resource_provider_(resource_provider), 31 : resource_provider_(resource_provider),
32 max_memory_usage_bytes_(0), 32 max_memory_usage_bytes_(0),
33 max_unused_memory_usage_bytes_(0), 33 max_unused_memory_usage_bytes_(0),
34 max_resource_count_(0),
34 memory_usage_bytes_(0), 35 memory_usage_bytes_(0),
35 unused_memory_usage_bytes_(0), 36 unused_memory_usage_bytes_(0),
36 num_resources_limit_(0) { 37 resource_count_(0) {
37 } 38 }
38 39
39 ResourcePool::~ResourcePool() { 40 ResourcePool::~ResourcePool() {
40 SetMemoryUsageLimits(0, 0, 0); 41 SetMemoryUsageLimits(0, 0, 0);
41 } 42 }
42 43
43 scoped_ptr<ResourcePool::Resource> ResourcePool::AcquireResource( 44 scoped_ptr<ResourcePool::Resource> ResourcePool::AcquireResource(
44 gfx::Size size, GLenum format) { 45 gfx::Size size, GLenum format) {
45 for (ResourceList::iterator it = resources_.begin(); 46 for (ResourceList::iterator it = resources_.begin();
46 it != resources_.end(); ++it) { 47 it != resources_.end(); ++it) {
47 Resource* resource = *it; 48 Resource* resource = *it;
48 49
49 // TODO(epenner): It would be nice to DCHECK that this 50 // TODO(epenner): It would be nice to DCHECK that this
50 // doesn't happen two frames in a row for any resource 51 // doesn't happen two frames in a row for any resource
51 // in this pool. 52 // in this pool.
52 if (!resource_provider_->CanLockForWrite(resource->id())) 53 if (!resource_provider_->CanLockForWrite(resource->id()))
53 continue; 54 continue;
54 55
55 if (resource->size() != size) 56 if (resource->size() != size)
56 continue; 57 continue;
57 if (resource->format() != format) 58 if (resource->format() != format)
58 continue; 59 continue;
59 60
60 resources_.erase(it); 61 resources_.erase(it);
61 unused_memory_usage_bytes_ -= resource->bytes(); 62 unused_memory_usage_bytes_ -= resource->bytes();
62 return make_scoped_ptr(resource); 63 return make_scoped_ptr(resource);
63 } 64 }
64 65
65 // Create new resource. 66 // Create new resource.
66 Resource* resource = new Resource( 67 Resource* resource = new Resource(resource_provider_, size, format);
67 resource_provider_, size, format);
68 68
69 // Extend all read locks on all resources until the resource is 69 // Extend all read locks on all resources until the resource is
70 // finished being used, such that we know when resources are 70 // finished being used, such that we know when resources are
71 // truly safe to recycle. 71 // truly safe to recycle.
72 resource_provider_->EnableReadLockFences(resource->id(), true); 72 resource_provider_->EnableReadLockFences(resource->id(), true);
73 73
74 memory_usage_bytes_ += resource->bytes(); 74 memory_usage_bytes_ += resource->bytes();
75 ++resource_count_;
75 return make_scoped_ptr(resource); 76 return make_scoped_ptr(resource);
76 } 77 }
77 78
78 void ResourcePool::ReleaseResource( 79 void ResourcePool::ReleaseResource(
79 scoped_ptr<ResourcePool::Resource> resource) { 80 scoped_ptr<ResourcePool::Resource> resource) {
80 if (MemoryUsageTooHigh()) { 81 if (MemoryUsageTooHigh()) {
81 memory_usage_bytes_ -= resource->bytes(); 82 memory_usage_bytes_ -= resource->bytes();
83 --resource_count_;
82 return; 84 return;
83 } 85 }
84 86
85 unused_memory_usage_bytes_ += resource->bytes(); 87 unused_memory_usage_bytes_ += resource->bytes();
86 resources_.push_back(resource.release()); 88 resources_.push_back(resource.release());
87 } 89 }
88 90
89 void ResourcePool::SetMemoryUsageLimits( 91 void ResourcePool::SetMemoryUsageLimits(
90 size_t max_memory_usage_bytes, 92 size_t max_memory_usage_bytes,
91 size_t max_unused_memory_usage_bytes, 93 size_t max_unused_memory_usage_bytes,
92 size_t num_resources_limit) { 94 size_t max_resource_count) {
93 max_memory_usage_bytes_ = max_memory_usage_bytes; 95 max_memory_usage_bytes_ = max_memory_usage_bytes;
94 max_unused_memory_usage_bytes_ = max_unused_memory_usage_bytes; 96 max_unused_memory_usage_bytes_ = max_unused_memory_usage_bytes;
95 num_resources_limit_ = num_resources_limit; 97 max_resource_count_ = max_resource_count;
96 98
99 ReduceMemoryUsage();
100 }
101
102 void ResourcePool::ReduceMemoryUsage() {
97 while (!resources_.empty()) { 103 while (!resources_.empty()) {
98 if (!MemoryUsageTooHigh()) 104 if (!MemoryUsageTooHigh())
99 break; 105 break;
100 106
101 // MRU eviction pattern as least recently used is less likely to 107 // MRU eviction pattern as least recently used is less likely to
102 // be blocked by read lock fence. 108 // be blocked by read lock fence.
103 Resource* resource = resources_.back(); 109 Resource* resource = resources_.back();
104 resources_.pop_back(); 110 resources_.pop_back();
105 memory_usage_bytes_ -= resource->bytes(); 111 memory_usage_bytes_ -= resource->bytes();
106 unused_memory_usage_bytes_ -= resource->bytes(); 112 unused_memory_usage_bytes_ -= resource->bytes();
113 --resource_count_;
107 delete resource; 114 delete resource;
108 } 115 }
109 } 116 }
110 117
111 bool ResourcePool::MemoryUsageTooHigh() { 118 bool ResourcePool::MemoryUsageTooHigh() {
112 if (resources_.size() > num_resources_limit_) 119 if (resource_count_ > max_resource_count_)
113 return true; 120 return true;
114 if (memory_usage_bytes_ > max_memory_usage_bytes_) 121 if (memory_usage_bytes_ > max_memory_usage_bytes_)
115 return true; 122 return true;
116 if (unused_memory_usage_bytes_ > max_unused_memory_usage_bytes_) 123 if (unused_memory_usage_bytes_ > max_unused_memory_usage_bytes_)
117 return true; 124 return true;
118 return false; 125 return false;
119 } 126 }
120 127
121 } // namespace cc 128 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698