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