1 /*
2  * Copyright 2018 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 SkRemoteGlyphCacheImpl_DEFINED
9 #define SkRemoteGlyphCacheImpl_DEFINED
10 
11 #include "SkArenaAlloc.h"
12 #include "SkDescriptor.h"
13 #include "SkGlyphRun.h"
14 #include "SkGlyphRunPainter.h"
15 #include "SkRemoteGlyphCache.h"
16 
17 class SkStrikeServer::SkGlyphCacheState : public SkStrikeInterface {
18 public:
19     // N.B. SkGlyphCacheState is not valid until ensureScalerContext is called.
20     SkGlyphCacheState(const SkDescriptor& descriptor,
21                       std::unique_ptr<SkScalerContext> context,
22                       SkDiscardableHandleId discardableHandleId);
23     ~SkGlyphCacheState() override;
24 
25     void addGlyph(SkPackedGlyphID, bool pathOnly);
26     void writePendingGlyphs(Serializer* serializer);
discardableHandleId()27     SkDiscardableHandleId discardableHandleId() const { return fDiscardableHandleId; }
28 
isSubpixel()29     bool isSubpixel() const { return fIsSubpixel; }
axisAlignmentForHText()30     SkAxisAlignment axisAlignmentForHText() const { return fAxisAlignmentForHText; }
31 
getDescriptor()32     const SkDescriptor& getDescriptor() const override {
33         return *fDescriptor.getDesc();
34     }
35 
strikeSpec()36     SkStrikeSpec strikeSpec() const override {
37         return SkStrikeSpec(this->getDescriptor(), *fTypeface, fEffects);
38     }
39 
40     void setTypefaceAndEffects(const SkTypeface* typeface, SkScalerContextEffects effects);
41 
42     SkVector rounding() const override;
43 
44     const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) override;
45 
46     int glyphMetrics(const SkGlyphID[], const SkPoint[], int n, SkGlyphPos result[]) override;
47 
48     bool decideCouldDrawFromPath(const SkGlyph& glyph) override;
49 
onAboutToExitScope()50     void onAboutToExitScope() override {}
51 
52 private:
hasPendingGlyphs()53     bool hasPendingGlyphs() const {
54         return !fPendingGlyphImages.empty() || !fPendingGlyphPaths.empty();
55     }
56     void writeGlyphPath(const SkPackedGlyphID& glyphID, Serializer* serializer) const;
57 
58     void ensureScalerContext();
59     void resetScalerContext();
60 
61     // The set of glyphs cached on the remote client.
62     SkTHashSet<SkPackedGlyphID> fCachedGlyphImages;
63     SkTHashSet<SkPackedGlyphID> fCachedGlyphPaths;
64 
65     // The set of glyphs which has not yet been serialized and sent to the
66     // remote client.
67     std::vector<SkPackedGlyphID> fPendingGlyphImages;
68     std::vector<SkPackedGlyphID> fPendingGlyphPaths;
69 
70     const SkAutoDescriptor fDescriptor;
71 
72     const SkDiscardableHandleId fDiscardableHandleId;
73 
74     // Values saved from the initial context.
75     const bool fIsSubpixel;
76     const SkAxisAlignment fAxisAlignmentForHText;
77 
78     // The context built using fDescriptor
79     std::unique_ptr<SkScalerContext> fContext;
80 
81     // These fields are set everytime getOrCreateCache. This allows the code to maintain the
82     // fContext as lazy as possible.
83     const SkTypeface* fTypeface{nullptr};
84     SkScalerContextEffects fEffects;
85 
86     class GlyphMapHashTraits {
87     public:
GetKey(const SkGlyph * glyph)88         static SkPackedGlyphID GetKey(const SkGlyph* glyph) {
89             return glyph->getPackedID();
90         }
Hash(SkPackedGlyphID glyphId)91         static uint32_t Hash(SkPackedGlyphID glyphId) {
92             return glyphId.hash();
93         }
94     };
95 
96     // FallbackTextHelper cases require glyph metrics when analyzing a glyph run, in which case
97     // we cache them here.
98     SkTHashTable<SkGlyph*, SkPackedGlyphID, GlyphMapHashTraits> fGlyphMap;
99 
100     SkArenaAlloc fAlloc{256};
101 };
102 
103 class SkTextBlobCacheDiffCanvas::TrackLayerDevice : public SkNoPixelsDevice {
104 public:
105     TrackLayerDevice(const SkIRect& bounds, const SkSurfaceProps& props, SkStrikeServer* server,
106                      sk_sp<SkColorSpace> colorSpace,
107                      const SkTextBlobCacheDiffCanvas::Settings& settings);
108 
109     SkBaseDevice* onCreateDevice(const CreateInfo& cinfo, const SkPaint*) override;
110 
111 protected:
112     void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override;
113 
114 private:
115     SkStrikeServer* const fStrikeServer;
116     const SkTextBlobCacheDiffCanvas::Settings fSettings;
117     SkGlyphRunListPainter fPainter;
118 };
119 
120 #endif // SkRemoteGlyphCacheImpl_DEFINED
121