47 std::unique_ptr<SkScalerContext> scaler,
49 std::unique_ptr<SkStrikePinner> pinner)
51 , fRoundingSpec{scaler->isSubpixel(),
52 scaler->computeAxisAlignmentForHText()}
53 , fStrikeSpec{strikeSpec}
54 , fStrikeCache{strikeCache}
55 , fScalerContext{
std::move(scaler)}
56 , fPinner{
std::move(pinner)} {
76 fStrikeLock.acquire();
81 const size_t memoryIncrease = fMemoryIncrease;
82 fStrikeLock.release();
83 this->updateMemoryUsage(memoryIncrease);
92 SkTFitsIn<int>(paths.
size()) &&
93 SkTFitsIn<int>(drawables.
size()));
119 const int imagesCount =
buffer.readInt();
120 if (imagesCount == 0 && !
buffer.isValid()) {
126 for (
int curImage = 0; curImage < imagesCount; ++curImage) {
127 if (!this->mergeGlyphAndImageFromBuffer(
buffer)) {
134 const int pathsCount =
buffer.readInt();
135 if (pathsCount == 0 && !
buffer.isValid()) {
140 for (
int curPath = 0; curPath < pathsCount; ++curPath) {
141 if (!this->mergeGlyphAndPathFromBuffer(
buffer)) {
148 const int drawablesCount =
buffer.readInt();
149 if (drawablesCount == 0 && !
buffer.isValid()) {
154 for (
int curDrawable = 0; curDrawable < drawablesCount; ++curDrawable) {
155 if (!this->mergeGlyphAndDrawableFromBuffer(
buffer)) {
168 if (digest !=
nullptr) {
173 SkDEBUGFAIL(
"Re-adding image to existing glyph. This should not happen.");
182 (void)this->addGlyphAndDigest(
glyph);
190 SkDEBUGFAIL(
"Re-adding path to existing glyph. This should not happen.");
202 SkDEBUGFAIL(
"Re-adding drawable to existing glyph. This should not happen.");
221 return this->internalPrepare(glyphIDs, kMetricsOnly, results);
227 return this->internalPrepare(glyphIDs, kMetricsAndPath, results);
232 const SkGlyph** cursor = results;
234 for (
auto glyphID : glyphIDs) {
240 return {results, glyphIDs.
size()};
245 const SkGlyph** cursor = results;
248 for (
auto glyphID : glyphIDs) {
255 return {results, glyphIDs.
size()};
279 const SkTypeface* face = fScalerContext->getTypeface();
289 msg.
printf(
"cache typeface:%x %25s:(%d,%d,%d)\n %s glyphs:%3d",
291 rec.
dump().
c_str(), fDigestForPackedGlyphID.count());
297 const SkTypeface* face = fScalerContext->getTypeface();
303 for (
size_t index = 0; index < fontName.
size(); ++index) {
304 if (!std::isalnum(fontName[index])) {
305 fontName[index] =
'_';
310 SkStrikeCache::kGlyphCacheDumpName,
315 dump->dumpNumericValue(dumpName.
c_str(),
"size",
"bytes", fMemoryUsed);
317 "glyph_count",
"objects",
318 fDigestForPackedGlyphID.count());
319 dump->setMemoryBacking(dumpName.
c_str(),
"malloc",
nullptr);
323 return fGlyphForIndex[digest.
index()];
328 return this->
glyph(digest);
332 SkGlyphDigest* digestPtr = fDigestForPackedGlyphID.find(packedGlyphID);
333 if (digestPtr !=
nullptr && digestPtr->
actionFor(actionType) != GlyphAction::kUnset) {
338 if (digestPtr !=
nullptr) {
341 glyph = fAlloc.
make<
SkGlyph>(fScalerContext->makeGlyph(packedGlyphID, &fAlloc));
342 fMemoryIncrease +=
sizeof(
SkGlyph);
343 digestPtr = this->addGlyphAndDigest(
glyph);
352 size_t index = fGlyphForIndex.size();
354 SkGlyphDigest* newDigest = fDigestForPackedGlyphID.set(digest);
355 fGlyphForIndex.push_back(
glyph);
377 fMemoryIncrease += increase;
385 if (!
buffer.validate(prototypeGlyph.has_value())) {
390 SkGlyphDigest* digestPtr = fDigestForPackedGlyphID.find(prototypeGlyph->getPackedID());
391 if (digestPtr !=
nullptr) {
392 return fGlyphForIndex[digestPtr->
index()];
397 fMemoryIncrease +=
sizeof(
SkGlyph);
398 this->addGlyphAndDigest(
glyph);
434 const SkGlyph** cursor = results;
435 for (
auto glyphID : glyphIDs) {
437 if (pathDetail == kMetricsAndPath) {
443 return {results, glyphIDs.
size()};
446void SkStrike::updateMemoryUsage(
size_t increase) {
451 fMemoryUsed += increase;
453 fStrikeCache->fTotalMemoryUsed += increase;
#define SkDEBUGFAIL(message)
#define SkASSERT_RELEASE(cond)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define SkScalarInvert(x)
static SkFontMetrics use_or_generate_metrics(const SkFontMetrics *metrics, SkScalerContext *context)
SK_API SkString static SkString SkStringPrintf()
#define SK_SCOPED_CAPABILITY
#define SK_RELEASE_CAPABILITY(...)
static void dump(const float m[20], SkYUVColorSpace cs, bool rgb2yuv)
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
size_t approximateBytesUsed()
void setActionFor(skglyph::ActionType, SkGlyph *, sktext::StrikeForGPU *)
skglyph::GlyphAction actionFor(skglyph::ActionType actionType) const
bool setPathHasBeenCalled() const
size_t addPathFromBuffer(SkReadBuffer &, SkArenaAlloc *)
void ensureIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos, SkScalar *array, int *count, SkArenaAlloc *alloc)
void flattenMetrics(SkWriteBuffer &) const
bool setDrawableHasBeenCalled() const
bool setImageHasBeenCalled() const
size_t setMetricsAndImage(SkArenaAlloc *alloc, const SkGlyph &from)
const SkPath * path() const
SkMask::Format maskFormat() const
bool setDrawable(SkArenaAlloc *alloc, SkScalerContext *scalerContext)
bool setPath(SkArenaAlloc *alloc, SkScalerContext *scalerContext)
void flattenPath(SkWriteBuffer &) const
bool setImage(SkArenaAlloc *alloc, SkScalerContext *scalerContext)
void flattenDrawable(SkWriteBuffer &) const
size_t addImageFromBuffer(SkReadBuffer &, SkArenaAlloc *)
size_t addDrawableFromBuffer(SkReadBuffer &, SkArenaAlloc *)
void flattenImage(SkWriteBuffer &) const
SkDrawable * drawable() const
const void * image() const
static std::optional< SkGlyph > MakeFromBuffer(SkReadBuffer &)
size_t approximateBytesUsed() const
void getFontMetrics(SkFontMetrics *)
constexpr size_t size() const
static void FlattenGlyphsByType(SkWriteBuffer &buffer, SkSpan< SkGlyph > images, SkSpan< SkGlyph > paths, SkSpan< SkGlyph > drawables)
void dump() const SK_EXCLUDES(fStrikeLock)
const SkDrawable * mergeDrawable(SkGlyph *glyph, sk_sp< SkDrawable > drawable) SK_EXCLUDES(fStrikeLock)
void glyphIDsToDrawables(SkSpan< sktext::IDOrDrawable > idsOrDrawables) SK_EXCLUDES(fStrikeLock)
void dumpMemoryStatistics(SkTraceMemoryDump *dump) const SK_EXCLUDES(fStrikeLock)
void unlock() override SK_RELEASE_CAPABILITY(fStrikeLock)
bool mergeFromBuffer(SkReadBuffer &buffer) SK_EXCLUDES(fStrikeLock)
~Monitor() SK_RELEASE_CAPABILITY()
SkSpan< const SkGlyph * > metrics(SkSpan< const SkGlyphID > glyphIDs, const SkGlyph *results[]) SK_EXCLUDES(fStrikeLock)
const SkPath * mergePath(SkGlyph *glyph, const SkPath *path, bool hairline) SK_EXCLUDES(fStrikeLock)
bool prepareForPath(SkGlyph *) override SK_REQUIRES(fStrikeLock)
void lock() override SK_ACQUIRE(fStrikeLock)
SkStrike(SkStrikeCache *strikeCache, const SkStrikeSpec &strikeSpec, std::unique_ptr< SkScalerContext > scaler, const SkFontMetrics *metrics, std::unique_ptr< SkStrikePinner > pinner)
SkSpan< const SkGlyph * > preparePaths(SkSpan< const SkGlyphID > glyphIDs, const SkGlyph *results[]) SK_EXCLUDES(fStrikeLock)
void findIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos, SkGlyph *, SkScalar *array, int *count) SK_EXCLUDES(fStrikeLock)
void glyphIDsToPaths(SkSpan< sktext::IDOrPath > idsOrPaths) SK_EXCLUDES(fStrikeLock)
SkGlyph * mergeGlyphAndImage(SkPackedGlyphID toID, const SkGlyph &fromGlyph) SK_EXCLUDES(fStrikeLock)
bool prepareForDrawable(SkGlyph *) override SK_REQUIRES(fStrikeLock)
Monitor(SkStrike *strike) SK_ACQUIRE(strike -> fStrikeLock) :fStrike
SkGlyph * glyph(SkGlyphDigest) SK_REQUIRES(fStrikeLock)
SkSpan< const SkGlyph * > prepareDrawables(SkSpan< const SkGlyphID > glyphIDs, const SkGlyph *results[]) SK_EXCLUDES(fStrikeLock)
bool prepareForImage(SkGlyph *glyph) override SK_REQUIRES(fStrikeLock)
SkSpan< const SkGlyph * > prepareImages(SkSpan< const SkPackedGlyphID > glyphIDs, const SkGlyph *results[]) SK_EXCLUDES(fStrikeLock)
SkGlyphDigest digestFor(skglyph::ActionType, SkPackedGlyphID) override SK_REQUIRES(fStrikeLock)
void printf(const char format[],...) SK_PRINTF_LIKE(2
const char * c_str() const
SkTypefaceID uniqueID() const
void getFamilyName(SkString *name) const
SkFontStyle fontStyle() const
static const uint8_t buffer[]
std::array< MockImage, 3 > images
static bool IsValidFormat(uint8_t format)
void getSingleMatrix(SkMatrix *) const