blob: 1aaa6f7ad2ae188b15f1f12dd667f669b811116a [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 Phillips646e4292017-06-13 12:44:56 -040012#include "GrGpu.h"
Robert Phillipsfbcef6e2017-06-15 12:07:18 -040013#include "GrOnFlushResourceProvider.h"
Robert Phillips9d6c64f2017-09-14 10:56:45 -040014#include "GrOpList.h"
Brian Osman11052242016-10-27 14:47:55 -040015#include "GrRenderTargetContext.h"
16#include "GrPathRenderingRenderTargetContext.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"
brianosman0e22eb82016-08-30 07:07:59 -070024#include "SkSurface_Gpu.h"
robertphillips3dc6ae52015-10-20 09:54:32 -070025#include "SkTTopoSort.h"
26
Brian Salomondcbb9d92017-07-19 10:53:20 -040027#include "GrTracing.h"
joshualitte8042922015-12-11 06:11:21 -080028#include "text/GrAtlasTextContext.h"
29#include "text/GrStencilAndCoverTextContext.h"
robertphillips498d7ac2015-10-30 10:11:30 -070030
robertphillips3dc6ae52015-10-20 09:54:32 -070031void GrDrawingManager::cleanup() {
Robert Phillipsf2361d22016-10-25 14:20:06 -040032 for (int i = 0; i < fOpLists.count(); ++i) {
Robert Phillipsee683652017-04-26 11:53:10 -040033 // no opList should receive a new command after this
34 fOpLists[i]->makeClosed(*fContext->caps());
robertphillips0dfa62c2015-11-16 06:23:31 -080035
Robert Phillipsf2361d22016-10-25 14:20:06 -040036 // We shouldn't need to do this, but it turns out some clients still hold onto opLists
Robert Phillips6cdc22c2017-05-11 16:29:14 -040037 // after a cleanup.
38 // MDB TODO: is this still true?
Chris Daltona84cacf2017-10-04 10:30:29 -060039 if (!fOpLists[i]->unique()) {
40 // TODO: Eventually this should be guaranteed unique.
41 // https://bugs.chromium.org/p/skia/issues/detail?id=7111
42 fOpLists[i]->endFlush();
43 }
robertphillips3dc6ae52015-10-20 09:54:32 -070044 }
45
Robert Phillipsf2361d22016-10-25 14:20:06 -040046 fOpLists.reset();
robertphillips3dc6ae52015-10-20 09:54:32 -070047
robertphillips13391dd2015-10-30 05:15:11 -070048 delete fPathRendererChain;
49 fPathRendererChain = nullptr;
robertphillips68737822015-10-29 12:12:21 -070050 SkSafeSetNull(fSoftwarePathRenderer);
Jim Van Verth106b5c42017-09-26 12:45:29 -040051
52 fOnFlushCBObjects.reset();
robertphillips3dc6ae52015-10-20 09:54:32 -070053}
54
55GrDrawingManager::~GrDrawingManager() {
56 this->cleanup();
57}
58
59void GrDrawingManager::abandon() {
60 fAbandoned = true;
Robert Phillipsf2361d22016-10-25 14:20:06 -040061 for (int i = 0; i < fOpLists.count(); ++i) {
62 fOpLists[i]->abandonGpuResources();
csmartdaltona7f29642016-07-07 08:49:11 -070063 }
robertphillips3dc6ae52015-10-20 09:54:32 -070064 this->cleanup();
65}
66
robertphillips68737822015-10-29 12:12:21 -070067void GrDrawingManager::freeGpuResources() {
Jim Van Verth106b5c42017-09-26 12:45:29 -040068 for (int i = fOnFlushCBObjects.count() - 1; i >= 0; --i) {
69 if (!fOnFlushCBObjects[i]->retainOnFreeGpuResources()) {
70 // it's safe to just do this because we're iterating in reverse
71 fOnFlushCBObjects.removeShuffle(i);
72 }
73 }
74
robertphillips68737822015-10-29 12:12:21 -070075 // a path renderer may be holding onto resources
robertphillips13391dd2015-10-30 05:15:11 -070076 delete fPathRendererChain;
77 fPathRendererChain = nullptr;
robertphillips68737822015-10-29 12:12:21 -070078 SkSafeSetNull(fSoftwarePathRenderer);
Robert Phillipsf2361d22016-10-25 14:20:06 -040079 for (int i = 0; i < fOpLists.count(); ++i) {
80 fOpLists[i]->freeGpuResources();
csmartdaltona7f29642016-07-07 08:49:11 -070081 }
Jim Van Verth106b5c42017-09-26 12:45:29 -040082
robertphillips68737822015-10-29 12:12:21 -070083}
84
Robert Phillipse3302df2017-04-24 07:31:02 -040085gr_instanced::OpAllocator* GrDrawingManager::instancingAllocator() {
86 if (fInstancingAllocator) {
87 return fInstancingAllocator.get();
88 }
89
90 fInstancingAllocator = fContext->getGpu()->createInstancedRenderingAllocator();
91 return fInstancingAllocator.get();
92}
93
Robert Phillips7ee385e2017-03-30 08:02:11 -040094// MDB TODO: make use of the 'proxy' parameter.
Greg Daniel51316782017-08-02 15:10:09 +000095GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
96 GrResourceCache::FlushType type,
97 int numSemaphores,
98 GrBackendSemaphore backendSemaphores[]) {
Brian Salomondcbb9d92017-07-19 10:53:20 -040099 GR_CREATE_TRACE_MARKER_CONTEXT("GrDrawingManager", "internalFlush", fContext);
100
robertphillips7761d612016-05-16 09:14:53 -0700101 if (fFlushing || this->wasAbandoned()) {
Greg Daniel51316782017-08-02 15:10:09 +0000102 return GrSemaphoresSubmitted::kNo;
joshualittb8918c42015-12-18 09:59:46 -0800103 }
104 fFlushing = true;
bsalomondc438982016-08-31 11:53:49 -0700105 bool flushed = false;
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400106
107 for (int i = 0; i < fOpLists.count(); ++i) {
108 // Semi-usually the GrOpLists are already closed at this point, but sometimes Ganesh
109 // needs to flush mid-draw. In that case, the SkGpuDevice's GrOpLists won't be closed
110 // but need to be flushed anyway. Closing such GrOpLists here will mean new
111 // GrOpLists will be created to replace them if the SkGpuDevice(s) write to them again.
Robert Phillipsee683652017-04-26 11:53:10 -0400112 fOpLists[i]->makeClosed(*fContext->caps());
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400113 }
114
Robert Phillipsa4c93ac2017-05-18 11:40:04 -0400115#ifdef SK_DEBUG
116 // This block checks for any unnecessary splits in the opLists. If two sequential opLists
117 // share the same backing GrSurfaceProxy it means the opList was artificially split.
118 if (fOpLists.count()) {
119 GrRenderTargetOpList* prevOpList = fOpLists[0]->asRenderTargetOpList();
120 for (int i = 1; i < fOpLists.count(); ++i) {
121 GrRenderTargetOpList* curOpList = fOpLists[i]->asRenderTargetOpList();
122
123 if (prevOpList && curOpList) {
124 SkASSERT(prevOpList->fTarget.get() != curOpList->fTarget.get());
125 }
126
127 prevOpList = curOpList;
128 }
129 }
130#endif
131
Robert Phillips9d6c64f2017-09-14 10:56:45 -0400132#ifdef ENABLE_MDB_SORT
halcanary9d524f22016-03-29 09:03:52 -0700133 SkDEBUGCODE(bool result =)
Robert Phillipsf2361d22016-10-25 14:20:06 -0400134 SkTTopoSort<GrOpList, GrOpList::TopoSortTraits>(&fOpLists);
robertphillips3dc6ae52015-10-20 09:54:32 -0700135 SkASSERT(result);
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400136#endif
robertphillips3dc6ae52015-10-20 09:54:32 -0700137
Chris Daltonfe199b72017-05-05 11:26:15 -0400138 GrOnFlushResourceProvider onFlushProvider(this);
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400139
Chris Dalton12658942017-10-05 19:45:25 -0600140 // Prepare any onFlush op lists (e.g. atlases).
141 SkSTArray<8, sk_sp<GrOpList>> onFlushOpLists;
Chris Daltonfe199b72017-05-05 11:26:15 -0400142 if (!fOnFlushCBObjects.empty()) {
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400143 // MDB TODO: pre-MDB '1' is the correct pre-allocated size. Post-MDB it will need
144 // to be larger.
145 SkAutoSTArray<1, uint32_t> opListIds(fOpLists.count());
146 for (int i = 0; i < fOpLists.count(); ++i) {
147 opListIds[i] = fOpLists[i]->uniqueID();
148 }
Chris Dalton12658942017-10-05 19:45:25 -0600149 SkSTArray<4, sk_sp<GrRenderTargetContext>> renderTargetContexts;
Chris Daltonfe199b72017-05-05 11:26:15 -0400150 for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) {
151 onFlushCBObject->preFlush(&onFlushProvider,
152 opListIds.get(), opListIds.count(),
153 &renderTargetContexts);
Chris Dalton12658942017-10-05 19:45:25 -0600154 for (const sk_sp<GrRenderTargetContext>& rtc : renderTargetContexts) {
155 sk_sp<GrOpList> onFlushOpList = sk_ref_sp(rtc->getOpList());
156 if (!onFlushOpList) {
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400157 continue; // Odd - but not a big deal
158 }
Chris Dalton12658942017-10-05 19:45:25 -0600159 onFlushOpList->makeClosed(*fContext->caps());
160 onFlushOpList->prepare(&fFlushState);
161 onFlushOpLists.push_back(std::move(onFlushOpList));
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400162 }
163 renderTargetContexts.reset();
164 }
165 }
166
robertphillipsa13e2022015-11-11 12:01:09 -0800167#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500168 // Enable this to print out verbose GrOp information
Robert Phillipsf2361d22016-10-25 14:20:06 -0400169 for (int i = 0; i < fOpLists.count(); ++i) {
170 SkDEBUGCODE(fOpLists[i]->dump();)
robertphillips3dc6ae52015-10-20 09:54:32 -0700171 }
robertphillipsa13e2022015-11-11 12:01:09 -0800172#endif
173
Robert Phillipsf8e25022017-11-08 15:24:31 -0500174 {
175 GrResourceAllocator alloc(fContext->resourceProvider());
176 for (int i = 0; i < fOpLists.count(); ++i) {
177 fOpLists[i]->gatherProxyIntervals(&alloc);
178 }
Robert Phillipsd375dbf2017-09-14 12:45:25 -0400179
Robert Phillips8186cbe2017-11-01 17:32:39 -0400180#ifdef MDB_ALLOC_RESOURCES
Robert Phillipsf8e25022017-11-08 15:24:31 -0500181 alloc.assign();
Robert Phillipsd375dbf2017-09-14 12:45:25 -0400182#endif
Robert Phillipsf8e25022017-11-08 15:24:31 -0500183 }
Robert Phillipsd375dbf2017-09-14 12:45:25 -0400184
Robert Phillips318c4192017-05-17 09:36:38 -0400185 for (int i = 0; i < fOpLists.count(); ++i) {
186 if (!fOpLists[i]->instantiate(fContext->resourceProvider())) {
Brian Osmane46c8d02017-08-23 16:15:22 -0400187 SkDebugf("OpList failed to instantiate.\n");
Robert Phillips318c4192017-05-17 09:36:38 -0400188 fOpLists[i] = nullptr;
189 continue;
190 }
191
Brian Osman099fa0f2017-10-02 16:38:32 -0400192 // Instantiate all deferred proxies (being built on worker threads) so we can upload them
193 fOpLists[i]->instantiateDeferredProxies(fContext->resourceProvider());
Brian Osman407b3422017-08-22 15:01:32 -0400194 fOpLists[i]->prepare(&fFlushState);
Robert Phillips318c4192017-05-17 09:36:38 -0400195 }
196
robertphillipsa13e2022015-11-11 12:01:09 -0800197 // Upload all data to the GPU
Brian Salomon7dc6e752017-11-02 11:34:51 -0400198 fFlushState.preExecuteDraws();
robertphillipsa13e2022015-11-11 12:01:09 -0800199
Chris Dalton12658942017-10-05 19:45:25 -0600200 // Execute the onFlush op lists first, if any.
201 for (sk_sp<GrOpList>& onFlushOpList : onFlushOpLists) {
202 if (!onFlushOpList->execute(&fFlushState)) {
203 SkDebugf("WARNING: onFlushOpList failed to execute.\n");
204 }
205 SkASSERT(onFlushOpList->unique());
206 onFlushOpList = nullptr;
207 }
208 onFlushOpLists.reset();
209
210 // Execute the normal op lists.
Robert Phillipsf2361d22016-10-25 14:20:06 -0400211 for (int i = 0; i < fOpLists.count(); ++i) {
Robert Phillips318c4192017-05-17 09:36:38 -0400212 if (!fOpLists[i]) {
213 continue;
214 }
215
Brian Osman407b3422017-08-22 15:01:32 -0400216 if (fOpLists[i]->execute(&fFlushState)) {
bsalomondc438982016-08-31 11:53:49 -0700217 flushed = true;
218 }
Greg Danielc42b20b2017-10-04 10:34:49 -0400219 }
220
221 SkASSERT(fFlushState.nextDrawToken() == fFlushState.nextTokenToFlush());
222
223 // We reset the flush state before the OpLists so that the last resources to be freed are those
224 // that are written to in the OpLists. This helps to make sure the most recently used resources
225 // are the last to be purged by the resource cache.
226 fFlushState.reset();
227
228 for (int i = 0; i < fOpLists.count(); ++i) {
229 if (!fOpLists[i]) {
230 continue;
231 }
Chris Daltona84cacf2017-10-04 10:30:29 -0600232 if (!fOpLists[i]->unique()) {
233 // TODO: Eventually this should be guaranteed unique.
234 // https://bugs.chromium.org/p/skia/issues/detail?id=7111
235 fOpLists[i]->endFlush();
236 }
Chris Dalton12658942017-10-05 19:45:25 -0600237 fOpLists[i] = nullptr;
robertphillipsa13e2022015-11-11 12:01:09 -0800238 }
Robert Phillips18e94842017-05-15 13:06:44 -0400239 fOpLists.reset();
robertphillipsa13e2022015-11-11 12:01:09 -0800240
Greg Daniel51316782017-08-02 15:10:09 +0000241 GrSemaphoresSubmitted result = fContext->getGpu()->finishFlush(numSemaphores,
242 backendSemaphores);
robertphillipsa13e2022015-11-11 12:01:09 -0800243
robertphillipsee843b22016-10-04 05:30:20 -0700244 // We always have to notify the cache when it requested a flush so it can reset its state.
245 if (flushed || type == GrResourceCache::FlushType::kCacheRequested) {
bsalomonb77a9072016-09-07 10:02:04 -0700246 fContext->getResourceCache()->notifyFlushOccurred(type);
247 }
Chris Daltonfe199b72017-05-05 11:26:15 -0400248 for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) {
Jim Van Verth106b5c42017-09-26 12:45:29 -0400249 onFlushCBObject->postFlush(fFlushState.nextTokenToFlush());
Chris Daltonfe199b72017-05-05 11:26:15 -0400250 }
joshualittb8918c42015-12-18 09:59:46 -0800251 fFlushing = false;
Greg Daniel51316782017-08-02 15:10:09 +0000252
253 return result;
robertphillips3dc6ae52015-10-20 09:54:32 -0700254}
255
Greg Daniel51316782017-08-02 15:10:09 +0000256GrSemaphoresSubmitted GrDrawingManager::prepareSurfaceForExternalIO(
257 GrSurfaceProxy* proxy, int numSemaphores, GrBackendSemaphore backendSemaphores[]) {
bsalomon6a2b1942016-09-08 11:28:59 -0700258 if (this->wasAbandoned()) {
Greg Daniel51316782017-08-02 15:10:09 +0000259 return GrSemaphoresSubmitted::kNo;
bsalomon6a2b1942016-09-08 11:28:59 -0700260 }
Robert Phillips7ee385e2017-03-30 08:02:11 -0400261 SkASSERT(proxy);
bsalomon6a2b1942016-09-08 11:28:59 -0700262
Greg Daniel51316782017-08-02 15:10:09 +0000263 GrSemaphoresSubmitted result;
264 if (proxy->priv().hasPendingIO() || numSemaphores) {
265 result = this->flush(proxy, numSemaphores, backendSemaphores);
bsalomon6a2b1942016-09-08 11:28:59 -0700266 }
267
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400268 if (!proxy->instantiate(fContext->resourceProvider())) {
Greg Daniel51316782017-08-02 15:10:09 +0000269 return result;
Robert Phillips7ee385e2017-03-30 08:02:11 -0400270 }
271
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400272 GrSurface* surface = proxy->priv().peekSurface();
273
Robert Phillips7ee385e2017-03-30 08:02:11 -0400274 if (fContext->getGpu() && surface->asRenderTarget()) {
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400275 fContext->getGpu()->resolveRenderTarget(surface->asRenderTarget(), proxy->origin());
bsalomon6a2b1942016-09-08 11:28:59 -0700276 }
Greg Daniel51316782017-08-02 15:10:09 +0000277 return result;
bsalomon6a2b1942016-09-08 11:28:59 -0700278}
279
Chris Daltonfe199b72017-05-05 11:26:15 -0400280void GrDrawingManager::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
281 fOnFlushCBObjects.push_back(onFlushCBObject);
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400282}
283
Robert Phillips941d1442017-06-14 16:37:02 -0400284sk_sp<GrRenderTargetOpList> GrDrawingManager::newRTOpList(GrRenderTargetProxy* rtp,
285 bool managedOpList) {
robertphillips3dc6ae52015-10-20 09:54:32 -0700286 SkASSERT(fContext);
287
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400288 // This is a temporary fix for the partial-MDB world. In that world we're not reordering
289 // so ops that (in the single opList world) would've just glommed onto the end of the single
290 // opList but referred to a far earlier RT need to appear in their own opList.
291 if (!fOpLists.empty()) {
292 fOpLists.back()->makeClosed(*fContext->caps());
robertphillips3dc6ae52015-10-20 09:54:32 -0700293 }
robertphillips3dc6ae52015-10-20 09:54:32 -0700294
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400295 sk_sp<GrRenderTargetOpList> opList(new GrRenderTargetOpList(rtp,
296 fContext->getGpu(),
Robert Phillips8185f592017-04-26 08:31:08 -0400297 fContext->getAuditTrail()));
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400298 SkASSERT(rtp->getLastOpList() == opList.get());
robertphillips3dc6ae52015-10-20 09:54:32 -0700299
Robert Phillips941d1442017-06-14 16:37:02 -0400300 if (managedOpList) {
301 fOpLists.push_back() = opList;
302 }
robertphillips3dc6ae52015-10-20 09:54:32 -0700303
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400304 return opList;
robertphillips3dc6ae52015-10-20 09:54:32 -0700305}
306
Robert Phillipsb6deea82017-05-11 14:14:30 -0400307sk_sp<GrTextureOpList> GrDrawingManager::newTextureOpList(GrTextureProxy* textureProxy) {
Brian Osman45580d32016-11-23 09:37:01 -0500308 SkASSERT(fContext);
309
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400310 // This is a temporary fix for the partial-MDB world. In that world we're not reordering
311 // so ops that (in the single opList world) would've just glommed onto the end of the single
312 // opList but referred to a far earlier RT need to appear in their own opList.
313 if (!fOpLists.empty()) {
314 fOpLists.back()->makeClosed(*fContext->caps());
315 }
316
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400317 sk_sp<GrTextureOpList> opList(new GrTextureOpList(fContext->resourceProvider(),
318 textureProxy,
319 fContext->getAuditTrail()));
Brian Osman45580d32016-11-23 09:37:01 -0500320
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400321 SkASSERT(textureProxy->getLastOpList() == opList.get());
Robert Phillips4a395042017-04-24 16:27:17 +0000322
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400323 fOpLists.push_back() = opList;
324
Robert Phillips4a395042017-04-24 16:27:17 +0000325 return opList;
Brian Osman45580d32016-11-23 09:37:01 -0500326}
327
brianosman86e76262016-08-11 12:17:31 -0700328GrAtlasTextContext* GrDrawingManager::getAtlasTextContext() {
329 if (!fAtlasTextContext) {
Brian Salomonaf597482017-11-07 16:23:34 -0500330 fAtlasTextContext = GrAtlasTextContext::Make(fOptionsForAtlasTextContext);
brianosman86e76262016-08-11 12:17:31 -0700331 }
332
333 return fAtlasTextContext.get();
334}
335
robertphillips68737822015-10-29 12:12:21 -0700336/*
337 * This method finds a path renderer that can draw the specified path on
338 * the provided target.
339 * Due to its expense, the software path renderer has split out so it can
340 * can be individually allowed/disallowed via the "allowSW" boolean.
341 */
342GrPathRenderer* GrDrawingManager::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
343 bool allowSW,
344 GrPathRendererChain::DrawType drawType,
345 GrPathRenderer::StencilSupport* stencilSupport) {
346
347 if (!fPathRendererChain) {
bsalomon6b2552f2016-09-15 13:50:26 -0700348 fPathRendererChain = new GrPathRendererChain(fContext, fOptionsForPathRendererChain);
robertphillips68737822015-10-29 12:12:21 -0700349 }
350
351 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(args, drawType, stencilSupport);
352 if (!pr && allowSW) {
353 if (!fSoftwarePathRenderer) {
bsalomon39ef7fb2016-09-21 11:16:05 -0700354 fSoftwarePathRenderer =
Brian Osman32342f02017-03-04 08:12:46 -0500355 new GrSoftwarePathRenderer(fContext->resourceProvider(),
bsalomon39ef7fb2016-09-21 11:16:05 -0700356 fOptionsForPathRendererChain.fAllowPathMaskCaching);
robertphillips68737822015-10-29 12:12:21 -0700357 }
Chris Dalton5ed44232017-09-07 13:22:46 -0600358 if (GrPathRenderer::CanDrawPath::kNo != fSoftwarePathRenderer->canDrawPath(args)) {
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500359 pr = fSoftwarePathRenderer;
360 }
robertphillips68737822015-10-29 12:12:21 -0700361 }
362
363 return pr;
364}
365
Chris Daltonfddb6c02017-11-04 15:22:22 -0600366GrCoverageCountingPathRenderer* GrDrawingManager::getCoverageCountingPathRenderer() {
367 if (!fPathRendererChain) {
368 fPathRendererChain = new GrPathRendererChain(fContext, fOptionsForPathRendererChain);
369 }
370 return fPathRendererChain->getCoverageCountingPathRenderer();
371}
372
Brian Osman11052242016-10-27 14:47:55 -0400373sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
Robert Phillips37430132016-11-09 06:50:43 -0500374 sk_sp<GrSurfaceProxy> sProxy,
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400375 sk_sp<SkColorSpace> colorSpace,
Robert Phillips941d1442017-06-14 16:37:02 -0400376 const SkSurfaceProps* surfaceProps,
377 bool managedOpList) {
Robert Phillips37430132016-11-09 06:50:43 -0500378 if (this->wasAbandoned() || !sProxy->asRenderTargetProxy()) {
robertphillips3dc6ae52015-10-20 09:54:32 -0700379 return nullptr;
380 }
381
brianosman0e22eb82016-08-30 07:07:59 -0700382 // SkSurface catches bad color space usage at creation. This check handles anything that slips
383 // by, including internal usage. We allow a null color space here, for read/write pixels and
384 // other special code paths. If a color space is provided, though, enforce all other rules.
Robert Phillips2c862492017-01-18 10:08:39 -0500385 if (colorSpace && !SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
brianosmana9c3c6a2016-09-29 10:08:36 -0700386 SkDEBUGFAIL("Invalid config and colorspace combination");
brianosman0e22eb82016-08-30 07:07:59 -0700387 return nullptr;
388 }
joshualitt96880d92016-02-16 10:36:53 -0800389
Robert Phillips2c862492017-01-18 10:08:39 -0500390 sk_sp<GrRenderTargetProxy> rtp(sk_ref_sp(sProxy->asRenderTargetProxy()));
391
joshualitt96880d92016-02-16 10:36:53 -0800392 bool useDIF = false;
393 if (surfaceProps) {
394 useDIF = surfaceProps->isUseDeviceIndependentFonts();
395 }
396
397 if (useDIF && fContext->caps()->shaderCaps()->pathRenderingSupport() &&
Brian Salomon7c8460e2017-05-12 11:36:10 -0400398 GrFSAAType::kNone != rtp->fsaaType()) {
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400399
Robert Phillipsc0192e32017-09-21 12:00:26 -0400400 return sk_sp<GrRenderTargetContext>(new GrPathRenderingRenderTargetContext(
401 fContext, this, std::move(rtp),
402 std::move(colorSpace), surfaceProps,
403 fContext->getAuditTrail(), fSingleOwner));
joshualitt96880d92016-02-16 10:36:53 -0800404 }
405
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400406 return sk_sp<GrRenderTargetContext>(new GrRenderTargetContext(fContext, this, std::move(rtp),
Brian Osman11052242016-10-27 14:47:55 -0400407 std::move(colorSpace),
408 surfaceProps,
409 fContext->getAuditTrail(),
Robert Phillips941d1442017-06-14 16:37:02 -0400410 fSingleOwner, managedOpList));
robertphillips3dc6ae52015-10-20 09:54:32 -0700411}
Brian Osman45580d32016-11-23 09:37:01 -0500412
Robert Phillips2c862492017-01-18 10:08:39 -0500413sk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProxy> sProxy,
414 sk_sp<SkColorSpace> colorSpace) {
Brian Osman45580d32016-11-23 09:37:01 -0500415 if (this->wasAbandoned() || !sProxy->asTextureProxy()) {
416 return nullptr;
417 }
418
Robert Phillips2c862492017-01-18 10:08:39 -0500419 // SkSurface catches bad color space usage at creation. This check handles anything that slips
420 // by, including internal usage. We allow a null color space here, for read/write pixels and
421 // other special code paths. If a color space is provided, though, enforce all other rules.
422 if (colorSpace && !SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
423 SkDEBUGFAIL("Invalid config and colorspace combination");
424 return nullptr;
425 }
426
Brian Osman45580d32016-11-23 09:37:01 -0500427 // GrTextureRenderTargets should always be using GrRenderTargetContext
428 SkASSERT(!sProxy->asRenderTargetProxy());
429
430 sk_sp<GrTextureProxy> textureProxy(sk_ref_sp(sProxy->asTextureProxy()));
431
432 return sk_sp<GrTextureContext>(new GrTextureContext(fContext, this, std::move(textureProxy),
Robert Phillips2c862492017-01-18 10:08:39 -0500433 std::move(colorSpace),
434 fContext->getAuditTrail(),
435 fSingleOwner));
Brian Osman45580d32016-11-23 09:37:01 -0500436}