blob: 23f25cdb5e9dc81696ca5c8f39717693dbd9c565 [file] [log] [blame]
Robert Phillips4217ea72019-01-30 13:08:28 -05001/*
2 * Copyright 2019 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#include "GrRecordingContext.h"
9
Robert Phillipsa41c6852019-02-07 10:44:10 -050010#include "GrCaps.h"
Robert Phillips0d075de2019-03-04 11:08:13 -050011#include "GrContext.h"
Robert Phillipsb97da532019-02-12 15:24:12 -050012#include "GrDrawingManager.h"
Robert Phillipsd6841482019-02-08 10:29:20 -050013#include "GrMemoryPool.h"
Robert Phillipsb97da532019-02-12 15:24:12 -050014#include "GrProxyProvider.h"
Robert Phillipsa41c6852019-02-07 10:44:10 -050015#include "GrRecordingContextPriv.h"
Robert Phillipsb97da532019-02-12 15:24:12 -050016#include "GrRenderTargetContext.h"
Robert Phillipsa41c6852019-02-07 10:44:10 -050017#include "GrSkSLFPFactoryCache.h"
Robert Phillips292a6b22019-02-14 14:49:02 -050018#include "GrTextureContext.h"
Robert Phillips6f0e02f2019-02-13 11:02:28 -050019#include "SkGr.h"
Robert Phillips2184fb72019-02-21 16:11:41 -050020#include "text/GrTextBlobCache.h"
Robert Phillipsa41c6852019-02-07 10:44:10 -050021
Robert Phillips292a6b22019-02-14 14:49:02 -050022#define ASSERT_SINGLE_OWNER_PRIV \
23 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
24
Robert Phillipsc1541ae2019-02-04 12:05:37 -050025GrRecordingContext::GrRecordingContext(GrBackendApi backend,
26 const GrContextOptions& options,
Robert Phillipsa41c6852019-02-07 10:44:10 -050027 uint32_t contextID)
28 : INHERITED(backend, options, contextID) {
Robert Phillips4217ea72019-01-30 13:08:28 -050029}
30
31GrRecordingContext::~GrRecordingContext() { }
32
Robert Phillips2184fb72019-02-21 16:11:41 -050033/**
34 * TODO: move textblob draw calls below context (see comment below)
35 */
36static void textblobcache_overbudget_CB(void* data) {
37 SkASSERT(data);
38 GrRecordingContext* context = reinterpret_cast<GrRecordingContext*>(data);
39
40 GrContext* direct = context->priv().asDirectContext();
41 if (!direct) {
42 return;
43 }
44
45 // TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on
46 // GrRenderTargetContext to perform a necessary flush. The solution is to move drawText calls
47 // to below the GrContext level, but this is not trivial because they call drawPath on
48 // SkGpuDevice.
49 direct->flush();
50}
51
Robert Phillips292a6b22019-02-14 14:49:02 -050052bool GrRecordingContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> cache) {
53
54 if (!INHERITED::init(std::move(caps), std::move(cache))) {
55 return false;
56 }
57
Herb Derbya00da612019-03-04 17:10:01 -050058 fStrikeCache.reset(new GrStrikeCache(this->caps(),
Robert Phillips2184fb72019-02-21 16:11:41 -050059 this->options().fGlyphCacheTextureMaximumBytes));
60
61 fTextBlobCache.reset(new GrTextBlobCache(textblobcache_overbudget_CB, this,
62 this->contextID()));
63
Robert Phillips69893702019-02-22 11:16:30 -050064 GrPathRendererChain::Options prcOptions;
65 prcOptions.fAllowPathMaskCaching = this->options().fAllowPathMaskCaching;
66#if GR_TEST_UTILS
67 prcOptions.fGpuPathRenderers = this->options().fGpuPathRenderers;
68#endif
69 if (this->options().fDisableCoverageCountingPaths) {
70 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
71 }
72 if (this->options().fDisableDistanceFieldPaths) {
73 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
74 }
75
76 if (!this->proxyProvider()->renderingDirectly()) {
77 // DDL TODO: remove this crippling of the path renderer chain
78 // Disable the small path renderer bc of the proxies in the atlas. They need to be
79 // unified when the opLists are added back to the destination drawing manager.
80 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
81 }
82
83 GrTextContext::Options textContextOptions;
84 textContextOptions.fMaxDistanceFieldFontSize = this->options().fGlyphsAsPathsFontSize;
85 textContextOptions.fMinDistanceFieldFontSize = this->options().fMinDistanceFieldFontSize;
86 textContextOptions.fDistanceFieldVerticesAlwaysHaveW = false;
87#if SK_SUPPORT_ATLAS_TEXT
88 if (GrContextOptions::Enable::kYes == this->options().fDistanceFieldGlyphVerticesAlwaysHaveW) {
89 textContextOptions.fDistanceFieldVerticesAlwaysHaveW = true;
90 }
91#endif
92
93 fDrawingManager.reset(new GrDrawingManager(this,
94 prcOptions,
95 textContextOptions,
Robert Phillips69893702019-02-22 11:16:30 -050096 this->explicitlyAllocateGPUResources(),
97 this->options().fSortRenderTargets,
98 this->options().fReduceOpListSplitting));
Robert Phillips292a6b22019-02-14 14:49:02 -050099 return true;
100}
101
Robert Phillipsa9162df2019-02-11 14:12:03 -0500102void GrRecordingContext::abandonContext() {
103 INHERITED::abandonContext();
Robert Phillips2184fb72019-02-21 16:11:41 -0500104
Herb Derbya00da612019-03-04 17:10:01 -0500105 fStrikeCache->freeAll();
Robert Phillips2184fb72019-02-21 16:11:41 -0500106 fTextBlobCache->freeAll();
Robert Phillipsa9162df2019-02-11 14:12:03 -0500107}
108
Robert Phillips69893702019-02-22 11:16:30 -0500109GrDrawingManager* GrRecordingContext::drawingManager() {
110 return fDrawingManager.get();
111}
112
Robert Phillipsd6841482019-02-08 10:29:20 -0500113sk_sp<GrOpMemoryPool> GrRecordingContext::refOpMemoryPool() {
114 if (!fOpMemoryPool) {
115 // DDL TODO: should the size of the memory pool be decreased in DDL mode? CPU-side memory
116 // consumed in DDL mode vs. normal mode for a single skp might be a good metric of wasted
117 // memory.
118 fOpMemoryPool = sk_sp<GrOpMemoryPool>(new GrOpMemoryPool(16384, 16384));
119 }
120
121 SkASSERT(fOpMemoryPool);
122 return fOpMemoryPool;
123}
124
125GrOpMemoryPool* GrRecordingContext::opMemoryPool() {
126 return this->refOpMemoryPool().get();
127}
128
Robert Phillips2184fb72019-02-21 16:11:41 -0500129GrTextBlobCache* GrRecordingContext::getTextBlobCache() {
130 return fTextBlobCache.get();
131}
132
133const GrTextBlobCache* GrRecordingContext::getTextBlobCache() const {
134 return fTextBlobCache.get();
135}
136
Robert Phillipsc5058a62019-02-15 12:52:59 -0500137void GrRecordingContext::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
138 this->drawingManager()->addOnFlushCallbackObject(onFlushCBObject);
139}
140
Robert Phillips292a6b22019-02-14 14:49:02 -0500141sk_sp<GrSurfaceContext> GrRecordingContext::makeWrappedSurfaceContext(
142 sk_sp<GrSurfaceProxy> proxy,
143 sk_sp<SkColorSpace> colorSpace,
144 const SkSurfaceProps* props) {
145 ASSERT_SINGLE_OWNER_PRIV
146
147 if (proxy->asRenderTargetProxy()) {
148 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
149 std::move(colorSpace), props);
150 } else {
151 SkASSERT(proxy->asTextureProxy());
152 SkASSERT(!props);
153 return this->drawingManager()->makeTextureContext(std::move(proxy), std::move(colorSpace));
154 }
155}
156
157sk_sp<GrSurfaceContext> GrRecordingContext::makeDeferredSurfaceContext(
158 const GrBackendFormat& format,
159 const GrSurfaceDesc& dstDesc,
160 GrSurfaceOrigin origin,
161 GrMipMapped mipMapped,
162 SkBackingFit fit,
163 SkBudgeted isDstBudgeted,
164 sk_sp<SkColorSpace> colorSpace,
165 const SkSurfaceProps* props) {
166 sk_sp<GrTextureProxy> proxy;
167 if (GrMipMapped::kNo == mipMapped) {
168 proxy = this->proxyProvider()->createProxy(format, dstDesc, origin, fit, isDstBudgeted);
169 } else {
170 SkASSERT(SkBackingFit::kExact == fit);
171 proxy = this->proxyProvider()->createMipMapProxy(format, dstDesc, origin, isDstBudgeted);
172 }
173 if (!proxy) {
174 return nullptr;
175 }
176
177 sk_sp<GrSurfaceContext> sContext = this->makeWrappedSurfaceContext(std::move(proxy),
178 std::move(colorSpace),
179 props);
180 if (sContext && sContext->asRenderTargetContext()) {
181 sContext->asRenderTargetContext()->discard();
182 }
183
184 return sContext;
185}
186
Robert Phillipsb97da532019-02-12 15:24:12 -0500187sk_sp<GrRenderTargetContext> GrRecordingContext::makeDeferredRenderTargetContext(
188 const GrBackendFormat& format,
189 SkBackingFit fit,
190 int width, int height,
191 GrPixelConfig config,
192 sk_sp<SkColorSpace> colorSpace,
193 int sampleCnt,
194 GrMipMapped mipMapped,
195 GrSurfaceOrigin origin,
196 const SkSurfaceProps* surfaceProps,
197 SkBudgeted budgeted) {
198 SkASSERT(sampleCnt > 0);
199 if (this->abandoned()) {
200 return nullptr;
201 }
202
203 GrSurfaceDesc desc;
204 desc.fFlags = kRenderTarget_GrSurfaceFlag;
205 desc.fWidth = width;
206 desc.fHeight = height;
207 desc.fConfig = config;
208 desc.fSampleCnt = sampleCnt;
209
210 sk_sp<GrTextureProxy> rtp;
211 if (GrMipMapped::kNo == mipMapped) {
212 rtp = this->proxyProvider()->createProxy(format, desc, origin, fit, budgeted);
213 } else {
214 rtp = this->proxyProvider()->createMipMapProxy(format, desc, origin, budgeted);
215 }
216 if (!rtp) {
217 return nullptr;
218 }
219
Robert Phillipsb97da532019-02-12 15:24:12 -0500220 auto drawingManager = this->drawingManager();
221
222 sk_sp<GrRenderTargetContext> renderTargetContext =
223 drawingManager->makeRenderTargetContext(std::move(rtp), std::move(colorSpace),
224 surfaceProps);
225 if (!renderTargetContext) {
226 return nullptr;
227 }
228
229 renderTargetContext->discard();
230
231 return renderTargetContext;
232}
Robert Phillipsd6841482019-02-08 10:29:20 -0500233
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500234static inline GrPixelConfig GrPixelConfigFallback(GrPixelConfig config) {
235 switch (config) {
236 case kAlpha_8_GrPixelConfig:
237 case kAlpha_8_as_Alpha_GrPixelConfig:
238 case kAlpha_8_as_Red_GrPixelConfig:
239 case kRGB_565_GrPixelConfig:
240 case kRGBA_4444_GrPixelConfig:
241 case kBGRA_8888_GrPixelConfig:
242 case kRGBA_1010102_GrPixelConfig:
243 case kRGBA_half_GrPixelConfig:
244 return kRGBA_8888_GrPixelConfig;
245 case kSBGRA_8888_GrPixelConfig:
246 return kSRGBA_8888_GrPixelConfig;
247 case kAlpha_half_GrPixelConfig:
248 case kAlpha_half_as_Red_GrPixelConfig:
249 return kRGBA_half_GrPixelConfig;
250 case kGray_8_GrPixelConfig:
251 case kGray_8_as_Lum_GrPixelConfig:
252 case kGray_8_as_Red_GrPixelConfig:
253 return kRGB_888_GrPixelConfig;
254 default:
255 return kUnknown_GrPixelConfig;
256 }
257}
258
259sk_sp<GrRenderTargetContext> GrRecordingContext::makeDeferredRenderTargetContextWithFallback(
260 const GrBackendFormat& format,
261 SkBackingFit fit,
262 int width, int height,
263 GrPixelConfig config,
264 sk_sp<SkColorSpace> colorSpace,
265 int sampleCnt,
266 GrMipMapped mipMapped,
267 GrSurfaceOrigin origin,
268 const SkSurfaceProps* surfaceProps,
269 SkBudgeted budgeted) {
270 GrBackendFormat localFormat = format;
271 SkASSERT(sampleCnt > 0);
272 if (0 == this->caps()->getRenderTargetSampleCount(sampleCnt, config)) {
273 config = GrPixelConfigFallback(config);
274 // TODO: First we should be checking the getRenderTargetSampleCount from the GrBackendFormat
275 // and not GrPixelConfig. Besides that, we should implement the fallback in the caps, but
276 // for now we just convert the fallback pixel config to an SkColorType and then get the
277 // GrBackendFormat from that.
278 SkColorType colorType;
279 if (!GrPixelConfigToColorType(config, &colorType)) {
280 return nullptr;
281 }
282 localFormat = this->caps()->getBackendFormatFromColorType(colorType);
283 }
284
285 return this->makeDeferredRenderTargetContext(localFormat, fit, width, height, config,
286 std::move(colorSpace), sampleCnt, mipMapped,
287 origin, surfaceProps, budgeted);
288}
289
Robert Phillipsa41c6852019-02-07 10:44:10 -0500290///////////////////////////////////////////////////////////////////////////////////////////////////
291sk_sp<const GrCaps> GrRecordingContextPriv::refCaps() const {
292 return fContext->refCaps();
293}
294
295sk_sp<GrSkSLFPFactoryCache> GrRecordingContextPriv::fpFactoryCache() {
296 return fContext->fpFactoryCache();
297}
Robert Phillipsd6841482019-02-08 10:29:20 -0500298
299sk_sp<GrOpMemoryPool> GrRecordingContextPriv::refOpMemoryPool() {
300 return fContext->refOpMemoryPool();
301}
Robert Phillipsb97da532019-02-12 15:24:12 -0500302
Robert Phillipsc5058a62019-02-15 12:52:59 -0500303void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
304 fContext->addOnFlushCallbackObject(onFlushCBObject);
305}
306
Robert Phillips292a6b22019-02-14 14:49:02 -0500307sk_sp<GrSurfaceContext> GrRecordingContextPriv::makeWrappedSurfaceContext(
308 sk_sp<GrSurfaceProxy> proxy,
309 sk_sp<SkColorSpace> colorSpace,
310 const SkSurfaceProps* props) {
311 return fContext->makeWrappedSurfaceContext(std::move(proxy), std::move(colorSpace), props);
312}
313
314sk_sp<GrSurfaceContext> GrRecordingContextPriv::makeDeferredSurfaceContext(
315 const GrBackendFormat& format,
316 const GrSurfaceDesc& dstDesc,
317 GrSurfaceOrigin origin,
318 GrMipMapped mipMapped,
319 SkBackingFit fit,
320 SkBudgeted isDstBudgeted,
321 sk_sp<SkColorSpace> colorSpace,
322 const SkSurfaceProps* props) {
323 return fContext->makeDeferredSurfaceContext(format, dstDesc, origin, mipMapped, fit,
324 isDstBudgeted, std::move(colorSpace), props);
325}
326
Robert Phillipsb97da532019-02-12 15:24:12 -0500327sk_sp<GrRenderTargetContext> GrRecordingContextPriv::makeDeferredRenderTargetContext(
328 const GrBackendFormat& format,
329 SkBackingFit fit,
330 int width, int height,
331 GrPixelConfig config,
332 sk_sp<SkColorSpace> colorSpace,
333 int sampleCnt,
334 GrMipMapped mipMapped,
335 GrSurfaceOrigin origin,
336 const SkSurfaceProps* surfaceProps,
337 SkBudgeted budgeted) {
338 return fContext->makeDeferredRenderTargetContext(format, fit, width, height, config,
339 std::move(colorSpace), sampleCnt, mipMapped,
340 origin, surfaceProps, budgeted);
341}
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500342
343sk_sp<GrRenderTargetContext> GrRecordingContextPriv::makeDeferredRenderTargetContextWithFallback(
344 const GrBackendFormat& format,
345 SkBackingFit fit,
346 int width, int height,
347 GrPixelConfig config,
348 sk_sp<SkColorSpace> colorSpace,
349 int sampleCnt,
350 GrMipMapped mipMapped,
351 GrSurfaceOrigin origin,
352 const SkSurfaceProps* surfaceProps,
353 SkBudgeted budgeted) {
354 return fContext->makeDeferredRenderTargetContextWithFallback(format, fit, width, height, config,
355 std::move(colorSpace), sampleCnt,
356 mipMapped, origin, surfaceProps,
357 budgeted);
358}
Robert Phillips9338c602019-02-19 12:52:29 -0500359
360GrContext* GrRecordingContextPriv::backdoor() {
361 return (GrContext*) fContext;
362}