GrRenderTargetOpList.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  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. #ifndef GrRenderTargetOpList_DEFINED
  8. #define GrRenderTargetOpList_DEFINED
  9. #include "include/core/SkMatrix.h"
  10. #include "include/core/SkStrokeRec.h"
  11. #include "include/core/SkTypes.h"
  12. #include "include/private/SkTArray.h"
  13. #include "src/core/SkArenaAlloc.h"
  14. #include "src/core/SkClipStack.h"
  15. #include "src/core/SkStringUtils.h"
  16. #include "src/core/SkTLazy.h"
  17. #include "src/gpu/GrAppliedClip.h"
  18. #include "src/gpu/GrOpList.h"
  19. #include "src/gpu/GrPathRendering.h"
  20. #include "src/gpu/GrPrimitiveProcessor.h"
  21. #include "src/gpu/ops/GrDrawOp.h"
  22. #include "src/gpu/ops/GrOp.h"
  23. class GrAuditTrail;
  24. class GrClearOp;
  25. class GrCaps;
  26. class GrRenderTargetProxy;
  27. class GrRenderTargetOpList final : public GrOpList {
  28. private:
  29. using DstProxy = GrXferProcessor::DstProxy;
  30. public:
  31. GrRenderTargetOpList(sk_sp<GrOpMemoryPool>, sk_sp<GrRenderTargetProxy>, GrAuditTrail*);
  32. ~GrRenderTargetOpList() override;
  33. void makeClosed(const GrCaps& caps) override {
  34. if (this->isClosed()) {
  35. return;
  36. }
  37. this->forwardCombine(caps);
  38. INHERITED::makeClosed(caps);
  39. }
  40. bool isEmpty() const { return fOpChains.empty(); }
  41. /**
  42. * Empties the draw buffer of any queued up draws.
  43. */
  44. void endFlush() override;
  45. /**
  46. * Together these two functions flush all queued up draws to GrCommandBuffer. The return value
  47. * of executeOps() indicates whether any commands were actually issued to the GPU.
  48. */
  49. void onPrepare(GrOpFlushState* flushState) override;
  50. bool onExecute(GrOpFlushState* flushState) override;
  51. void addOp(std::unique_ptr<GrOp> op, const GrCaps& caps) {
  52. auto addDependency = [ &caps, this ] (GrSurfaceProxy* p, GrMipMapped) {
  53. this->addDependency(p, caps);
  54. };
  55. op->visitProxies(addDependency);
  56. this->recordOp(std::move(op), GrProcessorSet::EmptySetAnalysis(), nullptr, nullptr, caps);
  57. }
  58. void addWaitOp(std::unique_ptr<GrOp> op, const GrCaps& caps) {
  59. fHasWaitOp= true;
  60. this->addOp(std::move(op), caps);
  61. }
  62. void addDrawOp(std::unique_ptr<GrDrawOp> op, const GrProcessorSet::Analysis& processorAnalysis,
  63. GrAppliedClip&& clip, const DstProxy& dstProxy, const GrCaps& caps) {
  64. auto addDependency = [ &caps, this ] (GrSurfaceProxy* p, GrMipMapped) {
  65. this->addDependency(p, caps);
  66. };
  67. op->visitProxies(addDependency);
  68. clip.visitProxies(addDependency);
  69. if (dstProxy.proxy()) {
  70. addDependency(dstProxy.proxy(), GrMipMapped::kNo);
  71. }
  72. this->recordOp(std::move(op), processorAnalysis, clip.doesClip() ? &clip : nullptr,
  73. &dstProxy, caps);
  74. }
  75. void discard();
  76. /**
  77. * Copies a pixel rectangle from one surface to another. This call may finalize
  78. * reserved vertex/index data (as though a draw call was made). The src pixels
  79. * copied are specified by srcRect. They are copied to a rect of the same
  80. * size in dst with top left at dstPoint. If the src rect is clipped by the
  81. * src bounds then pixel values in the dst rect corresponding to area clipped
  82. * by the src rect are not overwritten. This method is not guaranteed to succeed
  83. * depending on the type of surface, configs, etc, and the backend-specific
  84. * limitations.
  85. */
  86. bool copySurface(GrRecordingContext*,
  87. GrSurfaceProxy* dst,
  88. GrSurfaceProxy* src,
  89. const SkIRect& srcRect,
  90. const SkIPoint& dstPoint) override;
  91. GrRenderTargetOpList* asRenderTargetOpList() override { return this; }
  92. SkDEBUGCODE(void dump(bool printDependencies) const override;)
  93. SkDEBUGCODE(int numClips() const override { return fNumClips; })
  94. SkDEBUGCODE(void visitProxies_debugOnly(const GrOp::VisitProxyFunc&) const;)
  95. private:
  96. friend class GrRenderTargetContextPriv; // for stencil clip state. TODO: this is invasive
  97. // The RTC and RTOpList have to work together to handle buffer clears. In most cases, buffer
  98. // clearing can be done natively, in which case the op list's load ops are sufficient. In other
  99. // cases, draw ops must be used, which makes the RTC the best place for those decisions. This,
  100. // however, requires that the RTC be able to coordinate with the op list to achieve similar ends
  101. friend class GrRenderTargetContext;
  102. bool onIsUsed(GrSurfaceProxy*) const override;
  103. // Must only be called if native stencil buffer clearing is enabled
  104. void setStencilLoadOp(GrLoadOp op) { fStencilLoadOp = op; }
  105. // Must only be called if native color buffer clearing is enabled.
  106. void setColorLoadOp(GrLoadOp op, const SkPMColor4f& color);
  107. // Sets the clear color to transparent black
  108. void setColorLoadOp(GrLoadOp op) {
  109. static const SkPMColor4f kDefaultClearColor = {0.f, 0.f, 0.f, 0.f};
  110. this->setColorLoadOp(op, kDefaultClearColor);
  111. }
  112. enum class CanDiscardPreviousOps : bool {
  113. kYes = true,
  114. kNo = false
  115. };
  116. // Perform book-keeping for a fullscreen clear, regardless of how the clear is implemented later
  117. // (i.e. setColorLoadOp(), adding a ClearOp, or adding a GrFillRectOp that covers the device).
  118. // Returns true if the clear can be converted into a load op (barring device caps).
  119. bool resetForFullscreenClear(CanDiscardPreviousOps);
  120. void deleteOps();
  121. class OpChain {
  122. public:
  123. OpChain(const OpChain&) = delete;
  124. OpChain& operator=(const OpChain&) = delete;
  125. OpChain(std::unique_ptr<GrOp>, GrProcessorSet::Analysis, GrAppliedClip*, const DstProxy*);
  126. ~OpChain() {
  127. // The ops are stored in a GrMemoryPool and must be explicitly deleted via the pool.
  128. SkASSERT(fList.empty());
  129. }
  130. void visitProxies(const GrOp::VisitProxyFunc&) const;
  131. GrOp* head() const { return fList.head(); }
  132. GrAppliedClip* appliedClip() const { return fAppliedClip; }
  133. const DstProxy& dstProxy() const { return fDstProxy; }
  134. const SkRect& bounds() const { return fBounds; }
  135. // Deletes all the ops in the chain via the pool.
  136. void deleteOps(GrOpMemoryPool* pool);
  137. // Attempts to move the ops from the passed chain to this chain at the head. Also attempts
  138. // to merge ops between the chains. Upon success the passed chain is empty.
  139. // Fails when the chains aren't of the same op type, have different clips or dst proxies.
  140. bool prependChain(OpChain*, const GrCaps&, GrOpMemoryPool*, GrAuditTrail*);
  141. // Attempts to add 'op' to this chain either by merging or adding to the tail. Returns
  142. // 'op' to the caller upon failure, otherwise null. Fails when the op and chain aren't of
  143. // the same op type, have different clips or dst proxies.
  144. std::unique_ptr<GrOp> appendOp(std::unique_ptr<GrOp> op, GrProcessorSet::Analysis,
  145. const DstProxy*, const GrAppliedClip*, const GrCaps&,
  146. GrOpMemoryPool*, GrAuditTrail*);
  147. private:
  148. class List {
  149. public:
  150. List() = default;
  151. List(std::unique_ptr<GrOp>);
  152. List(List&&);
  153. List& operator=(List&& that);
  154. bool empty() const { return !SkToBool(fHead); }
  155. GrOp* head() const { return fHead.get(); }
  156. GrOp* tail() const { return fTail; }
  157. std::unique_ptr<GrOp> popHead();
  158. std::unique_ptr<GrOp> removeOp(GrOp* op);
  159. void pushHead(std::unique_ptr<GrOp> op);
  160. void pushTail(std::unique_ptr<GrOp>);
  161. void validate() const;
  162. private:
  163. std::unique_ptr<GrOp> fHead;
  164. GrOp* fTail = nullptr;
  165. };
  166. void validate() const;
  167. bool tryConcat(List*, GrProcessorSet::Analysis, const DstProxy&, const GrAppliedClip*,
  168. const SkRect& bounds, const GrCaps&, GrOpMemoryPool*, GrAuditTrail*);
  169. static List DoConcat(List, List, const GrCaps&, GrOpMemoryPool*, GrAuditTrail*);
  170. List fList;
  171. GrProcessorSet::Analysis fProcessorAnalysis;
  172. DstProxy fDstProxy;
  173. GrAppliedClip* fAppliedClip;
  174. SkRect fBounds;
  175. };
  176. void purgeOpsWithUninstantiatedProxies() override;
  177. void gatherProxyIntervals(GrResourceAllocator*) const override;
  178. void recordOp(std::unique_ptr<GrOp>, GrProcessorSet::Analysis, GrAppliedClip*, const DstProxy*,
  179. const GrCaps& caps);
  180. void forwardCombine(const GrCaps&);
  181. uint32_t fLastClipStackGenID;
  182. SkIRect fLastDevClipBounds;
  183. int fLastClipNumAnalyticFPs;
  184. // We must track if we have a wait op so that we don't delete the op when we have a full clear.
  185. bool fHasWaitOp = false;;
  186. // For ops/opList we have mean: 5 stdDev: 28
  187. SkSTArray<25, OpChain, true> fOpChains;
  188. // MDB TODO: 4096 for the first allocation of the clip space will be huge overkill.
  189. // Gather statistics to determine the correct size.
  190. SkArenaAlloc fClipAllocator{4096};
  191. SkDEBUGCODE(int fNumClips;)
  192. typedef GrOpList INHERITED;
  193. };
  194. #endif