use SkStrikeSpec in remote and main strike cache

* Remove the SkDescriptor from SkScalerCache where it is never really
  used.
* Have SkStrike hold the descriptor
* Add a method to the SkStrikeSpec to create SkScalerContexts

Flow all the parameter changes through the code.

Change-Id: I11f2eec590b509eef0396b9288a6297fbe967dff
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/468457
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
This commit is contained in:
Herb Derby 2021-11-05 15:44:41 -04:00 committed by SkCQ
parent 54ab0dcfed
commit 54c496ba2c
10 changed files with 97 additions and 132 deletions

View File

@ -10,6 +10,7 @@
#include "include/core/SkTypeface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrRecordingContext.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkUtils.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/SkGr.h"
@ -17,7 +18,6 @@
#include "src/gpu/text/GrTextBlob.h"
#include "src/utils/SkUTF.h"
// From Project Guttenberg. This is UTF-8 text.
static const char* gText =
"Call me Ishmael. Some years ago--never mind how long precisely";

View File

@ -36,6 +36,7 @@
#include "src/gpu/text/GrSDFTControl.h"
#endif
// This essentially replaces the font_id used on the RendererSide with the font_id on the GPU side.
static SkDescriptor* auto_descriptor_from_desc(const SkDescriptor* source_desc,
SkFontID font_id,
SkAutoDescriptor* ad) {
@ -63,15 +64,6 @@ static SkDescriptor* auto_descriptor_from_desc(const SkDescriptor* source_desc,
return desc;
}
static const SkDescriptor* create_descriptor(
const SkPaint& paint, const SkFont& font, const SkMatrix& m,
const SkSurfaceProps& props, SkScalerContextFlags flags,
SkAutoDescriptor* ad, SkScalerContextEffects* effects) {
SkScalerContextRec rec;
SkScalerContext::MakeRecAndEffects(font, paint, props, flags, m, &rec, effects);
return SkScalerContext::AutoDescriptorGivenRecAndEffects(rec, *effects, ad);
}
// -- Serializer -----------------------------------------------------------------------------------
size_t pad(size_t size, size_t alignment) { return (size + (alignment - 1)) & ~(alignment - 1); }
@ -244,7 +236,7 @@ bool MapOps::operator()(const SkDescriptor* lhs, const SkDescriptor* rhs) const
class RemoteStrike final : public SkStrikeForGPU {
public:
// N.B. RemoteStrike is not valid until ensureScalerContext is called.
RemoteStrike(const SkDescriptor& descriptor,
RemoteStrike(const SkStrikeSpec& strikeSpec,
std::unique_ptr<SkScalerContext> context,
SkDiscardableHandleId discardableHandleId);
~RemoteStrike() override = default;
@ -256,7 +248,7 @@ public:
return *fDescriptor.getDesc();
}
void setTypefaceAndEffects(const SkTypeface* typeface, SkScalerContextEffects effects);
void setStrikeSpec(const SkStrikeSpec& strikeSpec);
const SkGlyphPositionRoundingSpec& roundingSpec() const override {
return fRoundingSpec;
@ -338,10 +330,9 @@ private:
// The context built using fDescriptor
std::unique_ptr<SkScalerContext> fContext;
// These fields are set every time getOrCreateCache. This allows the code to maintain the
// fContext as lazy as possible.
const SkTypeface* fTypeface{nullptr};
SkScalerContextEffects fEffects;
// fStrikeSpec is set every time getOrCreateCache is called. This allows the code to maintain
// the fContext as lazy as possible.
const SkStrikeSpec* fStrikeSpec;
// Have the metrics been sent for this strike. Only send them once.
bool fHaveSentFontMetrics{false};
@ -362,10 +353,10 @@ private:
};
RemoteStrike::RemoteStrike(
const SkDescriptor& descriptor,
const SkStrikeSpec& strikeSpec,
std::unique_ptr<SkScalerContext> context,
uint32_t discardableHandleId)
: fDescriptor{descriptor}
: fDescriptor{strikeSpec.descriptor()}
, fDiscardableHandleId(discardableHandleId)
, fRoundingSpec{context->isSubpixel(), context->computeAxisAlignmentForHText()}
// N.B. context must come last because it is used above.
@ -432,19 +423,17 @@ void RemoteStrike::writePendingGlyphs(Serializer* serializer) {
void RemoteStrike::ensureScalerContext() {
if (fContext == nullptr) {
fContext = fTypeface->createScalerContext(fEffects, fDescriptor.getDesc());
fContext = fStrikeSpec->createScalerContext();
}
}
void RemoteStrike::resetScalerContext() {
fContext.reset();
fTypeface = nullptr;
fContext = nullptr;
fStrikeSpec = nullptr;
}
void RemoteStrike::setTypefaceAndEffects(
const SkTypeface* typeface, SkScalerContextEffects effects) {
fTypeface = typeface;
fEffects = effects;
void RemoteStrike::setStrikeSpec(const SkStrikeSpec& strikeSpec) {
fStrikeSpec = &strikeSpec;
}
void RemoteStrike::writeGlyphPath(
@ -594,17 +583,7 @@ public:
sk_sp<SkData> serializeTypeface(SkTypeface*);
void writeStrikeData(std::vector<uint8_t>* memory);
// Methods for SkStrikeForGPUCacheInterface
RemoteStrike* getOrCreateCache(const SkPaint&,
const SkFont& font,
const SkSurfaceProps&,
const SkMatrix&,
SkScalerContextFlags flags,
SkScalerContextEffects* effects);
SkScopedStrikeForGPU findOrCreateScopedStrike(const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface) override;
SkScopedStrikeForGPU findOrCreateScopedStrike(const SkStrikeSpec& strikeSpec) override;
// Methods for testing
void setMaxEntriesInDescriptorMapForTesting(size_t count);
@ -615,9 +594,7 @@ private:
void checkForDeletedEntries();
RemoteStrike* getOrCreateCache(const SkDescriptor& desc,
const SkTypeface& typeface,
SkScalerContextEffects effects);
RemoteStrike* getOrCreateCache(const SkStrikeSpec& strikeSpec);
using DescToRemoteStrike =
@ -722,23 +699,8 @@ void SkStrikeServerImpl::writeStrikeData(std::vector<uint8_t>* memory) {
#endif
}
RemoteStrike* SkStrikeServerImpl::getOrCreateCache(
const SkPaint& paint,
const SkFont& font,
const SkSurfaceProps& props,
const SkMatrix& matrix,
SkScalerContextFlags flags,
SkScalerContextEffects* effects) {
SkAutoDescriptor descStorage;
auto desc = create_descriptor(paint, font, matrix, props, flags, &descStorage, effects);
return this->getOrCreateCache(*desc, *font.getTypefaceOrDefault(), *effects);
}
SkScopedStrikeForGPU SkStrikeServerImpl::findOrCreateScopedStrike(const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface) {
return SkScopedStrikeForGPU{this->getOrCreateCache(desc, typeface, effects)};
SkScopedStrikeForGPU SkStrikeServerImpl::findOrCreateScopedStrike(const SkStrikeSpec& strikeSpec) {
return SkScopedStrikeForGPU{this->getOrCreateCache(strikeSpec)};
}
void SkStrikeServerImpl::checkForDeletedEntries() {
@ -756,15 +718,15 @@ void SkStrikeServerImpl::checkForDeletedEntries() {
}
}
RemoteStrike* SkStrikeServerImpl::getOrCreateCache(
const SkDescriptor& desc, const SkTypeface& typeface, SkScalerContextEffects effects) {
RemoteStrike* SkStrikeServerImpl::getOrCreateCache(const SkStrikeSpec& strikeSpec) {
// In cases where tracing is turned off, make sure not to get an unused function warning.
// Lambdaize the function.
TRACE_EVENT1("skia", "RecForDesc", "rec",
TRACE_STR_COPY(
[&desc](){
auto ptr = desc.findEntry(kRec_SkDescriptorTag, nullptr);
[&strikeSpec](){
auto ptr =
strikeSpec.descriptor().findEntry(kRec_SkDescriptorTag, nullptr);
SkScalerContextRec rec;
std::memcpy((void*)&rec, ptr, sizeof(rec));
return rec.dump();
@ -772,11 +734,11 @@ RemoteStrike* SkStrikeServerImpl::getOrCreateCache(
)
);
auto it = fDescToRemoteStrike.find(&desc);
auto it = fDescToRemoteStrike.find(&strikeSpec.descriptor());
if (it != fDescToRemoteStrike.end()) {
// We have processed the RemoteStrike before. Reuse it.
RemoteStrike* strike = it->second.get();
strike->setTypefaceAndEffects(&typeface, effects);
strike->setStrikeSpec(strikeSpec);
if (fRemoteStrikesToSend.contains(strike)) {
// Already tracking
return strike;
@ -792,6 +754,7 @@ RemoteStrike* SkStrikeServerImpl::getOrCreateCache(
fDescToRemoteStrike.erase(it);
}
const SkTypeface& typeface = strikeSpec.typeface();
// Create a new RemoteStrike. Start by processing the typeface.
const SkFontID typefaceId = typeface.uniqueID();
if (!fCachedTypefaces.contains(typefaceId)) {
@ -802,10 +765,10 @@ RemoteStrike* SkStrikeServerImpl::getOrCreateCache(
typeface.glyphMaskNeedsCurrentColor());
}
auto context = typeface.createScalerContext(effects, &desc);
auto context = strikeSpec.createScalerContext();
auto newHandle = fDiscardableHandleManager->createHandle(); // Locked on creation
auto remoteStrike = std::make_unique<RemoteStrike>(desc, std::move(context), newHandle);
remoteStrike->setTypefaceAndEffects(&typeface, effects);
auto remoteStrike = std::make_unique<RemoteStrike>(strikeSpec, std::move(context), newHandle);
remoteStrike->setStrikeSpec(strikeSpec);
auto remoteStrikePtr = remoteStrike.get();
fRemoteStrikesToSend.add(remoteStrikePtr);
auto d = &remoteStrike->getDescriptor();
@ -813,8 +776,6 @@ RemoteStrike* SkStrikeServerImpl::getOrCreateCache(
checkForDeletedEntries();
// Be sure we can build glyphs with this RemoteStrike.
remoteStrikePtr->setTypefaceAndEffects(&typeface, effects);
return remoteStrikePtr;
}
@ -1043,10 +1004,9 @@ bool SkStrikeClientImpl::readStrikeData(const volatile void* memory, size_t memo
// Note that we don't need to deserialize the effects since we won't be generating any
// glyphs here anyway, and the desc is still correct since it includes the serialized
// effects.
SkScalerContextEffects effects;
auto scaler = tf->createScalerContext(effects, client_desc);
SkStrikeSpec strikeSpec{*client_desc, *tfPtr};
strike = fStrikeCache->createStrike(
*client_desc, std::move(scaler), &fontMetrics,
strikeSpec, &fontMetrics,
std::make_unique<DiscardableStrikePinner>(
spec.discardableHandleId, fDiscardableHandleManager));
}

View File

@ -25,11 +25,9 @@ static SkFontMetrics use_or_generate_metrics(
}
SkScalerCache::SkScalerCache(
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
const SkFontMetrics* fontMetrics)
: fDesc{desc}
, fScalerContext{std::move(scaler)}
: fScalerContext{std::move(scaler)}
, fFontMetrics{use_or_generate_metrics(fontMetrics, fScalerContext.get())}
, fRoundingSpec{fScalerContext->isSubpixel(),
fScalerContext->computeAxisAlignmentForHText()} {
@ -77,10 +75,6 @@ std::tuple<const SkPath*, size_t> SkScalerCache::mergePath(SkGlyph* glyph, const
return {glyph->path(), pathDelta};
}
const SkDescriptor& SkScalerCache::getDescriptor() const {
return *fDesc.getDesc();
}
int SkScalerCache::countCachedGlyphs() const {
SkAutoMutexExclusive lock(fMu);
return fDigestForPackedGlyphID.count();

View File

@ -52,8 +52,7 @@ private:
// holds the glyphs for that strike.
class SkScalerCache {
public:
SkScalerCache(const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
SkScalerCache(std::unique_ptr<SkScalerContext> scaler,
const SkFontMetrics* metrics = nullptr);
// Lookup (or create if needed) the toGlyph using toID. If that glyph is not initialized with
@ -96,8 +95,6 @@ public:
return fRoundingSpec;
}
const SkDescriptor& getDescriptor() const;
size_t prepareForMaskDrawing(
SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) SK_EXCLUDES(fMu);
@ -140,7 +137,6 @@ private:
PathDetail pathDetail,
const SkGlyph** results) SK_REQUIRES(fMu);
const SkAutoDescriptor fDesc;
const std::unique_ptr<SkScalerContext> fScalerContext;
const SkFontMetrics fFontMetrics;
const SkGlyphPositionRoundingSpec fRoundingSpec;

View File

@ -29,23 +29,18 @@ SkStrikeCache* SkStrikeCache::GlobalStrikeCache() {
return cache;
}
auto SkStrikeCache::findOrCreateStrike(const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface) -> sk_sp<SkStrike> {
auto SkStrikeCache::findOrCreateStrike(const SkStrikeSpec& strikeSpec) -> sk_sp<SkStrike> {
SkAutoMutexExclusive ac(fLock);
sk_sp<SkStrike> strike = this->internalFindStrikeOrNull(desc);
sk_sp<SkStrike> strike = this->internalFindStrikeOrNull(strikeSpec.descriptor());
if (strike == nullptr) {
auto scaler = typeface.createScalerContext(effects, &desc);
strike = this->internalCreateStrike(desc, std::move(scaler));
strike = this->internalCreateStrike(strikeSpec);
}
this->internalPurge();
return strike;
}
SkScopedStrikeForGPU SkStrikeCache::findOrCreateScopedStrike(const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface) {
return SkScopedStrikeForGPU{this->findOrCreateStrike(desc, effects, typeface).release()};
SkScopedStrikeForGPU SkStrikeCache::findOrCreateScopedStrike(const SkStrikeSpec& strikeSpec) {
return SkScopedStrikeForGPU{this->findOrCreateStrike(strikeSpec).release()};
}
void SkStrikeCache::PurgeAll() {
@ -151,21 +146,20 @@ auto SkStrikeCache::internalFindStrikeOrNull(const SkDescriptor& desc) -> sk_sp<
}
sk_sp<SkStrike> SkStrikeCache::createStrike(
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
const SkStrikeSpec& strikeSpec,
SkFontMetrics* maybeMetrics,
std::unique_ptr<SkStrikePinner> pinner) {
SkAutoMutexExclusive ac(fLock);
return this->internalCreateStrike(desc, std::move(scaler), maybeMetrics, std::move(pinner));
return this->internalCreateStrike(strikeSpec, maybeMetrics, std::move(pinner));
}
auto SkStrikeCache::internalCreateStrike(
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
const SkStrikeSpec& strikeSpec,
SkFontMetrics* maybeMetrics,
std::unique_ptr<SkStrikePinner> pinner) -> sk_sp<SkStrike> {
std::unique_ptr<SkScalerContext> scaler = strikeSpec.createScalerContext();
auto strike =
sk_make_sp<SkStrike>(this, desc, std::move(scaler), maybeMetrics, std::move(pinner));
sk_make_sp<SkStrike>(this, strikeSpec, std::move(scaler), maybeMetrics, std::move(pinner));
this->internalAttachToHead(strike);
return strike;
}

View File

@ -16,6 +16,7 @@
#include "src/core/SkDescriptor.h"
#include "src/core/SkScalerCache.h"
#include "src/core/SkStrikeForGPU.h"
#include "src/core/SkStrikeSpec.h"
class SkTraceMemoryDump;
class SkStrikeCache;
@ -39,12 +40,13 @@ public:
class SkStrike final : public SkRefCnt, public SkStrikeForGPU {
public:
SkStrike(SkStrikeCache* strikeCache,
const SkDescriptor& desc,
const SkStrikeSpec& strikeSpec,
std::unique_ptr<SkScalerContext> scaler,
const SkFontMetrics* metrics,
std::unique_ptr<SkStrikePinner> pinner)
: fStrikeCache{strikeCache}
, fScalerCache{desc, std::move(scaler), metrics}
: fStrikeSpec(strikeSpec)
, fStrikeCache{strikeCache}
, fScalerCache{std::move(scaler), metrics}
, fPinner{std::move(pinner)} {}
SkGlyph* mergeGlyphAndImage(SkPackedGlyphID toID, const SkGlyph& from) {
@ -59,6 +61,7 @@ public:
return glyphPath;
}
// [[deprecated]]
SkScalerContext* getScalerContext() const {
return fScalerCache.getScalerContext();
}
@ -103,7 +106,7 @@ public:
}
const SkDescriptor& getDescriptor() const override {
return fScalerCache.getDescriptor();
return fStrikeSpec.descriptor();
}
void prepareForMaskDrawing(
@ -134,6 +137,7 @@ public:
void updateDelta(size_t increase);
const SkStrikeSpec fStrikeSpec;
SkStrikeCache* const fStrikeCache;
SkStrike* fNext{nullptr};
SkStrike* fPrev{nullptr};
@ -152,20 +156,14 @@ public:
sk_sp<SkStrike> findStrike(const SkDescriptor& desc) SK_EXCLUDES(fLock);
sk_sp<SkStrike> createStrike(
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
const SkStrikeSpec& strikeSpec,
SkFontMetrics* maybeMetrics = nullptr,
std::unique_ptr<SkStrikePinner> = nullptr) SK_EXCLUDES(fLock);
sk_sp<SkStrike> findOrCreateStrike(
const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface) SK_EXCLUDES(fLock);
sk_sp<SkStrike> findOrCreateStrike(const SkStrikeSpec& strikeSpec) SK_EXCLUDES(fLock);
SkScopedStrikeForGPU findOrCreateScopedStrike(
const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface) override SK_EXCLUDES(fLock);
const SkStrikeSpec& strikeSpec) override SK_EXCLUDES(fLock);
static void PurgeAll();
static void Dump();
@ -188,8 +186,7 @@ private:
friend class SkStrike; // for SkStrike::updateDelta
sk_sp<SkStrike> internalFindStrikeOrNull(const SkDescriptor& desc) SK_REQUIRES(fLock);
sk_sp<SkStrike> internalCreateStrike(
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
const SkStrikeSpec& strikeSpec,
SkFontMetrics* maybeMetrics = nullptr,
std::unique_ptr<SkStrikePinner> = nullptr) SK_REQUIRES(fLock);

View File

@ -23,6 +23,7 @@ class SkMaskFilter;
class SkPathEffect;
class SkSourceGlyphBuffer;
class SkStrike;
class SkStrikeSpec;
class SkTypeface;
struct SkGlyphPositionRoundingSpec;
struct SkScalerContextEffects;
@ -68,8 +69,6 @@ using SkScopedStrikeForGPU = std::unique_ptr<SkStrikeForGPU, SkStrikeForGPU::Del
class SkStrikeForGPUCacheInterface {
public:
virtual ~SkStrikeForGPUCacheInterface() = default;
virtual SkScopedStrikeForGPU findOrCreateScopedStrike(const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface) = 0;
virtual SkScopedStrikeForGPU findOrCreateScopedStrike(const SkStrikeSpec& strikeSpec) = 0;
};
#endif //SkStrikeInterface_DEFINED

View File

@ -19,6 +19,14 @@
#include "src/gpu/text/GrStrikeCache.h"
#endif
SkStrikeSpec::SkStrikeSpec(const SkDescriptor& descriptor, sk_sp<SkTypeface> typeface)
: fAutoDescriptor{descriptor}
, fTypeface{std::move(typeface)} {}
SkStrikeSpec::SkStrikeSpec(const SkStrikeSpec&) = default;
SkStrikeSpec::SkStrikeSpec(SkStrikeSpec&&) = default;
SkStrikeSpec::~SkStrikeSpec() = default;
SkStrikeSpec SkStrikeSpec::MakeMask(const SkFont& font, const SkPaint& paint,
const SkSurfaceProps& surfaceProps,
SkScalerContextFlags scalerContextFlags,
@ -208,14 +216,19 @@ SkStrikeSpec::SkStrikeSpec(const SkFont& font, const SkPaint& paint,
fTypeface = font.refTypefaceOrDefault();
}
SkScopedStrikeForGPU SkStrikeSpec::findOrCreateScopedStrike(SkStrikeForGPUCacheInterface* cache) const {
SkScopedStrikeForGPU SkStrikeSpec::findOrCreateScopedStrike(
SkStrikeForGPUCacheInterface* cache) const {
return cache->findOrCreateScopedStrike(*this);
}
sk_sp<SkStrike> SkStrikeSpec::findOrCreateStrike() const {
SkScalerContextEffects effects{fPathEffect.get(), fMaskFilter.get()};
return cache->findOrCreateScopedStrike(*fAutoDescriptor.getDesc(), effects, *fTypeface);
return SkStrikeCache::GlobalStrikeCache()->findOrCreateStrike(*this);
}
sk_sp<SkStrike> SkStrikeSpec::findOrCreateStrike(SkStrikeCache* cache) const {
SkScalerContextEffects effects{fPathEffect.get(), fMaskFilter.get()};
return cache->findOrCreateStrike(*fAutoDescriptor.getDesc(), effects, *fTypeface);
return cache->findOrCreateStrike(*this);
}
SkBulkGlyphMetrics::SkBulkGlyphMetrics(const SkStrikeSpec& spec)
@ -236,6 +249,8 @@ SkBulkGlyphMetricsAndPaths::SkBulkGlyphMetricsAndPaths(const SkStrikeSpec& spec)
SkBulkGlyphMetricsAndPaths::SkBulkGlyphMetricsAndPaths(sk_sp<SkStrike>&& strike)
: fStrike{std::move(strike)} { }
SkBulkGlyphMetricsAndPaths::~SkBulkGlyphMetricsAndPaths() = default;
SkSpan<const SkGlyph*> SkBulkGlyphMetricsAndPaths::glyphs(SkSpan<const SkGlyphID> glyphIDs) {
fGlyphs.reset(glyphIDs.size());
return fStrike->preparePaths(glyphIDs, fGlyphs.get());
@ -259,6 +274,8 @@ SkBulkGlyphMetricsAndImages::SkBulkGlyphMetricsAndImages(const SkStrikeSpec& spe
SkBulkGlyphMetricsAndImages::SkBulkGlyphMetricsAndImages(sk_sp<SkStrike>&& strike)
: fStrike{std::move(strike)} { }
SkBulkGlyphMetricsAndImages::~SkBulkGlyphMetricsAndImages() = default;
SkSpan<const SkGlyph*> SkBulkGlyphMetricsAndImages::glyphs(SkSpan<const SkPackedGlyphID> glyphIDs) {
fGlyphs.reset(glyphIDs.size());
return fStrike->prepareImages(glyphIDs, fGlyphs.get());

View File

@ -8,8 +8,9 @@
#ifndef SkStrikeSpec_DEFINED
#define SkStrikeSpec_DEFINED
#include "include/core/SkMaskFilter.h"
#include "include/core/SkPathEffect.h"
#include "src/core/SkDescriptor.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeForGPU.h"
#include <tuple>
@ -27,13 +28,14 @@ class SkSurfaceProps;
class SkStrikeSpec {
public:
SkStrikeSpec(const SkStrikeSpec&) = default;
SkStrikeSpec(const SkDescriptor& descriptor, sk_sp<SkTypeface> typeface);
SkStrikeSpec(const SkStrikeSpec&);
SkStrikeSpec& operator=(const SkStrikeSpec&) = delete;
SkStrikeSpec(SkStrikeSpec&&) = default;
SkStrikeSpec(SkStrikeSpec&&);
SkStrikeSpec& operator=(SkStrikeSpec&&) = delete;
~SkStrikeSpec() = default;
~SkStrikeSpec();
// Create a strike spec for mask style cache entries.
static SkStrikeSpec MakeMask(
@ -81,13 +83,20 @@ public:
SkScopedStrikeForGPU findOrCreateScopedStrike(SkStrikeForGPUCacheInterface* cache) const;
sk_sp<SkStrike> findOrCreateStrike(
SkStrikeCache* cache = SkStrikeCache::GlobalStrikeCache()) const;
sk_sp<SkStrike> findOrCreateStrike() const;
sk_sp<SkStrike> findOrCreateStrike(SkStrikeCache* cache) const;
std::unique_ptr<SkScalerContext> createScalerContext() const {
SkScalerContextEffects effects{fPathEffect.get(), fMaskFilter.get()};
return fTypeface->createScalerContext(effects, fAutoDescriptor.getDesc());
}
// This call is deprecated.
SkScalar strikeToSourceRatio() const { return fStrikeToSourceRatio; }
bool isEmpty() const { return SkScalarNearlyZero(fStrikeToSourceRatio); }
const SkDescriptor& descriptor() const { return *fAutoDescriptor.getDesc(); }
const SkTypeface& typeface() const { return *fTypeface; }
static bool ShouldDrawAsPath(const SkPaint& paint, const SkFont& font, const SkMatrix& matrix);
SkString dump() const;
@ -101,10 +110,10 @@ private:
SkScalar strikeToSourceRatio);
SkAutoDescriptor fAutoDescriptor;
sk_sp<SkMaskFilter> fMaskFilter;
sk_sp<SkPathEffect> fPathEffect;
sk_sp<SkMaskFilter> fMaskFilter{nullptr};
sk_sp<SkPathEffect> fPathEffect{nullptr};
sk_sp<SkTypeface> fTypeface;
const SkScalar fStrikeToSourceRatio;
const SkScalar fStrikeToSourceRatio{1.0f};
};
class SkBulkGlyphMetrics {
@ -123,6 +132,7 @@ class SkBulkGlyphMetricsAndPaths {
public:
explicit SkBulkGlyphMetricsAndPaths(const SkStrikeSpec& spec);
explicit SkBulkGlyphMetricsAndPaths(sk_sp<SkStrike>&& strike);
~SkBulkGlyphMetricsAndPaths();
SkSpan<const SkGlyph*> glyphs(SkSpan<const SkGlyphID> glyphIDs);
const SkGlyph* glyph(SkGlyphID glyphID);
void findIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos,
@ -138,6 +148,7 @@ class SkBulkGlyphMetricsAndImages {
public:
explicit SkBulkGlyphMetricsAndImages(const SkStrikeSpec& spec);
explicit SkBulkGlyphMetricsAndImages(sk_sp<SkStrike>&& strike);
~SkBulkGlyphMetricsAndImages();
SkSpan<const SkGlyph*> glyphs(SkSpan<const SkPackedGlyphID> packedIDs);
const SkGlyph* glyph(SkPackedGlyphID packedID);
const SkDescriptor& descriptor() const;

View File

@ -56,10 +56,7 @@ DEF_TEST(SkScalerCacheMultiThread, Reporter) {
// Make our own executor so the --threads parameter doesn't mess things up.
auto executor = SkExecutor::MakeFIFOThreadPool(kThreadCount);
for (int tries = 0; tries < 100; tries++) {
SkScalerContextEffects effects;
std::unique_ptr<SkScalerContext> ctx{
typeface->createScalerContext(effects, &strikeSpec.descriptor())};
SkScalerCache scalerCache{strikeSpec.descriptor(), std::move(ctx)};
SkScalerCache scalerCache{strikeSpec.createScalerContext()};
auto perThread = [&](int threadIndex) {
barrier.waitForAll();