• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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