1 /* 2 * Copyright 2010 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 GrRenderTargetOpList_DEFINED 9 #define GrRenderTargetOpList_DEFINED 10 11 #include "GrAppliedClip.h" 12 #include "GrOpList.h" 13 #include "GrPathRendering.h" 14 #include "GrPrimitiveProcessor.h" 15 #include "ops/GrOp.h" 16 #include "SkArenaAlloc.h" 17 #include "SkClipStack.h" 18 #include "SkMatrix.h" 19 #include "SkStringUtils.h" 20 #include "SkStrokeRec.h" 21 #include "SkTArray.h" 22 #include "SkTLazy.h" 23 #include "SkTypes.h" 24 25 class GrAuditTrail; 26 class GrClearOp; 27 class GrCaps; 28 class GrRenderTargetProxy; 29 30 class GrRenderTargetOpList final : public GrOpList { 31 private: 32 using DstProxy = GrXferProcessor::DstProxy; 33 34 public: 35 GrRenderTargetOpList(GrRenderTargetProxy*, GrResourceProvider*, GrAuditTrail*); 36 37 ~GrRenderTargetOpList() override; 38 makeClosed(const GrCaps & caps)39 void makeClosed(const GrCaps& caps) override { 40 if (this->isClosed()) { 41 return; 42 } 43 44 this->forwardCombine(caps); 45 46 INHERITED::makeClosed(caps); 47 } 48 isEmpty()49 bool isEmpty() const { return fRecordedOps.empty(); } 50 51 /** 52 * Empties the draw buffer of any queued up draws. 53 */ 54 void endFlush() override; 55 56 /** 57 * Together these two functions flush all queued up draws to GrCommandBuffer. The return value 58 * of executeOps() indicates whether any commands were actually issued to the GPU. 59 */ 60 void onPrepare(GrOpFlushState* flushState) override; 61 bool onExecute(GrOpFlushState* flushState) override; 62 addOp(std::unique_ptr<GrOp> op,const GrCaps & caps)63 uint32_t addOp(std::unique_ptr<GrOp> op, const GrCaps& caps) { 64 auto addDependency = [ &caps, this ] (GrSurfaceProxy* p) { 65 this->addDependency(p, caps); 66 }; 67 68 op->visitProxies(addDependency); 69 70 this->recordOp(std::move(op), caps); 71 72 return this->uniqueID(); 73 } 74 addOp(std::unique_ptr<GrOp> op,const GrCaps & caps,GrAppliedClip && clip,const DstProxy & dstProxy)75 uint32_t addOp(std::unique_ptr<GrOp> op, const GrCaps& caps, 76 GrAppliedClip&& clip, const DstProxy& dstProxy) { 77 auto addDependency = [ &caps, this ] (GrSurfaceProxy* p) { 78 this->addDependency(p, caps); 79 }; 80 81 op->visitProxies(addDependency); 82 clip.visitProxies(addDependency); 83 84 this->recordOp(std::move(op), caps, clip.doesClip() ? &clip : nullptr, &dstProxy); 85 86 return this->uniqueID(); 87 } 88 89 void discard(); 90 91 /** Clears the entire render target */ 92 void fullClear(const GrCaps& caps, GrColor color); 93 94 /** 95 * Copies a pixel rectangle from one surface to another. This call may finalize 96 * reserved vertex/index data (as though a draw call was made). The src pixels 97 * copied are specified by srcRect. They are copied to a rect of the same 98 * size in dst with top left at dstPoint. If the src rect is clipped by the 99 * src bounds then pixel values in the dst rect corresponding to area clipped 100 * by the src rect are not overwritten. This method is not guaranteed to succeed 101 * depending on the type of surface, configs, etc, and the backend-specific 102 * limitations. 103 */ 104 bool copySurface(const GrCaps& caps, 105 GrSurfaceProxy* dst, 106 GrSurfaceProxy* src, 107 const SkIRect& srcRect, 108 const SkIPoint& dstPoint) override; 109 asRenderTargetOpList()110 GrRenderTargetOpList* asRenderTargetOpList() override { return this; } 111 112 SkDEBUGCODE(void dump() const override;) 113 114 SkDEBUGCODE(int numOps() const override { return fRecordedOps.count(); }) 115 SkDEBUGCODE(int numClips() const override { return fNumClips; }) 116 SkDEBUGCODE(void visitProxies_debugOnly(const GrOp::VisitProxyFunc&) const;) 117 118 private: 119 friend class GrRenderTargetContextPriv; // for stencil clip state. TODO: this is invasive 120 121 struct RecordedOp { RecordedOpRecordedOp122 RecordedOp(std::unique_ptr<GrOp> op, GrAppliedClip* appliedClip, const DstProxy* dstProxy) 123 : fOp(std::move(op)), fAppliedClip(appliedClip) { 124 if (dstProxy) { 125 fDstProxy = *dstProxy; 126 } 127 } 128 visitProxiesRecordedOp129 void visitProxies(const GrOp::VisitProxyFunc& func) const { 130 if (fOp) { 131 fOp->visitProxies(func); 132 } 133 if (fDstProxy.proxy()) { 134 func(fDstProxy.proxy()); 135 } 136 if (fAppliedClip) { 137 fAppliedClip->visitProxies(func); 138 } 139 } 140 141 std::unique_ptr<GrOp> fOp; 142 DstProxy fDstProxy; 143 GrAppliedClip* fAppliedClip; 144 }; 145 146 void purgeOpsWithUninstantiatedProxies() override; 147 148 void gatherProxyIntervals(GrResourceAllocator*) const override; 149 150 void recordOp(std::unique_ptr<GrOp>, const GrCaps& caps, 151 GrAppliedClip* = nullptr, const DstProxy* = nullptr); 152 153 void forwardCombine(const GrCaps&); 154 155 // If this returns true then b has been merged into a's op. 156 bool combineIfPossible(const RecordedOp& a, GrOp* b, const GrAppliedClip* bClip, 157 const DstProxy* bDstTexture, const GrCaps&); 158 159 uint32_t fLastClipStackGenID; 160 SkIRect fLastDevClipBounds; 161 int fLastClipNumAnalyticFPs; 162 163 // For ops/opList we have mean: 5 stdDev: 28 164 SkSTArray<5, RecordedOp, true> fRecordedOps; 165 166 // MDB TODO: 4096 for the first allocation of the clip space will be huge overkill. 167 // Gather statistics to determine the correct size. 168 SkArenaAlloc fClipAllocator{4096}; 169 SkDEBUGCODE(int fNumClips;) 170 171 typedef GrOpList INHERITED; 172 }; 173 174 #endif 175