GrCCPerFlushResources.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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. #ifndef GrCCPerFlushResources_DEFINED
  8. #define GrCCPerFlushResources_DEFINED
  9. #include "src/gpu/GrNonAtomicRef.h"
  10. #include "src/gpu/ccpr/GrCCAtlas.h"
  11. #include "src/gpu/ccpr/GrCCFiller.h"
  12. #include "src/gpu/ccpr/GrCCPathProcessor.h"
  13. #include "src/gpu/ccpr/GrCCStroker.h"
  14. #include "src/gpu/ccpr/GrStencilAtlasOp.h"
  15. class GrCCPathCache;
  16. class GrCCPathCacheEntry;
  17. class GrOctoBounds;
  18. class GrOnFlushResourceProvider;
  19. class GrShape;
  20. /**
  21. * This struct counts values that help us preallocate buffers for rendered path geometry.
  22. */
  23. struct GrCCRenderedPathStats {
  24. int fMaxPointsPerPath = 0;
  25. int fNumTotalSkPoints = 0;
  26. int fNumTotalSkVerbs = 0;
  27. int fNumTotalConicWeights = 0;
  28. void statPath(const SkPath&);
  29. };
  30. /**
  31. * This struct encapsulates the minimum and desired requirements for the GPU resources required by
  32. * CCPR in a given flush.
  33. */
  34. struct GrCCPerFlushResourceSpecs {
  35. static constexpr int kFillIdx = 0;
  36. static constexpr int kStrokeIdx = 1;
  37. int fNumCachedPaths = 0;
  38. int fNumCopiedPaths[2] = {0, 0};
  39. GrCCRenderedPathStats fCopyPathStats[2];
  40. GrCCAtlas::Specs fCopyAtlasSpecs;
  41. int fNumRenderedPaths[2] = {0, 0};
  42. int fNumClipPaths = 0;
  43. GrCCRenderedPathStats fRenderedPathStats[2];
  44. GrCCAtlas::Specs fRenderedAtlasSpecs;
  45. bool isEmpty() const {
  46. return 0 == fNumCachedPaths + fNumCopiedPaths[kFillIdx] + fNumCopiedPaths[kStrokeIdx] +
  47. fNumRenderedPaths[kFillIdx] + fNumRenderedPaths[kStrokeIdx] + fNumClipPaths;
  48. }
  49. // Converts the copies to normal cached draws.
  50. void cancelCopies();
  51. };
  52. /**
  53. * This class wraps all the GPU resources that CCPR builds at flush time. It is allocated in CCPR's
  54. * preFlush() method, and referenced by all the GrCCPerOpListPaths objects that are being flushed.
  55. * It is deleted in postFlush() once all the flushing GrCCPerOpListPaths objects are deleted.
  56. */
  57. class GrCCPerFlushResources : public GrNonAtomicRef<GrCCPerFlushResources> {
  58. public:
  59. GrCCPerFlushResources(
  60. GrOnFlushResourceProvider*, GrCCAtlas::CoverageType,const GrCCPerFlushResourceSpecs&);
  61. bool isMapped() const { return SkToBool(fPathInstanceData); }
  62. GrCCAtlas::CoverageType renderedPathCoverageType() const {
  63. return fRenderedAtlasStack.coverageType();
  64. }
  65. // Copies a coverage-counted path out of the given texture proxy, and into a cached, 8-bit,
  66. // literal coverage atlas. Updates the cache entry to reference the new atlas.
  67. void upgradeEntryToLiteralCoverageAtlas(GrCCPathCache*, GrOnFlushResourceProvider*,
  68. GrCCPathCacheEntry*, GrFillRule);
  69. // These two methods render a path into a temporary coverage count atlas. See
  70. // GrCCPathProcessor::Instance for a description of the outputs.
  71. //
  72. // strokeDevWidth must be 0 for fills, 1 for hairlines, or the stroke width in device-space
  73. // pixels for non-hairline strokes (implicitly requiring a rigid-body transform).
  74. GrCCAtlas* renderShapeInAtlas(
  75. const SkIRect& clipIBounds, const SkMatrix&, const GrShape&, float strokeDevWidth,
  76. GrOctoBounds*, SkIRect* devIBounds, SkIVector* devToAtlasOffset);
  77. const GrCCAtlas* renderDeviceSpacePathInAtlas(
  78. const SkIRect& clipIBounds, const SkPath& devPath, const SkIRect& devPathIBounds,
  79. GrFillRule fillRule, SkIVector* devToAtlasOffset);
  80. // Returns the index in instanceBuffer() of the next instance that will be added by
  81. // appendDrawPathInstance().
  82. int nextPathInstanceIdx() const { return fNextPathInstanceIdx; }
  83. // Appends an instance to instanceBuffer() that will draw a path to the destination render
  84. // target. The caller is responsible to call set() on the returned instance, to keep track of
  85. // its atlas and index (see nextPathInstanceIdx()), and to issue the actual draw call.
  86. GrCCPathProcessor::Instance& appendDrawPathInstance() {
  87. SkASSERT(this->isMapped());
  88. SkASSERT(fNextPathInstanceIdx < fEndPathInstance);
  89. return fPathInstanceData[fNextPathInstanceIdx++];
  90. }
  91. // Finishes off the GPU buffers and renders the atlas(es).
  92. bool finalize(GrOnFlushResourceProvider*, SkTArray<sk_sp<GrRenderTargetContext>>* out);
  93. // Accessors used by draw calls, once the resources have been finalized.
  94. const GrCCFiller& filler() const { SkASSERT(!this->isMapped()); return fFiller; }
  95. const GrCCStroker& stroker() const { SkASSERT(!this->isMapped()); return fStroker; }
  96. sk_sp<const GrGpuBuffer> refIndexBuffer() const {
  97. SkASSERT(!this->isMapped());
  98. return fIndexBuffer;
  99. }
  100. sk_sp<const GrGpuBuffer> refVertexBuffer() const {
  101. SkASSERT(!this->isMapped());
  102. return fVertexBuffer;
  103. }
  104. sk_sp<const GrGpuBuffer> refInstanceBuffer() const {
  105. SkASSERT(!this->isMapped());
  106. return fInstanceBuffer;
  107. }
  108. sk_sp<const GrGpuBuffer> refStencilResolveBuffer() const {
  109. SkASSERT(!this->isMapped());
  110. return fStencilResolveBuffer;
  111. }
  112. private:
  113. void recordCopyPathInstance(const GrCCPathCacheEntry&, const SkIVector& newAtlasOffset,
  114. GrFillRule, sk_sp<GrTextureProxy> srcProxy);
  115. void placeRenderedPathInAtlas(
  116. const SkIRect& clippedPathIBounds, GrScissorTest, SkIVector* devToAtlasOffset);
  117. // In MSAA mode we record an additional instance per path that draws a rectangle on top of its
  118. // corresponding path in the atlas and resolves stencil winding values to coverage.
  119. void recordStencilResolveInstance(
  120. const SkIRect& clippedPathIBounds, const SkIVector& devToAtlasOffset, GrFillRule);
  121. const SkAutoSTArray<32, SkPoint> fLocalDevPtsBuffer;
  122. GrCCFiller fFiller;
  123. GrCCStroker fStroker;
  124. GrCCAtlasStack fCopyAtlasStack;
  125. GrCCAtlasStack fRenderedAtlasStack;
  126. const sk_sp<const GrGpuBuffer> fIndexBuffer;
  127. const sk_sp<const GrGpuBuffer> fVertexBuffer;
  128. const sk_sp<GrGpuBuffer> fInstanceBuffer;
  129. GrCCPathProcessor::Instance* fPathInstanceData = nullptr;
  130. int fNextCopyInstanceIdx;
  131. SkDEBUGCODE(int fEndCopyInstance);
  132. int fNextPathInstanceIdx;
  133. int fBasePathInstanceIdx;
  134. SkDEBUGCODE(int fEndPathInstance);
  135. // Represents a range of copy-path instances that all share the same source proxy. (i.e. Draw
  136. // instances that copy a path mask from a 16-bit coverage count atlas into an 8-bit literal
  137. // coverage atlas.)
  138. struct CopyPathRange {
  139. CopyPathRange() = default;
  140. CopyPathRange(sk_sp<GrTextureProxy> srcProxy, int count)
  141. : fSrcProxy(std::move(srcProxy)), fCount(count) {}
  142. sk_sp<GrTextureProxy> fSrcProxy;
  143. int fCount;
  144. };
  145. SkSTArray<4, CopyPathRange> fCopyPathRanges;
  146. int fCurrCopyAtlasRangesIdx = 0;
  147. // This is a list of coverage count atlas textures that have been invalidated due to us copying
  148. // their paths into new 8-bit literal coverage atlases. Since copying is finished by the time
  149. // we begin rendering new atlases, we can recycle these textures for the rendered atlases rather
  150. // than allocating new texture objects upon instantiation.
  151. SkSTArray<2, sk_sp<GrTexture>> fRecyclableAtlasTextures;
  152. // Used in MSAA mode make an intermediate draw that resolves stencil winding values to coverage.
  153. sk_sp<GrGpuBuffer> fStencilResolveBuffer;
  154. GrStencilAtlasOp::ResolveRectInstance* fStencilResolveInstanceData = nullptr;
  155. int fNextStencilResolveInstanceIdx = 0;
  156. SkDEBUGCODE(int fEndStencilResolveInstance);
  157. public:
  158. #ifdef SK_DEBUG
  159. void debugOnly_didReuseRenderedPath() {
  160. if (GrCCAtlas::CoverageType::kA8_Multisample == this->renderedPathCoverageType()) {
  161. --fEndStencilResolveInstance;
  162. }
  163. }
  164. #endif
  165. const GrTexture* testingOnly_frontCopyAtlasTexture() const;
  166. const GrTexture* testingOnly_frontRenderedAtlasTexture() const;
  167. };
  168. inline void GrCCRenderedPathStats::statPath(const SkPath& path) {
  169. fMaxPointsPerPath = SkTMax(fMaxPointsPerPath, path.countPoints());
  170. fNumTotalSkPoints += path.countPoints();
  171. fNumTotalSkVerbs += path.countVerbs();
  172. fNumTotalConicWeights += SkPathPriv::ConicWeightCnt(path);
  173. }
  174. #endif