• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "samplecode/Sample.h"
12 #include <chrono>
13 
14 struct TimingSample : public Sample {
15     inline static constexpr int W = 24,
16                                 H = 16;
17     sk_sp<SkImage> fImg;
18 
nameTimingSample19     SkString name() override { return SkString("Timing"); }
20 
onOnceBeforeDrawTimingSample21     void onOnceBeforeDraw() override {
22         sk_sp<SkSurface> surf = SkSurface::MakeRasterN32Premul(W,H);
23         surf->getCanvas()->drawString("abc", 2,H-4, SkFont{}, SkPaint{});
24         fImg = surf->makeImageSnapshot();
25     }
26 
onDrawContentTimingSample27     void onDrawContent(SkCanvas* canvas) override {
28         canvas->scale(8,8);
29 
30         // Draw normally.
31         canvas->drawImage(fImg, 0,0);
32 
33         canvas->translate(0,H);
34 
35         // Draw one pixel at a time with drawImageRect(),
36         // timing how long each drawImageRect() call takes.
37         double cost[H][W];
38         double min = +INFINITY,
39                max = -INFINITY;
40         for (int y = 0; y < H; y++)
41         for (int x = 0; x < W; x++) {
42             auto start = std::chrono::steady_clock::now();
43             canvas->drawImageRect(fImg.get(),
44                                   SkRect::MakeXYWH(x,y,1,1), SkRect::MakeXYWH(x,y,1,1),
45                                   SkSamplingOptions(), /*paint=*/nullptr,
46                                   SkCanvas::kStrict_SrcRectConstraint);
47             auto elapsed = std::chrono::steady_clock::now() - start;
48 
49             cost[y][x] = elapsed.count();
50             min = std::min(min, cost[y][x]);
51             max = std::max(max, cost[y][x]);
52         }
53 
54         canvas->translate(0,H);
55 
56         // Draw using those per-pixel timings,
57         // with the slowest pixel scaled to alpha=1, the fastest to alpha=0.
58         for (int y = 0; y < H; y++)
59         for (int x = 0; x < W; x++) {
60             SkPaint p;
61             p.setAlphaf( (cost[y][x] - min) / (max - min) );
62             canvas->drawRect(SkRect::MakeXYWH(x,y,1,1), p);
63         }
64 
65         canvas->translate(0,H);
66 
67         // Draw each pixel into offscreen, timing each draw.
68         SkImageInfo info = canvas->imageInfo().makeWH(1024,1024);
69         if (sk_sp<SkSurface> offscreen = canvas->makeSurface(info)) {
70             min = +INFINITY;
71             max = -INFINITY;
72             for (int y = 0; y < H; y++)
73             for (int x = 0; x < W; x++) {
74                 auto start = std::chrono::steady_clock::now();
75                 offscreen->getCanvas()->drawImageRect(fImg,
76                                                       SkRect::MakeXYWH(x,y,1,1),
77                                                       SkRect::MakeXYWH(0,0,1024,1024),
78                                                       SkSamplingOptions(),
79                                                       /*paint=*/nullptr,
80                                                       SkCanvas::kStrict_SrcRectConstraint);
81                 auto elapsed = std::chrono::steady_clock::now() - start;
82 
83                 cost[y][x] = elapsed.count();
84                 min = std::min(min, cost[y][x]);
85                 max = std::max(max, cost[y][x]);
86             }
87             for (int y = 0; y < H; y++)
88             for (int x = 0; x < W; x++) {
89                 SkPaint p;
90                 p.setAlphaf( (cost[y][x] - min) / (max - min) );
91                 canvas->drawRect(SkRect::MakeXYWH(x,y,1,1), p);
92             }
93         }
94     }
95 };
96 DEF_SAMPLE( return new TimingSample; )
97