97f85bb7fd
Chromium has been updated to use makeAnalysisCanvas directly and there are no more references to SkTextBlobDiffCanvas as a type in its code base. Since the GlyphTrackingDevice extends SkNoPixelsDevice, any SkCanvas that uses it is effectively a "no-draw" canvas. However, by returning a base SkCanvas the text tracking now automatically happens in the context of the base's AutoLayerForImageFilter handling it applies on every draw. This means that drawing a text blob with an image filter that modifies the transform state will now be analyzed in that context automatically (simplifying code in chrome after this lands). Another behavioral change is that all non-text draws will still go through the base SkCanvas' virtuals and invoke the device function. Since it's an SkNoPixelsDevice, it'll still be a no-op, it just happens a little later. This won't really impact performance because oop-r already inspects their operations and only plays back text and transform related ones to the analysis canvas, so we shouldn't really see non-text draws being invoked anyways. Bug: chromium:1187246 Change-Id: I83f86571300751f385b3065dfe889f218fa1edc6 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/405196 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
155 lines
5.6 KiB
C++
155 lines
5.6 KiB
C++
/*
|
|
* 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 SkRemoteGlyphCache_DEFINED
|
|
#define SkRemoteGlyphCache_DEFINED
|
|
|
|
// Or uncomment this line:
|
|
//#define SK_CAPTURE_DRAW_TEXT_BLOB
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include "include/core/SkData.h"
|
|
#include "include/core/SkRefCnt.h"
|
|
#include "include/utils/SkNoDrawCanvas.h"
|
|
|
|
class Deserializer;
|
|
class Serializer;
|
|
class SkAutoDescriptor;
|
|
struct SkPackedGlyphID;
|
|
class SkStrikeCache;
|
|
class SkStrikeClientImpl;
|
|
class SkStrikeServer;
|
|
class SkStrikeServerImpl;
|
|
class SkTypeface;
|
|
|
|
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.
|
|
// TODO(khushalsagar): Make pure virtual once chrome implementation lands.
|
|
SK_SPI virtual bool isHandleDeleted(SkDiscardableHandleId) { return false; }
|
|
};
|
|
|
|
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);
|
|
|
|
// Serializes the typeface to be transmitted using this server.
|
|
SK_SPI sk_sp<SkData> serializeTypeface(SkTypeface*);
|
|
|
|
// 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,
|
|
|
|
kLast = kGlyphPath
|
|
};
|
|
|
|
// 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;
|
|
|
|
// TODO: remove this old interface when Chrome has moved over to the one below.
|
|
virtual void notifyCacheMiss(CacheMissType type) { }
|
|
|
|
virtual void notifyCacheMiss(CacheMissType type, int fontSize) {
|
|
this->notifyCacheMiss(type);
|
|
}
|
|
|
|
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 typeface previously serialized using the SkStrikeServer. Returns null if the
|
|
// data is invalid.
|
|
SK_SPI sk_sp<SkTypeface> deserializeTypeface(const void* data, size_t length);
|
|
|
|
// 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);
|
|
|
|
private:
|
|
std::unique_ptr<SkStrikeClientImpl> fImpl;
|
|
};
|
|
|
|
// For exposure to fuzzing only.
|
|
bool SkFuzzDeserializeSkDescriptor(sk_sp<SkData> bytes, SkAutoDescriptor* ad);
|
|
|
|
#endif // SkRemoteGlyphCache_DEFINED
|