From 1a9971ed47843c606c47793e0f29fc42bbe9971f Mon Sep 17 00:00:00 2001 From: Herb Derby Date: Thu, 19 Jul 2018 13:41:15 -0400 Subject: Convert remote glyph cache to use glyp runs Change-Id: I763a3570ff6b970cfcbf172d786370c77a0db0d7 Reviewed-on: https://skia-review.googlesource.com/142507 Reviewed-by: Khusal Sagar Commit-Queue: Herb Derby --- src/core/SkGlyphRun.cpp | 3 +++ src/core/SkRemoteGlyphCache.cpp | 34 +++++++---------------------- tests/SkRemoteGlyphCacheTest.cpp | 46 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 28 deletions(-) diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp index b0bc59e760..82dae689f9 100644 --- a/src/core/SkGlyphRun.cpp +++ b/src/core/SkGlyphRun.cpp @@ -135,6 +135,9 @@ void SkGlyphRunList::temporaryShuntBlobNotifyAddedToCache(uint32_t cacheID) cons fOriginalTextBlob->notifyAddedToCache(cacheID); } +// -- SkGlyphRunListIterator ----------------------------------------------------------------------- +constexpr SkPoint SkGlyphRunListIterator::fZero; + // -- SkGlyphIDSet --------------------------------------------------------------------------------- // A faster set implementation that does not need any initialization, and reading the set items // is order the number of items, and not the size of the universe. diff --git a/src/core/SkRemoteGlyphCache.cpp b/src/core/SkRemoteGlyphCache.cpp index 4ed9cf287a..18e47f3f4c 100644 --- a/src/core/SkRemoteGlyphCache.cpp +++ b/src/core/SkRemoteGlyphCache.cpp @@ -16,9 +16,9 @@ #include "SkDevice.h" #include "SkDraw.h" #include "SkFindAndPlaceGlyph.h" +#include "SkGlyphRun.h" #include "SkPathEffect.h" #include "SkStrikeCache.h" -#include "SkTextBlobRunIterator.h" #include "SkTraceEvent.h" #include "SkTypeface_remote.h" @@ -240,38 +240,20 @@ public: } protected: - void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, - const SkPaint& paint) override { - // The looper should be applied by the SkCanvas. - SkASSERT(paint.getDrawLooper() == nullptr); - - SkPoint position{x, y}; - SkPaint runPaint{paint}; - SkTextBlobRunIterator it(blob); + void drawGlyphRunList(SkGlyphRunList* glyphRunList) override { + SkPaint runPaint; + SkGlyphRunListIterator it(glyphRunList); for (; !it.done(); it.next()) { // applyFontToPaint() always overwrites the exact same attributes, // so it is safe to not re-seed the paint for this reason. it.applyFontToPaint(&runPaint); - this->processGlyphRun(position, it, runPaint); - } - } - - void drawGlyphRunList(SkGlyphRunList* glyphRunList) override { - auto blob = glyphRunList->blob(); - - SkASSERT(blob != nullptr); - - if (blob != nullptr) { - auto origin = glyphRunList->origin(); - auto paint = glyphRunList->paint(); - this->drawTextBlob(blob, origin.x(), origin.y(), paint); + this->processGlyphRun(glyphRunList->origin(), it, runPaint); } } - private: void processGlyphRun(const SkPoint& position, - const SkTextBlobRunIterator& it, + const SkGlyphRunListIterator& it, const SkPaint& runPaint) { TRACE_EVENT0("skia", "SkTextBlobCacheDiffCanvas::processGlyphRun"); @@ -355,7 +337,7 @@ private: } } - void processGlyphRunForPaths(const SkTextBlobRunIterator& it, + void processGlyphRunForPaths(const SkGlyphRunListIterator& it, const SkPaint& runPaint, const SkMatrix& runMatrix) { TRACE_EVENT0("skia", "SkTextBlobCacheDiffCanvas::processGlyphRunForPaths"); @@ -405,7 +387,7 @@ private: } #if SK_SUPPORT_GPU - bool processGlyphRunForDFT(const SkTextBlobRunIterator& it, + bool processGlyphRunForDFT(const SkGlyphRunListIterator& it, const SkPaint& runPaint, const SkMatrix& runMatrix) { TRACE_EVENT0("skia", "SkTextBlobCacheDiffCanvas::processGlyphRunForDFT"); diff --git a/tests/SkRemoteGlyphCacheTest.cpp b/tests/SkRemoteGlyphCacheTest.cpp index 4a7bd86dc0..6986a7bb03 100644 --- a/tests/SkRemoteGlyphCacheTest.cpp +++ b/tests/SkRemoteGlyphCacheTest.cpp @@ -69,6 +69,8 @@ sk_sp buildTextBlob(sk_sp tf, int glyphCount) { font.setStyle(SkPaint::kFill_Style); font.setHinting(SkPaint::kNormal_Hinting); font.setTextSize(1u); + font.setAntiAlias(true); + font.setSubpixelText(true); SkTextBlobBuilder builder; SkRect bounds = SkRect::MakeWH(10, 10); @@ -99,12 +101,13 @@ SkTextBlobCacheDiffCanvas::Settings MakeSettings(GrContext* context) { } SkBitmap RasterBlob(sk_sp blob, int width, int height, const SkPaint& paint, - GrContext* context, const SkMatrix* matrix = nullptr) { + GrContext* context, const SkMatrix* matrix = nullptr, + SkScalar x = 0) { const SkImageInfo info = SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType); auto surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info); if (matrix) surface->getCanvas()->concat(*matrix); - surface->getCanvas()->drawTextBlob(blob.get(), 0u, 0u, paint); + surface->getCanvas()->drawTextBlob(blob.get(), x, 0, paint); SkBitmap bitmap; bitmap.allocN32Pixels(width, height); surface->readPixels(bitmap, 0, 0); @@ -332,6 +335,45 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextAsPath, reporter, discardableManager->unlockAndDeleteAll(); } +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextXY, reporter, ctxInfo) { + sk_sp discardableManager = sk_make_sp(); + SkStrikeServer server(discardableManager.get()); + SkStrikeClient client(discardableManager, false); + SkPaint paint; + paint.setAntiAlias(true); + paint.setSubpixelText(true); + paint.setLCDRenderText(true); + + // Server. + auto serverTf = SkTypeface::MakeFromName("monospace", SkFontStyle()); + auto serverTfData = server.serializeTypeface(serverTf.get()); + + int glyphCount = 10; + auto serverBlob = buildTextBlob(serverTf, glyphCount); + const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType); + SkTextBlobCacheDiffCanvas cache_diff_canvas(10, 10, SkMatrix::I(), props, &server, + MakeSettings(ctxInfo.grContext())); + cache_diff_canvas.drawTextBlob(serverBlob.get(), 0.5, 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 = RasterBlob(serverBlob, 10, 10, paint, ctxInfo.grContext(), nullptr, 0.5); + SkBitmap actual = RasterBlob(clientBlob, 10, 10, paint, ctxInfo.grContext(), nullptr, 0.5); + COMPARE_BLOBS(expected, actual, reporter); + REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss()); + SkStrikeCache::ValidateGlyphCacheDataSize(); + + // Must unlock everything on termination, otherwise valgrind complains about memory leaks. + discardableManager->unlockAndDeleteAll(); +} + DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextAsDFT, reporter, ctxInfo) { sk_sp discardableManager = sk_make_sp(); SkStrikeServer server(discardableManager.get()); -- cgit v1.2.3