blob: f2f1b5d0cafb97da5181b379af4c6a460ec9f847 [file] [log] [blame]
Ian Elliott1f0911e2022-09-09 16:31:47 -06001/*
2 * Copyright 2022 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// #define LOG_NDEBUG 0
18#undef LOG_TAG
19#define LOG_TAG "RenderEngine"
20#define ATRACE_TAG ATRACE_TAG_GRAPHICS
21
22#include "SkiaVkRenderEngine.h"
23
24#include <GrBackendSemaphore.h>
25#include <GrContextOptions.h>
26#include <vk/GrVkExtensions.h>
27#include <vk/GrVkTypes.h>
Kevin Lubick9f207082024-03-06 13:33:17 +000028#include <include/gpu/ganesh/vk/GrVkBackendSemaphore.h>
Kevin Lubick2fc49112023-10-13 13:10:48 +000029#include <include/gpu/ganesh/vk/GrVkDirectContext.h>
Ian Elliott1f0911e2022-09-09 16:31:47 -060030
31#include <android-base/stringprintf.h>
32#include <gui/TraceUtils.h>
33#include <sync/sync.h>
34#include <utils/Trace.h>
35
Ian Elliott1f0911e2022-09-09 16:31:47 -060036#include <memory>
Nolan Scobie0f539a72024-01-29 10:49:10 -050037#include <string>
Ian Elliott1f0911e2022-09-09 16:31:47 -060038
39#include <vulkan/vulkan.h>
40#include "log/log_main.h"
41
42namespace android {
43namespace renderengine {
44
Nolan Scobief52ad202024-03-06 18:18:28 -050045static skia::VulkanInterface sVulkanInterface;
46static skia::VulkanInterface sProtectedContentVulkanInterface;
Ian Elliott1f0911e2022-09-09 16:31:47 -060047
48static void sSetupVulkanInterface() {
Nolan Scobief52ad202024-03-06 18:18:28 -050049 if (!sVulkanInterface.isInitialized()) {
50 sVulkanInterface.init(false /* no protected content */);
Ian Elliott1f0911e2022-09-09 16:31:47 -060051 // We will have to abort if non-protected VkDevice creation fails (then nothing works).
Nolan Scobief52ad202024-03-06 18:18:28 -050052 LOG_ALWAYS_FATAL_IF(!sVulkanInterface.isInitialized(),
Ian Elliott1f0911e2022-09-09 16:31:47 -060053 "Could not initialize Vulkan RenderEngine!");
54 }
Nolan Scobief52ad202024-03-06 18:18:28 -050055 if (!sProtectedContentVulkanInterface.isInitialized()) {
56 sProtectedContentVulkanInterface.init(true /* protected content */);
57 if (!sProtectedContentVulkanInterface.isInitialized()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -060058 ALOGE("Could not initialize protected content Vulkan RenderEngine.");
59 }
60 }
61}
62
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050063bool RenderEngine::canSupport(GraphicsApi graphicsApi) {
64 switch (graphicsApi) {
65 case GraphicsApi::GL:
66 return true;
67 case GraphicsApi::VK: {
Nolan Scobief52ad202024-03-06 18:18:28 -050068 if (!sVulkanInterface.isInitialized()) {
69 sVulkanInterface.init(false /* no protected content */);
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050070 ALOGD("%s: initialized == %s.", __func__,
Nolan Scobief52ad202024-03-06 18:18:28 -050071 sVulkanInterface.isInitialized() ? "true" : "false");
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050072 }
Nolan Scobief52ad202024-03-06 18:18:28 -050073 return sVulkanInterface.isInitialized();
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050074 }
75 }
76}
77
Ian Elliott1f0911e2022-09-09 16:31:47 -060078namespace skia {
79
80using base::StringAppendF;
81
Ian Elliott1f0911e2022-09-09 16:31:47 -060082std::unique_ptr<SkiaVkRenderEngine> SkiaVkRenderEngine::create(
83 const RenderEngineCreationArgs& args) {
84 std::unique_ptr<SkiaVkRenderEngine> engine(new SkiaVkRenderEngine(args));
85 engine->ensureGrContextsCreated();
86
Nolan Scobief52ad202024-03-06 18:18:28 -050087 if (sVulkanInterface.isInitialized()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -060088 ALOGD("SkiaVkRenderEngine::%s: successfully initialized SkiaVkRenderEngine", __func__);
89 return engine;
90 } else {
91 ALOGD("SkiaVkRenderEngine::%s: could not create SkiaVkRenderEngine. "
92 "Likely insufficient Vulkan support",
93 __func__);
94 return {};
95 }
96}
97
98SkiaVkRenderEngine::SkiaVkRenderEngine(const RenderEngineCreationArgs& args)
Leon Scroggins III696bf932024-01-24 15:21:05 -050099 : SkiaRenderEngine(args.threaded, static_cast<PixelFormat>(args.pixelFormat),
Alec Mouri47bcb072023-08-15 02:02:49 +0000100 args.supportsBackgroundBlur) {}
Ian Elliott1f0911e2022-09-09 16:31:47 -0600101
102SkiaVkRenderEngine::~SkiaVkRenderEngine() {
103 finishRenderingAndAbandonContext();
104}
105
106SkiaRenderEngine::Contexts SkiaVkRenderEngine::createDirectContexts(
107 const GrContextOptions& options) {
108 sSetupVulkanInterface();
109
110 SkiaRenderEngine::Contexts contexts;
Kevin Lubick2fc49112023-10-13 13:10:48 +0000111 contexts.first = GrDirectContexts::MakeVulkan(sVulkanInterface.getBackendContext(), options);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600112 if (supportsProtectedContentImpl()) {
113 contexts.second =
Kevin Lubick2fc49112023-10-13 13:10:48 +0000114 GrDirectContexts::MakeVulkan(sProtectedContentVulkanInterface.getBackendContext(),
115 options);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600116 }
117
118 return contexts;
119}
120
121bool SkiaVkRenderEngine::supportsProtectedContentImpl() const {
Nolan Scobief52ad202024-03-06 18:18:28 -0500122 return sProtectedContentVulkanInterface.isInitialized();
Ian Elliott1f0911e2022-09-09 16:31:47 -0600123}
124
125bool SkiaVkRenderEngine::useProtectedContextImpl(GrProtected) {
126 return true;
127}
128
Nolan Scobief52ad202024-03-06 18:18:28 -0500129static void unref_semaphore(void* semaphore) {
130 SkiaVkRenderEngine::DestroySemaphoreInfo* info =
131 reinterpret_cast<SkiaVkRenderEngine::DestroySemaphoreInfo*>(semaphore);
132 info->unref();
Ian Elliott1f0911e2022-09-09 16:31:47 -0600133}
134
135static VulkanInterface& getVulkanInterface(bool protectedContext) {
136 if (protectedContext) {
137 return sProtectedContentVulkanInterface;
138 }
139 return sVulkanInterface;
140}
141
142void SkiaVkRenderEngine::waitFence(GrDirectContext* grContext, base::borrowed_fd fenceFd) {
143 if (fenceFd.get() < 0) return;
144
145 int dupedFd = dup(fenceFd.get());
146 if (dupedFd < 0) {
147 ALOGE("failed to create duplicate fence fd: %d", dupedFd);
148 sync_wait(fenceFd.get(), -1);
149 return;
150 }
151
152 base::unique_fd fenceDup(dupedFd);
153 VkSemaphore waitSemaphore =
154 getVulkanInterface(isProtected()).importSemaphoreFromSyncFd(fenceDup.release());
Kevin Lubick9f207082024-03-06 13:33:17 +0000155 GrBackendSemaphore beSemaphore = GrBackendSemaphores::MakeVk(waitSemaphore);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600156 grContext->wait(1, &beSemaphore, true /* delete after wait */);
157}
158
159base::unique_fd SkiaVkRenderEngine::flushAndSubmit(GrDirectContext* grContext) {
Ian Elliott98e87162023-04-14 14:05:19 -0600160 VulkanInterface& vi = getVulkanInterface(isProtected());
161 VkSemaphore semaphore = vi.createExportableSemaphore();
162
Kevin Lubick9f207082024-03-06 13:33:17 +0000163 GrBackendSemaphore backendSemaphore = GrBackendSemaphores::MakeVk(semaphore);
Ian Elliott98e87162023-04-14 14:05:19 -0600164
Ian Elliott1f0911e2022-09-09 16:31:47 -0600165 GrFlushInfo flushInfo;
Ian Elliott98e87162023-04-14 14:05:19 -0600166 DestroySemaphoreInfo* destroySemaphoreInfo = nullptr;
167 if (semaphore != VK_NULL_HANDLE) {
Nolan Scobief52ad202024-03-06 18:18:28 -0500168 destroySemaphoreInfo = new DestroySemaphoreInfo(vi, semaphore);
Ian Elliott98e87162023-04-14 14:05:19 -0600169 flushInfo.fNumSemaphores = 1;
170 flushInfo.fSignalSemaphores = &backendSemaphore;
Nolan Scobief52ad202024-03-06 18:18:28 -0500171 flushInfo.fFinishedProc = unref_semaphore;
Ian Elliott98e87162023-04-14 14:05:19 -0600172 flushInfo.fFinishedContext = destroySemaphoreInfo;
173 }
Ian Elliott1f0911e2022-09-09 16:31:47 -0600174 GrSemaphoresSubmitted submitted = grContext->flush(flushInfo);
Kevin Lubicka0efc342023-09-20 13:11:52 +0000175 grContext->submit(GrSyncCpu::kNo);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600176 int drawFenceFd = -1;
Ian Elliott98e87162023-04-14 14:05:19 -0600177 if (semaphore != VK_NULL_HANDLE) {
178 if (GrSemaphoresSubmitted::kYes == submitted) {
179 drawFenceFd = vi.exportSemaphoreSyncFd(semaphore);
180 }
181 // Now that drawFenceFd has been created, we can delete our reference to this semaphore
182 flushInfo.fFinishedProc(destroySemaphoreInfo);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600183 }
184 base::unique_fd res(drawFenceFd);
185 return res;
186}
187
188int SkiaVkRenderEngine::getContextPriority() {
189 // EGL_CONTEXT_PRIORITY_REALTIME_NV
190 constexpr int kRealtimePriority = 0x3357;
Nolan Scobief52ad202024-03-06 18:18:28 -0500191 if (getVulkanInterface(isProtected()).isRealtimePriority()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600192 return kRealtimePriority;
193 } else {
194 return 0;
195 }
196}
197
198void SkiaVkRenderEngine::appendBackendSpecificInfoToDump(std::string& result) {
199 StringAppendF(&result, "\n ------------RE Vulkan----------\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500200 StringAppendF(&result, "\n Vulkan device initialized: %d\n", sVulkanInterface.isInitialized());
Ian Elliott1f0911e2022-09-09 16:31:47 -0600201 StringAppendF(&result, "\n Vulkan protected device initialized: %d\n",
Nolan Scobief52ad202024-03-06 18:18:28 -0500202 sProtectedContentVulkanInterface.isInitialized());
Ian Elliott1f0911e2022-09-09 16:31:47 -0600203
Nolan Scobief52ad202024-03-06 18:18:28 -0500204 if (!sVulkanInterface.isInitialized()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600205 return;
206 }
207
208 StringAppendF(&result, "\n Instance extensions:\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500209 for (const auto& name : sVulkanInterface.getInstanceExtensionNames()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600210 StringAppendF(&result, "\n %s\n", name.c_str());
211 }
212
213 StringAppendF(&result, "\n Device extensions:\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500214 for (const auto& name : sVulkanInterface.getDeviceExtensionNames()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600215 StringAppendF(&result, "\n %s\n", name.c_str());
216 }
217}
218
219} // namespace skia
220} // namespace renderengine
221} // namespace android