• 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 "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