Skip to content

Commit

Permalink
SkRemoteGlyphCache Add tracing to diff canvas
Browse files Browse the repository at this point in the history
Use `extra_cflags=["-DSK_CAPTURE_DRAW_TEXT_BLOB"]` to enable.

Change-Id: I1d6db478ee91696cdce090647b889c17a83a2718
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/250259
Commit-Queue: Hal Canary <[email protected]>
Reviewed-by: Herb Derby <[email protected]>
  • Loading branch information
HalCanary authored and Skia Commit-Bot committed Oct 24, 2019
1 parent 96bce8f commit e107faa
Show file tree
Hide file tree
Showing 11 changed files with 468 additions and 9 deletions.
11 changes: 11 additions & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1765,6 +1765,17 @@ if (skia_enable_tools) {
}
}

if (!is_win) {
test_app("blob_cache_sim") {
sources = [
"tools/blob_cache_sim.cpp",
]
deps = [
":skia",
]
}
}

test_app("nanobench") {
sources = [
"bench/nanobench.cpp",
Expand Down
137 changes: 136 additions & 1 deletion bench/SkGlyphCacheBench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
* found in the LICENSE file.
*/


#include "src/core/SkStrike.h"

#include "bench/Benchmark.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkTypeface.h"
#include "src/core/SkRemoteGlyphCache.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkTaskGroup.h"
#include "src/core/SkTextBlobTrace.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"

static void do_font_stuff(SkFont* font) {
Expand Down Expand Up @@ -114,3 +116,136 @@ DEF_BENCH( return new SkGlyphCacheBasic(256 * 1024); )
DEF_BENCH( return new SkGlyphCacheBasic(32 * 1024 * 1024); )
DEF_BENCH( return new SkGlyphCacheStressTest(256 * 1024); )
DEF_BENCH( return new SkGlyphCacheStressTest(32 * 1024 * 1024); )

namespace {
class DiscardableManager : public SkStrikeServer::DiscardableHandleManager,
public SkStrikeClient::DiscardableHandleManager {
public:
DiscardableManager() { sk_bzero(&fCacheMissCount, sizeof(fCacheMissCount)); }
~DiscardableManager() override = default;

// Server implementation.
SkDiscardableHandleId createHandle() override {
SkAutoMutexExclusive l(fMutex);

// Handles starts as locked.
fLockedHandles.add(++fNextHandleId);
return fNextHandleId;
}
bool lockHandle(SkDiscardableHandleId id) override {
SkAutoMutexExclusive l(fMutex);

if (id <= fLastDeletedHandleId) return false;
fLockedHandles.add(id);
return true;
}

// Client implementation.
bool deleteHandle(SkDiscardableHandleId id) override {
SkAutoMutexExclusive l(fMutex);

return id <= fLastDeletedHandleId;
}

void notifyCacheMiss(SkStrikeClient::CacheMissType type) override {
SkAutoMutexExclusive l(fMutex);

fCacheMissCount[type]++;
}
bool isHandleDeleted(SkDiscardableHandleId id) override {
SkAutoMutexExclusive l(fMutex);

return id <= fLastDeletedHandleId;
}

void unlockAll() {
SkAutoMutexExclusive l(fMutex);

fLockedHandles.reset();
}
void unlockAndDeleteAll() {
SkAutoMutexExclusive l(fMutex);

fLockedHandles.reset();
fLastDeletedHandleId = fNextHandleId;
}
const SkTHashSet<SkDiscardableHandleId>& lockedHandles() const {
SkAutoMutexExclusive l(fMutex);

return fLockedHandles;
}
SkDiscardableHandleId handleCount() {
SkAutoMutexExclusive l(fMutex);

return fNextHandleId;
}
int cacheMissCount(uint32_t type) {
SkAutoMutexExclusive l(fMutex);

return fCacheMissCount[type];
}
bool hasCacheMiss() const {
SkAutoMutexExclusive l(fMutex);

for (uint32_t i = 0; i <= SkStrikeClient::CacheMissType::kLast; ++i) {
if (fCacheMissCount[i] > 0) return true;
}
return false;
}
void resetCacheMissCounts() {
SkAutoMutexExclusive l(fMutex);
sk_bzero(&fCacheMissCount, sizeof(fCacheMissCount));
}

private:
// The tests below run in parallel on multiple threads and use the same
// process global SkStrikeCache. So the implementation needs to be
// thread-safe.
mutable SkMutex fMutex;

SkDiscardableHandleId fNextHandleId = 0u;
SkDiscardableHandleId fLastDeletedHandleId = 0u;
SkTHashSet<SkDiscardableHandleId> fLockedHandles;
int fCacheMissCount[SkStrikeClient::CacheMissType::kLast + 1u];
};


class SkDiffCanvasBench : public Benchmark {
std::string fBenchName;
std::string fTraceName;
std::vector<SkTextBlobTrace::Record> fTrace;
sk_sp<DiscardableManager> fDiscardableManager;
SkTLazy<SkStrikeServer> fServer;

const char* onGetName() override { return fBenchName.c_str(); }

bool isSuitableFor(Backend b) override { return b == kNonRendering_Backend; }

void onDraw(int loops, SkCanvas*) override {
const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
SkTextBlobCacheDiffCanvas canvas{1024, 1024, props, fServer.get()};
loops *= 100;
while (loops --> 0) {
for (const auto& record : fTrace) {
canvas.drawTextBlob(
record.blob.get(), record.offset.x(), record.offset.y(),record.paint);
}
}
}

void onDelayedSetup() override {
auto resource = std::string("diff_canvas_traces/") + fTraceName + ".trace";
auto stream = GetResourceAsStream(resource.c_str());
fDiscardableManager = sk_make_sp<DiscardableManager>();
fServer.init(fDiscardableManager.get());
fTrace = SkTextBlobTrace::CreateBlobTrace(stream.get());
}

public:
SkDiffCanvasBench(const std::string& trace)
: fBenchName(std::string("SkDiffBench-") + trace)
, fTraceName(trace) {}
};
} // namespace

DEF_BENCH( return new SkDiffCanvasBench{"lorem_ipsum"});
2 changes: 2 additions & 0 deletions gn/core.gni
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@ skia_core_sources = [
"$_src/core/SkTDynamicHash.h",
"$_src/core/SkTextBlob.cpp",
"$_src/core/SkTextBlobPriv.h",
"$_src/core/SkTextBlobTrace.cpp",
"$_src/core/SkTextBlobTrace.h",
"$_src/core/SkTextFormatParams.h",
"$_src/core/SkTime.cpp",
"$_src/core/SkTInternalLList.h",
Expand Down
Binary file added resources/diff_canvas_traces/lorem_ipsum.trace
Binary file not shown.
2 changes: 2 additions & 0 deletions src/core/SkFontPriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ class SkFontPriv {

static void Flatten(const SkFont&, SkWriteBuffer& buffer);
static bool Unflatten(SkFont*, SkReadBuffer& buffer);

static inline uint8_t Flags(const SkFont& font) { return font.fFlags; }
};

class SkAutoToGlyphs {
Expand Down
42 changes: 35 additions & 7 deletions src/core/SkRemoteGlyphCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,12 +331,20 @@ class SkTextBlobCacheDiffCanvas::TrackLayerDevice final : public SkNoPixelsDevic
cinfo.fInfo.refColorSpace(), fDFTSupport);
}

SkStrikeServer* strikeServer() { return fStrikeServer; }

protected:
void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override {
#if SK_SUPPORT_GPU
GrTextContext::Options options;
GrTextContext::SanitizeOptions(&options);

#ifdef SK_CAPTURE_DRAW_TEXT_BLOB
if (SkTextBlobTrace::Capture* capture = fStrikeServer->fCapture.get()) {
capture->capture(glyphRunList);
}
#endif // SK_CAPTURE_DRAW_TEXT_BLOB

fPainter.processGlyphRunList(glyphRunList,
this->localToDevice(),
this->surfaceProps(),
Expand Down Expand Up @@ -364,13 +372,27 @@ SkTextBlobCacheDiffCanvas::SkTextBlobCacheDiffCanvas(int width, int height,
SkStrikeServer* strikeServer,
sk_sp<SkColorSpace> colorSpace,
bool DFTSupport)
: SkNoDrawCanvas{sk_make_sp<TrackLayerDevice>(SkIRect::MakeWH(width, height),
props,
strikeServer,
std::move(colorSpace),
DFTSupport)} { }
: SkNoDrawCanvas{sk_make_sp<TrackLayerDevice>(SkIRect::MakeWH(width, height),
props,
strikeServer,
std::move(colorSpace),
DFTSupport)} {
#ifdef SK_CAPTURE_DRAW_TEXT_BLOB
if (!strikeServer->fCapture) {
strikeServer->fCapture.reset(new SkTextBlobTrace::Capture);
}
#endif // SK_CAPTURE_DRAW_TEXT_BLOB
}

SkTextBlobCacheDiffCanvas::~SkTextBlobCacheDiffCanvas() = default;
SkTextBlobCacheDiffCanvas::~SkTextBlobCacheDiffCanvas() {
#ifdef SK_CAPTURE_DRAW_TEXT_BLOB
SkTextBlobTrace::Capture* capture =
((TrackLayerDevice*)this->getTopDevice())->strikeServer()->fCapture.get();
if (capture) {
capture->dump();
}
#endif // SK_CAPTURE_DRAW_TEXT_BLOB
}

SkCanvas::SaveLayerStrategy SkTextBlobCacheDiffCanvas::getSaveLayerStrategy(
const SaveLayerRec& rec) {
Expand Down Expand Up @@ -404,7 +426,13 @@ SkStrikeServer::SkStrikeServer(DiscardableHandleManager* discardableHandleManage
SkASSERT(fDiscardableHandleManager);
}

SkStrikeServer::~SkStrikeServer() = default;
SkStrikeServer::~SkStrikeServer() {
#ifdef SK_CAPTURE_DRAW_TEXT_BLOB
if (fCapture) {
fCapture->dump();
}
#endif // SK_CAPTURE_DRAW_TEXT_BLOB
}

sk_sp<SkData> SkStrikeServer::serializeTypeface(SkTypeface* tf) {
auto* data = fSerializedTypefaces.find(SkTypeface::UniqueID(tf));
Expand Down
11 changes: 11 additions & 0 deletions src/core/SkRemoteGlyphCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
#ifndef SkRemoteGlyphCache_DEFINED
#define SkRemoteGlyphCache_DEFINED

// Use `extra_cflags=["-DSK_CAPTURE_DRAW_TEXT_BLOB"]` to capture traces to disc.

// Or uncomment this line:
//#define SK_CAPTURE_DRAW_TEXT_BLOB

#include <memory>
#include <tuple>
#include <unordered_map>
Expand All @@ -24,6 +29,7 @@
#include "src/core/SkMakeUnique.h"
#include "src/core/SkStrikeForGPU.h"
#include "src/core/SkTLazy.h"
#include "src/core/SkTextBlobTrace.h"

class Deserializer;
class Serializer;
Expand Down Expand Up @@ -126,6 +132,11 @@ class SkStrikeServer final : public SkStrikeForGPUCacheInterface {
}
size_t remoteStrikeMapSizeForTesting() const { return fDescToRemoteStrike.size(); }

#ifdef SK_CAPTURE_DRAW_TEXT_BLOB
// DrawTextBlob trace capture.
std::unique_ptr<SkTextBlobTrace::Capture> fCapture;
#endif // SK_CAPTURE_DRAW_TEXT_BLOB

private:
static constexpr size_t kMaxEntriesInDescriptorMap = 2000u;

Expand Down
Loading

0 comments on commit e107faa

Please sign in to comment.