Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit ee2a3f3

Browse files
herbderbySkia Commit-Bot
authored andcommitted
Add back tight scaler context managment
Release the scaler context after the differences are calculated so that the type faces can recoup resources. Change-Id: Ieb65dafdeee6f84d0739399d58f8d8d53ad7364e Reviewed-on: https://skia-review.googlesource.com/149233 Reviewed-by: Khusal Sagar <khushalsagar@chromium.org> Commit-Queue: Herb Derby <herb@google.com>
1 parent 4f28d76 commit ee2a3f3

File tree

2 files changed

+54
-34
lines changed

2 files changed

+54
-34
lines changed

src/core/SkRemoteGlyphCache.cpp

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,33 @@ void SkStrikeServer::writeStrikeData(std::vector<uint8_t>* memory) {
429429
fLockedDescs.clear();
430430
}
431431

432+
SkStrikeServer::SkGlyphCacheState::SkGlyphCacheState(
433+
std::unique_ptr<SkDescriptor> keyDescriptor, uint32_t discardableHandleId)
434+
: fKeyDescriptor(std::move(keyDescriptor))
435+
, fDiscardableHandleId(discardableHandleId) {
436+
SkASSERT(fKeyDescriptor);
437+
}
438+
439+
SkStrikeServer::SkGlyphCacheState::~SkGlyphCacheState() = default;
440+
441+
void SkStrikeServer::SkGlyphCacheState::ensureScalerContext(
442+
const SkPaint& paint,
443+
const SkSurfaceProps* props,
444+
const SkMatrix* matrix,
445+
SkScalerContextFlags flags,
446+
SkScalerContextEffects* effects) {
447+
if (fContext == nullptr || fDeviceDescriptor == nullptr) {
448+
SkScalerContextRec deviceRec;
449+
SkScalerContext::MakeRecAndEffects(paint, props, matrix, flags, &deviceRec, effects, true);
450+
auto deviceDesc = SkScalerContext::DescriptorGivenRecAndEffects(deviceRec, *effects);
451+
auto* tf = paint.getTypeface();
452+
fContext = tf->createScalerContext(*effects, deviceDesc.get(), false);
453+
fIsSubpixel = fContext->isSubpixel();
454+
fAxisAlignmentForHText = fContext->computeAxisAlignmentForHText();
455+
fDeviceDescriptor = std::move(deviceDesc);
456+
}
457+
}
458+
432459
SkStrikeServer::SkGlyphCacheState* SkStrikeServer::getOrCreateCache(
433460
const SkPaint& paint,
434461
const SkSurfaceProps* props,
@@ -444,22 +471,26 @@ SkStrikeServer::SkGlyphCacheState* SkStrikeServer::getOrCreateCache(
444471
if (fLockedDescs.find(keyDesc.get()) != fLockedDescs.end()) {
445472
auto it = fRemoteGlyphStateMap.find(keyDesc.get());
446473
SkASSERT(it != fRemoteGlyphStateMap.end());
447-
return it->second.get();
474+
SkGlyphCacheState* cache = it->second.get();
475+
cache->ensureScalerContext(paint, props, matrix, flags, effects);
476+
return cache;
448477
}
449478

450479
// Try to lock.
451480
auto it = fRemoteGlyphStateMap.find(keyDesc.get());
452481
if (it != fRemoteGlyphStateMap.end()) {
482+
SkGlyphCacheState* cache = it->second.get();
453483
#ifdef SK_DEBUG
454484
SkScalerContextRec deviceRec;
455485
SkScalerContext::MakeRecAndEffects(paint, props, matrix, flags, &deviceRec, effects, true);
456486
auto deviceDesc = SkScalerContext::DescriptorGivenRecAndEffects(deviceRec, *effects);
457-
SkASSERT(it->second->getDeviceDescriptor() == *deviceDesc);
487+
SkASSERT(cache->getDeviceDescriptor() == *deviceDesc);
458488
#endif
459489
bool locked = fDiscardableHandleManager->lockHandle(it->second->discardableHandleId());
460490
if (locked) {
461491
fLockedDescs.insert(it->first);
462-
return it->second.get();
492+
cache->ensureScalerContext(paint, props, matrix, flags, effects);
493+
return cache;
463494
}
464495

465496
// If the lock failed, the entry was deleted on the client. Remove our
@@ -475,39 +506,18 @@ SkStrikeServer::SkGlyphCacheState* SkStrikeServer::getOrCreateCache(
475506
tf->isFixedPitch());
476507
}
477508

478-
SkScalerContextRec deviceRec;
479-
SkScalerContext::MakeRecAndEffects(paint, props, matrix, flags, &deviceRec, effects, true);
480-
auto deviceDesc = SkScalerContext::DescriptorGivenRecAndEffects(deviceRec, *effects);
481-
509+
// Create a new cache state and insert it into the map.
482510
auto* keyDescPtr = keyDesc.get();
483511
auto newHandle = fDiscardableHandleManager->createHandle();
484-
auto scalerContext = tf->createScalerContext(*effects, deviceDesc.get(), false);
485-
auto cacheState = skstd::make_unique<SkGlyphCacheState>(
486-
std::move(deviceDesc), std::move(keyDesc), newHandle, std::move(scalerContext));
512+
auto cacheState = skstd::make_unique<SkGlyphCacheState>(std::move(keyDesc), newHandle);
487513
auto* cacheStatePtr = cacheState.get();
488514

489515
fLockedDescs.insert(keyDescPtr);
490516
fRemoteGlyphStateMap[keyDescPtr] = std::move(cacheState);
517+
cacheStatePtr->ensureScalerContext(paint, props, matrix, flags, effects);
491518
return cacheStatePtr;
492519
}
493520

494-
SkStrikeServer::SkGlyphCacheState::SkGlyphCacheState(std::unique_ptr<SkDescriptor> deviceDescriptor,
495-
std::unique_ptr<SkDescriptor>
496-
keyDescriptor,
497-
uint32_t discardableHandleId,
498-
std::unique_ptr<SkScalerContext> context)
499-
: fDeviceDescriptor(std::move(deviceDescriptor))
500-
, fKeyDescriptor(std::move(keyDescriptor))
501-
, fDiscardableHandleId(discardableHandleId)
502-
, fContext(std::move(context))
503-
, fIsSubpixel(fContext->isSubpixel())
504-
, fAxisAlignmentForHText(fContext->computeAxisAlignmentForHText()) {
505-
SkASSERT(fDeviceDescriptor);
506-
SkASSERT(fKeyDescriptor);
507-
}
508-
509-
SkStrikeServer::SkGlyphCacheState::~SkGlyphCacheState() = default;
510-
511521
void SkStrikeServer::SkGlyphCacheState::addGlyph(SkPackedGlyphID glyph, bool asPath) {
512522
auto* cache = asPath ? &fCachedGlyphPaths : &fCachedGlyphImages;
513523
auto* pending = asPath ? &fPendingGlyphPaths : &fPendingGlyphImages;
@@ -525,6 +535,8 @@ void SkStrikeServer::SkGlyphCacheState::writePendingGlyphs(Serializer* serialize
525535
// TODO(khushalsagar): Write a strike only if it has any pending glyphs.
526536
serializer->emplace<bool>(this->hasPendingGlyphs());
527537
if (!this->hasPendingGlyphs()) {
538+
// See comment below for reset.
539+
fContext.reset();
528540
return;
529541
}
530542

@@ -591,6 +603,10 @@ void SkStrikeServer::SkGlyphCacheState::writePendingGlyphs(Serializer* serialize
591603
writeGlyphPath(glyphID, serializer);
592604
}
593605
fPendingGlyphPaths.clear();
606+
607+
// Note that we reset the context after serializing pending glyphs since we
608+
// don't want to extend the lifetime of the typeface.
609+
fContext.reset();
594610
}
595611

596612
const SkGlyph& SkStrikeServer::SkGlyphCacheState::findGlyph(SkPackedGlyphID glyphID) {

src/core/SkRemoteGlyphCache.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,9 @@ class SK_API SkStrikeServer {
149149
// Methods used internally in skia ------------------------------------------
150150
class SkGlyphCacheState {
151151
public:
152-
SkGlyphCacheState(std::unique_ptr<SkDescriptor> deviceDescriptor,
153-
std::unique_ptr<SkDescriptor> keyDescriptor,
154-
SkDiscardableHandleId discardableHandleId,
155-
std::unique_ptr<SkScalerContext> scalerContext);
152+
// N.B. SkGlyphCacheState is not valid until ensureScalerContext is called.
153+
SkGlyphCacheState(std::unique_ptr<SkDescriptor> keyDescriptor,
154+
SkDiscardableHandleId discardableHandleId);
156155
~SkGlyphCacheState();
157156

158157
void addGlyph(SkPackedGlyphID, bool pathOnly);
@@ -168,6 +167,11 @@ class SK_API SkStrikeServer {
168167
return *fKeyDescriptor;
169168
}
170169
const SkGlyph& findGlyph(SkPackedGlyphID);
170+
void ensureScalerContext(const SkPaint& paint,
171+
const SkSurfaceProps* props,
172+
const SkMatrix* matrix,
173+
SkScalerContextFlags flags,
174+
SkScalerContextEffects* effects);
171175

172176
private:
173177
bool hasPendingGlyphs() const {
@@ -191,9 +195,9 @@ class SK_API SkStrikeServer {
191195
std::unique_ptr<SkDescriptor> fKeyDescriptor;
192196
const SkDiscardableHandleId fDiscardableHandleId;
193197
// The context built using fDeviceDescriptor
194-
const std::unique_ptr<SkScalerContext> fContext;
195-
const bool fIsSubpixel;
196-
const SkAxisAlignment fAxisAlignmentForHText;
198+
std::unique_ptr<SkScalerContext> fContext;
199+
bool fIsSubpixel = true;
200+
SkAxisAlignment fAxisAlignmentForHText;
197201

198202
// FallbackTextHelper cases require glyph metrics when analyzing a glyph run, in which case
199203
// we cache them here.

0 commit comments

Comments
 (0)