xref: /aosp_15_r20/frameworks/native/libs/renderengine/skia/GaneshVkRenderEngine.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2024 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include "GaneshVkRenderEngine.h"
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #undef LOG_TAG
20*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "RenderEngine"
21*38e8c45fSAndroid Build Coastguard Worker 
22*38e8c45fSAndroid Build Coastguard Worker #include <include/gpu/ganesh/vk/GrVkBackendSemaphore.h>
23*38e8c45fSAndroid Build Coastguard Worker 
24*38e8c45fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <common/trace.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <log/log_main.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <sync/sync.h>
28*38e8c45fSAndroid Build Coastguard Worker 
29*38e8c45fSAndroid Build Coastguard Worker namespace android::renderengine::skia {
30*38e8c45fSAndroid Build Coastguard Worker 
31*38e8c45fSAndroid Build Coastguard Worker using base::StringAppendF;
32*38e8c45fSAndroid Build Coastguard Worker 
create(const RenderEngineCreationArgs & args)33*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<GaneshVkRenderEngine> GaneshVkRenderEngine::create(
34*38e8c45fSAndroid Build Coastguard Worker         const RenderEngineCreationArgs& args) {
35*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<GaneshVkRenderEngine> engine(new GaneshVkRenderEngine(args));
36*38e8c45fSAndroid Build Coastguard Worker     engine->ensureContextsCreated();
37*38e8c45fSAndroid Build Coastguard Worker 
38*38e8c45fSAndroid Build Coastguard Worker     if (getVulkanInterface(false).isInitialized()) {
39*38e8c45fSAndroid Build Coastguard Worker         ALOGD("GaneshVkRenderEngine::%s: successfully initialized GaneshVkRenderEngine", __func__);
40*38e8c45fSAndroid Build Coastguard Worker         return engine;
41*38e8c45fSAndroid Build Coastguard Worker     } else {
42*38e8c45fSAndroid Build Coastguard Worker         ALOGE("GaneshVkRenderEngine::%s: could not create GaneshVkRenderEngine. "
43*38e8c45fSAndroid Build Coastguard Worker               "Likely insufficient Vulkan support",
44*38e8c45fSAndroid Build Coastguard Worker               __func__);
45*38e8c45fSAndroid Build Coastguard Worker         return {};
46*38e8c45fSAndroid Build Coastguard Worker     }
47*38e8c45fSAndroid Build Coastguard Worker }
48*38e8c45fSAndroid Build Coastguard Worker 
49*38e8c45fSAndroid Build Coastguard Worker // Ganesh-specific function signature for fFinishedProc callback.
unref_semaphore(void * semaphore)50*38e8c45fSAndroid Build Coastguard Worker static void unref_semaphore(void* semaphore) {
51*38e8c45fSAndroid Build Coastguard Worker     SkiaVkRenderEngine::DestroySemaphoreInfo* info =
52*38e8c45fSAndroid Build Coastguard Worker             reinterpret_cast<SkiaVkRenderEngine::DestroySemaphoreInfo*>(semaphore);
53*38e8c45fSAndroid Build Coastguard Worker     info->unref();
54*38e8c45fSAndroid Build Coastguard Worker }
55*38e8c45fSAndroid Build Coastguard Worker 
createContext(VulkanInterface & vulkanInterface)56*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<SkiaGpuContext> GaneshVkRenderEngine::createContext(
57*38e8c45fSAndroid Build Coastguard Worker         VulkanInterface& vulkanInterface) {
58*38e8c45fSAndroid Build Coastguard Worker     return SkiaGpuContext::MakeVulkan_Ganesh(vulkanInterface.getGaneshBackendContext(),
59*38e8c45fSAndroid Build Coastguard Worker                                              mSkSLCacheMonitor);
60*38e8c45fSAndroid Build Coastguard Worker }
61*38e8c45fSAndroid Build Coastguard Worker 
waitFence(SkiaGpuContext * context,base::borrowed_fd fenceFd)62*38e8c45fSAndroid Build Coastguard Worker void GaneshVkRenderEngine::waitFence(SkiaGpuContext* context, base::borrowed_fd fenceFd) {
63*38e8c45fSAndroid Build Coastguard Worker     if (fenceFd.get() < 0) return;
64*38e8c45fSAndroid Build Coastguard Worker 
65*38e8c45fSAndroid Build Coastguard Worker     const int dupedFd = dup(fenceFd.get());
66*38e8c45fSAndroid Build Coastguard Worker     if (dupedFd < 0) {
67*38e8c45fSAndroid Build Coastguard Worker         ALOGE("failed to create duplicate fence fd: %d", dupedFd);
68*38e8c45fSAndroid Build Coastguard Worker         sync_wait(fenceFd.get(), -1);
69*38e8c45fSAndroid Build Coastguard Worker         return;
70*38e8c45fSAndroid Build Coastguard Worker     }
71*38e8c45fSAndroid Build Coastguard Worker 
72*38e8c45fSAndroid Build Coastguard Worker     base::unique_fd fenceDup(dupedFd);
73*38e8c45fSAndroid Build Coastguard Worker     VkSemaphore waitSemaphore =
74*38e8c45fSAndroid Build Coastguard Worker             getVulkanInterface(isProtected()).importSemaphoreFromSyncFd(fenceDup.release());
75*38e8c45fSAndroid Build Coastguard Worker     GrBackendSemaphore beSemaphore = GrBackendSemaphores::MakeVk(waitSemaphore);
76*38e8c45fSAndroid Build Coastguard Worker     constexpr bool kDeleteAfterWait = true;
77*38e8c45fSAndroid Build Coastguard Worker     context->grDirectContext()->wait(1, &beSemaphore, kDeleteAfterWait);
78*38e8c45fSAndroid Build Coastguard Worker }
79*38e8c45fSAndroid Build Coastguard Worker 
flushAndSubmit(SkiaGpuContext * context,sk_sp<SkSurface> dstSurface)80*38e8c45fSAndroid Build Coastguard Worker base::unique_fd GaneshVkRenderEngine::flushAndSubmit(SkiaGpuContext* context,
81*38e8c45fSAndroid Build Coastguard Worker                                                      sk_sp<SkSurface> dstSurface) {
82*38e8c45fSAndroid Build Coastguard Worker     sk_sp<GrDirectContext> grContext = context->grDirectContext();
83*38e8c45fSAndroid Build Coastguard Worker     {
84*38e8c45fSAndroid Build Coastguard Worker         SFTRACE_NAME("flush surface");
85*38e8c45fSAndroid Build Coastguard Worker         // TODO: Investigate feasibility of combining this "surface flush" into the "context flush"
86*38e8c45fSAndroid Build Coastguard Worker         // below.
87*38e8c45fSAndroid Build Coastguard Worker         context->grDirectContext()->flush(dstSurface.get());
88*38e8c45fSAndroid Build Coastguard Worker     }
89*38e8c45fSAndroid Build Coastguard Worker 
90*38e8c45fSAndroid Build Coastguard Worker     VulkanInterface& vi = getVulkanInterface(isProtected());
91*38e8c45fSAndroid Build Coastguard Worker     VkSemaphore semaphore = vi.createExportableSemaphore();
92*38e8c45fSAndroid Build Coastguard Worker     GrBackendSemaphore backendSemaphore = GrBackendSemaphores::MakeVk(semaphore);
93*38e8c45fSAndroid Build Coastguard Worker 
94*38e8c45fSAndroid Build Coastguard Worker     GrFlushInfo flushInfo;
95*38e8c45fSAndroid Build Coastguard Worker     DestroySemaphoreInfo* destroySemaphoreInfo = nullptr;
96*38e8c45fSAndroid Build Coastguard Worker     if (semaphore != VK_NULL_HANDLE) {
97*38e8c45fSAndroid Build Coastguard Worker         destroySemaphoreInfo = new DestroySemaphoreInfo(vi, semaphore);
98*38e8c45fSAndroid Build Coastguard Worker         flushInfo.fNumSemaphores = 1;
99*38e8c45fSAndroid Build Coastguard Worker         flushInfo.fSignalSemaphores = &backendSemaphore;
100*38e8c45fSAndroid Build Coastguard Worker         flushInfo.fFinishedProc = unref_semaphore;
101*38e8c45fSAndroid Build Coastguard Worker         flushInfo.fFinishedContext = destroySemaphoreInfo;
102*38e8c45fSAndroid Build Coastguard Worker     }
103*38e8c45fSAndroid Build Coastguard Worker     GrSemaphoresSubmitted submitted = grContext->flush(flushInfo);
104*38e8c45fSAndroid Build Coastguard Worker     grContext->submit(GrSyncCpu::kNo);
105*38e8c45fSAndroid Build Coastguard Worker     int drawFenceFd = -1;
106*38e8c45fSAndroid Build Coastguard Worker     if (semaphore != VK_NULL_HANDLE) {
107*38e8c45fSAndroid Build Coastguard Worker         if (GrSemaphoresSubmitted::kYes == submitted) {
108*38e8c45fSAndroid Build Coastguard Worker             drawFenceFd = vi.exportSemaphoreSyncFd(semaphore);
109*38e8c45fSAndroid Build Coastguard Worker         }
110*38e8c45fSAndroid Build Coastguard Worker         // Now that drawFenceFd has been created, we can delete our reference to this semaphore
111*38e8c45fSAndroid Build Coastguard Worker         flushInfo.fFinishedProc(destroySemaphoreInfo);
112*38e8c45fSAndroid Build Coastguard Worker     }
113*38e8c45fSAndroid Build Coastguard Worker     base::unique_fd res(drawFenceFd);
114*38e8c45fSAndroid Build Coastguard Worker     return res;
115*38e8c45fSAndroid Build Coastguard Worker }
116*38e8c45fSAndroid Build Coastguard Worker 
appendBackendSpecificInfoToDump(std::string & result)117*38e8c45fSAndroid Build Coastguard Worker void GaneshVkRenderEngine::appendBackendSpecificInfoToDump(std::string& result) {
118*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&result, "\n ------------RE Vulkan (Ganesh)----------\n");
119*38e8c45fSAndroid Build Coastguard Worker     SkiaVkRenderEngine::appendBackendSpecificInfoToDump(result);
120*38e8c45fSAndroid Build Coastguard Worker }
121*38e8c45fSAndroid Build Coastguard Worker 
122*38e8c45fSAndroid Build Coastguard Worker } // namespace android::renderengine::skia
123