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