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