/* * Copyright 2018 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkRemoteGlyphCacheImpl_DEFINED #define SkRemoteGlyphCacheImpl_DEFINED #include "SkArenaAlloc.h" #include "SkDescriptor.h" #include "SkGlyphRun.h" #include "SkGlyphRunPainter.h" #include "SkRemoteGlyphCache.h" class SkStrikeServer::SkGlyphCacheState : public SkStrikeInterface { public: // N.B. SkGlyphCacheState is not valid until ensureScalerContext is called. SkGlyphCacheState(const SkDescriptor& keyDescriptor, const SkDescriptor& deviceDescriptor, std::unique_ptr context, SkDiscardableHandleId discardableHandleId); ~SkGlyphCacheState() override; void addGlyph(SkPackedGlyphID, bool pathOnly); void writePendingGlyphs(Serializer* serializer); SkDiscardableHandleId discardableHandleId() const { return fDiscardableHandleId; } const SkDescriptor& getDeviceDescriptor() { return *fDeviceDescriptor.getDesc(); } bool isSubpixel() const { return fIsSubpixel; } SkAxisAlignment axisAlignmentForHText() const { return fAxisAlignmentForHText; } const SkDescriptor& getKeyDescriptor() { return *fKeyDescriptor.getDesc(); } const SkGlyph& findGlyph(SkPackedGlyphID); void setFontAndEffects(const SkFont& font, SkScalerContextEffects effects); SkVector rounding() const override; const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) override; bool hasImage(const SkGlyph& glyph) override; bool hasPath(const SkGlyph& glyph) override; private: bool hasPendingGlyphs() const { return !fPendingGlyphImages.empty() || !fPendingGlyphPaths.empty(); } void writeGlyphPath(const SkPackedGlyphID& glyphID, Serializer* serializer) const; void ensureScalerContext(); void resetScalerContext(); // The set of glyphs cached on the remote client. SkTHashSet fCachedGlyphImages; SkTHashSet fCachedGlyphPaths; // The set of glyphs which has not yet been serialized and sent to the // remote client. std::vector fPendingGlyphImages; std::vector fPendingGlyphPaths; // The device descriptor is used to create the scaler context. The glyphs to have the // correct device rendering. The key descriptor is used for communication. The GPU side will // create descriptors with out the device filtering, thus matching the key descriptor. const SkAutoDescriptor fKeyDescriptor; const SkAutoDescriptor fDeviceDescriptor; const SkDiscardableHandleId fDiscardableHandleId; // Values saved from the initial context. const bool fIsSubpixel; const SkAxisAlignment fAxisAlignmentForHText; // The context built using fDeviceDescriptor std::unique_ptr fContext; // These fields are set everytime getOrCreateCache. This allows the code to maintain the // fContext as lazy as possible. const SkFont* fFont{nullptr}; SkScalerContextEffects fEffects; class GlyphMapHashTraits { public: static SkPackedGlyphID GetKey(const SkGlyph* glyph) { return glyph->getPackedID(); } static uint32_t Hash(SkPackedGlyphID glyphId) { return glyphId.hash(); } }; // FallbackTextHelper cases require glyph metrics when analyzing a glyph run, in which case // we cache them here. SkTHashTable fGlyphMap; SkArenaAlloc fAlloc{256}; }; class SkTextBlobCacheDiffCanvas::TrackLayerDevice : public SkNoPixelsDevice { public: TrackLayerDevice(const SkIRect& bounds, const SkSurfaceProps& props, SkStrikeServer* server, const SkTextBlobCacheDiffCanvas::Settings& settings); SkBaseDevice* onCreateDevice(const CreateInfo& cinfo, const SkPaint*) override; protected: void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override; private: void processGlyphRun( const SkPoint& origin, const SkGlyphRun& glyphRun, const SkPaint& runPaint); void processGlyphRunForMask( const SkGlyphRun& glyphRun, const SkMatrix& runMatrix, SkPoint origin, const SkPaint& paint); void processGlyphRunForPaths( const SkGlyphRun& glyphRun, const SkMatrix& runMatrix, SkPoint origin, const SkPaint& paint); #if SK_SUPPORT_GPU bool maybeProcessGlyphRunForDFT( const SkGlyphRun& glyphRun, const SkMatrix& runMatrix, SkPoint origin, const SkPaint& paint); #endif SkStrikeServer* const fStrikeServer; const SkTextBlobCacheDiffCanvas::Settings fSettings; SkGlyphRunListPainter fPainter; }; #endif // SkRemoteGlyphCacheImpl_DEFINED