Convert GrGlyph::PackedID to SkPackedGlyphID

This changes ripples through many areas of the code like the
hash map.

This will simplify making SkGlyphCache and GrTextStrike work
together in future CLs.

* Convert ctor to take an SkGlyph
* Remove many unused functions

Change-Id: I43ea414f03dfbb683ba7b46bf48a93c7a78895c6
Reviewed-on: https://skia-review.googlesource.com/c/179641
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Herb Derby 2018-12-20 14:47:03 -05:00 committed by Skia Commit-Bot
parent edce0aa152
commit 5a3fdeecdc
4 changed files with 53 additions and 107 deletions

View File

@ -16,34 +16,52 @@
#include "SkFixed.h" #include "SkFixed.h"
#include "SkPath.h" #include "SkPath.h"
/* Need this to be quad-state:
- complete w/ image
- just metrics
- failed to get image, but has metrics
- failed to get metrics
*/
struct GrGlyph { struct GrGlyph {
enum MaskStyle { enum MaskStyle {
kCoverage_MaskStyle, kCoverage_MaskStyle,
kDistance_MaskStyle kDistance_MaskStyle
}; };
typedef uint32_t PackedID; static GrMaskFormat FormatFromSkGlyph(const SkGlyph& glyph) {
SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
static GrIRect16 SkIRectToGrIRect16(const SkIRect& rect) { switch (format) {
return GrIRect16::MakeXYWH(SkTo<int16_t>(rect.x()), case SkMask::kBW_Format:
SkTo<int16_t>(rect.y()), case SkMask::kSDF_Format:
SkTo<uint16_t>(rect.width()), // fall through to kA8 -- we store BW and SDF glyphs in our 8-bit cache
SkTo<uint16_t>(rect.height())); case SkMask::kA8_Format:
return kA8_GrMaskFormat;
case SkMask::k3D_Format:
return kA8_GrMaskFormat; // ignore the mul and add planes, just use the mask
case SkMask::kLCD16_Format:
return kA565_GrMaskFormat;
case SkMask::kARGB32_Format:
return kARGB_GrMaskFormat;
default:
SkDEBUGFAIL("unsupported SkMask::Format");
return kA8_GrMaskFormat;
}
} }
GrGlyph(GrGlyph::PackedID packed, const SkIRect& bounds, GrMaskFormat format, MaskStyle style) static GrIRect16 BoundsFromSkGlyph(const SkGlyph& glyph) {
: fPackedID{packed} return GrIRect16::MakeXYWH(glyph.fLeft,
, fMaskFormat{format} glyph.fTop,
, fMaskStyle{style} glyph.fWidth,
, fBounds{SkIRectToGrIRect16(bounds)} {} glyph.fHeight);
}
const PackedID fPackedID; static MaskStyle MaskStyleFromSkGlyph(const SkGlyph& skGlyph) {
return (SkMask::Format)skGlyph.fMaskFormat == SkMask::kSDF_Format
? GrGlyph::MaskStyle::kDistance_MaskStyle
: GrGlyph::MaskStyle::kCoverage_MaskStyle;
}
GrGlyph(const SkGlyph& skGlyph)
: fPackedID{skGlyph.getPackedID()}
, fMaskFormat{FormatFromSkGlyph(skGlyph)}
, fMaskStyle{MaskStyleFromSkGlyph(skGlyph)}
, fBounds{BoundsFromSkGlyph(skGlyph)} {}
const SkPackedGlyphID fPackedID;
const GrMaskFormat fMaskFormat; const GrMaskFormat fMaskFormat;
const MaskStyle fMaskStyle; const MaskStyle fMaskStyle;
const GrIRect16 fBounds; const GrIRect16 fBounds;
@ -52,55 +70,16 @@ struct GrGlyph {
int width() const { return fBounds.width(); } int width() const { return fBounds.width(); }
int height() const { return fBounds.height(); } int height() const { return fBounds.height(); }
bool isEmpty() const { return fBounds.isEmpty(); }
uint16_t glyphID() const { return UnpackID(fPackedID); }
uint32_t pageIndex() const { return GrDrawOpAtlas::GetPageIndexFromID(fID); } uint32_t pageIndex() const { return GrDrawOpAtlas::GetPageIndexFromID(fID); }
MaskStyle maskStyle() const { return fMaskStyle; } MaskStyle maskStyle() const { return fMaskStyle; }
/////////////////////////////////////////////////////////////////////////// // GetKey and Hash for the the hash table.
static const SkPackedGlyphID& GetKey(const GrGlyph& glyph) {
static unsigned ExtractSubPixelBitsFromFixed(SkFixed pos) {
// two most significant fraction bits from fixed-point
return (pos >> 14) & 3;
}
static PackedID FromSkGlyph(const SkGlyph& skGlyph) {
GrGlyph::MaskStyle maskStyle = (SkMask::Format)skGlyph.fMaskFormat == SkMask::kSDF_Format
? GrGlyph::MaskStyle::kDistance_MaskStyle
: GrGlyph::MaskStyle::kCoverage_MaskStyle;
SkPackedGlyphID skPackedID = skGlyph.getPackedID();
GrGlyph::PackedID packedID = GrGlyph::Pack(skPackedID.code(),
skPackedID.getSubXFixed(),
skPackedID.getSubYFixed(),
maskStyle);
return packedID;
}
static PackedID Pack(uint16_t glyphID, SkFixed x, SkFixed y, MaskStyle ms) {
x = ExtractSubPixelBitsFromFixed(x);
y = ExtractSubPixelBitsFromFixed(y);
int dfFlag = (ms == kDistance_MaskStyle) ? 0x1 : 0x0;
return (dfFlag << 20) | (x << 18) | (y << 16) | glyphID;
}
static SkFixed UnpackFixedX(PackedID packed) {
return ((packed >> 18) & 3) << 14;
}
static SkFixed UnpackFixedY(PackedID packed) {
return ((packed >> 16) & 3) << 14;
}
static uint16_t UnpackID(PackedID packed) {
return (uint16_t)packed;
}
static const GrGlyph::PackedID& GetKey(const GrGlyph& glyph) {
return glyph.fPackedID; return glyph.fPackedID;
} }
static uint32_t Hash(GrGlyph::PackedID key) { static uint32_t Hash(SkPackedGlyphID key) {
return SkChecksum::Mix(key); return SkChecksum::Mix(key.hash());
} }
}; };

View File

@ -56,26 +56,6 @@ void GrGlyphCache::HandleEviction(GrDrawOpAtlas::AtlasID id, void* ptr) {
} }
} }
static GrMaskFormat get_packed_glyph_mask_format(const SkGlyph& glyph) {
SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
switch (format) {
case SkMask::kBW_Format:
case SkMask::kSDF_Format:
// fall through to kA8 -- we store BW and SDF glyphs in our 8-bit cache
case SkMask::kA8_Format:
return kA8_GrMaskFormat;
case SkMask::k3D_Format:
return kA8_GrMaskFormat; // ignore the mul and add planes, just use the mask
case SkMask::kLCD16_Format:
return kA565_GrMaskFormat;
case SkMask::kARGB32_Format:
return kARGB_GrMaskFormat;
default:
SkDEBUGFAIL("unsupported SkMask::Format");
return kA8_GrMaskFormat;
}
}
// expands each bit in a bitmask to 0 or ~0 of type INT_TYPE. Used to expand a BW glyph mask to // expands each bit in a bitmask to 0 or ~0 of type INT_TYPE. Used to expand a BW glyph mask to
// A8, RGB565, or RGBA8888. // A8, RGB565, or RGBA8888.
template <typename INT_TYPE> template <typename INT_TYPE>
@ -113,7 +93,7 @@ static bool get_packed_glyph_image(SkGlyphCache* cache, const SkGlyph& glyph, in
// Convert if the glyph uses a 565 mask format since it is using LCD text rendering but the // Convert if the glyph uses a 565 mask format since it is using LCD text rendering but the
// expected format is 8888 (will happen on macOS with Metal since that combination does not // expected format is 8888 (will happen on macOS with Metal since that combination does not
// support 565). // support 565).
if (kA565_GrMaskFormat == get_packed_glyph_mask_format(glyph) && if (kA565_GrMaskFormat == GrGlyph::FormatFromSkGlyph(glyph) &&
kARGB_GrMaskFormat == expectedMaskFormat) { kARGB_GrMaskFormat == expectedMaskFormat) {
const int a565Bpp = GrMaskFormatBytesPerPixel(kA565_GrMaskFormat); const int a565Bpp = GrMaskFormatBytesPerPixel(kA565_GrMaskFormat);
const int argbBpp = GrMaskFormatBytesPerPixel(kARGB_GrMaskFormat); const int argbBpp = GrMaskFormatBytesPerPixel(kARGB_GrMaskFormat);
@ -136,7 +116,7 @@ static bool get_packed_glyph_image(SkGlyphCache* cache, const SkGlyph& glyph, in
// crbug:510931 // crbug:510931
// Retrieving the image from the cache can actually change the mask format. This case is very // Retrieving the image from the cache can actually change the mask format. This case is very
// uncommon so for now we just draw a clear box for these glyphs. // uncommon so for now we just draw a clear box for these glyphs.
if (get_packed_glyph_mask_format(glyph) != expectedMaskFormat) { if (GrGlyph::FormatFromSkGlyph(glyph) != expectedMaskFormat) {
const int bpp = GrMaskFormatBytesPerPixel(expectedMaskFormat); const int bpp = GrMaskFormatBytesPerPixel(expectedMaskFormat);
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
sk_bzero(dst, width * bpp); sk_bzero(dst, width * bpp);
@ -193,23 +173,13 @@ GrTextStrike::GrTextStrike(const SkDescriptor& key)
: fFontScalerKey(key) {} : fFontScalerKey(key) {}
GrGlyph* GrTextStrike::generateGlyph(const SkGlyph& skGlyph) { GrGlyph* GrTextStrike::generateGlyph(const SkGlyph& skGlyph) {
SkIRect bounds; GrGlyph* grGlyph = fAlloc.make<GrGlyph>(skGlyph);
fCache.add(grGlyph);
bounds.setXYWH(skGlyph.fLeft, skGlyph.fTop, skGlyph.fWidth, skGlyph.fHeight); return grGlyph;
GrMaskFormat format = get_packed_glyph_mask_format(skGlyph);
GrGlyph::MaskStyle maskStyle = (SkMask::Format)skGlyph.fMaskFormat == SkMask::kSDF_Format
? GrGlyph::MaskStyle::kDistance_MaskStyle
: GrGlyph::MaskStyle::kCoverage_MaskStyle;
GrGlyph* glyph = fAlloc.make<GrGlyph>(
GrGlyph::FromSkGlyph(skGlyph), bounds, format, maskStyle);
fCache.add(glyph);
return glyph;
} }
void GrTextStrike::removeID(GrDrawOpAtlas::AtlasID id) { void GrTextStrike::removeID(GrDrawOpAtlas::AtlasID id) {
SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache); SkTDynamicHash<GrGlyph, SkPackedGlyphID>::Iter iter(&fCache);
while (!iter.done()) { while (!iter.done()) {
if (id == (*iter).fID) { if (id == (*iter).fID) {
(*iter).fID = GrDrawOpAtlas::kInvalidAtlasID; (*iter).fID = GrDrawOpAtlas::kInvalidAtlasID;

View File

@ -31,8 +31,7 @@ public:
GrTextStrike(const SkDescriptor& fontScalerKey); GrTextStrike(const SkDescriptor& fontScalerKey);
GrGlyph* getGlyph(const SkGlyph& skGlyph) { GrGlyph* getGlyph(const SkGlyph& skGlyph) {
GrGlyph::PackedID packed = GrGlyph::FromSkGlyph(skGlyph); GrGlyph* glyph = fCache.find(skGlyph.getPackedID());
GrGlyph* glyph = fCache.find(packed);
if (!glyph) { if (!glyph) {
glyph = this->generateGlyph(skGlyph); glyph = this->generateGlyph(skGlyph);
} }
@ -43,7 +42,7 @@ public:
// that the maskformat of the glyph differs from what we expect. In these cases we will just // that the maskformat of the glyph differs from what we expect. In these cases we will just
// draw a clear square. // draw a clear square.
// skbug:4143 crbug:510931 // skbug:4143 crbug:510931
GrGlyph* getGlyph(GrGlyph::PackedID packed, GrGlyph* getGlyph(SkPackedGlyphID packed,
SkGlyphCache* cache) { SkGlyphCache* cache) {
GrGlyph* glyph = fCache.find(packed); GrGlyph* glyph = fCache.find(packed);
if (!glyph) { if (!glyph) {
@ -82,17 +81,15 @@ public:
static uint32_t Hash(const SkDescriptor& desc) { return desc.getChecksum(); } static uint32_t Hash(const SkDescriptor& desc) { return desc.getChecksum(); }
private: private:
SkTDynamicHash<GrGlyph, GrGlyph::PackedID> fCache; SkTDynamicHash<GrGlyph, SkPackedGlyphID> fCache;
SkAutoDescriptor fFontScalerKey; SkAutoDescriptor fFontScalerKey;
SkArenaAlloc fAlloc{512}; SkArenaAlloc fAlloc{512};
int fAtlasedGlyphs{0}; int fAtlasedGlyphs{0};
bool fIsAbandoned{false}; bool fIsAbandoned{false};
static const SkGlyph& GrToSkGlyph(SkGlyphCache* cache, GrGlyph::PackedID id) { static const SkGlyph& GrToSkGlyph(SkGlyphCache* cache, SkPackedGlyphID id) {
return cache->getGlyphIDMetrics(GrGlyph::UnpackID(id), return cache->getGlyphIDMetrics(id.code(), id.getSubXFixed(), id.getSubYFixed());
GrGlyph::UnpackFixedX(id),
GrGlyph::UnpackFixedY(id));
} }
GrGlyph* generateGlyph(const SkGlyph&); GrGlyph* generateGlyph(const SkGlyph&);

View File

@ -269,7 +269,7 @@ bool GrTextBlob::VertexRegenerator::doRegen(GrTextBlob::VertexRegenerator::Resul
if (regenGlyphs) { if (regenGlyphs) {
// Get the id from the old glyph, and use the new strike to lookup // Get the id from the old glyph, and use the new strike to lookup
// the glyph. // the glyph.
GrGlyph::PackedID id = fBlob->fGlyphs[glyphOffset]->fPackedID; SkPackedGlyphID id = fBlob->fGlyphs[glyphOffset]->fPackedID;
fBlob->fGlyphs[glyphOffset] = strike->getGlyph(id, fLazyCache->get()); fBlob->fGlyphs[glyphOffset] = strike->getGlyph(id, fLazyCache->get());
SkASSERT(id == fBlob->fGlyphs[glyphOffset]->fPackedID); SkASSERT(id == fBlob->fGlyphs[glyphOffset]->fPackedID);
} }