• 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 "include/core/SkSpan.h"
12 #include "include/core/SkSurface.h"
13 #include "include/private/base/SkTArray.h"
14 #include "src/core/SkTHash.h"
15 #include "src/gpu/ganesh/GrBufferAllocPool.h"
16 #include "src/gpu/ganesh/GrDeferredUpload.h"
17 #include "src/gpu/ganesh/GrHashMapWithCache.h"
18 #include "src/gpu/ganesh/GrResourceCache.h"
19 #include "src/gpu/ganesh/GrSamplerState.h"
20 #include "src/gpu/ganesh/GrSurfaceProxy.h"
21 #include "src/gpu/ganesh/PathRenderer.h"
22 #include "src/gpu/ganesh/PathRendererChain.h"
23 
24 // Enabling this will print out which path renderers are being chosen
25 #define GR_PATH_RENDERER_SPEW 0
26 
27 class GrArenas;
28 class GrGpuBuffer;
29 class GrOnFlushCallbackObject;
30 class GrOpFlushState;
31 class GrRecordingContext;
32 class GrRenderTargetProxy;
33 class GrRenderTask;
34 class GrResourceAllocator;
35 class GrSemaphore;
36 class GrSurfaceProxyView;
37 class GrTextureResolveRenderTask;
38 class SkDeferredDisplayList;
39 namespace skgpu { namespace v1 {
40     class OpsTask;
41     class SoftwarePathRenderer;
42 }}
43 
44 class GrDrawingManager {
45 public:
46     ~GrDrawingManager();
47 
48     void freeGpuResources();
49 
50     // OpsTasks created at flush time are stored and handled different from the others.
51     sk_sp<skgpu::v1::OpsTask> newOpsTask(GrSurfaceProxyView,
52                                          sk_sp<GrArenas> arenas);
53 
54     // Adds 'atlasTask' to the DAG and leaves it open.
55     //
56     // If 'previousAtlasTask' is provided, closes it and configures dependencies to guarantee
57     // previousAtlasTask and all its users are completely out of service before atlasTask executes.
58     void addAtlasTask(sk_sp<GrRenderTask> atlasTask, GrRenderTask* previousAtlasTask);
59 
60     // Create a render task that can resolve MSAA and/or regenerate mipmap levels on proxies. This
61     // method will only add the new render task to the list. However, it adds the task before the
62     // last task in the list. It is up to the caller to call addProxy() on the returned object.
63     GrTextureResolveRenderTask* newTextureResolveRenderTaskBefore(const GrCaps&);
64 
65     // Creates a render task that can resolve MSAA and/or regenerate mimap levels on the passed in
66     // proxy. The task is appended to the end of the current list of tasks.
67     void newTextureResolveRenderTask(sk_sp<GrSurfaceProxy> proxy,
68                                      GrSurfaceProxy::ResolveFlags,
69                                      const GrCaps&);
70 
71     // Create a new render task that will cause the gpu to wait on semaphores before executing any
72     // more RenderTasks that target proxy. It is possible for this wait to also block additional
73     // work (even to other proxies) that has already been recorded or will be recorded later. The
74     // only guarantee is that future work to the passed in proxy will wait on the semaphores to be
75     // signaled.
76     void newWaitRenderTask(sk_sp<GrSurfaceProxy> proxy,
77                            std::unique_ptr<std::unique_ptr<GrSemaphore>[]>,
78                            int numSemaphores);
79 
80     // Create a new render task which copies the pixels from the srcProxy into the dstBuffer. This
81     // is used to support the asynchronous readback API. The srcRect is the region of the srcProxy
82     // to be copied. The surfaceColorType says how we should interpret the data when reading back
83     // from the source. DstColorType describes how the data should be stored in the dstBuffer.
84     // DstOffset is the offset into the dstBuffer where we will start writing data.
85     void newTransferFromRenderTask(sk_sp<GrSurfaceProxy> srcProxy, const SkIRect& srcRect,
86                                    GrColorType surfaceColorType, GrColorType dstColorType,
87                                    sk_sp<GrGpuBuffer> dstBuffer, size_t dstOffset);
88 
89     // Creates a new render task which copies a pixel rectangle from srcView into dstView. The src
90     // pixels copied are specified by srcRect. They are copied to the dstRect in dstProxy. Some
91     // backends and formats may require dstRect to have the same size as srcRect. Regardless,
92     // srcRect must be contained by src's dimensions and dstRect must be contained by dst's
93     // dimensions. Any clipping, aspect-ratio adjustment, etc. must be handled prior to this call.
94     //
95     // This method is not guaranteed to succeed depending on the type of surface, formats, etc, and
96     // the backend-specific limitations. On success the task is returned so that the caller may mark
97     // it skippable if the copy is later deemed unnecessary.
98     sk_sp<GrRenderTask> newCopyRenderTask(sk_sp<GrSurfaceProxy> dst,
99                                           SkIRect dstRect,
100                                           sk_sp<GrSurfaceProxy> src,
101                                           SkIRect srcRect,
102                                           GrSamplerState::Filter filter,
103                                           GrSurfaceOrigin);
104 
105     // Adds a render task that copies the range [srcOffset, srcOffset + size] from src to
106     // [dstOffset, dstOffset + size] in dst. The src buffer must have type kXferCpuToGpu and the
107     // dst must NOT have type kXferCpuToGpu. Neither buffer may be mapped when this executes.
108     // Because this is used to insert transfers to vertex/index buffers between draws and we don't
109     // track dependencies with buffers, this task is a hard boundary for task reordering.
110     void newBufferTransferTask(sk_sp<GrGpuBuffer> src,
111                                size_t srcOffset,
112                                sk_sp<GrGpuBuffer> dst,
113                                size_t dstOffset,
114                                size_t size);
115 
116     // Adds a render task that copies the src SkData to [dstOffset, dstOffset + src->size()] in dst.
117     // The dst must not have type kXferCpuToGpu and must not be mapped. Because this is used to
118     // insert updata to vertex/index buffers between draws and we don't track dependencies with
119     // buffers, this task is a hard boundary for task reordering.
120     void newBufferUpdateTask(sk_sp<SkData> src, sk_sp<GrGpuBuffer> dst, size_t dstOffset);
121 
122     // Adds a task that writes the data from the passed GrMipLevels to dst. The lifetime of the
123     // pixel data in the levels should be tied to the passed SkData or the caller must flush the
124     // context before the data may become invalid. srcColorType is the color type of the
125     // GrMipLevels. dstColorType is the color type being used with dst and must be compatible with
126     // dst's format according to GrCaps::areColorTypeAndFormatCompatible().
127     bool newWritePixelsTask(sk_sp<GrSurfaceProxy> dst,
128                             SkIRect rect,
129                             GrColorType srcColorType,
130                             GrColorType dstColorType,
131                             const GrMipLevel[],
132                             int levelCount);
133 
getContext()134     GrRecordingContext* getContext() { return fContext; }
135 
136     using PathRenderer = skgpu::v1::PathRenderer;
137     using PathRendererChain = skgpu::v1::PathRendererChain;
138 
139     PathRenderer* getPathRenderer(const PathRenderer::CanDrawPathArgs&,
140                                   bool allowSW,
141                                   PathRendererChain::DrawType,
142                                   PathRenderer::StencilSupport* = nullptr);
143 
144     PathRenderer* getSoftwarePathRenderer();
145 
146     // Returns a direct pointer to the atlas path renderer, or null if it is not supported and
147     // turned on.
148     skgpu::v1::AtlasPathRenderer* getAtlasPathRenderer();
149 
150     // Returns a direct pointer to the tessellation path renderer, or null if it is not supported
151     // and turned on.
152     PathRenderer* getTessellationPathRenderer();
153 
154     void flushIfNecessary();
155 
156     static bool ProgramUnitTest(GrDirectContext*, int maxStages, int maxLevels);
157 
158     GrSemaphoresSubmitted flushSurfaces(SkSpan<GrSurfaceProxy*>,
159                                         SkSurface::BackendSurfaceAccess,
160                                         const GrFlushInfo&,
161                                         const skgpu::MutableTextureState* newState);
162 
163     void addOnFlushCallbackObject(GrOnFlushCallbackObject*);
164 
165 #if GR_TEST_UTILS
166     void testingOnly_removeOnFlushCallbackObject(GrOnFlushCallbackObject*);
testingOnly_getOptionsForPathRendererChain()167     PathRendererChain::Options testingOnly_getOptionsForPathRendererChain() {
168         return fOptionsForPathRendererChain;
169     }
170 #endif
171 
172     GrRenderTask* getLastRenderTask(const GrSurfaceProxy*) const;
173     skgpu::v1::OpsTask* getLastOpsTask(const GrSurfaceProxy*) const;
174     void setLastRenderTask(const GrSurfaceProxy*, GrRenderTask*);
175 
176     void moveRenderTasksToDDL(SkDeferredDisplayList* ddl);
177     void createDDLTask(sk_sp<const SkDeferredDisplayList>,
178                        sk_sp<GrRenderTargetProxy> newDest,
179                        SkIPoint offset);
180 
181 private:
182     GrDrawingManager(GrRecordingContext*,
183                      const PathRendererChain::Options&,
184                      bool reduceOpsTaskSplitting);
185 
186     bool wasAbandoned() const;
187 
188     void closeActiveOpsTask();
189 
190     // return true if any GrRenderTasks were actually executed; false otherwise
191     bool executeRenderTasks(GrOpFlushState*);
192 
193     void removeRenderTasks();
194 
195     void sortTasks();
196 
197     // Attempt to reorder tasks to reduce render passes, and check the memory budget of the
198     // resulting intervals. Returns whether the reordering was successful & the memory budget
199     // acceptable. If it returns true, fDAG has been updated to reflect the reordered tasks.
200     bool reorderTasks(GrResourceAllocator*);
201 
202     void closeAllTasks();
203 
204     GrRenderTask* appendTask(sk_sp<GrRenderTask>);
205     GrRenderTask* insertTaskBeforeLast(sk_sp<GrRenderTask>);
206 
207     bool flush(SkSpan<GrSurfaceProxy*> proxies,
208                SkSurface::BackendSurfaceAccess access,
209                const GrFlushInfo&,
210                const skgpu::MutableTextureState* newState);
211 
212     bool submitToGpu(bool syncToCpu);
213 
214     SkDEBUGCODE(void validate() const);
215 
216     friend class GrDirectContext; // access to: flush & cleanup
217     friend class GrDirectContextPriv; // access to: flush
218     friend class GrOnFlushResourceProvider; // this is just a shallow wrapper around this class
219     friend class GrRecordingContext;  // access to: ctor
220     friend class SkImage; // for access to: flush
221 
222     static const int kNumPixelGeometries = 5; // The different pixel geometries
223     static const int kNumDFTOptions = 2;      // DFT or no DFT
224 
225     GrRecordingContext*                      fContext;
226 
227     // This cache is used by both the vertex and index pools. It reuses memory across multiple
228     // flushes.
229     sk_sp<GrBufferAllocPool::CpuBufferCache> fCpuBufferCache;
230 
231     SkTArray<sk_sp<GrRenderTask>>            fDAG;
232     std::vector<int>                         fReorderBlockerTaskIndices;
233     skgpu::v1::OpsTask*                      fActiveOpsTask = nullptr;
234 
235     PathRendererChain::Options               fOptionsForPathRendererChain;
236     std::unique_ptr<PathRendererChain>       fPathRendererChain;
237     sk_sp<skgpu::v1::SoftwarePathRenderer>   fSoftwarePathRenderer;
238 
239     skgpu::TokenTracker                      fTokenTracker;
240     bool                                     fFlushing = false;
241     const bool                               fReduceOpsTaskSplitting;
242 
243     SkTArray<GrOnFlushCallbackObject*>       fOnFlushCBObjects;
244 
245     struct SurfaceIDKeyTraits {
GetInvalidKeySurfaceIDKeyTraits246         static uint32_t GetInvalidKey() {
247             return GrSurfaceProxy::UniqueID::InvalidID().asUInt();
248         }
249     };
250 
251     GrHashMapWithCache<uint32_t, GrRenderTask*, SurfaceIDKeyTraits, GrCheapHash> fLastRenderTasks;
252 };
253 
254 #endif
255