diff options
author | Herb Derby <herb@google.com> | 2018-03-15 17:34:40 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-03-16 20:28:36 +0000 |
commit | 76d69b44bbba118a6769b5fb267588ccac41a815 (patch) | |
tree | 2fdb871fb4f7ae9b00721661cd3fa361ba4cbfbd /tools/remote_demo.cpp | |
parent | 7278d68cac9e39970144909df449113d43fff480 (diff) |
Apply filterTextFlags so the fonts are the same.
In order to apply filterTextFlags correctly, teach
TrackLayerDevice how to process save and restore layers.
At this point, I don't see any other traffic than the
cache warming traffic.
This code has a performance between 82% and 105% of just
drawing the picture.
BUG=skia:7515
Change-Id: I44736be46884f18b6d120d4b5ca582f34dbdff0f
Reviewed-on: https://skia-review.googlesource.com/114641
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Herb Derby <herb@google.com>
Diffstat (limited to 'tools/remote_demo.cpp')
-rw-r--r-- | tools/remote_demo.cpp | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/tools/remote_demo.cpp b/tools/remote_demo.cpp index b8cfdc76f7..8ff7d2986d 100644 --- a/tools/remote_demo.cpp +++ b/tools/remote_demo.cpp @@ -21,6 +21,7 @@ #include "SkTextBlobRunIterator.h" #include "SkGlyphCache.h" #include "SkDrawFilter.h" +#include "SkDevice.h" #include <type_traits> #include <chrono> @@ -51,8 +52,13 @@ static bool gUseGpu = true; static bool gPurgeFontCaches = true; static bool gUseProcess = true; +static int gFontMetrics; +static int gMetricsImage; +static int gPath; + enum direction : int {kRead = 0, kWrite = 1}; +#define INSTRUMENT 0 template <typename T> class SkArraySlice : public std::tuple<const T*, size_t> { @@ -300,6 +306,18 @@ public: }; }; + +class TrackLayerDevice : public SkNoPixelsDevice { +public: + TrackLayerDevice(const SkIRect& bounds, const SkSurfaceProps& props) + : SkNoPixelsDevice(bounds, props) { } + SkBaseDevice* onCreateDevice(const CreateInfo& cinfo, const SkPaint*) override { + const SkSurfaceProps surfaceProps(this->surfaceProps().flags(), cinfo.fPixelGeometry); + return new TrackLayerDevice(this->getGlobalBounds(), surfaceProps); + } +}; + + class TextBlobFilterCanvas : public SkNoDrawCanvas { public: struct StrikeSpec { @@ -323,7 +341,7 @@ public: const SkMatrix& deviceMatrix, const SkSurfaceProps& props, SkScalerContextFlags flags) - : SkNoDrawCanvas(width, height) + : SkNoDrawCanvas{new TrackLayerDevice{SkIRect::MakeWH(width, height), props}} , fDeviceMatrix{deviceMatrix} , fSurfaceProps{props} , fScalerContextFlags{flags} { } @@ -422,6 +440,10 @@ public: protected: + SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override { + return kFullLayer_SaveLayerStrategy; + } + void onDrawTextBlob( const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) override { @@ -433,6 +455,7 @@ protected: // applyFontToPaint() always overwrites the exact same attributes, // so it is safe to not re-seed the paint for this reason. it.applyFontToPaint(&runPaint); + runPaint.setFlags(this->getTopDevice()->filterTextFlags(runPaint)); if (auto looper = runPaint.getLooper()) { this->processLooper(position, it, runPaint, looper, this); } else { @@ -441,6 +464,16 @@ protected: } } + void onDrawText(const void*, size_t, SkScalar, SkScalar, const SkPaint&) override { + SK_ABORT("DrawText"); + } + void onDrawPosText(const void*, size_t, const SkPoint[], const SkPaint&) override { + SK_ABORT("DrawPosText"); + } + void onDrawPosTextH(const void*, size_t, const SkScalar[], SkScalar, const SkPaint&) override { + SK_ABORT("DrawPosTextH"); + } + private: using PosFn = SkPoint(*)(int index, const SkScalar* pos); using MapFn = SkPoint(*)(const SkMatrix& m, SkPoint pt); @@ -633,13 +666,14 @@ public: void generateFontMetrics(const SkTypefaceProxy& tf, const SkScalerContextRec& rec, SkPaint::FontMetrics* metrics) override { + gFontMetrics += 1; //SK_ABORT("generateFontMetrics should not be called."); // Send generateFontMetrics Op* op = this->startOpWrite(OpCode::kFontMetrics, tf, rec); fTransport->endWrite(); -#if 1 +#if INSTRUMENT SkScalerContextRecDescriptor rd{rec}; std::cout << " metrics font op rec tf: " << rec.fFontID << " tf id: " << tf.fontID() @@ -656,15 +690,16 @@ public: const SkScalerContextRec& rec, SkArenaAlloc* alloc, SkGlyph* glyph) override { + gMetricsImage += 1; //SK_ABORT("generateMetricsAndImage should not be called."); // Send generateMetricsAndImage SkScalerContextRecDescriptor rd{rec}; -#if 1 +#if INSTRUMENT std::cout << " metrics image op rec tf: " << rec.fFontID << " tf id: " << tf.fontID() << " rec: " << rd.desc().getChecksum() - << " glyphid: " << glyph->getPackedID().getPackedID() + << " glyphid: " << glyph->getPackedID().getPackedID() << "\n" << rec.dump().c_str() << std::endl; #endif Op* op = this->startOpWrite(OpCode::kGlyphMetricsAndImage, tf, rec); @@ -690,6 +725,7 @@ public: void generatePath(const SkTypefaceProxy& tf, const SkScalerContextRec& rec, SkGlyphID glyph, SkPath* path) override { + gPath += 1; // Send generatePath SkScalerContextRecDescriptor rd{rec}; @@ -722,7 +758,7 @@ static void prepopulate_cache( sk_sp<SkPicture> pic, TextBlobFilterCanvas* filter) { - filter->drawPicture(pic); + pic->playback(filter); transport->startEmplace<Op>(OpCode::kPrepopulateCache, SkFontID{0}, SkScalerContextRec{}); @@ -747,7 +783,7 @@ static void prepopulate_cache( }; strike = SkGlyphCache::CreateStrikeExclusive(*desc,creator); } -#if 1 +#if INSTRUMENT std::cout << std::hex << "prepop cache " << (intptr_t)cache << " desc: " << desc->getChecksum() << " typeface id: " << tf->uniqueID() @@ -771,7 +807,9 @@ static void prepopulate_cache( // needed for font metrics mistake. Transport in = Transport::DoubleBuffer(*transport); +#if INSTRUMENT SkDebugf("========= Sending prep cache ========\n"); +#endif in.startRead(); filter->readDataFromTransport(&in, perStrike, perGlyph, finishStrike); @@ -797,7 +835,8 @@ static void final_draw(std::string outFilename, SkMatrix deviceMatrix = SkMatrix::I(); // kFakeGammaAndBoostContrast TextBlobFilterCanvas filter( - r.width(), r.height(), deviceMatrix, s->props(), SkScalerContextFlags::kFakeGammaAndBoostContrast); + r.width(), r.height(), deviceMatrix, s->props(), + SkScalerContextFlags::kFakeGammaAndBoostContrast); if (cache != nullptr) { for (int i = 0; i < 0; i++) { @@ -815,7 +854,7 @@ static void final_draw(std::string outFilename, } std::chrono::duration<double> total_seconds{0.0}; - for (int i = 0; i < 1; i++) { // 20 + for (int i = 0; i < 100; i++) { // 20 if (gPurgeFontCaches) { SkGraphics::PurgeFontCache(); } @@ -860,6 +899,10 @@ static void gpu(int readFd, int writeFd) { rc.prepareDeserializeProcs(&procs); final_draw("test.png", &transport, &procs, picData.get(), &rc); + + if (gFontMetrics + gMetricsImage + gPath > 0) { + fprintf(stderr, "exceptions - fm: %d mi: %d p: %d\n", gFontMetrics, gMetricsImage, gPath); + } } static int renderer( |