1 /*
2 * Copyright 2019 Google LLC
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 "bench/Benchmark.h"
9
10 #include "include/core/SkDeferredDisplayListRecorder.h"
11 #include "include/core/SkSurfaceCharacterization.h"
12
create_characterization(GrContext * context)13 static SkSurfaceCharacterization create_characterization(GrContext* context) {
14 size_t maxResourceBytes = context->getResourceCacheLimit();
15
16 if (!context->colorTypeSupportedAsSurface(kRGBA_8888_SkColorType)) {
17 return SkSurfaceCharacterization();
18 }
19
20 SkImageInfo ii = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
21 kPremul_SkAlphaType, nullptr);
22
23 GrBackendFormat backendFormat = context->defaultBackendFormat(kRGBA_8888_SkColorType,
24 GrRenderable::kYes);
25 if (!backendFormat.isValid()) {
26 return SkSurfaceCharacterization();
27 }
28
29 SkSurfaceProps props(0x0, kUnknown_SkPixelGeometry);
30
31 SkSurfaceCharacterization c = context->threadSafeProxy()->createCharacterization(
32 maxResourceBytes, ii, backendFormat, 1,
33 kTopLeft_GrSurfaceOrigin, props, false);
34 return c;
35 }
36
37 // This benchmark tries to simulate how Viz is using SkDDLRecorders.
38 // For each config it will create a single DDLRecorder which it reuses for all the runs
39 // For each run it creates a DDL and stores it for later deletion.
40 class DDLRecorderBench : public Benchmark {
41 public:
DDLRecorderBench()42 DDLRecorderBench() { }
43
44 protected:
onGetName()45 const char* onGetName() override { return "DDLRecorder"; }
46
onDraw(int loops,SkCanvas * origCanvas)47 void onDraw(int loops, SkCanvas* origCanvas) override {
48 if (!fRecorder) {
49 return;
50 }
51
52 SkASSERT(!fDDLs.size());
53 fDDLs.reserve(loops);
54
55 for (int i = 0; i < loops; ++i) {
56 SkCanvas* recordingCanvas = fRecorder->getCanvas();
57
58 recordingCanvas->drawRect(SkRect::MakeWH(32, 32), SkPaint());
59
60 fDDLs.emplace_back(fRecorder->detach());
61 }
62 }
63
64 private:
65 // We create one DDLRecorder for all the timing runs and just keep reusing it
onPerCanvasPreDraw(SkCanvas * origCanvas)66 void onPerCanvasPreDraw(SkCanvas* origCanvas) override {
67 GrContext* context = origCanvas->getGrContext();
68 if (!context) {
69 return;
70 }
71
72 SkSurfaceCharacterization c = create_characterization(context);
73
74 fRecorder.reset(new SkDeferredDisplayListRecorder(c));
75 }
76
77 // We defer the clean up of the DDLs so it is done outside of the timing loop
onPostDraw(SkCanvas *)78 void onPostDraw(SkCanvas*) override {
79 fDDLs.clear();
80 }
81
82 std::unique_ptr<SkDeferredDisplayListRecorder> fRecorder = nullptr;
83 std::vector<std::unique_ptr<SkDeferredDisplayList>> fDDLs;
84
85 typedef Benchmark INHERITED;
86 };
87
88 DEF_BENCH(return new DDLRecorderBench();)
89