blob: 177abe6c9fc7b8a6513bae156ca435f752d2f344 [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
Nolan Scobie02c160c2024-03-18 10:40:23 -040024#include "GaneshVkRenderEngine.h"
Nolan Scobiefc125ec2024-03-11 20:08:27 -040025#include "compat/SkiaGpuContext.h"
26
Nolan Scobiebc3f3602024-08-30 13:51:37 -040027#include <include/gpu/ganesh/GrBackendSemaphore.h>
28#include <include/gpu/ganesh/GrContextOptions.h>
29#include <include/gpu/ganesh/GrDirectContext.h>
Kevin Lubick9f207082024-03-06 13:33:17 +000030#include <include/gpu/ganesh/vk/GrVkBackendSemaphore.h>
Kevin Lubick2fc49112023-10-13 13:10:48 +000031#include <include/gpu/ganesh/vk/GrVkDirectContext.h>
Nolan Scobiebc3f3602024-08-30 13:51:37 -040032#include <include/gpu/ganesh/vk/GrVkTypes.h>
Ian Elliott1f0911e2022-09-09 16:31:47 -060033
34#include <android-base/stringprintf.h>
Vishnu Nair40d80012024-07-13 23:25:06 +000035#include <common/trace.h>
Ian Elliott1f0911e2022-09-09 16:31:47 -060036#include <sync/sync.h>
Ian Elliott1f0911e2022-09-09 16:31:47 -060037
Ian Elliott1f0911e2022-09-09 16:31:47 -060038#include <memory>
Nolan Scobie0f539a72024-01-29 10:49:10 -050039#include <string>
Ian Elliott1f0911e2022-09-09 16:31:47 -060040
41#include <vulkan/vulkan.h>
42#include "log/log_main.h"
43
44namespace android {
45namespace renderengine {
46
Nolan Scobief52ad202024-03-06 18:18:28 -050047static skia::VulkanInterface sVulkanInterface;
48static skia::VulkanInterface sProtectedContentVulkanInterface;
Ian Elliott1f0911e2022-09-09 16:31:47 -060049
50static void sSetupVulkanInterface() {
Nolan Scobief52ad202024-03-06 18:18:28 -050051 if (!sVulkanInterface.isInitialized()) {
52 sVulkanInterface.init(false /* no protected content */);
Ian Elliott1f0911e2022-09-09 16:31:47 -060053 // We will have to abort if non-protected VkDevice creation fails (then nothing works).
Nolan Scobief52ad202024-03-06 18:18:28 -050054 LOG_ALWAYS_FATAL_IF(!sVulkanInterface.isInitialized(),
Ian Elliott1f0911e2022-09-09 16:31:47 -060055 "Could not initialize Vulkan RenderEngine!");
56 }
Nolan Scobief52ad202024-03-06 18:18:28 -050057 if (!sProtectedContentVulkanInterface.isInitialized()) {
58 sProtectedContentVulkanInterface.init(true /* protected content */);
59 if (!sProtectedContentVulkanInterface.isInitialized()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -060060 ALOGE("Could not initialize protected content Vulkan RenderEngine.");
61 }
62 }
63}
64
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050065bool RenderEngine::canSupport(GraphicsApi graphicsApi) {
66 switch (graphicsApi) {
67 case GraphicsApi::GL:
68 return true;
69 case GraphicsApi::VK: {
Nolan Scobie2526b2f2024-04-16 15:12:22 -040070 // Static local variables are initialized once, on first invocation of the function.
71 static const bool canSupportVulkan = []() {
72 if (!sVulkanInterface.isInitialized()) {
73 sVulkanInterface.init(false /* no protected content */);
74 ALOGD("%s: initialized == %s.", __func__,
75 sVulkanInterface.isInitialized() ? "true" : "false");
76 if (!sVulkanInterface.isInitialized()) {
77 sVulkanInterface.teardown();
78 return false;
79 }
80 }
81 return true;
82 }();
83 return canSupportVulkan;
84 }
85 }
86}
87
88void RenderEngine::teardown(GraphicsApi graphicsApi) {
89 switch (graphicsApi) {
90 case GraphicsApi::GL:
91 break;
92 case GraphicsApi::VK: {
93 if (sVulkanInterface.isInitialized()) {
94 sVulkanInterface.teardown();
95 ALOGD("Tearing down the unprotected VulkanInterface.");
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050096 }
Nolan Scobie2526b2f2024-04-16 15:12:22 -040097 if (sProtectedContentVulkanInterface.isInitialized()) {
98 sProtectedContentVulkanInterface.teardown();
99 ALOGD("Tearing down the protected VulkanInterface.");
100 }
101 break;
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -0500102 }
103 }
104}
105
Ian Elliott1f0911e2022-09-09 16:31:47 -0600106namespace skia {
107
108using base::StringAppendF;
109
Ian Elliott1f0911e2022-09-09 16:31:47 -0600110SkiaVkRenderEngine::SkiaVkRenderEngine(const RenderEngineCreationArgs& args)
Leon Scroggins III696bf932024-01-24 15:21:05 -0500111 : SkiaRenderEngine(args.threaded, static_cast<PixelFormat>(args.pixelFormat),
Robin Lee7338bd92024-04-04 14:05:07 +0000112 args.blurAlgorithm) {}
Ian Elliott1f0911e2022-09-09 16:31:47 -0600113
114SkiaVkRenderEngine::~SkiaVkRenderEngine() {
Nolan Scobie2526b2f2024-04-16 15:12:22 -0400115 finishRenderingAndAbandonContexts();
116 // Teardown VulkanInterfaces after Skia contexts have been abandoned
117 teardown(GraphicsApi::VK);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600118}
119
Nolan Scobiefc125ec2024-03-11 20:08:27 -0400120SkiaRenderEngine::Contexts SkiaVkRenderEngine::createContexts() {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600121 sSetupVulkanInterface();
Nolan Scobie2526b2f2024-04-16 15:12:22 -0400122 // More work would need to be done in order to have multiple RenderEngine instances. In
123 // particular, they would not be able to share the same VulkanInterface(s).
124 LOG_ALWAYS_FATAL_IF(!sVulkanInterface.takeOwnership(),
125 "SkiaVkRenderEngine couldn't take ownership of existing unprotected "
126 "VulkanInterface! Only one SkiaVkRenderEngine instance may exist at a "
127 "time.");
128 if (sProtectedContentVulkanInterface.isInitialized()) {
129 // takeOwnership fails on an uninitialized VulkanInterface, but protected content support is
130 // optional.
131 LOG_ALWAYS_FATAL_IF(!sProtectedContentVulkanInterface.takeOwnership(),
132 "SkiaVkRenderEngine couldn't take ownership of existing protected "
133 "VulkanInterface! Only one SkiaVkRenderEngine instance may exist at a "
134 "time.");
135 }
Ian Elliott1f0911e2022-09-09 16:31:47 -0600136
137 SkiaRenderEngine::Contexts contexts;
Nolan Scobie342d3942024-03-21 16:41:39 -0400138 contexts.first = createContext(sVulkanInterface);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600139 if (supportsProtectedContentImpl()) {
Nolan Scobie342d3942024-03-21 16:41:39 -0400140 contexts.second = createContext(sProtectedContentVulkanInterface);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600141 }
142
143 return contexts;
144}
145
146bool SkiaVkRenderEngine::supportsProtectedContentImpl() const {
Nolan Scobief52ad202024-03-06 18:18:28 -0500147 return sProtectedContentVulkanInterface.isInitialized();
Ian Elliott1f0911e2022-09-09 16:31:47 -0600148}
149
150bool SkiaVkRenderEngine::useProtectedContextImpl(GrProtected) {
151 return true;
152}
153
Nolan Scobie02c160c2024-03-18 10:40:23 -0400154VulkanInterface& SkiaVkRenderEngine::getVulkanInterface(bool protectedContext) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600155 if (protectedContext) {
156 return sProtectedContentVulkanInterface;
157 }
158 return sVulkanInterface;
159}
160
Ian Elliott1f0911e2022-09-09 16:31:47 -0600161int SkiaVkRenderEngine::getContextPriority() {
162 // EGL_CONTEXT_PRIORITY_REALTIME_NV
163 constexpr int kRealtimePriority = 0x3357;
Nolan Scobief52ad202024-03-06 18:18:28 -0500164 if (getVulkanInterface(isProtected()).isRealtimePriority()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600165 return kRealtimePriority;
166 } else {
167 return 0;
168 }
169}
170
171void SkiaVkRenderEngine::appendBackendSpecificInfoToDump(std::string& result) {
Nolan Scobiea4814642024-10-30 15:15:00 -0400172 // Subclasses will prepend a backend-specific name / section header
173 StringAppendF(&result, "Vulkan device initialized: %d\n", sVulkanInterface.isInitialized());
174 StringAppendF(&result, "Vulkan protected device initialized: %d\n",
Nolan Scobief52ad202024-03-06 18:18:28 -0500175 sProtectedContentVulkanInterface.isInitialized());
Ian Elliott1f0911e2022-09-09 16:31:47 -0600176
Nolan Scobief52ad202024-03-06 18:18:28 -0500177 if (!sVulkanInterface.isInitialized()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600178 return;
179 }
180
Nolan Scobiea4814642024-10-30 15:15:00 -0400181 StringAppendF(&result, "Instance extensions: [\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500182 for (const auto& name : sVulkanInterface.getInstanceExtensionNames()) {
Nolan Scobiea4814642024-10-30 15:15:00 -0400183 StringAppendF(&result, " %s\n", name.c_str());
Ian Elliott1f0911e2022-09-09 16:31:47 -0600184 }
Nolan Scobiea4814642024-10-30 15:15:00 -0400185 StringAppendF(&result, "]\n");
Ian Elliott1f0911e2022-09-09 16:31:47 -0600186
Nolan Scobiea4814642024-10-30 15:15:00 -0400187 StringAppendF(&result, "Device extensions: [\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500188 for (const auto& name : sVulkanInterface.getDeviceExtensionNames()) {
Nolan Scobiea4814642024-10-30 15:15:00 -0400189 StringAppendF(&result, " %s\n", name.c_str());
Ian Elliott1f0911e2022-09-09 16:31:47 -0600190 }
Nolan Scobiea4814642024-10-30 15:15:00 -0400191 StringAppendF(&result, "]\n");
Ian Elliott1f0911e2022-09-09 16:31:47 -0600192}
193
194} // namespace skia
195} // namespace renderengine
196} // namespace android