Flutter Engine
The Flutter Engine
SkStrike.h
Go to the documentation of this file.
1/*
2 * Copyright 2006 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
5 */
6
7#ifndef SkStrike_DEFINED
8#define SkStrike_DEFINED
9
18#include "src/core/SkGlyph.h"
21#include "src/core/SkTHash.h"
23
24#include <cstddef>
25#include <memory>
26#include <vector>
27
28class SkDescriptor;
29class SkDrawable;
30class SkPath;
31class SkReadBuffer;
32class SkStrikeCache;
34class SkWriteBuffer;
35
37public:
38 virtual ~SkStrikePinner() = default;
39 virtual bool canDelete() = 0;
40 virtual void assertValid() {}
41};
42
43// This class holds the results of an SkScalerContext, and owns a references to that scaler.
44class SkStrike final : public sktext::StrikeForGPU {
45public:
46 SkStrike(SkStrikeCache* strikeCache,
48 std::unique_ptr<SkScalerContext> scaler,
50 std::unique_ptr<SkStrikePinner> pinner);
51
52 void lock() override SK_ACQUIRE(fStrikeLock);
53 void unlock() override SK_RELEASE_CAPABILITY(fStrikeLock);
55 bool prepareForImage(SkGlyph* glyph) override SK_REQUIRES(fStrikeLock);
56 bool prepareForPath(SkGlyph*) override SK_REQUIRES(fStrikeLock);
57 bool prepareForDrawable(SkGlyph*) override SK_REQUIRES(fStrikeLock);
58
62 SkSpan<SkGlyph> paths,
63 SkSpan<SkGlyph> drawables);
64
65 // Lookup (or create if needed) the returned glyph using toID. If that glyph is not initialized
66 // with an image, then use the information in fromGlyph to initialize the width, height top,
67 // left, format and image of the glyph. This is mainly used preserving the glyph if it was
68 // created by a search of desperation. This is deprecated.
70 SkPackedGlyphID toID, const SkGlyph& fromGlyph) SK_EXCLUDES(fStrikeLock);
71
72 // If the path has never been set, then add a path to glyph. This is deprecated.
73 const SkPath* mergePath(
74 SkGlyph* glyph, const SkPath* path, bool hairline) SK_EXCLUDES(fStrikeLock);
75
76 // If the drawable has never been set, then add a drawable to glyph. This is deprecated.
78 SkGlyph* glyph, sk_sp<SkDrawable> drawable) SK_EXCLUDES(fStrikeLock);
79
80 // If the advance axis intersects the glyph's path, append the positions scaled and offset
81 // to the array (if non-null), and set the count to the updated array length.
82 // TODO: track memory usage.
84 SkGlyph*, SkScalar* array, int* count) SK_EXCLUDES(fStrikeLock);
85
87 return fFontMetrics;
88 }
89
91 SkSpan<const SkGlyphID> glyphIDs, const SkGlyph* results[]) SK_EXCLUDES(fStrikeLock);
92
94 SkSpan<const SkGlyphID> glyphIDs, const SkGlyph* results[]) SK_EXCLUDES(fStrikeLock);
95
97 const SkGlyph* results[]) SK_EXCLUDES(fStrikeLock);
98
100 SkSpan<const SkGlyphID> glyphIDs, const SkGlyph* results[]) SK_EXCLUDES(fStrikeLock);
101
102 // SkStrikeForGPU APIs
103 const SkDescriptor& getDescriptor() const override {
104 return fStrikeSpec.descriptor();
105 }
106
108 return fRoundingSpec;
109 }
110
112 return sktext::SkStrikePromise(sk_ref_sp<SkStrike>(this));
113 }
114
115 // Convert all the IDs into SkPaths in the span.
116 void glyphIDsToPaths(SkSpan<sktext::IDOrPath> idsOrPaths) SK_EXCLUDES(fStrikeLock);
117
118 // Convert all the IDs into SkDrawables in the span.
119 void glyphIDsToDrawables(SkSpan<sktext::IDOrDrawable> idsOrDrawables) SK_EXCLUDES(fStrikeLock);
120
121 const SkStrikeSpec& strikeSpec() const {
122 return fStrikeSpec;
123 }
124
125 void verifyPinnedStrike() const {
126 if (fPinner != nullptr) {
127 fPinner->assertValid();
128 }
129 }
130
131 void dump() const SK_EXCLUDES(fStrikeLock);
132 void dumpMemoryStatistics(SkTraceMemoryDump* dump) const SK_EXCLUDES(fStrikeLock);
133
134 SkGlyph* glyph(SkGlyphDigest) SK_REQUIRES(fStrikeLock);
135
136private:
137 friend class SkStrikeCache;
139 class Monitor;
140
141 // Return a glyph. Create it if it doesn't exist, and initialize the glyph with metrics and
142 // advances using a scaler.
144
145 // Generate the glyph digest information and update structures to add the glyph.
146 SkGlyphDigest* addGlyphAndDigest(SkGlyph* glyph) SK_REQUIRES(fStrikeLock);
147
148 SkGlyph* mergeGlyphFromBuffer(SkReadBuffer& buffer) SK_REQUIRES(fStrikeLock);
149 bool mergeGlyphAndImageFromBuffer(SkReadBuffer& buffer) SK_REQUIRES(fStrikeLock);
150 bool mergeGlyphAndPathFromBuffer(SkReadBuffer& buffer) SK_REQUIRES(fStrikeLock);
151 bool mergeGlyphAndDrawableFromBuffer(SkReadBuffer& buffer) SK_REQUIRES(fStrikeLock);
152
153 // Maintain memory use statistics.
154 void updateMemoryUsage(size_t increase) SK_EXCLUDES(fStrikeLock);
155
156 enum PathDetail {
157 kMetricsOnly,
158 kMetricsAndPath
159 };
160
161 // internalPrepare will only be called with a mutex already held.
162 SkSpan<const SkGlyph*> internalPrepare(
164 PathDetail pathDetail,
165 const SkGlyph** results) SK_REQUIRES(fStrikeLock);
166
167 // The following are const and need no mutex protection.
168 const SkFontMetrics fFontMetrics;
169 const SkGlyphPositionRoundingSpec fRoundingSpec;
170 const SkStrikeSpec fStrikeSpec;
171 SkStrikeCache* const fStrikeCache;
172
173 // This mutex provides protection for this specific SkStrike.
174 mutable SkMutex fStrikeLock;
175
176 // Maps from a combined GlyphID and sub-pixel position to a SkGlyphDigest. The actual glyph is
177 // stored in the fAlloc. The pointer to the glyph is stored fGlyphForIndex. The
178 // SkGlyphDigest's fIndex field stores the index. This pointer provides an unchanging
179 // reference to the SkGlyph as long as the strike is alive, and fGlyphForIndex
180 // provides a dense index for glyphs.
182 fDigestForPackedGlyphID SK_GUARDED_BY(fStrikeLock);
183
184 // Maps from a glyphIndex to a glyph
185 std::vector<SkGlyph*> fGlyphForIndex SK_GUARDED_BY(fStrikeLock);
186
187 // Context that corresponds to the glyph information in this strike.
188 const std::unique_ptr<SkScalerContext> fScalerContext SK_GUARDED_BY(fStrikeLock);
189
190 // Used while changing the strike to track memory increase.
191 size_t fMemoryIncrease SK_GUARDED_BY(fStrikeLock) {0};
192
193 // So, we don't grow our arrays a lot.
194 inline static constexpr size_t kMinGlyphCount = 8;
195 inline static constexpr size_t kMinGlyphImageSize = 16 /* height */ * 8 /* width */;
196 inline static constexpr size_t kMinAllocAmount = kMinGlyphImageSize * kMinGlyphCount;
197
198 SkArenaAlloc fAlloc SK_GUARDED_BY(fStrikeLock) {kMinAllocAmount};
199
200 // The following are protected by the SkStrikeCache's mutex.
201 SkStrike* fNext{nullptr};
202 SkStrike* fPrev{nullptr};
203 std::unique_ptr<SkStrikePinner> fPinner;
204 size_t fMemoryUsed{sizeof(SkStrike)};
205 bool fRemoved{false};
206};
207
208#endif // SkStrike_DEFINED
int count
Definition: FontMgrTest.cpp:50
#define SK_EXCLUDES(...)
#define SK_RELEASE_CAPABILITY(...)
#define SK_REQUIRES(...)
#define SK_ACQUIRE(...)
Definition: SkPath.h:59
virtual void assertValid()
Definition: SkStrike.h:40
virtual bool canDelete()=0
virtual ~SkStrikePinner()=default
const SkDescriptor & descriptor() const
Definition: SkStrikeSpec.h:96
static void FlattenGlyphsByType(SkWriteBuffer &buffer, SkSpan< SkGlyph > images, SkSpan< SkGlyph > paths, SkSpan< SkGlyph > drawables)
Definition: SkStrike.cpp:87
void dump() const SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:277
const SkDrawable * mergeDrawable(SkGlyph *glyph, sk_sp< SkDrawable > drawable) SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:199
const SkDescriptor & getDescriptor() const override
Definition: SkStrike.h:103
void glyphIDsToDrawables(SkSpan< sktext::IDOrDrawable > idsOrDrawables) SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:267
void verifyPinnedStrike() const
Definition: SkStrike.h:125
void dumpMemoryStatistics(SkTraceMemoryDump *dump) const SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:295
void unlock() override SK_RELEASE_CAPABILITY(fStrikeLock)
Definition: SkStrike.cpp:80
bool mergeFromBuffer(SkReadBuffer &buffer) SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:117
sktext::SkStrikePromise strikePromise() override
Definition: SkStrike.h:111
SkSpan< const SkGlyph * > metrics(SkSpan< const SkGlyphID > glyphIDs, const SkGlyph *results[]) SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:218
const SkPath * mergePath(SkGlyph *glyph, const SkPath *path, bool hairline) SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:187
const SkFontMetrics & getFontMetrics() const
Definition: SkStrike.h:86
const SkStrikeSpec & strikeSpec() const
Definition: SkStrike.h:121
bool prepareForPath(SkGlyph *) override SK_REQUIRES(fStrikeLock)
Definition: SkStrike.cpp:366
void lock() override SK_ACQUIRE(fStrikeLock)
Definition: SkStrike.cpp:75
SkStrike(SkStrikeCache *strikeCache, const SkStrikeSpec &strikeSpec, std::unique_ptr< SkScalerContext > scaler, const SkFontMetrics *metrics, std::unique_ptr< SkStrikePinner > pinner)
Definition: SkStrike.cpp:45
SkSpan< const SkGlyph * > preparePaths(SkSpan< const SkGlyphID > glyphIDs, const SkGlyph *results[]) SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:224
void findIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos, SkGlyph *, SkScalar *array, int *count) SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:212
void glyphIDsToPaths(SkSpan< sktext::IDOrPath > idsOrPaths) SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:258
SkGlyph * mergeGlyphAndImage(SkPackedGlyphID toID, const SkGlyph &fromGlyph) SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:164
bool prepareForDrawable(SkGlyph *) override SK_REQUIRES(fStrikeLock)
Definition: SkStrike.cpp:373
Monitor(SkStrike *strike) SK_ACQUIRE(strike -> fStrikeLock) :fStrike
Definition: SkStrike.cpp:62
SkGlyph * glyph(SkGlyphDigest) SK_REQUIRES(fStrikeLock)
Definition: SkStrike.cpp:322
SkSpan< const SkGlyph * > prepareDrawables(SkSpan< const SkGlyphID > glyphIDs, const SkGlyph *results[]) SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:243
bool prepareForImage(SkGlyph *glyph) override SK_REQUIRES(fStrikeLock)
Definition: SkStrike.cpp:359
const SkGlyphPositionRoundingSpec & roundingSpec() const override
Definition: SkStrike.h:107
SkSpan< const SkGlyph * > prepareImages(SkSpan< const SkPackedGlyphID > glyphIDs, const SkGlyph *results[]) SK_EXCLUDES(fStrikeLock)
Definition: SkStrike.cpp:230
SkGlyphDigest digestFor(skglyph::ActionType, SkPackedGlyphID) override SK_REQUIRES(fStrikeLock)
Definition: SkStrike.cpp:331
float SkScalar
Definition: extension.cpp:12
std::array< MockImage, 3 > images
Definition: mock_vulkan.cc:41
Optional< SkRect > bounds
Definition: SkRecords.h:189
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
ActionType
Definition: SkGlyph.h:312
const Scalar scale