| 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 |