Flutter Engine
The Flutter Engine
ColorSpaceBench.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 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"
10#include "modules/skcms/skcms.h"
15
16#include <functional>
17
18enum class Mode {
19 kMultipleImage, // Transforms multiple images via one pipeline. (skcms doesn't support this.)
20 kSingleImage, // Transforms a single image at a time.
21 kSingleScanline, // Transforms an image scanline-by-scanline.
22};
23
24static const char* mode_name(Mode m) {
25 switch (m) {
26 case Mode::kMultipleImage: return "MultipleImage";
27 case Mode::kSingleImage: return "SingleImage";
28 case Mode::kSingleScanline: return "SingleScanline";
29 default: SkUNREACHABLE;
30 }
31}
32
34public:
36 fName = std::string("ColorSpace") + mode_name(fMode) + "Transform";
37 }
38
39protected:
40 const char* onGetName() override {
41 return fName.c_str();
42 }
43
44 bool isSuitableFor(Backend backend) override {
46 }
47
48 // Call before draw, allows the benchmark to do setup work outside of the
49 // timer. When a benchmark is repeatedly drawn, this should be called once
50 // before the initial draw.
51 void onDelayedSetup() override {
52 // Set the image buffer to solid white.
53 std::fill(std::begin(fSrcPixels), std::end(fSrcPixels), 0xFF);
54
55 // Create a conversion from sRGB to Adobe.
56 fSRGBCS = SkColorSpace::MakeSRGB();
58
59 fXformSteps = SkColorSpaceXformSteps(fSRGBCS.get(), kPremul_SkAlphaType,
60 fAdobeCS.get(), kPremul_SkAlphaType);
61
62 // Build up a pipeline.
63 fSrcCtx = SkRasterPipeline_MemoryCtx{fSrcPixels, kWidth};
64 fDstCtx = SkRasterPipeline_MemoryCtx{fDstPixels, kWidth};
65
66 fPipeline.append(SkRasterPipelineOp::load_8888, &fSrcCtx);
67 fXformSteps.apply(&fPipeline);
68 fPipeline.append(SkRasterPipelineOp::store_8888, &fDstCtx);
69
70 fConversionPipeline = fPipeline.compile();
71 }
72
73 void onDraw(int loops, SkCanvas* canvas) override {
74 switch (fMode) {
76 for (int i = 0; i < loops; i++) {
77 fConversionPipeline(0, 0, kWidth, kHeight);
78 }
79 break;
80
82 for (int i = 0; i < loops; i++) {
83 fPipeline.run(0, 0, kWidth, kHeight);
84 }
85 break;
86
88 for (int i = 0; i < loops; i++) {
89 for (int y = 0; y < kHeight; ++y) {
90 fPipeline.run(0, y, kWidth, 1);
91 }
92 }
93 break;
94 }
95 }
96
97private:
98 using INHERITED = Benchmark;
99
100 Mode fMode;
101 std::string fName;
102
103 sk_sp<SkColorSpace> fAdobeCS;
104 sk_sp<SkColorSpace> fSRGBCS;
105
106 SkRasterPipeline_<256> fPipeline;
109 SkColorSpaceXformSteps fXformSteps;
110
111 static constexpr int kWidth = 512;
112 static constexpr int kHeight = 512;
113 static constexpr int kBytesPerPixel = 4;
114 uint8_t fSrcPixels[kWidth * kHeight * kBytesPerPixel];
115 uint8_t fDstPixels[kWidth * kHeight * kBytesPerPixel];
116
117 std::function<void(size_t, size_t, size_t, size_t)> fConversionPipeline;
118};
119
121public:
123 fName = std::string("Skcms") + mode_name(fMode) + "Transform";
124 }
125
126protected:
127 const char* onGetName() override {
128 return fName.c_str();
129 }
130
133 }
134
135 // Call before draw, allows the benchmark to do setup work outside of the
136 // timer. When a benchmark is repeatedly drawn, this should be called once
137 // before the initial draw.
138 void onDelayedSetup() override {
139 // Set the image buffer to solid white. NANs/denorms might affect timing, but otherwise it
140 // doesn't really matter.
141 std::fill(std::begin(fSrcPixels), std::end(fSrcPixels), 0xFF);
142
143 // Create profiles for sRGB to Adobe.
144 SkColorSpace::MakeSRGB()->toProfile(&fSRGBProfile);
146 SkNamedGamut::kAdobeRGB)->toProfile(&fAdobeProfile);
147 }
148
149 void onDraw(int loops, SkCanvas* canvas) override {
150 switch (fMode) {
153
155 for (int i = 0; i < loops; i++) {
156 skcms_Transform(fSrcPixels,
159 &fSRGBProfile,
160 fDstPixels,
163 &fAdobeProfile,
164 kWidth * kHeight);
165 }
166 break;
167
169 for (int i = 0; i < loops; i++) {
170 uint8_t* src = fSrcPixels;
171 uint8_t* dst = fDstPixels;
172 for (int y = 0; y < kHeight; ++y) {
176 &fSRGBProfile,
177 dst,
180 &fAdobeProfile,
181 kWidth);
182 src += kWidth * kBytesPerPixel;
183 dst += kWidth * kBytesPerPixel;
184 }
185 }
186 break;
187 }
188 }
189
190private:
191 using INHERITED = Benchmark;
192
193 Mode fMode;
194 std::string fName;
195
196 skcms_ICCProfile fAdobeProfile;
197 skcms_ICCProfile fSRGBProfile;
198
199 static constexpr int kWidth = 512;
200 static constexpr int kHeight = 512;
201 static constexpr int kBytesPerPixel = 4;
202 uint8_t fSrcPixels[kWidth * kHeight * kBytesPerPixel];
203 uint8_t fDstPixels[kWidth * kHeight * kBytesPerPixel];
204};
205
#define DEF_BENCH(code)
Definition: Benchmark.h:20
@ kMultipleImage
@ kSingleImage
@ kSingleScanline
static const char * mode_name(Mode m)
const char * backend
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SkUNREACHABLE
Definition: SkAssert.h:135
void onDraw(int loops, SkCanvas *canvas) override
const char * onGetName() override
void onDelayedSetup() override
bool isSuitableFor(Backend backend) override
void toProfile(skcms_ICCProfile *) const
static sk_sp< SkColorSpace > MakeSRGB()
static sk_sp< SkColorSpace > MakeRGB(const skcms_TransferFunction &transferFn, const skcms_Matrix3x3 &toXYZ)
void run(size_t x, size_t y, size_t w, size_t h) const
void append(SkRasterPipelineOp, void *=nullptr)
std::function< void(size_t, size_t, size_t, size_t)> compile() const
const char * onGetName() override
bool isSuitableFor(Backend backend) override
void onDraw(int loops, SkCanvas *canvas) override
SkcmsTransformBench(Mode mode)
void onDelayedSetup() override
T * get() const
Definition: SkRefCnt.h:303
static const char * begin(const StringSlice &s)
Definition: editor.cpp:252
Dart_NativeFunction function
Definition: fuchsia.cc:51
double y
static constexpr skcms_Matrix3x3 kAdobeRGB
Definition: SkColorSpace.h:77
static constexpr skcms_TransferFunction k2Dot2
Definition: SkColorSpace.h:48
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
dst
Definition: cp.py:12
bool skcms_Transform(const void *src, skcms_PixelFormat srcFmt, skcms_AlphaFormat srcAlpha, const skcms_ICCProfile *srcProfile, void *dst, skcms_PixelFormat dstFmt, skcms_AlphaFormat dstAlpha, const skcms_ICCProfile *dstProfile, size_t nz)
Definition: skcms.cc:2495
@ skcms_PixelFormat_RGBA_8888
Definition: skcms_public.h:287
@ skcms_AlphaFormat_PremulAsEncoded
Definition: skcms_public.h:341
void apply(float rgba[4]) const
constexpr size_t kHeight
constexpr size_t kWidth