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