blob: bdf5edf5e5b3df0acee21ae577a5bd66e71f5c69 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/private/GrRecordingContext.h"
Robert Phillips4217ea72019-01-30 13:08:28 -05009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/gpu/GrContext.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040011#include "src/gpu/GrAuditTrail.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#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"
Greg Danielf91aeb22019-06-18 09:58:02 -040018#include "src/gpu/GrSkSLFPFactoryCache.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "src/gpu/GrTextureContext.h"
20#include "src/gpu/SkGr.h"
21#include "src/gpu/text/GrTextBlobCache.h"
Robert Phillipsa41c6852019-02-07 10:44:10 -050022
Robert Phillips292a6b22019-02-14 14:49:02 -050023#define ASSERT_SINGLE_OWNER_PRIV \
24 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
25
Robert Phillipsc1541ae2019-02-04 12:05:37 -050026GrRecordingContext::GrRecordingContext(GrBackendApi backend,
27 const GrContextOptions& options,
Robert Phillipsa41c6852019-02-07 10:44:10 -050028 uint32_t contextID)
Greg Danielf91aeb22019-06-18 09:58:02 -040029 : INHERITED(backend, options, contextID)
30 , fAuditTrail(new GrAuditTrail()) {
Robert Phillips4217ea72019-01-30 13:08:28 -050031}
32
33GrRecordingContext::~GrRecordingContext() { }
34
Robert Phillips2184fb72019-02-21 16:11:41 -050035/**
36 * TODO: move textblob draw calls below context (see comment below)
37 */
38static 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
Robert Phillips292a6b22019-02-14 14:49:02 -050054bool 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
Herb Derbya00da612019-03-04 17:10:01 -050060 fStrikeCache.reset(new GrStrikeCache(this->caps(),
Robert Phillips2184fb72019-02-21 16:11:41 -050061 this->options().fGlyphCacheTextureMaximumBytes));
62
63 fTextBlobCache.reset(new GrTextBlobCache(textblobcache_overbudget_CB, this,
64 this->contextID()));
65
Robert Phillips56181ba2019-03-08 12:00:45 -050066 return true;
67}
68
Robert Phillips6db27c22019-05-01 10:43:56 -040069void GrRecordingContext::setupDrawingManager(bool sortOpLists, bool reduceOpListSplitting) {
Robert Phillips69893702019-02-22 11:16:30 -050070 GrPathRendererChain::Options prcOptions;
71 prcOptions.fAllowPathMaskCaching = this->options().fAllowPathMaskCaching;
72#if GR_TEST_UTILS
73 prcOptions.fGpuPathRenderers = this->options().fGpuPathRenderers;
74#endif
Chris Daltonf7748182019-03-18 16:22:30 +000075 // FIXME: Once this is removed from Chrome and Android, rename to fEnable"".
76 if (!this->options().fDisableCoverageCountingPaths) {
77 prcOptions.fGpuPathRenderers |= GpuPathRenderers::kCoverageCounting;
Robert Phillips69893702019-02-22 11:16:30 -050078 }
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,
Robert Phillips12c46292019-04-23 07:36:17 -0400101 prcOptions,
102 textContextOptions,
103 sortOpLists,
Robert Phillips6db27c22019-05-01 10:43:56 -0400104 reduceOpListSplitting));
Robert Phillips292a6b22019-02-14 14:49:02 -0500105}
106
Robert Phillipsa9162df2019-02-11 14:12:03 -0500107void GrRecordingContext::abandonContext() {
108 INHERITED::abandonContext();
Robert Phillips2184fb72019-02-21 16:11:41 -0500109
Herb Derbya00da612019-03-04 17:10:01 -0500110 fStrikeCache->freeAll();
Robert Phillips2184fb72019-02-21 16:11:41 -0500111 fTextBlobCache->freeAll();
Robert Phillipsa9162df2019-02-11 14:12:03 -0500112}
113
Robert Phillips69893702019-02-22 11:16:30 -0500114GrDrawingManager* GrRecordingContext::drawingManager() {
115 return fDrawingManager.get();
116}
117
Robert Phillipsd6841482019-02-08 10:29:20 -0500118sk_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
130GrOpMemoryPool* GrRecordingContext::opMemoryPool() {
131 return this->refOpMemoryPool().get();
132}
133
Robert Phillips2184fb72019-02-21 16:11:41 -0500134GrTextBlobCache* GrRecordingContext::getTextBlobCache() {
135 return fTextBlobCache.get();
136}
137
138const GrTextBlobCache* GrRecordingContext::getTextBlobCache() const {
139 return fTextBlobCache.get();
140}
141
Robert Phillipsc5058a62019-02-15 12:52:59 -0500142void GrRecordingContext::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
143 this->drawingManager()->addOnFlushCallbackObject(onFlushCBObject);
144}
145
Robert Phillips292a6b22019-02-14 14:49:02 -0500146sk_sp<GrSurfaceContext> GrRecordingContext::makeWrappedSurfaceContext(
147 sk_sp<GrSurfaceProxy> proxy,
148 sk_sp<SkColorSpace> colorSpace,
149 const SkSurfaceProps* props) {
150 ASSERT_SINGLE_OWNER_PRIV
151
152 if (proxy->asRenderTargetProxy()) {
153 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
154 std::move(colorSpace), props);
155 } else {
156 SkASSERT(proxy->asTextureProxy());
157 SkASSERT(!props);
158 return this->drawingManager()->makeTextureContext(std::move(proxy), std::move(colorSpace));
159 }
160}
161
162sk_sp<GrSurfaceContext> GrRecordingContext::makeDeferredSurfaceContext(
163 const GrBackendFormat& format,
164 const GrSurfaceDesc& dstDesc,
165 GrSurfaceOrigin origin,
166 GrMipMapped mipMapped,
167 SkBackingFit fit,
168 SkBudgeted isDstBudgeted,
169 sk_sp<SkColorSpace> colorSpace,
170 const SkSurfaceProps* props) {
171 sk_sp<GrTextureProxy> proxy;
172 if (GrMipMapped::kNo == mipMapped) {
173 proxy = this->proxyProvider()->createProxy(format, dstDesc, origin, fit, isDstBudgeted);
174 } else {
175 SkASSERT(SkBackingFit::kExact == fit);
176 proxy = this->proxyProvider()->createMipMapProxy(format, dstDesc, origin, isDstBudgeted);
177 }
178 if (!proxy) {
179 return nullptr;
180 }
181
182 sk_sp<GrSurfaceContext> sContext = this->makeWrappedSurfaceContext(std::move(proxy),
183 std::move(colorSpace),
184 props);
185 if (sContext && sContext->asRenderTargetContext()) {
186 sContext->asRenderTargetContext()->discard();
187 }
188
189 return sContext;
190}
191
Robert Phillipsb97da532019-02-12 15:24:12 -0500192sk_sp<GrRenderTargetContext> GrRecordingContext::makeDeferredRenderTargetContext(
193 const GrBackendFormat& format,
194 SkBackingFit fit,
195 int width, int height,
196 GrPixelConfig config,
197 sk_sp<SkColorSpace> colorSpace,
198 int sampleCnt,
199 GrMipMapped mipMapped,
200 GrSurfaceOrigin origin,
201 const SkSurfaceProps* surfaceProps,
202 SkBudgeted budgeted) {
203 SkASSERT(sampleCnt > 0);
204 if (this->abandoned()) {
205 return nullptr;
206 }
207
208 GrSurfaceDesc desc;
209 desc.fFlags = kRenderTarget_GrSurfaceFlag;
210 desc.fWidth = width;
211 desc.fHeight = height;
212 desc.fConfig = config;
213 desc.fSampleCnt = sampleCnt;
214
215 sk_sp<GrTextureProxy> rtp;
216 if (GrMipMapped::kNo == mipMapped) {
217 rtp = this->proxyProvider()->createProxy(format, desc, origin, fit, budgeted);
218 } else {
219 rtp = this->proxyProvider()->createMipMapProxy(format, desc, origin, budgeted);
220 }
221 if (!rtp) {
222 return nullptr;
223 }
224
Robert Phillipsb97da532019-02-12 15:24:12 -0500225 auto drawingManager = this->drawingManager();
226
227 sk_sp<GrRenderTargetContext> renderTargetContext =
228 drawingManager->makeRenderTargetContext(std::move(rtp), std::move(colorSpace),
229 surfaceProps);
230 if (!renderTargetContext) {
231 return nullptr;
232 }
233
234 renderTargetContext->discard();
235
236 return renderTargetContext;
237}
Robert Phillipsd6841482019-02-08 10:29:20 -0500238
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500239static inline GrPixelConfig GrPixelConfigFallback(GrPixelConfig config) {
240 switch (config) {
241 case kAlpha_8_GrPixelConfig:
242 case kAlpha_8_as_Alpha_GrPixelConfig:
243 case kAlpha_8_as_Red_GrPixelConfig:
244 case kRGB_565_GrPixelConfig:
245 case kRGBA_4444_GrPixelConfig:
246 case kBGRA_8888_GrPixelConfig:
247 case kRGBA_1010102_GrPixelConfig:
248 case kRGBA_half_GrPixelConfig:
Brian Osmand0626aa2019-03-11 15:28:06 -0400249 case kRGBA_half_Clamped_GrPixelConfig:
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500250 return kRGBA_8888_GrPixelConfig;
251 case kSBGRA_8888_GrPixelConfig:
252 return kSRGBA_8888_GrPixelConfig;
253 case kAlpha_half_GrPixelConfig:
254 case kAlpha_half_as_Red_GrPixelConfig:
255 return kRGBA_half_GrPixelConfig;
256 case kGray_8_GrPixelConfig:
257 case kGray_8_as_Lum_GrPixelConfig:
258 case kGray_8_as_Red_GrPixelConfig:
259 return kRGB_888_GrPixelConfig;
260 default:
261 return kUnknown_GrPixelConfig;
262 }
263}
264
265sk_sp<GrRenderTargetContext> GrRecordingContext::makeDeferredRenderTargetContextWithFallback(
266 const GrBackendFormat& format,
267 SkBackingFit fit,
268 int width, int height,
269 GrPixelConfig config,
270 sk_sp<SkColorSpace> colorSpace,
271 int sampleCnt,
272 GrMipMapped mipMapped,
273 GrSurfaceOrigin origin,
274 const SkSurfaceProps* surfaceProps,
275 SkBudgeted budgeted) {
276 GrBackendFormat localFormat = format;
277 SkASSERT(sampleCnt > 0);
278 if (0 == this->caps()->getRenderTargetSampleCount(sampleCnt, config)) {
279 config = GrPixelConfigFallback(config);
280 // TODO: First we should be checking the getRenderTargetSampleCount from the GrBackendFormat
281 // and not GrPixelConfig. Besides that, we should implement the fallback in the caps, but
282 // for now we just convert the fallback pixel config to an SkColorType and then get the
283 // GrBackendFormat from that.
284 SkColorType colorType;
285 if (!GrPixelConfigToColorType(config, &colorType)) {
286 return nullptr;
287 }
288 localFormat = this->caps()->getBackendFormatFromColorType(colorType);
289 }
290
291 return this->makeDeferredRenderTargetContext(localFormat, fit, width, height, config,
292 std::move(colorSpace), sampleCnt, mipMapped,
293 origin, surfaceProps, budgeted);
294}
295
Robert Phillipsa41c6852019-02-07 10:44:10 -0500296///////////////////////////////////////////////////////////////////////////////////////////////////
297sk_sp<const GrCaps> GrRecordingContextPriv::refCaps() const {
298 return fContext->refCaps();
299}
300
301sk_sp<GrSkSLFPFactoryCache> GrRecordingContextPriv::fpFactoryCache() {
302 return fContext->fpFactoryCache();
303}
Robert Phillipsd6841482019-02-08 10:29:20 -0500304
305sk_sp<GrOpMemoryPool> GrRecordingContextPriv::refOpMemoryPool() {
306 return fContext->refOpMemoryPool();
307}
Robert Phillipsb97da532019-02-12 15:24:12 -0500308
Robert Phillipsc5058a62019-02-15 12:52:59 -0500309void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
310 fContext->addOnFlushCallbackObject(onFlushCBObject);
311}
312
Robert Phillips292a6b22019-02-14 14:49:02 -0500313sk_sp<GrSurfaceContext> GrRecordingContextPriv::makeWrappedSurfaceContext(
314 sk_sp<GrSurfaceProxy> proxy,
315 sk_sp<SkColorSpace> colorSpace,
316 const SkSurfaceProps* props) {
317 return fContext->makeWrappedSurfaceContext(std::move(proxy), std::move(colorSpace), props);
318}
319
320sk_sp<GrSurfaceContext> GrRecordingContextPriv::makeDeferredSurfaceContext(
321 const GrBackendFormat& format,
322 const GrSurfaceDesc& dstDesc,
323 GrSurfaceOrigin origin,
324 GrMipMapped mipMapped,
325 SkBackingFit fit,
326 SkBudgeted isDstBudgeted,
327 sk_sp<SkColorSpace> colorSpace,
328 const SkSurfaceProps* props) {
329 return fContext->makeDeferredSurfaceContext(format, dstDesc, origin, mipMapped, fit,
330 isDstBudgeted, std::move(colorSpace), props);
331}
332
Robert Phillipsb97da532019-02-12 15:24:12 -0500333sk_sp<GrRenderTargetContext> GrRecordingContextPriv::makeDeferredRenderTargetContext(
334 const GrBackendFormat& format,
335 SkBackingFit fit,
336 int width, int height,
337 GrPixelConfig config,
338 sk_sp<SkColorSpace> colorSpace,
339 int sampleCnt,
340 GrMipMapped mipMapped,
341 GrSurfaceOrigin origin,
342 const SkSurfaceProps* surfaceProps,
343 SkBudgeted budgeted) {
344 return fContext->makeDeferredRenderTargetContext(format, fit, width, height, config,
345 std::move(colorSpace), sampleCnt, mipMapped,
346 origin, surfaceProps, budgeted);
347}
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500348
349sk_sp<GrRenderTargetContext> GrRecordingContextPriv::makeDeferredRenderTargetContextWithFallback(
350 const GrBackendFormat& format,
351 SkBackingFit fit,
352 int width, int height,
353 GrPixelConfig config,
354 sk_sp<SkColorSpace> colorSpace,
355 int sampleCnt,
356 GrMipMapped mipMapped,
357 GrSurfaceOrigin origin,
358 const SkSurfaceProps* surfaceProps,
359 SkBudgeted budgeted) {
360 return fContext->makeDeferredRenderTargetContextWithFallback(format, fit, width, height, config,
361 std::move(colorSpace), sampleCnt,
362 mipMapped, origin, surfaceProps,
363 budgeted);
364}
Robert Phillips9338c602019-02-19 12:52:29 -0500365
366GrContext* GrRecordingContextPriv::backdoor() {
367 return (GrContext*) fContext;
368}