From 38a08436886e82de4eb9ebdbcb2bbd5ea7b05c6d Mon Sep 17 00:00:00 2001 From: Khushal Date: Wed, 2 May 2018 10:29:37 -0700 Subject: fonts: Reland push font remoting. This relands the following changes: 1) https://skia-review.googlesource.com/c/skia/+/120283 2) https://skia-review.googlesource.com/c/skia/+/125029 3) https://skia-review.googlesource.com/c/skia/+/125140 The original changes had to be reverted due to a memory leak in SkBaseDevice from SkTextBlobCacheDiffCanvas. This has been addressed by https://skia-review.googlesource.com/c/skia/+/125160 TBR=herb@google.com Bug: skia:7515, 831354 Change-Id: I73f4fcb1c397f31bf01553ff48c71ed2d6dd0770 Reviewed-on: https://skia-review.googlesource.com/125326 Commit-Queue: Khusal Sagar Reviewed-by: Khusal Sagar --- tools/remote_demo.cpp | 130 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 41 deletions(-) (limited to 'tools') diff --git a/tools/remote_demo.cpp b/tools/remote_demo.cpp index 8fc96cadb8..105a9b3ea7 100644 --- a/tools/remote_demo.cpp +++ b/tools/remote_demo.cpp @@ -16,8 +16,9 @@ #include #include -#include "SkRemoteGlyphCache.h" #include "SkGraphics.h" +#include "SkRemoteGlyphCache.h" +#include "SkScalerContext.h" #include "SkSurface.h" static std::string gSkpName; @@ -25,6 +26,46 @@ static bool gUseGpu = true; static bool gPurgeFontCaches = true; static bool gUseProcess = true; +class ServerDiscardableManager : public SkStrikeServer::DiscardableHandleManager { +public: + ServerDiscardableManager() = default; + ~ServerDiscardableManager() override = default; + + SkDiscardableHandleId createHandle() override { return ++nextHandleId; } + bool lockHandle(SkDiscardableHandleId handleId) override { + return handleId > lastPurgedHandleId; + } + void purgeAll() { lastPurgedHandleId = nextHandleId; } + +private: + SkDiscardableHandleId nextHandleId = 0u; + SkDiscardableHandleId lastPurgedHandleId = 0u; +}; + +class ClientDiscardableManager : public SkStrikeClient::DiscardableHandleManager { +public: + class ScopedPurgeCache { + public: + ScopedPurgeCache(ClientDiscardableManager* manager) : fManager(manager) { + if (fManager) fManager->allowPurging = true; + } + ~ScopedPurgeCache() { + if (fManager) fManager->allowPurging = false; + } + + private: + ClientDiscardableManager* fManager; + }; + + ClientDiscardableManager() = default; + ~ClientDiscardableManager() override = default; + + bool deleteHandle(SkDiscardableHandleId) override { return allowPurging; } + +private: + bool allowPurging = false; +}; + static bool write_SkData(int fd, const SkData& data) { size_t size = data.size(); ssize_t bytesWritten = ::write(fd, &size, sizeof(size)); @@ -43,7 +84,6 @@ static bool write_SkData(int fd, const SkData& data) { } static sk_sp read_SkData(int fd) { - size_t size; ssize_t readSize = ::read(fd, &size, sizeof(size)); if (readSize <= 0) { @@ -92,44 +132,56 @@ private: std::chrono::duration fElapsedSeconds{0.0}; }; -static void build_prime_cache_spec(const SkIRect &bounds, - const SkSurfaceProps &props, - const SkPicture &pic, - SkStrikeCacheDifferenceSpec *strikeDifference) { +static bool push_font_data(const SkPicture& pic, SkStrikeServer* strikeServer, int writeFd) { SkMatrix deviceMatrix = SkMatrix::I(); - - SkTextBlobCacheDiffCanvas filter( - bounds.width(), bounds.height(), deviceMatrix, props, - SkScalerContextFlags::kFakeGammaAndBoostContrast, - strikeDifference); - + const SkIRect bounds = pic.cullRect().round(); + const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType); + SkTextBlobCacheDiffCanvas filter(bounds.width(), bounds.height(), deviceMatrix, props, + strikeServer); pic.playback(&filter); + + std::vector fontData; + strikeServer->writeStrikeData(&fontData); + auto data = SkData::MakeWithoutCopy(fontData.data(), fontData.size()); + return write_SkData(writeFd, *data); } -static void final_draw(std::string outFilename, - SkDeserialProcs* procs, - SkData* picData, - SkStrikeClient* client) { +static void final_draw(std::string outFilename, SkData* picData, SkStrikeClient* client, + ClientDiscardableManager* discardableManager, int readFd, int writeFd) { + SkDeserialProcs procs; + auto decode = [](const void* data, size_t length, void* ctx) -> sk_sp { + return reinterpret_cast(ctx)->deserializeTypeface(data, length); + }; + procs.fTypefaceProc = decode; + procs.fTypefaceCtx = client; - auto pic = SkPicture::MakeFromData(picData, procs); + auto pic = SkPicture::MakeFromData(picData, &procs); auto cullRect = pic->cullRect(); auto r = cullRect.round(); auto s = SkSurface::MakeRasterN32Premul(r.width(), r.height()); auto c = s->getCanvas(); - auto picUnderTest = SkPicture::MakeFromData(picData, procs); + auto picUnderTest = SkPicture::MakeFromData(picData, &procs); Timer drawTime; + auto randomData = SkData::MakeUninitialized(1u); for (int i = 0; i < 100; i++) { if (gPurgeFontCaches) { + ClientDiscardableManager::ScopedPurgeCache purge(discardableManager); SkGraphics::PurgeFontCache(); + SkASSERT(SkGraphics::GetFontCacheUsed() == 0u); } + drawTime.start(); if (client != nullptr) { - SkStrikeCacheDifferenceSpec strikeDifference; - build_prime_cache_spec(r, s->props(), *picUnderTest, &strikeDifference); - client->primeStrikeCache(strikeDifference); + // Kick the renderer to send us the fonts. + write_SkData(writeFd, *randomData); + auto fontData = read_SkData(readFd); + if (fontData && !fontData->isEmpty()) { + if (!client->readStrikeData(fontData->data(), fontData->size())) + SK_ABORT("Bad serialization"); + } } c->drawPicture(picUnderTest); drawTime.stop(); @@ -150,22 +202,16 @@ static void final_draw(std::string outFilename, static void gpu(int readFd, int writeFd) { if (gUseGpu) { - auto clientRPC = [readFd, writeFd](const SkData& inBuffer) { - write_SkData(writeFd, inBuffer); - return read_SkData(readFd); - }; - auto picData = read_SkData(readFd); if (picData == nullptr) { return; } - SkStrikeClient client{clientRPC}; + sk_sp discardableManager = sk_make_sp(); + SkStrikeClient strikeClient(discardableManager); - SkDeserialProcs procs; - client.prepareDeserializeProcs(&procs); - - final_draw("test.png", &procs, picData.get(), &client); + final_draw("test.png", picData.get(), &strikeClient, discardableManager.get(), readFd, + writeFd); } ::close(writeFd); @@ -177,7 +223,8 @@ static void gpu(int readFd, int writeFd) { static int renderer( const std::string& skpName, int readFd, int writeFd) { - SkStrikeServer server{}; + ServerDiscardableManager discardableManager; + SkStrikeServer server(&discardableManager); auto closeAll = [readFd, writeFd]() { ::close(writeFd); ::close(readFd); @@ -186,11 +233,16 @@ static int renderer( auto skpData = SkData::MakeFromFileName(skpName.c_str()); std::cout << "skp stream is " << skpData->size() << " bytes long " << std::endl; - SkSerialProcs procs; sk_sp stream; if (gUseGpu) { auto pic = SkPicture::MakeFromData(skpData.get()); - server.prepareSerializeProcs(&procs); + SkSerialProcs procs; + auto encode = [](SkTypeface* tf, void* ctx) -> sk_sp { + return reinterpret_cast(ctx)->serializeTypeface(tf); + }; + procs.fTypefaceProc = encode; + procs.fTypefaceCtx = &server; + stream = pic->serialize(&procs); if (!write_SkData(writeFd, *stream)) { @@ -198,22 +250,18 @@ static int renderer( return 1; } - std::vector tmpBuffer; while (true) { auto inBuffer = read_SkData(readFd); if (inBuffer == nullptr) { closeAll(); return 0; } - - tmpBuffer.clear(); - server.serve(*inBuffer, &tmpBuffer); - auto outBuffer = SkData::MakeWithoutCopy(tmpBuffer.data(), tmpBuffer.size()); - write_SkData(writeFd, *outBuffer); + if (gPurgeFontCaches) discardableManager.purgeAll(); + push_font_data(*pic.get(), &server, writeFd); } } else { stream = skpData; - final_draw("test-correct.png", nullptr, stream.get(), nullptr); + final_draw("test-correct.png", stream.get(), nullptr, nullptr, -1, -1); closeAll(); return 0; } -- cgit v1.2.3