Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkResourceCache.h
1 /*
2  * Copyright 2013 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 #ifndef SkResourceCache_DEFINED
9 #define SkResourceCache_DEFINED
10
11 #include "SkBitmap.h"
12
13 class SkCachedData;
14 class SkDiscardableMemory;
15 class SkMipMap;
16
17 /**
18  *  Cache object for bitmaps (with possible scale in X Y as part of the key).
19  *
20  *  Multiple caches can be instantiated, but each instance is not implicitly
21  *  thread-safe, so if a given instance is to be shared across threads, the
22  *  caller must manage the access itself (e.g. via a mutex).
23  *
24  *  As a convenience, a global instance is also defined, which can be safely
25  *  access across threads via the static methods (e.g. FindAndLock, etc.).
26  */
27 class SkResourceCache {
28 public:
29     struct Key {
30         // Call this to access your private contents. Must not use the address after calling init()
31         void* writableContents() { return this + 1; }
32
33         // must call this after your private data has been written.
34         // nameSpace must be unique per Key subclass.
35         // length must be a multiple of 4
36         void init(void* nameSpace, size_t length);
37
38         // This is only valid after having called init().
39         uint32_t hash() const { return fHash; }
40
41         bool operator==(const Key& other) const {
42             const uint32_t* a = this->as32();
43             const uint32_t* b = other.as32();
44             for (int i = 0; i < fCount32; ++i) {  // (This checks fCount == other.fCount first.)
45                 if (a[i] != b[i]) {
46                     return false;
47                 }
48             }
49             return true;
50         }
51
52     private:
53         int32_t  fCount32;   // local + user contents count32
54         uint32_t fHash;
55         void*    fNamespace; // A unique namespace tag. This is hashed.
56         /* uint32_t fContents32[] */
57
58         const uint32_t* as32() const { return (const uint32_t*)this; }
59     };
60
61     struct Rec {
62         typedef SkResourceCache::Key Key;
63
64         Rec() {}
65         virtual ~Rec() {}
66
67         uint32_t getHash() const { return this->getKey().hash(); }
68
69         virtual const Key& getKey() const = 0;
70         virtual size_t bytesUsed() const = 0;
71
72         // for SkTDynamicHash::Traits
73         static uint32_t Hash(const Key& key) { return key.hash(); }
74         static const Key& GetKey(const Rec& rec) { return rec.getKey(); }
75
76     private:
77         Rec*    fNext;
78         Rec*    fPrev;
79
80         friend class SkResourceCache;
81     };
82
83     typedef const Rec* ID;
84
85     /**
86      *  Callback function for find(). If called, the cache will have found a match for the
87      *  specified Key, and will pass in the corresponding Rec, along with a caller-specified
88      *  context. The function can read the data in Rec, and copy whatever it likes into context
89      *  (casting context to whatever it really is).
90      *
91      *  The return value determines what the cache will do with the Rec. If the function returns
92      *  true, then the Rec is considered "valid". If false is returned, the Rec will be considered
93      *  "stale" and will be purged from the cache.
94      */
95     typedef bool (*VisitorProc)(const Rec&, void* context);
96
97     /**
98      *  Returns a locked/pinned SkDiscardableMemory instance for the specified
99      *  number of bytes, or NULL on failure.
100      */
101     typedef SkDiscardableMemory* (*DiscardableFactory)(size_t bytes);
102
103     /*
104      *  The following static methods are thread-safe wrappers around a global
105      *  instance of this cache.
106      */
107
108     /**
109      *  Returns true if the visitor was called on a matching Key, and the visitor returned true.
110      *
111      *  Find() will search the cache for the specified Key. If no match is found, return false and
112      *  do not call the VisitorProc. If a match is found, return whatever the visitor returns.
113      *  Its return value is interpreted to mean:
114      *      true  : Rec is valid
115      *      false : Rec is "stale" -- the cache will purge it.
116      */
117     static bool Find(const Key& key, VisitorProc, void* context);
118     static void Add(Rec*);
119
120     static size_t GetTotalBytesUsed();
121     static size_t GetTotalByteLimit();
122     static size_t SetTotalByteLimit(size_t newLimit);
123
124     static size_t SetSingleAllocationByteLimit(size_t);
125     static size_t GetSingleAllocationByteLimit();
126
127     static void PurgeAll();
128
129     /**
130      *  Returns the DiscardableFactory used by the global cache, or NULL.
131      */
132     static DiscardableFactory GetDiscardableFactory();
133
134     /**
135      * Use this allocator for bitmaps, so they can use ashmem when available.
136      * Returns NULL if the ResourceCache has not been initialized with a DiscardableFactory.
137      */
138     static SkBitmap::Allocator* GetAllocator();
139
140     static SkCachedData* NewCachedData(size_t bytes);
141
142     /**
143      *  Call SkDebugf() with diagnostic information about the state of the cache
144      */
145     static void Dump();
146
147     ///////////////////////////////////////////////////////////////////////////
148
149     /**
150      *  Construct the cache to call DiscardableFactory when it
151      *  allocates memory for the pixels. In this mode, the cache has
152      *  not explicit budget, and so methods like getTotalBytesUsed()
153      *  and getTotalByteLimit() will return 0, and setTotalByteLimit
154      *  will ignore its argument and return 0.
155      */
156     SkResourceCache(DiscardableFactory);
157
158     /**
159      *  Construct the cache, allocating memory with malloc, and respect the
160      *  byteLimit, purging automatically when a new image is added to the cache
161      *  that pushes the total bytesUsed over the limit. Note: The limit can be
162      *  changed at runtime with setTotalByteLimit.
163      */
164     explicit SkResourceCache(size_t byteLimit);
165     ~SkResourceCache();
166
167     /**
168      *  Returns true if the visitor was called on a matching Key, and the visitor returned true.
169      *
170      *  find() will search the cache for the specified Key. If no match is found, return false and
171      *  do not call the VisitorProc. If a match is found, return whatever the visitor returns.
172      *  Its return value is interpreted to mean:
173      *      true  : Rec is valid
174      *      false : Rec is "stale" -- the cache will purge it.
175      */
176     bool find(const Key&, VisitorProc, void* context);
177     void add(Rec*);
178
179     size_t getTotalBytesUsed() const { return fTotalBytesUsed; }
180     size_t getTotalByteLimit() const { return fTotalByteLimit; }
181
182     /**
183      *  This is respected by SkBitmapProcState::possiblyScaleImage.
184      *  0 is no maximum at all; this is the default.
185      *  setSingleAllocationByteLimit() returns the previous value.
186      */
187     size_t setSingleAllocationByteLimit(size_t maximumAllocationSize);
188     size_t getSingleAllocationByteLimit() const;
189     /**
190      *  Set the maximum number of bytes available to this cache. If the current
191      *  cache exceeds this new value, it will be purged to try to fit within
192      *  this new limit.
193      */
194     size_t setTotalByteLimit(size_t newLimit);
195
196     void purgeAll() {
197         this->purgeAsNeeded(true);
198     }
199
200     DiscardableFactory discardableFactory() const { return fDiscardableFactory; }
201     SkBitmap::Allocator* allocator() const { return fAllocator; };
202
203     SkCachedData* newCachedData(size_t bytes);
204
205     /**
206      *  Call SkDebugf() with diagnostic information about the state of the cache
207      */
208     void dump() const;
209
210 private:
211     Rec*    fHead;
212     Rec*    fTail;
213
214     class Hash;
215     Hash*   fHash;
216
217     DiscardableFactory  fDiscardableFactory;
218     // the allocator is NULL or one that matches discardables
219     SkBitmap::Allocator* fAllocator;
220
221     size_t  fTotalBytesUsed;
222     size_t  fTotalByteLimit;
223     size_t  fSingleAllocationByteLimit;
224     int     fCount;
225
226     void purgeAsNeeded(bool forcePurge = false);
227
228     // linklist management
229     void moveToHead(Rec*);
230     void addToHead(Rec*);
231     void detach(Rec*);
232     void remove(Rec*);
233
234     void init();    // called by constructors
235
236 #ifdef SK_DEBUG
237     void validate() const;
238 #else
239     void validate() const {}
240 #endif
241 };
242 #endif