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 "GrDeferredUpload.h" 12 #include "GrPathRenderer.h" 13 #include "GrPathRendererChain.h" 14 #include "GrResourceCache.h" 15 #include "SkTArray.h" 16 #include "text/GrTextContext.h" 17 18 class GrContext; 19 class GrCoverageCountingPathRenderer; 20 class GrOnFlushCallbackObject; 21 class GrOpFlushState; 22 class GrRenderTargetContext; 23 class GrRenderTargetProxy; 24 class GrSingleOWner; 25 class GrRenderTargetOpList; 26 class GrSoftwarePathRenderer; 27 class GrTextureContext; 28 class GrTextureOpList; 29 class SkDeferredDisplayList; 30 31 // The GrDrawingManager allocates a new GrRenderTargetContext for each GrRenderTarget 32 // but all of them still land in the same GrOpList! 33 // 34 // In the future this class will allocate a new GrRenderTargetContext for 35 // each GrRenderTarget/GrOpList and manage the DAG. 36 class GrDrawingManager { 37 public: 38 ~GrDrawingManager(); 39 wasAbandoned()40 bool wasAbandoned() const { return fAbandoned; } 41 void freeGpuResources(); 42 43 sk_sp<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrSurfaceProxy>, 44 sk_sp<SkColorSpace>, 45 const SkSurfaceProps*, 46 bool managedOpList = true); 47 sk_sp<GrTextureContext> makeTextureContext(sk_sp<GrSurfaceProxy>, sk_sp<SkColorSpace>); 48 49 // The caller automatically gets a ref on the returned opList. It must 50 // be balanced by an unref call. 51 // A managed opList is controlled by the drawing manager (i.e., sorted & flushed with the 52 // other). An unmanaged one is created and used by the onFlushCallback. 53 sk_sp<GrRenderTargetOpList> newRTOpList(GrRenderTargetProxy* rtp, bool managedOpList); 54 sk_sp<GrTextureOpList> newTextureOpList(GrTextureProxy* textureProxy); 55 getContext()56 GrContext* getContext() { return fContext; } 57 58 GrTextContext* getTextContext(); 59 60 GrPathRenderer* getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args, 61 bool allowSW, 62 GrPathRendererChain::DrawType drawType, 63 GrPathRenderer::StencilSupport* stencilSupport = nullptr); 64 65 GrPathRenderer* getSoftwarePathRenderer(); 66 67 // Returns a direct pointer to the coverage counting path renderer, or null if it is not 68 // supported and turned on. 69 GrCoverageCountingPathRenderer* getCoverageCountingPathRenderer(); 70 71 void flushIfNecessary(); 72 73 static bool ProgramUnitTest(GrContext* context, int maxStages, int maxLevels); 74 75 GrSemaphoresSubmitted prepareSurfaceForExternalIO(GrSurfaceProxy*, 76 int numSemaphores, 77 GrBackendSemaphore backendSemaphores[]); 78 79 void addOnFlushCallbackObject(GrOnFlushCallbackObject*); 80 void testingOnly_removeOnFlushCallbackObject(GrOnFlushCallbackObject*); 81 82 void moveOpListsToDDL(SkDeferredDisplayList* ddl); 83 void copyOpListsFromDDL(const SkDeferredDisplayList*, GrRenderTargetProxy* newDest); 84 85 private: 86 // This class encapsulates maintenance and manipulation of the drawing manager's DAG of opLists. 87 class OpListDAG { 88 public: 89 OpListDAG(bool explicitlyAllocating, GrContextOptions::Enable sortOpLists); 90 ~OpListDAG(); 91 92 // Currently, when explicitly allocating resources, this call will topologically sort the 93 // opLists. 94 // MDB TODO: remove once incremental opList sorting is enabled 95 void prepForFlush(); 96 97 void closeAll(const GrCaps* caps); 98 99 // A yucky combination of closeAll and reset 100 void cleanup(const GrCaps* caps); 101 102 void gatherIDs(SkSTArray<8, uint32_t, true>* idArray) const; 103 104 void reset(); 105 106 // These calls forceably remove an opList from the DAG. They are problematic bc they just 107 // remove the opList but don't cleanup any refering pointers (i.e., dependency pointers 108 // in the DAG). They work right now bc they are only called at flush time, after the 109 // topological sort is complete (so the dangling pointers aren't used). 110 void removeOpList(int index); 111 void removeOpLists(int startIndex, int stopIndex); 112 empty()113 bool empty() const { return fOpLists.empty(); } numOpLists()114 int numOpLists() const { return fOpLists.count(); } 115 opList(int index)116 GrOpList* opList(int index) { return fOpLists[index].get(); } opList(int index)117 const GrOpList* opList(int index) const { return fOpLists[index].get(); } 118 back()119 GrOpList* back() { return fOpLists.back().get(); } back()120 const GrOpList* back() const { return fOpLists.back().get(); } 121 122 void add(sk_sp<GrOpList>); 123 void add(const SkTArray<sk_sp<GrOpList>>&); 124 125 void swap(SkTArray<sk_sp<GrOpList>>* opLists); 126 sortingOpLists()127 bool sortingOpLists() const { return fSortOpLists; } 128 129 private: 130 SkTArray<sk_sp<GrOpList>> fOpLists; 131 bool fSortOpLists; 132 }; 133 134 GrDrawingManager(GrContext*, const GrPathRendererChain::Options&, 135 const GrTextContext::Options&, GrSingleOwner*, 136 bool explicitlyAllocating, GrContextOptions::Enable sortRenderTargets, 137 GrContextOptions::Enable reduceOpListSplitting); 138 139 void abandon(); 140 void cleanup(); 141 142 // return true if any opLists were actually executed; false otherwise 143 bool executeOpLists(int startIndex, int stopIndex, GrOpFlushState*, int* numOpListsExecuted); 144 145 GrSemaphoresSubmitted flush(GrSurfaceProxy* proxy, 146 int numSemaphores = 0, 147 GrBackendSemaphore backendSemaphores[] = nullptr); 148 149 SkDEBUGCODE(void validate() const); 150 151 friend class GrContext; // for access to: ctor, abandon, reset & flush 152 friend class GrContextPriv; // access to: flush 153 friend class GrOnFlushResourceProvider; // this is just a shallow wrapper around this class 154 155 static const int kNumPixelGeometries = 5; // The different pixel geometries 156 static const int kNumDFTOptions = 2; // DFT or no DFT 157 158 GrContext* fContext; 159 GrPathRendererChain::Options fOptionsForPathRendererChain; 160 GrTextContext::Options fOptionsForTextContext; 161 162 std::unique_ptr<char[]> fVertexBufferSpace; 163 std::unique_ptr<char[]> fIndexBufferSpace; 164 // In debug builds we guard against improper thread handling 165 GrSingleOwner* fSingleOwner; 166 167 bool fAbandoned; 168 OpListDAG fDAG; 169 GrOpList* fActiveOpList = nullptr; 170 // These are the IDs of the opLists currently being flushed (in internalFlush) 171 SkSTArray<8, uint32_t, true> fFlushingOpListIDs; 172 // These are the new opLists generated by the onFlush CBs 173 SkSTArray<8, sk_sp<GrOpList>> fOnFlushCBOpLists; 174 175 std::unique_ptr<GrTextContext> fTextContext; 176 177 std::unique_ptr<GrPathRendererChain> fPathRendererChain; 178 sk_sp<GrSoftwarePathRenderer> fSoftwarePathRenderer; 179 180 GrTokenTracker fTokenTracker; 181 bool fFlushing; 182 bool fReduceOpListSplitting; 183 184 SkTArray<GrOnFlushCallbackObject*> fOnFlushCBObjects; 185 }; 186 187 #endif 188