blob: 63d117593059b1188edb334f50685c4aafb41fc1 [file] [log] [blame]
robertphillips3dc6ae52015-10-20 09:54:32 -07001/*
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
bsalomon5eb41fd2016-09-06 13:49:32 -07008#include "GrDrawingManager.h"
bsalomonb77a9072016-09-07 10:02:04 -07009
Greg Daniel51316782017-08-02 15:10:09 +000010#include "GrBackendSemaphore.h"
bsalomonb77a9072016-09-07 10:02:04 -070011#include "GrContext.h"
Robert Phillips1afd4cd2018-01-08 13:40:32 -050012#include "GrContextPriv.h"
Robert Phillips646e4292017-06-13 12:44:56 -040013#include "GrGpu.h"
Robert Phillipsfbcef6e2017-06-15 12:07:18 -040014#include "GrOnFlushResourceProvider.h"
Robert Phillips9d6c64f2017-09-14 10:56:45 -040015#include "GrOpList.h"
Brian Osman11052242016-10-27 14:47:55 -040016#include "GrRenderTargetContext.h"
Robert Phillipsc7635fa2016-10-28 13:25:24 -040017#include "GrRenderTargetProxy.h"
Robert Phillipsd375dbf2017-09-14 12:45:25 -040018#include "GrResourceAllocator.h"
robertphillips3dc6ae52015-10-20 09:54:32 -070019#include "GrResourceProvider.h"
robertphillips68737822015-10-29 12:12:21 -070020#include "GrSoftwarePathRenderer.h"
Robert Phillips7ee385e2017-03-30 08:02:11 -040021#include "GrSurfaceProxyPriv.h"
Brian Osman45580d32016-11-23 09:37:01 -050022#include "GrTextureContext.h"
23#include "GrTextureOpList.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070024#include "GrTextureProxy.h"
25#include "GrTextureProxyPriv.h"
Robert Phillips62000362018-02-01 09:10:04 -050026
27#include "SkDeferredDisplayList.h"
brianosman0e22eb82016-08-30 07:07:59 -070028#include "SkSurface_Gpu.h"
robertphillips3dc6ae52015-10-20 09:54:32 -070029#include "SkTTopoSort.h"
30
Brian Salomondcbb9d92017-07-19 10:53:20 -040031#include "GrTracing.h"
joshualitte8042922015-12-11 06:11:21 -080032#include "text/GrAtlasTextContext.h"
robertphillips498d7ac2015-10-30 10:11:30 -070033
Robert Phillipsa3f70262018-02-08 10:59:38 -050034// Turn on/off the sorting of opLists at flush time
35#ifndef SK_DISABLE_RENDER_TARGET_SORTING
36 #define SK_DISABLE_RENDER_TARGET_SORTING
37#endif
38
39#ifdef SK_DISABLE_RENDER_TARGET_SORTING
40static const bool kDefaultSortRenderTargets = false;
41#else
42static const bool kDefaultSortRenderTargets = true;
43#endif
44
45GrDrawingManager::GrDrawingManager(GrContext* context,
46 const GrPathRendererChain::Options& optionsForPathRendererChain,
47 const GrAtlasTextContext::Options& optionsForAtlasTextContext,
48 GrSingleOwner* singleOwner,
49 GrContextOptions::Enable sortRenderTargets)
50 : fContext(context)
51 , fOptionsForPathRendererChain(optionsForPathRendererChain)
52 , fOptionsForAtlasTextContext(optionsForAtlasTextContext)
53 , fSingleOwner(singleOwner)
54 , fAbandoned(false)
55 , fAtlasTextContext(nullptr)
56 , fPathRendererChain(nullptr)
57 , fSoftwarePathRenderer(nullptr)
58 , fFlushing(false) {
59
60 if (GrContextOptions::Enable::kNo == sortRenderTargets) {
61 fSortRenderTargets = false;
62 } else if (GrContextOptions::Enable::kYes == sortRenderTargets) {
63 fSortRenderTargets = true;
64 } else {
65 fSortRenderTargets = kDefaultSortRenderTargets;
66 }
67}
68
robertphillips3dc6ae52015-10-20 09:54:32 -070069void GrDrawingManager::cleanup() {
Robert Phillipsf2361d22016-10-25 14:20:06 -040070 for (int i = 0; i < fOpLists.count(); ++i) {
Robert Phillipsee683652017-04-26 11:53:10 -040071 // no opList should receive a new command after this
72 fOpLists[i]->makeClosed(*fContext->caps());
robertphillips0dfa62c2015-11-16 06:23:31 -080073
Robert Phillipsf2361d22016-10-25 14:20:06 -040074 // We shouldn't need to do this, but it turns out some clients still hold onto opLists
Robert Phillips6cdc22c2017-05-11 16:29:14 -040075 // after a cleanup.
76 // MDB TODO: is this still true?
Chris Daltona84cacf2017-10-04 10:30:29 -060077 if (!fOpLists[i]->unique()) {
78 // TODO: Eventually this should be guaranteed unique.
79 // https://bugs.chromium.org/p/skia/issues/detail?id=7111
80 fOpLists[i]->endFlush();
81 }
robertphillips3dc6ae52015-10-20 09:54:32 -070082 }
83
Robert Phillipsf2361d22016-10-25 14:20:06 -040084 fOpLists.reset();
robertphillips3dc6ae52015-10-20 09:54:32 -070085
robertphillips13391dd2015-10-30 05:15:11 -070086 delete fPathRendererChain;
87 fPathRendererChain = nullptr;
robertphillips68737822015-10-29 12:12:21 -070088 SkSafeSetNull(fSoftwarePathRenderer);
Jim Van Verth106b5c42017-09-26 12:45:29 -040089
90 fOnFlushCBObjects.reset();
robertphillips3dc6ae52015-10-20 09:54:32 -070091}
92
93GrDrawingManager::~GrDrawingManager() {
94 this->cleanup();
95}
96
97void GrDrawingManager::abandon() {
98 fAbandoned = true;
99 this->cleanup();
100}
101
robertphillips68737822015-10-29 12:12:21 -0700102void GrDrawingManager::freeGpuResources() {
Jim Van Verth106b5c42017-09-26 12:45:29 -0400103 for (int i = fOnFlushCBObjects.count() - 1; i >= 0; --i) {
104 if (!fOnFlushCBObjects[i]->retainOnFreeGpuResources()) {
105 // it's safe to just do this because we're iterating in reverse
106 fOnFlushCBObjects.removeShuffle(i);
107 }
108 }
109
robertphillips68737822015-10-29 12:12:21 -0700110 // a path renderer may be holding onto resources
robertphillips13391dd2015-10-30 05:15:11 -0700111 delete fPathRendererChain;
112 fPathRendererChain = nullptr;
robertphillips68737822015-10-29 12:12:21 -0700113 SkSafeSetNull(fSoftwarePathRenderer);
Robert Phillipse3302df2017-04-24 07:31:02 -0400114}
115
Robert Phillips7ee385e2017-03-30 08:02:11 -0400116// MDB TODO: make use of the 'proxy' parameter.
Greg Daniel51316782017-08-02 15:10:09 +0000117GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
118 GrResourceCache::FlushType type,
119 int numSemaphores,
120 GrBackendSemaphore backendSemaphores[]) {
Brian Salomondcbb9d92017-07-19 10:53:20 -0400121 GR_CREATE_TRACE_MARKER_CONTEXT("GrDrawingManager", "internalFlush", fContext);
122
robertphillips7761d612016-05-16 09:14:53 -0700123 if (fFlushing || this->wasAbandoned()) {
Greg Daniel51316782017-08-02 15:10:09 +0000124 return GrSemaphoresSubmitted::kNo;
joshualittb8918c42015-12-18 09:59:46 -0800125 }
126 fFlushing = true;
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400127
128 for (int i = 0; i < fOpLists.count(); ++i) {
129 // Semi-usually the GrOpLists are already closed at this point, but sometimes Ganesh
130 // needs to flush mid-draw. In that case, the SkGpuDevice's GrOpLists won't be closed
131 // but need to be flushed anyway. Closing such GrOpLists here will mean new
132 // GrOpLists will be created to replace them if the SkGpuDevice(s) write to them again.
Robert Phillipsee683652017-04-26 11:53:10 -0400133 fOpLists[i]->makeClosed(*fContext->caps());
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400134 }
135
Robert Phillipsa4c93ac2017-05-18 11:40:04 -0400136#ifdef SK_DEBUG
137 // This block checks for any unnecessary splits in the opLists. If two sequential opLists
138 // share the same backing GrSurfaceProxy it means the opList was artificially split.
139 if (fOpLists.count()) {
140 GrRenderTargetOpList* prevOpList = fOpLists[0]->asRenderTargetOpList();
141 for (int i = 1; i < fOpLists.count(); ++i) {
142 GrRenderTargetOpList* curOpList = fOpLists[i]->asRenderTargetOpList();
143
144 if (prevOpList && curOpList) {
145 SkASSERT(prevOpList->fTarget.get() != curOpList->fTarget.get());
146 }
147
148 prevOpList = curOpList;
149 }
150 }
151#endif
152
Robert Phillips4150eea2018-02-07 17:08:21 -0500153 if (fSortRenderTargets) {
154 SkDEBUGCODE(bool result =) SkTTopoSort<GrOpList, GrOpList::TopoSortTraits>(&fOpLists);
155 SkASSERT(result);
156 }
robertphillips3dc6ae52015-10-20 09:54:32 -0700157
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500158 GrGpu* gpu = fContext->contextPriv().getGpu();
159
160 GrOpFlushState flushState(gpu, fContext->contextPriv().resourceProvider(),
Robert Phillips40a29d72018-01-18 12:59:22 -0500161 &fTokenTracker);
162
Chris Daltonfe199b72017-05-05 11:26:15 -0400163 GrOnFlushResourceProvider onFlushProvider(this);
Robert Phillipseafd48a2017-11-16 07:52:08 -0500164 // TODO: AFAICT the only reason fFlushState is on GrDrawingManager rather than on the
165 // stack here is to preserve the flush tokens.
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400166
Chris Dalton12658942017-10-05 19:45:25 -0600167 // Prepare any onFlush op lists (e.g. atlases).
Chris Daltonfe199b72017-05-05 11:26:15 -0400168 if (!fOnFlushCBObjects.empty()) {
Chris Dalton3968ff92017-11-27 12:26:31 -0700169 fFlushingOpListIDs.reset(fOpLists.count());
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400170 for (int i = 0; i < fOpLists.count(); ++i) {
Chris Dalton3968ff92017-11-27 12:26:31 -0700171 fFlushingOpListIDs[i] = fOpLists[i]->uniqueID();
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400172 }
Chris Dalton12658942017-10-05 19:45:25 -0600173 SkSTArray<4, sk_sp<GrRenderTargetContext>> renderTargetContexts;
Chris Daltonfe199b72017-05-05 11:26:15 -0400174 for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) {
175 onFlushCBObject->preFlush(&onFlushProvider,
Chris Dalton3968ff92017-11-27 12:26:31 -0700176 fFlushingOpListIDs.begin(), fFlushingOpListIDs.count(),
Chris Daltonfe199b72017-05-05 11:26:15 -0400177 &renderTargetContexts);
Chris Dalton12658942017-10-05 19:45:25 -0600178 for (const sk_sp<GrRenderTargetContext>& rtc : renderTargetContexts) {
Chris Dalton706a6ff2017-11-29 22:01:06 -0700179 sk_sp<GrRenderTargetOpList> onFlushOpList = sk_ref_sp(rtc->getRTOpList());
Chris Dalton12658942017-10-05 19:45:25 -0600180 if (!onFlushOpList) {
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400181 continue; // Odd - but not a big deal
182 }
Chris Dalton706a6ff2017-11-29 22:01:06 -0700183#ifdef SK_DEBUG
184 // OnFlush callbacks are already invoked during flush, and are therefore expected to
185 // handle resource allocation & usage on their own. (No deferred or lazy proxies!)
186 onFlushOpList->visitProxies_debugOnly([](GrSurfaceProxy* p) {
187 SkASSERT(!p->asTextureProxy() || !p->asTextureProxy()->texPriv().isDeferred());
Greg Daniel65fa8ca2018-01-10 17:06:31 -0500188 SkASSERT(GrSurfaceProxy::LazyState::kNot == p->lazyInstantiationState());
Chris Dalton706a6ff2017-11-29 22:01:06 -0700189 });
190#endif
Chris Dalton12658942017-10-05 19:45:25 -0600191 onFlushOpList->makeClosed(*fContext->caps());
Robert Phillips40a29d72018-01-18 12:59:22 -0500192 onFlushOpList->prepare(&flushState);
Chris Dalton3968ff92017-11-27 12:26:31 -0700193 fOnFlushCBOpLists.push_back(std::move(onFlushOpList));
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400194 }
195 renderTargetContexts.reset();
196 }
197 }
198
robertphillipsa13e2022015-11-11 12:01:09 -0800199#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500200 // Enable this to print out verbose GrOp information
Robert Phillipsf2361d22016-10-25 14:20:06 -0400201 for (int i = 0; i < fOpLists.count(); ++i) {
202 SkDEBUGCODE(fOpLists[i]->dump();)
robertphillips3dc6ae52015-10-20 09:54:32 -0700203 }
robertphillipsa13e2022015-11-11 12:01:09 -0800204#endif
205
Robert Phillipseafd48a2017-11-16 07:52:08 -0500206 int startIndex, stopIndex;
207 bool flushed = false;
208
Robert Phillipsf8e25022017-11-08 15:24:31 -0500209 {
Robert Phillips6be756b2018-01-16 15:07:54 -0500210 GrResourceAllocator alloc(fContext->contextPriv().resourceProvider());
Robert Phillipsf8e25022017-11-08 15:24:31 -0500211 for (int i = 0; i < fOpLists.count(); ++i) {
212 fOpLists[i]->gatherProxyIntervals(&alloc);
Robert Phillipseafd48a2017-11-16 07:52:08 -0500213 alloc.markEndOfOpList(i);
Robert Phillipsf8e25022017-11-08 15:24:31 -0500214 }
Robert Phillipsd375dbf2017-09-14 12:45:25 -0400215
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500216 GrResourceAllocator::AssignError error = GrResourceAllocator::AssignError::kNoError;
Greg Daniel4684f822018-03-08 15:27:36 -0500217 while (alloc.assign(&startIndex, &stopIndex, flushState.uninstantiateProxyTracker(),
218 &error)) {
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500219 if (GrResourceAllocator::AssignError::kFailedProxyInstantiation == error) {
220 for (int i = startIndex; i < stopIndex; ++i) {
221 fOpLists[i]->purgeOpsWithUninstantiatedProxies();
222 }
223 }
Robert Phillips4150eea2018-02-07 17:08:21 -0500224
Robert Phillips40a29d72018-01-18 12:59:22 -0500225 if (this->executeOpLists(startIndex, stopIndex, &flushState)) {
Robert Phillipseafd48a2017-11-16 07:52:08 -0500226 flushed = true;
227 }
bsalomondc438982016-08-31 11:53:49 -0700228 }
Greg Danielc42b20b2017-10-04 10:34:49 -0400229 }
230
Robert Phillips18e94842017-05-15 13:06:44 -0400231 fOpLists.reset();
robertphillipsa13e2022015-11-11 12:01:09 -0800232
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500233 GrSemaphoresSubmitted result = gpu->finishFlush(numSemaphores, backendSemaphores);
robertphillipsa13e2022015-11-11 12:01:09 -0800234
Greg Daniel4684f822018-03-08 15:27:36 -0500235 flushState.uninstantiateProxyTracker()->uninstantiateAllProxies();
236
robertphillipsee843b22016-10-04 05:30:20 -0700237 // We always have to notify the cache when it requested a flush so it can reset its state.
238 if (flushed || type == GrResourceCache::FlushType::kCacheRequested) {
Robert Phillips6be756b2018-01-16 15:07:54 -0500239 fContext->contextPriv().getResourceCache()->notifyFlushOccurred(type);
bsalomonb77a9072016-09-07 10:02:04 -0700240 }
Chris Daltonfe199b72017-05-05 11:26:15 -0400241 for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) {
Robert Phillips40a29d72018-01-18 12:59:22 -0500242 onFlushCBObject->postFlush(fTokenTracker.nextTokenToFlush(), fFlushingOpListIDs.begin(),
Chris Dalton3968ff92017-11-27 12:26:31 -0700243 fFlushingOpListIDs.count());
Chris Daltonfe199b72017-05-05 11:26:15 -0400244 }
Chris Dalton3968ff92017-11-27 12:26:31 -0700245 fFlushingOpListIDs.reset();
joshualittb8918c42015-12-18 09:59:46 -0800246 fFlushing = false;
Greg Daniel51316782017-08-02 15:10:09 +0000247
248 return result;
robertphillips3dc6ae52015-10-20 09:54:32 -0700249}
250
Robert Phillipseafd48a2017-11-16 07:52:08 -0500251bool GrDrawingManager::executeOpLists(int startIndex, int stopIndex, GrOpFlushState* flushState) {
252 SkASSERT(startIndex <= stopIndex && stopIndex <= fOpLists.count());
253
Robert Phillips4150eea2018-02-07 17:08:21 -0500254 GrResourceProvider* resourceProvider = fContext->contextPriv().resourceProvider();
Robert Phillipseafd48a2017-11-16 07:52:08 -0500255 bool anyOpListsExecuted = false;
256
257 for (int i = startIndex; i < stopIndex; ++i) {
258 if (!fOpLists[i]) {
259 continue;
260 }
261
Robert Phillips4150eea2018-02-07 17:08:21 -0500262 if (resourceProvider->explicitlyAllocateGPUResources()) {
263 if (!fOpLists[i]->isInstantiated()) {
264 // If the backing surface wasn't allocated drop the draw of the entire opList.
265 fOpLists[i] = nullptr;
266 continue;
267 }
268 } else {
269 if (!fOpLists[i]->instantiate(resourceProvider)) {
270 SkDebugf("OpList failed to instantiate.\n");
271 fOpLists[i] = nullptr;
272 continue;
273 }
Robert Phillipseafd48a2017-11-16 07:52:08 -0500274 }
Robert Phillipseafd48a2017-11-16 07:52:08 -0500275
276 // TODO: handle this instantiation via lazy surface proxies?
277 // Instantiate all deferred proxies (being built on worker threads) so we can upload them
Robert Phillips6be756b2018-01-16 15:07:54 -0500278 fOpLists[i]->instantiateDeferredProxies(fContext->contextPriv().resourceProvider());
Robert Phillipseafd48a2017-11-16 07:52:08 -0500279 fOpLists[i]->prepare(flushState);
280 }
281
282 // Upload all data to the GPU
283 flushState->preExecuteDraws();
284
285 // Execute the onFlush op lists first, if any.
Chris Dalton3968ff92017-11-27 12:26:31 -0700286 for (sk_sp<GrOpList>& onFlushOpList : fOnFlushCBOpLists) {
Robert Phillipseafd48a2017-11-16 07:52:08 -0500287 if (!onFlushOpList->execute(flushState)) {
288 SkDebugf("WARNING: onFlushOpList failed to execute.\n");
289 }
290 SkASSERT(onFlushOpList->unique());
291 onFlushOpList = nullptr;
292 }
Chris Dalton3968ff92017-11-27 12:26:31 -0700293 fOnFlushCBOpLists.reset();
Robert Phillipseafd48a2017-11-16 07:52:08 -0500294
295 // Execute the normal op lists.
296 for (int i = startIndex; i < stopIndex; ++i) {
297 if (!fOpLists[i]) {
298 continue;
299 }
300
301 if (fOpLists[i]->execute(flushState)) {
302 anyOpListsExecuted = true;
303 }
304 }
305
306 SkASSERT(!flushState->commandBuffer());
Robert Phillips40a29d72018-01-18 12:59:22 -0500307 SkASSERT(fTokenTracker.nextDrawToken() == fTokenTracker.nextTokenToFlush());
Robert Phillipseafd48a2017-11-16 07:52:08 -0500308
309 // We reset the flush state before the OpLists so that the last resources to be freed are those
310 // that are written to in the OpLists. This helps to make sure the most recently used resources
311 // are the last to be purged by the resource cache.
312 flushState->reset();
313
314 for (int i = startIndex; i < stopIndex; ++i) {
315 if (!fOpLists[i]) {
316 continue;
317 }
318 if (!fOpLists[i]->unique()) {
319 // TODO: Eventually this should be guaranteed unique.
320 // https://bugs.chromium.org/p/skia/issues/detail?id=7111
321 fOpLists[i]->endFlush();
322 }
323 fOpLists[i] = nullptr;
324 }
325
326 return anyOpListsExecuted;
327}
328
Greg Daniel51316782017-08-02 15:10:09 +0000329GrSemaphoresSubmitted GrDrawingManager::prepareSurfaceForExternalIO(
330 GrSurfaceProxy* proxy, int numSemaphores, GrBackendSemaphore backendSemaphores[]) {
bsalomon6a2b1942016-09-08 11:28:59 -0700331 if (this->wasAbandoned()) {
Greg Daniel51316782017-08-02 15:10:09 +0000332 return GrSemaphoresSubmitted::kNo;
bsalomon6a2b1942016-09-08 11:28:59 -0700333 }
Robert Phillips7ee385e2017-03-30 08:02:11 -0400334 SkASSERT(proxy);
bsalomon6a2b1942016-09-08 11:28:59 -0700335
Kevin Lubick42846132018-01-05 10:11:11 -0500336 GrSemaphoresSubmitted result = GrSemaphoresSubmitted::kNo;
Greg Daniel51316782017-08-02 15:10:09 +0000337 if (proxy->priv().hasPendingIO() || numSemaphores) {
338 result = this->flush(proxy, numSemaphores, backendSemaphores);
bsalomon6a2b1942016-09-08 11:28:59 -0700339 }
340
Robert Phillips6be756b2018-01-16 15:07:54 -0500341 if (!proxy->instantiate(fContext->contextPriv().resourceProvider())) {
Greg Daniel51316782017-08-02 15:10:09 +0000342 return result;
Robert Phillips7ee385e2017-03-30 08:02:11 -0400343 }
344
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500345 GrGpu* gpu = fContext->contextPriv().getGpu();
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400346 GrSurface* surface = proxy->priv().peekSurface();
347
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500348 if (gpu && surface->asRenderTarget()) {
Brian Salomon1fabd512018-02-09 09:54:25 -0500349 gpu->resolveRenderTarget(surface->asRenderTarget());
bsalomon6a2b1942016-09-08 11:28:59 -0700350 }
Greg Daniel51316782017-08-02 15:10:09 +0000351 return result;
bsalomon6a2b1942016-09-08 11:28:59 -0700352}
353
Chris Daltonfe199b72017-05-05 11:26:15 -0400354void GrDrawingManager::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
355 fOnFlushCBObjects.push_back(onFlushCBObject);
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400356}
357
Robert Phillips62000362018-02-01 09:10:04 -0500358void GrDrawingManager::moveOpListsToDDL(SkDeferredDisplayList* ddl) {
359#ifndef SK_RASTER_RECORDER_IMPLEMENTATION
Robert Phillips7a137052018-02-01 11:23:12 -0500360 for (int i = 0; i < fOpLists.count(); ++i) {
361 // no opList should receive a new command after this
362 fOpLists[i]->makeClosed(*fContext->caps());
363 }
364
Robert Phillips62000362018-02-01 09:10:04 -0500365 ddl->fOpLists = std::move(fOpLists);
366#endif
367}
368
369void GrDrawingManager::copyOpListsFromDDL(const SkDeferredDisplayList* ddl,
370 GrRenderTargetProxy* newDest) {
371#ifndef SK_RASTER_RECORDER_IMPLEMENTATION
372 // Here we jam the proxy that backs the current replay SkSurface into the LazyProxyData.
373 // The lazy proxy that references it (in the copied opLists) will steal its GrTexture.
374 ddl->fLazyProxyData->fReplayDest = newDest;
375 fOpLists.push_back_n(ddl->fOpLists.count(), ddl->fOpLists.begin());
376#endif
377}
378
Robert Phillips941d1442017-06-14 16:37:02 -0400379sk_sp<GrRenderTargetOpList> GrDrawingManager::newRTOpList(GrRenderTargetProxy* rtp,
380 bool managedOpList) {
robertphillips3dc6ae52015-10-20 09:54:32 -0700381 SkASSERT(fContext);
382
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400383 // This is a temporary fix for the partial-MDB world. In that world we're not reordering
384 // so ops that (in the single opList world) would've just glommed onto the end of the single
385 // opList but referred to a far earlier RT need to appear in their own opList.
386 if (!fOpLists.empty()) {
387 fOpLists.back()->makeClosed(*fContext->caps());
robertphillips3dc6ae52015-10-20 09:54:32 -0700388 }
robertphillips3dc6ae52015-10-20 09:54:32 -0700389
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500390 auto resourceProvider = fContext->contextPriv().resourceProvider();
391
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500392 sk_sp<GrRenderTargetOpList> opList(new GrRenderTargetOpList(
393 rtp,
394 resourceProvider,
395 fContext->contextPriv().getAuditTrail()));
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400396 SkASSERT(rtp->getLastOpList() == opList.get());
robertphillips3dc6ae52015-10-20 09:54:32 -0700397
Robert Phillips941d1442017-06-14 16:37:02 -0400398 if (managedOpList) {
399 fOpLists.push_back() = opList;
400 }
robertphillips3dc6ae52015-10-20 09:54:32 -0700401
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400402 return opList;
robertphillips3dc6ae52015-10-20 09:54:32 -0700403}
404
Robert Phillipsb6deea82017-05-11 14:14:30 -0400405sk_sp<GrTextureOpList> GrDrawingManager::newTextureOpList(GrTextureProxy* textureProxy) {
Brian Osman45580d32016-11-23 09:37:01 -0500406 SkASSERT(fContext);
407
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400408 // This is a temporary fix for the partial-MDB world. In that world we're not reordering
409 // so ops that (in the single opList world) would've just glommed onto the end of the single
410 // opList but referred to a far earlier RT need to appear in their own opList.
411 if (!fOpLists.empty()) {
412 fOpLists.back()->makeClosed(*fContext->caps());
413 }
414
Robert Phillips6be756b2018-01-16 15:07:54 -0500415 sk_sp<GrTextureOpList> opList(new GrTextureOpList(fContext->contextPriv().resourceProvider(),
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400416 textureProxy,
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500417 fContext->contextPriv().getAuditTrail()));
Brian Osman45580d32016-11-23 09:37:01 -0500418
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400419 SkASSERT(textureProxy->getLastOpList() == opList.get());
Robert Phillips4a395042017-04-24 16:27:17 +0000420
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400421 fOpLists.push_back() = opList;
422
Robert Phillips4a395042017-04-24 16:27:17 +0000423 return opList;
Brian Osman45580d32016-11-23 09:37:01 -0500424}
425
brianosman86e76262016-08-11 12:17:31 -0700426GrAtlasTextContext* GrDrawingManager::getAtlasTextContext() {
427 if (!fAtlasTextContext) {
Brian Salomonaf597482017-11-07 16:23:34 -0500428 fAtlasTextContext = GrAtlasTextContext::Make(fOptionsForAtlasTextContext);
brianosman86e76262016-08-11 12:17:31 -0700429 }
430
431 return fAtlasTextContext.get();
432}
433
robertphillips68737822015-10-29 12:12:21 -0700434/*
435 * This method finds a path renderer that can draw the specified path on
436 * the provided target.
437 * Due to its expense, the software path renderer has split out so it can
438 * can be individually allowed/disallowed via the "allowSW" boolean.
439 */
440GrPathRenderer* GrDrawingManager::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
441 bool allowSW,
442 GrPathRendererChain::DrawType drawType,
443 GrPathRenderer::StencilSupport* stencilSupport) {
444
445 if (!fPathRendererChain) {
bsalomon6b2552f2016-09-15 13:50:26 -0700446 fPathRendererChain = new GrPathRendererChain(fContext, fOptionsForPathRendererChain);
robertphillips68737822015-10-29 12:12:21 -0700447 }
448
449 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(args, drawType, stencilSupport);
450 if (!pr && allowSW) {
451 if (!fSoftwarePathRenderer) {
bsalomon39ef7fb2016-09-21 11:16:05 -0700452 fSoftwarePathRenderer =
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500453 new GrSoftwarePathRenderer(fContext->contextPriv().proxyProvider(),
bsalomon39ef7fb2016-09-21 11:16:05 -0700454 fOptionsForPathRendererChain.fAllowPathMaskCaching);
robertphillips68737822015-10-29 12:12:21 -0700455 }
Chris Dalton5ed44232017-09-07 13:22:46 -0600456 if (GrPathRenderer::CanDrawPath::kNo != fSoftwarePathRenderer->canDrawPath(args)) {
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500457 pr = fSoftwarePathRenderer;
458 }
robertphillips68737822015-10-29 12:12:21 -0700459 }
460
461 return pr;
462}
463
Chris Daltonfddb6c02017-11-04 15:22:22 -0600464GrCoverageCountingPathRenderer* GrDrawingManager::getCoverageCountingPathRenderer() {
465 if (!fPathRendererChain) {
466 fPathRendererChain = new GrPathRendererChain(fContext, fOptionsForPathRendererChain);
467 }
468 return fPathRendererChain->getCoverageCountingPathRenderer();
469}
470
Brian Osman11052242016-10-27 14:47:55 -0400471sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
Robert Phillips37430132016-11-09 06:50:43 -0500472 sk_sp<GrSurfaceProxy> sProxy,
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400473 sk_sp<SkColorSpace> colorSpace,
Robert Phillips941d1442017-06-14 16:37:02 -0400474 const SkSurfaceProps* surfaceProps,
475 bool managedOpList) {
Robert Phillips37430132016-11-09 06:50:43 -0500476 if (this->wasAbandoned() || !sProxy->asRenderTargetProxy()) {
robertphillips3dc6ae52015-10-20 09:54:32 -0700477 return nullptr;
478 }
479
brianosman0e22eb82016-08-30 07:07:59 -0700480 // SkSurface catches bad color space usage at creation. This check handles anything that slips
Brian Salomon366093f2018-02-13 09:25:22 -0500481 // by, including internal usage.
482 if (!SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
brianosmana9c3c6a2016-09-29 10:08:36 -0700483 SkDEBUGFAIL("Invalid config and colorspace combination");
brianosman0e22eb82016-08-30 07:07:59 -0700484 return nullptr;
485 }
joshualitt96880d92016-02-16 10:36:53 -0800486
Robert Phillips2c862492017-01-18 10:08:39 -0500487 sk_sp<GrRenderTargetProxy> rtp(sk_ref_sp(sProxy->asRenderTargetProxy()));
488
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500489 return sk_sp<GrRenderTargetContext>(new GrRenderTargetContext(
490 fContext, this, std::move(rtp),
491 std::move(colorSpace),
492 surfaceProps,
493 fContext->contextPriv().getAuditTrail(),
494 fSingleOwner, managedOpList));
robertphillips3dc6ae52015-10-20 09:54:32 -0700495}
Brian Osman45580d32016-11-23 09:37:01 -0500496
Robert Phillips2c862492017-01-18 10:08:39 -0500497sk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProxy> sProxy,
498 sk_sp<SkColorSpace> colorSpace) {
Brian Osman45580d32016-11-23 09:37:01 -0500499 if (this->wasAbandoned() || !sProxy->asTextureProxy()) {
500 return nullptr;
501 }
502
Robert Phillips2c862492017-01-18 10:08:39 -0500503 // SkSurface catches bad color space usage at creation. This check handles anything that slips
Brian Salomon366093f2018-02-13 09:25:22 -0500504 // by, including internal usage.
505 if (!SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
Robert Phillips2c862492017-01-18 10:08:39 -0500506 SkDEBUGFAIL("Invalid config and colorspace combination");
507 return nullptr;
508 }
509
Robert Phillips383c4182018-02-07 12:47:44 -0500510 // GrTextureRenderTargets should always be using a GrRenderTargetContext
Brian Osman45580d32016-11-23 09:37:01 -0500511 SkASSERT(!sProxy->asRenderTargetProxy());
512
513 sk_sp<GrTextureProxy> textureProxy(sk_ref_sp(sProxy->asTextureProxy()));
514
515 return sk_sp<GrTextureContext>(new GrTextureContext(fContext, this, std::move(textureProxy),
Robert Phillips2c862492017-01-18 10:08:39 -0500516 std::move(colorSpace),
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500517 fContext->contextPriv().getAuditTrail(),
Robert Phillips2c862492017-01-18 10:08:39 -0500518 fSingleOwner));
Brian Osman45580d32016-11-23 09:37:01 -0500519}