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 15 namespace skgpu::v1 { 16 17 // Fills a rectangle of pixels with a clip against coverage values from an atlas. 18 class DrawAtlasPathOp final : public GrDrawOp { 19 public: 20 DEFINE_OP_CLASS_ID 21 DrawAtlasPathOp(SkArenaAlloc * arena,const SkIRect & fillBounds,const SkMatrix & localToDevice,GrPaint && paint,SkIPoint16 locationInAtlas,const SkIRect & pathDevIBounds,bool transposedInAtlas,GrSurfaceProxyView atlasView,bool isInverseFill)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 name()38 const char* name() const override { return "DrawAtlasPathOp"; } fixedFunctionFlags()39 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; } visitProxies(const GrVisitProxyFunc & func)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 52 private: 53 void prepareProgram(const GrCaps&, SkArenaAlloc*, const GrSurfaceProxyView& writeView, 54 bool usesMSAASurface, GrAppliedClip&&, const GrDstProxyView&, 55 GrXferBarrierFlags, GrLoadOp colorLoadOp); 56 57 struct Instance { InstanceInstance58 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