blob: ebd937382c2c8750d45e80a0e17db397851c5fca [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
8#include "GrRecordingContext.h"
9
Robert Phillipsa41c6852019-02-07 10:44:10 -050010#include "GrCaps.h"
Robert Phillipsb97da532019-02-12 15:24:12 -050011#include "GrDrawingManager.h"
Robert Phillipsd6841482019-02-08 10:29:20 -050012#include "GrMemoryPool.h"
Robert Phillipsb97da532019-02-12 15:24:12 -050013#include "GrProxyProvider.h"
Robert Phillipsa41c6852019-02-07 10:44:10 -050014#include "GrRecordingContextPriv.h"
Robert Phillipsb97da532019-02-12 15:24:12 -050015#include "GrRenderTargetContext.h"
Robert Phillipsa41c6852019-02-07 10:44:10 -050016#include "GrSkSLFPFactoryCache.h"
Robert Phillips292a6b22019-02-14 14:49:02 -050017#include "GrTextureContext.h"
Robert Phillips6f0e02f2019-02-13 11:02:28 -050018#include "SkGr.h"
Robert Phillips2184fb72019-02-21 16:11:41 -050019#include "text/GrTextBlobCache.h"
Robert Phillipsa41c6852019-02-07 10:44:10 -050020
Robert Phillips292a6b22019-02-14 14:49:02 -050021#define ASSERT_SINGLE_OWNER_PRIV \
22 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
23
Robert Phillipsc1541ae2019-02-04 12:05:37 -050024GrRecordingContext::GrRecordingContext(GrBackendApi backend,
25 const GrContextOptions& options,
Robert Phillipsa41c6852019-02-07 10:44:10 -050026 uint32_t contextID)
27 : INHERITED(backend, options, contextID) {
Robert Phillips4217ea72019-01-30 13:08:28 -050028}
29
30GrRecordingContext::~GrRecordingContext() { }
31
Robert Phillips2184fb72019-02-21 16:11:41 -050032/**
33 * TODO: move textblob draw calls below context (see comment below)
34 */
35static void textblobcache_overbudget_CB(void* data) {
36 SkASSERT(data);
37 GrRecordingContext* context = reinterpret_cast<GrRecordingContext*>(data);
38
39 GrContext* direct = context->priv().asDirectContext();
40 if (!direct) {
41 return;
42 }
43
44 // TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on
45 // GrRenderTargetContext to perform a necessary flush. The solution is to move drawText calls
46 // to below the GrContext level, but this is not trivial because they call drawPath on
47 // SkGpuDevice.
48 direct->flush();
49}
50
Robert Phillips292a6b22019-02-14 14:49:02 -050051bool GrRecordingContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> cache) {
52
53 if (!INHERITED::init(std::move(caps), std::move(cache))) {
54 return false;
55 }
56
Robert Phillips2184fb72019-02-21 16:11:41 -050057 fGlyphCache.reset(new GrStrikeCache(this->caps(),
58 this->options().fGlyphCacheTextureMaximumBytes));
59
60 fTextBlobCache.reset(new GrTextBlobCache(textblobcache_overbudget_CB, this,
61 this->contextID()));
62
Robert Phillips292a6b22019-02-14 14:49:02 -050063 return true;
64}
65
Robert Phillipsa9162df2019-02-11 14:12:03 -050066void GrRecordingContext::abandonContext() {
67 INHERITED::abandonContext();
Robert Phillips2184fb72019-02-21 16:11:41 -050068
69 fGlyphCache->freeAll();
70 fTextBlobCache->freeAll();
Robert Phillipsa9162df2019-02-11 14:12:03 -050071}
72
Robert Phillipsd6841482019-02-08 10:29:20 -050073sk_sp<GrOpMemoryPool> GrRecordingContext::refOpMemoryPool() {
74 if (!fOpMemoryPool) {
75 // DDL TODO: should the size of the memory pool be decreased in DDL mode? CPU-side memory
76 // consumed in DDL mode vs. normal mode for a single skp might be a good metric of wasted
77 // memory.
78 fOpMemoryPool = sk_sp<GrOpMemoryPool>(new GrOpMemoryPool(16384, 16384));
79 }
80
81 SkASSERT(fOpMemoryPool);
82 return fOpMemoryPool;
83}
84
85GrOpMemoryPool* GrRecordingContext::opMemoryPool() {
86 return this->refOpMemoryPool().get();
87}
88
Robert Phillips2184fb72019-02-21 16:11:41 -050089GrTextBlobCache* GrRecordingContext::getTextBlobCache() {
90 return fTextBlobCache.get();
91}
92
93const GrTextBlobCache* GrRecordingContext::getTextBlobCache() const {
94 return fTextBlobCache.get();
95}
96
Robert Phillipsc5058a62019-02-15 12:52:59 -050097void GrRecordingContext::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
98 this->drawingManager()->addOnFlushCallbackObject(onFlushCBObject);
99}
100
Robert Phillips292a6b22019-02-14 14:49:02 -0500101sk_sp<GrSurfaceContext> GrRecordingContext::makeWrappedSurfaceContext(
102 sk_sp<GrSurfaceProxy> proxy,
103 sk_sp<SkColorSpace> colorSpace,
104 const SkSurfaceProps* props) {
105 ASSERT_SINGLE_OWNER_PRIV
106
107 if (proxy->asRenderTargetProxy()) {
108 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
109 std::move(colorSpace), props);
110 } else {
111 SkASSERT(proxy->asTextureProxy());
112 SkASSERT(!props);
113 return this->drawingManager()->makeTextureContext(std::move(proxy), std::move(colorSpace));
114 }
115}
116
117sk_sp<GrSurfaceContext> GrRecordingContext::makeDeferredSurfaceContext(
118 const GrBackendFormat& format,
119 const GrSurfaceDesc& dstDesc,
120 GrSurfaceOrigin origin,
121 GrMipMapped mipMapped,
122 SkBackingFit fit,
123 SkBudgeted isDstBudgeted,
124 sk_sp<SkColorSpace> colorSpace,
125 const SkSurfaceProps* props) {
126 sk_sp<GrTextureProxy> proxy;
127 if (GrMipMapped::kNo == mipMapped) {
128 proxy = this->proxyProvider()->createProxy(format, dstDesc, origin, fit, isDstBudgeted);
129 } else {
130 SkASSERT(SkBackingFit::kExact == fit);
131 proxy = this->proxyProvider()->createMipMapProxy(format, dstDesc, origin, isDstBudgeted);
132 }
133 if (!proxy) {
134 return nullptr;
135 }
136
137 sk_sp<GrSurfaceContext> sContext = this->makeWrappedSurfaceContext(std::move(proxy),
138 std::move(colorSpace),
139 props);
140 if (sContext && sContext->asRenderTargetContext()) {
141 sContext->asRenderTargetContext()->discard();
142 }
143
144 return sContext;
145}
146
Robert Phillipsb97da532019-02-12 15:24:12 -0500147sk_sp<GrRenderTargetContext> GrRecordingContext::makeDeferredRenderTargetContext(
148 const GrBackendFormat& format,
149 SkBackingFit fit,
150 int width, int height,
151 GrPixelConfig config,
152 sk_sp<SkColorSpace> colorSpace,
153 int sampleCnt,
154 GrMipMapped mipMapped,
155 GrSurfaceOrigin origin,
156 const SkSurfaceProps* surfaceProps,
157 SkBudgeted budgeted) {
158 SkASSERT(sampleCnt > 0);
159 if (this->abandoned()) {
160 return nullptr;
161 }
162
163 GrSurfaceDesc desc;
164 desc.fFlags = kRenderTarget_GrSurfaceFlag;
165 desc.fWidth = width;
166 desc.fHeight = height;
167 desc.fConfig = config;
168 desc.fSampleCnt = sampleCnt;
169
170 sk_sp<GrTextureProxy> rtp;
171 if (GrMipMapped::kNo == mipMapped) {
172 rtp = this->proxyProvider()->createProxy(format, desc, origin, fit, budgeted);
173 } else {
174 rtp = this->proxyProvider()->createMipMapProxy(format, desc, origin, budgeted);
175 }
176 if (!rtp) {
177 return nullptr;
178 }
179
180 // CONTEXT TODO: move GrDrawingManager to GrRecordingContext for real
181 auto drawingManager = this->drawingManager();
182
183 sk_sp<GrRenderTargetContext> renderTargetContext =
184 drawingManager->makeRenderTargetContext(std::move(rtp), std::move(colorSpace),
185 surfaceProps);
186 if (!renderTargetContext) {
187 return nullptr;
188 }
189
190 renderTargetContext->discard();
191
192 return renderTargetContext;
193}
Robert Phillipsd6841482019-02-08 10:29:20 -0500194
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500195static inline GrPixelConfig GrPixelConfigFallback(GrPixelConfig config) {
196 switch (config) {
197 case kAlpha_8_GrPixelConfig:
198 case kAlpha_8_as_Alpha_GrPixelConfig:
199 case kAlpha_8_as_Red_GrPixelConfig:
200 case kRGB_565_GrPixelConfig:
201 case kRGBA_4444_GrPixelConfig:
202 case kBGRA_8888_GrPixelConfig:
203 case kRGBA_1010102_GrPixelConfig:
204 case kRGBA_half_GrPixelConfig:
205 return kRGBA_8888_GrPixelConfig;
206 case kSBGRA_8888_GrPixelConfig:
207 return kSRGBA_8888_GrPixelConfig;
208 case kAlpha_half_GrPixelConfig:
209 case kAlpha_half_as_Red_GrPixelConfig:
210 return kRGBA_half_GrPixelConfig;
211 case kGray_8_GrPixelConfig:
212 case kGray_8_as_Lum_GrPixelConfig:
213 case kGray_8_as_Red_GrPixelConfig:
214 return kRGB_888_GrPixelConfig;
215 default:
216 return kUnknown_GrPixelConfig;
217 }
218}
219
220sk_sp<GrRenderTargetContext> GrRecordingContext::makeDeferredRenderTargetContextWithFallback(
221 const GrBackendFormat& format,
222 SkBackingFit fit,
223 int width, int height,
224 GrPixelConfig config,
225 sk_sp<SkColorSpace> colorSpace,
226 int sampleCnt,
227 GrMipMapped mipMapped,
228 GrSurfaceOrigin origin,
229 const SkSurfaceProps* surfaceProps,
230 SkBudgeted budgeted) {
231 GrBackendFormat localFormat = format;
232 SkASSERT(sampleCnt > 0);
233 if (0 == this->caps()->getRenderTargetSampleCount(sampleCnt, config)) {
234 config = GrPixelConfigFallback(config);
235 // TODO: First we should be checking the getRenderTargetSampleCount from the GrBackendFormat
236 // and not GrPixelConfig. Besides that, we should implement the fallback in the caps, but
237 // for now we just convert the fallback pixel config to an SkColorType and then get the
238 // GrBackendFormat from that.
239 SkColorType colorType;
240 if (!GrPixelConfigToColorType(config, &colorType)) {
241 return nullptr;
242 }
243 localFormat = this->caps()->getBackendFormatFromColorType(colorType);
244 }
245
246 return this->makeDeferredRenderTargetContext(localFormat, fit, width, height, config,
247 std::move(colorSpace), sampleCnt, mipMapped,
248 origin, surfaceProps, budgeted);
249}
250
Robert Phillipsa41c6852019-02-07 10:44:10 -0500251///////////////////////////////////////////////////////////////////////////////////////////////////
252sk_sp<const GrCaps> GrRecordingContextPriv::refCaps() const {
253 return fContext->refCaps();
254}
255
256sk_sp<GrSkSLFPFactoryCache> GrRecordingContextPriv::fpFactoryCache() {
257 return fContext->fpFactoryCache();
258}
Robert Phillipsd6841482019-02-08 10:29:20 -0500259
260sk_sp<GrOpMemoryPool> GrRecordingContextPriv::refOpMemoryPool() {
261 return fContext->refOpMemoryPool();
262}
Robert Phillipsb97da532019-02-12 15:24:12 -0500263
Robert Phillipsc5058a62019-02-15 12:52:59 -0500264void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
265 fContext->addOnFlushCallbackObject(onFlushCBObject);
266}
267
Robert Phillips292a6b22019-02-14 14:49:02 -0500268sk_sp<GrSurfaceContext> GrRecordingContextPriv::makeWrappedSurfaceContext(
269 sk_sp<GrSurfaceProxy> proxy,
270 sk_sp<SkColorSpace> colorSpace,
271 const SkSurfaceProps* props) {
272 return fContext->makeWrappedSurfaceContext(std::move(proxy), std::move(colorSpace), props);
273}
274
275sk_sp<GrSurfaceContext> GrRecordingContextPriv::makeDeferredSurfaceContext(
276 const GrBackendFormat& format,
277 const GrSurfaceDesc& dstDesc,
278 GrSurfaceOrigin origin,
279 GrMipMapped mipMapped,
280 SkBackingFit fit,
281 SkBudgeted isDstBudgeted,
282 sk_sp<SkColorSpace> colorSpace,
283 const SkSurfaceProps* props) {
284 return fContext->makeDeferredSurfaceContext(format, dstDesc, origin, mipMapped, fit,
285 isDstBudgeted, std::move(colorSpace), props);
286}
287
Robert Phillipsb97da532019-02-12 15:24:12 -0500288sk_sp<GrRenderTargetContext> GrRecordingContextPriv::makeDeferredRenderTargetContext(
289 const GrBackendFormat& format,
290 SkBackingFit fit,
291 int width, int height,
292 GrPixelConfig config,
293 sk_sp<SkColorSpace> colorSpace,
294 int sampleCnt,
295 GrMipMapped mipMapped,
296 GrSurfaceOrigin origin,
297 const SkSurfaceProps* surfaceProps,
298 SkBudgeted budgeted) {
299 return fContext->makeDeferredRenderTargetContext(format, fit, width, height, config,
300 std::move(colorSpace), sampleCnt, mipMapped,
301 origin, surfaceProps, budgeted);
302}
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500303
304sk_sp<GrRenderTargetContext> GrRecordingContextPriv::makeDeferredRenderTargetContextWithFallback(
305 const GrBackendFormat& format,
306 SkBackingFit fit,
307 int width, int height,
308 GrPixelConfig config,
309 sk_sp<SkColorSpace> colorSpace,
310 int sampleCnt,
311 GrMipMapped mipMapped,
312 GrSurfaceOrigin origin,
313 const SkSurfaceProps* surfaceProps,
314 SkBudgeted budgeted) {
315 return fContext->makeDeferredRenderTargetContextWithFallback(format, fit, width, height, config,
316 std::move(colorSpace), sampleCnt,
317 mipMapped, origin, surfaceProps,
318 budgeted);
319}
Robert Phillips9338c602019-02-19 12:52:29 -0500320
321GrContext* GrRecordingContextPriv::backdoor() {
322 return (GrContext*) fContext;
323}