blob: d7ab495573474465d133e09d36c357b7160c02f2 [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"
Brian Osman11052242016-10-27 14:47:55 -040014#include "GrRenderTargetContext.h"
15#include "GrPathRenderingRenderTargetContext.h"
Robert Phillipsc7635fa2016-10-28 13:25:24 -040016#include "GrRenderTargetProxy.h"
robertphillips3dc6ae52015-10-20 09:54:32 -070017#include "GrResourceProvider.h"
robertphillips68737822015-10-29 12:12:21 -070018#include "GrSoftwarePathRenderer.h"
bsalomon6a2b1942016-09-08 11:28:59 -070019#include "GrSurfacePriv.h"
Robert Phillips7ee385e2017-03-30 08:02:11 -040020#include "GrSurfaceProxyPriv.h"
Brian Osman45580d32016-11-23 09:37:01 -050021#include "GrTextureContext.h"
22#include "GrTextureOpList.h"
brianosman0e22eb82016-08-30 07:07:59 -070023#include "SkSurface_Gpu.h"
robertphillips3dc6ae52015-10-20 09:54:32 -070024#include "SkTTopoSort.h"
25
Brian Salomondcbb9d92017-07-19 10:53:20 -040026#include "GrTracing.h"
joshualitte8042922015-12-11 06:11:21 -080027#include "text/GrAtlasTextContext.h"
28#include "text/GrStencilAndCoverTextContext.h"
robertphillips498d7ac2015-10-30 10:11:30 -070029
robertphillips3dc6ae52015-10-20 09:54:32 -070030void GrDrawingManager::cleanup() {
Robert Phillipsf2361d22016-10-25 14:20:06 -040031 for (int i = 0; i < fOpLists.count(); ++i) {
Robert Phillipsee683652017-04-26 11:53:10 -040032 // no opList should receive a new command after this
33 fOpLists[i]->makeClosed(*fContext->caps());
robertphillips0dfa62c2015-11-16 06:23:31 -080034
Robert Phillipsf2361d22016-10-25 14:20:06 -040035 // We shouldn't need to do this, but it turns out some clients still hold onto opLists
Robert Phillips6cdc22c2017-05-11 16:29:14 -040036 // after a cleanup.
37 // MDB TODO: is this still true?
Robert Phillipsf2361d22016-10-25 14:20:06 -040038 fOpLists[i]->reset();
robertphillips3dc6ae52015-10-20 09:54:32 -070039 }
40
Robert Phillipsf2361d22016-10-25 14:20:06 -040041 fOpLists.reset();
robertphillips3dc6ae52015-10-20 09:54:32 -070042
robertphillips13391dd2015-10-30 05:15:11 -070043 delete fPathRendererChain;
44 fPathRendererChain = nullptr;
robertphillips68737822015-10-29 12:12:21 -070045 SkSafeSetNull(fSoftwarePathRenderer);
robertphillips3dc6ae52015-10-20 09:54:32 -070046}
47
48GrDrawingManager::~GrDrawingManager() {
49 this->cleanup();
50}
51
52void GrDrawingManager::abandon() {
53 fAbandoned = true;
Robert Phillipsf2361d22016-10-25 14:20:06 -040054 for (int i = 0; i < fOpLists.count(); ++i) {
55 fOpLists[i]->abandonGpuResources();
csmartdaltona7f29642016-07-07 08:49:11 -070056 }
robertphillips3dc6ae52015-10-20 09:54:32 -070057 this->cleanup();
58}
59
robertphillips68737822015-10-29 12:12:21 -070060void GrDrawingManager::freeGpuResources() {
61 // a path renderer may be holding onto resources
robertphillips13391dd2015-10-30 05:15:11 -070062 delete fPathRendererChain;
63 fPathRendererChain = nullptr;
robertphillips68737822015-10-29 12:12:21 -070064 SkSafeSetNull(fSoftwarePathRenderer);
Robert Phillipsf2361d22016-10-25 14:20:06 -040065 for (int i = 0; i < fOpLists.count(); ++i) {
66 fOpLists[i]->freeGpuResources();
csmartdaltona7f29642016-07-07 08:49:11 -070067 }
robertphillips68737822015-10-29 12:12:21 -070068}
69
robertphillips3dc6ae52015-10-20 09:54:32 -070070void GrDrawingManager::reset() {
Robert Phillipsf2361d22016-10-25 14:20:06 -040071 for (int i = 0; i < fOpLists.count(); ++i) {
72 fOpLists[i]->reset();
robertphillips3dc6ae52015-10-20 09:54:32 -070073 }
robertphillipsa13e2022015-11-11 12:01:09 -080074 fFlushState.reset();
robertphillips3dc6ae52015-10-20 09:54:32 -070075}
76
Robert Phillipse3302df2017-04-24 07:31:02 -040077gr_instanced::OpAllocator* GrDrawingManager::instancingAllocator() {
78 if (fInstancingAllocator) {
79 return fInstancingAllocator.get();
80 }
81
82 fInstancingAllocator = fContext->getGpu()->createInstancedRenderingAllocator();
83 return fInstancingAllocator.get();
84}
85
Robert Phillips7ee385e2017-03-30 08:02:11 -040086// MDB TODO: make use of the 'proxy' parameter.
Greg Daniel51316782017-08-02 15:10:09 +000087GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
88 GrResourceCache::FlushType type,
89 int numSemaphores,
90 GrBackendSemaphore backendSemaphores[]) {
Brian Salomondcbb9d92017-07-19 10:53:20 -040091 GR_CREATE_TRACE_MARKER_CONTEXT("GrDrawingManager", "internalFlush", fContext);
92
robertphillips7761d612016-05-16 09:14:53 -070093 if (fFlushing || this->wasAbandoned()) {
Greg Daniel51316782017-08-02 15:10:09 +000094 return GrSemaphoresSubmitted::kNo;
joshualittb8918c42015-12-18 09:59:46 -080095 }
96 fFlushing = true;
bsalomondc438982016-08-31 11:53:49 -070097 bool flushed = false;
Robert Phillipseb35f4d2017-03-21 07:56:47 -040098
99 for (int i = 0; i < fOpLists.count(); ++i) {
100 // Semi-usually the GrOpLists are already closed at this point, but sometimes Ganesh
101 // needs to flush mid-draw. In that case, the SkGpuDevice's GrOpLists won't be closed
102 // but need to be flushed anyway. Closing such GrOpLists here will mean new
103 // GrOpLists will be created to replace them if the SkGpuDevice(s) write to them again.
Robert Phillipsee683652017-04-26 11:53:10 -0400104 fOpLists[i]->makeClosed(*fContext->caps());
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400105 }
106
Robert Phillipsa4c93ac2017-05-18 11:40:04 -0400107#ifdef SK_DEBUG
108 // This block checks for any unnecessary splits in the opLists. If two sequential opLists
109 // share the same backing GrSurfaceProxy it means the opList was artificially split.
110 if (fOpLists.count()) {
111 GrRenderTargetOpList* prevOpList = fOpLists[0]->asRenderTargetOpList();
112 for (int i = 1; i < fOpLists.count(); ++i) {
113 GrRenderTargetOpList* curOpList = fOpLists[i]->asRenderTargetOpList();
114
115 if (prevOpList && curOpList) {
116 SkASSERT(prevOpList->fTarget.get() != curOpList->fTarget.get());
117 }
118
119 prevOpList = curOpList;
120 }
121 }
122#endif
123
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400124#ifdef ENABLE_MDB
halcanary9d524f22016-03-29 09:03:52 -0700125 SkDEBUGCODE(bool result =)
Robert Phillipsf2361d22016-10-25 14:20:06 -0400126 SkTTopoSort<GrOpList, GrOpList::TopoSortTraits>(&fOpLists);
robertphillips3dc6ae52015-10-20 09:54:32 -0700127 SkASSERT(result);
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400128#endif
robertphillips3dc6ae52015-10-20 09:54:32 -0700129
Chris Daltonfe199b72017-05-05 11:26:15 -0400130 GrOnFlushResourceProvider onFlushProvider(this);
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400131
Chris Daltonfe199b72017-05-05 11:26:15 -0400132 if (!fOnFlushCBObjects.empty()) {
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400133 // MDB TODO: pre-MDB '1' is the correct pre-allocated size. Post-MDB it will need
134 // to be larger.
135 SkAutoSTArray<1, uint32_t> opListIds(fOpLists.count());
136 for (int i = 0; i < fOpLists.count(); ++i) {
137 opListIds[i] = fOpLists[i]->uniqueID();
138 }
139
140 SkSTArray<1, sk_sp<GrRenderTargetContext>> renderTargetContexts;
Chris Daltonfe199b72017-05-05 11:26:15 -0400141 for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) {
142 onFlushCBObject->preFlush(&onFlushProvider,
143 opListIds.get(), opListIds.count(),
144 &renderTargetContexts);
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400145 if (!renderTargetContexts.count()) {
146 continue; // This is fine. No atlases of this type are required for this flush
147 }
148
149 for (int j = 0; j < renderTargetContexts.count(); ++j) {
Robert Phillips2de8cfa2017-06-28 10:33:41 -0400150 GrOpList* opList = renderTargetContexts[j]->getOpList();
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400151 if (!opList) {
152 continue; // Odd - but not a big deal
153 }
Robert Phillipsb6deea82017-05-11 14:14:30 -0400154 opList->makeClosed(*fContext->caps());
Brian Osman407b3422017-08-22 15:01:32 -0400155 opList->prepare(&fFlushState);
156 if (!opList->execute(&fFlushState)) {
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400157 continue; // This is bad
158 }
159 }
160 renderTargetContexts.reset();
161 }
162 }
163
robertphillipsa13e2022015-11-11 12:01:09 -0800164#if 0
Brian Salomon09d994e2016-12-21 11:14:46 -0500165 // Enable this to print out verbose GrOp information
Robert Phillipsf2361d22016-10-25 14:20:06 -0400166 for (int i = 0; i < fOpLists.count(); ++i) {
167 SkDEBUGCODE(fOpLists[i]->dump();)
robertphillips3dc6ae52015-10-20 09:54:32 -0700168 }
robertphillipsa13e2022015-11-11 12:01:09 -0800169#endif
170
Robert Phillips318c4192017-05-17 09:36:38 -0400171 for (int i = 0; i < fOpLists.count(); ++i) {
172 if (!fOpLists[i]->instantiate(fContext->resourceProvider())) {
Brian Osmane46c8d02017-08-23 16:15:22 -0400173 SkDebugf("OpList failed to instantiate.\n");
Robert Phillips318c4192017-05-17 09:36:38 -0400174 fOpLists[i] = nullptr;
175 continue;
176 }
177
Brian Osman407b3422017-08-22 15:01:32 -0400178 fOpLists[i]->prepare(&fFlushState);
Robert Phillips318c4192017-05-17 09:36:38 -0400179 }
180
robertphillipsa13e2022015-11-11 12:01:09 -0800181 // Upload all data to the GPU
182 fFlushState.preIssueDraws();
183
Robert Phillipsf2361d22016-10-25 14:20:06 -0400184 for (int i = 0; i < fOpLists.count(); ++i) {
Robert Phillips318c4192017-05-17 09:36:38 -0400185 if (!fOpLists[i]) {
186 continue;
187 }
188
Brian Osman407b3422017-08-22 15:01:32 -0400189 if (fOpLists[i]->execute(&fFlushState)) {
bsalomondc438982016-08-31 11:53:49 -0700190 flushed = true;
191 }
Robert Phillips18e94842017-05-15 13:06:44 -0400192 fOpLists[i]->reset();
robertphillipsa13e2022015-11-11 12:01:09 -0800193 }
Robert Phillips18e94842017-05-15 13:06:44 -0400194 fOpLists.reset();
robertphillipsa13e2022015-11-11 12:01:09 -0800195
bsalomon342bfc22016-04-01 06:06:20 -0700196 SkASSERT(fFlushState.nextDrawToken() == fFlushState.nextTokenToFlush());
robertphillips3dc6ae52015-10-20 09:54:32 -0700197
Greg Daniel51316782017-08-02 15:10:09 +0000198 GrSemaphoresSubmitted result = fContext->getGpu()->finishFlush(numSemaphores,
199 backendSemaphores);
robertphillipsa13e2022015-11-11 12:01:09 -0800200
robertphillipsa13e2022015-11-11 12:01:09 -0800201 fFlushState.reset();
robertphillipsee843b22016-10-04 05:30:20 -0700202 // We always have to notify the cache when it requested a flush so it can reset its state.
203 if (flushed || type == GrResourceCache::FlushType::kCacheRequested) {
bsalomonb77a9072016-09-07 10:02:04 -0700204 fContext->getResourceCache()->notifyFlushOccurred(type);
205 }
Chris Daltonfe199b72017-05-05 11:26:15 -0400206 for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) {
207 onFlushCBObject->postFlush();
208 }
joshualittb8918c42015-12-18 09:59:46 -0800209 fFlushing = false;
Greg Daniel51316782017-08-02 15:10:09 +0000210
211 return result;
robertphillips3dc6ae52015-10-20 09:54:32 -0700212}
213
Greg Daniel51316782017-08-02 15:10:09 +0000214GrSemaphoresSubmitted GrDrawingManager::prepareSurfaceForExternalIO(
215 GrSurfaceProxy* proxy, int numSemaphores, GrBackendSemaphore backendSemaphores[]) {
bsalomon6a2b1942016-09-08 11:28:59 -0700216 if (this->wasAbandoned()) {
Greg Daniel51316782017-08-02 15:10:09 +0000217 return GrSemaphoresSubmitted::kNo;
bsalomon6a2b1942016-09-08 11:28:59 -0700218 }
Robert Phillips7ee385e2017-03-30 08:02:11 -0400219 SkASSERT(proxy);
bsalomon6a2b1942016-09-08 11:28:59 -0700220
Greg Daniel51316782017-08-02 15:10:09 +0000221 GrSemaphoresSubmitted result;
222 if (proxy->priv().hasPendingIO() || numSemaphores) {
223 result = this->flush(proxy, numSemaphores, backendSemaphores);
bsalomon6a2b1942016-09-08 11:28:59 -0700224 }
225
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400226 if (!proxy->instantiate(fContext->resourceProvider())) {
Greg Daniel51316782017-08-02 15:10:09 +0000227 return result;
Robert Phillips7ee385e2017-03-30 08:02:11 -0400228 }
229
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400230 GrSurface* surface = proxy->priv().peekSurface();
231
Robert Phillips7ee385e2017-03-30 08:02:11 -0400232 if (fContext->getGpu() && surface->asRenderTarget()) {
Robert Phillips7294b852017-08-01 13:51:44 +0000233 fContext->getGpu()->resolveRenderTarget(surface->asRenderTarget());
bsalomon6a2b1942016-09-08 11:28:59 -0700234 }
Greg Daniel51316782017-08-02 15:10:09 +0000235 return result;
bsalomon6a2b1942016-09-08 11:28:59 -0700236}
237
Chris Daltonfe199b72017-05-05 11:26:15 -0400238void GrDrawingManager::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
239 fOnFlushCBObjects.push_back(onFlushCBObject);
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400240}
241
Robert Phillips941d1442017-06-14 16:37:02 -0400242sk_sp<GrRenderTargetOpList> GrDrawingManager::newRTOpList(GrRenderTargetProxy* rtp,
243 bool managedOpList) {
robertphillips3dc6ae52015-10-20 09:54:32 -0700244 SkASSERT(fContext);
245
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400246 // This is a temporary fix for the partial-MDB world. In that world we're not reordering
247 // so ops that (in the single opList world) would've just glommed onto the end of the single
248 // opList but referred to a far earlier RT need to appear in their own opList.
249 if (!fOpLists.empty()) {
250 fOpLists.back()->makeClosed(*fContext->caps());
robertphillips3dc6ae52015-10-20 09:54:32 -0700251 }
robertphillips3dc6ae52015-10-20 09:54:32 -0700252
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400253 sk_sp<GrRenderTargetOpList> opList(new GrRenderTargetOpList(rtp,
254 fContext->getGpu(),
Robert Phillips8185f592017-04-26 08:31:08 -0400255 fContext->getAuditTrail()));
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400256 SkASSERT(rtp->getLastOpList() == opList.get());
robertphillips3dc6ae52015-10-20 09:54:32 -0700257
Robert Phillips941d1442017-06-14 16:37:02 -0400258 if (managedOpList) {
259 fOpLists.push_back() = opList;
260 }
robertphillips3dc6ae52015-10-20 09:54:32 -0700261
Robert Phillipsf5442bb2017-04-17 14:18:34 -0400262 return opList;
robertphillips3dc6ae52015-10-20 09:54:32 -0700263}
264
Robert Phillipsb6deea82017-05-11 14:14:30 -0400265sk_sp<GrTextureOpList> GrDrawingManager::newTextureOpList(GrTextureProxy* textureProxy) {
Brian Osman45580d32016-11-23 09:37:01 -0500266 SkASSERT(fContext);
267
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400268 // This is a temporary fix for the partial-MDB world. In that world we're not reordering
269 // so ops that (in the single opList world) would've just glommed onto the end of the single
270 // opList but referred to a far earlier RT need to appear in their own opList.
271 if (!fOpLists.empty()) {
272 fOpLists.back()->makeClosed(*fContext->caps());
273 }
274
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400275 sk_sp<GrTextureOpList> opList(new GrTextureOpList(fContext->resourceProvider(),
276 textureProxy,
277 fContext->getAuditTrail()));
Brian Osman45580d32016-11-23 09:37:01 -0500278
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400279 SkASSERT(textureProxy->getLastOpList() == opList.get());
Robert Phillips4a395042017-04-24 16:27:17 +0000280
Robert Phillips6cdc22c2017-05-11 16:29:14 -0400281 fOpLists.push_back() = opList;
282
Robert Phillips4a395042017-04-24 16:27:17 +0000283 return opList;
Brian Osman45580d32016-11-23 09:37:01 -0500284}
285
brianosman86e76262016-08-11 12:17:31 -0700286GrAtlasTextContext* GrDrawingManager::getAtlasTextContext() {
287 if (!fAtlasTextContext) {
288 fAtlasTextContext.reset(GrAtlasTextContext::Create());
289 }
290
291 return fAtlasTextContext.get();
292}
293
robertphillips68737822015-10-29 12:12:21 -0700294/*
295 * This method finds a path renderer that can draw the specified path on
296 * the provided target.
297 * Due to its expense, the software path renderer has split out so it can
298 * can be individually allowed/disallowed via the "allowSW" boolean.
299 */
300GrPathRenderer* GrDrawingManager::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
301 bool allowSW,
302 GrPathRendererChain::DrawType drawType,
303 GrPathRenderer::StencilSupport* stencilSupport) {
304
305 if (!fPathRendererChain) {
bsalomon6b2552f2016-09-15 13:50:26 -0700306 fPathRendererChain = new GrPathRendererChain(fContext, fOptionsForPathRendererChain);
robertphillips68737822015-10-29 12:12:21 -0700307 }
308
309 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(args, drawType, stencilSupport);
310 if (!pr && allowSW) {
311 if (!fSoftwarePathRenderer) {
bsalomon39ef7fb2016-09-21 11:16:05 -0700312 fSoftwarePathRenderer =
Brian Osman32342f02017-03-04 08:12:46 -0500313 new GrSoftwarePathRenderer(fContext->resourceProvider(),
bsalomon39ef7fb2016-09-21 11:16:05 -0700314 fOptionsForPathRendererChain.fAllowPathMaskCaching);
robertphillips68737822015-10-29 12:12:21 -0700315 }
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500316 if (fSoftwarePathRenderer->canDrawPath(args)) {
317 pr = fSoftwarePathRenderer;
318 }
robertphillips68737822015-10-29 12:12:21 -0700319 }
320
321 return pr;
322}
323
Brian Osman11052242016-10-27 14:47:55 -0400324sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
Robert Phillips37430132016-11-09 06:50:43 -0500325 sk_sp<GrSurfaceProxy> sProxy,
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400326 sk_sp<SkColorSpace> colorSpace,
Robert Phillips941d1442017-06-14 16:37:02 -0400327 const SkSurfaceProps* surfaceProps,
328 bool managedOpList) {
Robert Phillips37430132016-11-09 06:50:43 -0500329 if (this->wasAbandoned() || !sProxy->asRenderTargetProxy()) {
robertphillips3dc6ae52015-10-20 09:54:32 -0700330 return nullptr;
331 }
332
brianosman0e22eb82016-08-30 07:07:59 -0700333 // SkSurface catches bad color space usage at creation. This check handles anything that slips
334 // by, including internal usage. We allow a null color space here, for read/write pixels and
335 // other special code paths. If a color space is provided, though, enforce all other rules.
Robert Phillips2c862492017-01-18 10:08:39 -0500336 if (colorSpace && !SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
brianosmana9c3c6a2016-09-29 10:08:36 -0700337 SkDEBUGFAIL("Invalid config and colorspace combination");
brianosman0e22eb82016-08-30 07:07:59 -0700338 return nullptr;
339 }
joshualitt96880d92016-02-16 10:36:53 -0800340
Robert Phillips2c862492017-01-18 10:08:39 -0500341 sk_sp<GrRenderTargetProxy> rtp(sk_ref_sp(sProxy->asRenderTargetProxy()));
342
joshualitt96880d92016-02-16 10:36:53 -0800343 bool useDIF = false;
344 if (surfaceProps) {
345 useDIF = surfaceProps->isUseDeviceIndependentFonts();
346 }
347
348 if (useDIF && fContext->caps()->shaderCaps()->pathRenderingSupport() &&
Brian Salomon7c8460e2017-05-12 11:36:10 -0400349 GrFSAAType::kNone != rtp->fsaaType()) {
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400350 // TODO: defer stencil buffer attachment for PathRenderingDrawContext
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400351 if (!rtp->instantiate(fContext->resourceProvider())) {
Robert Phillipse60ad622016-11-17 10:22:48 -0500352 return nullptr;
353 }
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400354 GrRenderTarget* rt = rtp->priv().peekRenderTarget();
355
356 GrStencilAttachment* sb = fContext->resourceProvider()->attachStencilAttachment(rt);
joshualitt96880d92016-02-16 10:36:53 -0800357 if (sb) {
Brian Osman11052242016-10-27 14:47:55 -0400358 return sk_sp<GrRenderTargetContext>(new GrPathRenderingRenderTargetContext(
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400359 fContext, this, std::move(rtp),
brianosmandfe4f2e2016-07-21 13:28:36 -0700360 std::move(colorSpace), surfaceProps,
robertphillips6c7e3252016-04-27 10:47:51 -0700361 fContext->getAuditTrail(), fSingleOwner));
joshualitt96880d92016-02-16 10:36:53 -0800362 }
363 }
364
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400365 return sk_sp<GrRenderTargetContext>(new GrRenderTargetContext(fContext, this, std::move(rtp),
Brian Osman11052242016-10-27 14:47:55 -0400366 std::move(colorSpace),
367 surfaceProps,
368 fContext->getAuditTrail(),
Robert Phillips941d1442017-06-14 16:37:02 -0400369 fSingleOwner, managedOpList));
robertphillips3dc6ae52015-10-20 09:54:32 -0700370}
Brian Osman45580d32016-11-23 09:37:01 -0500371
Robert Phillips2c862492017-01-18 10:08:39 -0500372sk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProxy> sProxy,
373 sk_sp<SkColorSpace> colorSpace) {
Brian Osman45580d32016-11-23 09:37:01 -0500374 if (this->wasAbandoned() || !sProxy->asTextureProxy()) {
375 return nullptr;
376 }
377
Robert Phillips2c862492017-01-18 10:08:39 -0500378 // SkSurface catches bad color space usage at creation. This check handles anything that slips
379 // by, including internal usage. We allow a null color space here, for read/write pixels and
380 // other special code paths. If a color space is provided, though, enforce all other rules.
381 if (colorSpace && !SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
382 SkDEBUGFAIL("Invalid config and colorspace combination");
383 return nullptr;
384 }
385
Brian Osman45580d32016-11-23 09:37:01 -0500386 // GrTextureRenderTargets should always be using GrRenderTargetContext
387 SkASSERT(!sProxy->asRenderTargetProxy());
388
389 sk_sp<GrTextureProxy> textureProxy(sk_ref_sp(sProxy->asTextureProxy()));
390
391 return sk_sp<GrTextureContext>(new GrTextureContext(fContext, this, std::move(textureProxy),
Robert Phillips2c862492017-01-18 10:08:39 -0500392 std::move(colorSpace),
393 fContext->getAuditTrail(),
394 fSingleOwner));
Brian Osman45580d32016-11-23 09:37:01 -0500395}