xref: /third_party/skia/tools/gpu/TestOps.cpp (revision cb93a386)
1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2019 Google LLC
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 "tools/gpu/TestOps.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "src/core/SkPointPriv.h"
11cb93a386Sopenharmony_ci#include "src/gpu/BufferWriter.h"
12cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h"
13cb93a386Sopenharmony_ci#include "src/gpu/GrGeometryProcessor.h"
14cb93a386Sopenharmony_ci#include "src/gpu/GrMemoryPool.h"
15cb93a386Sopenharmony_ci#include "src/gpu/GrOpFlushState.h"
16cb93a386Sopenharmony_ci#include "src/gpu/GrProgramInfo.h"
17cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
18cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVarying.h"
19cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
20cb93a386Sopenharmony_ci#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
21cb93a386Sopenharmony_ci
22cb93a386Sopenharmony_cinamespace {
23cb93a386Sopenharmony_ci
24cb93a386Sopenharmony_ciclass GP : public GrGeometryProcessor {
25cb93a386Sopenharmony_cipublic:
26cb93a386Sopenharmony_ci    GP(const SkMatrix& localMatrix, bool wideColor)
27cb93a386Sopenharmony_ci            : GrGeometryProcessor(kTestRectOp_ClassID), fLocalMatrix(localMatrix) {
28cb93a386Sopenharmony_ci        fInColor = MakeColorAttribute("color", wideColor);
29cb93a386Sopenharmony_ci        this->setVertexAttributes(&fInPosition, 3);
30cb93a386Sopenharmony_ci    }
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ci    const char* name() const override { return "TestRectOp::GP"; }
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_ci    std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override {
35cb93a386Sopenharmony_ci        class Impl : public ProgramImpl {
36cb93a386Sopenharmony_ci        public:
37cb93a386Sopenharmony_ci            void setData(const GrGLSLProgramDataManager& pdman,
38cb93a386Sopenharmony_ci                         const GrShaderCaps& shaderCaps,
39cb93a386Sopenharmony_ci                         const GrGeometryProcessor& geomProc) override {
40cb93a386Sopenharmony_ci                const auto& gp = geomProc.cast<GP>();
41cb93a386Sopenharmony_ci                SetTransform(pdman, shaderCaps, fLocalMatrixUni, gp.fLocalMatrix);
42cb93a386Sopenharmony_ci            }
43cb93a386Sopenharmony_ci
44cb93a386Sopenharmony_ci        private:
45cb93a386Sopenharmony_ci            void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
46cb93a386Sopenharmony_ci                const auto& gp = args.fGeomProc.cast<GP>();
47cb93a386Sopenharmony_ci                args.fVaryingHandler->emitAttributes(gp);
48cb93a386Sopenharmony_ci                GrGLSLVarying colorVarying(kHalf4_GrSLType);
49cb93a386Sopenharmony_ci                args.fVaryingHandler->addVarying("color", &colorVarying,
50cb93a386Sopenharmony_ci                                                 GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
51cb93a386Sopenharmony_ci                args.fVertBuilder->codeAppendf("%s = %s;", colorVarying.vsOut(), gp.fInColor.name());
52cb93a386Sopenharmony_ci                args.fFragBuilder->codeAppendf("half4 %s = %s;",
53cb93a386Sopenharmony_ci                                               args.fOutputColor, colorVarying.fsIn());
54cb93a386Sopenharmony_ci                args.fFragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
55cb93a386Sopenharmony_ci                WriteOutputPosition(args.fVertBuilder, gpArgs, gp.fInPosition.name());
56cb93a386Sopenharmony_ci                WriteLocalCoord(args.fVertBuilder,
57cb93a386Sopenharmony_ci                                args.fUniformHandler,
58cb93a386Sopenharmony_ci                                *args.fShaderCaps,
59cb93a386Sopenharmony_ci                                gpArgs,
60cb93a386Sopenharmony_ci                                gp.fInLocalCoords.asShaderVar(),
61cb93a386Sopenharmony_ci                                gp.fLocalMatrix,
62cb93a386Sopenharmony_ci                                &fLocalMatrixUni);
63cb93a386Sopenharmony_ci            }
64cb93a386Sopenharmony_ci
65cb93a386Sopenharmony_ci            UniformHandle fLocalMatrixUni;
66cb93a386Sopenharmony_ci        };
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ci        return std::make_unique<Impl>();
69cb93a386Sopenharmony_ci    }
70cb93a386Sopenharmony_ci
71cb93a386Sopenharmony_ci    void addToKey(const GrShaderCaps& shaderCaps, GrProcessorKeyBuilder* b) const override {
72cb93a386Sopenharmony_ci        b->add32(ProgramImpl::ComputeMatrixKey(shaderCaps, fLocalMatrix));
73cb93a386Sopenharmony_ci    }
74cb93a386Sopenharmony_ci
75cb93a386Sopenharmony_ci    bool wideColor() const { return fInColor.cpuType() != kUByte4_norm_GrVertexAttribType; }
76cb93a386Sopenharmony_ci
77cb93a386Sopenharmony_ciprivate:
78cb93a386Sopenharmony_ci    Attribute fInPosition    = {   "inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
79cb93a386Sopenharmony_ci    Attribute fInLocalCoords = {"inLocalCoords", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
80cb93a386Sopenharmony_ci    Attribute fInColor;
81cb93a386Sopenharmony_ci
82cb93a386Sopenharmony_ci    SkMatrix fLocalMatrix;
83cb93a386Sopenharmony_ci};
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ciclass TestRectOp final : public GrMeshDrawOp {
86cb93a386Sopenharmony_cipublic:
87cb93a386Sopenharmony_ci    static GrOp::Owner Make(GrRecordingContext*,
88cb93a386Sopenharmony_ci                            GrPaint&&,
89cb93a386Sopenharmony_ci                            const SkRect& drawRect,
90cb93a386Sopenharmony_ci                            const SkRect& localRect,
91cb93a386Sopenharmony_ci                            const SkMatrix& localM);
92cb93a386Sopenharmony_ci
93cb93a386Sopenharmony_ci    const char* name() const override { return "TestRectOp"; }
94cb93a386Sopenharmony_ci
95cb93a386Sopenharmony_ci    FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
96cb93a386Sopenharmony_ci
97cb93a386Sopenharmony_ci    GrProcessorSet::Analysis finalize(const GrCaps&,
98cb93a386Sopenharmony_ci                                      const GrAppliedClip*,
99cb93a386Sopenharmony_ci                                      GrClampType) override;
100cb93a386Sopenharmony_ci
101cb93a386Sopenharmony_ci    void visitProxies(const GrVisitProxyFunc& func) const override {
102cb93a386Sopenharmony_ci        if (fProgramInfo) {
103cb93a386Sopenharmony_ci            fProgramInfo->visitFPProxies(func);
104cb93a386Sopenharmony_ci        } else {
105cb93a386Sopenharmony_ci            fProcessorSet.visitProxies(func);
106cb93a386Sopenharmony_ci        }
107cb93a386Sopenharmony_ci    }
108cb93a386Sopenharmony_ci
109cb93a386Sopenharmony_ciprivate:
110cb93a386Sopenharmony_ci    DEFINE_OP_CLASS_ID
111cb93a386Sopenharmony_ci
112cb93a386Sopenharmony_ci    TestRectOp(const GrCaps*,
113cb93a386Sopenharmony_ci               GrPaint&&,
114cb93a386Sopenharmony_ci               const SkRect& drawRect,
115cb93a386Sopenharmony_ci               const SkRect& localRect,
116cb93a386Sopenharmony_ci               const SkMatrix& localMatrix);
117cb93a386Sopenharmony_ci
118cb93a386Sopenharmony_ci    GrProgramInfo* programInfo() override { return fProgramInfo; }
119cb93a386Sopenharmony_ci    void onCreateProgramInfo(const GrCaps*,
120cb93a386Sopenharmony_ci                             SkArenaAlloc*,
121cb93a386Sopenharmony_ci                             const GrSurfaceProxyView& writeView,
122cb93a386Sopenharmony_ci                             bool usesMSAASurface,
123cb93a386Sopenharmony_ci                             GrAppliedClip&&,
124cb93a386Sopenharmony_ci                             const GrDstProxyView&,
125cb93a386Sopenharmony_ci                             GrXferBarrierFlags renderPassXferBarriers,
126cb93a386Sopenharmony_ci                             GrLoadOp colorLoadOp) override;
127cb93a386Sopenharmony_ci
128cb93a386Sopenharmony_ci    void onPrepareDraws(GrMeshDrawTarget*) override;
129cb93a386Sopenharmony_ci    void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
130cb93a386Sopenharmony_ci
131cb93a386Sopenharmony_ci    SkRect         fDrawRect;
132cb93a386Sopenharmony_ci    SkRect         fLocalRect;
133cb93a386Sopenharmony_ci    SkPMColor4f    fColor;
134cb93a386Sopenharmony_ci    GP             fGP;
135cb93a386Sopenharmony_ci    GrProcessorSet fProcessorSet;
136cb93a386Sopenharmony_ci
137cb93a386Sopenharmony_ci    // If this op is prePrepared the created programInfo will be stored here for use in
138cb93a386Sopenharmony_ci    // onExecute. In the prePrepared case it will have been stored in the record-time arena.
139cb93a386Sopenharmony_ci    GrProgramInfo* fProgramInfo = nullptr;
140cb93a386Sopenharmony_ci    GrSimpleMesh*  fMesh        = nullptr;
141cb93a386Sopenharmony_ci
142cb93a386Sopenharmony_ci    friend class ::GrOp;
143cb93a386Sopenharmony_ci};
144cb93a386Sopenharmony_ci
145cb93a386Sopenharmony_ciGrOp::Owner TestRectOp::Make(GrRecordingContext* context,
146cb93a386Sopenharmony_ci                             GrPaint&& paint,
147cb93a386Sopenharmony_ci                             const SkRect& drawRect,
148cb93a386Sopenharmony_ci                             const SkRect& localRect,
149cb93a386Sopenharmony_ci                             const SkMatrix& localM) {
150cb93a386Sopenharmony_ci    const auto* caps = context->priv().caps();
151cb93a386Sopenharmony_ci    return GrOp::Make<TestRectOp>(context, caps, std::move(paint), drawRect, localRect, localM);
152cb93a386Sopenharmony_ci}
153cb93a386Sopenharmony_ci
154cb93a386Sopenharmony_ciGrProcessorSet::Analysis TestRectOp::finalize(const GrCaps& caps,
155cb93a386Sopenharmony_ci                                              const GrAppliedClip* clip,
156cb93a386Sopenharmony_ci                                              GrClampType clampType) {
157cb93a386Sopenharmony_ci    return fProcessorSet.finalize(GrProcessorAnalysisColor::Opaque::kYes,
158cb93a386Sopenharmony_ci                                  GrProcessorAnalysisCoverage::kSingleChannel, clip,
159cb93a386Sopenharmony_ci                                  &GrUserStencilSettings::kUnused, caps, clampType, &fColor);
160cb93a386Sopenharmony_ci}
161cb93a386Sopenharmony_ci
162cb93a386Sopenharmony_cistatic bool use_wide_color(const GrPaint& paint, const GrCaps* caps) {
163cb93a386Sopenharmony_ci    return !paint.getColor4f().fitsInBytes() && caps->halfFloatVertexAttributeSupport();
164cb93a386Sopenharmony_ci}
165cb93a386Sopenharmony_ciTestRectOp::TestRectOp(const GrCaps* caps,
166cb93a386Sopenharmony_ci                       GrPaint&& paint,
167cb93a386Sopenharmony_ci                       const SkRect& drawRect,
168cb93a386Sopenharmony_ci                       const SkRect& localRect,
169cb93a386Sopenharmony_ci                       const SkMatrix& localMatrix)
170cb93a386Sopenharmony_ci        : GrMeshDrawOp(ClassID())
171cb93a386Sopenharmony_ci        , fDrawRect(drawRect)
172cb93a386Sopenharmony_ci        , fLocalRect(localRect)
173cb93a386Sopenharmony_ci        , fColor(paint.getColor4f())
174cb93a386Sopenharmony_ci        , fGP(localMatrix, use_wide_color(paint, caps))
175cb93a386Sopenharmony_ci        , fProcessorSet(std::move(paint)) {
176cb93a386Sopenharmony_ci    this->setBounds(drawRect.makeSorted(), HasAABloat::kNo, IsHairline::kNo);
177cb93a386Sopenharmony_ci}
178cb93a386Sopenharmony_ci
179cb93a386Sopenharmony_civoid TestRectOp::onCreateProgramInfo(const GrCaps* caps,
180cb93a386Sopenharmony_ci                                     SkArenaAlloc* arena,
181cb93a386Sopenharmony_ci                                     const GrSurfaceProxyView& writeView,
182cb93a386Sopenharmony_ci                                     bool usesMSAASurface,
183cb93a386Sopenharmony_ci                                     GrAppliedClip&& appliedClip,
184cb93a386Sopenharmony_ci                                     const GrDstProxyView& dstProxyView,
185cb93a386Sopenharmony_ci                                     GrXferBarrierFlags renderPassXferBarriers,
186cb93a386Sopenharmony_ci                                     GrLoadOp colorLoadOp) {
187cb93a386Sopenharmony_ci    fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps,
188cb93a386Sopenharmony_ci                                                               arena,
189cb93a386Sopenharmony_ci                                                               writeView,
190cb93a386Sopenharmony_ci                                                               usesMSAASurface,
191cb93a386Sopenharmony_ci                                                               std::move(appliedClip),
192cb93a386Sopenharmony_ci                                                               dstProxyView,
193cb93a386Sopenharmony_ci                                                               &fGP,
194cb93a386Sopenharmony_ci                                                               std::move(fProcessorSet),
195cb93a386Sopenharmony_ci                                                               GrPrimitiveType::kTriangles,
196cb93a386Sopenharmony_ci                                                               renderPassXferBarriers,
197cb93a386Sopenharmony_ci                                                               colorLoadOp,
198cb93a386Sopenharmony_ci                                                               GrPipeline::InputFlags::kNone);
199cb93a386Sopenharmony_ci}
200cb93a386Sopenharmony_ci
201cb93a386Sopenharmony_civoid TestRectOp::onPrepareDraws(GrMeshDrawTarget* target) {
202cb93a386Sopenharmony_ci    QuadHelper helper(target, fGP.vertexStride(), 1);
203cb93a386Sopenharmony_ci    skgpu::VertexWriter writer{helper.vertices()};
204cb93a386Sopenharmony_ci    auto pos = skgpu::VertexWriter::TriStripFromRect(fDrawRect);
205cb93a386Sopenharmony_ci    auto local = skgpu::VertexWriter::TriStripFromRect(fLocalRect);
206cb93a386Sopenharmony_ci    GrVertexColor color(fColor, fGP.wideColor());
207cb93a386Sopenharmony_ci    writer.writeQuad(pos, local, color);
208cb93a386Sopenharmony_ci
209cb93a386Sopenharmony_ci    fMesh = helper.mesh();
210cb93a386Sopenharmony_ci}
211cb93a386Sopenharmony_ci
212cb93a386Sopenharmony_civoid TestRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
213cb93a386Sopenharmony_ci    if (!fProgramInfo) {
214cb93a386Sopenharmony_ci        this->createProgramInfo(flushState);
215cb93a386Sopenharmony_ci    }
216cb93a386Sopenharmony_ci
217cb93a386Sopenharmony_ci    flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
218cb93a386Sopenharmony_ci    flushState->bindTextures(fProgramInfo->geomProc(), nullptr, fProgramInfo->pipeline());
219cb93a386Sopenharmony_ci    flushState->drawMesh(*fMesh);
220cb93a386Sopenharmony_ci}
221cb93a386Sopenharmony_ci
222cb93a386Sopenharmony_ci}  // anonymous namespace
223cb93a386Sopenharmony_ci
224cb93a386Sopenharmony_cinamespace sk_gpu_test::test_ops {
225cb93a386Sopenharmony_ci
226cb93a386Sopenharmony_ciGrOp::Owner MakeRect(GrRecordingContext* context,
227cb93a386Sopenharmony_ci                     GrPaint&& paint,
228cb93a386Sopenharmony_ci                     const SkRect& drawRect,
229cb93a386Sopenharmony_ci                     const SkRect& localRect,
230cb93a386Sopenharmony_ci                     const SkMatrix& localM) {
231cb93a386Sopenharmony_ci    return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM);
232cb93a386Sopenharmony_ci}
233cb93a386Sopenharmony_ci
234cb93a386Sopenharmony_ciGrOp::Owner MakeRect(GrRecordingContext* context,
235cb93a386Sopenharmony_ci                     std::unique_ptr<GrFragmentProcessor> fp,
236cb93a386Sopenharmony_ci                     const SkRect& drawRect,
237cb93a386Sopenharmony_ci                     const SkRect& localRect,
238cb93a386Sopenharmony_ci                     const SkMatrix& localM) {
239cb93a386Sopenharmony_ci    GrPaint paint;
240cb93a386Sopenharmony_ci    paint.setColorFragmentProcessor(std::move(fp));
241cb93a386Sopenharmony_ci    return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM);
242cb93a386Sopenharmony_ci}
243cb93a386Sopenharmony_ci
244cb93a386Sopenharmony_ciGrOp::Owner MakeRect(GrRecordingContext* context,
245cb93a386Sopenharmony_ci                     GrPaint&& paint,
246cb93a386Sopenharmony_ci                     const SkRect& rect) {
247cb93a386Sopenharmony_ci    return TestRectOp::Make(context, std::move(paint), rect, rect, SkMatrix::I());
248cb93a386Sopenharmony_ci}
249cb93a386Sopenharmony_ci
250cb93a386Sopenharmony_ci}  // namespace sk_gpu_test::test_ops
251