xref: /aosp_15_r20/external/skia/src/text/StrikeForGPU.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2019 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 sktext_StrikeForGPU_DEFINED
9 #define sktext_StrikeForGPU_DEFINED
10 
11 #include "include/core/SkPath.h"
12 #include "include/core/SkRefCnt.h"
13 #include "include/core/SkTypes.h"
14 #include "src/core/SkGlyph.h"
15 
16 #include <memory>
17 #include <optional>
18 #include <variant>
19 
20 class SkDescriptor;
21 class SkDrawable;
22 class SkReadBuffer;
23 class SkStrike;
24 class SkStrikeCache;
25 class SkStrikeClient;
26 class SkStrikeSpec;
27 class SkWriteBuffer;
28 
29 namespace sktext {
30 // -- SkStrikePromise ------------------------------------------------------------------------------
31 // SkStrikePromise produces an SkStrike when needed by GPU glyph rendering. In ordinary
32 // operation, it just wraps an SkStrike. When used for remote glyph cache operation, the promise is
33 // serialized to an SkDescriptor. When SkStrikePromise is deserialized, it uses the descriptor to
34 // look up the SkStrike.
35 //
36 // When deserializing some care must be taken; if the needed SkStrike is removed from the cache,
37 // then looking up using the descriptor will fail resulting in a deserialization failure. The
38 // Renderer/GPU system solves this problem by pinning all the strikes needed into the cache.
39 class SkStrikePromise {
40 public:
41     SkStrikePromise() = delete;
42     SkStrikePromise(const SkStrikePromise&) = delete;
43     SkStrikePromise& operator=(const SkStrikePromise&) = delete;
44     SkStrikePromise(SkStrikePromise&&);
45     SkStrikePromise& operator=(SkStrikePromise&&);
46 
47     explicit SkStrikePromise(sk_sp<SkStrike>&& strike);
48     explicit SkStrikePromise(const SkStrikeSpec& spec);
49 
50     // This only works when the GPU code is compiled in.
51     static std::optional<SkStrikePromise> MakeFromBuffer(SkReadBuffer& buffer,
52                                                          const SkStrikeClient* client,
53                                                          SkStrikeCache* strikeCache);
54     void flatten(SkWriteBuffer& buffer) const;
55 
56     // Do what is needed to return a strike.
57     SkStrike* strike();
58 
59     // Reset the sk_sp<SkStrike> to nullptr.
60     void resetStrike();
61 
62     // Return a descriptor used to look up the SkStrike.
63     const SkDescriptor& descriptor() const;
64 
65 private:
66     std::variant<sk_sp<SkStrike>, std::unique_ptr<SkStrikeSpec>> fStrikeOrSpec;
67 };
68 
69 // -- StrikeForGPU ---------------------------------------------------------------------------------
70 class StrikeForGPU : public SkRefCnt {
71 public:
72     virtual void lock() = 0;
73     virtual void unlock() = 0;
74 
75     // Generate a digest for a given packed glyph ID as drawn using the give action type.
76     virtual SkGlyphDigest digestFor(skglyph::ActionType, SkPackedGlyphID) = 0;
77 
78     // Prepare the glyph to draw an image, and return if the image exists.
79     virtual bool prepareForImage(SkGlyph*) = 0;
80 
81     // Prepare the glyph to draw a path, and return if the path exists.
82     virtual bool prepareForPath(SkGlyph*) = 0;
83 
84     // Prepare the glyph to draw a drawable, and return if the drawable exists.
85     virtual bool prepareForDrawable(SkGlyph*) = 0;
86 
87 
88     virtual const SkDescriptor& getDescriptor() const = 0;
89 
90     virtual const SkGlyphPositionRoundingSpec& roundingSpec() const = 0;
91 
92     // Return a strike promise.
93     virtual SkStrikePromise strikePromise() = 0;
94 };
95 
96 // prepareForPathDrawing uses this union to convert glyph ids to paths.
97 union IDOrPath {
IDOrPath()98     IDOrPath() {}
IDOrPath(SkGlyphID glyphID)99     IDOrPath(SkGlyphID glyphID) : fGlyphID{glyphID} {}
100 
101     // PathOpSubmitter takes care of destroying the paths.
~IDOrPath()102     ~IDOrPath() {}
103     SkGlyphID fGlyphID;
104     SkPath fPath;
105 };
106 
107 // prepareForDrawableDrawing uses this union to convert glyph ids to drawables.
108 union IDOrDrawable {
109     SkGlyphID fGlyphID;
110     SkDrawable* fDrawable;
111 };
112 
113 // -- StrikeMutationMonitor ------------------------------------------------------------------------
114 class StrikeMutationMonitor {
115 public:
116     StrikeMutationMonitor(StrikeForGPU* strike);
117     ~StrikeMutationMonitor();
118 
119 private:
120     StrikeForGPU* fStrike;
121 };
122 
123 // -- StrikeForGPUCacheInterface -------------------------------------------------------------------
124 class StrikeForGPUCacheInterface {
125 public:
126     virtual ~StrikeForGPUCacheInterface() = default;
127     virtual sk_sp<StrikeForGPU> findOrCreateScopedStrike(const SkStrikeSpec& strikeSpec) = 0;
128 };
129 }  // namespace sktext
130 #endif  // sktext_StrikeForGPU_DEFINED
131