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 GrOpsTask; 25 class GrRecordingContext; 26 class GrRenderTargetContext; 27 class GrRenderTargetProxy; 28 class GrSoftwarePathRenderer; 29 class GrTextureContext; 30 class GrTextureResolveRenderTask; 31 class SkDeferredDisplayList; 32 33 class GrDrawingManager { 34 public: 35 ~GrDrawingManager(); 36 37 void freeGpuResources(); 38 39 std::unique_ptr<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrSurfaceProxy>, 40 GrColorType, 41 sk_sp<SkColorSpace>, 42 const SkSurfaceProps*, 43 bool managedOpsTask = true); 44 std::unique_ptr<GrTextureContext> makeTextureContext(sk_sp<GrSurfaceProxy>, 45 GrColorType, 46 SkAlphaType, 47 sk_sp<SkColorSpace>); 48 49 // A managed opsTask is controlled by the drawing manager (i.e., sorted & flushed with the 50 // others). An unmanaged one is created and used by the onFlushCallback. 51 sk_sp<GrOpsTask> newOpsTask(sk_sp<GrRenderTargetProxy>, bool managedOpsTask); 52 53 // Create a render task that can resolve MSAA and/or regenerate mipmap levels on proxies. This 54 // method will only add the new render task to the list. It is up to the caller to call 55 // addProxy() on the returned object. 56 GrTextureResolveRenderTask* newTextureResolveRenderTask(const GrCaps&); 57 58 // Create a new render task that will cause the gpu to wait on semaphores before executing any 59 // more RenderTasks that target proxy. It is possible for this wait to also block additional 60 // work (even to other proxies) that has already been recorded or will be recorded later. The 61 // only guarantee is that future work to the passed in proxy will wait on the semaphores to be 62 // signaled. 63 void newWaitRenderTask(sk_sp<GrSurfaceProxy> proxy, std::unique_ptr<sk_sp<GrSemaphore>[]>, 64 int numSemaphores); 65 66 // Create a new render task which copies the pixels from the srcProxy into the dstBuffer. This 67 // is used to support the asynchronous readback API. The srcRect is the region of the srcProxy 68 // to be copied. The surfaceColorType says how we should interpret the data when reading back 69 // from the source. DstColorType describes how the data should be stored in the dstBuffer. 70 // DstOffset is the offset into the dstBuffer where we will start writing data. 71 void newTransferFromRenderTask(sk_sp<GrSurfaceProxy> srcProxy, const SkIRect& srcRect, 72 GrColorType surfaceColorType, GrColorType dstColorType, 73 sk_sp<GrGpuBuffer> dstBuffer, size_t dstOffset); 74 75 // Creates a new render task which copies a pixel rectangle from srcProxy into dstProxy. The src 76 // pixels copied are specified by srcRect. They are copied to a rect of the same size in 77 // dstProxy with top left at dstPoint. If the src rect is clipped by the src bounds then pixel 78 // values in the dst rect corresponding to the area clipped by the src rect are not overwritten. 79 // This method is not guaranteed to succeed depending on the type of surface, formats, etc, and 80 // the backend-specific limitations. 81 bool newCopyRenderTask(sk_sp<GrSurfaceProxy> srcProxy, const SkIRect& srcRect, 82 sk_sp<GrSurfaceProxy> dstProxy, const SkIPoint& dstPoint); 83 getContext()84 GrRecordingContext* getContext() { return fContext; } 85 86 GrTextContext* getTextContext(); 87 88 GrPathRenderer* getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args, 89 bool allowSW, 90 GrPathRendererChain::DrawType drawType, 91 GrPathRenderer::StencilSupport* stencilSupport = nullptr); 92 93 GrPathRenderer* getSoftwarePathRenderer(); 94 95 // Returns a direct pointer to the coverage counting path renderer, or null if it is not 96 // supported and turned on. 97 GrCoverageCountingPathRenderer* getCoverageCountingPathRenderer(); 98 99 void flushIfNecessary(); 100 101 static bool ProgramUnitTest(GrContext* context, int maxStages, int maxLevels); 102 103 GrSemaphoresSubmitted flushSurfaces(GrSurfaceProxy* proxies[], 104 int cnt, 105 SkSurface::BackendSurfaceAccess access, 106 const GrFlushInfo& info); flushSurface(GrSurfaceProxy * proxy,SkSurface::BackendSurfaceAccess access,const GrFlushInfo & info)107 GrSemaphoresSubmitted flushSurface(GrSurfaceProxy* proxy, 108 SkSurface::BackendSurfaceAccess access, 109 const GrFlushInfo& info) { 110 return this->flushSurfaces(&proxy, 1, access, info); 111 } 112 113 void addOnFlushCallbackObject(GrOnFlushCallbackObject*); 114 115 #if GR_TEST_UTILS 116 void testingOnly_removeOnFlushCallbackObject(GrOnFlushCallbackObject*); 117 #endif 118 119 void moveRenderTasksToDDL(SkDeferredDisplayList* ddl); 120 void copyRenderTasksFromDDL(const SkDeferredDisplayList*, GrRenderTargetProxy* newDest); 121 122 private: 123 // This class encapsulates maintenance and manipulation of the drawing manager's DAG of 124 // renderTasks. 125 class RenderTaskDAG { 126 public: 127 RenderTaskDAG(bool sortRenderTasks); 128 ~RenderTaskDAG(); 129 130 // Currently, when explicitly allocating resources, this call will topologically sort the 131 // GrRenderTasks. 132 // MDB TODO: remove once incremental GrRenderTask sorting is enabled 133 void prepForFlush(); 134 135 void closeAll(const GrCaps* caps); 136 137 // A yucky combination of closeAll and reset 138 void cleanup(const GrCaps* caps); 139 140 void gatherIDs(SkSTArray<8, uint32_t, true>* idArray) const; 141 142 void reset(); 143 144 // These calls forceably remove a GrRenderTask from the DAG. They are problematic bc they 145 // just remove the GrRenderTask but don't cleanup any refering pointers (i.e., dependency 146 // pointers in the DAG). They work right now bc they are only called at flush time, after 147 // the topological sort is complete (so the dangling pointers aren't used). 148 void removeRenderTask(int index); 149 void removeRenderTasks(int startIndex, int stopIndex); 150 empty()151 bool empty() const { return fRenderTasks.empty(); } numRenderTasks()152 int numRenderTasks() const { return fRenderTasks.count(); } 153 154 bool isUsed(GrSurfaceProxy*) const; 155 renderTask(int index)156 GrRenderTask* renderTask(int index) { return fRenderTasks[index].get(); } renderTask(int index)157 const GrRenderTask* renderTask(int index) const { return fRenderTasks[index].get(); } 158 back()159 GrRenderTask* back() { return fRenderTasks.back().get(); } back()160 const GrRenderTask* back() const { return fRenderTasks.back().get(); } 161 162 GrRenderTask* add(sk_sp<GrRenderTask>); 163 GrRenderTask* addBeforeLast(sk_sp<GrRenderTask>); 164 void add(const SkTArray<sk_sp<GrRenderTask>>&); 165 166 void swap(SkTArray<sk_sp<GrRenderTask>>* renderTasks); 167 sortingRenderTasks()168 bool sortingRenderTasks() const { return fSortRenderTasks; } 169 170 private: 171 SkTArray<sk_sp<GrRenderTask>> fRenderTasks; 172 bool fSortRenderTasks; 173 }; 174 175 GrDrawingManager(GrRecordingContext*, const GrPathRendererChain::Options&, 176 const GrTextContext::Options&, 177 bool sortRenderTasks, 178 bool reduceOpsTaskSplitting); 179 180 bool wasAbandoned() const; 181 182 void cleanup(); 183 184 // Closes the target's dependent render tasks (or, if not in sorting/opsTask-splitting-reduction 185 // mode, closes fActiveOpsTask) in preparation for us opening a new opsTask that will write to 186 // 'target'. 187 void closeRenderTasksForNewRenderTask(GrSurfaceProxy* target); 188 189 // return true if any GrRenderTasks were actually executed; false otherwise 190 bool executeRenderTasks(int startIndex, int stopIndex, GrOpFlushState*, 191 int* numRenderTasksExecuted); 192 193 GrSemaphoresSubmitted flush(GrSurfaceProxy* proxies[], 194 int numProxies, 195 SkSurface::BackendSurfaceAccess access, 196 const GrFlushInfo&, 197 const GrPrepareForExternalIORequests&); 198 199 SkDEBUGCODE(void validate() const); 200 201 friend class GrContext; // access to: flush & cleanup 202 friend class GrContextPriv; // access to: flush 203 friend class GrOnFlushResourceProvider; // this is just a shallow wrapper around this class 204 friend class GrRecordingContext; // access to: ctor 205 friend class SkImage; // for access to: flush 206 207 static const int kNumPixelGeometries = 5; // The different pixel geometries 208 static const int kNumDFTOptions = 2; // DFT or no DFT 209 210 GrRecordingContext* fContext; 211 GrPathRendererChain::Options fOptionsForPathRendererChain; 212 GrTextContext::Options fOptionsForTextContext; 213 // This cache is used by both the vertex and index pools. It reuses memory across multiple 214 // flushes. 215 sk_sp<GrBufferAllocPool::CpuBufferCache> fCpuBufferCache; 216 217 RenderTaskDAG fDAG; 218 GrOpsTask* fActiveOpsTask = nullptr; 219 // These are the IDs of the opsTask currently being flushed (in internalFlush) 220 SkSTArray<8, uint32_t, true> fFlushingRenderTaskIDs; 221 // These are the new renderTasks generated by the onFlush CBs 222 SkSTArray<4, sk_sp<GrRenderTask>> fOnFlushRenderTasks; 223 224 std::unique_ptr<GrTextContext> fTextContext; 225 226 std::unique_ptr<GrPathRendererChain> fPathRendererChain; 227 sk_sp<GrSoftwarePathRenderer> fSoftwarePathRenderer; 228 229 GrTokenTracker fTokenTracker; 230 bool fFlushing; 231 bool fReduceOpsTaskSplitting; 232 233 SkTArray<GrOnFlushCallbackObject*> fOnFlushCBObjects; 234 addDDLTarget(GrSurfaceProxy * proxy)235 void addDDLTarget(GrSurfaceProxy* proxy) { fDDLTargets.insert(proxy); } isDDLTarget(GrSurfaceProxy * proxy)236 bool isDDLTarget(GrSurfaceProxy* proxy) { return fDDLTargets.find(proxy) != fDDLTargets.end(); } clearDDLTargets()237 void clearDDLTargets() { fDDLTargets.clear(); } 238 239 // We play a trick with lazy proxies to retarget the base target of a DDL to the SkSurface 240 // it is replayed on. Because of this remapping we need to explicitly store the targets of 241 // DDL replaying. 242 // Note: we do not expect a whole lot of these per flush 243 std::set<GrSurfaceProxy*> fDDLTargets; 244 }; 245 246 #endif 247