blob: cc73f405a688e0101e83808c48eb341af0fa0f58 [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
Nolan Scobiea4814642024-10-30 15:15:00 -040024#include <android-base/stringprintf.h>
Vishnu Nair40d80012024-07-13 23:25:06 +000025#include <common/trace.h>
Nolan Scobie02c160c2024-03-18 10:40:23 -040026#include <log/log_main.h>
27#include <sync/sync.h>
28
29namespace android::renderengine::skia {
30
Nolan Scobiea4814642024-10-30 15:15:00 -040031using base::StringAppendF;
32
Nolan Scobie576e77f2024-03-26 10:59:59 -040033std::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
Nolan Scobie02c160c2024-03-18 10:40:23 -040049// Ganesh-specific function signature for fFinishedProc callback.
50static void unref_semaphore(void* semaphore) {
51 SkiaVkRenderEngine::DestroySemaphoreInfo* info =
52 reinterpret_cast<SkiaVkRenderEngine::DestroySemaphoreInfo*>(semaphore);
53 info->unref();
54}
55
Nolan Scobie342d3942024-03-21 16:41:39 -040056std::unique_ptr<SkiaGpuContext> GaneshVkRenderEngine::createContext(
57 VulkanInterface& vulkanInterface) {
58 return SkiaGpuContext::MakeVulkan_Ganesh(vulkanInterface.getGaneshBackendContext(),
59 mSkSLCacheMonitor);
60}
61
Nolan Scobie02c160c2024-03-18 10:40:23 -040062void 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
Nolan Scobie1e06f2d2024-03-21 14:56:38 -040080base::unique_fd GaneshVkRenderEngine::flushAndSubmit(SkiaGpuContext* context,
81 sk_sp<SkSurface> dstSurface) {
Nolan Scobie02c160c2024-03-18 10:40:23 -040082 sk_sp<GrDirectContext> grContext = context->grDirectContext();
Nolan Scobie1e06f2d2024-03-21 14:56:38 -040083 {
Vishnu Nair40d80012024-07-13 23:25:06 +000084 SFTRACE_NAME("flush surface");
Nolan Scobie1e06f2d2024-03-21 14:56:38 -040085 // TODO: Investigate feasibility of combining this "surface flush" into the "context flush"
86 // below.
87 context->grDirectContext()->flush(dstSurface.get());
88 }
89
Nolan Scobie02c160c2024-03-18 10:40:23 -040090 VulkanInterface& vi = getVulkanInterface(isProtected());
91 VkSemaphore semaphore = vi.createExportableSemaphore();
Nolan Scobie02c160c2024-03-18 10:40:23 -040092 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
Nolan Scobiea4814642024-10-30 15:15:00 -0400117void GaneshVkRenderEngine::appendBackendSpecificInfoToDump(std::string& result) {
118 StringAppendF(&result, "\n ------------RE Vulkan (Ganesh)----------\n");
119 SkiaVkRenderEngine::appendBackendSpecificInfoToDump(result);
120}
121
Nolan Scobie02c160c2024-03-18 10:40:23 -0400122} // namespace android::renderengine::skia