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