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