1// Copyright 2019 Google LLC.
2#ifndef ParagraphCache_DEFINED
3#define ParagraphCache_DEFINED
4
5#include "include/private/SkMutex.h"
6#include "src/core/SkLRUCache.h"
7#include <functional>  // std::function
8
9#define PARAGRAPH_CACHE_STATS
10
11namespace skia {
12namespace textlayout {
13
14class ParagraphImpl;
15class ParagraphCacheKey;
16class ParagraphCacheValue;
17
18class ParagraphCache {
19public:
20    ParagraphCache();
21    ~ParagraphCache();
22
23    void abandon();
24    void reset();
25    bool updateParagraph(ParagraphImpl* paragraph);
26    bool findParagraph(ParagraphImpl* paragraph);
27#ifdef OHOS_SUPPORT
28    void SetStoredLayout(ParagraphImpl& paragraph);
29    bool GetStoredLayout(ParagraphImpl& paragraph);
30#endif
31
32    // For testing
33    void setChecker(std::function<void(ParagraphImpl* impl, const char*, bool)> checker) {
34        fChecker = std::move(checker);
35    }
36    void printStatistics();
37    void turnOn(bool value) { fCacheIsOn = value; }
38    int count() { return fLRUCacheMap.count(); }
39
40    bool isPossiblyTextEditing(ParagraphImpl* paragraph);
41
42 private:
43
44    struct Entry;
45    void updateFrom(const ParagraphImpl* paragraph, Entry* entry);
46    void updateTo(ParagraphImpl* paragraph, const Entry* entry);
47
48#ifdef OHOS_SUPPORT
49    bool useCachedLayout(const ParagraphImpl& paragraph, const ParagraphCacheValue* value);
50    void SetStoredLayoutImpl(ParagraphImpl& paragraph, ParagraphCacheValue* value);
51    ParagraphCacheValue* cacheLayout(ParagraphImpl* paragraph);
52#endif
53
54    mutable SkMutex fParagraphMutex;
55    std::function<void(ParagraphImpl* impl, const char*, bool)> fChecker;
56
57    static const int kMaxEntries = 128;
58
59    struct KeyHash {
60        uint32_t operator()(const ParagraphCacheKey& key) const;
61    };
62
63    SkLRUCache<ParagraphCacheKey, std::unique_ptr<Entry>, KeyHash> fLRUCacheMap;
64    bool fCacheIsOn;
65    ParagraphCacheValue* fLastCachedValue;
66
67#ifdef PARAGRAPH_CACHE_STATS
68    int fTotalRequests;
69    int fCacheMisses;
70    int fHashMisses; // cache hit but hash table missed
71#endif
72};
73
74}  // namespace textlayout
75}  // namespace skia
76
77#endif  // ParagraphCache_DEFINED
78