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:
parent
edce0aa152
commit
5a3fdeecdc
@ -16,34 +16,52 @@
|
||||
#include "SkFixed.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 {
|
||||
enum MaskStyle {
|
||||
kCoverage_MaskStyle,
|
||||
kDistance_MaskStyle
|
||||
};
|
||||
|
||||
typedef uint32_t PackedID;
|
||||
|
||||
static GrIRect16 SkIRectToGrIRect16(const SkIRect& rect) {
|
||||
return GrIRect16::MakeXYWH(SkTo<int16_t>(rect.x()),
|
||||
SkTo<int16_t>(rect.y()),
|
||||
SkTo<uint16_t>(rect.width()),
|
||||
SkTo<uint16_t>(rect.height()));
|
||||
static GrMaskFormat FormatFromSkGlyph(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;
|
||||
}
|
||||
}
|
||||
|
||||
GrGlyph(GrGlyph::PackedID packed, const SkIRect& bounds, GrMaskFormat format, MaskStyle style)
|
||||
: fPackedID{packed}
|
||||
, fMaskFormat{format}
|
||||
, fMaskStyle{style}
|
||||
, fBounds{SkIRectToGrIRect16(bounds)} {}
|
||||
static GrIRect16 BoundsFromSkGlyph(const SkGlyph& glyph) {
|
||||
return GrIRect16::MakeXYWH(glyph.fLeft,
|
||||
glyph.fTop,
|
||||
glyph.fWidth,
|
||||
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 MaskStyle fMaskStyle;
|
||||
const GrIRect16 fBounds;
|
||||
@ -52,55 +70,16 @@ struct GrGlyph {
|
||||
|
||||
int width() const { return fBounds.width(); }
|
||||
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); }
|
||||
MaskStyle maskStyle() const { return fMaskStyle; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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) {
|
||||
// GetKey and Hash for the the hash table.
|
||||
static const SkPackedGlyphID& GetKey(const GrGlyph& glyph) {
|
||||
return glyph.fPackedID;
|
||||
}
|
||||
|
||||
static uint32_t Hash(GrGlyph::PackedID key) {
|
||||
return SkChecksum::Mix(key);
|
||||
static uint32_t Hash(SkPackedGlyphID key) {
|
||||
return SkChecksum::Mix(key.hash());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
// A8, RGB565, or RGBA8888.
|
||||
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
|
||||
// expected format is 8888 (will happen on macOS with Metal since that combination does not
|
||||
// support 565).
|
||||
if (kA565_GrMaskFormat == get_packed_glyph_mask_format(glyph) &&
|
||||
if (kA565_GrMaskFormat == GrGlyph::FormatFromSkGlyph(glyph) &&
|
||||
kARGB_GrMaskFormat == expectedMaskFormat) {
|
||||
const int a565Bpp = GrMaskFormatBytesPerPixel(kA565_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
|
||||
// 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.
|
||||
if (get_packed_glyph_mask_format(glyph) != expectedMaskFormat) {
|
||||
if (GrGlyph::FormatFromSkGlyph(glyph) != expectedMaskFormat) {
|
||||
const int bpp = GrMaskFormatBytesPerPixel(expectedMaskFormat);
|
||||
for (int y = 0; y < height; y++) {
|
||||
sk_bzero(dst, width * bpp);
|
||||
@ -193,23 +173,13 @@ GrTextStrike::GrTextStrike(const SkDescriptor& key)
|
||||
: fFontScalerKey(key) {}
|
||||
|
||||
GrGlyph* GrTextStrike::generateGlyph(const SkGlyph& skGlyph) {
|
||||
SkIRect bounds;
|
||||
|
||||
bounds.setXYWH(skGlyph.fLeft, skGlyph.fTop, skGlyph.fWidth, skGlyph.fHeight);
|
||||
|
||||
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;
|
||||
GrGlyph* grGlyph = fAlloc.make<GrGlyph>(skGlyph);
|
||||
fCache.add(grGlyph);
|
||||
return grGlyph;
|
||||
}
|
||||
|
||||
void GrTextStrike::removeID(GrDrawOpAtlas::AtlasID id) {
|
||||
SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache);
|
||||
SkTDynamicHash<GrGlyph, SkPackedGlyphID>::Iter iter(&fCache);
|
||||
while (!iter.done()) {
|
||||
if (id == (*iter).fID) {
|
||||
(*iter).fID = GrDrawOpAtlas::kInvalidAtlasID;
|
||||
|
@ -31,8 +31,7 @@ public:
|
||||
GrTextStrike(const SkDescriptor& fontScalerKey);
|
||||
|
||||
GrGlyph* getGlyph(const SkGlyph& skGlyph) {
|
||||
GrGlyph::PackedID packed = GrGlyph::FromSkGlyph(skGlyph);
|
||||
GrGlyph* glyph = fCache.find(packed);
|
||||
GrGlyph* glyph = fCache.find(skGlyph.getPackedID());
|
||||
if (!glyph) {
|
||||
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
|
||||
// draw a clear square.
|
||||
// skbug:4143 crbug:510931
|
||||
GrGlyph* getGlyph(GrGlyph::PackedID packed,
|
||||
GrGlyph* getGlyph(SkPackedGlyphID packed,
|
||||
SkGlyphCache* cache) {
|
||||
GrGlyph* glyph = fCache.find(packed);
|
||||
if (!glyph) {
|
||||
@ -82,17 +81,15 @@ public:
|
||||
static uint32_t Hash(const SkDescriptor& desc) { return desc.getChecksum(); }
|
||||
|
||||
private:
|
||||
SkTDynamicHash<GrGlyph, GrGlyph::PackedID> fCache;
|
||||
SkTDynamicHash<GrGlyph, SkPackedGlyphID> fCache;
|
||||
SkAutoDescriptor fFontScalerKey;
|
||||
SkArenaAlloc fAlloc{512};
|
||||
|
||||
int fAtlasedGlyphs{0};
|
||||
bool fIsAbandoned{false};
|
||||
|
||||
static const SkGlyph& GrToSkGlyph(SkGlyphCache* cache, GrGlyph::PackedID id) {
|
||||
return cache->getGlyphIDMetrics(GrGlyph::UnpackID(id),
|
||||
GrGlyph::UnpackFixedX(id),
|
||||
GrGlyph::UnpackFixedY(id));
|
||||
static const SkGlyph& GrToSkGlyph(SkGlyphCache* cache, SkPackedGlyphID id) {
|
||||
return cache->getGlyphIDMetrics(id.code(), id.getSubXFixed(), id.getSubYFixed());
|
||||
}
|
||||
|
||||
GrGlyph* generateGlyph(const SkGlyph&);
|
||||
|
@ -269,7 +269,7 @@ bool GrTextBlob::VertexRegenerator::doRegen(GrTextBlob::VertexRegenerator::Resul
|
||||
if (regenGlyphs) {
|
||||
// Get the id from the old glyph, and use the new strike to lookup
|
||||
// the glyph.
|
||||
GrGlyph::PackedID id = fBlob->fGlyphs[glyphOffset]->fPackedID;
|
||||
SkPackedGlyphID id = fBlob->fGlyphs[glyphOffset]->fPackedID;
|
||||
fBlob->fGlyphs[glyphOffset] = strike->getGlyph(id, fLazyCache->get());
|
||||
SkASSERT(id == fBlob->fGlyphs[glyphOffset]->fPackedID);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user