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