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 GrCoverageCountingPathRenderer_DEFINED 9 #define GrCoverageCountingPathRenderer_DEFINED 10 11 #include <map> 12 #include "GrCCPerOpListPaths.h" 13 #include "GrOnFlushResourceProvider.h" 14 #include "GrPathRenderer.h" 15 #include "GrRenderTargetOpList.h" 16 #include "ccpr/GrCCPerFlushResources.h" 17 18 class GrCCDrawPathsOp; 19 class GrCCPathCache; 20 21 /** 22 * This is a path renderer that draws antialiased paths by counting coverage in an offscreen 23 * buffer. (See GrCCCoverageProcessor, GrCCPathProcessor.) 24 * 25 * It also serves as the per-render-target tracker for pending path draws, and at the start of 26 * flush, it compiles GPU buffers and renders a "coverage count atlas" for the upcoming paths. 27 */ 28 class GrCoverageCountingPathRenderer : public GrPathRenderer, public GrOnFlushCallbackObject { 29 public: 30 static bool IsSupported(const GrCaps&); 31 32 enum class AllowCaching : bool { 33 kNo = false, 34 kYes = true 35 }; 36 37 static sk_sp<GrCoverageCountingPathRenderer> CreateIfSupported(const GrCaps&, AllowCaching, 38 uint32_t contextUniqueID); 39 40 using PendingPathsMap = std::map<uint32_t, sk_sp<GrCCPerOpListPaths>>; 41 42 // In DDL mode, Ganesh needs to be able to move the pending GrCCPerOpListPaths to the DDL object 43 // (detachPendingPaths) and then return them upon replay (mergePendingPaths). detachPendingPaths()44 PendingPathsMap detachPendingPaths() { return std::move(fPendingPaths); } 45 mergePendingPaths(const PendingPathsMap & paths)46 void mergePendingPaths(const PendingPathsMap& paths) { 47 #ifdef SK_DEBUG 48 // Ensure there are no duplicate opList IDs between the incoming path map and ours. 49 // This should always be true since opList IDs are globally unique and these are coming 50 // from different DDL recordings. 51 for (const auto& it : paths) { 52 SkASSERT(!fPendingPaths.count(it.first)); 53 } 54 #endif 55 56 fPendingPaths.insert(paths.begin(), paths.end()); 57 } 58 59 std::unique_ptr<GrFragmentProcessor> makeClipProcessor(uint32_t oplistID, 60 const SkPath& deviceSpacePath, 61 const SkIRect& accessRect, int rtWidth, 62 int rtHeight, const GrCaps&); 63 64 // GrOnFlushCallbackObject overrides. 65 void preFlush(GrOnFlushResourceProvider*, const uint32_t* opListIDs, int numOpListIDs, 66 SkTArray<sk_sp<GrRenderTargetContext>>* out) override; 67 void postFlush(GrDeferredUploadToken, const uint32_t* opListIDs, int numOpListIDs) override; 68 69 void purgeCacheEntriesOlderThan(GrProxyProvider*, const GrStdSteadyClock::time_point&); 70 71 // If a path spans more pixels than this, we need to crop it or else analytic AA can run out of 72 // fp32 precision. 73 static constexpr float kPathCropThreshold = 1 << 16; 74 75 static void CropPath(const SkPath&, const SkIRect& cropbox, SkPath* out); 76 77 // Maximum inflation of path bounds due to stroking (from width, miter, caps). Strokes wider 78 // than this will be converted to fill paths and drawn by the CCPR filler instead. 79 static constexpr float kMaxBoundsInflationFromStroke = 4096; 80 81 static float GetStrokeDevWidth(const SkMatrix&, const SkStrokeRec&, 82 float* inflationRadius = nullptr); 83 84 private: 85 GrCoverageCountingPathRenderer(AllowCaching, uint32_t contextUniqueID); 86 87 // GrPathRenderer overrides. onGetStencilSupport(const GrShape &)88 StencilSupport onGetStencilSupport(const GrShape&) const override { 89 return GrPathRenderer::kNoSupport_StencilSupport; 90 } 91 CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; 92 bool onDrawPath(const DrawPathArgs&) override; 93 94 GrCCPerOpListPaths* lookupPendingPaths(uint32_t opListID); 95 void recordOp(std::unique_ptr<GrCCDrawPathsOp>, const DrawPathArgs&); 96 97 // fPendingPaths holds the GrCCPerOpListPaths objects that have already been created, but not 98 // flushed, and those that are still being created. All GrCCPerOpListPaths objects will first 99 // reside in fPendingPaths, then be moved to fFlushingPaths during preFlush(). 100 PendingPathsMap fPendingPaths; 101 102 // fFlushingPaths holds the GrCCPerOpListPaths objects that are currently being flushed. 103 // (It will only contain elements when fFlushing is true.) 104 SkSTArray<4, sk_sp<GrCCPerOpListPaths>> fFlushingPaths; 105 106 std::unique_ptr<GrCCPathCache> fPathCache; 107 108 SkDEBUGCODE(bool fFlushing = false); 109 110 public: 111 void testingOnly_drawPathDirectly(const DrawPathArgs&); 112 const GrCCPerFlushResources* testingOnly_getCurrentFlushResources(); 113 const GrCCPathCache* testingOnly_getPathCache() const; 114 }; 115 116 #endif 117