Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrResourceCache.h
1
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8
9 #ifndef GrResourceCache_DEFINED
10 #define GrResourceCache_DEFINED
11
12 #include "GrDrawTargetCaps.h"
13 #include "GrResourceKey.h"
14 #include "SkTMultiMap.h"
15 #include "SkMessageBus.h"
16 #include "SkTInternalLList.h"
17
18 class GrGpuResource;
19 class GrResourceCache;
20 class GrResourceCacheEntry;
21
22
23 // The cache listens for these messages to purge junk resources proactively.
24 struct GrResourceInvalidatedMessage {
25     GrResourceKey key;
26 };
27
28 ///////////////////////////////////////////////////////////////////////////////
29
30 class GrResourceCacheEntry {
31 public:
32     GrGpuResource* resource() const { return fResource; }
33     const GrResourceKey& key() const { return fKey; }
34
35     static const GrResourceKey& GetKey(const GrResourceCacheEntry& e) { return e.key(); }
36     static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); }
37 #ifdef SK_DEBUG
38     void validate() const;
39 #else
40     void validate() const {}
41 #endif
42
43     /**
44      *  Update the cached size for this entry and inform the resource cache that
45      *  it has changed. Usually invoked from GrGpuResource::didChangeGpuMemorySize,
46      *  not directly from here.
47      */
48     void didChangeResourceSize();
49
50 private:
51     GrResourceCacheEntry(GrResourceCache* resourceCache,
52                          const GrResourceKey& key,
53                          GrGpuResource* resource);
54     ~GrResourceCacheEntry();
55
56     GrResourceCache* fResourceCache;
57     GrResourceKey    fKey;
58     GrGpuResource*   fResource;
59     size_t           fCachedSize;
60     bool             fIsExclusive;
61
62     // Linked list for the LRU ordering.
63     SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrResourceCacheEntry);
64
65     friend class GrResourceCache;
66     friend class GrContext;
67 };
68
69 ///////////////////////////////////////////////////////////////////////////////
70
71 /**
72  *  Cache of GrGpuResource objects.
73  *
74  *  These have a corresponding GrResourceKey, built from 128bits identifying the
75  *  resource. Multiple resources can map to same GrResourceKey.
76  *
77  *  The cache stores the entries in a double-linked list, which is its LRU.
78  *  When an entry is "locked" (i.e. given to the caller), it is moved to the
79  *  head of the list. If/when we must purge some of the entries, we walk the
80  *  list backwards from the tail, since those are the least recently used.
81  *
82  *  For fast searches, we maintain a hash map based on the GrResourceKey.
83  *
84  *  It is a goal to make the GrResourceCache the central repository and bookkeeper
85  *  of all resources. It should replace the linked list of GrGpuResources that
86  *  GrGpu uses to call abandon/release.
87  */
88 class GrResourceCache {
89 public:
90     GrResourceCache(const GrDrawTargetCaps*, int maxCount, size_t maxBytes);
91     ~GrResourceCache();
92
93     /**
94      *  Return the current resource cache limits.
95      *
96      *  @param maxResource If non-null, returns maximum number of resources
97      *                     that can be held in the cache.
98      *  @param maxBytes    If non-null, returns maximum number of bytes of
99      *                     gpu memory that can be held in the cache.
100      */
101     void getLimits(int* maxResources, size_t* maxBytes) const;
102
103     /**
104      *  Specify the resource cache limits. If the current cache exceeds either
105      *  of these, it will be purged (LRU) to keep the cache within these limits.
106      *
107      *  @param maxResources The maximum number of resources that can be held in
108      *                      the cache.
109      *  @param maxBytes     The maximum number of bytes of resource memory that
110      *                      can be held in the cache.
111      */
112     void setLimits(int maxResources, size_t maxResourceBytes);
113
114     /**
115      *  The callback function used by the cache when it is still over budget
116      *  after a purge. The passed in 'data' is the same 'data' handed to
117      *  setOverbudgetCallback. The callback returns true if some resources
118      *  have been freed.
119      */
120     typedef bool (*PFOverbudgetCB)(void* data);
121
122     /**
123      *  Set the callback the cache should use when it is still over budget
124      *  after a purge. The 'data' provided here will be passed back to the
125      *  callback. Note that the cache will attempt to purge any resources newly
126      *  freed by the callback.
127      */
128     void setOverbudgetCallback(PFOverbudgetCB overbudgetCB, void* data) {
129         fOverbudgetCB = overbudgetCB;
130         fOverbudgetData = data;
131     }
132
133     /**
134      * Returns the number of bytes consumed by cached resources.
135      */
136     size_t getCachedResourceBytes() const { return fEntryBytes; }
137
138     /**
139      * Returns the number of cached resources.
140      */
141     int getCachedResourceCount() const { return fEntryCount; }
142
143     /**
144      *  Search for an entry with the same Key. If found, return it.
145      *  If not found, return null.
146      */
147     GrGpuResource* find(const GrResourceKey& key);
148
149     void makeResourceMRU(GrGpuResource*);
150
151     /** Called by GrGpuResources when they detects that they are newly purgable. */
152     void notifyPurgable(const GrGpuResource*);
153
154     /**
155      *  Add the new resource to the cache (by creating a new cache entry based
156      *  on the provided key and resource).
157      *
158      *  Ownership of the resource is transferred to the resource cache,
159      *  which will unref() it when it is purged or deleted.
160      */
161     void addResource(const GrResourceKey& key, GrGpuResource* resource);
162
163     /**
164      * Determines if the cache contains an entry matching a key. If a matching
165      * entry exists but was detached then it will not be found.
166      */
167     bool hasKey(const GrResourceKey& key) const { return SkToBool(fCache.find(key)); }
168
169     /**
170      * Notify the cache that the size of a resource has changed.
171      */
172     void didIncreaseResourceSize(const GrResourceCacheEntry*, size_t amountInc);
173     void didDecreaseResourceSize(const GrResourceCacheEntry*, size_t amountDec);
174
175     /**
176      * Remove a resource from the cache and delete it!
177      */
178     void deleteResource(GrResourceCacheEntry* entry);
179
180     /**
181      * Removes every resource in the cache that isn't locked.
182      */
183     void purgeAllUnlocked();
184
185     /**
186      * Allow cache to purge unused resources to obey resource limitations
187      * Note: this entry point will be hidden (again) once totally ref-driven
188      * cache maintenance is implemented. Note that the overbudget callback
189      * will be called if the initial purge doesn't get the cache under
190      * its budget.
191      *
192      * extraCount and extraBytes are added to the current resource allocation
193      * to make sure enough room is available for future additions (e.g,
194      * 10MB across 10 textures is about to be added).
195      */
196     void purgeAsNeeded(int extraCount = 0, size_t extraBytes = 0);
197
198 #ifdef SK_DEBUG
199     void validate() const;
200 #else
201     void validate() const {}
202 #endif
203
204 #if GR_CACHE_STATS
205     void printStats();
206 #endif
207
208 private:
209     void internalDetach(GrResourceCacheEntry*);
210     void attachToHead(GrResourceCacheEntry*);
211     void purgeInvalidated();
212     void internalPurge(int extraCount, size_t extraBytes);
213 #ifdef SK_DEBUG
214     static size_t countBytes(const SkTInternalLList<GrResourceCacheEntry>& list);
215 #endif
216
217     typedef SkTMultiMap<GrResourceCacheEntry, GrResourceKey> CacheMap;
218     CacheMap                                fCache;
219
220     // We're an internal doubly linked list
221     typedef SkTInternalLList<GrResourceCacheEntry> EntryList;
222     EntryList                               fList;
223
224     // our budget, used in purgeAsNeeded()
225     int                                     fMaxCount;
226     size_t                                  fMaxBytes;
227
228     // our current stats, related to our budget
229 #if GR_CACHE_STATS
230     int                                     fHighWaterEntryCount;
231     size_t                                  fHighWaterEntryBytes;
232 #endif
233
234     int                                     fEntryCount;
235     size_t                                  fEntryBytes;
236
237     // prevents recursive purging
238     bool                                    fPurging;
239
240     PFOverbudgetCB                          fOverbudgetCB;
241     void*                                   fOverbudgetData;
242
243     SkAutoTUnref<const GrDrawTargetCaps>    fCaps;
244
245     // Listen for messages that a resource has been invalidated and purge cached junk proactively.
246    typedef  SkMessageBus<GrResourceInvalidatedMessage>::Inbox Inbox;
247    Inbox                                    fInvalidationInbox;
248 };
249
250 ///////////////////////////////////////////////////////////////////////////////
251
252 #ifdef SK_DEBUG
253     class GrAutoResourceCacheValidate {
254     public:
255         GrAutoResourceCacheValidate(GrResourceCache* cache) : fCache(cache) {
256             cache->validate();
257         }
258         ~GrAutoResourceCacheValidate() {
259             fCache->validate();
260         }
261     private:
262         GrResourceCache* fCache;
263     };
264 #else
265     class GrAutoResourceCacheValidate {
266     public:
267         GrAutoResourceCacheValidate(GrResourceCache*) {}
268     };
269 #endif
270
271 #endif