OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef CC_RESOURCES_PRIORITIZED_RESOURCE_MANAGER_H_ | |
6 #define CC_RESOURCES_PRIORITIZED_RESOURCE_MANAGER_H_ | |
7 | |
8 #include <list> | |
9 #include <vector> | |
10 | |
11 #include "base/basictypes.h" | |
12 #include "base/containers/hash_tables.h" | |
13 #include "base/memory/scoped_ptr.h" | |
14 #include "base/synchronization/lock.h" | |
15 #include "cc/base/cc_export.h" | |
16 #include "cc/resources/prioritized_resource.h" | |
17 #include "cc/resources/priority_calculator.h" | |
18 #include "cc/resources/resource.h" | |
19 #include "ui/gfx/geometry/size.h" | |
20 | |
21 namespace cc { | |
22 | |
23 class Proxy; | |
24 | |
25 class CC_EXPORT PrioritizedResourceManager { | |
26 public: | |
27 static scoped_ptr<PrioritizedResourceManager> Create(const Proxy* proxy) { | |
28 return make_scoped_ptr(new PrioritizedResourceManager(proxy)); | |
29 } | |
30 scoped_ptr<PrioritizedResource> CreateTexture( | |
31 const gfx::Size& size, ResourceFormat format) { | |
32 return make_scoped_ptr(new PrioritizedResource(this, size, format)); | |
33 } | |
34 ~PrioritizedResourceManager(); | |
35 | |
36 typedef std::list<PrioritizedResource::Backing*> BackingList; | |
37 | |
38 // TODO(epenner): (http://crbug.com/137094) This 64MB default is a straggler | |
39 // from the old texture manager and is just to give us a default memory | |
40 // allocation before we get a callback from the GPU memory manager. We | |
41 // should probaby either: | |
42 // - wait for the callback before rendering anything instead | |
43 // - push this into the GPU memory manager somehow. | |
44 static size_t DefaultMemoryAllocationLimit() { return 64 * 1024 * 1024; } | |
45 | |
46 // MemoryUseBytes() describes the number of bytes used by existing allocated | |
47 // textures. | |
48 size_t MemoryUseBytes() const { return memory_use_bytes_; } | |
49 // MemoryAboveCutoffBytes() describes the number of bytes that | |
50 // would be used if all textures that are above the cutoff were allocated. | |
51 // MemoryUseBytes() <= MemoryAboveCutoffBytes() should always be true. | |
52 size_t MemoryAboveCutoffBytes() const { return memory_above_cutoff_bytes_; } | |
53 // MaxMemoryNeededBytes() describes the number of bytes that would be used | |
54 // by textures if there were no limit on memory usage. | |
55 size_t MaxMemoryNeededBytes() const { return max_memory_needed_bytes_; } | |
56 size_t MemoryForSelfManagedTextures() const { | |
57 return max_memory_limit_bytes_ - memory_available_bytes_; | |
58 } | |
59 | |
60 void SetMaxMemoryLimitBytes(size_t bytes) { max_memory_limit_bytes_ = bytes; } | |
61 size_t MaxMemoryLimitBytes() const { return max_memory_limit_bytes_; } | |
62 | |
63 // Sepecify a external priority cutoff. Only textures that have a strictly | |
64 // higher priority than this cutoff will be allowed. | |
65 void SetExternalPriorityCutoff(int priority_cutoff) { | |
66 external_priority_cutoff_ = priority_cutoff; | |
67 } | |
68 int ExternalPriorityCutoff() const { | |
69 return external_priority_cutoff_; | |
70 } | |
71 | |
72 // Return the amount of texture memory required at particular cutoffs. | |
73 size_t MemoryVisibleBytes() const; | |
74 size_t MemoryVisibleAndNearbyBytes() const; | |
75 | |
76 void PrioritizeTextures(); | |
77 void ClearPriorities(); | |
78 | |
79 // Delete contents textures' backing resources until they use only | |
80 // limit_bytes bytes. This may be called on the impl thread while the main | |
81 // thread is running. Returns true if resources are indeed evicted as a | |
82 // result of this call. | |
83 bool ReduceMemoryOnImplThread(size_t limit_bytes, | |
84 int priority_cutoff, | |
85 ResourceProvider* resource_provider); | |
86 | |
87 // Returns true if there exist any textures that are linked to backings that | |
88 // have had their resources evicted. Only when we commit a tree that has no | |
89 // textures linked to evicted backings may we allow drawing. After an | |
90 // eviction, this will not become true until unlinkAndClearEvictedBackings | |
91 // is called. | |
92 bool LinkedEvictedBackingsExist() const; | |
93 | |
94 // Unlink the list of contents textures' backings from their owning textures | |
95 // and delete the evicted backings' structures. This is called just before | |
96 // updating layers, and is only ever called on the main thread. | |
97 void UnlinkAndClearEvictedBackings(); | |
98 | |
99 bool RequestLate(PrioritizedResource* texture); | |
100 | |
101 void ReduceWastedMemory(ResourceProvider* resource_provider); | |
102 void ReduceMemory(ResourceProvider* resource_provider); | |
103 void ClearAllMemory(ResourceProvider* resource_provider); | |
104 | |
105 void AcquireBackingTextureIfNeeded(PrioritizedResource* texture, | |
106 ResourceProvider* resource_provider); | |
107 | |
108 void RegisterTexture(PrioritizedResource* texture); | |
109 void UnregisterTexture(PrioritizedResource* texture); | |
110 void ReturnBackingTexture(PrioritizedResource* texture); | |
111 | |
112 // Update all backings' priorities from their owning texture. | |
113 void PushTexturePrioritiesToBackings(); | |
114 | |
115 // Mark all textures' backings as being in the drawing impl tree. | |
116 void UpdateBackingsState(ResourceProvider* resource_provider); | |
117 | |
118 const Proxy* ProxyForDebug() const; | |
119 | |
120 private: | |
121 friend class PrioritizedResourceTest; | |
122 | |
123 enum EvictionPolicy { | |
124 EVICT_ONLY_RECYCLABLE, | |
125 EVICT_ANYTHING, | |
126 }; | |
127 enum UnlinkPolicy { | |
128 DO_NOT_UNLINK_BACKINGS, | |
129 UNLINK_BACKINGS, | |
130 }; | |
131 | |
132 // Compare textures. Highest priority first. | |
133 static inline bool CompareTextures(PrioritizedResource* a, | |
134 PrioritizedResource* b) { | |
135 if (a->request_priority() == b->request_priority()) | |
136 return a < b; | |
137 return PriorityCalculator::priority_is_higher(a->request_priority(), | |
138 b->request_priority()); | |
139 } | |
140 // Compare backings. Lowest priority first. | |
141 static inline bool CompareBackings(PrioritizedResource::Backing* a, | |
142 PrioritizedResource::Backing* b) { | |
143 // Make textures that can be recycled appear first. | |
144 if (a->CanBeRecycledIfNotInExternalUse() != | |
145 b->CanBeRecycledIfNotInExternalUse()) | |
146 return (a->CanBeRecycledIfNotInExternalUse() > | |
147 b->CanBeRecycledIfNotInExternalUse()); | |
148 // Then sort by being above or below the priority cutoff. | |
149 if (a->was_above_priority_cutoff_at_last_priority_update() != | |
150 b->was_above_priority_cutoff_at_last_priority_update()) | |
151 return (a->was_above_priority_cutoff_at_last_priority_update() < | |
152 b->was_above_priority_cutoff_at_last_priority_update()); | |
153 // Then sort by priority (note that backings that no longer have owners will | |
154 // always have the lowest priority). | |
155 if (a->request_priority_at_last_priority_update() != | |
156 b->request_priority_at_last_priority_update()) | |
157 return PriorityCalculator::priority_is_lower( | |
158 a->request_priority_at_last_priority_update(), | |
159 b->request_priority_at_last_priority_update()); | |
160 // Then sort by being in the impl tree versus being completely | |
161 // unreferenced. | |
162 if (a->in_drawing_impl_tree() != b->in_drawing_impl_tree()) | |
163 return (a->in_drawing_impl_tree() < b->in_drawing_impl_tree()); | |
164 // Finally, prefer to evict textures in the parent compositor because | |
165 // they will otherwise take another roundtrip to the parent compositor | |
166 // before they are evicted. | |
167 if (a->in_parent_compositor() != b->in_parent_compositor()) | |
168 return (a->in_parent_compositor() > b->in_parent_compositor()); | |
169 return a < b; | |
170 } | |
171 | |
172 explicit PrioritizedResourceManager(const Proxy* proxy); | |
173 | |
174 bool EvictBackingsToReduceMemory(size_t limit_bytes, | |
175 int priority_cutoff, | |
176 EvictionPolicy eviction_policy, | |
177 UnlinkPolicy unlink_policy, | |
178 ResourceProvider* resource_provider); | |
179 PrioritizedResource::Backing* CreateBacking( | |
180 const gfx::Size& size, | |
181 ResourceFormat format, | |
182 ResourceProvider* resource_provider); | |
183 void EvictFirstBackingResource(ResourceProvider* resource_provider); | |
184 void SortBackings(); | |
185 | |
186 void AssertInvariants(); | |
187 | |
188 size_t max_memory_limit_bytes_; | |
189 // The priority cutoff based on memory pressure. This is not a strict | |
190 // cutoff -- RequestLate allows textures with priority equal to this | |
191 // cutoff to be allowed. | |
192 int priority_cutoff_; | |
193 // The priority cutoff based on external memory policy. This is a strict | |
194 // cutoff -- no textures with priority equal to this cutoff will be allowed. | |
195 int external_priority_cutoff_; | |
196 size_t memory_use_bytes_; | |
197 size_t memory_above_cutoff_bytes_; | |
198 size_t max_memory_needed_bytes_; | |
199 size_t memory_available_bytes_; | |
200 | |
201 typedef base::hash_set<PrioritizedResource*> TextureSet; | |
202 typedef std::vector<PrioritizedResource*> TextureVector; | |
203 | |
204 const Proxy* proxy_; | |
205 | |
206 TextureSet textures_; | |
207 // This list is always sorted in eviction order, with the exception the | |
208 // newly-allocated or recycled textures at the very end of the tail that | |
209 // are not sorted by priority. | |
210 BackingList backings_; | |
211 bool backings_tail_not_sorted_; | |
212 | |
213 // The list of backings that have been evicted, but may still be linked | |
214 // to textures. This can be accessed concurrently by the main and impl | |
215 // threads, and may only be accessed while holding evicted_backings_lock_. | |
216 mutable base::Lock evicted_backings_lock_; | |
217 BackingList evicted_backings_; | |
218 | |
219 TextureVector temp_texture_vector_; | |
220 | |
221 // Statistics about memory usage at priority cutoffs, computed at | |
222 // PrioritizeTextures. | |
223 size_t memory_visible_bytes_; | |
224 size_t memory_visible_and_nearby_bytes_; | |
225 | |
226 // Statistics copied at the time of PushTexturePrioritiesToBackings. | |
227 size_t memory_visible_last_pushed_bytes_; | |
228 size_t memory_visible_and_nearby_last_pushed_bytes_; | |
229 | |
230 DISALLOW_COPY_AND_ASSIGN(PrioritizedResourceManager); | |
231 }; | |
232 | |
233 } // namespace cc | |
234 | |
235 #endif // CC_RESOURCES_PRIORITIZED_RESOURCE_MANAGER_H_ | |
OLD | NEW |