diff --git a/src/gpu/GrGlyph.h b/src/gpu/GrGlyph.h index ed0090b1ec..94a3f2f04b 100644 --- a/src/gpu/GrGlyph.h +++ b/src/gpu/GrGlyph.h @@ -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(rect.x()), - SkTo(rect.y()), - SkTo(rect.width()), - SkTo(rect.height())); + static GrMaskFormat FormatFromSkGlyph(const SkGlyph& glyph) { + SkMask::Format format = static_cast(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()); } }; diff --git a/src/gpu/text/GrGlyphCache.cpp b/src/gpu/text/GrGlyphCache.cpp index f9a8540a39..7af769ffa6 100644 --- a/src/gpu/text/GrGlyphCache.cpp +++ b/src/gpu/text/GrGlyphCache.cpp @@ -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(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 @@ -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::FromSkGlyph(skGlyph), bounds, format, maskStyle); - fCache.add(glyph); - return glyph; + GrGlyph* grGlyph = fAlloc.make(skGlyph); + fCache.add(grGlyph); + return grGlyph; } void GrTextStrike::removeID(GrDrawOpAtlas::AtlasID id) { - SkTDynamicHash::Iter iter(&fCache); + SkTDynamicHash::Iter iter(&fCache); while (!iter.done()) { if (id == (*iter).fID) { (*iter).fID = GrDrawOpAtlas::kInvalidAtlasID; diff --git a/src/gpu/text/GrGlyphCache.h b/src/gpu/text/GrGlyphCache.h index 835d4846be..585570c68c 100644 --- a/src/gpu/text/GrGlyphCache.h +++ b/src/gpu/text/GrGlyphCache.h @@ -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 fCache; + SkTDynamicHash 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&); diff --git a/src/gpu/text/GrTextBlobVertexRegenerator.cpp b/src/gpu/text/GrTextBlobVertexRegenerator.cpp index 6b6beb357a..786e3187e2 100644 --- a/src/gpu/text/GrTextBlobVertexRegenerator.cpp +++ b/src/gpu/text/GrTextBlobVertexRegenerator.cpp @@ -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); }