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