xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrContextThreadSafeProxy.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2019 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrContextThreadSafeProxy.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrSurfaceCharacterization.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrContextThreadSafeProxyPriv.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrThreadSafeCache.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrThreadSafePipelineBuilder.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/gpu/TextBlobRedrawCoordinator.h"
19*c8dee2aaSAndroid Build Coastguard Worker 
20*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
21*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
22*c8dee2aaSAndroid Build Coastguard Worker 
next_id()23*c8dee2aaSAndroid Build Coastguard Worker static uint32_t next_id() {
24*c8dee2aaSAndroid Build Coastguard Worker     static std::atomic<uint32_t> nextID{1};
25*c8dee2aaSAndroid Build Coastguard Worker     uint32_t id;
26*c8dee2aaSAndroid Build Coastguard Worker     do {
27*c8dee2aaSAndroid Build Coastguard Worker         id = nextID.fetch_add(1, std::memory_order_relaxed);
28*c8dee2aaSAndroid Build Coastguard Worker     } while (id == SK_InvalidGenID);
29*c8dee2aaSAndroid Build Coastguard Worker     return id;
30*c8dee2aaSAndroid Build Coastguard Worker }
31*c8dee2aaSAndroid Build Coastguard Worker 
GrContextThreadSafeProxy(GrBackendApi backend,const GrContextOptions & options)32*c8dee2aaSAndroid Build Coastguard Worker GrContextThreadSafeProxy::GrContextThreadSafeProxy(GrBackendApi backend,
33*c8dee2aaSAndroid Build Coastguard Worker                                                    const GrContextOptions& options)
34*c8dee2aaSAndroid Build Coastguard Worker         : fBackend(backend), fOptions(options), fContextID(next_id()) {
35*c8dee2aaSAndroid Build Coastguard Worker }
36*c8dee2aaSAndroid Build Coastguard Worker 
37*c8dee2aaSAndroid Build Coastguard Worker GrContextThreadSafeProxy::~GrContextThreadSafeProxy() = default;
38*c8dee2aaSAndroid Build Coastguard Worker 
init(sk_sp<const GrCaps> caps,sk_sp<GrThreadSafePipelineBuilder> pipelineBuilder)39*c8dee2aaSAndroid Build Coastguard Worker void GrContextThreadSafeProxy::init(sk_sp<const GrCaps> caps,
40*c8dee2aaSAndroid Build Coastguard Worker                                     sk_sp<GrThreadSafePipelineBuilder> pipelineBuilder) {
41*c8dee2aaSAndroid Build Coastguard Worker     fCaps = std::move(caps);
42*c8dee2aaSAndroid Build Coastguard Worker     fTextBlobRedrawCoordinator =
43*c8dee2aaSAndroid Build Coastguard Worker             std::make_unique<sktext::gpu::TextBlobRedrawCoordinator>(fContextID);
44*c8dee2aaSAndroid Build Coastguard Worker     fThreadSafeCache = std::make_unique<GrThreadSafeCache>();
45*c8dee2aaSAndroid Build Coastguard Worker     fPipelineBuilder = std::move(pipelineBuilder);
46*c8dee2aaSAndroid Build Coastguard Worker }
47*c8dee2aaSAndroid Build Coastguard Worker 
createCharacterization(size_t cacheMaxResourceBytes,const SkImageInfo & ii,const GrBackendFormat & backendFormat,int sampleCnt,GrSurfaceOrigin origin,const SkSurfaceProps & surfaceProps,skgpu::Mipmapped isMipmapped,bool willUseGLFBO0,bool isTextureable,skgpu::Protected isProtected,bool vkRTSupportsInputAttachment,bool forVulkanSecondaryCommandBuffer)48*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization(
49*c8dee2aaSAndroid Build Coastguard Worker         size_t cacheMaxResourceBytes,
50*c8dee2aaSAndroid Build Coastguard Worker         const SkImageInfo& ii,
51*c8dee2aaSAndroid Build Coastguard Worker         const GrBackendFormat& backendFormat,
52*c8dee2aaSAndroid Build Coastguard Worker         int sampleCnt,
53*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceOrigin origin,
54*c8dee2aaSAndroid Build Coastguard Worker         const SkSurfaceProps& surfaceProps,
55*c8dee2aaSAndroid Build Coastguard Worker         skgpu::Mipmapped isMipmapped,
56*c8dee2aaSAndroid Build Coastguard Worker         bool willUseGLFBO0,
57*c8dee2aaSAndroid Build Coastguard Worker         bool isTextureable,
58*c8dee2aaSAndroid Build Coastguard Worker         skgpu::Protected isProtected,
59*c8dee2aaSAndroid Build Coastguard Worker         bool vkRTSupportsInputAttachment,
60*c8dee2aaSAndroid Build Coastguard Worker         bool forVulkanSecondaryCommandBuffer) {
61*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fCaps);
62*c8dee2aaSAndroid Build Coastguard Worker     if (!backendFormat.isValid()) {
63*c8dee2aaSAndroid Build Coastguard Worker         return {};
64*c8dee2aaSAndroid Build Coastguard Worker     }
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(isTextureable || isMipmapped == skgpu::Mipmapped::kNo);
67*c8dee2aaSAndroid Build Coastguard Worker 
68*c8dee2aaSAndroid Build Coastguard Worker     if (GrBackendApi::kOpenGL != backendFormat.backend() && willUseGLFBO0) {
69*c8dee2aaSAndroid Build Coastguard Worker         // The willUseGLFBO0 flags can only be used for a GL backend.
70*c8dee2aaSAndroid Build Coastguard Worker         return {};
71*c8dee2aaSAndroid Build Coastguard Worker     }
72*c8dee2aaSAndroid Build Coastguard Worker 
73*c8dee2aaSAndroid Build Coastguard Worker     if (GrBackendApi::kVulkan != backendFormat.backend() &&
74*c8dee2aaSAndroid Build Coastguard Worker         (vkRTSupportsInputAttachment || forVulkanSecondaryCommandBuffer)) {
75*c8dee2aaSAndroid Build Coastguard Worker         // The vkRTSupportsInputAttachment and forVulkanSecondaryCommandBuffer flags can only be
76*c8dee2aaSAndroid Build Coastguard Worker         // used for a Vulkan backend.
77*c8dee2aaSAndroid Build Coastguard Worker         return {};
78*c8dee2aaSAndroid Build Coastguard Worker     }
79*c8dee2aaSAndroid Build Coastguard Worker 
80*c8dee2aaSAndroid Build Coastguard Worker     if (!fCaps->mipmapSupport()) {
81*c8dee2aaSAndroid Build Coastguard Worker         isMipmapped = skgpu::Mipmapped::kNo;
82*c8dee2aaSAndroid Build Coastguard Worker     }
83*c8dee2aaSAndroid Build Coastguard Worker 
84*c8dee2aaSAndroid Build Coastguard Worker     if (ii.width()  < 1 || ii.width()  > fCaps->maxRenderTargetSize() ||
85*c8dee2aaSAndroid Build Coastguard Worker         ii.height() < 1 || ii.height() > fCaps->maxRenderTargetSize()) {
86*c8dee2aaSAndroid Build Coastguard Worker         return {};
87*c8dee2aaSAndroid Build Coastguard Worker     }
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker     GrColorType grColorType = SkColorTypeToGrColorType(ii.colorType());
90*c8dee2aaSAndroid Build Coastguard Worker 
91*c8dee2aaSAndroid Build Coastguard Worker     if (!fCaps->areColorTypeAndFormatCompatible(grColorType, backendFormat)) {
92*c8dee2aaSAndroid Build Coastguard Worker         return {};
93*c8dee2aaSAndroid Build Coastguard Worker     }
94*c8dee2aaSAndroid Build Coastguard Worker 
95*c8dee2aaSAndroid Build Coastguard Worker     if (!fCaps->isFormatAsColorTypeRenderable(grColorType, backendFormat, sampleCnt)) {
96*c8dee2aaSAndroid Build Coastguard Worker         return {};
97*c8dee2aaSAndroid Build Coastguard Worker     }
98*c8dee2aaSAndroid Build Coastguard Worker 
99*c8dee2aaSAndroid Build Coastguard Worker     sampleCnt = fCaps->getRenderTargetSampleCount(sampleCnt, backendFormat);
100*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(sampleCnt);
101*c8dee2aaSAndroid Build Coastguard Worker 
102*c8dee2aaSAndroid Build Coastguard Worker     if (willUseGLFBO0 && isTextureable) {
103*c8dee2aaSAndroid Build Coastguard Worker         return {};
104*c8dee2aaSAndroid Build Coastguard Worker     }
105*c8dee2aaSAndroid Build Coastguard Worker 
106*c8dee2aaSAndroid Build Coastguard Worker     if (isTextureable && !fCaps->isFormatTexturable(backendFormat, backendFormat.textureType())) {
107*c8dee2aaSAndroid Build Coastguard Worker         // Skia doesn't agree that this is textureable.
108*c8dee2aaSAndroid Build Coastguard Worker         return {};
109*c8dee2aaSAndroid Build Coastguard Worker     }
110*c8dee2aaSAndroid Build Coastguard Worker 
111*c8dee2aaSAndroid Build Coastguard Worker     if (GrBackendApi::kVulkan == backendFormat.backend()) {
112*c8dee2aaSAndroid Build Coastguard Worker         if (!isValidCharacterizationForVulkan(fCaps,
113*c8dee2aaSAndroid Build Coastguard Worker                                               isTextureable,
114*c8dee2aaSAndroid Build Coastguard Worker                                               isMipmapped,
115*c8dee2aaSAndroid Build Coastguard Worker                                               isProtected,
116*c8dee2aaSAndroid Build Coastguard Worker                                               vkRTSupportsInputAttachment,
117*c8dee2aaSAndroid Build Coastguard Worker                                               forVulkanSecondaryCommandBuffer)) {
118*c8dee2aaSAndroid Build Coastguard Worker             return {};
119*c8dee2aaSAndroid Build Coastguard Worker         }
120*c8dee2aaSAndroid Build Coastguard Worker     }
121*c8dee2aaSAndroid Build Coastguard Worker 
122*c8dee2aaSAndroid Build Coastguard Worker     return GrSurfaceCharacterization(
123*c8dee2aaSAndroid Build Coastguard Worker             sk_ref_sp<GrContextThreadSafeProxy>(this),
124*c8dee2aaSAndroid Build Coastguard Worker             cacheMaxResourceBytes,
125*c8dee2aaSAndroid Build Coastguard Worker             ii,
126*c8dee2aaSAndroid Build Coastguard Worker             backendFormat,
127*c8dee2aaSAndroid Build Coastguard Worker             origin,
128*c8dee2aaSAndroid Build Coastguard Worker             sampleCnt,
129*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization::Textureable(isTextureable),
130*c8dee2aaSAndroid Build Coastguard Worker             isMipmapped,
131*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization::UsesGLFBO0(willUseGLFBO0),
132*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization::VkRTSupportsInputAttachment(vkRTSupportsInputAttachment),
133*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization::VulkanSecondaryCBCompatible(forVulkanSecondaryCommandBuffer),
134*c8dee2aaSAndroid Build Coastguard Worker             isProtected,
135*c8dee2aaSAndroid Build Coastguard Worker             surfaceProps);
136*c8dee2aaSAndroid Build Coastguard Worker }
137*c8dee2aaSAndroid Build Coastguard Worker 
isValidCharacterizationForVulkan(sk_sp<const GrCaps>,bool isTextureable,skgpu::Mipmapped isMipmapped,skgpu::Protected isProtected,bool vkRTSupportsInputAttachment,bool forVulkanSecondaryCommandBuffer)138*c8dee2aaSAndroid Build Coastguard Worker bool GrContextThreadSafeProxy::isValidCharacterizationForVulkan(
139*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<const GrCaps>,
140*c8dee2aaSAndroid Build Coastguard Worker         bool isTextureable,
141*c8dee2aaSAndroid Build Coastguard Worker         skgpu::Mipmapped isMipmapped,
142*c8dee2aaSAndroid Build Coastguard Worker         skgpu::Protected isProtected,
143*c8dee2aaSAndroid Build Coastguard Worker         bool vkRTSupportsInputAttachment,
144*c8dee2aaSAndroid Build Coastguard Worker         bool forVulkanSecondaryCommandBuffer) {
145*c8dee2aaSAndroid Build Coastguard Worker     return false;  // handled by a subclass
146*c8dee2aaSAndroid Build Coastguard Worker }
147*c8dee2aaSAndroid Build Coastguard Worker 
defaultBackendFormat(SkColorType skColorType,GrRenderable renderable) const148*c8dee2aaSAndroid Build Coastguard Worker GrBackendFormat GrContextThreadSafeProxy::defaultBackendFormat(SkColorType skColorType,
149*c8dee2aaSAndroid Build Coastguard Worker                                                                GrRenderable renderable) const {
150*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fCaps);
151*c8dee2aaSAndroid Build Coastguard Worker     GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
152*c8dee2aaSAndroid Build Coastguard Worker 
153*c8dee2aaSAndroid Build Coastguard Worker     GrBackendFormat format = fCaps->getDefaultBackendFormat(grColorType, renderable);
154*c8dee2aaSAndroid Build Coastguard Worker     if (!format.isValid()) {
155*c8dee2aaSAndroid Build Coastguard Worker         return GrBackendFormat();
156*c8dee2aaSAndroid Build Coastguard Worker     }
157*c8dee2aaSAndroid Build Coastguard Worker 
158*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(renderable == GrRenderable::kNo ||
159*c8dee2aaSAndroid Build Coastguard Worker              fCaps->isFormatAsColorTypeRenderable(grColorType, format));
160*c8dee2aaSAndroid Build Coastguard Worker 
161*c8dee2aaSAndroid Build Coastguard Worker     return format;
162*c8dee2aaSAndroid Build Coastguard Worker }
163*c8dee2aaSAndroid Build Coastguard Worker 
compressedBackendFormat(SkTextureCompressionType c) const164*c8dee2aaSAndroid Build Coastguard Worker GrBackendFormat GrContextThreadSafeProxy::compressedBackendFormat(SkTextureCompressionType c) const {
165*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fCaps);
166*c8dee2aaSAndroid Build Coastguard Worker 
167*c8dee2aaSAndroid Build Coastguard Worker     GrBackendFormat format = fCaps->getBackendFormatFromCompressionType(c);
168*c8dee2aaSAndroid Build Coastguard Worker 
169*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!format.isValid() || fCaps->isFormatTexturable(format, GrTextureType::k2D));
170*c8dee2aaSAndroid Build Coastguard Worker     return format;
171*c8dee2aaSAndroid Build Coastguard Worker }
172*c8dee2aaSAndroid Build Coastguard Worker 
maxSurfaceSampleCountForColorType(SkColorType colorType) const173*c8dee2aaSAndroid Build Coastguard Worker int GrContextThreadSafeProxy::maxSurfaceSampleCountForColorType(SkColorType colorType) const {
174*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fCaps);
175*c8dee2aaSAndroid Build Coastguard Worker 
176*c8dee2aaSAndroid Build Coastguard Worker     GrBackendFormat format = fCaps->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
177*c8dee2aaSAndroid Build Coastguard Worker                                                             GrRenderable::kYes);
178*c8dee2aaSAndroid Build Coastguard Worker     return fCaps->maxRenderTargetSampleCount(format);
179*c8dee2aaSAndroid Build Coastguard Worker }
180*c8dee2aaSAndroid Build Coastguard Worker 
abandonContext()181*c8dee2aaSAndroid Build Coastguard Worker void GrContextThreadSafeProxy::abandonContext() {
182*c8dee2aaSAndroid Build Coastguard Worker     if (!fAbandoned.exchange(true)) {
183*c8dee2aaSAndroid Build Coastguard Worker         fTextBlobRedrawCoordinator->freeAll();
184*c8dee2aaSAndroid Build Coastguard Worker     }
185*c8dee2aaSAndroid Build Coastguard Worker }
186*c8dee2aaSAndroid Build Coastguard Worker 
abandoned() const187*c8dee2aaSAndroid Build Coastguard Worker bool GrContextThreadSafeProxy::abandoned() const {
188*c8dee2aaSAndroid Build Coastguard Worker     return fAbandoned;
189*c8dee2aaSAndroid Build Coastguard Worker }
190*c8dee2aaSAndroid Build Coastguard Worker 
191*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
Make(GrBackendApi backend,const GrContextOptions & options)192*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrContextThreadSafeProxy> GrContextThreadSafeProxyPriv::Make(
193*c8dee2aaSAndroid Build Coastguard Worker                              GrBackendApi backend,
194*c8dee2aaSAndroid Build Coastguard Worker                              const GrContextOptions& options) {
195*c8dee2aaSAndroid Build Coastguard Worker     return sk_sp<GrContextThreadSafeProxy>(new GrContextThreadSafeProxy(backend, options));
196*c8dee2aaSAndroid Build Coastguard Worker }
197*c8dee2aaSAndroid Build Coastguard Worker 
init(sk_sp<const GrCaps> caps,sk_sp<GrThreadSafePipelineBuilder> builder) const198*c8dee2aaSAndroid Build Coastguard Worker void GrContextThreadSafeProxyPriv::init(sk_sp<const GrCaps> caps,
199*c8dee2aaSAndroid Build Coastguard Worker                                         sk_sp<GrThreadSafePipelineBuilder> builder) const {
200*c8dee2aaSAndroid Build Coastguard Worker     fProxy->init(std::move(caps), std::move(builder));
201*c8dee2aaSAndroid Build Coastguard Worker }
202