blob: a1f917dc0315e4baf6bf6c6c4ee0c3fa8b71c1dc [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
Ian Elliott1f0911e2022-09-09 16:31:47 -060027#include <GrBackendSemaphore.h>
28#include <GrContextOptions.h>
Nolan Scobiefc125ec2024-03-11 20:08:27 -040029#include <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 Scobiefc125ec2024-03-11 20:08:27 -040032#include <vk/GrVkTypes.h>
Ian Elliott1f0911e2022-09-09 16:31:47 -060033
34#include <android-base/stringprintf.h>
35#include <gui/TraceUtils.h>
36#include <sync/sync.h>
37#include <utils/Trace.h>
38
Ian Elliott1f0911e2022-09-09 16:31:47 -060039#include <memory>
Nolan Scobie0f539a72024-01-29 10:49:10 -050040#include <string>
Ian Elliott1f0911e2022-09-09 16:31:47 -060041
42#include <vulkan/vulkan.h>
43#include "log/log_main.h"
44
45namespace android {
46namespace renderengine {
47
Nolan Scobief52ad202024-03-06 18:18:28 -050048static skia::VulkanInterface sVulkanInterface;
49static skia::VulkanInterface sProtectedContentVulkanInterface;
Ian Elliott1f0911e2022-09-09 16:31:47 -060050
51static void sSetupVulkanInterface() {
Nolan Scobief52ad202024-03-06 18:18:28 -050052 if (!sVulkanInterface.isInitialized()) {
53 sVulkanInterface.init(false /* no protected content */);
Ian Elliott1f0911e2022-09-09 16:31:47 -060054 // We will have to abort if non-protected VkDevice creation fails (then nothing works).
Nolan Scobief52ad202024-03-06 18:18:28 -050055 LOG_ALWAYS_FATAL_IF(!sVulkanInterface.isInitialized(),
Ian Elliott1f0911e2022-09-09 16:31:47 -060056 "Could not initialize Vulkan RenderEngine!");
57 }
Nolan Scobief52ad202024-03-06 18:18:28 -050058 if (!sProtectedContentVulkanInterface.isInitialized()) {
59 sProtectedContentVulkanInterface.init(true /* protected content */);
60 if (!sProtectedContentVulkanInterface.isInitialized()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -060061 ALOGE("Could not initialize protected content Vulkan RenderEngine.");
62 }
63 }
64}
65
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050066bool RenderEngine::canSupport(GraphicsApi graphicsApi) {
67 switch (graphicsApi) {
68 case GraphicsApi::GL:
69 return true;
70 case GraphicsApi::VK: {
Nolan Scobie2526b2f2024-04-16 15:12:22 -040071 // Static local variables are initialized once, on first invocation of the function.
72 static const bool canSupportVulkan = []() {
73 if (!sVulkanInterface.isInitialized()) {
74 sVulkanInterface.init(false /* no protected content */);
75 ALOGD("%s: initialized == %s.", __func__,
76 sVulkanInterface.isInitialized() ? "true" : "false");
77 if (!sVulkanInterface.isInitialized()) {
78 sVulkanInterface.teardown();
79 return false;
80 }
81 }
82 return true;
83 }();
84 return canSupportVulkan;
85 }
86 }
87}
88
89void RenderEngine::teardown(GraphicsApi graphicsApi) {
90 switch (graphicsApi) {
91 case GraphicsApi::GL:
92 break;
93 case GraphicsApi::VK: {
94 if (sVulkanInterface.isInitialized()) {
95 sVulkanInterface.teardown();
96 ALOGD("Tearing down the unprotected VulkanInterface.");
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050097 }
Nolan Scobie2526b2f2024-04-16 15:12:22 -040098 if (sProtectedContentVulkanInterface.isInitialized()) {
99 sProtectedContentVulkanInterface.teardown();
100 ALOGD("Tearing down the protected VulkanInterface.");
101 }
102 break;
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -0500103 }
104 }
105}
106
Ian Elliott1f0911e2022-09-09 16:31:47 -0600107namespace skia {
108
109using base::StringAppendF;
110
Ian Elliott1f0911e2022-09-09 16:31:47 -0600111SkiaVkRenderEngine::SkiaVkRenderEngine(const RenderEngineCreationArgs& args)
Leon Scroggins III696bf932024-01-24 15:21:05 -0500112 : SkiaRenderEngine(args.threaded, static_cast<PixelFormat>(args.pixelFormat),
Robin Lee7338bd92024-04-04 14:05:07 +0000113 args.blurAlgorithm) {}
Ian Elliott1f0911e2022-09-09 16:31:47 -0600114
115SkiaVkRenderEngine::~SkiaVkRenderEngine() {
Nolan Scobie2526b2f2024-04-16 15:12:22 -0400116 finishRenderingAndAbandonContexts();
117 // Teardown VulkanInterfaces after Skia contexts have been abandoned
118 teardown(GraphicsApi::VK);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600119}
120
Nolan Scobiefc125ec2024-03-11 20:08:27 -0400121SkiaRenderEngine::Contexts SkiaVkRenderEngine::createContexts() {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600122 sSetupVulkanInterface();
Nolan Scobie2526b2f2024-04-16 15:12:22 -0400123 // More work would need to be done in order to have multiple RenderEngine instances. In
124 // particular, they would not be able to share the same VulkanInterface(s).
125 LOG_ALWAYS_FATAL_IF(!sVulkanInterface.takeOwnership(),
126 "SkiaVkRenderEngine couldn't take ownership of existing unprotected "
127 "VulkanInterface! Only one SkiaVkRenderEngine instance may exist at a "
128 "time.");
129 if (sProtectedContentVulkanInterface.isInitialized()) {
130 // takeOwnership fails on an uninitialized VulkanInterface, but protected content support is
131 // optional.
132 LOG_ALWAYS_FATAL_IF(!sProtectedContentVulkanInterface.takeOwnership(),
133 "SkiaVkRenderEngine couldn't take ownership of existing protected "
134 "VulkanInterface! Only one SkiaVkRenderEngine instance may exist at a "
135 "time.");
136 }
Ian Elliott1f0911e2022-09-09 16:31:47 -0600137
138 SkiaRenderEngine::Contexts contexts;
Nolan Scobie342d3942024-03-21 16:41:39 -0400139 contexts.first = createContext(sVulkanInterface);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600140 if (supportsProtectedContentImpl()) {
Nolan Scobie342d3942024-03-21 16:41:39 -0400141 contexts.second = createContext(sProtectedContentVulkanInterface);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600142 }
143
144 return contexts;
145}
146
147bool SkiaVkRenderEngine::supportsProtectedContentImpl() const {
Nolan Scobief52ad202024-03-06 18:18:28 -0500148 return sProtectedContentVulkanInterface.isInitialized();
Ian Elliott1f0911e2022-09-09 16:31:47 -0600149}
150
151bool SkiaVkRenderEngine::useProtectedContextImpl(GrProtected) {
152 return true;
153}
154
Nolan Scobie02c160c2024-03-18 10:40:23 -0400155VulkanInterface& SkiaVkRenderEngine::getVulkanInterface(bool protectedContext) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600156 if (protectedContext) {
157 return sProtectedContentVulkanInterface;
158 }
159 return sVulkanInterface;
160}
161
Ian Elliott1f0911e2022-09-09 16:31:47 -0600162int SkiaVkRenderEngine::getContextPriority() {
163 // EGL_CONTEXT_PRIORITY_REALTIME_NV
164 constexpr int kRealtimePriority = 0x3357;
Nolan Scobief52ad202024-03-06 18:18:28 -0500165 if (getVulkanInterface(isProtected()).isRealtimePriority()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600166 return kRealtimePriority;
167 } else {
168 return 0;
169 }
170}
171
172void SkiaVkRenderEngine::appendBackendSpecificInfoToDump(std::string& result) {
173 StringAppendF(&result, "\n ------------RE Vulkan----------\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500174 StringAppendF(&result, "\n Vulkan device initialized: %d\n", sVulkanInterface.isInitialized());
Ian Elliott1f0911e2022-09-09 16:31:47 -0600175 StringAppendF(&result, "\n Vulkan protected device initialized: %d\n",
Nolan Scobief52ad202024-03-06 18:18:28 -0500176 sProtectedContentVulkanInterface.isInitialized());
Ian Elliott1f0911e2022-09-09 16:31:47 -0600177
Nolan Scobief52ad202024-03-06 18:18:28 -0500178 if (!sVulkanInterface.isInitialized()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600179 return;
180 }
181
182 StringAppendF(&result, "\n Instance extensions:\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500183 for (const auto& name : sVulkanInterface.getInstanceExtensionNames()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600184 StringAppendF(&result, "\n %s\n", name.c_str());
185 }
186
187 StringAppendF(&result, "\n Device extensions:\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500188 for (const auto& name : sVulkanInterface.getDeviceExtensionNames()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600189 StringAppendF(&result, "\n %s\n", name.c_str());
190 }
191}
192
193} // namespace skia
194} // namespace renderengine
195} // namespace android