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