Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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);
54 SkGlyphDigest digestFor(skglyph::ActionType, SkPackedGlyphID) override SK_REQUIRES(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
61 SkSpan<SkGlyph> images,
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.
83 void findIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos,
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
#define SK_EXCLUDES(...)
#define SK_RELEASE_CAPABILITY(...)
#define SK_GUARDED_BY(x)
#define SK_REQUIRES(...)
#define SK_ACQUIRE(...)
virtual void assertValid()
Definition SkStrike.h:40
virtual bool canDelete()=0
virtual ~SkStrikePinner()=default
const SkDescriptor & descriptor() const
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
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
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
static const uint8_t buffer[]
const Scalar scale