blob: 241ee2cd5057d076f0682973af4a0326bd35c4bb [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 Lubick2fc49112023-10-13 13:10:48 +000028#include <include/gpu/ganesh/vk/GrVkDirectContext.h>
Ian Elliott1f0911e2022-09-09 16:31:47 -060029
30#include <android-base/stringprintf.h>
31#include <gui/TraceUtils.h>
32#include <sync/sync.h>
33#include <utils/Trace.h>
34
Ian Elliott1f0911e2022-09-09 16:31:47 -060035#include <memory>
Nolan Scobie0f539a72024-01-29 10:49:10 -050036#include <string>
Ian Elliott1f0911e2022-09-09 16:31:47 -060037
38#include <vulkan/vulkan.h>
39#include "log/log_main.h"
40
41namespace android {
42namespace renderengine {
43
Nolan Scobief52ad202024-03-06 18:18:28 -050044static skia::VulkanInterface sVulkanInterface;
45static skia::VulkanInterface sProtectedContentVulkanInterface;
Ian Elliott1f0911e2022-09-09 16:31:47 -060046
47static void sSetupVulkanInterface() {
Nolan Scobief52ad202024-03-06 18:18:28 -050048 if (!sVulkanInterface.isInitialized()) {
49 sVulkanInterface.init(false /* no protected content */);
Ian Elliott1f0911e2022-09-09 16:31:47 -060050 // We will have to abort if non-protected VkDevice creation fails (then nothing works).
Nolan Scobief52ad202024-03-06 18:18:28 -050051 LOG_ALWAYS_FATAL_IF(!sVulkanInterface.isInitialized(),
Ian Elliott1f0911e2022-09-09 16:31:47 -060052 "Could not initialize Vulkan RenderEngine!");
53 }
Nolan Scobief52ad202024-03-06 18:18:28 -050054 if (!sProtectedContentVulkanInterface.isInitialized()) {
55 sProtectedContentVulkanInterface.init(true /* protected content */);
56 if (!sProtectedContentVulkanInterface.isInitialized()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -060057 ALOGE("Could not initialize protected content Vulkan RenderEngine.");
58 }
59 }
60}
61
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050062bool RenderEngine::canSupport(GraphicsApi graphicsApi) {
63 switch (graphicsApi) {
64 case GraphicsApi::GL:
65 return true;
66 case GraphicsApi::VK: {
Nolan Scobief52ad202024-03-06 18:18:28 -050067 if (!sVulkanInterface.isInitialized()) {
68 sVulkanInterface.init(false /* no protected content */);
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050069 ALOGD("%s: initialized == %s.", __func__,
Nolan Scobief52ad202024-03-06 18:18:28 -050070 sVulkanInterface.isInitialized() ? "true" : "false");
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050071 }
Nolan Scobief52ad202024-03-06 18:18:28 -050072 return sVulkanInterface.isInitialized();
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050073 }
74 }
75}
76
Ian Elliott1f0911e2022-09-09 16:31:47 -060077namespace skia {
78
79using base::StringAppendF;
80
Ian Elliott1f0911e2022-09-09 16:31:47 -060081std::unique_ptr<SkiaVkRenderEngine> SkiaVkRenderEngine::create(
82 const RenderEngineCreationArgs& args) {
83 std::unique_ptr<SkiaVkRenderEngine> engine(new SkiaVkRenderEngine(args));
84 engine->ensureGrContextsCreated();
85
Nolan Scobief52ad202024-03-06 18:18:28 -050086 if (sVulkanInterface.isInitialized()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -060087 ALOGD("SkiaVkRenderEngine::%s: successfully initialized SkiaVkRenderEngine", __func__);
88 return engine;
89 } else {
90 ALOGD("SkiaVkRenderEngine::%s: could not create SkiaVkRenderEngine. "
91 "Likely insufficient Vulkan support",
92 __func__);
93 return {};
94 }
95}
96
97SkiaVkRenderEngine::SkiaVkRenderEngine(const RenderEngineCreationArgs& args)
Leon Scroggins III696bf932024-01-24 15:21:05 -050098 : SkiaRenderEngine(args.threaded, static_cast<PixelFormat>(args.pixelFormat),
Alec Mouri47bcb072023-08-15 02:02:49 +000099 args.supportsBackgroundBlur) {}
Ian Elliott1f0911e2022-09-09 16:31:47 -0600100
101SkiaVkRenderEngine::~SkiaVkRenderEngine() {
102 finishRenderingAndAbandonContext();
103}
104
105SkiaRenderEngine::Contexts SkiaVkRenderEngine::createDirectContexts(
106 const GrContextOptions& options) {
107 sSetupVulkanInterface();
108
109 SkiaRenderEngine::Contexts contexts;
Kevin Lubick2fc49112023-10-13 13:10:48 +0000110 contexts.first = GrDirectContexts::MakeVulkan(sVulkanInterface.getBackendContext(), options);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600111 if (supportsProtectedContentImpl()) {
112 contexts.second =
Kevin Lubick2fc49112023-10-13 13:10:48 +0000113 GrDirectContexts::MakeVulkan(sProtectedContentVulkanInterface.getBackendContext(),
114 options);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600115 }
116
117 return contexts;
118}
119
120bool SkiaVkRenderEngine::supportsProtectedContentImpl() const {
Nolan Scobief52ad202024-03-06 18:18:28 -0500121 return sProtectedContentVulkanInterface.isInitialized();
Ian Elliott1f0911e2022-09-09 16:31:47 -0600122}
123
124bool SkiaVkRenderEngine::useProtectedContextImpl(GrProtected) {
125 return true;
126}
127
Nolan Scobief52ad202024-03-06 18:18:28 -0500128static void unref_semaphore(void* semaphore) {
129 SkiaVkRenderEngine::DestroySemaphoreInfo* info =
130 reinterpret_cast<SkiaVkRenderEngine::DestroySemaphoreInfo*>(semaphore);
131 info->unref();
Ian Elliott1f0911e2022-09-09 16:31:47 -0600132}
133
134static VulkanInterface& getVulkanInterface(bool protectedContext) {
135 if (protectedContext) {
136 return sProtectedContentVulkanInterface;
137 }
138 return sVulkanInterface;
139}
140
141void SkiaVkRenderEngine::waitFence(GrDirectContext* grContext, base::borrowed_fd fenceFd) {
142 if (fenceFd.get() < 0) return;
143
144 int dupedFd = dup(fenceFd.get());
145 if (dupedFd < 0) {
146 ALOGE("failed to create duplicate fence fd: %d", dupedFd);
147 sync_wait(fenceFd.get(), -1);
148 return;
149 }
150
151 base::unique_fd fenceDup(dupedFd);
152 VkSemaphore waitSemaphore =
153 getVulkanInterface(isProtected()).importSemaphoreFromSyncFd(fenceDup.release());
154 GrBackendSemaphore beSemaphore;
155 beSemaphore.initVulkan(waitSemaphore);
156 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
163 GrBackendSemaphore backendSemaphore;
164 backendSemaphore.initVulkan(semaphore);
165
Ian Elliott1f0911e2022-09-09 16:31:47 -0600166 GrFlushInfo flushInfo;
Ian Elliott98e87162023-04-14 14:05:19 -0600167 DestroySemaphoreInfo* destroySemaphoreInfo = nullptr;
168 if (semaphore != VK_NULL_HANDLE) {
Nolan Scobief52ad202024-03-06 18:18:28 -0500169 destroySemaphoreInfo = new DestroySemaphoreInfo(vi, semaphore);
Ian Elliott98e87162023-04-14 14:05:19 -0600170 flushInfo.fNumSemaphores = 1;
171 flushInfo.fSignalSemaphores = &backendSemaphore;
Nolan Scobief52ad202024-03-06 18:18:28 -0500172 flushInfo.fFinishedProc = unref_semaphore;
Ian Elliott98e87162023-04-14 14:05:19 -0600173 flushInfo.fFinishedContext = destroySemaphoreInfo;
174 }
Ian Elliott1f0911e2022-09-09 16:31:47 -0600175 GrSemaphoresSubmitted submitted = grContext->flush(flushInfo);
Kevin Lubicka0efc342023-09-20 13:11:52 +0000176 grContext->submit(GrSyncCpu::kNo);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600177 int drawFenceFd = -1;
Ian Elliott98e87162023-04-14 14:05:19 -0600178 if (semaphore != VK_NULL_HANDLE) {
179 if (GrSemaphoresSubmitted::kYes == submitted) {
180 drawFenceFd = vi.exportSemaphoreSyncFd(semaphore);
181 }
182 // Now that drawFenceFd has been created, we can delete our reference to this semaphore
183 flushInfo.fFinishedProc(destroySemaphoreInfo);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600184 }
185 base::unique_fd res(drawFenceFd);
186 return res;
187}
188
189int SkiaVkRenderEngine::getContextPriority() {
190 // EGL_CONTEXT_PRIORITY_REALTIME_NV
191 constexpr int kRealtimePriority = 0x3357;
Nolan Scobief52ad202024-03-06 18:18:28 -0500192 if (getVulkanInterface(isProtected()).isRealtimePriority()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600193 return kRealtimePriority;
194 } else {
195 return 0;
196 }
197}
198
199void SkiaVkRenderEngine::appendBackendSpecificInfoToDump(std::string& result) {
200 StringAppendF(&result, "\n ------------RE Vulkan----------\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500201 StringAppendF(&result, "\n Vulkan device initialized: %d\n", sVulkanInterface.isInitialized());
Ian Elliott1f0911e2022-09-09 16:31:47 -0600202 StringAppendF(&result, "\n Vulkan protected device initialized: %d\n",
Nolan Scobief52ad202024-03-06 18:18:28 -0500203 sProtectedContentVulkanInterface.isInitialized());
Ian Elliott1f0911e2022-09-09 16:31:47 -0600204
Nolan Scobief52ad202024-03-06 18:18:28 -0500205 if (!sVulkanInterface.isInitialized()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600206 return;
207 }
208
209 StringAppendF(&result, "\n Instance extensions:\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500210 for (const auto& name : sVulkanInterface.getInstanceExtensionNames()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600211 StringAppendF(&result, "\n %s\n", name.c_str());
212 }
213
214 StringAppendF(&result, "\n Device extensions:\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500215 for (const auto& name : sVulkanInterface.getDeviceExtensionNames()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600216 StringAppendF(&result, "\n %s\n", name.c_str());
217 }
218}
219
220} // namespace skia
221} // namespace renderengine
222} // namespace android