use digests internally for SkScalerCache
Switch to using digests internally for the bulk glyph processing calls. Put attributes in the digest that the bulk loops need for processing. Change-Id: I5852a5f8fa86759ec4b4a7b9937400f19abcf034 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317588 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
parent
b4aa639f23
commit
ad48610a01
@ -37,24 +37,28 @@ SkScalerCache::SkScalerCache(
|
||||
}
|
||||
|
||||
std::tuple<SkGlyph*, size_t> SkScalerCache::glyph(SkPackedGlyphID packedGlyphID) {
|
||||
auto [digest, size] = this->digest(packedGlyphID);
|
||||
return {fGlyphForIndex[digest.index()], size};
|
||||
}
|
||||
|
||||
std::tuple<SkGlyphDigest, size_t> SkScalerCache::digest(SkPackedGlyphID packedGlyphID) {
|
||||
SkGlyphDigest* digest = fDigestForPackedGlyphID.find(packedGlyphID);
|
||||
|
||||
if (digest != nullptr) {
|
||||
return {fGlyphForIndex[digest->index()], 0};
|
||||
return {*digest, 0};
|
||||
}
|
||||
|
||||
SkGlyph* glyph = fAlloc.make<SkGlyph>(packedGlyphID);
|
||||
fScalerContext->getMetrics(glyph);
|
||||
this->addGlyph(glyph);
|
||||
|
||||
return {glyph, sizeof(SkGlyph)};
|
||||
return {this->addGlyph(glyph), sizeof(SkGlyph)};
|
||||
}
|
||||
|
||||
void SkScalerCache::addGlyph(SkGlyph* glyph) {
|
||||
SkGlyphDigest SkScalerCache::addGlyph(SkGlyph* glyph) {
|
||||
size_t index = fGlyphForIndex.size();
|
||||
SkGlyphDigest digest = SkGlyphDigest{index};
|
||||
SkGlyphDigest digest = SkGlyphDigest{index, *glyph};
|
||||
fDigestForPackedGlyphID.set(glyph->getPackedID(), digest);
|
||||
fGlyphForIndex.push_back(glyph);
|
||||
return digest;
|
||||
}
|
||||
|
||||
std::tuple<const SkPath*, size_t> SkScalerCache::preparePath(SkGlyph* glyph) {
|
||||
@ -122,7 +126,7 @@ std::tuple<SkGlyph*, size_t> SkScalerCache::mergeGlyphAndImage(
|
||||
} else {
|
||||
SkGlyph* glyph = fAlloc.make<SkGlyph>(toID);
|
||||
size_t delta = glyph->setMetricsAndImage(&fAlloc, from);
|
||||
this->addGlyph(glyph);
|
||||
(void)this->addGlyph(glyph);
|
||||
return {glyph, sizeof(SkGlyph) + delta};
|
||||
}
|
||||
}
|
||||
@ -161,10 +165,10 @@ size_t SkScalerCache::commonFilterLoop(SkDrawableGlyphBuffer* drawables, Fn&& fn
|
||||
size_t total = 0;
|
||||
for (auto [i, packedID, pos] : SkMakeEnumerate(drawables->input())) {
|
||||
if (SkScalarsAreFinite(pos.x(), pos.y())) {
|
||||
auto [glyph, size] = this->glyph(packedID);
|
||||
auto [digest, size] = this->digest(packedID);
|
||||
total += size;
|
||||
if (!glyph->isEmpty()) {
|
||||
fn(i, glyph, pos);
|
||||
if (!digest.isEmpty()) {
|
||||
fn(i, digest, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -175,8 +179,9 @@ size_t SkScalerCache::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer* drawables
|
||||
SkAutoMutexExclusive lock{fMu};
|
||||
size_t imageDelta = 0;
|
||||
size_t delta = this->commonFilterLoop(drawables,
|
||||
[&](size_t i, SkGlyph* glyph, SkPoint pos) SK_REQUIRES(fMu) {
|
||||
[&](size_t i, SkGlyphDigest digest, SkPoint pos) SK_REQUIRES(fMu) {
|
||||
// If the glyph is too large, then no image is created.
|
||||
SkGlyph* glyph = fGlyphForIndex[digest.index()];
|
||||
auto [image, imageSize] = this->prepareImage(glyph);
|
||||
if (image != nullptr) {
|
||||
drawables->push_back(glyph, i);
|
||||
@ -192,9 +197,9 @@ size_t SkScalerCache::prepareForMaskDrawing(
|
||||
SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) {
|
||||
SkAutoMutexExclusive lock{fMu};
|
||||
size_t delta = this->commonFilterLoop(drawables,
|
||||
[&](size_t i, SkGlyph* glyph, SkPoint pos) {
|
||||
if (SkStrikeForGPU::CanDrawAsMask(*glyph)) {
|
||||
drawables->push_back(glyph, i);
|
||||
[&](size_t i, SkGlyphDigest digest, SkPoint pos) SK_REQUIRES(fMu) {
|
||||
if (digest.canDrawAsMask()) {
|
||||
drawables->push_back(fGlyphForIndex[digest.index()], i);
|
||||
} else {
|
||||
rejects->reject(i);
|
||||
}
|
||||
@ -207,9 +212,9 @@ size_t SkScalerCache::prepareForSDFTDrawing(
|
||||
SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) {
|
||||
SkAutoMutexExclusive lock{fMu};
|
||||
size_t delta = this->commonFilterLoop(drawables,
|
||||
[&](size_t i, SkGlyph* glyph, SkPoint pos) {
|
||||
if (SkStrikeForGPU::CanDrawAsSDFT(*glyph)) {
|
||||
drawables->push_back(glyph, i);
|
||||
[&](size_t i, SkGlyphDigest digest, SkPoint pos) SK_REQUIRES(fMu) {
|
||||
if (digest.canDrawAsSDFT()) {
|
||||
drawables->push_back(fGlyphForIndex[digest.index()], i);
|
||||
} else {
|
||||
rejects->reject(i);
|
||||
}
|
||||
@ -223,8 +228,9 @@ size_t SkScalerCache::prepareForPathDrawing(
|
||||
SkAutoMutexExclusive lock{fMu};
|
||||
size_t pathDelta = 0;
|
||||
size_t delta = this->commonFilterLoop(drawables,
|
||||
[&](size_t i, SkGlyph* glyph, SkPoint pos) SK_REQUIRES(fMu) {
|
||||
if (!glyph->isColor()) {
|
||||
[&](size_t i, SkGlyphDigest digest, SkPoint pos) SK_REQUIRES(fMu) {
|
||||
SkGlyph* glyph = fGlyphForIndex[digest.index()];
|
||||
if (!digest.isColor()) {
|
||||
auto [path, pathSize] = this->preparePath(glyph);
|
||||
pathDelta += pathSize;
|
||||
if (path != nullptr) {
|
||||
|
@ -25,13 +25,27 @@ class SkScalerContext;
|
||||
// index() is the index into fGlyphForIndex.
|
||||
class SkGlyphDigest {
|
||||
public:
|
||||
SkGlyphDigest() : fIndex{0} {}
|
||||
SkGlyphDigest(size_t i) : fIndex{SkTo<uint32_t>(i)} {}
|
||||
int index() const {return fIndex;}
|
||||
// Default ctor is only needed for the hash table.
|
||||
SkGlyphDigest() = default;
|
||||
SkGlyphDigest(size_t i, const SkGlyph& glyph)
|
||||
: fIndex{SkTo<uint32_t>(i)}
|
||||
, fIsEmpty(glyph.isEmpty())
|
||||
, fIsColor(glyph.isColor())
|
||||
, fCanDrawAsMask{SkStrikeForGPU::CanDrawAsMask(glyph)}
|
||||
, fCanDrawAsSDFT{SkStrikeForGPU::CanDrawAsSDFT(glyph)} {}
|
||||
int index() const {return fIndex; }
|
||||
bool isEmpty() const {return fIsEmpty; }
|
||||
bool isColor() const {return fIsColor; }
|
||||
bool canDrawAsMask() const {return fCanDrawAsMask;}
|
||||
bool canDrawAsSDFT() const {return fCanDrawAsSDFT;}
|
||||
|
||||
private:
|
||||
static_assert(SkPackedGlyphID::kEndData == 20);
|
||||
uint32_t fIndex : SkPackedGlyphID::kEndData;
|
||||
uint32_t fIsEmpty : 1;
|
||||
uint32_t fIsColor : 1;
|
||||
uint32_t fCanDrawAsMask : 1;
|
||||
uint32_t fCanDrawAsSDFT : 1;
|
||||
};
|
||||
|
||||
// This class represents a strike: a specific combination of typeface, size, matrix, etc., and
|
||||
@ -105,8 +119,10 @@ private:
|
||||
// advances using a scaler.
|
||||
std::tuple<SkGlyph*, size_t> glyph(SkPackedGlyphID) SK_REQUIRES(fMu);
|
||||
|
||||
std::tuple<SkGlyphDigest, size_t> digest(SkPackedGlyphID) SK_REQUIRES(fMu);
|
||||
|
||||
// Generate the glyph digest information and update structures to add the glyph.
|
||||
void addGlyph(SkGlyph* glyph) SK_REQUIRES(fMu);
|
||||
SkGlyphDigest addGlyph(SkGlyph* glyph) SK_REQUIRES(fMu);
|
||||
|
||||
std::tuple<const void*, size_t> prepareImage(SkGlyph* glyph) SK_REQUIRES(fMu);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user