1 /* 2 * Copyright 2017 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 gr_instanced_InstancedOp_DEFINED 9 #define gr_instanced_InstancedOp_DEFINED 10 11 12 #include "../private/GrInstancedPipelineInfo.h" 13 #include "GrMemoryPool.h" 14 #include "ops/GrDrawOp.h" 15 #include "instanced/InstancedRenderingTypes.h" 16 17 #include "SkTInternalLList.h" 18 19 namespace gr_instanced { 20 21 class InstancedRendering; 22 class OpAllocator; 23 24 class InstancedOp : public GrDrawOp { 25 public: 26 SK_DECLARE_INTERNAL_LLIST_INTERFACE(InstancedOp); 27 28 ~InstancedOp() override; name()29 const char* name() const override { return "InstancedOp"; } 30 dumpInfo()31 SkString dumpInfo() const override { 32 SkString string; 33 string.printf( 34 "AA: %d, ShapeTypes: 0x%02x, IShapeTypes: 0x%02x, Persp %d, " 35 "NonSquare: %d, PLoad: %0.2f, Tracked: %d, NumDraws: %d, " 36 "GeomChanges: %d\n", 37 (unsigned)fInfo.fAAType, 38 fInfo.fShapeTypes, 39 fInfo.fInnerShapeTypes, 40 fInfo.fHasPerspective, 41 fInfo.fNonSquare, 42 fPixelLoad, 43 fIsTracked, 44 fNumDraws, 45 fNumChangesInGeometry); 46 string.append(INHERITED::dumpInfo()); 47 return string; 48 } 49 50 struct Draw { 51 Instance fInstance; 52 IndexRange fGeometry; 53 Draw* fNext; 54 }; 55 getSingleDraw()56 Draw& getSingleDraw() const { SkASSERT(fHeadDraw && !fHeadDraw->fNext); return *fHeadDraw; } getSingleInstance()57 Instance& getSingleInstance() const { return this->getSingleDraw().fInstance; } 58 59 void appendRRectParams(const SkRRect&); 60 void appendParamsTexel(const SkScalar* vals, int count); 61 void appendParamsTexel(SkScalar x, SkScalar y, SkScalar z, SkScalar w); 62 void appendParamsTexel(SkScalar x, SkScalar y, SkScalar z); fixedFunctionFlags()63 FixedFunctionFlags fixedFunctionFlags() const override { 64 return GrAATypeIsHW(fInfo.aaType()) ? FixedFunctionFlags::kUsesHWAA 65 : FixedFunctionFlags::kNone; 66 } 67 RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*) override; 68 69 // Registers the op with the InstancedRendering list of tracked ops. 70 void wasRecorded(GrRenderTargetOpList*) override; 71 72 protected: 73 InstancedOp(uint32_t classID, GrPaint&&, OpAllocator*); 74 75 bool fIsTracked : 1; 76 bool fRequiresBarrierOnOverlap : 1; 77 bool fAllowsSRGBInputs : 1; 78 bool fDisableSRGBOutputConversion : 1; 79 int fNumDraws; 80 int fNumChangesInGeometry; 81 Draw* fHeadDraw; 82 Draw* fTailDraw; 83 OpAllocator* fAllocator; 84 InstancedRendering* fInstancedRendering; 85 OpInfo fInfo; 86 SkScalar fPixelLoad; 87 GrProcessorSet fProcessors; 88 SkSTArray<5, ParamsTexel, true> fParams; 89 90 private: 91 bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override; onPrepare(GrOpFlushState *)92 void onPrepare(GrOpFlushState*) override {} 93 void onExecute(GrOpFlushState*) override; 94 95 typedef GrDrawOp INHERITED; 96 97 friend class InstancedRendering; 98 friend class OpAllocator; 99 }; 100 101 class OpAllocator : public SkNoncopyable { 102 public: 103 virtual ~OpAllocator(); 104 105 /** 106 * These methods make a new record internally for an instanced draw, and return an op that is 107 * effectively just an index to that record. The returned op is not self-contained, but 108 * rather relies on this class to handle the rendering. The client must call beginFlush() on 109 * this class before attempting to flush ops returned by it. It is invalid to record new 110 * draws between beginFlush() and endFlush(). 111 */ 112 std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&, 113 GrPaint&&, GrAA, 114 const GrInstancedPipelineInfo&); 115 116 std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&, 117 GrPaint&&, const SkRect& localRect, 118 GrAA, 119 const GrInstancedPipelineInfo&); 120 121 std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&, 122 GrPaint&&, 123 const SkMatrix& localMatrix, GrAA, 124 const GrInstancedPipelineInfo&); 125 126 std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordOval(const SkRect&, const SkMatrix&, 127 GrPaint&&, GrAA, 128 const GrInstancedPipelineInfo&); 129 130 std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRRect(const SkRRect&, const SkMatrix&, 131 GrPaint&&, GrAA, 132 const GrInstancedPipelineInfo&); 133 134 std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordDRRect(const SkRRect& outer, 135 const SkRRect& inner, 136 const SkMatrix&, GrPaint&&, GrAA, 137 const GrInstancedPipelineInfo&); 138 allocateDraw()139 InstancedOp::Draw* allocateDraw() { return fDrawPool.allocate(); } releaseDraw(InstancedOp::Draw * draw)140 void releaseDraw(InstancedOp::Draw* draw) { fDrawPool.release(draw); } 141 142 protected: 143 OpAllocator(const GrCaps*); 144 145 private: 146 bool selectAntialiasMode(const SkMatrix& viewMatrix, GrAA aa, const GrInstancedPipelineInfo&, 147 GrAAType*); 148 virtual std::unique_ptr<InstancedOp> makeOp(GrPaint&&) = 0; 149 150 std::unique_ptr<InstancedOp> SK_WARN_UNUSED_RESULT recordShape( 151 ShapeType, const SkRect& bounds, 152 const SkMatrix& viewMatrix, GrPaint&&, 153 const SkRect& localRect, GrAA aa, 154 const GrInstancedPipelineInfo&); 155 156 GrObjectMemoryPool<InstancedOp::Draw> fDrawPool; 157 sk_sp<const GrCaps> fCaps; 158 }; 159 160 } 161 162 #endif 163