working serialize Slugs with DirectMask runs
Add fully functional flatten, and MakeFromBuffer functionality for the DirectMaskSubRunSlug type. The other runs will need to come later. Add MakeFromBuffer stubs for all the rest of the subrun types. This has a single unit test to check basic functionality of flatten and MakeFromBuffer calls. Change-Id: I379ded4609a2160170ed6a3670c7c7b6ed2c5b2e Reviewed-on: https://skia-review.googlesource.com/c/skia/+/509137 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
parent
e39f253c2a
commit
d3243f660e
@ -520,6 +520,12 @@ public:
|
||||
return true;
|
||||
}
|
||||
const GrAtlasSubRun* testingOnly_atlasSubRun() const override { return nullptr; }
|
||||
static GrSubRunOwner MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
|
||||
SkReadBuffer& buffer,
|
||||
GrSubRunAllocator* alloc,
|
||||
const SkStrikeClient* client) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
SubRunType subRunType() const override { return kPath; }
|
||||
@ -641,7 +647,15 @@ GrSubRunOwner make_drawable_sub_run(const SkZip<SkGlyphVariant, SkPoint>& drawab
|
||||
// -- DrawableSubRunSlug ---------------------------------------------------------------------------
|
||||
class DrawableSubRunSlug : public GrSubRun {
|
||||
public:
|
||||
DrawableSubRunSlug(DrawableOpSubmitter&& drawingDrawing) : fDrawingDrawing(std::move(drawingDrawing)) {}
|
||||
DrawableSubRunSlug(DrawableOpSubmitter&& drawingDrawing)
|
||||
: fDrawingDrawing(std::move(drawingDrawing)) {}
|
||||
|
||||
static GrSubRunOwner MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
|
||||
SkReadBuffer& buffer,
|
||||
GrSubRunAllocator* alloc,
|
||||
const SkStrikeClient* client) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void draw(SkCanvas* canvas,
|
||||
const GrClip* clip,
|
||||
@ -1109,6 +1123,13 @@ public:
|
||||
GrMaskFormat format,
|
||||
GrSubRunAllocator* alloc);
|
||||
|
||||
static GrSubRunOwner MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
|
||||
SkReadBuffer& buffer,
|
||||
GrSubRunAllocator* alloc,
|
||||
const SkStrikeClient* client) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void draw(SkCanvas*,
|
||||
const GrClip*,
|
||||
const SkMatrixProvider& viewMatrix,
|
||||
@ -1326,6 +1347,13 @@ public:
|
||||
const GrSDFTMatrixRange& matrixRange,
|
||||
GrSubRunAllocator* alloc);
|
||||
|
||||
static GrSubRunOwner MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
|
||||
SkReadBuffer& buffer,
|
||||
GrSubRunAllocator* alloc,
|
||||
const SkStrikeClient* client) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void draw(SkCanvas*,
|
||||
const GrClip*,
|
||||
const SkMatrixProvider& viewMatrix,
|
||||
@ -2777,6 +2805,11 @@ public:
|
||||
GrMaskFormat format,
|
||||
GrSubRunAllocator* alloc);
|
||||
|
||||
static GrSubRunOwner MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
|
||||
SkReadBuffer& buffer,
|
||||
GrSubRunAllocator* alloc,
|
||||
const SkStrikeClient* client);
|
||||
|
||||
void draw(SkCanvas*,
|
||||
const GrClip* clip,
|
||||
const SkMatrixProvider& viewMatrix,
|
||||
@ -2816,9 +2849,7 @@ public:
|
||||
|
||||
protected:
|
||||
SubRunType subRunType() const override { return kDirectMask; }
|
||||
void doFlatten(SkWriteBuffer& buffer) const override {
|
||||
SK_ABORT("Not implemented.");
|
||||
}
|
||||
void doFlatten(SkWriteBuffer& buffer) const override;
|
||||
|
||||
private:
|
||||
// Return true if the positionMatrix represents an integer translation. Return the device
|
||||
@ -2891,6 +2922,54 @@ GrSubRunOwner DirectMaskSubRunSlug::Make(const GrTextReferenceFrame* referenceFr
|
||||
GrGlyphVector{std::move(strike), {glyphIDs, goodPosCount}});
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool pun_read(SkReadBuffer& buffer, T* dst) {
|
||||
return buffer.readPad32(dst, sizeof(T));
|
||||
}
|
||||
|
||||
GrSubRunOwner DirectMaskSubRunSlug::MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
|
||||
SkReadBuffer& buffer,
|
||||
GrSubRunAllocator* alloc,
|
||||
const SkStrikeClient*) {
|
||||
|
||||
GrMaskFormat format = (GrMaskFormat)buffer.readInt();
|
||||
SkGlyphRect runBounds;
|
||||
pun_read(buffer, &runBounds);
|
||||
|
||||
int glyphCount = buffer.readInt();
|
||||
SkASSERT(0 < glyphCount);
|
||||
if (glyphCount <= 0) { return nullptr; }
|
||||
DevicePosition* positionsData = alloc->makePODArray<DevicePosition>(glyphCount);
|
||||
for (int i = 0; i < glyphCount; ++i) {
|
||||
pun_read(buffer, &positionsData[i]);
|
||||
}
|
||||
SkSpan<DevicePosition> positions(positionsData, glyphCount);
|
||||
|
||||
auto glyphVector = GrGlyphVector::MakeFromBuffer(buffer, alloc);
|
||||
SkASSERT(glyphVector.has_value());
|
||||
if (!glyphVector) { return nullptr; }
|
||||
SkASSERT(SkTo<int>(glyphVector->glyphs().size()) == glyphCount);
|
||||
if (SkTo<int>(glyphVector->glyphs().size()) != glyphCount) { return nullptr; }
|
||||
return alloc->makeUnique<DirectMaskSubRunSlug>(
|
||||
referenceFrame, format, runBounds, positions, std::move(glyphVector.value()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void pun_write(SkWriteBuffer& buffer, const T& src) {
|
||||
buffer.writePad32(&src, sizeof(T));
|
||||
}
|
||||
|
||||
void DirectMaskSubRunSlug::doFlatten(SkWriteBuffer& buffer) const {
|
||||
buffer.writeInt(fMaskFormat);
|
||||
pun_write(buffer, fGlyphDeviceBounds);
|
||||
int glyphCount = SkTo<int>(fLeftTopDevicePos.size());
|
||||
buffer.writeInt(glyphCount);
|
||||
for (auto pos : fLeftTopDevicePos) {
|
||||
pun_write(buffer, pos);
|
||||
}
|
||||
fGlyphs.flatten(buffer);
|
||||
}
|
||||
|
||||
int DirectMaskSubRunSlug::unflattenSize() const {
|
||||
return sizeof(DirectMaskSubRunSlug) +
|
||||
fGlyphs.unflattenSize() +
|
||||
@ -3177,12 +3256,10 @@ sk_sp<Slug> Slug::Make(const SkMatrixProvider& viewMatrix,
|
||||
|
||||
size_t allocationSize = sizeof(GrTextBlob) + bytesNeededForSubRun;
|
||||
|
||||
void* allocation = ::operator new (allocationSize);
|
||||
|
||||
const SkMatrix positionMatrix =
|
||||
position_matrix(viewMatrix.localToDevice(), glyphRunList.origin());
|
||||
|
||||
sk_sp<Slug> slug{new (allocation)
|
||||
sk_sp<Slug> slug{new (::operator new (allocationSize))
|
||||
Slug(glyphRunList.sourceBounds(),
|
||||
paint,
|
||||
positionMatrix,
|
||||
@ -3196,7 +3273,7 @@ sk_sp<Slug> Slug::Make(const SkMatrixProvider& viewMatrix,
|
||||
positionMatrix,
|
||||
paint,
|
||||
control,
|
||||
"Slug",
|
||||
"Make Slug",
|
||||
uniqueID);
|
||||
}
|
||||
|
||||
@ -3305,11 +3382,11 @@ GrSubRunOwner GrSubRun::MakeFromBuffer(const GrTextReferenceFrame* referenceFram
|
||||
/* The makers will be populated in the next CL. */
|
||||
static Maker makers[kSubRunTypeCount] = {
|
||||
nullptr, // 0 index is bad.
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
DirectMaskSubRunSlug::MakeFromBuffer,
|
||||
SDFTSubRun::MakeFromBuffer,
|
||||
TransformedMaskSubRun::MakeFromBuffer,
|
||||
PathSubRun::MakeFromBuffer,
|
||||
DrawableSubRunSlug::MakeFromBuffer,
|
||||
};
|
||||
int subRunTypeInt = buffer.readInt();
|
||||
SkASSERT(kBad < subRunTypeInt && subRunTypeInt < kSubRunTypeCount);
|
||||
@ -3318,7 +3395,7 @@ GrSubRunOwner GrSubRun::MakeFromBuffer(const GrTextReferenceFrame* referenceFram
|
||||
}
|
||||
auto maker = makers[subRunTypeInt];
|
||||
if (!buffer.validate(maker != nullptr)) { return nullptr; }
|
||||
return makers[subRunTypeInt](referenceFrame, buffer, alloc, client);
|
||||
return maker(referenceFrame, buffer, alloc, client);
|
||||
}
|
||||
|
||||
sk_sp<GrSlug> SkMakeSlugFromBuffer(SkReadBuffer& buffer, const SkStrikeClient* client) {
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "include/private/chromium/SkChromeRemoteGlyphCache.h"
|
||||
#include "src/core/SkDraw.h"
|
||||
#include "src/core/SkFontPriv.h"
|
||||
#include "src/core/SkReadBuffer.h"
|
||||
#include "src/core/SkScalerCache.h"
|
||||
#include "src/core/SkStrikeCache.h"
|
||||
#include "src/core/SkStrikeSpec.h"
|
||||
@ -187,7 +188,23 @@ SkBitmap RasterBlob(sk_sp<SkTextBlob> blob, int width, int height, const SkPaint
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
SkBitmap RasterSlug(sk_sp<SkTextBlob> blob, int width, int height, const SkPaint& paint,
|
||||
SkBitmap RasterBlobThroughSlug(sk_sp<SkTextBlob> blob, int width, int height, const SkPaint& paint,
|
||||
GrRecordingContext* rContext, const SkMatrix* matrix = nullptr,
|
||||
SkScalar x = 0) {
|
||||
auto surface = MakeSurface(width, height, rContext);
|
||||
if (matrix) {
|
||||
surface->getCanvas()->concat(*matrix);
|
||||
}
|
||||
auto canvas = surface->getCanvas();
|
||||
auto slug = GrSlug::ConvertBlob(canvas, *blob, {x, height/2.0f}, paint);
|
||||
slug->draw(canvas);
|
||||
SkBitmap bitmap;
|
||||
bitmap.allocN32Pixels(width, height);
|
||||
surface->readPixels(bitmap, 0, 0);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
SkBitmap RasterSlug(sk_sp<GrSlug> slug, int width, int height, const SkPaint& paint,
|
||||
GrRecordingContext* rContext, const SkMatrix* matrix = nullptr,
|
||||
SkScalar x = 0) {
|
||||
auto surface = MakeSurface(width, height, rContext);
|
||||
@ -195,7 +212,6 @@ SkBitmap RasterSlug(sk_sp<SkTextBlob> blob, int width, int height, const SkPaint
|
||||
surface->getCanvas()->concat(*matrix);
|
||||
}
|
||||
auto canvas = surface->getCanvas();
|
||||
auto slug = GrSlug::ConvertBlob(canvas, *blob, {x, height/2.0f}, paint);
|
||||
slug->draw(canvas);
|
||||
SkBitmap bitmap;
|
||||
bitmap.allocN32Pixels(width, height);
|
||||
@ -291,8 +307,54 @@ DEF_GPUTEST_FOR_CONTEXTS(SkRemoteGlyphCache_StrikeSerializationSlug,
|
||||
client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
|
||||
auto clientBlob = buildTextBlob(clientTf, glyphCount);
|
||||
|
||||
SkBitmap expected = RasterSlug(serverBlob, 10, 10, paint, dContext);
|
||||
SkBitmap actual = RasterSlug(clientBlob, 10, 10, paint, dContext);
|
||||
SkBitmap expected = RasterBlobThroughSlug(serverBlob, 10, 10, paint, dContext);
|
||||
SkBitmap actual = RasterBlobThroughSlug(clientBlob, 10, 10, paint, dContext);
|
||||
compare_blobs(expected, actual, reporter);
|
||||
REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
|
||||
|
||||
// Must unlock everything on termination, otherwise valgrind complains about memory leaks.
|
||||
discardableManager->unlockAndDeleteAll();
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_CONTEXTS(SkRemoteGlyphCache_SlugSerialization,
|
||||
sk_gpu_test::GrContextFactory::IsRenderingContext,
|
||||
reporter, ctxInfo, use_padding_options) {
|
||||
auto dContext = ctxInfo.directContext();
|
||||
sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
|
||||
SkStrikeServer server(discardableManager.get());
|
||||
SkStrikeClient client(discardableManager, false);
|
||||
const SkPaint paint;
|
||||
|
||||
// Server.
|
||||
auto serverTf = SkTypeface::MakeFromName("monospace", SkFontStyle());
|
||||
auto serverTfData = server.serializeTypeface(serverTf.get());
|
||||
|
||||
int glyphCount = 10;
|
||||
auto serverBlob = buildTextBlob(serverTf, glyphCount);
|
||||
auto props = FindSurfaceProps(dContext);
|
||||
std::unique_ptr<SkCanvas> analysisCanvas = server.makeAnalysisCanvas(
|
||||
10, 10, props, nullptr, dContext->supportsDistanceFieldText());
|
||||
|
||||
// Generate strike updates.
|
||||
auto srcSlug = GrSlug::ConvertBlob(analysisCanvas.get(), *serverBlob, {0, 0}, paint);
|
||||
SkBinaryWriteBuffer writeBuffer;
|
||||
srcSlug->flatten(writeBuffer);
|
||||
|
||||
auto data = writeBuffer.snapshotAsData();
|
||||
SkReadBuffer readBuffer(data->data(), data->size());
|
||||
|
||||
auto dstSlug = client.makeSlugFromBuffer(readBuffer);
|
||||
REPORTER_ASSERT(reporter, dstSlug != nullptr);
|
||||
|
||||
std::vector<uint8_t> serverStrikeData;
|
||||
server.writeStrikeData(&serverStrikeData);
|
||||
|
||||
// Client.
|
||||
REPORTER_ASSERT(reporter,
|
||||
client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
|
||||
|
||||
SkBitmap expected = RasterSlug(srcSlug, 10, 10, paint, dContext);
|
||||
SkBitmap actual = RasterSlug(dstSlug, 10, 10, paint, dContext);
|
||||
compare_blobs(expected, actual, reporter);
|
||||
REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user