blob: bd501073d74b49c99445fb971ed07e8325e5384c [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/GrVkExtensions.h>
33#include <vk/GrVkTypes.h>
Ian Elliott1f0911e2022-09-09 16:31:47 -060034
35#include <android-base/stringprintf.h>
36#include <gui/TraceUtils.h>
37#include <sync/sync.h>
38#include <utils/Trace.h>
39
Ian Elliott1f0911e2022-09-09 16:31:47 -060040#include <memory>
Nolan Scobie0f539a72024-01-29 10:49:10 -050041#include <string>
Ian Elliott1f0911e2022-09-09 16:31:47 -060042
43#include <vulkan/vulkan.h>
44#include "log/log_main.h"
45
46namespace android {
47namespace renderengine {
48
Nolan Scobief52ad202024-03-06 18:18:28 -050049static skia::VulkanInterface sVulkanInterface;
50static skia::VulkanInterface sProtectedContentVulkanInterface;
Ian Elliott1f0911e2022-09-09 16:31:47 -060051
52static void sSetupVulkanInterface() {
Nolan Scobief52ad202024-03-06 18:18:28 -050053 if (!sVulkanInterface.isInitialized()) {
54 sVulkanInterface.init(false /* no protected content */);
Ian Elliott1f0911e2022-09-09 16:31:47 -060055 // We will have to abort if non-protected VkDevice creation fails (then nothing works).
Nolan Scobief52ad202024-03-06 18:18:28 -050056 LOG_ALWAYS_FATAL_IF(!sVulkanInterface.isInitialized(),
Ian Elliott1f0911e2022-09-09 16:31:47 -060057 "Could not initialize Vulkan RenderEngine!");
58 }
Nolan Scobief52ad202024-03-06 18:18:28 -050059 if (!sProtectedContentVulkanInterface.isInitialized()) {
60 sProtectedContentVulkanInterface.init(true /* protected content */);
61 if (!sProtectedContentVulkanInterface.isInitialized()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -060062 ALOGE("Could not initialize protected content Vulkan RenderEngine.");
63 }
64 }
65}
66
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050067bool RenderEngine::canSupport(GraphicsApi graphicsApi) {
68 switch (graphicsApi) {
69 case GraphicsApi::GL:
70 return true;
71 case GraphicsApi::VK: {
Nolan Scobie2526b2f2024-04-16 15:12:22 -040072 // Static local variables are initialized once, on first invocation of the function.
73 static const bool canSupportVulkan = []() {
74 if (!sVulkanInterface.isInitialized()) {
75 sVulkanInterface.init(false /* no protected content */);
76 ALOGD("%s: initialized == %s.", __func__,
77 sVulkanInterface.isInitialized() ? "true" : "false");
78 if (!sVulkanInterface.isInitialized()) {
79 sVulkanInterface.teardown();
80 return false;
81 }
82 }
83 return true;
84 }();
85 return canSupportVulkan;
86 }
87 }
88}
89
90void RenderEngine::teardown(GraphicsApi graphicsApi) {
91 switch (graphicsApi) {
92 case GraphicsApi::GL:
93 break;
94 case GraphicsApi::VK: {
95 if (sVulkanInterface.isInitialized()) {
96 sVulkanInterface.teardown();
97 ALOGD("Tearing down the unprotected VulkanInterface.");
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -050098 }
Nolan Scobie2526b2f2024-04-16 15:12:22 -040099 if (sProtectedContentVulkanInterface.isInitialized()) {
100 sProtectedContentVulkanInterface.teardown();
101 ALOGD("Tearing down the protected VulkanInterface.");
102 }
103 break;
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -0500104 }
105 }
106}
107
Ian Elliott1f0911e2022-09-09 16:31:47 -0600108namespace skia {
109
110using base::StringAppendF;
111
Ian Elliott1f0911e2022-09-09 16:31:47 -0600112SkiaVkRenderEngine::SkiaVkRenderEngine(const RenderEngineCreationArgs& args)
Leon Scroggins III696bf932024-01-24 15:21:05 -0500113 : SkiaRenderEngine(args.threaded, static_cast<PixelFormat>(args.pixelFormat),
Robin Lee7338bd92024-04-04 14:05:07 +0000114 args.blurAlgorithm) {}
Ian Elliott1f0911e2022-09-09 16:31:47 -0600115
116SkiaVkRenderEngine::~SkiaVkRenderEngine() {
Nolan Scobie2526b2f2024-04-16 15:12:22 -0400117 finishRenderingAndAbandonContexts();
118 // Teardown VulkanInterfaces after Skia contexts have been abandoned
119 teardown(GraphicsApi::VK);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600120}
121
Nolan Scobiefc125ec2024-03-11 20:08:27 -0400122SkiaRenderEngine::Contexts SkiaVkRenderEngine::createContexts() {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600123 sSetupVulkanInterface();
Nolan Scobie2526b2f2024-04-16 15:12:22 -0400124 // More work would need to be done in order to have multiple RenderEngine instances. In
125 // particular, they would not be able to share the same VulkanInterface(s).
126 LOG_ALWAYS_FATAL_IF(!sVulkanInterface.takeOwnership(),
127 "SkiaVkRenderEngine couldn't take ownership of existing unprotected "
128 "VulkanInterface! Only one SkiaVkRenderEngine instance may exist at a "
129 "time.");
130 if (sProtectedContentVulkanInterface.isInitialized()) {
131 // takeOwnership fails on an uninitialized VulkanInterface, but protected content support is
132 // optional.
133 LOG_ALWAYS_FATAL_IF(!sProtectedContentVulkanInterface.takeOwnership(),
134 "SkiaVkRenderEngine couldn't take ownership of existing protected "
135 "VulkanInterface! Only one SkiaVkRenderEngine instance may exist at a "
136 "time.");
137 }
Ian Elliott1f0911e2022-09-09 16:31:47 -0600138
139 SkiaRenderEngine::Contexts contexts;
Nolan Scobie342d3942024-03-21 16:41:39 -0400140 contexts.first = createContext(sVulkanInterface);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600141 if (supportsProtectedContentImpl()) {
Nolan Scobie342d3942024-03-21 16:41:39 -0400142 contexts.second = createContext(sProtectedContentVulkanInterface);
Ian Elliott1f0911e2022-09-09 16:31:47 -0600143 }
144
145 return contexts;
146}
147
148bool SkiaVkRenderEngine::supportsProtectedContentImpl() const {
Nolan Scobief52ad202024-03-06 18:18:28 -0500149 return sProtectedContentVulkanInterface.isInitialized();
Ian Elliott1f0911e2022-09-09 16:31:47 -0600150}
151
152bool SkiaVkRenderEngine::useProtectedContextImpl(GrProtected) {
153 return true;
154}
155
Nolan Scobie02c160c2024-03-18 10:40:23 -0400156VulkanInterface& SkiaVkRenderEngine::getVulkanInterface(bool protectedContext) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600157 if (protectedContext) {
158 return sProtectedContentVulkanInterface;
159 }
160 return sVulkanInterface;
161}
162
Ian Elliott1f0911e2022-09-09 16:31:47 -0600163int SkiaVkRenderEngine::getContextPriority() {
164 // EGL_CONTEXT_PRIORITY_REALTIME_NV
165 constexpr int kRealtimePriority = 0x3357;
Nolan Scobief52ad202024-03-06 18:18:28 -0500166 if (getVulkanInterface(isProtected()).isRealtimePriority()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600167 return kRealtimePriority;
168 } else {
169 return 0;
170 }
171}
172
173void SkiaVkRenderEngine::appendBackendSpecificInfoToDump(std::string& result) {
174 StringAppendF(&result, "\n ------------RE Vulkan----------\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500175 StringAppendF(&result, "\n Vulkan device initialized: %d\n", sVulkanInterface.isInitialized());
Ian Elliott1f0911e2022-09-09 16:31:47 -0600176 StringAppendF(&result, "\n Vulkan protected device initialized: %d\n",
Nolan Scobief52ad202024-03-06 18:18:28 -0500177 sProtectedContentVulkanInterface.isInitialized());
Ian Elliott1f0911e2022-09-09 16:31:47 -0600178
Nolan Scobief52ad202024-03-06 18:18:28 -0500179 if (!sVulkanInterface.isInitialized()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600180 return;
181 }
182
183 StringAppendF(&result, "\n Instance extensions:\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500184 for (const auto& name : sVulkanInterface.getInstanceExtensionNames()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600185 StringAppendF(&result, "\n %s\n", name.c_str());
186 }
187
188 StringAppendF(&result, "\n Device extensions:\n");
Nolan Scobief52ad202024-03-06 18:18:28 -0500189 for (const auto& name : sVulkanInterface.getDeviceExtensionNames()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600190 StringAppendF(&result, "\n %s\n", name.c_str());
191 }
192}
193
194} // namespace skia
195} // namespace renderengine
196} // namespace android