diff options
Diffstat (limited to 'chromium/cc/resources/prioritized_resource_manager.h')
-rw-r--r-- | chromium/cc/resources/prioritized_resource_manager.h | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/chromium/cc/resources/prioritized_resource_manager.h b/chromium/cc/resources/prioritized_resource_manager.h new file mode 100644 index 00000000000..73967727c2c --- /dev/null +++ b/chromium/cc/resources/prioritized_resource_manager.h @@ -0,0 +1,241 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_RESOURCES_PRIORITIZED_RESOURCE_MANAGER_H_ +#define CC_RESOURCES_PRIORITIZED_RESOURCE_MANAGER_H_ + +#include <list> +#include <vector> + +#include "base/basictypes.h" +#include "base/containers/hash_tables.h" +#include "base/memory/scoped_ptr.h" +#include "base/synchronization/lock.h" +#include "cc/base/cc_export.h" +#include "cc/resources/prioritized_resource.h" +#include "cc/resources/priority_calculator.h" +#include "cc/resources/resource.h" +#include "cc/trees/proxy.h" +#include "third_party/khronos/GLES2/gl2.h" +#include "ui/gfx/size.h" + +#if defined(COMPILER_GCC) +namespace BASE_HASH_NAMESPACE { +template <> struct hash<cc::PrioritizedResource*> { + size_t operator()(cc::PrioritizedResource* ptr) const { + return hash<size_t>()(reinterpret_cast<size_t>(ptr)); + } +}; +} // namespace BASE_HASH_NAMESPACE +#endif // COMPILER + +namespace cc { + +class PriorityCalculator; +class Proxy; + +class CC_EXPORT PrioritizedResourceManager { + public: + static scoped_ptr<PrioritizedResourceManager> Create(const Proxy* proxy) { + return make_scoped_ptr(new PrioritizedResourceManager(proxy)); + } + scoped_ptr<PrioritizedResource> CreateTexture(gfx::Size size, GLenum format) { + return make_scoped_ptr(new PrioritizedResource(this, size, format)); + } + ~PrioritizedResourceManager(); + + typedef std::list<PrioritizedResource::Backing*> BackingList; + + // TODO(epenner): (http://crbug.com/137094) This 64MB default is a straggler + // from the old texture manager and is just to give us a default memory + // allocation before we get a callback from the GPU memory manager. We + // should probaby either: + // - wait for the callback before rendering anything instead + // - push this into the GPU memory manager somehow. + static size_t DefaultMemoryAllocationLimit() { return 64 * 1024 * 1024; } + + // MemoryUseBytes() describes the number of bytes used by existing allocated + // textures. + size_t MemoryUseBytes() const { return memory_use_bytes_; } + // MemoryAboveCutoffBytes() describes the number of bytes that + // would be used if all textures that are above the cutoff were allocated. + // MemoryUseBytes() <= MemoryAboveCutoffBytes() should always be true. + size_t MemoryAboveCutoffBytes() const { return memory_above_cutoff_bytes_; } + // MaxMemoryNeededBytes() describes the number of bytes that would be used + // by textures if there were no limit on memory usage. + size_t MaxMemoryNeededBytes() const { return max_memory_needed_bytes_; } + size_t MemoryForSelfManagedTextures() const { + return max_memory_limit_bytes_ - memory_available_bytes_; + } + + void SetMaxMemoryLimitBytes(size_t bytes) { max_memory_limit_bytes_ = bytes; } + size_t MaxMemoryLimitBytes() const { return max_memory_limit_bytes_; } + + // Sepecify a external priority cutoff. Only textures that have a strictly + // higher priority than this cutoff will be allowed. + void SetExternalPriorityCutoff(int priority_cutoff) { + external_priority_cutoff_ = priority_cutoff; + } + + // Return the amount of texture memory required at particular cutoffs. + size_t MemoryVisibleBytes() const; + size_t MemoryVisibleAndNearbyBytes() const; + + void PrioritizeTextures(); + void ClearPriorities(); + + // Delete contents textures' backing resources until they use only + // limit_bytes bytes. This may be called on the impl thread while the main + // thread is running. Returns true if resources are indeed evicted as a + // result of this call. + bool ReduceMemoryOnImplThread(size_t limit_bytes, + int priority_cutoff, + ResourceProvider* resource_provider); + + // Delete contents textures' backing resources that can be recycled. This + // may be called on the impl thread while the main thread is running. + void ReduceWastedMemoryOnImplThread(ResourceProvider* resource_provider); + + // Returns true if there exist any textures that are linked to backings that + // have had their resources evicted. Only when we commit a tree that has no + // textures linked to evicted backings may we allow drawing. After an + // eviction, this will not become true until unlinkAndClearEvictedBackings + // is called. + bool LinkedEvictedBackingsExist() const; + + // Unlink the list of contents textures' backings from their owning textures + // and delete the evicted backings' structures. This is called just before + // updating layers, and is only ever called on the main thread. + void UnlinkAndClearEvictedBackings(); + + bool RequestLate(PrioritizedResource* texture); + + void ReduceWastedMemory(ResourceProvider* resource_provider); + void ReduceMemory(ResourceProvider* resource_provider); + void ClearAllMemory(ResourceProvider* resource_provider); + + void AcquireBackingTextureIfNeeded(PrioritizedResource* texture, + ResourceProvider* resource_provider); + + void RegisterTexture(PrioritizedResource* texture); + void UnregisterTexture(PrioritizedResource* texture); + void ReturnBackingTexture(PrioritizedResource* texture); + + // Update all backings' priorities from their owning texture. + void PushTexturePrioritiesToBackings(); + + // Mark all textures' backings as being in the drawing impl tree. + void UpdateBackingsInDrawingImplTree(); + + const Proxy* ProxyForDebug() const; + + private: + friend class PrioritizedResourceTest; + + enum EvictionPolicy { + EVICT_ONLY_RECYCLABLE, + EVICT_ANYTHING, + }; + enum UnlinkPolicy { + DO_NOT_UNLINK_BACKINGS, + UNLINK_BACKINGS, + }; + + // Compare textures. Highest priority first. + static inline bool CompareTextures(PrioritizedResource* a, + PrioritizedResource* b) { + if (a->request_priority() == b->request_priority()) + return a < b; + return PriorityCalculator::priority_is_higher(a->request_priority(), + b->request_priority()); + } + // Compare backings. Lowest priority first. + static inline bool CompareBackings(PrioritizedResource::Backing* a, + PrioritizedResource::Backing* b) { + // Make textures that can be recycled appear first + if (a->CanBeRecycled() != b->CanBeRecycled()) + return (a->CanBeRecycled() > b->CanBeRecycled()); + // Then sort by being above or below the priority cutoff. + if (a->was_above_priority_cutoff_at_last_priority_update() != + b->was_above_priority_cutoff_at_last_priority_update()) + return (a->was_above_priority_cutoff_at_last_priority_update() < + b->was_above_priority_cutoff_at_last_priority_update()); + // Then sort by priority (note that backings that no longer have owners will + // always have the lowest priority) + if (a->request_priority_at_last_priority_update() != + b->request_priority_at_last_priority_update()) + return PriorityCalculator::priority_is_lower( + a->request_priority_at_last_priority_update(), + b->request_priority_at_last_priority_update()); + // Finally sort by being in the impl tree versus being completely + // unreferenced + if (a->in_drawing_impl_tree() != b->in_drawing_impl_tree()) + return (a->in_drawing_impl_tree() < b->in_drawing_impl_tree()); + return a < b; + } + + explicit PrioritizedResourceManager(const Proxy* proxy); + + bool EvictBackingsToReduceMemory(size_t limit_bytes, + int priority_cutoff, + EvictionPolicy eviction_policy, + UnlinkPolicy unlink_policy, + ResourceProvider* resource_provider); + PrioritizedResource::Backing* CreateBacking( + gfx::Size size, + GLenum format, + ResourceProvider* resource_provider); + void EvictFirstBackingResource(ResourceProvider* resource_provider); + void SortBackings(); + + void AssertInvariants(); + + size_t max_memory_limit_bytes_; + // The priority cutoff based on memory pressure. This is not a strict + // cutoff -- RequestLate allows textures with priority equal to this + // cutoff to be allowed. + int priority_cutoff_; + // The priority cutoff based on external memory policy. This is a strict + // cutoff -- no textures with priority equal to this cutoff will be allowed. + int external_priority_cutoff_; + size_t memory_use_bytes_; + size_t memory_above_cutoff_bytes_; + size_t max_memory_needed_bytes_; + size_t memory_available_bytes_; + + typedef base::hash_set<PrioritizedResource*> TextureSet; + typedef std::vector<PrioritizedResource*> TextureVector; + + const Proxy* proxy_; + + TextureSet textures_; + // This list is always sorted in eviction order, with the exception the + // newly-allocated or recycled textures at the very end of the tail that + // are not sorted by priority. + BackingList backings_; + bool backings_tail_not_sorted_; + + // The list of backings that have been evicted, but may still be linked + // to textures. This can be accessed concurrently by the main and impl + // threads, and may only be accessed while holding evicted_backings_lock_. + mutable base::Lock evicted_backings_lock_; + BackingList evicted_backings_; + + TextureVector temp_texture_vector_; + + // Statistics about memory usage at priority cutoffs, computed at + // PrioritizeTextures. + size_t memory_visible_bytes_; + size_t memory_visible_and_nearby_bytes_; + + // Statistics copied at the time of PushTexturePrioritiesToBackings. + size_t memory_visible_last_pushed_bytes_; + size_t memory_visible_and_nearby_last_pushed_bytes_; + + DISALLOW_COPY_AND_ASSIGN(PrioritizedResourceManager); +}; + +} // namespace cc + +#endif // CC_RESOURCES_PRIORITIZED_RESOURCE_MANAGER_H_ |