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