Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
ImageFilterDAGBench.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 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 "bench/Benchmark.h"
12#include "tools/DecodeUtils.h"
13#include "tools/Resources.h"
14
15#if defined(SK_GANESH)
18#endif
19
20#if defined(SK_GRAPHITE)
22#endif
23
24// Exercise a blur filter connected to 5 inputs of the same merge filter.
25// This bench shows an improvement in performance once cacheing of re-used
26// nodes is implemented, since the DAG is no longer flattened to a tree.
28public:
30
31protected:
32 const char* onGetName() override {
33 return "image_filter_dag";
34 }
35
36 void onDraw(int loops, SkCanvas* canvas) override {
37 const SkRect rect = SkRect::Make(SkIRect::MakeWH(400, 400));
38
39 // Set up the filters once, we're not interested in measuring allocation time here
40 sk_sp<SkImageFilter> blur(SkImageFilters::Blur(20.0f, 20.0f, nullptr));
41 sk_sp<SkImageFilter> inputs[kNumInputs];
42 for (int i = 0; i < kNumInputs; ++i) {
43 inputs[i] = blur;
44 }
46 paint.setImageFilter(SkImageFilters::Merge(inputs, kNumInputs));
47
48 // Only measure the filter computations done in drawRect()
49 // TODO (michaelludwig) - This benchmark, and the ones defined below, allocate their filters
50 // outside of the loop. This means that repeatedly drawing with the same filter will hit
51 // the global image filter cache inside the loop. Raster backend uses this cache so will see
52 // artificially improved performance. Ganesh will not because it uses a cache per filter
53 // call, so only within-DAG cache hits are measured (as desired). skbug:9297 wants to move
54 // raster backend to the same pattern, which will make the benchmark executions fair again.
55 for (int j = 0; j < loops; j++) {
56 canvas->drawRect(rect, paint);
57 }
58 }
59
60private:
61 static const int kNumInputs = 5;
62
63 using INHERITED = Benchmark;
64};
65
67public:
69
70protected:
71 const char* onGetName() override {
72 return "image_make_with_filter_dag";
73 }
74
75 void onDelayedSetup() override {
76 fImage = ToolUtils::GetResourceAsImage("images/mandrill_512.png");
77 }
78
79 void onDraw(int loops, SkCanvas* canvas) override {
80 SkIRect subset = SkIRect::MakeSize(fImage->dimensions());
82 SkIRect discardSubset;
83
84 // Set up the filters once so the allocation cost isn't included per-loop
85 sk_sp<SkImageFilter> blur(SkImageFilters::Blur(20.0f, 20.0f, nullptr));
86 sk_sp<SkImageFilter> inputs[kNumInputs];
87 for (int i = 0; i < kNumInputs; ++i) {
88 inputs[i] = blur;
89 }
90 sk_sp<SkImageFilter> mergeFilter = SkImageFilters::Merge(inputs, kNumInputs);
91
92 // But measure MakeWithFilter() per loop since that's the focus of this benchmark
93 for (int j = 0; j < loops; j++) {
95
96#if defined(SK_GANESH)
97 if (auto rContext = canvas->recordingContext()) {
98 image = SkImages::MakeWithFilter(rContext, fImage, mergeFilter.get(),
99 subset, subset, &discardSubset, &offset);
100 } else
101#endif
102#if defined(SK_GRAPHITE)
103 if (auto recorder = canvas->recorder()) {
104 image = SkImages::MakeWithFilter(recorder, fImage, mergeFilter.get(),
105 subset, subset, &discardSubset, &offset);
106 } else
107#endif
108 {
109 image = SkImages::MakeWithFilter(fImage, mergeFilter.get(),
110 subset, subset, &discardSubset, &offset);
111 }
112 }
113 }
114
115private:
116 static const int kNumInputs = 5;
117 sk_sp<SkImage> fImage;
118
119 using INHERITED = Benchmark;
120};
121
122// Exercise a blur filter connected to both inputs of an SkDisplacementMapEffect.
123
125public:
127
128protected:
129 const char* onGetName() override {
130 return "image_filter_displaced_blur";
131 }
132
133 void onDraw(int loops, SkCanvas* canvas) override {
134 // Setup filter once
135 sk_sp<SkImageFilter> blur(SkImageFilters::Blur(4.0f, 4.0f, nullptr));
136 SkScalar scale = 2;
137
140 scale, blur, blur));
141
142 SkRect rect = SkRect::Make(SkIRect::MakeWH(400, 400));
143
144 // As before, measure just the filter computation time inside the loops
145 for (int j = 0; j < loops; j++) {
146 canvas->drawRect(rect, paint);
147 }
148 }
149
150private:
151 using INHERITED = Benchmark;
152};
153
154// Exercise an Xfermode kSrcIn filter compositing two inputs which have a small intersection.
156public:
158
159protected:
160 const char* onGetName() override { return "image_filter_xfermode_in"; }
161
162 void onDraw(int loops, SkCanvas* canvas) override {
163 // Allocate filters once to avoid measuring instantiation time
164 auto blur = SkImageFilters::Blur(20.0f, 20.0f, nullptr);
165 auto offset1 = SkImageFilters::Offset(100.0f, 100.0f, blur);
166 auto offset2 = SkImageFilters::Offset(-100.0f, -100.0f, blur);
167 auto xfermode =
168 SkImageFilters::Blend(SkBlendMode::kSrcIn, offset1, offset2, nullptr);
169
171 paint.setImageFilter(xfermode);
172
173 // Measure only the filter time
174 for (int j = 0; j < loops; j++) {
175 canvas->drawRect(SkRect::MakeWH(200.0f, 200.0f), paint);
176 }
177 }
178
179private:
180 using INHERITED = Benchmark;
181};
182
#define DEF_BENCH(code)
Definition Benchmark.h:20
@ kSrcIn
r = s * da
const char * onGetName() override
void onDraw(int loops, SkCanvas *canvas) override
const char * onGetName() override
void onDraw(int loops, SkCanvas *canvas) override
void onDraw(int loops, SkCanvas *canvas) override
const char * onGetName() override
const char * onGetName() override
void onDraw(int loops, SkCanvas *canvas) override
void drawRect(const SkRect &rect, const SkPaint &paint)
virtual GrRecordingContext * recordingContext() const
virtual skgpu::graphite::Recorder * recorder() const
static sk_sp< SkImageFilter > Merge(sk_sp< SkImageFilter > *const filters, int count, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Blur(SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > DisplacementMap(SkColorChannel xChannelSelector, SkColorChannel yChannelSelector, SkScalar scale, sk_sp< SkImageFilter > displacement, sk_sp< SkImageFilter > color, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Blend(SkBlendMode mode, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground=nullptr, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Offset(SkScalar dx, SkScalar dy, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
SkISize dimensions() const
Definition SkImage.h:297
T * get() const
Definition SkRefCnt.h:303
const Paint & paint
sk_sp< SkImage > image
Definition examples.cpp:29
float SkScalar
Definition extension.cpp:12
SK_API sk_sp< SkImage > MakeWithFilter(sk_sp< SkImage > src, const SkImageFilter *filter, const SkIRect &subset, const SkIRect &clipBounds, SkIRect *outSubset, SkIPoint *offset)
sk_sp< SkImage > GetResourceAsImage(const char *resource)
Definition DecodeUtils.h:25
const Scalar scale
Point offset
static constexpr SkIPoint Make(int32_t x, int32_t y)
static constexpr SkIRect MakeSize(const SkISize &size)
Definition SkRect.h:66
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition SkRect.h:56
static SkRect Make(const SkISize &size)
Definition SkRect.h:669
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609