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