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 "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());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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&);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user