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