aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/remote_demo.cpp
diff options
context:
space:
mode:
authorGravatar Khushal <khushalsagar@chromium.org>2018-05-02 10:29:37 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-02 18:39:31 +0000
commit38a08436886e82de4eb9ebdbcb2bbd5ea7b05c6d (patch)
tree3477528878c8d4b0a053fbc807efd02e60fcde14 /tools/remote_demo.cpp
parent81afc04b5368fc4a7cb6ae4b4d7069e67a3a51f8 (diff)
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 <khushalsagar@chromium.org> Reviewed-by: Khusal Sagar <khushalsagar@chromium.org>
Diffstat (limited to 'tools/remote_demo.cpp')
-rw-r--r--tools/remote_demo.cpp130
1 files changed, 89 insertions, 41 deletions
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 <thread>
#include <unistd.h>
-#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<SkData> 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<double> 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<uint8_t> 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<SkTypeface> {
+ return reinterpret_cast<SkStrikeClient*>(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<ClientDiscardableManager> discardableManager = sk_make_sp<ClientDiscardableManager>();
+ 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<SkData> stream;
if (gUseGpu) {
auto pic = SkPicture::MakeFromData(skpData.get());
- server.prepareSerializeProcs(&procs);
+ SkSerialProcs procs;
+ auto encode = [](SkTypeface* tf, void* ctx) -> sk_sp<SkData> {
+ return reinterpret_cast<SkStrikeServer*>(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<uint8_t> 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;
}