1 /* 2 * Copyright 2018 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 GrCCDrawPathsOp_DEFINED 9 #define GrCCDrawPathsOp_DEFINED 10 11 #include "src/core/SkTInternalLList.h" 12 #include "src/gpu/ccpr/GrCCPathCache.h" 13 #include "src/gpu/ccpr/GrCCSTLList.h" 14 #include "src/gpu/geometry/GrShape.h" 15 #include "src/gpu/ops/GrDrawOp.h" 16 17 class GrCCAtlas; 18 class GrCCPerFlushResources; 19 struct GrCCPerFlushResourceSpecs; 20 struct GrCCPerOpListPaths; 21 class GrOnFlushResourceProvider; 22 class GrRecordingContext; 23 24 /** 25 * This is the Op that draws paths to the actual canvas, using atlases generated by CCPR. 26 */ 27 class GrCCDrawPathsOp : public GrDrawOp { 28 public: 29 DEFINE_OP_CLASS_ID 30 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrCCDrawPathsOp); 31 32 static std::unique_ptr<GrCCDrawPathsOp> Make(GrRecordingContext*, const SkIRect& clipIBounds, 33 const SkMatrix&, const GrShape&, GrPaint&&); 34 ~GrCCDrawPathsOp() override; 35 name()36 const char* name() const override { return "GrCCDrawPathsOp"; } fixedFunctionFlags()37 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; } 38 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, 39 bool hasMixedSampledCoverage, GrClampType) override; 40 CombineResult onCombineIfPossible(GrOp*, const GrCaps&) override; visitProxies(const VisitProxyFunc & fn)41 void visitProxies(const VisitProxyFunc& fn) const override { 42 for (const auto& range : fInstanceRanges) { 43 fn(range.fAtlasProxy, GrMipMapped::kNo); 44 } 45 fProcessors.visitProxies(fn); 46 } onPrepare(GrOpFlushState *)47 void onPrepare(GrOpFlushState*) override {} 48 49 void addToOwningPerOpListPaths(sk_sp<GrCCPerOpListPaths> owningPerOpListPaths); 50 51 // Makes decisions about how to draw each path (cached, copied, rendered, etc.), and 52 // increments/fills out the corresponding GrCCPerFlushResourceSpecs. 53 void accountForOwnPaths(GrCCPathCache*, GrOnFlushResourceProvider*, GrCCPerFlushResourceSpecs*); 54 55 // Allows the caller to decide whether to actually do the suggested copies from cached 16-bit 56 // coverage count atlases, and into 8-bit literal coverage atlases. Purely to save space. 57 enum class DoCopiesToA8Coverage : bool { 58 kNo = false, 59 kYes = true 60 }; 61 62 // Allocates the GPU resources indicated by accountForOwnPaths(), in preparation for drawing. If 63 // DoCopiesToA8Coverage is kNo, the paths slated for copy will instead be left in their 16-bit 64 // coverage count atlases. 65 // 66 // NOTE: If using DoCopiesToA8Coverage::kNo, it is the caller's responsibility to have called 67 // cancelCopies() on the GrCCPerFlushResourceSpecs, prior to making this call. 68 void setupResources(GrCCPathCache*, GrOnFlushResourceProvider*, GrCCPerFlushResources*, 69 DoCopiesToA8Coverage); 70 71 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; 72 73 private: 74 friend class GrOpMemoryPool; 75 76 static std::unique_ptr<GrCCDrawPathsOp> InternalMake(GrRecordingContext*, 77 const SkIRect& clipIBounds, 78 const SkMatrix&, const GrShape&, 79 float strokeDevWidth, 80 const SkRect& conservativeDevBounds, 81 GrPaint&&); 82 83 GrCCDrawPathsOp(const SkMatrix&, const GrShape&, float strokeDevWidth, 84 const SkIRect& shapeConservativeIBounds, const SkIRect& maskDevIBounds, 85 const SkRect& conservativeDevBounds, GrPaint&&); 86 87 void recordInstance( 88 GrCCPathProcessor::CoverageMode, GrTextureProxy* atlasProxy, int instanceIdx); 89 90 const SkMatrix fViewMatrixIfUsingLocalCoords; 91 92 class SingleDraw { 93 public: 94 SingleDraw(const SkMatrix&, const GrShape&, float strokeDevWidth, 95 const SkIRect& shapeConservativeIBounds, const SkIRect& maskDevIBounds, 96 const SkPMColor4f&); 97 98 // See the corresponding methods in GrCCDrawPathsOp. 99 GrProcessorSet::Analysis finalize( 100 const GrCaps&, const GrAppliedClip*, bool hasMixedSampledCoverage, GrClampType, 101 GrProcessorSet*); 102 void accountForOwnPath(GrCCPathCache*, GrOnFlushResourceProvider*, 103 GrCCPerFlushResourceSpecs*); 104 void setupResources(GrCCPathCache*, GrOnFlushResourceProvider*, GrCCPerFlushResources*, 105 DoCopiesToA8Coverage, GrCCDrawPathsOp*); 106 107 private: 108 bool shouldCachePathMask(int maxRenderTargetSize) const; 109 110 SkMatrix fMatrix; 111 GrShape fShape; 112 float fStrokeDevWidth; 113 const SkIRect fShapeConservativeIBounds; 114 SkIRect fMaskDevIBounds; 115 SkPMColor4f fColor; 116 117 GrCCPathCache::OnFlushEntryRef fCacheEntry; 118 SkIVector fCachedMaskShift; 119 bool fDoCopyToA8Coverage = false; 120 bool fDoCachePathMask = false; 121 SkDEBUGCODE(bool fWasCountedAsRender = false); 122 123 SingleDraw* fNext = nullptr; 124 125 friend class GrCCSTLList<SingleDraw>; // To access fNext. 126 }; 127 128 // Declare fOwningPerOpListPaths first, before fDraws. The draws use memory allocated by 129 // fOwningPerOpListPaths, so it must not be unreffed until after fDraws is destroyed. 130 sk_sp<GrCCPerOpListPaths> fOwningPerOpListPaths; 131 132 GrCCSTLList<SingleDraw> fDraws; 133 SkDEBUGCODE(int fNumDraws = 1); 134 135 GrProcessorSet fProcessors; 136 137 struct InstanceRange { 138 GrCCPathProcessor::CoverageMode fCoverageMode; 139 GrTextureProxy* fAtlasProxy; 140 int fEndInstanceIdx; 141 }; 142 143 SkSTArray<2, InstanceRange, true> fInstanceRanges; 144 int fBaseInstance SkDEBUGCODE(= -1); 145 }; 146 147 #endif 148