• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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