1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2021 Google LLC. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkChromeRemoteGlyphCache_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define SkChromeRemoteGlyphCache_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAPI.h" 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef> 16*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 17*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 18*c8dee2aaSAndroid Build Coastguard Worker #include <vector> 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Worker class SkAutoDescriptor; 21*c8dee2aaSAndroid Build Coastguard Worker class SkCanvas; 22*c8dee2aaSAndroid Build Coastguard Worker class SkColorSpace; 23*c8dee2aaSAndroid Build Coastguard Worker class SkStrikeCache; 24*c8dee2aaSAndroid Build Coastguard Worker class SkStrikeClientImpl; 25*c8dee2aaSAndroid Build Coastguard Worker class SkStrikeServerImpl; 26*c8dee2aaSAndroid Build Coastguard Worker class SkSurfaceProps; 27*c8dee2aaSAndroid Build Coastguard Worker namespace sktext::gpu { class Slug; } 28*c8dee2aaSAndroid Build Coastguard Worker 29*c8dee2aaSAndroid Build Coastguard Worker using SkDiscardableHandleId = uint32_t; 30*c8dee2aaSAndroid Build Coastguard Worker // This class is not thread-safe. 31*c8dee2aaSAndroid Build Coastguard Worker class SkStrikeServer { 32*c8dee2aaSAndroid Build Coastguard Worker public: 33*c8dee2aaSAndroid Build Coastguard Worker // An interface used by the server to create handles for pinning SkStrike 34*c8dee2aaSAndroid Build Coastguard Worker // entries on the remote client. 35*c8dee2aaSAndroid Build Coastguard Worker class DiscardableHandleManager { 36*c8dee2aaSAndroid Build Coastguard Worker public: 37*c8dee2aaSAndroid Build Coastguard Worker SK_SPI virtual ~DiscardableHandleManager() = default; 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker // Creates a new *locked* handle and returns a unique ID that can be used to identify 40*c8dee2aaSAndroid Build Coastguard Worker // it on the remote client. 41*c8dee2aaSAndroid Build Coastguard Worker SK_SPI virtual SkDiscardableHandleId createHandle() = 0; 42*c8dee2aaSAndroid Build Coastguard Worker 43*c8dee2aaSAndroid Build Coastguard Worker // Returns true if the handle could be successfully locked. The server can 44*c8dee2aaSAndroid Build Coastguard Worker // assume it will remain locked until the next set of serialized entries is 45*c8dee2aaSAndroid Build Coastguard Worker // pulled from the SkStrikeServer. 46*c8dee2aaSAndroid Build Coastguard Worker // If returns false, the cache entry mapped to the handle has been deleted 47*c8dee2aaSAndroid Build Coastguard Worker // on the client. Any subsequent attempts to lock the same handle are not 48*c8dee2aaSAndroid Build Coastguard Worker // allowed. 49*c8dee2aaSAndroid Build Coastguard Worker SK_SPI virtual bool lockHandle(SkDiscardableHandleId) = 0; 50*c8dee2aaSAndroid Build Coastguard Worker 51*c8dee2aaSAndroid Build Coastguard Worker // Returns true if a handle has been deleted on the remote client. It is 52*c8dee2aaSAndroid Build Coastguard Worker // invalid to use a handle id again with this manager once this returns true. 53*c8dee2aaSAndroid Build Coastguard Worker SK_SPI virtual bool isHandleDeleted(SkDiscardableHandleId) = 0; 54*c8dee2aaSAndroid Build Coastguard Worker }; 55*c8dee2aaSAndroid Build Coastguard Worker 56*c8dee2aaSAndroid Build Coastguard Worker SK_SPI explicit SkStrikeServer(DiscardableHandleManager* discardableHandleManager); 57*c8dee2aaSAndroid Build Coastguard Worker SK_SPI ~SkStrikeServer(); 58*c8dee2aaSAndroid Build Coastguard Worker 59*c8dee2aaSAndroid Build Coastguard Worker // Create an analysis SkCanvas used to populate the SkStrikeServer with ops 60*c8dee2aaSAndroid Build Coastguard Worker // which will be serialized and rendered using the SkStrikeClient. 61*c8dee2aaSAndroid Build Coastguard Worker SK_API std::unique_ptr<SkCanvas> makeAnalysisCanvas(int width, int height, 62*c8dee2aaSAndroid Build Coastguard Worker const SkSurfaceProps& props, 63*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace, 64*c8dee2aaSAndroid Build Coastguard Worker bool DFTSupport, 65*c8dee2aaSAndroid Build Coastguard Worker bool DFTPerspSupport = true); 66*c8dee2aaSAndroid Build Coastguard Worker 67*c8dee2aaSAndroid Build Coastguard Worker // Serializes the strike data captured using a canvas returned by ::makeAnalysisCanvas. Any 68*c8dee2aaSAndroid Build Coastguard Worker // handles locked using the DiscardableHandleManager will be assumed to be 69*c8dee2aaSAndroid Build Coastguard Worker // unlocked after this call. 70*c8dee2aaSAndroid Build Coastguard Worker SK_SPI void writeStrikeData(std::vector<uint8_t>* memory); 71*c8dee2aaSAndroid Build Coastguard Worker 72*c8dee2aaSAndroid Build Coastguard Worker // Testing helpers 73*c8dee2aaSAndroid Build Coastguard Worker void setMaxEntriesInDescriptorMapForTesting(size_t count); 74*c8dee2aaSAndroid Build Coastguard Worker size_t remoteStrikeMapSizeForTesting() const; 75*c8dee2aaSAndroid Build Coastguard Worker 76*c8dee2aaSAndroid Build Coastguard Worker private: 77*c8dee2aaSAndroid Build Coastguard Worker SkStrikeServerImpl* impl(); 78*c8dee2aaSAndroid Build Coastguard Worker 79*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkStrikeServerImpl> fImpl; 80*c8dee2aaSAndroid Build Coastguard Worker }; 81*c8dee2aaSAndroid Build Coastguard Worker 82*c8dee2aaSAndroid Build Coastguard Worker class SkStrikeClient { 83*c8dee2aaSAndroid Build Coastguard Worker public: 84*c8dee2aaSAndroid Build Coastguard Worker // This enum is used in histogram reporting in chromium. Please don't re-order the list of 85*c8dee2aaSAndroid Build Coastguard Worker // entries, and consider it to be append-only. 86*c8dee2aaSAndroid Build Coastguard Worker enum CacheMissType : uint32_t { 87*c8dee2aaSAndroid Build Coastguard Worker // Hard failures where no fallback could be found. 88*c8dee2aaSAndroid Build Coastguard Worker kFontMetrics = 0, 89*c8dee2aaSAndroid Build Coastguard Worker kGlyphMetrics = 1, 90*c8dee2aaSAndroid Build Coastguard Worker kGlyphImage = 2, 91*c8dee2aaSAndroid Build Coastguard Worker kGlyphPath = 3, 92*c8dee2aaSAndroid Build Coastguard Worker 93*c8dee2aaSAndroid Build Coastguard Worker // (DEPRECATED) The original glyph could not be found and a fallback was used. 94*c8dee2aaSAndroid Build Coastguard Worker kGlyphMetricsFallback = 4, 95*c8dee2aaSAndroid Build Coastguard Worker kGlyphPathFallback = 5, 96*c8dee2aaSAndroid Build Coastguard Worker 97*c8dee2aaSAndroid Build Coastguard Worker kGlyphDrawable = 6, 98*c8dee2aaSAndroid Build Coastguard Worker kLast = kGlyphDrawable 99*c8dee2aaSAndroid Build Coastguard Worker }; 100*c8dee2aaSAndroid Build Coastguard Worker 101*c8dee2aaSAndroid Build Coastguard Worker // An interface to delete handles that may be pinned by the remote server. 102*c8dee2aaSAndroid Build Coastguard Worker class DiscardableHandleManager : public SkRefCnt { 103*c8dee2aaSAndroid Build Coastguard Worker public: 104*c8dee2aaSAndroid Build Coastguard Worker ~DiscardableHandleManager() override = default; 105*c8dee2aaSAndroid Build Coastguard Worker 106*c8dee2aaSAndroid Build Coastguard Worker // Returns true if the handle was unlocked and can be safely deleted. Once 107*c8dee2aaSAndroid Build Coastguard Worker // successful, subsequent attempts to delete the same handle are invalid. 108*c8dee2aaSAndroid Build Coastguard Worker virtual bool deleteHandle(SkDiscardableHandleId) = 0; 109*c8dee2aaSAndroid Build Coastguard Worker assertHandleValid(SkDiscardableHandleId)110*c8dee2aaSAndroid Build Coastguard Worker virtual void assertHandleValid(SkDiscardableHandleId) {} 111*c8dee2aaSAndroid Build Coastguard Worker 112*c8dee2aaSAndroid Build Coastguard Worker virtual void notifyCacheMiss(CacheMissType type, int fontSize) = 0; 113*c8dee2aaSAndroid Build Coastguard Worker 114*c8dee2aaSAndroid Build Coastguard Worker struct ReadFailureData { 115*c8dee2aaSAndroid Build Coastguard Worker size_t memorySize; 116*c8dee2aaSAndroid Build Coastguard Worker size_t bytesRead; 117*c8dee2aaSAndroid Build Coastguard Worker uint64_t typefaceSize; 118*c8dee2aaSAndroid Build Coastguard Worker uint64_t strikeCount; 119*c8dee2aaSAndroid Build Coastguard Worker uint64_t glyphImagesCount; 120*c8dee2aaSAndroid Build Coastguard Worker uint64_t glyphPathsCount; 121*c8dee2aaSAndroid Build Coastguard Worker }; notifyReadFailure(const ReadFailureData & data)122*c8dee2aaSAndroid Build Coastguard Worker virtual void notifyReadFailure(const ReadFailureData& data) {} 123*c8dee2aaSAndroid Build Coastguard Worker }; 124*c8dee2aaSAndroid Build Coastguard Worker 125*c8dee2aaSAndroid Build Coastguard Worker SK_SPI explicit SkStrikeClient(sk_sp<DiscardableHandleManager>, 126*c8dee2aaSAndroid Build Coastguard Worker bool isLogging = true, 127*c8dee2aaSAndroid Build Coastguard Worker SkStrikeCache* strikeCache = nullptr); 128*c8dee2aaSAndroid Build Coastguard Worker SK_SPI ~SkStrikeClient(); 129*c8dee2aaSAndroid Build Coastguard Worker 130*c8dee2aaSAndroid Build Coastguard Worker // Deserializes the strike data from a SkStrikeServer. All messages generated 131*c8dee2aaSAndroid Build Coastguard Worker // from a server when serializing the ops must be deserialized before the op 132*c8dee2aaSAndroid Build Coastguard Worker // is rasterized. 133*c8dee2aaSAndroid Build Coastguard Worker // Returns false if the data is invalid. 134*c8dee2aaSAndroid Build Coastguard Worker SK_SPI bool readStrikeData(const volatile void* memory, size_t memorySize); 135*c8dee2aaSAndroid Build Coastguard Worker 136*c8dee2aaSAndroid Build Coastguard Worker // Given a descriptor re-write the Rec mapping the typefaceID from the renderer to the 137*c8dee2aaSAndroid Build Coastguard Worker // corresponding typefaceID on the GPU. 138*c8dee2aaSAndroid Build Coastguard Worker SK_SPI bool translateTypefaceID(SkAutoDescriptor* descriptor) const; 139*c8dee2aaSAndroid Build Coastguard Worker 140*c8dee2aaSAndroid Build Coastguard Worker // Testing helpers 141*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> retrieveTypefaceUsingServerIDForTest(SkTypefaceID) const; 142*c8dee2aaSAndroid Build Coastguard Worker 143*c8dee2aaSAndroid Build Coastguard Worker // Given a buffer, unflatten into a slug making sure to do the typefaceID translation from 144*c8dee2aaSAndroid Build Coastguard Worker // renderer to GPU. Returns nullptr if there was a problem. 145*c8dee2aaSAndroid Build Coastguard Worker sk_sp<sktext::gpu::Slug> deserializeSlugForTest(const void* data, size_t size) const; 146*c8dee2aaSAndroid Build Coastguard Worker 147*c8dee2aaSAndroid Build Coastguard Worker private: 148*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkStrikeClientImpl> fImpl; 149*c8dee2aaSAndroid Build Coastguard Worker }; 150*c8dee2aaSAndroid Build Coastguard Worker #endif // SkChromeRemoteGlyphCache_DEFINED 151