1/*
2 * Copyright 2010 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 SkGlyphCache_Globals_DEFINED
9#define SkGlyphCache_Globals_DEFINED
10
11#include "SkGlyphCache.h"
12#include "SkMutex.h"
13#include "SkSpinlock.h"
14#include "SkTLS.h"
15
16#ifndef SK_DEFAULT_FONT_CACHE_COUNT_LIMIT
17    #define SK_DEFAULT_FONT_CACHE_COUNT_LIMIT   2048
18#endif
19
20#ifndef SK_DEFAULT_FONT_CACHE_LIMIT
21    #define SK_DEFAULT_FONT_CACHE_LIMIT     (2 * 1024 * 1024)
22#endif
23
24#ifndef SK_DEFAULT_FONT_CACHE_POINT_SIZE_LIMIT
25    #define SK_DEFAULT_FONT_CACHE_POINT_SIZE_LIMIT  256
26#endif
27
28///////////////////////////////////////////////////////////////////////////////
29
30class SkGlyphCache_Globals {
31public:
32    SkGlyphCache_Globals() {
33        fHead = nullptr;
34        fTotalMemoryUsed = 0;
35        fCacheSizeLimit = SK_DEFAULT_FONT_CACHE_LIMIT;
36        fCacheCount = 0;
37        fCacheCountLimit = SK_DEFAULT_FONT_CACHE_COUNT_LIMIT;
38        fPointSizeLimit = SK_DEFAULT_FONT_CACHE_POINT_SIZE_LIMIT;
39    }
40
41    ~SkGlyphCache_Globals() {
42        SkGlyphCache* cache = fHead;
43        while (cache) {
44            SkGlyphCache* next = cache->fNext;
45            delete cache;
46            cache = next;
47        }
48    }
49
50    mutable SkSpinlock     fLock;
51
52    SkGlyphCache* internalGetHead() const { return fHead; }
53    SkGlyphCache* internalGetTail() const;
54
55    size_t getTotalMemoryUsed() const;
56    int getCacheCountUsed() const;
57
58#ifdef SK_DEBUG
59    void validate() const;
60#else
61    void validate() const {}
62#endif
63
64    int getCacheCountLimit() const;
65    int setCacheCountLimit(int limit);
66
67    size_t  getCacheSizeLimit() const;
68    size_t  setCacheSizeLimit(size_t limit);
69
70    int  getCachePointSizeLimit() const;
71    int  setCachePointSizeLimit(int limit);
72
73    void purgeAll(); // does not change budget
74
75    // call when a glyphcache is available for caching (i.e. not in use)
76    void attachCacheToHead(SkGlyphCache*);
77
78    // can only be called when the mutex is already held
79    void internalDetachCache(SkGlyphCache*);
80    void internalAttachCacheToHead(SkGlyphCache*);
81
82private:
83    SkGlyphCache* fHead;
84    size_t  fTotalMemoryUsed;
85    size_t  fCacheSizeLimit;
86    int32_t fCacheCountLimit;
87    int32_t fCacheCount;
88    int32_t fPointSizeLimit;
89
90    // Checkout budgets, modulated by the specified min-bytes-needed-to-purge,
91    // and attempt to purge caches to match.
92    // Returns number of bytes freed.
93    size_t internalPurge(size_t minBytesNeeded = 0);
94};
95
96#endif
97