• 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 "GrRecordingContext.h"
9 
10 #include "GrCaps.h"
11 #include "GrContext.h"
12 #include "GrDrawingManager.h"
13 #include "GrMemoryPool.h"
14 #include "GrProxyProvider.h"
15 #include "GrRecordingContextPriv.h"
16 #include "GrRenderTargetContext.h"
17 #include "GrSkSLFPFactoryCache.h"
18 #include "GrTextureContext.h"
19 #include "SkGr.h"
20 #include "text/GrTextBlobCache.h"
21 
22 #define ASSERT_SINGLE_OWNER_PRIV \
23     SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
24 
GrRecordingContext(GrBackendApi backend,const GrContextOptions & options,uint32_t contextID)25 GrRecordingContext::GrRecordingContext(GrBackendApi backend,
26                                        const GrContextOptions& options,
27                                        uint32_t contextID)
28         : INHERITED(backend, options, contextID) {
29 }
30 
~GrRecordingContext()31 GrRecordingContext::~GrRecordingContext() { }
32 
33 /**
34  * TODO: move textblob draw calls below context (see comment below)
35  */
textblobcache_overbudget_CB(void * data)36 static 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 
init(sk_sp<const GrCaps> caps,sk_sp<GrSkSLFPFactoryCache> cache)52 bool 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 
58     fStrikeCache.reset(new GrStrikeCache(this->caps(),
59                                         this->options().fGlyphCacheTextureMaximumBytes));
60 
61     fTextBlobCache.reset(new GrTextBlobCache(textblobcache_overbudget_CB, this,
62                                              this->contextID()));
63 
64     return true;
65 }
66 
setupDrawingManager(bool explicitlyAllocate,bool sortOpLists)67 void GrRecordingContext::setupDrawingManager(bool explicitlyAllocate, bool sortOpLists) {
68     GrPathRendererChain::Options prcOptions;
69     prcOptions.fAllowPathMaskCaching = this->options().fAllowPathMaskCaching;
70 #if GR_TEST_UTILS
71     prcOptions.fGpuPathRenderers = this->options().fGpuPathRenderers;
72 #endif
73     if (this->options().fDisableCoverageCountingPaths) {
74         prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
75     }
76     if (this->options().fDisableDistanceFieldPaths) {
77         prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
78     }
79 
80     if (!this->proxyProvider()->renderingDirectly()) {
81         // DDL TODO: remove this crippling of the path renderer chain
82         // Disable the small path renderer bc of the proxies in the atlas. They need to be
83         // unified when the opLists are added back to the destination drawing manager.
84         prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
85     }
86 
87     GrTextContext::Options textContextOptions;
88     textContextOptions.fMaxDistanceFieldFontSize = this->options().fGlyphsAsPathsFontSize;
89     textContextOptions.fMinDistanceFieldFontSize = this->options().fMinDistanceFieldFontSize;
90     textContextOptions.fDistanceFieldVerticesAlwaysHaveW = false;
91 #if SK_SUPPORT_ATLAS_TEXT
92     if (GrContextOptions::Enable::kYes == this->options().fDistanceFieldGlyphVerticesAlwaysHaveW) {
93         textContextOptions.fDistanceFieldVerticesAlwaysHaveW = true;
94     }
95 #endif
96 
97     // SHORT TERM TODO: until intermediate flushes at allocation time are added we need to obey the
98     // reduceOpListSplitting flag. Once that lands we should always reduce opList splitting in
99     // DDL contexts/drawing managers. We should still obey the options for non-DDL drawing managers
100     // until predictive intermediate flushes are added (i.e., we can't reorder forever).
101     fDrawingManager.reset(new GrDrawingManager(this,
102                                                 prcOptions,
103                                                 textContextOptions,
104                                                 explicitlyAllocate,
105                                                 sortOpLists,
106                                                 this->options().fReduceOpListSplitting));
107 }
108 
abandonContext()109 void GrRecordingContext::abandonContext() {
110     INHERITED::abandonContext();
111 
112     fStrikeCache->freeAll();
113     fTextBlobCache->freeAll();
114 }
115 
drawingManager()116 GrDrawingManager* GrRecordingContext::drawingManager() {
117     return fDrawingManager.get();
118 }
119 
refOpMemoryPool()120 sk_sp<GrOpMemoryPool> GrRecordingContext::refOpMemoryPool() {
121     if (!fOpMemoryPool) {
122         // DDL TODO: should the size of the memory pool be decreased in DDL mode? CPU-side memory
123         // consumed in DDL mode vs. normal mode for a single skp might be a good metric of wasted
124         // memory.
125         fOpMemoryPool = sk_sp<GrOpMemoryPool>(new GrOpMemoryPool(16384, 16384));
126     }
127 
128     SkASSERT(fOpMemoryPool);
129     return fOpMemoryPool;
130 }
131 
opMemoryPool()132 GrOpMemoryPool* GrRecordingContext::opMemoryPool() {
133     return this->refOpMemoryPool().get();
134 }
135 
getTextBlobCache()136 GrTextBlobCache* GrRecordingContext::getTextBlobCache() {
137     return fTextBlobCache.get();
138 }
139 
getTextBlobCache() const140 const GrTextBlobCache* GrRecordingContext::getTextBlobCache() const {
141     return fTextBlobCache.get();
142 }
143 
addOnFlushCallbackObject(GrOnFlushCallbackObject * onFlushCBObject)144 void GrRecordingContext::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
145     this->drawingManager()->addOnFlushCallbackObject(onFlushCBObject);
146 }
147 
makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * props)148 sk_sp<GrSurfaceContext> GrRecordingContext::makeWrappedSurfaceContext(
149                                                                  sk_sp<GrSurfaceProxy> proxy,
150                                                                  sk_sp<SkColorSpace> colorSpace,
151                                                                  const SkSurfaceProps* props) {
152     ASSERT_SINGLE_OWNER_PRIV
153 
154     if (proxy->asRenderTargetProxy()) {
155         return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
156                                                                std::move(colorSpace), props);
157     } else {
158         SkASSERT(proxy->asTextureProxy());
159         SkASSERT(!props);
160         return this->drawingManager()->makeTextureContext(std::move(proxy), std::move(colorSpace));
161     }
162 }
163 
makeDeferredSurfaceContext(const GrBackendFormat & format,const GrSurfaceDesc & dstDesc,GrSurfaceOrigin origin,GrMipMapped mipMapped,SkBackingFit fit,SkBudgeted isDstBudgeted,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * props)164 sk_sp<GrSurfaceContext> GrRecordingContext::makeDeferredSurfaceContext(
165                                                                   const GrBackendFormat& format,
166                                                                   const GrSurfaceDesc& dstDesc,
167                                                                   GrSurfaceOrigin origin,
168                                                                   GrMipMapped mipMapped,
169                                                                   SkBackingFit fit,
170                                                                   SkBudgeted isDstBudgeted,
171                                                                   sk_sp<SkColorSpace> colorSpace,
172                                                                   const SkSurfaceProps* props) {
173     sk_sp<GrTextureProxy> proxy;
174     if (GrMipMapped::kNo == mipMapped) {
175         proxy = this->proxyProvider()->createProxy(format, dstDesc, origin, fit, isDstBudgeted);
176     } else {
177         SkASSERT(SkBackingFit::kExact == fit);
178         proxy = this->proxyProvider()->createMipMapProxy(format, dstDesc, origin, isDstBudgeted);
179     }
180     if (!proxy) {
181         return nullptr;
182     }
183 
184     sk_sp<GrSurfaceContext> sContext = this->makeWrappedSurfaceContext(std::move(proxy),
185                                                                        std::move(colorSpace),
186                                                                        props);
187     if (sContext && sContext->asRenderTargetContext()) {
188         sContext->asRenderTargetContext()->discard();
189     }
190 
191     return sContext;
192 }
193 
makeDeferredRenderTargetContext(const GrBackendFormat & format,SkBackingFit fit,int width,int height,GrPixelConfig config,sk_sp<SkColorSpace> colorSpace,int sampleCnt,GrMipMapped mipMapped,GrSurfaceOrigin origin,const SkSurfaceProps * surfaceProps,SkBudgeted budgeted)194 sk_sp<GrRenderTargetContext> GrRecordingContext::makeDeferredRenderTargetContext(
195                                                         const GrBackendFormat& format,
196                                                         SkBackingFit fit,
197                                                         int width, int height,
198                                                         GrPixelConfig config,
199                                                         sk_sp<SkColorSpace> colorSpace,
200                                                         int sampleCnt,
201                                                         GrMipMapped mipMapped,
202                                                         GrSurfaceOrigin origin,
203                                                         const SkSurfaceProps* surfaceProps,
204                                                         SkBudgeted budgeted) {
205     SkASSERT(sampleCnt > 0);
206     if (this->abandoned()) {
207         return nullptr;
208     }
209 
210     GrSurfaceDesc desc;
211     desc.fFlags = kRenderTarget_GrSurfaceFlag;
212     desc.fWidth = width;
213     desc.fHeight = height;
214     desc.fConfig = config;
215     desc.fSampleCnt = sampleCnt;
216 
217     sk_sp<GrTextureProxy> rtp;
218     if (GrMipMapped::kNo == mipMapped) {
219         rtp = this->proxyProvider()->createProxy(format, desc, origin, fit, budgeted);
220     } else {
221         rtp = this->proxyProvider()->createMipMapProxy(format, desc, origin, budgeted);
222     }
223     if (!rtp) {
224         return nullptr;
225     }
226 
227     auto drawingManager = this->drawingManager();
228 
229     sk_sp<GrRenderTargetContext> renderTargetContext =
230         drawingManager->makeRenderTargetContext(std::move(rtp), std::move(colorSpace),
231                                                 surfaceProps);
232     if (!renderTargetContext) {
233         return nullptr;
234     }
235 
236     renderTargetContext->discard();
237 
238     return renderTargetContext;
239 }
240 
GrPixelConfigFallback(GrPixelConfig config)241 static inline GrPixelConfig GrPixelConfigFallback(GrPixelConfig config) {
242     switch (config) {
243         case kAlpha_8_GrPixelConfig:
244         case kAlpha_8_as_Alpha_GrPixelConfig:
245         case kAlpha_8_as_Red_GrPixelConfig:
246         case kRGB_565_GrPixelConfig:
247         case kRGBA_4444_GrPixelConfig:
248         case kBGRA_8888_GrPixelConfig:
249         case kRGBA_1010102_GrPixelConfig:
250         case kRGBA_half_GrPixelConfig:
251         case kRGBA_half_Clamped_GrPixelConfig:
252             return kRGBA_8888_GrPixelConfig;
253         case kSBGRA_8888_GrPixelConfig:
254             return kSRGBA_8888_GrPixelConfig;
255         case kAlpha_half_GrPixelConfig:
256         case kAlpha_half_as_Red_GrPixelConfig:
257             return kRGBA_half_GrPixelConfig;
258         case kGray_8_GrPixelConfig:
259         case kGray_8_as_Lum_GrPixelConfig:
260         case kGray_8_as_Red_GrPixelConfig:
261             return kRGB_888_GrPixelConfig;
262         default:
263             return kUnknown_GrPixelConfig;
264     }
265 }
266 
makeDeferredRenderTargetContextWithFallback(const GrBackendFormat & format,SkBackingFit fit,int width,int height,GrPixelConfig config,sk_sp<SkColorSpace> colorSpace,int sampleCnt,GrMipMapped mipMapped,GrSurfaceOrigin origin,const SkSurfaceProps * surfaceProps,SkBudgeted budgeted)267 sk_sp<GrRenderTargetContext> GrRecordingContext::makeDeferredRenderTargetContextWithFallback(
268                                                                  const GrBackendFormat& format,
269                                                                  SkBackingFit fit,
270                                                                  int width, int height,
271                                                                  GrPixelConfig config,
272                                                                  sk_sp<SkColorSpace> colorSpace,
273                                                                  int sampleCnt,
274                                                                  GrMipMapped mipMapped,
275                                                                  GrSurfaceOrigin origin,
276                                                                  const SkSurfaceProps* surfaceProps,
277                                                                  SkBudgeted budgeted) {
278     GrBackendFormat localFormat = format;
279     SkASSERT(sampleCnt > 0);
280     if (0 == this->caps()->getRenderTargetSampleCount(sampleCnt, config)) {
281         config = GrPixelConfigFallback(config);
282         // TODO: First we should be checking the getRenderTargetSampleCount from the GrBackendFormat
283         // and not GrPixelConfig. Besides that, we should implement the fallback in the caps, but
284         // for now we just convert the fallback pixel config to an SkColorType and then get the
285         // GrBackendFormat from that.
286         SkColorType colorType;
287         if (!GrPixelConfigToColorType(config, &colorType)) {
288             return nullptr;
289         }
290         localFormat = this->caps()->getBackendFormatFromColorType(colorType);
291     }
292 
293     return this->makeDeferredRenderTargetContext(localFormat, fit, width, height, config,
294                                                  std::move(colorSpace), sampleCnt, mipMapped,
295                                                  origin, surfaceProps, budgeted);
296 }
297 
298 ///////////////////////////////////////////////////////////////////////////////////////////////////
refCaps() const299 sk_sp<const GrCaps> GrRecordingContextPriv::refCaps() const {
300     return fContext->refCaps();
301 }
302 
fpFactoryCache()303 sk_sp<GrSkSLFPFactoryCache> GrRecordingContextPriv::fpFactoryCache() {
304     return fContext->fpFactoryCache();
305 }
306 
refOpMemoryPool()307 sk_sp<GrOpMemoryPool> GrRecordingContextPriv::refOpMemoryPool() {
308     return fContext->refOpMemoryPool();
309 }
310 
addOnFlushCallbackObject(GrOnFlushCallbackObject * onFlushCBObject)311 void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
312     fContext->addOnFlushCallbackObject(onFlushCBObject);
313 }
314 
makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * props)315 sk_sp<GrSurfaceContext> GrRecordingContextPriv::makeWrappedSurfaceContext(
316                                                     sk_sp<GrSurfaceProxy> proxy,
317                                                     sk_sp<SkColorSpace> colorSpace,
318                                                     const SkSurfaceProps* props) {
319     return fContext->makeWrappedSurfaceContext(std::move(proxy), std::move(colorSpace), props);
320 }
321 
makeDeferredSurfaceContext(const GrBackendFormat & format,const GrSurfaceDesc & dstDesc,GrSurfaceOrigin origin,GrMipMapped mipMapped,SkBackingFit fit,SkBudgeted isDstBudgeted,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * props)322 sk_sp<GrSurfaceContext> GrRecordingContextPriv::makeDeferredSurfaceContext(
323                                                     const GrBackendFormat& format,
324                                                     const GrSurfaceDesc& dstDesc,
325                                                     GrSurfaceOrigin origin,
326                                                     GrMipMapped mipMapped,
327                                                     SkBackingFit fit,
328                                                     SkBudgeted isDstBudgeted,
329                                                     sk_sp<SkColorSpace> colorSpace,
330                                                     const SkSurfaceProps* props) {
331     return fContext->makeDeferredSurfaceContext(format, dstDesc, origin, mipMapped, fit,
332                                                 isDstBudgeted, std::move(colorSpace), props);
333 }
334 
makeDeferredRenderTargetContext(const GrBackendFormat & format,SkBackingFit fit,int width,int height,GrPixelConfig config,sk_sp<SkColorSpace> colorSpace,int sampleCnt,GrMipMapped mipMapped,GrSurfaceOrigin origin,const SkSurfaceProps * surfaceProps,SkBudgeted budgeted)335 sk_sp<GrRenderTargetContext> GrRecordingContextPriv::makeDeferredRenderTargetContext(
336                                                     const GrBackendFormat& format,
337                                                     SkBackingFit fit,
338                                                     int width, int height,
339                                                     GrPixelConfig config,
340                                                     sk_sp<SkColorSpace> colorSpace,
341                                                     int sampleCnt,
342                                                     GrMipMapped mipMapped,
343                                                     GrSurfaceOrigin origin,
344                                                     const SkSurfaceProps* surfaceProps,
345                                                     SkBudgeted budgeted) {
346     return fContext->makeDeferredRenderTargetContext(format, fit, width, height, config,
347                                                      std::move(colorSpace), sampleCnt, mipMapped,
348                                                      origin, surfaceProps, budgeted);
349 }
350 
makeDeferredRenderTargetContextWithFallback(const GrBackendFormat & format,SkBackingFit fit,int width,int height,GrPixelConfig config,sk_sp<SkColorSpace> colorSpace,int sampleCnt,GrMipMapped mipMapped,GrSurfaceOrigin origin,const SkSurfaceProps * surfaceProps,SkBudgeted budgeted)351 sk_sp<GrRenderTargetContext> GrRecordingContextPriv::makeDeferredRenderTargetContextWithFallback(
352                                         const GrBackendFormat& format,
353                                         SkBackingFit fit,
354                                         int width, int height,
355                                         GrPixelConfig config,
356                                         sk_sp<SkColorSpace> colorSpace,
357                                         int sampleCnt,
358                                         GrMipMapped mipMapped,
359                                         GrSurfaceOrigin origin,
360                                         const SkSurfaceProps* surfaceProps,
361                                         SkBudgeted budgeted) {
362     return fContext->makeDeferredRenderTargetContextWithFallback(format, fit, width, height, config,
363                                                                  std::move(colorSpace), sampleCnt,
364                                                                  mipMapped, origin, surfaceProps,
365                                                                  budgeted);
366 }
367 
backdoor()368 GrContext* GrRecordingContextPriv::backdoor() {
369     return (GrContext*) fContext;
370 }
371