1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "bench/Benchmark.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "include/core/SkString.h"
11cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h"
12cb93a386Sopenharmony_ci#include "include/private/SkHalf.h"
13cb93a386Sopenharmony_ci#include "src/core/SkColorSpacePriv.h"
14cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h"
15cb93a386Sopenharmony_ci#include "src/gpu/GrGeometryProcessor.h"
16cb93a386Sopenharmony_ci#include "src/gpu/GrMemoryPool.h"
17cb93a386Sopenharmony_ci#include "src/gpu/GrProgramInfo.h"
18cb93a386Sopenharmony_ci#include "src/gpu/SkGr.h"
19cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
20cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
21cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVarying.h"
22cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
23cb93a386Sopenharmony_ci#include "src/gpu/ops/GrMeshDrawOp.h"
24cb93a386Sopenharmony_ci#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
25cb93a386Sopenharmony_ci#include "src/gpu/v1/SurfaceDrawContext_v1.h"
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_cinamespace {
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_cienum Mode {
30cb93a386Sopenharmony_ci    kBaseline_Mode,  // Do the wrong thing, but quickly.
31cb93a386Sopenharmony_ci    kFloat_Mode,     // Transform colors on CPU, use float4 attributes.
32cb93a386Sopenharmony_ci    kHalf_Mode,      // Transform colors on CPU, use half4 attributes.
33cb93a386Sopenharmony_ci    kShader_Mode,    // Use ubyte4 attributes, transform colors on GPU (vertex shader).
34cb93a386Sopenharmony_ci};
35cb93a386Sopenharmony_ci
36cb93a386Sopenharmony_ciclass GP : public GrGeometryProcessor {
37cb93a386Sopenharmony_cipublic:
38cb93a386Sopenharmony_ci    static GrGeometryProcessor* Make(SkArenaAlloc* arena, Mode mode,
39cb93a386Sopenharmony_ci                                     sk_sp<GrColorSpaceXform> colorSpaceXform) {
40cb93a386Sopenharmony_ci        return arena->make([&](void* ptr) {
41cb93a386Sopenharmony_ci            return new (ptr) GP(mode, std::move(colorSpaceXform));
42cb93a386Sopenharmony_ci        });
43cb93a386Sopenharmony_ci    }
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_ci    const char* name() const override { return "VertexColorXformGP"; }
46cb93a386Sopenharmony_ci
47cb93a386Sopenharmony_ci    std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override {
48cb93a386Sopenharmony_ci        class Impl : public ProgramImpl {
49cb93a386Sopenharmony_ci        public:
50cb93a386Sopenharmony_ci            void setData(const GrGLSLProgramDataManager& pdman,
51cb93a386Sopenharmony_ci                         const GrShaderCaps&,
52cb93a386Sopenharmony_ci                         const GrGeometryProcessor& geomProc) override {
53cb93a386Sopenharmony_ci                const GP& gp = geomProc.cast<GP>();
54cb93a386Sopenharmony_ci                fColorSpaceHelper.setData(pdman, gp.fColorSpaceXform.get());
55cb93a386Sopenharmony_ci            }
56cb93a386Sopenharmony_ci
57cb93a386Sopenharmony_ci        private:
58cb93a386Sopenharmony_ci            void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
59cb93a386Sopenharmony_ci                const GP& gp = args.fGeomProc.cast<GP>();
60cb93a386Sopenharmony_ci                GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
61cb93a386Sopenharmony_ci                GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
62cb93a386Sopenharmony_ci                GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
63cb93a386Sopenharmony_ci                GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
64cb93a386Sopenharmony_ci
65cb93a386Sopenharmony_ci                varyingHandler->emitAttributes(gp);
66cb93a386Sopenharmony_ci
67cb93a386Sopenharmony_ci                // Setup color
68cb93a386Sopenharmony_ci                GrGLSLVarying varying(kHalf4_GrSLType);
69cb93a386Sopenharmony_ci                varyingHandler->addVarying("color", &varying);
70cb93a386Sopenharmony_ci                vertBuilder->codeAppendf("half4 color = %s;", gp.fInColor.name());
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_ci                if (kShader_Mode == gp.fMode) {
73cb93a386Sopenharmony_ci                    fColorSpaceHelper.emitCode(uniformHandler, gp.fColorSpaceXform.get(),
74cb93a386Sopenharmony_ci                                               kVertex_GrShaderFlag);
75cb93a386Sopenharmony_ci                    SkString xformedColor;
76cb93a386Sopenharmony_ci                    vertBuilder->appendColorGamutXform(&xformedColor, "color", &fColorSpaceHelper);
77cb93a386Sopenharmony_ci                    vertBuilder->codeAppendf("color = %s;", xformedColor.c_str());
78cb93a386Sopenharmony_ci                    vertBuilder->codeAppend("color = half4(color.rgb * color.a, color.a);");
79cb93a386Sopenharmony_ci                }
80cb93a386Sopenharmony_ci
81cb93a386Sopenharmony_ci                vertBuilder->codeAppendf("%s = color;", varying.vsOut());
82cb93a386Sopenharmony_ci                fragBuilder->codeAppendf("half4 %s = %s;", args.fOutputColor, varying.fsIn());
83cb93a386Sopenharmony_ci
84cb93a386Sopenharmony_ci                // Position
85cb93a386Sopenharmony_ci                WriteOutputPosition(args.fVertBuilder, gpArgs, gp.fInPosition.name());
86cb93a386Sopenharmony_ci
87cb93a386Sopenharmony_ci                // Coverage
88cb93a386Sopenharmony_ci                fragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
89cb93a386Sopenharmony_ci            }
90cb93a386Sopenharmony_ci
91cb93a386Sopenharmony_ci            GrGLSLColorSpaceXformHelper fColorSpaceHelper;
92cb93a386Sopenharmony_ci        };
93cb93a386Sopenharmony_ci
94cb93a386Sopenharmony_ci        return std::make_unique<Impl>();
95cb93a386Sopenharmony_ci    }
96cb93a386Sopenharmony_ci
97cb93a386Sopenharmony_ci    void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
98cb93a386Sopenharmony_ci        b->add32(fMode);
99cb93a386Sopenharmony_ci        b->add32(GrColorSpaceXform::XformKey(fColorSpaceXform.get()));
100cb93a386Sopenharmony_ci    }
101cb93a386Sopenharmony_ci
102cb93a386Sopenharmony_ciprivate:
103cb93a386Sopenharmony_ci    GP(Mode mode, sk_sp<GrColorSpaceXform> colorSpaceXform)
104cb93a386Sopenharmony_ci            : INHERITED(kVertexColorSpaceBenchGP_ClassID)
105cb93a386Sopenharmony_ci            , fMode(mode)
106cb93a386Sopenharmony_ci            , fColorSpaceXform(std::move(colorSpaceXform)) {
107cb93a386Sopenharmony_ci        fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
108cb93a386Sopenharmony_ci        switch (fMode) {
109cb93a386Sopenharmony_ci            case kBaseline_Mode:
110cb93a386Sopenharmony_ci            case kShader_Mode:
111cb93a386Sopenharmony_ci                fInColor = {"inColor", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType};
112cb93a386Sopenharmony_ci                break;
113cb93a386Sopenharmony_ci            case kFloat_Mode:
114cb93a386Sopenharmony_ci                fInColor = {"inColor", kFloat4_GrVertexAttribType, kHalf4_GrSLType};
115cb93a386Sopenharmony_ci                break;
116cb93a386Sopenharmony_ci            case kHalf_Mode:
117cb93a386Sopenharmony_ci                fInColor = {"inColor", kHalf4_GrVertexAttribType, kHalf4_GrSLType};
118cb93a386Sopenharmony_ci                break;
119cb93a386Sopenharmony_ci        }
120cb93a386Sopenharmony_ci        this->setVertexAttributes(&fInPosition, 2);
121cb93a386Sopenharmony_ci    }
122cb93a386Sopenharmony_ci
123cb93a386Sopenharmony_ci    Mode fMode;
124cb93a386Sopenharmony_ci    sk_sp<GrColorSpaceXform> fColorSpaceXform;
125cb93a386Sopenharmony_ci
126cb93a386Sopenharmony_ci    Attribute fInPosition;
127cb93a386Sopenharmony_ci    Attribute fInColor;
128cb93a386Sopenharmony_ci
129cb93a386Sopenharmony_ci    using INHERITED = GrGeometryProcessor;
130cb93a386Sopenharmony_ci};
131cb93a386Sopenharmony_ci
132cb93a386Sopenharmony_ciclass Op : public GrMeshDrawOp {
133cb93a386Sopenharmony_cipublic:
134cb93a386Sopenharmony_ci    DEFINE_OP_CLASS_ID
135cb93a386Sopenharmony_ci
136cb93a386Sopenharmony_ci    const char* name() const override { return "VertColorXformOp"; }
137cb93a386Sopenharmony_ci
138cb93a386Sopenharmony_ci    Op(GrColor color)
139cb93a386Sopenharmony_ci            : INHERITED(ClassID())
140cb93a386Sopenharmony_ci            , fMode(kBaseline_Mode)
141cb93a386Sopenharmony_ci            , fColor(color) {
142cb93a386Sopenharmony_ci        this->setBounds(SkRect::MakeWH(100.f, 100.f), HasAABloat::kNo, IsHairline::kNo);
143cb93a386Sopenharmony_ci    }
144cb93a386Sopenharmony_ci
145cb93a386Sopenharmony_ci    Op(const SkColor4f& color4f, Mode mode)
146cb93a386Sopenharmony_ci            : INHERITED(ClassID())
147cb93a386Sopenharmony_ci            , fMode(mode)
148cb93a386Sopenharmony_ci            , fColor4f(color4f) {
149cb93a386Sopenharmony_ci        SkASSERT(kFloat_Mode == fMode || kHalf_Mode == mode);
150cb93a386Sopenharmony_ci        this->setBounds(SkRect::MakeWH(100.f, 100.f), HasAABloat::kNo, IsHairline::kNo);
151cb93a386Sopenharmony_ci    }
152cb93a386Sopenharmony_ci
153cb93a386Sopenharmony_ci    Op(GrColor color, sk_sp<GrColorSpaceXform> colorSpaceXform)
154cb93a386Sopenharmony_ci            : INHERITED(ClassID())
155cb93a386Sopenharmony_ci            , fMode(kShader_Mode)
156cb93a386Sopenharmony_ci            , fColor(color)
157cb93a386Sopenharmony_ci            , fColorSpaceXform(std::move(colorSpaceXform)) {
158cb93a386Sopenharmony_ci        this->setBounds(SkRect::MakeWH(100.f, 100.f), HasAABloat::kNo, IsHairline::kNo);
159cb93a386Sopenharmony_ci    }
160cb93a386Sopenharmony_ci
161cb93a386Sopenharmony_ci    FixedFunctionFlags fixedFunctionFlags() const override {
162cb93a386Sopenharmony_ci        return FixedFunctionFlags::kNone;
163cb93a386Sopenharmony_ci    }
164cb93a386Sopenharmony_ci
165cb93a386Sopenharmony_ci    GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override {
166cb93a386Sopenharmony_ci        return GrProcessorSet::EmptySetAnalysis();
167cb93a386Sopenharmony_ci    }
168cb93a386Sopenharmony_ci
169cb93a386Sopenharmony_ciprivate:
170cb93a386Sopenharmony_ci    friend class ::GrMemoryPool;
171cb93a386Sopenharmony_ci
172cb93a386Sopenharmony_ci    GrProgramInfo* programInfo() override { return fProgramInfo; }
173cb93a386Sopenharmony_ci
174cb93a386Sopenharmony_ci    void onCreateProgramInfo(const GrCaps* caps,
175cb93a386Sopenharmony_ci                             SkArenaAlloc* arena,
176cb93a386Sopenharmony_ci                             const GrSurfaceProxyView& writeView,
177cb93a386Sopenharmony_ci                             bool usesMSAASurface,
178cb93a386Sopenharmony_ci                             GrAppliedClip&& appliedClip,
179cb93a386Sopenharmony_ci                             const GrDstProxyView& dstProxyView,
180cb93a386Sopenharmony_ci                             GrXferBarrierFlags renderPassXferBarriers,
181cb93a386Sopenharmony_ci                             GrLoadOp colorLoadOp) override {
182cb93a386Sopenharmony_ci        GrGeometryProcessor* gp = GP::Make(arena, fMode, fColorSpaceXform);
183cb93a386Sopenharmony_ci
184cb93a386Sopenharmony_ci        fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps,
185cb93a386Sopenharmony_ci                                                                   arena,
186cb93a386Sopenharmony_ci                                                                   writeView,
187cb93a386Sopenharmony_ci                                                                   usesMSAASurface,
188cb93a386Sopenharmony_ci                                                                   std::move(appliedClip),
189cb93a386Sopenharmony_ci                                                                   dstProxyView,
190cb93a386Sopenharmony_ci                                                                   gp,
191cb93a386Sopenharmony_ci                                                                   GrProcessorSet::MakeEmptySet(),
192cb93a386Sopenharmony_ci                                                                   GrPrimitiveType::kTriangleStrip,
193cb93a386Sopenharmony_ci                                                                   renderPassXferBarriers,
194cb93a386Sopenharmony_ci                                                                   colorLoadOp,
195cb93a386Sopenharmony_ci                                                                   GrPipeline::InputFlags::kNone);
196cb93a386Sopenharmony_ci    }
197cb93a386Sopenharmony_ci
198cb93a386Sopenharmony_ci    void onPrepareDraws(GrMeshDrawTarget* target) override {
199cb93a386Sopenharmony_ci        if (!fProgramInfo) {
200cb93a386Sopenharmony_ci            this->createProgramInfo(target);
201cb93a386Sopenharmony_ci        }
202cb93a386Sopenharmony_ci
203cb93a386Sopenharmony_ci        size_t vertexStride = fProgramInfo->geomProc().vertexStride();
204cb93a386Sopenharmony_ci        const int kVertexCount = 1024;
205cb93a386Sopenharmony_ci        sk_sp<const GrBuffer> vertexBuffer;
206cb93a386Sopenharmony_ci        int firstVertex = 0;
207cb93a386Sopenharmony_ci        void* verts = target->makeVertexSpace(vertexStride, kVertexCount, &vertexBuffer,
208cb93a386Sopenharmony_ci                                              &firstVertex);
209cb93a386Sopenharmony_ci        if (!verts) {
210cb93a386Sopenharmony_ci            return;
211cb93a386Sopenharmony_ci        }
212cb93a386Sopenharmony_ci
213cb93a386Sopenharmony_ci        const float dx = 100.0f / kVertexCount;
214cb93a386Sopenharmony_ci        if (kFloat_Mode == fMode) {
215cb93a386Sopenharmony_ci            struct V {
216cb93a386Sopenharmony_ci                SkPoint fPos;
217cb93a386Sopenharmony_ci                SkColor4f fColor;
218cb93a386Sopenharmony_ci            };
219cb93a386Sopenharmony_ci            SkASSERT(sizeof(V) == vertexStride);
220cb93a386Sopenharmony_ci            V* v = (V*)verts;
221cb93a386Sopenharmony_ci            for (int i = 0; i < kVertexCount; i += 2) {
222cb93a386Sopenharmony_ci                v[i + 0].fPos.set(dx * i, 0.0f);
223cb93a386Sopenharmony_ci                v[i + 0].fColor = fColor4f;
224cb93a386Sopenharmony_ci                v[i + 1].fPos.set(dx * i, 100.0f);
225cb93a386Sopenharmony_ci                v[i + 1].fColor = fColor4f;
226cb93a386Sopenharmony_ci            }
227cb93a386Sopenharmony_ci        } else if (kHalf_Mode == fMode) {
228cb93a386Sopenharmony_ci            struct V {
229cb93a386Sopenharmony_ci                SkPoint fPos;
230cb93a386Sopenharmony_ci                uint64_t fColor;
231cb93a386Sopenharmony_ci            };
232cb93a386Sopenharmony_ci            SkASSERT(sizeof(V) == vertexStride);
233cb93a386Sopenharmony_ci            uint64_t color;
234cb93a386Sopenharmony_ci            Sk4h halfColor = SkFloatToHalf_finite_ftz(Sk4f::Load(&fColor4f));
235cb93a386Sopenharmony_ci            color = (uint64_t)halfColor[0] << 48 |
236cb93a386Sopenharmony_ci                    (uint64_t)halfColor[1] << 32 |
237cb93a386Sopenharmony_ci                    (uint64_t)halfColor[2] << 16 |
238cb93a386Sopenharmony_ci                    (uint64_t)halfColor[3] << 0;
239cb93a386Sopenharmony_ci            V* v = (V*)verts;
240cb93a386Sopenharmony_ci            for (int i = 0; i < kVertexCount; i += 2) {
241cb93a386Sopenharmony_ci                v[i + 0].fPos.set(dx * i, 0.0f);
242cb93a386Sopenharmony_ci                v[i + 0].fColor = color;
243cb93a386Sopenharmony_ci                v[i + 1].fPos.set(dx * i, 100.0f);
244cb93a386Sopenharmony_ci                v[i + 1].fColor = color;
245cb93a386Sopenharmony_ci            }
246cb93a386Sopenharmony_ci        } else {
247cb93a386Sopenharmony_ci            struct V {
248cb93a386Sopenharmony_ci                SkPoint fPos;
249cb93a386Sopenharmony_ci                GrColor fColor;
250cb93a386Sopenharmony_ci            };
251cb93a386Sopenharmony_ci            SkASSERT(sizeof(V) == vertexStride);
252cb93a386Sopenharmony_ci            V* v = (V*)verts;
253cb93a386Sopenharmony_ci            for (int i = 0; i < kVertexCount; i += 2) {
254cb93a386Sopenharmony_ci                v[i + 0].fPos.set(dx * i, 0.0f);
255cb93a386Sopenharmony_ci                v[i + 0].fColor = fColor;
256cb93a386Sopenharmony_ci                v[i + 1].fPos.set(dx * i, 100.0f);
257cb93a386Sopenharmony_ci                v[i + 1].fColor = fColor;
258cb93a386Sopenharmony_ci            }
259cb93a386Sopenharmony_ci        }
260cb93a386Sopenharmony_ci
261cb93a386Sopenharmony_ci        fMesh = target->allocMesh();
262cb93a386Sopenharmony_ci        fMesh->set(std::move(vertexBuffer), kVertexCount, firstVertex);
263cb93a386Sopenharmony_ci    }
264cb93a386Sopenharmony_ci
265cb93a386Sopenharmony_ci    void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
266cb93a386Sopenharmony_ci        if (!fProgramInfo || !fMesh) {
267cb93a386Sopenharmony_ci            return;
268cb93a386Sopenharmony_ci        }
269cb93a386Sopenharmony_ci
270cb93a386Sopenharmony_ci        flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
271cb93a386Sopenharmony_ci        flushState->bindTextures(fProgramInfo->geomProc(), nullptr, fProgramInfo->pipeline());
272cb93a386Sopenharmony_ci        flushState->drawMesh(*fMesh);
273cb93a386Sopenharmony_ci    }
274cb93a386Sopenharmony_ci
275cb93a386Sopenharmony_ci    Mode fMode;
276cb93a386Sopenharmony_ci    GrColor fColor;
277cb93a386Sopenharmony_ci    SkColor4f fColor4f;
278cb93a386Sopenharmony_ci    sk_sp<GrColorSpaceXform> fColorSpaceXform;
279cb93a386Sopenharmony_ci
280cb93a386Sopenharmony_ci    GrSimpleMesh*  fMesh = nullptr;
281cb93a386Sopenharmony_ci    GrProgramInfo* fProgramInfo = nullptr;
282cb93a386Sopenharmony_ci
283cb93a386Sopenharmony_ci    using INHERITED = GrMeshDrawOp;
284cb93a386Sopenharmony_ci};
285cb93a386Sopenharmony_ci}  // namespace
286cb93a386Sopenharmony_ci
287cb93a386Sopenharmony_ciclass VertexColorSpaceBench : public Benchmark {
288cb93a386Sopenharmony_cipublic:
289cb93a386Sopenharmony_ci    VertexColorSpaceBench(Mode mode, const char* name) : fMode(mode) {
290cb93a386Sopenharmony_ci        fName = "vertexcolorspace";
291cb93a386Sopenharmony_ci        fName.appendf("_%s", name);
292cb93a386Sopenharmony_ci    }
293cb93a386Sopenharmony_ci
294cb93a386Sopenharmony_ci    bool isSuitableFor(Backend backend) override { return kGPU_Backend == backend; }
295cb93a386Sopenharmony_ci    const char* onGetName() override { return fName.c_str(); }
296cb93a386Sopenharmony_ci
297cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
298cb93a386Sopenharmony_ci        auto context = canvas->recordingContext()->asDirectContext();
299cb93a386Sopenharmony_ci        SkASSERT(context);
300cb93a386Sopenharmony_ci
301cb93a386Sopenharmony_ci        if (kHalf_Mode == fMode &&
302cb93a386Sopenharmony_ci            !context->priv().caps()->halfFloatVertexAttributeSupport()) {
303cb93a386Sopenharmony_ci            return;
304cb93a386Sopenharmony_ci        }
305cb93a386Sopenharmony_ci
306cb93a386Sopenharmony_ci        auto p3 = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,
307cb93a386Sopenharmony_ci                                        SkNamedGamut::kDisplayP3);
308cb93a386Sopenharmony_ci        auto xform = GrColorSpaceXform::Make(sk_srgb_singleton(), kUnpremul_SkAlphaType,
309cb93a386Sopenharmony_ci                                             p3.get(),            kUnpremul_SkAlphaType);
310cb93a386Sopenharmony_ci
311cb93a386Sopenharmony_ci        SkRandom r;
312cb93a386Sopenharmony_ci        const int kDrawsPerLoop = 32;
313cb93a386Sopenharmony_ci
314cb93a386Sopenharmony_ci        for (int i = 0; i < loops; ++i) {
315cb93a386Sopenharmony_ci            auto sdc = skgpu::v1::SurfaceDrawContext::Make(context, GrColorType::kRGBA_8888, p3,
316cb93a386Sopenharmony_ci                                                           SkBackingFit::kApprox, {100, 100},
317cb93a386Sopenharmony_ci                                                           SkSurfaceProps());
318cb93a386Sopenharmony_ci            SkASSERT(sdc);
319cb93a386Sopenharmony_ci
320cb93a386Sopenharmony_ci            for (int j = 0; j < kDrawsPerLoop; ++j) {
321cb93a386Sopenharmony_ci                SkColor c = r.nextU();
322cb93a386Sopenharmony_ci                GrOp::Owner op = nullptr;
323cb93a386Sopenharmony_ci                GrRecordingContext* rContext = canvas->recordingContext();
324cb93a386Sopenharmony_ci                switch (fMode) {
325cb93a386Sopenharmony_ci                    case kBaseline_Mode:
326cb93a386Sopenharmony_ci                        op = GrOp::Make<Op>(rContext, SkColorToPremulGrColor(c));
327cb93a386Sopenharmony_ci                        break;
328cb93a386Sopenharmony_ci                    case kShader_Mode:
329cb93a386Sopenharmony_ci                        op = GrOp::Make<Op>(rContext, SkColorToUnpremulGrColor(c), xform);
330cb93a386Sopenharmony_ci                        break;
331cb93a386Sopenharmony_ci                    case kHalf_Mode:
332cb93a386Sopenharmony_ci                    case kFloat_Mode: {
333cb93a386Sopenharmony_ci                        SkColor4f c4f = SkColor4f::FromColor(c);
334cb93a386Sopenharmony_ci                        c4f = xform->apply(c4f);
335cb93a386Sopenharmony_ci                        op = GrOp::Make<Op>(rContext, c4f, fMode);
336cb93a386Sopenharmony_ci                    }
337cb93a386Sopenharmony_ci                }
338cb93a386Sopenharmony_ci                sdc->addDrawOp(std::move(op));
339cb93a386Sopenharmony_ci            }
340cb93a386Sopenharmony_ci
341cb93a386Sopenharmony_ci            context->flushAndSubmit();
342cb93a386Sopenharmony_ci        }
343cb93a386Sopenharmony_ci    }
344cb93a386Sopenharmony_ci
345cb93a386Sopenharmony_ciprivate:
346cb93a386Sopenharmony_ci    SkString fName;
347cb93a386Sopenharmony_ci    Mode fMode;
348cb93a386Sopenharmony_ci
349cb93a386Sopenharmony_ci    using INHERITED = Benchmark;
350cb93a386Sopenharmony_ci};
351cb93a386Sopenharmony_ci
352cb93a386Sopenharmony_ciDEF_BENCH(return new VertexColorSpaceBench(kBaseline_Mode, "baseline"));
353cb93a386Sopenharmony_ciDEF_BENCH(return new VertexColorSpaceBench(kFloat_Mode,    "float"));
354cb93a386Sopenharmony_ciDEF_BENCH(return new VertexColorSpaceBench(kHalf_Mode,     "half"));
355cb93a386Sopenharmony_ciDEF_BENCH(return new VertexColorSpaceBench(kShader_Mode,   "shader"));
356