xref: /third_party/skia/src/gpu/ops/DrawAtlasPathOp.h (revision cb93a386)
1/*
2 * Copyright 2020 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#ifndef DrawAtlasPathOp_DEFINED
9#define DrawAtlasPathOp_DEFINED
10
11#include "src/core/SkIPoint16.h"
12#include "src/gpu/ops/AtlasInstancedHelper.h"
13#include "src/gpu/ops/GrDrawOp.h"
14
15namespace skgpu::v1 {
16
17// Fills a rectangle of pixels with a clip against coverage values from an atlas.
18class DrawAtlasPathOp final : public GrDrawOp {
19public:
20    DEFINE_OP_CLASS_ID
21
22    DrawAtlasPathOp(SkArenaAlloc* arena, const SkIRect& fillBounds, const SkMatrix& localToDevice,
23                    GrPaint&& paint, SkIPoint16 locationInAtlas, const SkIRect& pathDevIBounds,
24                    bool transposedInAtlas, GrSurfaceProxyView atlasView, bool isInverseFill)
25            : GrDrawOp(ClassID())
26            , fHeadInstance(arena->make<Instance>(fillBounds, localToDevice, paint.getColor4f(),
27                                                  locationInAtlas, pathDevIBounds,
28                                                  transposedInAtlas))
29            , fTailInstance(&fHeadInstance->fNext)
30            , fAtlasHelper(std::move(atlasView),
31                           isInverseFill ? AtlasInstancedHelper::ShaderFlags::kCheckBounds |
32                                           AtlasInstancedHelper::ShaderFlags::kInvertCoverage
33                                         : AtlasInstancedHelper::ShaderFlags::kNone)
34            , fProcessors(std::move(paint)) {
35        this->setBounds(SkRect::Make(fillBounds), HasAABloat::kYes, IsHairline::kNo);
36    }
37
38    const char* name() const override { return "DrawAtlasPathOp"; }
39    FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
40    void visitProxies(const GrVisitProxyFunc& func) const override {
41        func(fAtlasHelper.proxy(), GrMipmapped::kNo);
42        fProcessors.visitProxies(func);
43    }
44    GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
45    CombineResult onCombineIfPossible(GrOp*, SkArenaAlloc*, const GrCaps&) override;
46
47    void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView& writeView, GrAppliedClip*,
48                      const GrDstProxyView&, GrXferBarrierFlags, GrLoadOp colorLoadOp) override;
49    void onPrepare(GrOpFlushState*) override;
50    void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
51
52private:
53    void prepareProgram(const GrCaps&, SkArenaAlloc*, const GrSurfaceProxyView& writeView,
54                        bool usesMSAASurface, GrAppliedClip&&, const GrDstProxyView&,
55                        GrXferBarrierFlags, GrLoadOp colorLoadOp);
56
57    struct Instance {
58        Instance(const SkIRect& fillIBounds, const SkMatrix& m,
59                 const SkPMColor4f& color, SkIPoint16 locationInAtlas,
60                 const SkIRect& pathDevIBounds, bool transposedInAtlas)
61                : fFillBounds(fillIBounds)
62                , fLocalToDeviceIfUsingLocalCoords{m.getScaleX(), m.getSkewY(),
63                                                   m.getSkewX(), m.getScaleY(),
64                                                   m.getTranslateX(), m.getTranslateY()}
65                , fColor(color)
66                , fAtlasInstance(locationInAtlas, pathDevIBounds, transposedInAtlas) {
67        }
68        SkIRect fFillBounds;
69        std::array<float, 6> fLocalToDeviceIfUsingLocalCoords;
70        SkPMColor4f fColor;
71        AtlasInstancedHelper::Instance fAtlasInstance;
72        Instance* fNext = nullptr;
73    };
74
75    Instance* fHeadInstance;
76    Instance** fTailInstance;
77
78    AtlasInstancedHelper fAtlasHelper;
79    bool fUsesLocalCoords = false;
80
81    int fInstanceCount = 1;
82
83    GrProgramInfo* fProgram = nullptr;
84
85    sk_sp<const GrBuffer> fInstanceBuffer;
86    int fBaseInstance;
87
88    // Only used if sk_VertexID is not supported.
89    sk_sp<const GrGpuBuffer> fVertexBufferIfNoIDSupport;
90
91    GrProcessorSet fProcessors;
92};
93
94} // namespace skgpu::v1
95
96#endif // DrawAtlasPathOp_DEFINED
97