• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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