blob: 3a71a45e1746cf5bb5521b38012b423a34411ea6 [file] [log] [blame]
/*
* 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