blob: 7384e3c169a8240791dfa33a9009018297492df7 [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 Phillipsb97da532019-02-12 15:24:12 -050011#include "GrDrawingManager.h"
Robert Phillipsd6841482019-02-08 10:29:20 -050012#include "GrMemoryPool.h"
Robert Phillipsb97da532019-02-12 15:24:12 -050013#include "GrProxyProvider.h"
Robert Phillipsa41c6852019-02-07 10:44:10 -050014#include "GrRecordingContextPriv.h"
Robert Phillipsb97da532019-02-12 15:24:12 -050015#include "GrRenderTargetContext.h"
Robert Phillipsa41c6852019-02-07 10:44:10 -050016#include "GrSkSLFPFactoryCache.h"
Robert Phillips292a6b22019-02-14 14:49:02 -050017#include "GrTextureContext.h"
Robert Phillips6f0e02f2019-02-13 11:02:28 -050018#include "SkGr.h"
Robert Phillips2184fb72019-02-21 16:11:41 -050019#include "text/GrTextBlobCache.h"
Robert Phillipsa41c6852019-02-07 10:44:10 -050020
Robert Phillips292a6b22019-02-14 14:49:02 -050021#define ASSERT_SINGLE_OWNER_PRIV \
22 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
23
Robert Phillipsc1541ae2019-02-04 12:05:37 -050024GrRecordingContext::GrRecordingContext(GrBackendApi backend,
25 const GrContextOptions& options,
Robert Phillipsa41c6852019-02-07 10:44:10 -050026 uint32_t contextID)
27 : INHERITED(backend, options, contextID) {
Robert Phillips4217ea72019-01-30 13:08:28 -050028}
29
30GrRecordingContext::~GrRecordingContext() { }
31
Robert Phillips2184fb72019-02-21 16:11:41 -050032/**
33 * TODO: move textblob draw calls below context (see comment below)
34 */
35static void textblobcache_overbudget_CB(void* data) {
36 SkASSERT(data);
37 GrRecordingContext* context = reinterpret_cast<GrRecordingContext*>(data);
38
39 GrContext* direct = context->priv().asDirectContext();
40 if (!direct) {
41 return;
42 }
43
44 // TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on
45 // GrRenderTargetContext to perform a necessary flush. The solution is to move drawText calls
46 // to below the GrContext level, but this is not trivial because they call drawPath on
47 // SkGpuDevice.
48 direct->flush();
49}
50
Robert Phillips292a6b22019-02-14 14:49:02 -050051bool GrRecordingContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> cache) {
52
53 if (!INHERITED::init(std::move(caps), std::move(cache))) {
54 return false;
55 }
56
Robert Phillips2184fb72019-02-21 16:11:41 -050057 fGlyphCache.reset(new GrStrikeCache(this->caps(),
58 this->options().fGlyphCacheTextureMaximumBytes));
59
60 fTextBlobCache.reset(new GrTextBlobCache(textblobcache_overbudget_CB, this,
61 this->contextID()));
62
Robert Phillips69893702019-02-22 11:16:30 -050063 GrPathRendererChain::Options prcOptions;
64 prcOptions.fAllowPathMaskCaching = this->options().fAllowPathMaskCaching;
65#if GR_TEST_UTILS
66 prcOptions.fGpuPathRenderers = this->options().fGpuPathRenderers;
67#endif
68 if (this->options().fDisableCoverageCountingPaths) {
69 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
70 }
71 if (this->options().fDisableDistanceFieldPaths) {
72 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
73 }
74
75 if (!this->proxyProvider()->renderingDirectly()) {
76 // DDL TODO: remove this crippling of the path renderer chain
77 // Disable the small path renderer bc of the proxies in the atlas. They need to be
78 // unified when the opLists are added back to the destination drawing manager.
79 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
80 }
81
82 GrTextContext::Options textContextOptions;
83 textContextOptions.fMaxDistanceFieldFontSize = this->options().fGlyphsAsPathsFontSize;
84 textContextOptions.fMinDistanceFieldFontSize = this->options().fMinDistanceFieldFontSize;
85 textContextOptions.fDistanceFieldVerticesAlwaysHaveW = false;
86#if SK_SUPPORT_ATLAS_TEXT
87 if (GrContextOptions::Enable::kYes == this->options().fDistanceFieldGlyphVerticesAlwaysHaveW) {
88 textContextOptions.fDistanceFieldVerticesAlwaysHaveW = true;
89 }
90#endif
91
92 fDrawingManager.reset(new GrDrawingManager(this,
93 prcOptions,
94 textContextOptions,
95 this->singleOwner(),
96 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
105 fGlyphCache->freeAll();
106 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}