diff --git a/src/core/SkChromeRemoteGlyphCache.cpp b/src/core/SkChromeRemoteGlyphCache.cpp index 3d93d75812..7893343948 100644 --- a/src/core/SkChromeRemoteGlyphCache.cpp +++ b/src/core/SkChromeRemoteGlyphCache.cpp @@ -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 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}; diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index d114b58e27..5d4018bccf 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -482,7 +482,7 @@ void SkBaseDevice::simplifyGlyphRunRSXFormAndRedraw(SkCanvas* canvas, #if SK_SUPPORT_GPU sk_sp SkBaseDevice::convertGlyphRunListToSlug( const SkGlyphRunList& glyphRunList, - const SkPaint& paint) const { + const SkPaint& paint) { return nullptr; } diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h index ba5b99d784..2b2fac2381 100644 --- a/src/core/SkDevice.h +++ b/src/core/SkDevice.h @@ -302,7 +302,7 @@ protected: #if SK_SUPPORT_GPU virtual sk_sp convertGlyphRunListToSlug( const SkGlyphRunList& glyphRunList, - const SkPaint& paint) const; + const SkPaint& paint); virtual void drawSlug(SkCanvas*, GrSlug* slug); #endif diff --git a/src/gpu/text/GrTextBlob.cpp b/src/gpu/text/GrTextBlob.cpp index ab01c2a9b9..908fb85dd5 100644 --- a/src/gpu/text/GrTextBlob.cpp +++ b/src/gpu/text/GrTextBlob.cpp @@ -3102,7 +3102,7 @@ void Slug::processSourceMasks(const SkZip& drawables, namespace skgpu::v1 { sk_sp -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 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 diff --git a/src/gpu/text/GrTextBlob.h b/src/gpu/text/GrTextBlob.h index 680539e0d5..f3d79d6d12 100644 --- a/src/gpu/text/GrTextBlob.h +++ b/src/gpu/text/GrTextBlob.h @@ -319,4 +319,11 @@ private: const SkPaint& fPaint; }; +namespace skgpu::v1 { +sk_sp MakeSlug(const SkMatrixProvider& drawMatrix, + const SkGlyphRunList& glyphRunList, + const SkPaint& paint, + const GrSDFTControl& control, + SkGlyphRunListPainter* painter); +} // namespace skgpu::v1 #endif // GrTextBlob_DEFINED diff --git a/src/gpu/v1/Device_v1.h b/src/gpu/v1/Device_v1.h index 38aab48fbd..ae56d777d1 100644 --- a/src/gpu/v1/Device_v1.h +++ b/src/gpu/v1/Device_v1.h @@ -159,7 +159,7 @@ protected: sk_sp convertGlyphRunListToSlug( const SkGlyphRunList& glyphRunList, - const SkPaint& paint) const override; + const SkPaint& paint) override; void drawSlug(SkCanvas*, GrSlug* slug) override; diff --git a/tests/SkRemoteGlyphCacheTest.cpp b/tests/SkRemoteGlyphCacheTest.cpp index b513159748..b07b05235c 100644 --- a/tests/SkRemoteGlyphCacheTest.cpp +++ b/tests/SkRemoteGlyphCacheTest.cpp @@ -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 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 blob, int width, int height, const SkPaint return bitmap; } +SkBitmap RasterSlug(sk_sp 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 = sk_make_sp(); 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 = sk_make_sp(); + 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 analysisCanvas = server.makeAnalysisCanvas( + 10, 10, props, nullptr, dContext->supportsDistanceFieldText()); + + // Generate strike updates. + (void)GrSlug::ConvertBlob(analysisCanvas.get(), *serverBlob, {0, 0}, paint); + + std::vector 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 = sk_make_sp(); SkStrikeServer server(discardableManager.get());