blob: a3a43e20be4f800bf72a54350aecb6706f6d5b40 [file] [log] [blame]
Nolan Scobie02c160c2024-03-18 10:40:23 -04001/*
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
Vishnu Nair40d80012024-07-13 23:25:06 +000024#include <common/trace.h>
Nolan Scobie02c160c2024-03-18 10:40:23 -040025#include <log/log_main.h>
26#include <sync/sync.h>
27
28namespace android::renderengine::skia {
29
Nolan Scobie576e77f2024-03-26 10:59:59 -040030std::unique_ptr<GaneshVkRenderEngine> GaneshVkRenderEngine::create(
31 const RenderEngineCreationArgs& args) {
32 std::unique_ptr<GaneshVkRenderEngine> engine(new GaneshVkRenderEngine(args));
33 engine->ensureContextsCreated();
34
35 if (getVulkanInterface(false).isInitialized()) {
36 ALOGD("GaneshVkRenderEngine::%s: successfully initialized GaneshVkRenderEngine", __func__);
37 return engine;
38 } else {
39 ALOGE("GaneshVkRenderEngine::%s: could not create GaneshVkRenderEngine. "
40 "Likely insufficient Vulkan support",
41 __func__);
42 return {};
43 }
44}
45
Nolan Scobie02c160c2024-03-18 10:40:23 -040046// Ganesh-specific function signature for fFinishedProc callback.
47static void unref_semaphore(void* semaphore) {
48 SkiaVkRenderEngine::DestroySemaphoreInfo* info =
49 reinterpret_cast<SkiaVkRenderEngine::DestroySemaphoreInfo*>(semaphore);
50 info->unref();
51}
52
Nolan Scobie342d3942024-03-21 16:41:39 -040053std::unique_ptr<SkiaGpuContext> GaneshVkRenderEngine::createContext(
54 VulkanInterface& vulkanInterface) {
55 return SkiaGpuContext::MakeVulkan_Ganesh(vulkanInterface.getGaneshBackendContext(),
56 mSkSLCacheMonitor);
57}
58
Nolan Scobie02c160c2024-03-18 10:40:23 -040059void GaneshVkRenderEngine::waitFence(SkiaGpuContext* context, base::borrowed_fd fenceFd) {
60 if (fenceFd.get() < 0) return;
61
62 const int dupedFd = dup(fenceFd.get());
63 if (dupedFd < 0) {
64 ALOGE("failed to create duplicate fence fd: %d", dupedFd);
65 sync_wait(fenceFd.get(), -1);
66 return;
67 }
68
69 base::unique_fd fenceDup(dupedFd);
70 VkSemaphore waitSemaphore =
71 getVulkanInterface(isProtected()).importSemaphoreFromSyncFd(fenceDup.release());
72 GrBackendSemaphore beSemaphore = GrBackendSemaphores::MakeVk(waitSemaphore);
73 constexpr bool kDeleteAfterWait = true;
74 context->grDirectContext()->wait(1, &beSemaphore, kDeleteAfterWait);
75}
76
Nolan Scobie1e06f2d2024-03-21 14:56:38 -040077base::unique_fd GaneshVkRenderEngine::flushAndSubmit(SkiaGpuContext* context,
78 sk_sp<SkSurface> dstSurface) {
Nolan Scobie02c160c2024-03-18 10:40:23 -040079 sk_sp<GrDirectContext> grContext = context->grDirectContext();
Nolan Scobie1e06f2d2024-03-21 14:56:38 -040080 {
Vishnu Nair40d80012024-07-13 23:25:06 +000081 SFTRACE_NAME("flush surface");
Nolan Scobie1e06f2d2024-03-21 14:56:38 -040082 // TODO: Investigate feasibility of combining this "surface flush" into the "context flush"
83 // below.
84 context->grDirectContext()->flush(dstSurface.get());
85 }
86
Nolan Scobie02c160c2024-03-18 10:40:23 -040087 VulkanInterface& vi = getVulkanInterface(isProtected());
88 VkSemaphore semaphore = vi.createExportableSemaphore();
Nolan Scobie02c160c2024-03-18 10:40:23 -040089 GrBackendSemaphore backendSemaphore = GrBackendSemaphores::MakeVk(semaphore);
90
91 GrFlushInfo flushInfo;
92 DestroySemaphoreInfo* destroySemaphoreInfo = nullptr;
93 if (semaphore != VK_NULL_HANDLE) {
94 destroySemaphoreInfo = new DestroySemaphoreInfo(vi, semaphore);
95 flushInfo.fNumSemaphores = 1;
96 flushInfo.fSignalSemaphores = &backendSemaphore;
97 flushInfo.fFinishedProc = unref_semaphore;
98 flushInfo.fFinishedContext = destroySemaphoreInfo;
99 }
100 GrSemaphoresSubmitted submitted = grContext->flush(flushInfo);
101 grContext->submit(GrSyncCpu::kNo);
102 int drawFenceFd = -1;
103 if (semaphore != VK_NULL_HANDLE) {
104 if (GrSemaphoresSubmitted::kYes == submitted) {
105 drawFenceFd = vi.exportSemaphoreSyncFd(semaphore);
106 }
107 // Now that drawFenceFd has been created, we can delete our reference to this semaphore
108 flushInfo.fFinishedProc(destroySemaphoreInfo);
109 }
110 base::unique_fd res(drawFenceFd);
111 return res;
112}
113
114} // namespace android::renderengine::skia