xref: /aosp_15_r20/external/skia/tools/blob_cache_sim.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2019 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "include/core/SkCanvas.h"
9 #include "include/core/SkColor.h"
10 #include "include/core/SkFontMgr.h"
11 #include "include/core/SkStream.h"
12 #include "include/core/SkSurface.h"
13 #include "include/encode/SkPngEncoder.h"
14 #include "include/private/chromium/SkChromeRemoteGlyphCache.h"
15 #include "src/core/SkScalerContext.h"
16 #include "tools/text/SkTextBlobTrace.h"
17 
18 #include <iostream>
19 #include <string>
20 #include <unordered_map>
21 #include <vector>
22 
main(int argc,char ** argv)23 int main(int argc, char** argv) {
24     std::unordered_map<uint64_t, uint32_t> counts;
25     size_t total = 0;
26 
27     for (int i = 1; i < argc; i++) {
28         const char* filename = argv[i];
29 
30         SkFILEStream in{filename};
31         std::vector<SkTextBlobTrace::Record> trace = SkTextBlobTrace::CreateBlobTrace(&in, nullptr);
32         for (const SkTextBlobTrace::Record& record : trace) {
33             total++;
34             const SkPaint paint = record.paint;
35             bool fastByPass = paint.getStyle() == SkPaint::kFill_Style
36                     && paint.getPathEffect() == nullptr
37                     && paint.getMaskFilter() == nullptr;
38             if (fastByPass) {
39                 uint64_t blobID = record.origUniqueID;
40                 SkPoint offset = record.offset;
41                 SkColor c = SkMaskGamma::CanonicalColor(paint.getColor());
42                 uint32_t colorBits =
43                         (SkColorGetR(c) >> 5u) << 6u
44                       | (SkColorGetG(c) >> 5u) << 3u
45                       |  SkColorGetB(c) >> 5u;
46 
47                 SkFixed fx = (SkScalarToFixed(offset.x()) >> 13) & 7;
48                 SkFixed fy = (SkScalarToFixed(offset.y()) >> 13) & 7;
49                 uint32_t posBits = (fx << 3 | fy) << 12;
50 
51                 uint64_t blobKey = blobID << 32u | posBits | colorBits;
52                 auto lookup = counts.find(blobKey);
53                 if (lookup == counts.end()) {
54                     bool ok;
55                     std::tie(lookup, ok) = counts.insert({blobKey, 0});
56                     SkASSERT(ok);
57                 }
58                 lookup->second += 1;
59                 std::cout << std::hex << blobKey << "\n";
60             }
61         }
62         std::cerr << "trace: " << filename
63                   << " unique: " << counts.size()
64                   << " all: " << total
65                   << " ratio: " << (float)total/counts.size() << "\n";
66 
67         SkRect bounds = {0, 0, 0, 0};
68         for (const SkTextBlobTrace::Record& record : trace) {
69             bounds.join(record.blob->bounds().makeOffset(record.offset.x(), record.offset.y()));
70         }
71         SkIRect iBounds = bounds.roundOut();
72         if (iBounds.size().isEmpty()) {
73             continue;
74         }
75         static constexpr SkColor kBackground = SK_ColorWHITE;
76         sk_sp<SkSurface> surf = SkSurfaces::Raster(
77                 SkImageInfo::MakeN32Premul(iBounds.width() + 16, iBounds.height() + 16));
78         SkCanvas* canvas = surf->getCanvas();
79         canvas->translate(8.0f - iBounds.x(), 8.0f - iBounds.y());
80         canvas->clear(kBackground);
81 
82         for (const SkTextBlobTrace::Record& record : trace) {
83             canvas->drawTextBlob(
84                     record.blob.get(), record.offset.x(), record.offset.y(), record.paint);
85         }
86 
87         sk_sp<SkImage> img(surf->makeImageSnapshot());
88         if (img) {
89             sk_sp<SkData> png = SkPngEncoder::Encode(nullptr, img.get(), {});
90             if (png) {
91                 SkString path = SkStringPrintf("text_blob_trace_%04d.png", i);
92                 SkFILEWStream(path.c_str()).write(png->data(), png->size());
93             }
94         }
95     }
96     return 0;
97 }
98