1 /*
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 "include/private/GrRecordingContext.h"
9
10 #include "include/gpu/GrContext.h"
11 #include "src/gpu/GrAuditTrail.h"
12 #include "src/gpu/GrCaps.h"
13 #include "src/gpu/GrDrawingManager.h"
14 #include "src/gpu/GrMemoryPool.h"
15 #include "src/gpu/GrProxyProvider.h"
16 #include "src/gpu/GrRecordingContextPriv.h"
17 #include "src/gpu/GrRenderTargetContext.h"
18 #include "src/gpu/GrSkSLFPFactoryCache.h"
19 #include "src/gpu/GrTextureContext.h"
20 #include "src/gpu/SkGr.h"
21 #include "src/gpu/text/GrTextBlobCache.h"
22
23 #define ASSERT_SINGLE_OWNER_PRIV \
24 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
25
GrRecordingContext(GrBackendApi backend,const GrContextOptions & options,uint32_t contextID)26 GrRecordingContext::GrRecordingContext(GrBackendApi backend,
27 const GrContextOptions& options,
28 uint32_t contextID)
29 : INHERITED(backend, options, contextID)
30 , fAuditTrail(new GrAuditTrail()) {
31 }
32
~GrRecordingContext()33 GrRecordingContext::~GrRecordingContext() { }
34
35 /**
36 * TODO: move textblob draw calls below context (see comment below)
37 */
textblobcache_overbudget_CB(void * data)38 static void textblobcache_overbudget_CB(void* data) {
39 SkASSERT(data);
40 GrRecordingContext* context = reinterpret_cast<GrRecordingContext*>(data);
41
42 GrContext* direct = context->priv().asDirectContext();
43 if (!direct) {
44 return;
45 }
46
47 // TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on
48 // GrRenderTargetContext to perform a necessary flush. The solution is to move drawText calls
49 // to below the GrContext level, but this is not trivial because they call drawPath on
50 // SkGpuDevice.
51 direct->flush();
52 }
53
init(sk_sp<const GrCaps> caps,sk_sp<GrSkSLFPFactoryCache> cache)54 bool GrRecordingContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> cache) {
55
56 if (!INHERITED::init(std::move(caps), std::move(cache))) {
57 return false;
58 }
59
60 fStrikeCache.reset(new GrStrikeCache(this->caps(),
61 this->options().fGlyphCacheTextureMaximumBytes));
62
63 fTextBlobCache.reset(new GrTextBlobCache(textblobcache_overbudget_CB, this,
64 this->contextID()));
65
66 return true;
67 }
68
setupDrawingManager(bool sortOpLists,bool reduceOpListSplitting)69 void GrRecordingContext::setupDrawingManager(bool sortOpLists, bool reduceOpListSplitting) {
70 GrPathRendererChain::Options prcOptions;
71 prcOptions.fAllowPathMaskCaching = this->options().fAllowPathMaskCaching;
72 #if GR_TEST_UTILS
73 prcOptions.fGpuPathRenderers = this->options().fGpuPathRenderers;
74 #endif
75 // FIXME: Once this is removed from Chrome and Android, rename to fEnable"".
76 if (!this->options().fDisableCoverageCountingPaths) {
77 prcOptions.fGpuPathRenderers |= GpuPathRenderers::kCoverageCounting;
78 }
79 if (this->options().fDisableDistanceFieldPaths) {
80 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
81 }
82
83 if (!this->proxyProvider()->renderingDirectly()) {
84 // DDL TODO: remove this crippling of the path renderer chain
85 // Disable the small path renderer bc of the proxies in the atlas. They need to be
86 // unified when the opLists are added back to the destination drawing manager.
87 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
88 }
89
90 GrTextContext::Options textContextOptions;
91 textContextOptions.fMaxDistanceFieldFontSize = this->options().fGlyphsAsPathsFontSize;
92 textContextOptions.fMinDistanceFieldFontSize = this->options().fMinDistanceFieldFontSize;
93 textContextOptions.fDistanceFieldVerticesAlwaysHaveW = false;
94 #if SK_SUPPORT_ATLAS_TEXT
95 if (GrContextOptions::Enable::kYes == this->options().fDistanceFieldGlyphVerticesAlwaysHaveW) {
96 textContextOptions.fDistanceFieldVerticesAlwaysHaveW = true;
97 }
98 #endif
99
100 fDrawingManager.reset(new GrDrawingManager(this,
101 prcOptions,
102 textContextOptions,
103 sortOpLists,
104 reduceOpListSplitting));
105 }
106
abandonContext()107 void GrRecordingContext::abandonContext() {
108 INHERITED::abandonContext();
109
110 fStrikeCache->freeAll();
111 fTextBlobCache->freeAll();
112 }
113
drawingManager()114 GrDrawingManager* GrRecordingContext::drawingManager() {
115 return fDrawingManager.get();
116 }
117
refOpMemoryPool()118 sk_sp<GrOpMemoryPool> GrRecordingContext::refOpMemoryPool() {
119 if (!fOpMemoryPool) {
120 // DDL TODO: should the size of the memory pool be decreased in DDL mode? CPU-side memory
121 // consumed in DDL mode vs. normal mode for a single skp might be a good metric of wasted
122 // memory.
123 fOpMemoryPool = sk_sp<GrOpMemoryPool>(new GrOpMemoryPool(16384, 16384));
124 }
125
126 SkASSERT(fOpMemoryPool);
127 return fOpMemoryPool;
128 }
129
opMemoryPool()130 GrOpMemoryPool* GrRecordingContext::opMemoryPool() {
131 return this->refOpMemoryPool().get();
132 }
133
getTextBlobCache()134 GrTextBlobCache* GrRecordingContext::getTextBlobCache() {
135 return fTextBlobCache.get();
136 }
137
getTextBlobCache() const138 const GrTextBlobCache* GrRecordingContext::getTextBlobCache() const {
139 return fTextBlobCache.get();
140 }
141
addOnFlushCallbackObject(GrOnFlushCallbackObject * onFlushCBObject)142 void GrRecordingContext::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
143 this->drawingManager()->addOnFlushCallbackObject(onFlushCBObject);
144 }
145
makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,GrColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * props)146 sk_sp<GrSurfaceContext> GrRecordingContext::makeWrappedSurfaceContext(
147 sk_sp<GrSurfaceProxy> proxy,
148 GrColorType colorType,
149 SkAlphaType alphaType,
150 sk_sp<SkColorSpace> colorSpace,
151 const SkSurfaceProps* props) {
152 ASSERT_SINGLE_OWNER_PRIV
153
154 SkASSERT(proxy);
155
156 if (proxy->asRenderTargetProxy()) {
157 SkASSERT(kPremul_SkAlphaType == alphaType || kOpaque_SkAlphaType == alphaType);
158 return this->drawingManager()->makeRenderTargetContext(std::move(proxy), colorType,
159 std::move(colorSpace), props);
160 } else {
161 SkASSERT(proxy->asTextureProxy());
162 SkASSERT(!props);
163 return this->drawingManager()->makeTextureContext(std::move(proxy), colorType, alphaType,
164 std::move(colorSpace));
165 }
166 }
167
makeDeferredTextureContext(SkBackingFit fit,int width,int height,GrColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace,GrMipMapped mipMapped,GrSurfaceOrigin origin,SkBudgeted budgeted,GrProtected isProtected)168 sk_sp<GrTextureContext> GrRecordingContext::makeDeferredTextureContext(
169 SkBackingFit fit,
170 int width,
171 int height,
172 GrColorType colorType,
173 SkAlphaType alphaType,
174 sk_sp<SkColorSpace> colorSpace,
175 GrMipMapped mipMapped,
176 GrSurfaceOrigin origin,
177 SkBudgeted budgeted,
178 GrProtected isProtected) {
179 auto format = this->caps()->getDefaultBackendFormat(colorType, GrRenderable::kNo);
180 if (!format.isValid()) {
181 return nullptr;
182 }
183 auto config = this->caps()->getConfigFromBackendFormat(format, colorType);
184 if (config == kUnknown_GrPixelConfig) {
185 return nullptr;
186 }
187
188 GrSurfaceDesc desc;
189 desc.fWidth = width;
190 desc.fHeight = height;
191 desc.fConfig = config;
192
193 sk_sp<GrTextureProxy> texture;
194 if (GrMipMapped::kNo == mipMapped) {
195 texture = this->proxyProvider()->createProxy(format, desc, GrRenderable::kNo, 1, origin,
196 fit, budgeted, isProtected);
197 } else {
198 texture = this->proxyProvider()->createMipMapProxy(format, desc, GrRenderable::kNo, 1,
199 origin, budgeted, isProtected);
200 }
201 if (!texture) {
202 return nullptr;
203 }
204
205 auto drawingManager = this->drawingManager();
206
207 return drawingManager->makeTextureContext(std::move(texture), colorType, alphaType,
208 std::move(colorSpace));
209 }
210
makeDeferredRenderTargetContext(SkBackingFit fit,int width,int height,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,int sampleCnt,GrMipMapped mipMapped,GrSurfaceOrigin origin,const SkSurfaceProps * surfaceProps,SkBudgeted budgeted,GrProtected isProtected)211 sk_sp<GrRenderTargetContext> GrRecordingContext::makeDeferredRenderTargetContext(
212 SkBackingFit fit,
213 int width,
214 int height,
215 GrColorType colorType,
216 sk_sp<SkColorSpace> colorSpace,
217 int sampleCnt,
218 GrMipMapped mipMapped,
219 GrSurfaceOrigin origin,
220 const SkSurfaceProps* surfaceProps,
221 SkBudgeted budgeted,
222 GrProtected isProtected) {
223 SkASSERT(sampleCnt > 0);
224 if (this->abandoned()) {
225 return nullptr;
226 }
227
228 auto format = this->caps()->getDefaultBackendFormat(colorType, GrRenderable::kYes);
229 if (!format.isValid()) {
230 return nullptr;
231 }
232 auto config = this->caps()->getConfigFromBackendFormat(format, colorType);
233 if (config == kUnknown_GrPixelConfig) {
234 return nullptr;
235 }
236
237 GrSurfaceDesc desc;
238 desc.fWidth = width;
239 desc.fHeight = height;
240 desc.fConfig = config;
241
242 sk_sp<GrTextureProxy> rtp;
243 if (GrMipMapped::kNo == mipMapped) {
244 rtp = this->proxyProvider()->createProxy(format, desc, GrRenderable::kYes, sampleCnt,
245 origin, fit, budgeted, isProtected);
246 } else {
247 rtp = this->proxyProvider()->createMipMapProxy(format, desc, GrRenderable::kYes, sampleCnt,
248 origin, budgeted, isProtected);
249 }
250 if (!rtp) {
251 return nullptr;
252 }
253
254 auto drawingManager = this->drawingManager();
255
256 sk_sp<GrRenderTargetContext> renderTargetContext = drawingManager->makeRenderTargetContext(
257 std::move(rtp), colorType, std::move(colorSpace), surfaceProps);
258 if (!renderTargetContext) {
259 return nullptr;
260 }
261
262 renderTargetContext->discard();
263
264 return renderTargetContext;
265 }
266
color_type_fallback(GrColorType ct)267 static inline GrColorType color_type_fallback(GrColorType ct) {
268 switch (ct) {
269 // kRGBA_8888 is our default fallback for many color types that may not have renderable
270 // backend formats.
271 case GrColorType::kAlpha_8:
272 case GrColorType::kBGR_565:
273 case GrColorType::kABGR_4444:
274 case GrColorType::kBGRA_8888:
275 case GrColorType::kRGBA_1010102:
276 case GrColorType::kRGBA_F16:
277 case GrColorType::kRGBA_F16_Clamped:
278 return GrColorType::kRGBA_8888;
279 case GrColorType::kAlpha_F16:
280 return GrColorType::kRGBA_F16;
281 case GrColorType::kGray_8:
282 return GrColorType::kRGB_888x;
283 default:
284 return GrColorType::kUnknown;
285 }
286 }
287
makeDeferredRenderTargetContextWithFallback(SkBackingFit fit,int width,int height,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,int sampleCnt,GrMipMapped mipMapped,GrSurfaceOrigin origin,const SkSurfaceProps * surfaceProps,SkBudgeted budgeted,GrProtected isProtected)288 sk_sp<GrRenderTargetContext> GrRecordingContext::makeDeferredRenderTargetContextWithFallback(
289 SkBackingFit fit,
290 int width,
291 int height,
292 GrColorType colorType,
293 sk_sp<SkColorSpace> colorSpace,
294 int sampleCnt,
295 GrMipMapped mipMapped,
296 GrSurfaceOrigin origin,
297 const SkSurfaceProps* surfaceProps,
298 SkBudgeted budgeted,
299 GrProtected isProtected) {
300 SkASSERT(sampleCnt > 0);
301 sk_sp<GrRenderTargetContext> rtc;
302 do {
303 rtc = this->makeDeferredRenderTargetContext(fit, width, height, colorType, colorSpace,
304 sampleCnt, mipMapped, origin, surfaceProps,
305 budgeted, isProtected);
306 colorType = color_type_fallback(colorType);
307 } while (!rtc && colorType != GrColorType::kUnknown);
308 return rtc;
309 }
310
311 ///////////////////////////////////////////////////////////////////////////////////////////////////
refCaps() const312 sk_sp<const GrCaps> GrRecordingContextPriv::refCaps() const {
313 return fContext->refCaps();
314 }
315
fpFactoryCache()316 sk_sp<GrSkSLFPFactoryCache> GrRecordingContextPriv::fpFactoryCache() {
317 return fContext->fpFactoryCache();
318 }
319
refOpMemoryPool()320 sk_sp<GrOpMemoryPool> GrRecordingContextPriv::refOpMemoryPool() {
321 return fContext->refOpMemoryPool();
322 }
323
addOnFlushCallbackObject(GrOnFlushCallbackObject * onFlushCBObject)324 void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
325 fContext->addOnFlushCallbackObject(onFlushCBObject);
326 }
327
makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,GrColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * props)328 sk_sp<GrSurfaceContext> GrRecordingContextPriv::makeWrappedSurfaceContext(
329 sk_sp<GrSurfaceProxy> proxy,
330 GrColorType colorType,
331 SkAlphaType alphaType,
332 sk_sp<SkColorSpace> colorSpace,
333 const SkSurfaceProps* props) {
334 return fContext->makeWrappedSurfaceContext(std::move(proxy), colorType, alphaType,
335 std::move(colorSpace), props);
336 }
337
makeDeferredTextureContext(SkBackingFit fit,int width,int height,GrColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace,GrMipMapped mipMapped,GrSurfaceOrigin origin,SkBudgeted budgeted,GrProtected isProtected)338 sk_sp<GrTextureContext> GrRecordingContextPriv::makeDeferredTextureContext(
339 SkBackingFit fit,
340 int width,
341 int height,
342 GrColorType colorType,
343 SkAlphaType alphaType,
344 sk_sp<SkColorSpace> colorSpace,
345 GrMipMapped mipMapped,
346 GrSurfaceOrigin origin,
347 SkBudgeted budgeted,
348 GrProtected isProtected) {
349 return fContext->makeDeferredTextureContext(fit, width, height, colorType, alphaType,
350 std::move(colorSpace), mipMapped, origin, budgeted,
351 isProtected);
352 }
353
makeDeferredRenderTargetContext(SkBackingFit fit,int width,int height,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,int sampleCnt,GrMipMapped mipMapped,GrSurfaceOrigin origin,const SkSurfaceProps * surfaceProps,SkBudgeted budgeted,GrProtected isProtected)354 sk_sp<GrRenderTargetContext> GrRecordingContextPriv::makeDeferredRenderTargetContext(
355 SkBackingFit fit,
356 int width,
357 int height,
358 GrColorType colorType,
359 sk_sp<SkColorSpace> colorSpace,
360 int sampleCnt,
361 GrMipMapped mipMapped,
362 GrSurfaceOrigin origin,
363 const SkSurfaceProps* surfaceProps,
364 SkBudgeted budgeted,
365 GrProtected isProtected) {
366 return fContext->makeDeferredRenderTargetContext(fit, width, height, colorType,
367 std::move(colorSpace), sampleCnt, mipMapped,
368 origin, surfaceProps, budgeted, isProtected);
369 }
370
makeDeferredRenderTargetContextWithFallback(SkBackingFit fit,int width,int height,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,int sampleCnt,GrMipMapped mipMapped,GrSurfaceOrigin origin,const SkSurfaceProps * surfaceProps,SkBudgeted budgeted,GrProtected isProtected)371 sk_sp<GrRenderTargetContext> GrRecordingContextPriv::makeDeferredRenderTargetContextWithFallback(
372 SkBackingFit fit,
373 int width,
374 int height,
375 GrColorType colorType,
376 sk_sp<SkColorSpace> colorSpace,
377 int sampleCnt,
378 GrMipMapped mipMapped,
379 GrSurfaceOrigin origin,
380 const SkSurfaceProps* surfaceProps,
381 SkBudgeted budgeted,
382 GrProtected isProtected) {
383 return fContext->makeDeferredRenderTargetContextWithFallback(fit,
384 width,
385 height,
386 colorType,
387 std::move(colorSpace),
388 sampleCnt,
389 mipMapped,
390 origin,
391 surfaceProps,
392 budgeted,
393 isProtected);
394 }
395
backdoor()396 GrContext* GrRecordingContextPriv::backdoor() {
397 return (GrContext*) fContext;
398 }
399
400