blob: 440e730819508f864ac4f5417d0d19b1be3fd7ec [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(
Brian Salomone7499c72019-06-24 12:12:36 -0400147 sk_sp<GrSurfaceProxy> proxy,
Brian Salomond6287472019-06-24 15:50:07 -0400148 GrColorType colorType,
Brian Salomone7499c72019-06-24 12:12:36 -0400149 SkAlphaType alphaType,
150 sk_sp<SkColorSpace> colorSpace,
151 const SkSurfaceProps* props) {
Robert Phillips292a6b22019-02-14 14:49:02 -0500152 ASSERT_SINGLE_OWNER_PRIV
153
154 if (proxy->asRenderTargetProxy()) {
Brian Salomone7499c72019-06-24 12:12:36 -0400155 SkASSERT(kPremul_SkAlphaType == alphaType || kOpaque_SkAlphaType == alphaType);
Brian Salomond6287472019-06-24 15:50:07 -0400156 return this->drawingManager()->makeRenderTargetContext(std::move(proxy), colorType,
Robert Phillips292a6b22019-02-14 14:49:02 -0500157 std::move(colorSpace), props);
158 } else {
159 SkASSERT(proxy->asTextureProxy());
160 SkASSERT(!props);
Brian Salomond6287472019-06-24 15:50:07 -0400161 return this->drawingManager()->makeTextureContext(std::move(proxy), colorType, alphaType,
Brian Salomone7499c72019-06-24 12:12:36 -0400162 std::move(colorSpace));
Robert Phillips292a6b22019-02-14 14:49:02 -0500163 }
164}
165
166sk_sp<GrSurfaceContext> GrRecordingContext::makeDeferredSurfaceContext(
Brian Salomone7499c72019-06-24 12:12:36 -0400167 const GrBackendFormat& format,
168 const GrSurfaceDesc& dstDesc,
169 GrSurfaceOrigin origin,
170 GrMipMapped mipMapped,
171 SkBackingFit fit,
172 SkBudgeted isDstBudgeted,
Brian Salomond6287472019-06-24 15:50:07 -0400173 GrColorType colorType,
Brian Salomone7499c72019-06-24 12:12:36 -0400174 SkAlphaType alphaType,
175 sk_sp<SkColorSpace> colorSpace,
176 const SkSurfaceProps* props) {
Robert Phillips292a6b22019-02-14 14:49:02 -0500177 sk_sp<GrTextureProxy> proxy;
178 if (GrMipMapped::kNo == mipMapped) {
179 proxy = this->proxyProvider()->createProxy(format, dstDesc, origin, fit, isDstBudgeted);
180 } else {
181 SkASSERT(SkBackingFit::kExact == fit);
182 proxy = this->proxyProvider()->createMipMapProxy(format, dstDesc, origin, isDstBudgeted);
183 }
184 if (!proxy) {
185 return nullptr;
186 }
187
188 sk_sp<GrSurfaceContext> sContext = this->makeWrappedSurfaceContext(std::move(proxy),
Brian Salomond6287472019-06-24 15:50:07 -0400189 colorType,
Brian Salomone7499c72019-06-24 12:12:36 -0400190 alphaType,
Robert Phillips292a6b22019-02-14 14:49:02 -0500191 std::move(colorSpace),
192 props);
193 if (sContext && sContext->asRenderTargetContext()) {
194 sContext->asRenderTargetContext()->discard();
195 }
196
197 return sContext;
198}
199
Robert Phillipsb97da532019-02-12 15:24:12 -0500200sk_sp<GrRenderTargetContext> GrRecordingContext::makeDeferredRenderTargetContext(
Brian Salomond6287472019-06-24 15:50:07 -0400201 const GrBackendFormat& format,
202 SkBackingFit fit,
203 int width,
204 int height,
205 GrPixelConfig config,
206 GrColorType colorType,
207 sk_sp<SkColorSpace> colorSpace,
208 int sampleCnt,
209 GrMipMapped mipMapped,
210 GrSurfaceOrigin origin,
211 const SkSurfaceProps* surfaceProps,
212 SkBudgeted budgeted,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400213 GrProtected isProtected) {
Robert Phillipsb97da532019-02-12 15:24:12 -0500214 SkASSERT(sampleCnt > 0);
215 if (this->abandoned()) {
216 return nullptr;
217 }
218
219 GrSurfaceDesc desc;
220 desc.fFlags = kRenderTarget_GrSurfaceFlag;
221 desc.fWidth = width;
222 desc.fHeight = height;
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400223 desc.fIsProtected = isProtected;
Robert Phillipsb97da532019-02-12 15:24:12 -0500224 desc.fConfig = config;
225 desc.fSampleCnt = sampleCnt;
226
227 sk_sp<GrTextureProxy> rtp;
228 if (GrMipMapped::kNo == mipMapped) {
229 rtp = this->proxyProvider()->createProxy(format, desc, origin, fit, budgeted);
230 } else {
231 rtp = this->proxyProvider()->createMipMapProxy(format, desc, origin, budgeted);
232 }
233 if (!rtp) {
234 return nullptr;
235 }
236
Robert Phillipsb97da532019-02-12 15:24:12 -0500237 auto drawingManager = this->drawingManager();
238
Brian Salomond6287472019-06-24 15:50:07 -0400239 sk_sp<GrRenderTargetContext> renderTargetContext = drawingManager->makeRenderTargetContext(
240 std::move(rtp), colorType, std::move(colorSpace), surfaceProps);
Robert Phillipsb97da532019-02-12 15:24:12 -0500241 if (!renderTargetContext) {
242 return nullptr;
243 }
244
245 renderTargetContext->discard();
246
247 return renderTargetContext;
248}
Robert Phillipsd6841482019-02-08 10:29:20 -0500249
Brian Salomond6287472019-06-24 15:50:07 -0400250static inline bool color_type_and_config_fallback(GrColorType* ct, GrPixelConfig* config) {
251 switch (*ct) {
252 case GrColorType::kAlpha_8:
253 if (*config != kAlpha_8_GrPixelConfig && *config != kAlpha_8_as_Red_GrPixelConfig &&
254 *config != kAlpha_8_as_Alpha_GrPixelConfig) {
255 return false;
256 }
257 *config = kRGBA_8888_GrPixelConfig;
258 *ct = GrColorType::kRGBA_8888;
259 return true;
260 case GrColorType::kBGR_565:
261 if (*config != kRGB_565_GrPixelConfig) {
262 return false;
263 }
264 *config = kRGBA_8888_GrPixelConfig;
265 *ct = GrColorType::kRGBA_8888;
266 return true;
267 case GrColorType::kABGR_4444:
268 if (*config != kRGBA_4444_GrPixelConfig) {
269 return false;
270 }
271 *config = kRGBA_8888_GrPixelConfig;
272 *ct = GrColorType::kRGBA_8888;
273 return true;
274 case GrColorType::kBGRA_8888:
275 if (*config != kBGRA_8888_GrPixelConfig && *config != kSBGRA_8888_GrPixelConfig) {
276 return false;
277 }
278 *config = (*config == kSBGRA_8888_GrPixelConfig) ? kSRGBA_8888_GrPixelConfig
279 : kRGBA_8888_GrPixelConfig;
280 *ct = GrColorType::kRGBA_8888;
281 return true;
282 case GrColorType::kRGBA_1010102:
283 if (*config != kRGBA_1010102_GrPixelConfig) {
284 return false;
285 }
286 *config = kRGBA_8888_GrPixelConfig;
287 *ct = GrColorType::kRGBA_8888;
288 return true;
289 case GrColorType::kRGBA_F16:
290 if (*config != kRGBA_half_GrPixelConfig) {
291 return false;
292 }
293 *config = kRGBA_8888_GrPixelConfig;
294 *ct = GrColorType::kRGBA_8888;
295 return true;
296 case GrColorType::kRGBA_F16_Clamped:
297 if (*config != kRGBA_half_Clamped_GrPixelConfig) {
298 return false;
299 }
300 *config = kRGBA_8888_GrPixelConfig;
301 *ct = GrColorType::kRGBA_8888;
302 return true;
303 case GrColorType::kAlpha_F16:
304 if (*config != kAlpha_half_GrPixelConfig &&
305 *config != kAlpha_half_as_Red_GrPixelConfig) {
306 return false;
307 }
308 *config = kRGBA_half_GrPixelConfig;
309 *ct = GrColorType::kRGBA_F16;
310 return true;
311 case GrColorType::kGray_8:
312 if (*config != kGray_8_GrPixelConfig && *config != kGray_8_as_Red_GrPixelConfig &&
313 *config != kGray_8_as_Lum_GrPixelConfig) {
314 return false;
315 }
316 *config = kRGB_888_GrPixelConfig;
317 *ct = GrColorType::kRGB_888x;
318 return true;
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500319 default:
Brian Salomond6287472019-06-24 15:50:07 -0400320 return false;
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500321 }
322}
323
324sk_sp<GrRenderTargetContext> GrRecordingContext::makeDeferredRenderTargetContextWithFallback(
Brian Salomond6287472019-06-24 15:50:07 -0400325 const GrBackendFormat& format,
326 SkBackingFit fit,
327 int width,
328 int height,
329 GrPixelConfig config,
330 GrColorType colorType,
331 sk_sp<SkColorSpace> colorSpace,
332 int sampleCnt,
333 GrMipMapped mipMapped,
334 GrSurfaceOrigin origin,
335 const SkSurfaceProps* surfaceProps,
336 SkBudgeted budgeted,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400337 GrProtected isProtected) {
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500338 GrBackendFormat localFormat = format;
339 SkASSERT(sampleCnt > 0);
340 if (0 == this->caps()->getRenderTargetSampleCount(sampleCnt, config)) {
Brian Salomond6287472019-06-24 15:50:07 -0400341 // TODO: Make the fallback part of GrCaps?
342 if (!color_type_and_config_fallback(&colorType, &config)) {
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500343 return nullptr;
344 }
Brian Salomond6287472019-06-24 15:50:07 -0400345 // Figure out what the new backend format should be for the new color type.
346 auto srgb = GrPixelConfigIsSRGBEncoded(config);
347 localFormat = this->caps()->getBackendFormatFromGrColorType(colorType, srgb);
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500348 }
349
Brian Salomond6287472019-06-24 15:50:07 -0400350 return this->makeDeferredRenderTargetContext(localFormat, fit, width, height, config, colorType,
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500351 std::move(colorSpace), sampleCnt, mipMapped,
Brian Salomond6287472019-06-24 15:50:07 -0400352 origin, surfaceProps, budgeted, isProtected);
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500353}
354
Robert Phillipsa41c6852019-02-07 10:44:10 -0500355///////////////////////////////////////////////////////////////////////////////////////////////////
356sk_sp<const GrCaps> GrRecordingContextPriv::refCaps() const {
357 return fContext->refCaps();
358}
359
360sk_sp<GrSkSLFPFactoryCache> GrRecordingContextPriv::fpFactoryCache() {
361 return fContext->fpFactoryCache();
362}
Robert Phillipsd6841482019-02-08 10:29:20 -0500363
364sk_sp<GrOpMemoryPool> GrRecordingContextPriv::refOpMemoryPool() {
365 return fContext->refOpMemoryPool();
366}
Robert Phillipsb97da532019-02-12 15:24:12 -0500367
Robert Phillipsc5058a62019-02-15 12:52:59 -0500368void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
369 fContext->addOnFlushCallbackObject(onFlushCBObject);
370}
371
Robert Phillips292a6b22019-02-14 14:49:02 -0500372sk_sp<GrSurfaceContext> GrRecordingContextPriv::makeWrappedSurfaceContext(
Brian Salomone7499c72019-06-24 12:12:36 -0400373 sk_sp<GrSurfaceProxy> proxy,
Brian Salomond6287472019-06-24 15:50:07 -0400374 GrColorType colorType,
Brian Salomone7499c72019-06-24 12:12:36 -0400375 SkAlphaType alphaType,
376 sk_sp<SkColorSpace> colorSpace,
377 const SkSurfaceProps* props) {
Brian Salomond6287472019-06-24 15:50:07 -0400378 return fContext->makeWrappedSurfaceContext(std::move(proxy), colorType, alphaType,
379 std::move(colorSpace), props);
Robert Phillips292a6b22019-02-14 14:49:02 -0500380}
381
382sk_sp<GrSurfaceContext> GrRecordingContextPriv::makeDeferredSurfaceContext(
Brian Salomone7499c72019-06-24 12:12:36 -0400383 const GrBackendFormat& format,
384 const GrSurfaceDesc& dstDesc,
385 GrSurfaceOrigin origin,
386 GrMipMapped mipMapped,
387 SkBackingFit fit,
388 SkBudgeted isDstBudgeted,
Brian Salomond6287472019-06-24 15:50:07 -0400389 GrColorType colorType,
Brian Salomone7499c72019-06-24 12:12:36 -0400390 SkAlphaType alphaType,
391 sk_sp<SkColorSpace> colorSpace,
392 const SkSurfaceProps* props) {
Robert Phillips292a6b22019-02-14 14:49:02 -0500393 return fContext->makeDeferredSurfaceContext(format, dstDesc, origin, mipMapped, fit,
Brian Salomond6287472019-06-24 15:50:07 -0400394 isDstBudgeted, colorType, alphaType,
395 std::move(colorSpace), props);
Robert Phillips292a6b22019-02-14 14:49:02 -0500396}
397
Robert Phillipsb97da532019-02-12 15:24:12 -0500398sk_sp<GrRenderTargetContext> GrRecordingContextPriv::makeDeferredRenderTargetContext(
Brian Salomond6287472019-06-24 15:50:07 -0400399 const GrBackendFormat& format,
400 SkBackingFit fit,
401 int width,
402 int height,
403 GrPixelConfig config,
404 GrColorType colorType,
405 sk_sp<SkColorSpace> colorSpace,
406 int sampleCnt,
407 GrMipMapped mipMapped,
408 GrSurfaceOrigin origin,
409 const SkSurfaceProps* surfaceProps,
410 SkBudgeted budgeted,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400411 GrProtected isProtected) {
Brian Salomond6287472019-06-24 15:50:07 -0400412 return fContext->makeDeferredRenderTargetContext(format, fit, width, height, config, colorType,
Robert Phillipsb97da532019-02-12 15:24:12 -0500413 std::move(colorSpace), sampleCnt, mipMapped,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400414 origin, surfaceProps, budgeted, isProtected);
Robert Phillipsb97da532019-02-12 15:24:12 -0500415}
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500416
417sk_sp<GrRenderTargetContext> GrRecordingContextPriv::makeDeferredRenderTargetContextWithFallback(
Brian Salomond6287472019-06-24 15:50:07 -0400418 const GrBackendFormat& format,
419 SkBackingFit fit,
420 int width,
421 int height,
422 GrPixelConfig config,
423 GrColorType colorType,
424 sk_sp<SkColorSpace> colorSpace,
425 int sampleCnt,
426 GrMipMapped mipMapped,
427 GrSurfaceOrigin origin,
428 const SkSurfaceProps* surfaceProps,
429 SkBudgeted budgeted,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400430 GrProtected isProtected) {
Brian Salomond6287472019-06-24 15:50:07 -0400431 return fContext->makeDeferredRenderTargetContextWithFallback(format,
432 fit,
433 width,
434 height,
435 config,
436 colorType,
437 std::move(colorSpace),
438 sampleCnt,
439 mipMapped,
440 origin,
441 surfaceProps,
442 budgeted,
443 isProtected);
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500444}
Robert Phillips9338c602019-02-19 12:52:29 -0500445
446GrContext* GrRecordingContextPriv::backdoor() {
447 return (GrContext*) fContext;
448}