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