diff options
author | Herb Derby <herb@google.com> | 2018-03-27 14:40:53 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-03-27 21:51:44 +0000 |
commit | 39e45df22d07549cc09760dfc9946734eed17a41 (patch) | |
tree | a8a18e7a2ca40adda7e576466c9b2ecc481d64e1 | |
parent | d24c32545233692d66bcf658b46aedab381b669c (diff) |
Various cleanup to remote_demo
Integrate SkRemoteGlyphCacheRenderer into SkStrikeServer
Add a Timer.
Remove unused code.
BUG=skia:7515
Change-Id: Idffb477af71cbcc4035df190e29e8910b61aa6e5
Reviewed-on: https://skia-review.googlesource.com/116485
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Herb Derby <herb@google.com>
-rw-r--r-- | src/core/SkRemoteGlyphCache.cpp | 137 | ||||
-rw-r--r-- | src/core/SkRemoteGlyphCache.h | 66 | ||||
-rw-r--r-- | tools/remote_demo.cpp | 98 |
3 files changed, 140 insertions, 161 deletions
diff --git a/src/core/SkRemoteGlyphCache.cpp b/src/core/SkRemoteGlyphCache.cpp index dfad89a7c2..9acb615f5a 100644 --- a/src/core/SkRemoteGlyphCache.cpp +++ b/src/core/SkRemoteGlyphCache.cpp @@ -45,9 +45,9 @@ private: size_t fSize; }; -// -- SkTransport ---------------------------------------------------------------------------------- +// -- SkRemoteStrikeTransport ---------------------------------------------------------------------------------- -SkTransport::IOResult SkTransport::writeSkData(const SkData& data) { +SkRemoteStrikeTransport::IOResult SkRemoteStrikeTransport::writeSkData(const SkData& data) { size_t size = data.size(); if (this->write(&size, sizeof(size)) == kFail) { @@ -60,7 +60,7 @@ SkTransport::IOResult SkTransport::writeSkData(const SkData& data) { return kSuccess; } -sk_sp<SkData> SkTransport::readSkData() { +sk_sp<SkData> SkRemoteStrikeTransport::readSkData() { size_t size; if(std::get<1>(this->read(&size, sizeof(size))) == kFail) { return nullptr; @@ -135,7 +135,7 @@ public: return result; } - SkTransport::IOResult endWrite(SkTransport* transport) { + SkRemoteStrikeTransport::IOResult endWrite(SkRemoteStrikeTransport* transport) { return transport->write(fBuffer.get(), fCursor); } @@ -150,14 +150,14 @@ private: class Deserializer { public: - void startRead(SkTransport* transport) { + void startRead(SkRemoteStrikeTransport* transport) { fCursor = 0; fEnd = 0; fTransport = transport; } template <typename T> - T* startRead(SkTransport* transport) { + T* startRead(SkRemoteStrikeTransport* transport) { this->startRead(transport); return this->read<T>(); } @@ -196,30 +196,30 @@ public: private: void* ensureAtLeast(size_t size) { if (size > fEnd - fCursor) { - if (readAtLeast(size) == SkTransport::kFail) { + if (readAtLeast(size) == SkRemoteStrikeTransport::kFail) { return nullptr; } } return &fBuffer[fCursor]; } - SkTransport::IOResult readAtLeast(size_t size) { + SkRemoteStrikeTransport::IOResult readAtLeast(size_t size) { size_t readSoFar = 0; size_t bufferLeft = kBufferSize - fCursor; size_t needed = size - (fEnd - fCursor); while (readSoFar < needed) { - SkTransport::IOResult result; + SkRemoteStrikeTransport::IOResult result; size_t readSize; std::tie(readSize, result) = fTransport->read(&fBuffer[fEnd+readSoFar], bufferLeft - readSoFar); - if (result == SkTransport::kFail || readSize == 0) {return SkTransport::kFail;} + if (result == SkRemoteStrikeTransport::kFail || readSize == 0) {return SkRemoteStrikeTransport::kFail;} readSoFar += readSize; } fEnd += readSoFar; - return SkTransport::kSuccess; + return SkRemoteStrikeTransport::kSuccess; } - SkTransport* fTransport; + SkRemoteStrikeTransport* fTransport; static constexpr size_t kBufferSize = kPageSize * 2000; std::unique_ptr<uint8_t[]> fBuffer{new uint8_t[kBufferSize]}; @@ -227,38 +227,6 @@ private: size_t fEnd{0}; }; -// -- SkRemoteGlyphCacheRenderer ----------------------------------------------------------------- - -void SkRemoteGlyphCacheRenderer::prepareSerializeProcs(SkSerialProcs* procs) { - auto encode = [](SkTypeface* tf, void* ctx) { - return reinterpret_cast<SkRemoteGlyphCacheRenderer*>(ctx)->encodeTypeface(tf); - }; - procs->fTypefaceProc = encode; - procs->fTypefaceCtx = this; -} - -SkScalerContext* SkRemoteGlyphCacheRenderer::generateScalerContext( - const SkScalerContextRecDescriptor& desc, SkFontID typefaceId) -{ - - auto scaler = fScalerContextMap.find(desc); - if (scaler == nullptr) { - auto typefaceIter = fTypefaceMap.find(typefaceId); - if (typefaceIter == nullptr) { - // TODO: handle this with some future fallback strategy. - SK_ABORT("unknown type face"); - // Should never happen - return nullptr; - } - auto tf = typefaceIter->get(); - // TODO: make effects really work. - SkScalerContextEffects effects; - auto mapSc = tf->createScalerContext(effects, &desc.desc(), false); - scaler = fScalerContextMap.set(desc, std::move(mapSc)); - } - return scaler->get(); -} - // -- TrackLayerDevice ----------------------------------------------------------------------------- class TrackLayerDevice : public SkNoPixelsDevice { public: @@ -536,23 +504,9 @@ struct WireTypeface { bool isFixed; }; -sk_sp<SkData> SkRemoteGlyphCacheRenderer::encodeTypeface(SkTypeface* tf) { - WireTypeface wire = { - SkTypeface::UniqueID(tf), - tf->countGlyphs(), - tf->fontStyle(), - tf->isFixedPitch() - }; - auto typeFace = fTypefaceMap.find(SkTypeface::UniqueID(tf)); - if (typeFace == nullptr) { - fTypefaceMap.set(SkTypeface::UniqueID(tf), sk_ref_sp(tf)); - } - // Can this be done with no copy? - return SkData::MakeWithCopy(&wire, sizeof(wire)); -} static void write_strikes_spec(const SkStrikeCacheDifferenceSpec &spec, Serializer* serializer, - SkTransport* transport) { + SkRemoteStrikeTransport* transport) { serializer->startEmplace<Op>(OpCode::kPrepopulateCache, SkFontID{0}, SkScalerContextRec{}); serializer->emplace<Header>(spec.size()); @@ -631,8 +585,8 @@ template <typename PerHeader, typename PerStrike, typename PerGlyph> #endif static void read_strikes_spec_write_strikes_data( - Deserializer* deserializer, Serializer* serializer, SkTransport* transport, - SkRemoteGlyphCacheRenderer* rc) + Deserializer* deserializer, Serializer* serializer, SkRemoteStrikeTransport* transport, + SkStrikeServer* rc) { // Don't start because the op started this deserialization. auto header = deserializer->read<Header>(); @@ -668,7 +622,7 @@ static void read_strikes_spec_write_strikes_data( static void update_caches_from_strikes_data(SkStrikeClient *client, Deserializer *deserializer, - SkTransport *transport) { + SkRemoteStrikeTransport *transport) { deserializer->startRead(transport); auto header = deserializer->read<Header>(); for (int i = 0; i < header->strikeCount; i++) { @@ -700,9 +654,8 @@ static void update_caches_from_strikes_data(SkStrikeClient *client, deserializer->endRead(); } - // -- SkStrikeServer ------------------------------------------------------------------------------- -SkStrikeServer::SkStrikeServer(SkTransport* transport) +SkStrikeServer::SkStrikeServer(SkRemoteStrikeTransport* transport) : fTransport{transport} { } int SkStrikeServer::serve() { @@ -711,13 +664,12 @@ int SkStrikeServer::serve() { auto deserializer = skstd::make_unique<Deserializer>();; while (true) { - printf("Server is waiting for an op\n"); Op* op = deserializer->startRead<Op>(fTransport); if (op == nullptr) { break; } switch (op->opCode) { case OpCode::kFontMetrics : { - auto sc = fRendererCache.generateScalerContext(op->descriptor, op->typefaceId); + auto sc = this->generateScalerContext(op->descriptor, op->typefaceId); SkPaint::FontMetrics metrics; sc->getFontMetrics(&metrics); serializer->startWrite<SkPaint::FontMetrics>(metrics); @@ -725,7 +677,7 @@ int SkStrikeServer::serve() { break; } case OpCode::kGlyphPath : { - auto sc = fRendererCache.generateScalerContext(op->descriptor, op->typefaceId); + auto sc = this->generateScalerContext(op->descriptor, op->typefaceId); // TODO: check for buffer overflow. SkPath path; sc->getPath(op->glyphId, &path); @@ -737,7 +689,7 @@ int SkStrikeServer::serve() { break; } case OpCode::kGlyphMetricsAndImage : { - auto sc = fRendererCache.generateScalerContext(op->descriptor, op->typefaceId); + auto sc = this->generateScalerContext(op->descriptor, op->typefaceId); serializer->startWrite(); auto glyph = serializer->allocate<SkGlyph>(); @@ -758,7 +710,7 @@ int SkStrikeServer::serve() { } case OpCode::kPrepopulateCache : { read_strikes_spec_write_strikes_data( - deserializer.get(), serializer.get(), fTransport, &fRendererCache); + deserializer.get(), serializer.get(), fTransport, this); break; } @@ -769,6 +721,51 @@ int SkStrikeServer::serve() { return 0; } +void SkStrikeServer::prepareSerializeProcs(SkSerialProcs* procs) { + auto encode = [](SkTypeface* tf, void* ctx) { + return reinterpret_cast<SkStrikeServer*>(ctx)->encodeTypeface(tf); + }; + procs->fTypefaceProc = encode; + procs->fTypefaceCtx = this; +} + +SkScalerContext* SkStrikeServer::generateScalerContext( + const SkScalerContextRecDescriptor& desc, SkFontID typefaceId) +{ + + auto scaler = fScalerContextMap.find(desc); + if (scaler == nullptr) { + auto typefaceIter = fTypefaceMap.find(typefaceId); + if (typefaceIter == nullptr) { + // TODO: handle this with some future fallback strategy. + SK_ABORT("unknown type face"); + // Should never happen + return nullptr; + } + auto tf = typefaceIter->get(); + // TODO: make effects really work. + SkScalerContextEffects effects; + auto mapSc = tf->createScalerContext(effects, &desc.desc(), false); + scaler = fScalerContextMap.set(desc, std::move(mapSc)); + } + return scaler->get(); +} + +sk_sp<SkData> SkStrikeServer::encodeTypeface(SkTypeface* tf) { + WireTypeface wire = { + SkTypeface::UniqueID(tf), + tf->countGlyphs(), + tf->fontStyle(), + tf->isFixedPitch() + }; + auto typeFace = fTypefaceMap.find(SkTypeface::UniqueID(tf)); + if (typeFace == nullptr) { + fTypefaceMap.set(SkTypeface::UniqueID(tf), sk_ref_sp(tf)); + } + // Can this be done with no copy? + return SkData::MakeWithCopy(&wire, sizeof(wire)); +} + // -- SkStrikeClient ------------------------------------------------------------------------------- static Op* start_op_write( @@ -777,7 +774,7 @@ static Op* start_op_write( return serializer->startEmplace<Op>(opCode, tf.remoteTypefaceID(), rec); } -SkStrikeClient::SkStrikeClient(SkTransport* transport) : fTransport{transport} { } +SkStrikeClient::SkStrikeClient(SkRemoteStrikeTransport* transport) : fTransport{transport} { } void SkStrikeClient::generateFontMetrics( const SkTypefaceProxy& typefaceProxy, diff --git a/src/core/SkRemoteGlyphCache.h b/src/core/SkRemoteGlyphCache.h index 021431e656..a655c74f65 100644 --- a/src/core/SkRemoteGlyphCache.h +++ b/src/core/SkRemoteGlyphCache.h @@ -25,11 +25,13 @@ #include "SkTypeface.h" #include "SkTypeface_remote.h" -class SkTransport { +class SkScalerContextRecDescriptor; + +class SkRemoteStrikeTransport { public: enum IOResult : bool {kFail = false, kSuccess = true}; - virtual ~SkTransport() {} + virtual ~SkRemoteStrikeTransport() {} virtual IOResult write(const void*, size_t) = 0; virtual std::tuple<size_t, IOResult> read(void*, size_t) = 0; IOResult writeSkData(const SkData&); @@ -90,25 +92,6 @@ private: } fDescriptor; }; -class SkRemoteGlyphCacheRenderer { -public: - void prepareSerializeProcs(SkSerialProcs* procs); - - SkScalerContext* generateScalerContext( - const SkScalerContextRecDescriptor& desc, SkFontID typefaceId); - -private: - sk_sp<SkData> encodeTypeface(SkTypeface* tf); - - SkTHashMap<SkFontID, sk_sp<SkTypeface>> fTypefaceMap; - - using DescriptorToContextMap = SkTHashMap<SkScalerContextRecDescriptor, - std::unique_ptr<SkScalerContext>, - SkScalerContextRecDescriptor::Hash>; - - DescriptorToContextMap fScalerContextMap; -}; - class SkStrikeCacheDifferenceSpec { class StrikeDifferences; @@ -145,7 +128,6 @@ private: DescMap fDescMap{16, DescHash(), DescEq()}; }; - class SkTextBlobCacheDiffCanvas : public SkNoDrawCanvas { public: SkTextBlobCacheDiffCanvas(int width, int height, @@ -179,35 +161,45 @@ private: SkStrikeCacheDifferenceSpec* const fStrikeCacheDiff; }; - class SkStrikeServer { public: - SkStrikeServer(SkTransport* transport); + SkStrikeServer(SkRemoteStrikeTransport* transport); - int serve(); - void prepareSerializeProcs(SkSerialProcs* procs) { - fRendererCache.prepareSerializeProcs(procs); - } + // embedding clients call these methods + int serve(); // very negotiable + void prepareSerializeProcs(SkSerialProcs* procs); + + // mostly called internally by Skia + SkScalerContext* generateScalerContext( + const SkScalerContextRecDescriptor& desc, SkFontID typefaceId); private: - SkTransport* const fTransport; - SkRemoteGlyphCacheRenderer fRendererCache; + using DescriptorToContextMap = SkTHashMap<SkScalerContextRecDescriptor, + std::unique_ptr<SkScalerContext>, + SkScalerContextRecDescriptor::Hash>; + + sk_sp<SkData> encodeTypeface(SkTypeface* tf); + + SkRemoteStrikeTransport* const fTransport; + SkTHashMap<SkFontID, sk_sp<SkTypeface>> fTypefaceMap; + DescriptorToContextMap fScalerContextMap; }; class SkStrikeClient { public: - SkStrikeClient(SkTransport*); + SkStrikeClient(SkRemoteStrikeTransport*); + + // embedding clients call these methods + void primeStrikeCache(const SkStrikeCacheDifferenceSpec&); + void prepareDeserializeProcs(SkDeserialProcs* procs); + + // mostly called internally by Skia void generateFontMetrics( const SkTypefaceProxy&, const SkScalerContextRec&, SkPaint::FontMetrics*); void generateMetricsAndImage( const SkTypefaceProxy&, const SkScalerContextRec&, SkArenaAlloc*, SkGlyph*); void generatePath( const SkTypefaceProxy&, const SkScalerContextRec&, SkGlyphID glyph, SkPath* path); - - void primeStrikeCache(const SkStrikeCacheDifferenceSpec&); - - void prepareDeserializeProcs(SkDeserialProcs* procs); - SkTypeface* lookupTypeface(SkFontID id); private: @@ -216,7 +208,7 @@ private: // TODO: Figure out how to manage the entries for the following maps. SkTHashMap<SkFontID, sk_sp<SkTypefaceProxy>> fMapIdToTypeface; - SkTransport* const fTransport; + SkRemoteStrikeTransport* const fTransport; }; #endif // SkRemoteGlyphCache_DEFINED diff --git a/tools/remote_demo.cpp b/tools/remote_demo.cpp index 0649ec9cbd..d572673bcf 100644 --- a/tools/remote_demo.cpp +++ b/tools/remote_demo.cpp @@ -25,8 +25,7 @@ static bool gUseGpu = true; static bool gPurgeFontCaches = true; static bool gUseProcess = true; - -class ReadWriteTransport : public SkTransport { +class ReadWriteTransport : public SkRemoteStrikeTransport { public: ReadWriteTransport(int readFd, int writeFd) : fReadFd{readFd}, fWriteFd{writeFd} {} ~ReadWriteTransport() override { @@ -56,10 +55,30 @@ private: fWriteFd; }; -static void prime_cache_spec(const SkIRect& bounds, - const SkSurfaceProps& props, - const SkPicture& pic, - SkStrikeCacheDifferenceSpec* strikeDifference) { +class Timer { +public: + void start() { + fStart = std::chrono::high_resolution_clock::now(); + } + + void stop() { + auto end = std::chrono::high_resolution_clock::now(); + fElapsedSeconds += end - fStart; + } + + double elapsedSeconds() { + return fElapsedSeconds.count(); + } + +private: + decltype(std::chrono::high_resolution_clock::now()) fStart; + std::chrono::duration<double> fElapsedSeconds{0.0}; +}; + +static void build_prime_cache_spec(const SkIRect &bounds, + const SkSurfaceProps &props, + const SkPicture &pic, + SkStrikeCacheDifferenceSpec *strikeDifference) { SkMatrix deviceMatrix = SkMatrix::I(); SkTextBlobCacheDiffCanvas filter( @@ -71,7 +90,7 @@ static void prime_cache_spec(const SkIRect& bounds, } static void final_draw(std::string outFilename, - SkTransport* transport, + SkRemoteStrikeTransport* transport, SkDeserialProcs* procs, SkData* picData, SkStrikeClient* client) { @@ -85,56 +104,26 @@ static void final_draw(std::string outFilename, auto c = s->getCanvas(); auto picUnderTest = SkPicture::MakeFromData(picData, procs); - SkMatrix deviceMatrix = SkMatrix::I(); - - SkStrikeCacheDifferenceSpec strikeDifference; - SkTextBlobCacheDiffCanvas filter( - r.width(), r.height(), deviceMatrix, s->props(), - SkScalerContextFlags::kFakeGammaAndBoostContrast, - &strikeDifference); - - if (client != nullptr) { - for (int i = 0; i < 0; i++) { - auto start = std::chrono::high_resolution_clock::now(); - - - SkStrikeCacheDifferenceSpec strikeDifference; - - prime_cache_spec(r, s->props(), *picUnderTest, &strikeDifference); - - client->primeStrikeCache(strikeDifference); - - auto end = std::chrono::high_resolution_clock::now(); - std::chrono::duration<double> elapsed_seconds = end - start; - (void)elapsed_seconds; - if (i == 0) { - std::cout << "filter time: " << elapsed_seconds.count() * 1e6 << std::endl; - } - } - } - - std::chrono::duration<double> total_seconds{0.0}; - for (int i = 0; i < 1; i++) { // 20 + Timer drawTime; + for (int i = 0; i < 100; i++) { if (gPurgeFontCaches) { SkGraphics::PurgeFontCache(); } - auto start = std::chrono::high_resolution_clock::now(); + drawTime.start(); if (client != nullptr) { SkStrikeCacheDifferenceSpec strikeDifference; - prime_cache_spec(r, s->props(), *picUnderTest, &strikeDifference); + build_prime_cache_spec(r, s->props(), *picUnderTest, &strikeDifference); client->primeStrikeCache(strikeDifference); } c->drawPicture(picUnderTest); - auto end = std::chrono::high_resolution_clock::now(); - std::chrono::duration<double> elapsed_seconds = end-start; - total_seconds += elapsed_seconds; + drawTime.stop(); } std::cout << "useProcess: " << gUseProcess << " useGPU: " << gUseGpu << " purgeCache: " << gPurgeFontCaches << std::endl; fprintf(stderr, "%s use GPU %s elapsed time %8.6f s\n", gSkpName.c_str(), - gUseGpu ? "true" : "false", total_seconds.count()); + gUseGpu ? "true" : "false", drawTime.elapsedSeconds()); auto i = s->makeImageSnapshot(); auto data = i->encodeToData(); @@ -144,19 +133,21 @@ static void final_draw(std::string outFilename, static void gpu(int readFd, int writeFd) { - ReadWriteTransport rwTransport{readFd, writeFd}; + if (gUseGpu) { + ReadWriteTransport rwTransport{readFd, writeFd}; - auto picData = rwTransport.readSkData(); - if (picData == nullptr) { - return; - } + auto picData = rwTransport.readSkData(); + if (picData == nullptr) { + return; + } - SkStrikeClient client{&rwTransport}; + SkStrikeClient client{&rwTransport}; - SkDeserialProcs procs; - client.prepareDeserializeProcs(&procs); + SkDeserialProcs procs; + client.prepareDeserializeProcs(&procs); - final_draw("test.png", &rwTransport, &procs, picData.get(), &client); + final_draw("test.png", &rwTransport, &procs, picData.get(), &client); + } printf("GPU is exiting\n"); } @@ -177,7 +168,7 @@ static int renderer( server.prepareSerializeProcs(&procs); stream = pic->serialize(&procs); - if (rwTransport.writeSkData(*stream) == SkTransport::kFail) { + if (rwTransport.writeSkData(*stream) == SkRemoteStrikeTransport::kFail) { return 1; } @@ -191,7 +182,6 @@ static int renderer( } } - int main(int argc, char** argv) { std::string skpName = argc > 1 ? std::string{argv[1]} : std::string{"skps/desk_nytimes.skp"}; int mode = argc > 2 ? atoi(argv[2]) : -1; |