1 /*
2 * Copyright 2020 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 "src/gpu/GrRecordingContextPriv.h"
9
10 #include "src/gpu/GrCaps.h"
11 #include "src/gpu/GrDrawingManager.h"
12 #include "src/gpu/GrProxyProvider.h"
13 #include "src/gpu/GrRenderTargetProxy.h"
14 #include "src/gpu/GrSurfaceProxyView.h"
15
16 #if SK_GPU_V1
17 #include "src/gpu/v1/Device_v1.h"
18 #include "src/gpu/v1/SurfaceDrawContext_v1.h"
19 #include "src/gpu/v1/SurfaceFillContext_v1.h"
20 #endif
21
addOnFlushCallbackObject(GrOnFlushCallbackObject * onFlushCBObject)22 void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
23 this->context()->addOnFlushCallbackObject(onFlushCBObject);
24 }
25
createDevice(GrColorType colorType,sk_sp<GrSurfaceProxy> proxy,sk_sp<SkColorSpace> colorSpace,GrSurfaceOrigin origin,const SkSurfaceProps & props,skgpu::BaseDevice::InitContents init)26 sk_sp<skgpu::BaseDevice> GrRecordingContextPriv::createDevice(GrColorType colorType,
27 sk_sp<GrSurfaceProxy> proxy,
28 sk_sp<SkColorSpace> colorSpace,
29 GrSurfaceOrigin origin,
30 const SkSurfaceProps& props,
31 skgpu::BaseDevice::InitContents init) {
32 #if SK_GPU_V1
33 return skgpu::v1::Device::Make(this->context(), colorType, std::move(proxy),
34 std::move(colorSpace), origin, props, init);
35 #else
36 return nullptr;
37 #endif
38 }
39
createDevice(SkBudgeted budgeted,const SkImageInfo & ii,SkBackingFit fit,int sampleCount,GrMipmapped mipmapped,GrProtected isProtected,GrSurfaceOrigin origin,const SkSurfaceProps & props,skgpu::BaseDevice::InitContents init)40 sk_sp<skgpu::BaseDevice> GrRecordingContextPriv::createDevice(SkBudgeted budgeted,
41 const SkImageInfo& ii,
42 SkBackingFit fit,
43 int sampleCount,
44 GrMipmapped mipmapped,
45 GrProtected isProtected,
46 GrSurfaceOrigin origin,
47 const SkSurfaceProps& props,
48 skgpu::BaseDevice::InitContents init) {
49 #if SK_GPU_V1
50 return skgpu::v1::Device::Make(this->context(), budgeted, ii, fit, sampleCount,
51 mipmapped, isProtected, origin, props, init);
52 #else
53 return nullptr;
54 #endif
55 }
56
moveRenderTasksToDDL(SkDeferredDisplayList * ddl)57 void GrRecordingContextPriv::moveRenderTasksToDDL(SkDeferredDisplayList* ddl) {
58 this->context()->drawingManager()->moveRenderTasksToDDL(ddl);
59 }
60
getSDFTControl(bool useSDFTForSmallText) const61 GrSDFTControl GrRecordingContextPriv::getSDFTControl(bool useSDFTForSmallText) const {
62 return GrSDFTControl{
63 this->caps()->shaderCaps()->supportsDistanceFieldText(),
64 useSDFTForSmallText,
65 this->options().fMinDistanceFieldFontSize,
66 this->options().fGlyphsAsPathsFontSize};
67 }
68
makeSC(GrSurfaceProxyView readView,const GrColorInfo & info)69 std::unique_ptr<skgpu::SurfaceContext> GrRecordingContextPriv::makeSC(GrSurfaceProxyView readView,
70 const GrColorInfo& info) {
71 #if SK_GPU_V1
72 // It is probably not necessary to check if the context is abandoned here since uses of the
73 // SurfaceContext which need the context will mostly likely fail later on w/o an issue.
74 // However having this here adds some reassurance in case there is a path that doesn't
75 // handle an abandoned context correctly. It also lets us early out of some extra work.
76 if (this->context()->abandoned()) {
77 return nullptr;
78 }
79 GrSurfaceProxy* proxy = readView.proxy();
80 SkASSERT(proxy && proxy->asTextureProxy());
81
82 std::unique_ptr<skgpu::SurfaceContext> sc;
83 if (proxy->asRenderTargetProxy()) {
84 // Will we ever want a swizzle that is not the default write swizzle for the format and
85 // colorType here? If so we will need to manually pass that in.
86 GrSwizzle writeSwizzle;
87 if (info.colorType() != GrColorType::kUnknown) {
88 writeSwizzle = this->caps()->getWriteSwizzle(proxy->backendFormat(),
89 info.colorType());
90 }
91 GrSurfaceProxyView writeView(readView.refProxy(), readView.origin(), writeSwizzle);
92 if (info.alphaType() == kPremul_SkAlphaType ||
93 info.alphaType() == kOpaque_SkAlphaType) {
94 sc = std::make_unique<skgpu::v1::SurfaceDrawContext>(this->context(),
95 std::move(readView),
96 std::move(writeView),
97 info.colorType(),
98 info.refColorSpace(),
99 SkSurfaceProps());
100 } else {
101 sc = std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
102 std::move(readView),
103 std::move(writeView),
104 info);
105 }
106 } else {
107 sc = std::make_unique<skgpu::SurfaceContext>(this->context(),
108 std::move(readView),
109 info);
110 }
111 SkDEBUGCODE(sc->validate();)
112 return sc;
113 #endif
114 return nullptr;
115 }
116
makeSC(const GrImageInfo & info,const GrBackendFormat & format,SkBackingFit fit,GrSurfaceOrigin origin,GrRenderable renderable,int sampleCount,GrMipmapped mipmapped,GrProtected isProtected,SkBudgeted budgeted)117 std::unique_ptr<skgpu::SurfaceContext> GrRecordingContextPriv::makeSC(const GrImageInfo& info,
118 const GrBackendFormat& format,
119 SkBackingFit fit,
120 GrSurfaceOrigin origin,
121 GrRenderable renderable,
122 int sampleCount,
123 GrMipmapped mipmapped,
124 GrProtected isProtected,
125 SkBudgeted budgeted) {
126 SkASSERT(renderable == GrRenderable::kYes || sampleCount == 1);
127 if (this->abandoned()) {
128 return nullptr;
129 }
130 sk_sp<GrTextureProxy> proxy = this->proxyProvider()->createProxy(format,
131 info.dimensions(),
132 renderable,
133 sampleCount,
134 mipmapped,
135 fit,
136 budgeted,
137 isProtected);
138 if (!proxy) {
139 return nullptr;
140 }
141
142 GrSwizzle swizzle;
143 if (info.colorType() != GrColorType::kUnknown &&
144 !this->caps()->isFormatCompressed(format)) {
145 swizzle = this->caps()->getReadSwizzle(format, info.colorType());
146 }
147
148 GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
149 return this->makeSC(std::move(view), info.colorInfo());
150 }
151
makeSFC(GrImageInfo info,SkBackingFit fit,int sampleCount,GrMipmapped mipmapped,GrProtected isProtected,GrSurfaceOrigin origin,SkBudgeted budgeted)152 std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFC(GrImageInfo info,
153 SkBackingFit fit,
154 int sampleCount,
155 GrMipmapped mipmapped,
156 GrProtected isProtected,
157 GrSurfaceOrigin origin,
158 SkBudgeted budgeted) {
159
160 #if SK_GPU_V1
161 if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
162 return skgpu::v1::SurfaceDrawContext::Make(this->context(),
163 info.colorType(),
164 info.refColorSpace(),
165 fit,
166 info.dimensions(),
167 SkSurfaceProps(),
168 sampleCount,
169 mipmapped,
170 isProtected,
171 origin,
172 budgeted);
173 }
174 GrBackendFormat format = this->caps()->getDefaultBackendFormat(info.colorType(),
175 GrRenderable::kYes);
176 sk_sp<GrTextureProxy> proxy = this->proxyProvider()->createProxy(format,
177 info.dimensions(),
178 GrRenderable::kYes,
179 sampleCount,
180 mipmapped,
181 fit,
182 budgeted,
183 isProtected);
184 if (!proxy) {
185 return nullptr;
186 }
187 GrSwizzle readSwizzle = this->caps()->getReadSwizzle (format, info.colorType());
188 GrSwizzle writeSwizzle = this->caps()->getWriteSwizzle(format, info.colorType());
189
190 GrSurfaceProxyView readView( proxy, origin, readSwizzle);
191 GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
192 std::unique_ptr<skgpu::SurfaceFillContext> sfc;
193 sfc = std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
194 std::move(readView),
195 std::move(writeView),
196 info.colorInfo());
197 sfc->discard();
198 return sfc;
199 #endif
200
201 return nullptr;
202 }
203
makeSFC(SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace,SkISize dimensions,SkBackingFit fit,const GrBackendFormat & format,int sampleCount,GrMipmapped mipmapped,GrProtected isProtected,GrSwizzle readSwizzle,GrSwizzle writeSwizzle,GrSurfaceOrigin origin,SkBudgeted budgeted)204 std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFC(
205 SkAlphaType alphaType,
206 sk_sp<SkColorSpace> colorSpace,
207 SkISize dimensions,
208 SkBackingFit fit,
209 const GrBackendFormat& format,
210 int sampleCount,
211 GrMipmapped mipmapped,
212 GrProtected isProtected,
213 GrSwizzle readSwizzle,
214 GrSwizzle writeSwizzle,
215 GrSurfaceOrigin origin,
216 SkBudgeted budgeted) {
217
218 #if SK_GPU_V1
219 SkASSERT(!dimensions.isEmpty());
220 SkASSERT(sampleCount >= 1);
221 SkASSERT(format.isValid() && format.backend() == fContext->backend());
222 if (alphaType == kPremul_SkAlphaType || alphaType == kOpaque_SkAlphaType) {
223 return skgpu::v1::SurfaceDrawContext::Make(this->context(),
224 std::move(colorSpace),
225 fit,
226 dimensions,
227 format,
228 sampleCount,
229 mipmapped,
230 isProtected,
231 readSwizzle,
232 writeSwizzle,
233 origin,
234 budgeted,
235 SkSurfaceProps());
236 }
237
238 sk_sp<GrTextureProxy> proxy = this->proxyProvider()->createProxy(format,
239 dimensions,
240 GrRenderable::kYes,
241 sampleCount,
242 mipmapped,
243 fit,
244 budgeted,
245 isProtected);
246 if (!proxy) {
247 return nullptr;
248 }
249 GrImageInfo info(GrColorType::kUnknown, alphaType, std::move(colorSpace), dimensions);
250 GrSurfaceProxyView readView( proxy, origin, readSwizzle);
251 GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
252 std::unique_ptr<skgpu::SurfaceFillContext> sfc;
253 sfc = std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
254 std::move(readView),
255 std::move(writeView),
256 info.colorInfo());
257 sfc->discard();
258 return sfc;
259 #endif
260
261 return nullptr;
262 }
263
makeSFCWithFallback(GrImageInfo info,SkBackingFit fit,int sampleCount,GrMipmapped mipmapped,GrProtected isProtected,GrSurfaceOrigin origin,SkBudgeted budgeted)264 std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFCWithFallback(
265 GrImageInfo info,
266 SkBackingFit fit,
267 int sampleCount,
268 GrMipmapped mipmapped,
269 GrProtected isProtected,
270 GrSurfaceOrigin origin,
271 SkBudgeted budgeted) {
272
273 #if SK_GPU_V1
274 if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
275 return skgpu::v1::SurfaceDrawContext::MakeWithFallback(this->context(),
276 info.colorType(),
277 info.refColorSpace(),
278 fit,
279 info.dimensions(),
280 SkSurfaceProps(),
281 sampleCount,
282 mipmapped,
283 isProtected,
284 origin,
285 budgeted);
286 }
287 const GrCaps* caps = this->caps();
288
289 auto [ct, _] = caps->getFallbackColorTypeAndFormat(info.colorType(), sampleCount);
290 if (ct == GrColorType::kUnknown) {
291 return nullptr;
292 }
293 info = info.makeColorType(ct);
294 return this->makeSFC(info,
295 fit,
296 sampleCount,
297 mipmapped,
298 isProtected,
299 origin,
300 budgeted);
301 #endif
302
303 return nullptr;
304 }
305
makeSFCFromBackendTexture(GrColorInfo info,const GrBackendTexture & tex,int sampleCount,GrSurfaceOrigin origin,sk_sp<GrRefCntedCallback> releaseHelper)306 std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFCFromBackendTexture(
307 GrColorInfo info,
308 const GrBackendTexture& tex,
309 int sampleCount,
310 GrSurfaceOrigin origin,
311 sk_sp<GrRefCntedCallback> releaseHelper) {
312
313 #if SK_GPU_V1
314 SkASSERT(sampleCount > 0);
315
316 if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
317 return skgpu::v1::SurfaceDrawContext::MakeFromBackendTexture(this->context(),
318 info.colorType(),
319 info.refColorSpace(),
320 tex,
321 sampleCount,
322 origin,
323 SkSurfaceProps(),
324 std::move(releaseHelper));
325 }
326
327 if (info.colorType() == GrColorType::kUnknown) {
328 return nullptr;
329 }
330
331 const GrBackendFormat& format = tex.getBackendFormat();
332 if (!this->caps()->areColorTypeAndFormatCompatible(info.colorType(), format)) {
333 return nullptr;
334 }
335 GrSwizzle readSwizzle = this->caps()->getReadSwizzle (format, info.colorType());
336 GrSwizzle writeSwizzle = this->caps()->getWriteSwizzle(format, info.colorType());
337
338 sk_sp<GrTextureProxy> proxy(this->proxyProvider()->wrapRenderableBackendTexture(
339 tex, sampleCount, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
340 std::move(releaseHelper)));
341 if (!proxy) {
342 return nullptr;
343 }
344
345 GrSurfaceProxyView readView( proxy, origin, readSwizzle);
346 GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
347
348 return std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
349 std::move(readView),
350 std::move(writeView),
351 std::move(info));
352 #endif
353
354 return nullptr;
355 }
356