• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 GrDrawingManager_DEFINED
9 #define GrDrawingManager_DEFINED
10 
11 #include <set>
12 #include "include/core/SkSurface.h"
13 #include "include/private/SkTArray.h"
14 #include "src/gpu/GrBufferAllocPool.h"
15 #include "src/gpu/GrDeferredUpload.h"
16 #include "src/gpu/GrPathRenderer.h"
17 #include "src/gpu/GrPathRendererChain.h"
18 #include "src/gpu/GrResourceCache.h"
19 #include "src/gpu/text/GrTextContext.h"
20 
21 class GrCoverageCountingPathRenderer;
22 class GrOnFlushCallbackObject;
23 class GrOpFlushState;
24 class GrOpList;
25 class GrRecordingContext;
26 class GrRenderTargetContext;
27 class GrRenderTargetProxy;
28 class GrRenderTargetOpList;
29 class GrSoftwarePathRenderer;
30 class GrTextureContext;
31 class GrTextureOpList;
32 class SkDeferredDisplayList;
33 
34 class GrDrawingManager {
35 public:
36     ~GrDrawingManager();
37 
38     void freeGpuResources();
39 
40     sk_sp<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrSurfaceProxy>,
41                                                          GrColorType,
42                                                          sk_sp<SkColorSpace>,
43                                                          const SkSurfaceProps*,
44                                                          bool managedOpList = true);
45     sk_sp<GrTextureContext> makeTextureContext(sk_sp<GrSurfaceProxy>,
46                                                GrColorType,
47                                                SkAlphaType,
48                                                sk_sp<SkColorSpace>);
49 
50     // A managed opList is controlled by the drawing manager (i.e., sorted & flushed with the
51     // others). An unmanaged one is created and used by the onFlushCallback.
52     sk_sp<GrRenderTargetOpList> newRTOpList(sk_sp<GrRenderTargetProxy>, bool managedOpList);
53     sk_sp<GrTextureOpList> newTextureOpList(sk_sp<GrTextureProxy>);
54 
55     // Create a new, specialized, render task that will regenerate mipmap levels and/or resolve
56     // MSAA (depending on GrTextureResolveFlags). This method will add the new render task to the
57     // list of render tasks and make it depend on the target texture proxy. It is up to the caller
58     // to add any dependencies on the new render task.
59     GrRenderTask* newTextureResolveRenderTask(
60             sk_sp<GrTextureProxy>, GrTextureResolveFlags, const GrCaps&);
61 
getContext()62     GrRecordingContext* getContext() { return fContext; }
63 
64     GrTextContext* getTextContext();
65 
66     GrPathRenderer* getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
67                                     bool allowSW,
68                                     GrPathRendererChain::DrawType drawType,
69                                     GrPathRenderer::StencilSupport* stencilSupport = nullptr);
70 
71     GrPathRenderer* getSoftwarePathRenderer();
72 
73     // Returns a direct pointer to the coverage counting path renderer, or null if it is not
74     // supported and turned on.
75     GrCoverageCountingPathRenderer* getCoverageCountingPathRenderer();
76 
77     void flushIfNecessary();
78 
79     static bool ProgramUnitTest(GrContext* context, int maxStages, int maxLevels);
80 
81     GrSemaphoresSubmitted flushSurfaces(GrSurfaceProxy* proxies[],
82                                         int cnt,
83                                         SkSurface::BackendSurfaceAccess access,
84                                         const GrFlushInfo& info);
flushSurface(GrSurfaceProxy * proxy,SkSurface::BackendSurfaceAccess access,const GrFlushInfo & info)85     GrSemaphoresSubmitted flushSurface(GrSurfaceProxy* proxy,
86                                        SkSurface::BackendSurfaceAccess access,
87                                        const GrFlushInfo& info) {
88         return this->flushSurfaces(&proxy, 1, access, info);
89     }
90 
91     void addOnFlushCallbackObject(GrOnFlushCallbackObject*);
92 
93 #if GR_TEST_UTILS
94     void testingOnly_removeOnFlushCallbackObject(GrOnFlushCallbackObject*);
95 #endif
96 
97     void moveRenderTasksToDDL(SkDeferredDisplayList* ddl);
98     void copyRenderTasksFromDDL(const SkDeferredDisplayList*, GrRenderTargetProxy* newDest);
99 
100 private:
101     // This class encapsulates maintenance and manipulation of the drawing manager's DAG of
102     // renderTasks.
103     class RenderTaskDAG {
104     public:
105         RenderTaskDAG(bool sortRenderTasks);
106         ~RenderTaskDAG();
107 
108         // Currently, when explicitly allocating resources, this call will topologically sort the
109         // opLists.
110         // MDB TODO: remove once incremental opList sorting is enabled
111         void prepForFlush();
112 
113         void closeAll(const GrCaps* caps);
114 
115         // A yucky combination of closeAll and reset
116         void cleanup(const GrCaps* caps);
117 
118         void gatherIDs(SkSTArray<8, uint32_t, true>* idArray) const;
119 
120         void reset();
121 
122         // These calls forceably remove an opList from the DAG. They are problematic bc they just
123         // remove the opList but don't cleanup any refering pointers (i.e., dependency pointers
124         // in the DAG). They work right now bc they are only called at flush time, after the
125         // topological sort is complete (so the dangling pointers aren't used).
126         void removeRenderTask(int index);
127         void removeRenderTasks(int startIndex, int stopIndex);
128 
empty()129         bool empty() const { return fRenderTasks.empty(); }
numRenderTasks()130         int numRenderTasks() const { return fRenderTasks.count(); }
131 
132         bool isUsed(GrSurfaceProxy*) const;
133 
renderTask(int index)134         GrRenderTask* renderTask(int index) { return fRenderTasks[index].get(); }
renderTask(int index)135         const GrRenderTask* renderTask(int index) const { return fRenderTasks[index].get(); }
136 
back()137         GrRenderTask* back() { return fRenderTasks.back().get(); }
back()138         const GrRenderTask* back() const { return fRenderTasks.back().get(); }
139 
140         GrRenderTask* add(sk_sp<GrRenderTask>);
141         GrRenderTask* addBeforeLast(sk_sp<GrRenderTask>);
142         void add(const SkTArray<sk_sp<GrRenderTask>>&);
143 
144         void swap(SkTArray<sk_sp<GrRenderTask>>* renderTasks);
145 
sortingRenderTasks()146         bool sortingRenderTasks() const { return fSortRenderTasks; }
147 
148     private:
149         SkTArray<sk_sp<GrRenderTask>> fRenderTasks;
150         bool                          fSortRenderTasks;
151     };
152 
153     GrDrawingManager(GrRecordingContext*, const GrPathRendererChain::Options&,
154                      const GrTextContext::Options&,
155                      bool sortRenderTasks,
156                      bool reduceOpListSplitting);
157 
158     bool wasAbandoned() const;
159 
160     void cleanup();
161 
162     // Closes the target's dependent render tasks (or, if not in sorting/opList-splitting-reduction
163     // mode, closes fActiveOpList) in preparation for us opening a new opList that will write to
164     // 'target'.
165     void closeRenderTasksForNewOpList(GrSurfaceProxy* target);
166 
167     // return true if any opLists were actually executed; false otherwise
168     bool executeRenderTasks(int startIndex, int stopIndex, GrOpFlushState*,
169                             int* numRenderTasksExecuted);
170 
171     GrSemaphoresSubmitted flush(GrSurfaceProxy* proxies[],
172                                 int numProxies,
173                                 SkSurface::BackendSurfaceAccess access,
174                                 const GrFlushInfo&,
175                                 const GrPrepareForExternalIORequests&);
176 
177     SkDEBUGCODE(void validate() const);
178 
179     friend class GrContext; // access to: flush & cleanup
180     friend class GrContextPriv; // access to: flush
181     friend class GrOnFlushResourceProvider; // this is just a shallow wrapper around this class
182     friend class GrRecordingContext;  // access to: ctor
183     friend class SkImage; // for access to: flush
184 
185     static const int kNumPixelGeometries = 5; // The different pixel geometries
186     static const int kNumDFTOptions = 2;      // DFT or no DFT
187 
188     GrRecordingContext*               fContext;
189     GrPathRendererChain::Options      fOptionsForPathRendererChain;
190     GrTextContext::Options            fOptionsForTextContext;
191     // This cache is used by both the vertex and index pools. It reuses memory across multiple
192     // flushes.
193     sk_sp<GrBufferAllocPool::CpuBufferCache> fCpuBufferCache;
194 
195     RenderTaskDAG                     fDAG;
196     GrOpList*                         fActiveOpList = nullptr;
197     // These are the IDs of the opLists currently being flushed (in internalFlush)
198     SkSTArray<8, uint32_t, true>      fFlushingRenderTaskIDs;
199     // These are the new opLists generated by the onFlush CBs
200     SkSTArray<8, sk_sp<GrOpList>>     fOnFlushCBOpLists;
201 
202     std::unique_ptr<GrTextContext>    fTextContext;
203 
204     std::unique_ptr<GrPathRendererChain> fPathRendererChain;
205     sk_sp<GrSoftwarePathRenderer>     fSoftwarePathRenderer;
206 
207     GrTokenTracker                    fTokenTracker;
208     bool                              fFlushing;
209     bool                              fReduceOpListSplitting;
210 
211     SkTArray<GrOnFlushCallbackObject*> fOnFlushCBObjects;
212 
addDDLTarget(GrSurfaceProxy * proxy)213     void addDDLTarget(GrSurfaceProxy* proxy) { fDDLTargets.insert(proxy); }
isDDLTarget(GrSurfaceProxy * proxy)214     bool isDDLTarget(GrSurfaceProxy* proxy) { return fDDLTargets.find(proxy) != fDDLTargets.end(); }
clearDDLTargets()215     void clearDDLTargets() { fDDLTargets.clear(); }
216 
217     // We play a trick with lazy proxies to retarget the base target of a DDL to the SkSurface
218     // it is replayed on. Because of this remapping we need to explicitly store the targets of
219     // DDL replaying.
220     // Note: we do not expect a whole lot of these per flush
221     std::set<GrSurfaceProxy*> fDDLTargets;
222 };
223 
224 #endif
225