convertToBlob added to remote glyphs cache

Have the AnalysisCanvas (also known as the diff canvas) convert
SkTextBlobs to GrSlugs and record the Strike differences. Make sure
these differences are tracked and recorded.

Bug: chromium:1278340

Change-Id: I2c8d62fa61511abd1e14d4bf595e6db1a0b5e26b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/503827
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2022-02-03 14:09:07 -05:00 committed by SkCQ
parent d33334d44e
commit 7cb61889c5
7 changed files with 99 additions and 7 deletions

View File

@ -33,6 +33,7 @@
#include "include/gpu/GrContextOptions.h"
#include "src/gpu/GrDrawOpAtlas.h"
#include "src/gpu/text/GrSDFTControl.h"
#include "src/gpu/text/GrTextBlob.h"
#endif
namespace {
@ -759,10 +760,10 @@ public:
}
protected:
#if SK_SUPPORT_GPU
void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) override {
#if SK_SUPPORT_GPU
GrContextOptions ctxOptions;
GrSDFTControl control =
GrSDFTControl{fDFTSupport,
@ -782,9 +783,22 @@ protected:
"Cache Diff",
uniqueID);
}
#endif // SK_SUPPORT_GPU
}
sk_sp<GrSlug> convertGlyphRunListToSlug(const SkGlyphRunList& glyphRunList,
const SkPaint& paint) override {
GrContextOptions ctxOptions;
GrSDFTControl control =
GrSDFTControl{fDFTSupport,
this->surfaceProps().isUseDeviceIndependentFonts(),
ctxOptions.fMinDistanceFieldFontSize,
ctxOptions.fGlyphsAsPathsFontSize};
SkMatrix drawMatrix = this->localToDevice();
return skgpu::v1::MakeSlug(drawMatrix, glyphRunList, paint, control, &fPainter);
}
#endif // SK_SUPPORT_GPU
private:
SkStrikeServerImpl* const fStrikeServerImpl;
const bool fDFTSupport{false};

View File

@ -482,7 +482,7 @@ void SkBaseDevice::simplifyGlyphRunRSXFormAndRedraw(SkCanvas* canvas,
#if SK_SUPPORT_GPU
sk_sp<GrSlug> SkBaseDevice::convertGlyphRunListToSlug(
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) const {
const SkPaint& paint) {
return nullptr;
}

View File

@ -302,7 +302,7 @@ protected:
#if SK_SUPPORT_GPU
virtual sk_sp<GrSlug> convertGlyphRunListToSlug(
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) const;
const SkPaint& paint);
virtual void drawSlug(SkCanvas*, GrSlug* slug);
#endif

View File

@ -3102,7 +3102,7 @@ void Slug::processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables,
namespace skgpu::v1 {
sk_sp<GrSlug>
Device::convertGlyphRunListToSlug(const SkGlyphRunList& glyphRunList, const SkPaint& paint) const {
Device::convertGlyphRunListToSlug(const SkGlyphRunList& glyphRunList, const SkPaint& paint) {
return fSurfaceDrawContext->convertGlyphRunListToSlug(
this->asMatrixProvider(), glyphRunList, paint);
}
@ -3132,4 +3132,12 @@ void SurfaceDrawContext::drawSlug(SkCanvas* canvas,
slug->surfaceDraw(canvas, clip, viewMatrix, this);
}
sk_sp<GrSlug> MakeSlug(const SkMatrixProvider& drawMatrix,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint,
const GrSDFTControl& control,
SkGlyphRunListPainter* painter) {
return Slug::Make(drawMatrix, glyphRunList, paint, control, painter);
}
} // namespace skgpu::v1

View File

@ -319,4 +319,11 @@ private:
const SkPaint& fPaint;
};
namespace skgpu::v1 {
sk_sp<GrSlug> MakeSlug(const SkMatrixProvider& drawMatrix,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint,
const GrSDFTControl& control,
SkGlyphRunListPainter* painter);
} // namespace skgpu::v1
#endif // GrTextBlob_DEFINED

View File

@ -159,7 +159,7 @@ protected:
sk_sp<GrSlug> convertGlyphRunListToSlug(
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) const override;
const SkPaint& paint) override;
void drawSlug(SkCanvas*, GrSlug* slug) override;

View File

@ -11,6 +11,7 @@
#include "include/core/SkTextBlob.h"
#include "include/gpu/GrDirectContext.h"
#include "include/private/SkMutex.h"
#include "include/private/chromium/GrSlug.h"
#include "include/private/chromium/SkChromeRemoteGlyphCache.h"
#include "src/core/SkDraw.h"
#include "src/core/SkFontPriv.h"
@ -176,7 +177,9 @@ SkBitmap RasterBlob(sk_sp<SkTextBlob> blob, int width, int height, const SkPaint
GrRecordingContext* rContext, const SkMatrix* matrix = nullptr,
SkScalar x = 0) {
auto surface = MakeSurface(width, height, rContext);
if (matrix) surface->getCanvas()->concat(*matrix);
if (matrix) {
surface->getCanvas()->concat(*matrix);
}
surface->getCanvas()->drawTextBlob(blob.get(), x, height/2, paint);
SkBitmap bitmap;
bitmap.allocN32Pixels(width, height);
@ -184,6 +187,22 @@ 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,
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;
}
DEF_TEST(SkRemoteGlyphCache_TypefaceSerialization, reporter) {
sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
SkStrikeServer server(discardableManager.get());
@ -237,6 +256,50 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_StrikeSerialization, repor
discardableManager->unlockAndDeleteAll();
}
static void use_padding_options(GrContextOptions* options) {
options->fSupportBilerpFromGlyphAtlas = true;
}
DEF_GPUTEST_FOR_CONTEXTS(SkRemoteGlyphCache_StrikeSerializationSlug,
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.
(void)GrSlug::ConvertBlob(analysisCanvas.get(), *serverBlob, {0, 0}, paint);
std::vector<uint8_t> serverStrikeData;
server.writeStrikeData(&serverStrikeData);
// Client.
auto clientTf = client.deserializeTypeface(serverTfData->data(), serverTfData->size());
REPORTER_ASSERT(reporter,
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);
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_RENDERING_CONTEXTS(SkRemoteGlyphCache_ReleaseTypeFace, reporter, ctxInfo) {
sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
SkStrikeServer server(discardableManager.get());