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