xref: /aosp_15_r20/external/skia/src/gpu/ganesh/vk/GrVkSecondaryCBDrawContext.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/private/chromium/GrVkSecondaryCBDrawContext.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/GrDirectContext.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrRecordingContext.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkTypes.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrDeferredDisplayList.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrSurfaceCharacterization.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkSurfacePriv.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrContextThreadSafeProxyPriv.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProxyProvider.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRecordingContextPriv.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRenderTarget.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRenderTargetProxy.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrResourceProvider.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxyView.h"
26*c8dee2aaSAndroid Build Coastguard Worker 
Make(GrRecordingContext * rContext,const SkImageInfo & imageInfo,const GrVkDrawableInfo & vkInfo,const SkSurfaceProps * props)27*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrVkSecondaryCBDrawContext> GrVkSecondaryCBDrawContext::Make(GrRecordingContext* rContext,
28*c8dee2aaSAndroid Build Coastguard Worker                                                                    const SkImageInfo& imageInfo,
29*c8dee2aaSAndroid Build Coastguard Worker                                                                    const GrVkDrawableInfo& vkInfo,
30*c8dee2aaSAndroid Build Coastguard Worker                                                                    const SkSurfaceProps* props) {
31*c8dee2aaSAndroid Build Coastguard Worker     if (!rContext) {
32*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
33*c8dee2aaSAndroid Build Coastguard Worker     }
34*c8dee2aaSAndroid Build Coastguard Worker 
35*c8dee2aaSAndroid Build Coastguard Worker     if (rContext->backend() != GrBackendApi::kVulkan) {
36*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
37*c8dee2aaSAndroid Build Coastguard Worker     }
38*c8dee2aaSAndroid Build Coastguard Worker 
39*c8dee2aaSAndroid Build Coastguard Worker 
40*c8dee2aaSAndroid Build Coastguard Worker     GrProxyProvider* gpp = rContext->priv().proxyProvider();
41*c8dee2aaSAndroid Build Coastguard Worker     if (gpp->isAbandoned()) {
42*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
43*c8dee2aaSAndroid Build Coastguard Worker     }
44*c8dee2aaSAndroid Build Coastguard Worker 
45*c8dee2aaSAndroid Build Coastguard Worker     GrResourceProvider* resourceProvider = gpp->resourceProvider();
46*c8dee2aaSAndroid Build Coastguard Worker     if (!resourceProvider) {
47*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
48*c8dee2aaSAndroid Build Coastguard Worker     }
49*c8dee2aaSAndroid Build Coastguard Worker 
50*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrRenderTarget> rt = resourceProvider->wrapVulkanSecondaryCBAsRenderTarget(imageInfo,
51*c8dee2aaSAndroid Build Coastguard Worker                                                                                      vkInfo);
52*c8dee2aaSAndroid Build Coastguard Worker     if (!rt) {
53*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
54*c8dee2aaSAndroid Build Coastguard Worker     }
55*c8dee2aaSAndroid Build Coastguard Worker 
56*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!rt->asTexture());  // A GrRenderTarget that's not textureable
57*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!rt->getUniqueKey().isValid());
58*c8dee2aaSAndroid Build Coastguard Worker     // This proxy should be unbudgeted because we're just wrapping an external resource
59*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(GrBudgetedType::kBudgeted != rt->resourcePriv().budgetedType());
60*c8dee2aaSAndroid Build Coastguard Worker 
61*c8dee2aaSAndroid Build Coastguard Worker     GrColorType colorType = SkColorTypeToGrColorType(imageInfo.colorType());
62*c8dee2aaSAndroid Build Coastguard Worker 
63*c8dee2aaSAndroid Build Coastguard Worker     if (!gpp->caps()->isFormatAsColorTypeRenderable(
64*c8dee2aaSAndroid Build Coastguard Worker             colorType, GrBackendFormats::MakeVk(vkInfo.fFormat), /*sampleCount=*/1)) {
65*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
66*c8dee2aaSAndroid Build Coastguard Worker     }
67*c8dee2aaSAndroid Build Coastguard Worker 
68*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrRenderTargetProxy> proxy(
69*c8dee2aaSAndroid Build Coastguard Worker             new GrRenderTargetProxy(std::move(rt),
70*c8dee2aaSAndroid Build Coastguard Worker                                     GrSurfaceProxy::UseAllocator::kNo,
71*c8dee2aaSAndroid Build Coastguard Worker                                     GrRenderTargetProxy::WrapsVkSecondaryCB::kYes));
72*c8dee2aaSAndroid Build Coastguard Worker 
73*c8dee2aaSAndroid Build Coastguard Worker     if (!proxy) {
74*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
75*c8dee2aaSAndroid Build Coastguard Worker     }
76*c8dee2aaSAndroid Build Coastguard Worker 
77*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(proxy->isInstantiated());
78*c8dee2aaSAndroid Build Coastguard Worker 
79*c8dee2aaSAndroid Build Coastguard Worker     auto device = rContext->priv().createDevice(SkColorTypeToGrColorType(imageInfo.colorType()),
80*c8dee2aaSAndroid Build Coastguard Worker                                                 std::move(proxy),
81*c8dee2aaSAndroid Build Coastguard Worker                                                 imageInfo.refColorSpace(),
82*c8dee2aaSAndroid Build Coastguard Worker                                                 kTopLeft_GrSurfaceOrigin,
83*c8dee2aaSAndroid Build Coastguard Worker                                                 SkSurfacePropsCopyOrDefault(props),
84*c8dee2aaSAndroid Build Coastguard Worker                                                 skgpu::ganesh::Device::InitContents::kUninit);
85*c8dee2aaSAndroid Build Coastguard Worker     if (!device) {
86*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
87*c8dee2aaSAndroid Build Coastguard Worker     }
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker     return sk_sp<GrVkSecondaryCBDrawContext>(new GrVkSecondaryCBDrawContext(std::move(device),
90*c8dee2aaSAndroid Build Coastguard Worker                                                                             props));
91*c8dee2aaSAndroid Build Coastguard Worker }
92*c8dee2aaSAndroid Build Coastguard Worker 
GrVkSecondaryCBDrawContext(sk_sp<skgpu::ganesh::Device> device,const SkSurfaceProps * props)93*c8dee2aaSAndroid Build Coastguard Worker GrVkSecondaryCBDrawContext::GrVkSecondaryCBDrawContext(sk_sp<skgpu::ganesh::Device> device,
94*c8dee2aaSAndroid Build Coastguard Worker                                                        const SkSurfaceProps* props)
95*c8dee2aaSAndroid Build Coastguard Worker         : fDevice(std::move(device)), fProps(SkSurfacePropsCopyOrDefault(props)) {}
96*c8dee2aaSAndroid Build Coastguard Worker 
~GrVkSecondaryCBDrawContext()97*c8dee2aaSAndroid Build Coastguard Worker GrVkSecondaryCBDrawContext::~GrVkSecondaryCBDrawContext() {
98*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!fDevice);
99*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!fCachedCanvas.get());
100*c8dee2aaSAndroid Build Coastguard Worker }
101*c8dee2aaSAndroid Build Coastguard Worker 
getCanvas()102*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* GrVkSecondaryCBDrawContext::getCanvas() {
103*c8dee2aaSAndroid Build Coastguard Worker     if (!fCachedCanvas) {
104*c8dee2aaSAndroid Build Coastguard Worker         fCachedCanvas = std::make_unique<SkCanvas>(fDevice);
105*c8dee2aaSAndroid Build Coastguard Worker     }
106*c8dee2aaSAndroid Build Coastguard Worker     return fCachedCanvas.get();
107*c8dee2aaSAndroid Build Coastguard Worker }
108*c8dee2aaSAndroid Build Coastguard Worker 
flush()109*c8dee2aaSAndroid Build Coastguard Worker void GrVkSecondaryCBDrawContext::flush() {
110*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = GrAsDirectContext(fDevice->recordingContext());
111*c8dee2aaSAndroid Build Coastguard Worker 
112*c8dee2aaSAndroid Build Coastguard Worker     if (dContext) {
113*c8dee2aaSAndroid Build Coastguard Worker         dContext->priv().flushSurface(fDevice->targetProxy());
114*c8dee2aaSAndroid Build Coastguard Worker         dContext->submit();
115*c8dee2aaSAndroid Build Coastguard Worker     }
116*c8dee2aaSAndroid Build Coastguard Worker }
117*c8dee2aaSAndroid Build Coastguard Worker 
wait(int numSemaphores,const GrBackendSemaphore waitSemaphores[],bool deleteSemaphoresAfterWait)118*c8dee2aaSAndroid Build Coastguard Worker bool GrVkSecondaryCBDrawContext::wait(int numSemaphores,
119*c8dee2aaSAndroid Build Coastguard Worker                                       const GrBackendSemaphore waitSemaphores[],
120*c8dee2aaSAndroid Build Coastguard Worker                                       bool deleteSemaphoresAfterWait) {
121*c8dee2aaSAndroid Build Coastguard Worker     return fDevice->wait(numSemaphores, waitSemaphores, deleteSemaphoresAfterWait);
122*c8dee2aaSAndroid Build Coastguard Worker }
123*c8dee2aaSAndroid Build Coastguard Worker 
releaseResources()124*c8dee2aaSAndroid Build Coastguard Worker void GrVkSecondaryCBDrawContext::releaseResources() {
125*c8dee2aaSAndroid Build Coastguard Worker     fCachedCanvas.reset();
126*c8dee2aaSAndroid Build Coastguard Worker     fDevice.reset();
127*c8dee2aaSAndroid Build Coastguard Worker }
128*c8dee2aaSAndroid Build Coastguard Worker 
characterize(GrSurfaceCharacterization * characterization) const129*c8dee2aaSAndroid Build Coastguard Worker bool GrVkSecondaryCBDrawContext::characterize(GrSurfaceCharacterization* characterization) const {
130*c8dee2aaSAndroid Build Coastguard Worker     auto direct = fDevice->recordingContext()->asDirectContext();
131*c8dee2aaSAndroid Build Coastguard Worker     if (!direct) {
132*c8dee2aaSAndroid Build Coastguard Worker         return false;
133*c8dee2aaSAndroid Build Coastguard Worker     }
134*c8dee2aaSAndroid Build Coastguard Worker 
135*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo ii = fDevice->imageInfo();
136*c8dee2aaSAndroid Build Coastguard Worker     if (ii.colorType() == kUnknown_SkColorType) {
137*c8dee2aaSAndroid Build Coastguard Worker         return false;
138*c8dee2aaSAndroid Build Coastguard Worker     }
139*c8dee2aaSAndroid Build Coastguard Worker 
140*c8dee2aaSAndroid Build Coastguard Worker     GrSurfaceProxyView readSurfaceView = fDevice->readSurfaceView();
141*c8dee2aaSAndroid Build Coastguard Worker     size_t maxResourceBytes = direct->getResourceCacheLimit();
142*c8dee2aaSAndroid Build Coastguard Worker 
143*c8dee2aaSAndroid Build Coastguard Worker     // We current don't support textured GrVkSecondaryCBDrawContexts.
144*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!readSurfaceView.asTextureProxy());
145*c8dee2aaSAndroid Build Coastguard Worker 
146*c8dee2aaSAndroid Build Coastguard Worker     GrBackendFormat format = readSurfaceView.asRenderTargetProxy()->backendFormat();
147*c8dee2aaSAndroid Build Coastguard Worker     int numSamples = readSurfaceView.asRenderTargetProxy()->numSamples();
148*c8dee2aaSAndroid Build Coastguard Worker     GrProtected isProtected = readSurfaceView.asRenderTargetProxy()->isProtected();
149*c8dee2aaSAndroid Build Coastguard Worker 
150*c8dee2aaSAndroid Build Coastguard Worker     characterization->set(direct->threadSafeProxy(),
151*c8dee2aaSAndroid Build Coastguard Worker                           maxResourceBytes,
152*c8dee2aaSAndroid Build Coastguard Worker                           ii,
153*c8dee2aaSAndroid Build Coastguard Worker                           format,
154*c8dee2aaSAndroid Build Coastguard Worker                           readSurfaceView.origin(),
155*c8dee2aaSAndroid Build Coastguard Worker                           numSamples,
156*c8dee2aaSAndroid Build Coastguard Worker                           GrSurfaceCharacterization::Textureable(false),
157*c8dee2aaSAndroid Build Coastguard Worker                           skgpu::Mipmapped::kNo,
158*c8dee2aaSAndroid Build Coastguard Worker                           GrSurfaceCharacterization::UsesGLFBO0(false),
159*c8dee2aaSAndroid Build Coastguard Worker                           GrSurfaceCharacterization::VkRTSupportsInputAttachment(false),
160*c8dee2aaSAndroid Build Coastguard Worker                           GrSurfaceCharacterization::VulkanSecondaryCBCompatible(true),
161*c8dee2aaSAndroid Build Coastguard Worker                           isProtected,
162*c8dee2aaSAndroid Build Coastguard Worker                           this->props());
163*c8dee2aaSAndroid Build Coastguard Worker 
164*c8dee2aaSAndroid Build Coastguard Worker     return true;
165*c8dee2aaSAndroid Build Coastguard Worker }
166*c8dee2aaSAndroid Build Coastguard Worker 
isCompatible(const GrSurfaceCharacterization & characterization) const167*c8dee2aaSAndroid Build Coastguard Worker bool GrVkSecondaryCBDrawContext::isCompatible(
168*c8dee2aaSAndroid Build Coastguard Worker         const GrSurfaceCharacterization& characterization) const {
169*c8dee2aaSAndroid Build Coastguard Worker 
170*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = fDevice->recordingContext()->asDirectContext();
171*c8dee2aaSAndroid Build Coastguard Worker     if (!dContext) {
172*c8dee2aaSAndroid Build Coastguard Worker         return false;
173*c8dee2aaSAndroid Build Coastguard Worker     }
174*c8dee2aaSAndroid Build Coastguard Worker 
175*c8dee2aaSAndroid Build Coastguard Worker     if (!characterization.isValid()) {
176*c8dee2aaSAndroid Build Coastguard Worker         return false;
177*c8dee2aaSAndroid Build Coastguard Worker     }
178*c8dee2aaSAndroid Build Coastguard Worker 
179*c8dee2aaSAndroid Build Coastguard Worker     if (!characterization.vulkanSecondaryCBCompatible()) {
180*c8dee2aaSAndroid Build Coastguard Worker         return false;
181*c8dee2aaSAndroid Build Coastguard Worker     }
182*c8dee2aaSAndroid Build Coastguard Worker 
183*c8dee2aaSAndroid Build Coastguard Worker     if (characterization.isTextureable()) {
184*c8dee2aaSAndroid Build Coastguard Worker         // We don't support textureable DDL when rendering to a GrVkSecondaryCBDrawContext.
185*c8dee2aaSAndroid Build Coastguard Worker         return false;
186*c8dee2aaSAndroid Build Coastguard Worker     }
187*c8dee2aaSAndroid Build Coastguard Worker 
188*c8dee2aaSAndroid Build Coastguard Worker     if (characterization.usesGLFBO0()) {
189*c8dee2aaSAndroid Build Coastguard Worker         return false;
190*c8dee2aaSAndroid Build Coastguard Worker     }
191*c8dee2aaSAndroid Build Coastguard Worker 
192*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo ii = fDevice->imageInfo();
193*c8dee2aaSAndroid Build Coastguard Worker     if (ii.colorType() == kUnknown_SkColorType) {
194*c8dee2aaSAndroid Build Coastguard Worker         return false;
195*c8dee2aaSAndroid Build Coastguard Worker     }
196*c8dee2aaSAndroid Build Coastguard Worker 
197*c8dee2aaSAndroid Build Coastguard Worker     GrSurfaceProxyView readSurfaceView = fDevice->readSurfaceView();
198*c8dee2aaSAndroid Build Coastguard Worker     // As long as the current state in the context allows for greater or equal resources,
199*c8dee2aaSAndroid Build Coastguard Worker     // we allow the DDL to be replayed.
200*c8dee2aaSAndroid Build Coastguard Worker     // DDL TODO: should we just remove the resource check and ignore the cache limits on playback?
201*c8dee2aaSAndroid Build Coastguard Worker     size_t maxResourceBytes = dContext->getResourceCacheLimit();
202*c8dee2aaSAndroid Build Coastguard Worker 
203*c8dee2aaSAndroid Build Coastguard Worker     GrBackendFormat format = readSurfaceView.asRenderTargetProxy()->backendFormat();
204*c8dee2aaSAndroid Build Coastguard Worker     int numSamples = readSurfaceView.asRenderTargetProxy()->numSamples();
205*c8dee2aaSAndroid Build Coastguard Worker     GrProtected isProtected = readSurfaceView.asRenderTargetProxy()->isProtected();
206*c8dee2aaSAndroid Build Coastguard Worker 
207*c8dee2aaSAndroid Build Coastguard Worker     return characterization.contextInfo() &&
208*c8dee2aaSAndroid Build Coastguard Worker            characterization.contextInfo()->priv().matches(dContext) &&
209*c8dee2aaSAndroid Build Coastguard Worker            characterization.cacheMaxResourceBytes() <= maxResourceBytes &&
210*c8dee2aaSAndroid Build Coastguard Worker            characterization.origin() == readSurfaceView.origin() &&
211*c8dee2aaSAndroid Build Coastguard Worker            characterization.backendFormat() == format &&
212*c8dee2aaSAndroid Build Coastguard Worker            characterization.width() == ii.width() &&
213*c8dee2aaSAndroid Build Coastguard Worker            characterization.height() == ii.height() &&
214*c8dee2aaSAndroid Build Coastguard Worker            characterization.colorType() == ii.colorType() &&
215*c8dee2aaSAndroid Build Coastguard Worker            characterization.sampleCount() == numSamples &&
216*c8dee2aaSAndroid Build Coastguard Worker            SkColorSpace::Equals(characterization.colorSpace(), ii.colorInfo().colorSpace()) &&
217*c8dee2aaSAndroid Build Coastguard Worker            characterization.isProtected() == isProtected &&
218*c8dee2aaSAndroid Build Coastguard Worker            characterization.surfaceProps() == fDevice->surfaceProps();
219*c8dee2aaSAndroid Build Coastguard Worker }
220*c8dee2aaSAndroid Build Coastguard Worker 
221*c8dee2aaSAndroid Build Coastguard Worker #ifndef SK_DDL_IS_UNIQUE_POINTER
draw(sk_sp<const GrDeferredDisplayList> ddl)222*c8dee2aaSAndroid Build Coastguard Worker bool GrVkSecondaryCBDrawContext::draw(sk_sp<const GrDeferredDisplayList> ddl) {
223*c8dee2aaSAndroid Build Coastguard Worker #else
224*c8dee2aaSAndroid Build Coastguard Worker bool GrVkSecondaryCBDrawContext::draw(const GrDeferredDisplayList* ddl) {
225*c8dee2aaSAndroid Build Coastguard Worker #endif
226*c8dee2aaSAndroid Build Coastguard Worker     if (!ddl || !this->isCompatible(ddl->characterization())) {
227*c8dee2aaSAndroid Build Coastguard Worker         return false;
228*c8dee2aaSAndroid Build Coastguard Worker     }
229*c8dee2aaSAndroid Build Coastguard Worker 
230*c8dee2aaSAndroid Build Coastguard Worker     auto direct = fDevice->recordingContext()->asDirectContext();
231*c8dee2aaSAndroid Build Coastguard Worker     if (!direct) {
232*c8dee2aaSAndroid Build Coastguard Worker         return false;
233*c8dee2aaSAndroid Build Coastguard Worker     }
234*c8dee2aaSAndroid Build Coastguard Worker 
235*c8dee2aaSAndroid Build Coastguard Worker     GrSurfaceProxyView readSurfaceView = fDevice->readSurfaceView();
236*c8dee2aaSAndroid Build Coastguard Worker 
237*c8dee2aaSAndroid Build Coastguard Worker     direct->priv().createDDLTask(std::move(ddl), readSurfaceView.asRenderTargetProxyRef());
238*c8dee2aaSAndroid Build Coastguard Worker     return true;
239*c8dee2aaSAndroid Build Coastguard Worker }
240