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
14enum InternalState {
15 kUnknown = 0,
16 kShaped = 2,
17 kClusterized = 3,
18 kMarked = 4,
19 kLineBroken = 5,
20 kFormatted = 6,
21 kDrawn = 7
22};
23
24class ParagraphImpl;
25class ParagraphCacheKey;
26class ParagraphCacheValue;
27
28bool operator==(const ParagraphCacheKey& a, const ParagraphCacheKey& b);
29
30class ParagraphCache {
31public:
32 ParagraphCache();
33 ~ParagraphCache();
34
35 void abandon();
36 void reset();
37 bool updateParagraph(ParagraphImpl* paragraph);
38 bool findParagraph(ParagraphImpl* paragraph);
39
40 // For testing
41 void setChecker(std::function<void(ParagraphImpl* impl, const char*, bool)> checker) {
42 fChecker = std::move(checker);
43 }
44 void printStatistics();
45 void turnOn(bool value) { fCacheIsOn = value; }
46 int count() { return fLRUCacheMap.count(); }
47
48 private:
49
50 struct Entry;
51 void updateFrom(const ParagraphImpl* paragraph, Entry* entry);
52 void updateTo(ParagraphImpl* paragraph, const Entry* entry);
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 mix(uint32_t hash, uint32_t data) const;
61 uint32_t operator()(const ParagraphCacheKey& key) const;
62 };
63
64 SkLRUCache<ParagraphCacheKey, std::unique_ptr<Entry>, KeyHash> fLRUCacheMap;
65 bool fCacheIsOn;
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