blob: 659686b9dcded534f2bb59d431d70e1942084d18 [file] [log] [blame]
Chris Dalton4e998532020-02-10 11:06:42 -07001/*
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
Robert Phillips769b4882021-09-07 16:48:46 -04008#ifndef DrawAtlasPathOp_DEFINED
9#define DrawAtlasPathOp_DEFINED
Chris Dalton4e998532020-02-10 11:06:42 -070010
Chris Daltond2dc8dd2020-05-19 16:32:02 -060011#include "src/core/SkIPoint16.h"
Robert Phillipsef80d7b2021-09-14 16:10:56 -040012#include "src/gpu/ops/AtlasInstancedHelper.h"
Chris Dalton4e998532020-02-10 11:06:42 -070013#include "src/gpu/ops/GrDrawOp.h"
14
Robert Phillips769b4882021-09-07 16:48:46 -040015namespace skgpu::v1 {
16
Chris Daltonee40d5a2021-07-07 16:34:36 -060017// Fills a rectangle of pixels with a clip against coverage values from an atlas.
Robert Phillips769b4882021-09-07 16:48:46 -040018class DrawAtlasPathOp final : public GrDrawOp {
Chris Dalton4e998532020-02-10 11:06:42 -070019public:
20 DEFINE_OP_CLASS_ID
21
Robert Phillips769b4882021-09-07 16:48:46 -040022 DrawAtlasPathOp(SkArenaAlloc* arena, const SkIRect& fillBounds, const SkMatrix& localToDevice,
23 GrPaint&& paint, SkIPoint16 locationInAtlas, const SkIRect& pathDevIBounds,
24 bool transposedInAtlas, GrSurfaceProxyView atlasView, bool isInverseFill)
Chris Dalton4e998532020-02-10 11:06:42 -070025 : GrDrawOp(ClassID())
Chris Daltonee40d5a2021-07-07 16:34:36 -060026 , fHeadInstance(arena->make<Instance>(fillBounds, localToDevice, paint.getColor4f(),
27 locationInAtlas, pathDevIBounds,
28 transposedInAtlas))
29 , fTailInstance(&fHeadInstance->fNext)
Chris Daltonb1fd64e2021-07-08 15:38:51 -060030 , fAtlasHelper(std::move(atlasView),
Robert Phillipsef80d7b2021-09-14 16:10:56 -040031 isInverseFill ? AtlasInstancedHelper::ShaderFlags::kCheckBounds |
32 AtlasInstancedHelper::ShaderFlags::kInvertCoverage
33 : AtlasInstancedHelper::ShaderFlags::kNone)
Chris Dalton4e998532020-02-10 11:06:42 -070034 , fProcessors(std::move(paint)) {
Chris Daltonee40d5a2021-07-07 16:34:36 -060035 this->setBounds(SkRect::Make(fillBounds), HasAABloat::kYes, IsHairline::kNo);
Chris Dalton4e998532020-02-10 11:06:42 -070036 }
37
Robert Phillips769b4882021-09-07 16:48:46 -040038 const char* name() const override { return "DrawAtlasPathOp"; }
Chris Daltoncc29a392021-07-12 15:16:29 -060039 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
Robert Phillips294723d2021-06-17 09:23:58 -040040 void visitProxies(const GrVisitProxyFunc& func) const override {
Chris Daltonb1fd64e2021-07-08 15:38:51 -060041 func(fAtlasHelper.proxy(), GrMipmapped::kNo);
Robert Phillips294723d2021-06-17 09:23:58 -040042 fProcessors.visitProxies(func);
Chris Dalton4e998532020-02-10 11:06:42 -070043 }
Chris Dalton57ab06c2021-04-22 12:57:28 -060044 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
Herb Derbye25c3002020-10-27 15:57:27 -040045 CombineResult onCombineIfPossible(GrOp*, SkArenaAlloc*, const GrCaps&) override;
Chris Daltonee40d5a2021-07-07 16:34:36 -060046
47 void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView& writeView, GrAppliedClip*,
48 const GrDstProxyView&, GrXferBarrierFlags, GrLoadOp colorLoadOp) override;
Chris Dalton4e998532020-02-10 11:06:42 -070049 void onPrepare(GrOpFlushState*) override;
50 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
51
52private:
Chris Daltonee40d5a2021-07-07 16:34:36 -060053 void prepareProgram(const GrCaps&, SkArenaAlloc*, const GrSurfaceProxyView& writeView,
Chris Daltoncc29a392021-07-12 15:16:29 -060054 bool usesMSAASurface, GrAppliedClip&&, const GrDstProxyView&,
55 GrXferBarrierFlags, GrLoadOp colorLoadOp);
Robert Phillipsc655c3a2020-03-18 13:23:45 -040056
Chris Dalton4e998532020-02-10 11:06:42 -070057 struct Instance {
Chris Daltonee40d5a2021-07-07 16:34:36 -060058 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()}
Chris Dalton4e998532020-02-10 11:06:42 -070065 , fColor(color)
Chris Daltonb1fd64e2021-07-08 15:38:51 -060066 , fAtlasInstance(locationInAtlas, pathDevIBounds, transposedInAtlas) {
Chris Dalton4e998532020-02-10 11:06:42 -070067 }
Chris Daltonee40d5a2021-07-07 16:34:36 -060068 SkIRect fFillBounds;
69 std::array<float, 6> fLocalToDeviceIfUsingLocalCoords;
Chris Dalton4e998532020-02-10 11:06:42 -070070 SkPMColor4f fColor;
Robert Phillipsef80d7b2021-09-14 16:10:56 -040071 AtlasInstancedHelper::Instance fAtlasInstance;
Chris Daltonbaae2dd2021-06-25 14:52:49 -060072 Instance* fNext = nullptr;
Chris Dalton4e998532020-02-10 11:06:42 -070073 };
74
Chris Daltonee40d5a2021-07-07 16:34:36 -060075 Instance* fHeadInstance;
76 Instance** fTailInstance;
77
Robert Phillipsef80d7b2021-09-14 16:10:56 -040078 AtlasInstancedHelper fAtlasHelper;
Chris Dalton4e998532020-02-10 11:06:42 -070079 bool fUsesLocalCoords = false;
80
Chris Dalton4e998532020-02-10 11:06:42 -070081 int fInstanceCount = 1;
82
Chris Daltonbaae2dd2021-06-25 14:52:49 -060083 GrProgramInfo* fProgram = nullptr;
84
Chris Dalton4e998532020-02-10 11:06:42 -070085 sk_sp<const GrBuffer> fInstanceBuffer;
86 int fBaseInstance;
87
Chris Daltona05ccc32021-06-29 19:42:13 -060088 // Only used if sk_VertexID is not supported.
89 sk_sp<const GrGpuBuffer> fVertexBufferIfNoIDSupport;
90
Chris Dalton4e998532020-02-10 11:06:42 -070091 GrProcessorSet fProcessors;
92};
93
Robert Phillips769b4882021-09-07 16:48:46 -040094} // namespace skgpu::v1
95
96#endif // DrawAtlasPathOp_DEFINED