xref: /aosp_15_r20/external/skia/tools/viewer/TimingSlide.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2020 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/SkFont.h"
10 #include "include/core/SkSurface.h"
11 #include "tools/fonts/FontToolUtils.h"
12 #include "tools/viewer/Slide.h"
13 
14 #include <chrono>
15 
16 class TimingSlide : public Slide {
17 public:
TimingSlide()18     TimingSlide() { fName = "Timing";}
19 
load(SkScalar w,SkScalar h)20     void load(SkScalar w, SkScalar h) override {
21         sk_sp<SkSurface> surf = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(W, H));
22         surf->getCanvas()->drawString("abc", 2,H-4, ToolUtils::DefaultFont(), SkPaint{});
23         fImg = surf->makeImageSnapshot();
24     }
25 
draw(SkCanvas * canvas)26     void draw(SkCanvas* canvas) override {
27         canvas->scale(8,8);
28 
29         // Draw normally.
30         canvas->drawImage(fImg, 0,0);
31 
32         canvas->translate(0,H);
33 
34         // Draw one pixel at a time with drawImageRect(),
35         // timing how long each drawImageRect() call takes.
36         double cost[H][W];
37         double min = +INFINITY,
38                max = -INFINITY;
39         for (int y = 0; y < H; y++)
40         for (int x = 0; x < W; x++) {
41             auto start = std::chrono::steady_clock::now();
42             canvas->drawImageRect(fImg.get(),
43                                   SkRect::MakeXYWH(x,y,1,1), SkRect::MakeXYWH(x,y,1,1),
44                                   SkSamplingOptions(), /*paint=*/nullptr,
45                                   SkCanvas::kStrict_SrcRectConstraint);
46             auto elapsed = std::chrono::steady_clock::now() - start;
47 
48             cost[y][x] = elapsed.count();
49             min = std::min(min, cost[y][x]);
50             max = std::max(max, cost[y][x]);
51         }
52 
53         canvas->translate(0,H);
54 
55         // Draw using those per-pixel timings,
56         // with the slowest pixel scaled to alpha=1, the fastest to alpha=0.
57         for (int y = 0; y < H; y++)
58         for (int x = 0; x < W; x++) {
59             SkPaint p;
60             p.setAlphaf( (cost[y][x] - min) / (max - min) );
61             canvas->drawRect(SkRect::MakeXYWH(x,y,1,1), p);
62         }
63 
64         canvas->translate(0,H);
65 
66         // Draw each pixel into offscreen, timing each draw.
67         SkImageInfo info = canvas->imageInfo().makeWH(1024,1024);
68         if (sk_sp<SkSurface> offscreen = canvas->makeSurface(info)) {
69             min = +INFINITY;
70             max = -INFINITY;
71             for (int y = 0; y < H; y++)
72             for (int x = 0; x < W; x++) {
73                 auto start = std::chrono::steady_clock::now();
74                 offscreen->getCanvas()->drawImageRect(fImg,
75                                                       SkRect::MakeXYWH(x,y,1,1),
76                                                       SkRect::MakeXYWH(0,0,1024,1024),
77                                                       SkSamplingOptions(),
78                                                       /*paint=*/nullptr,
79                                                       SkCanvas::kStrict_SrcRectConstraint);
80                 auto elapsed = std::chrono::steady_clock::now() - start;
81 
82                 cost[y][x] = elapsed.count();
83                 min = std::min(min, cost[y][x]);
84                 max = std::max(max, cost[y][x]);
85             }
86             for (int y = 0; y < H; y++)
87             for (int x = 0; x < W; x++) {
88                 SkPaint p;
89                 p.setAlphaf( (cost[y][x] - min) / (max - min) );
90                 canvas->drawRect(SkRect::MakeXYWH(x,y,1,1), p);
91             }
92         }
93     }
94 private:
95     inline static constexpr int W = 24,
96                                 H = 16;
97     sk_sp<SkImage> fImg;
98 };
99 
100 DEF_SLIDE( return new TimingSlide; )
101