Move the ownership of DisplayVk to VkEmulation am: 4ddffd9a1d
Original change: https://android-review.googlesource.com/c/device/generic/vulkan-cereal/+/1955444
Change-Id: I66fc4cb47d8d000d49d3b7e4ecfeef32ee54a0c9
diff --git a/stream-servers/FrameBuffer.cpp b/stream-servers/FrameBuffer.cpp
index dc088ef..f39b3e1 100644
--- a/stream-servers/FrameBuffer.cpp
+++ b/stream-servers/FrameBuffer.cpp
@@ -342,7 +342,6 @@
}
m_readbackThread.enqueue({ReadbackCmd::Exit});
- m_displayVk.reset();
if (m_vkSurface != VK_NULL_HANDLE) {
emugl::vkDispatch(false /* not for testing */)
->vkDestroySurfaceKHR(m_vkInstance, m_vkSurface, nullptr);
@@ -380,22 +379,13 @@
goldfish_vk::VulkanDispatch* vkDispatch = nullptr;
if (feature_is_enabled(kFeature_Vulkan)) {
vkDispatch = emugl::vkDispatch(false /* not for testing */);
- vkEmu = goldfish_vk::createOrGetGlobalVkEmulation(vkDispatch);
+ vkEmu = goldfish_vk::createGlobalVkEmulation(vkDispatch);
if (!vkEmu) {
ERR("Failed to initialize global Vulkan emulation. Disable the Vulkan support.");
}
}
if (vkEmu) {
- bool useDeferredCommands =
- android::base::getEnvironmentVariable("ANDROID_EMU_VK_DISABLE_DEFERRED_COMMANDS").empty();
- bool useCreateResourcesWithRequirements =
- android::base::getEnvironmentVariable("ANDROID_EMU_VK_DISABLE_USE_CREATE_RESOURCES_WITH_REQUIREMENTS").empty();
- goldfish_vk::setUseDeferredCommands(vkEmu, useDeferredCommands);
- goldfish_vk::setUseCreateResourcesWithRequirements(vkEmu, useCreateResourcesWithRequirements);
if (feature_is_enabled(kFeature_VulkanNativeSwapchain)) {
- fb->m_displayVk = std::make_shared<DisplayVk>(
- *vkEmu->ivk, vkEmu->physdev, vkEmu->queueFamilyIndex, vkEmu->queueFamilyIndex,
- vkEmu->device, vkEmu->queue, vkEmu->queueLock, vkEmu->queue, vkEmu->queueLock);
fb->m_vkInstance = vkEmu->instance;
}
if (vkEmu->deviceInfo.supportsIdProperties) {
@@ -500,6 +490,18 @@
feature_is_enabled(
kFeature_GuestUsesAngle);
+ goldfish_vk::VkEmulationFeatures vkEmulationFeatures = {
+ .glInteropSupported = false, // Set later.
+ .deferredCommands =
+ android::base::getEnvironmentVariable("ANDROID_EMU_VK_DISABLE_DEFERRED_COMMANDS")
+ .empty(),
+ .createResourceWithRequirements =
+ android::base::getEnvironmentVariable(
+ "ANDROID_EMU_VK_DISABLE_USE_CREATE_RESOURCES_WITH_REQUIREMENTS")
+ .empty(),
+ .useVulkanNativeSwapchain = feature_is_enabled(kFeature_VulkanNativeSwapchain),
+ };
+
//
// if GLES2 plugin has loaded - try to make GLES2 context and
// get GLES2 extension string
@@ -802,7 +804,13 @@
}
GL_LOG("glvk interop final: %d", fb->m_vulkanInteropSupported);
- goldfish_vk::setGlInteropSupported(fb->m_vulkanInteropSupported);
+ vkEmulationFeatures.glInteropSupported = fb->m_vulkanInteropSupported;
+ if (feature_is_enabled(kFeature_Vulkan)) {
+ goldfish_vk::initVkEmulationFeatures(vkEmulationFeatures);
+ if (vkEmu->displayVk) {
+ fb->m_displayVk = vkEmu->displayVk.get();
+ }
+ }
// Start up the single sync thread. If we are using Vulkan native
// swapchain, then don't initialize SyncThread worker threads with EGL
@@ -844,8 +852,12 @@
auto& cb = *c->second.cb;
std::shared_ptr<DisplayVk::DisplayBufferInfo> db = nullptr;
- if (m_displayVk != nullptr) {
+ if (m_displayVk) {
db = m_displayVk->createDisplayBuffer(image, imageCi);
+ if (!db) {
+ ERR("Fail to create display buffer for ColorBuffer %" PRIu64 ".",
+ static_cast<uint64_t>(colorBufferHandle));
+ }
}
return cb.importMemory(handle, size, dedicated, imageCi.tiling == VK_IMAGE_TILING_LINEAR,
vulkanOnly, std::move(db));
@@ -1045,9 +1057,8 @@
return false;
}
INFO("Recreating swapchain...");
- m_displayVk->bindToSurface(
- m_vkSurface, static_cast<uint32_t>(m_windowWidth),
- static_cast<uint32_t>(m_windowHeight));
+ m_displayVk->bindToSurface(m_vkSurface, static_cast<uint32_t>(m_windowWidth),
+ static_cast<uint32_t>(m_windowHeight));
INFO("Recreating swapchain completes.");
return true;
}
diff --git a/stream-servers/FrameBuffer.h b/stream-servers/FrameBuffer.h
index 4f7640d..b960c30 100644
--- a/stream-servers/FrameBuffer.h
+++ b/stream-servers/FrameBuffer.h
@@ -24,6 +24,7 @@
#include <functional>
#include <map>
#include <memory>
+#include <optional>
#include <unordered_map>
#include <unordered_set>
@@ -46,8 +47,8 @@
#include "base/WorkerThread.h"
#include "render_api.h"
#include "snapshot/common.h"
-#include "vulkan/vk_util.h"
#include "virtio_gpu_ops.h"
+#include "vulkan/vk_util.h"
struct ColorBufferRef {
ColorBufferPtr cb;
@@ -786,9 +787,9 @@
android::base::MessageChannel<HandleType, 1024>
mOutstandingColorBufferDestroys;
- // The implementation for Vulkan native swapchain. Only initialized when
- // useVulkan is set when calling FrameBuffer::initialize().
- std::shared_ptr<DisplayVk> m_displayVk;
+ // The implementation for Vulkan native swapchain. Only initialized when useVulkan is set when
+ // calling FrameBuffer::initialize(). DisplayVk is actually owned by VkEmulation.
+ DisplayVk *m_displayVk;
VkInstance m_vkInstance = VK_NULL_HANDLE;
VkSurfaceKHR m_vkSurface = VK_NULL_HANDLE;
diff --git a/stream-servers/PostWorker.cpp b/stream-servers/PostWorker.cpp
index b9ac93c..d8cb380 100644
--- a/stream-servers/PostWorker.cpp
+++ b/stream-servers/PostWorker.cpp
@@ -53,17 +53,16 @@
(void)wait;
}
-PostWorker::PostWorker(PostWorker::BindSubwinCallback&& cb,
- bool mainThreadPostingOnly, EGLContext eglContext,
- EGLSurface, std::shared_ptr<DisplayVk> displayVk)
+PostWorker::PostWorker(PostWorker::BindSubwinCallback&& cb, bool mainThreadPostingOnly,
+ EGLContext eglContext, EGLSurface,
+ DisplayVk* displayVk)
: mFb(FrameBuffer::getFB()),
mBindSubwin(cb),
m_mainThreadPostingOnly(mainThreadPostingOnly),
- m_runOnUiThread(m_mainThreadPostingOnly
- ? emugl::get_emugl_window_operations().runOnUiThread
- : sDefaultRunOnUiThread),
+ m_runOnUiThread(m_mainThreadPostingOnly ? emugl::get_emugl_window_operations().runOnUiThread
+ : sDefaultRunOnUiThread),
mContext(eglContext),
- m_displayVk(std::move(displayVk)) {}
+ m_displayVk(displayVk) {}
void PostWorker::fillMultiDisplayPostStruct(ComposeLayer* l,
hwc_rect_t displayArea,
diff --git a/stream-servers/PostWorker.h b/stream-servers/PostWorker.h
index 3fe8097..ccbb3cf 100644
--- a/stream-servers/PostWorker.h
+++ b/stream-servers/PostWorker.h
@@ -41,9 +41,8 @@
public:
using BindSubwinCallback = std::function<bool(void)>;
- PostWorker(BindSubwinCallback&& cb, bool mainThreadPostingOnly,
- EGLContext eglContext, EGLSurface eglSurface,
- std::shared_ptr<DisplayVk>);
+ PostWorker(BindSubwinCallback&& cb, bool mainThreadPostingOnly, EGLContext eglContext,
+ EGLSurface eglSurface, DisplayVk*);
~PostWorker();
// post: posts the next color buffer.
@@ -120,8 +119,9 @@
EGLContext mContext = EGL_NO_CONTEXT;
// The implementation for Vulkan native swapchain. Only initialized when
- // useVulkan is set when calling FrameBuffer::initialize().
- std::shared_ptr<DisplayVk> m_displayVk;
+ // useVulkan is set when calling FrameBuffer::initialize(). PostWorker
+ // doesn't take the ownership of this DisplayVk object.
+ DisplayVk* const m_displayVk;
// With Vulkan swapchain, compose also means to post to the WSI surface.
// In this case, don't do anything in the subsequent resource flush.
std::optional<uint32_t> m_lastVkComposeColorBuffer = std::nullopt;
diff --git a/stream-servers/vulkan/VkCommonOperations.cpp b/stream-servers/vulkan/VkCommonOperations.cpp
index 2e955fa..e1d4e29 100644
--- a/stream-servers/vulkan/VkCommonOperations.cpp
+++ b/stream-servers/vulkan/VkCommonOperations.cpp
@@ -445,7 +445,7 @@
return res;
}
-VkEmulation* createOrGetGlobalVkEmulation(VulkanDispatch* vk) {
+VkEmulation* createGlobalVkEmulation(VulkanDispatch* vk) {
#define VK_EMU_INIT_RETURN_ON_ERROR(...) \
do { \
ERR(__VA_ARGS__); \
@@ -1060,30 +1060,32 @@
return sVkEmulation;
}
-void setGlInteropSupported(bool supported) {
- if (!sVkEmulation) {
- // LOG(VERBOSE) << "Not setting vk/gl interop support, Vulkan not enabled";
+void initVkEmulationFeatures(const VkEmulationFeatures& features) {
+ if (!sVkEmulation || !sVkEmulation->live) {
+ ERR("VkEmulation is either not initialized or destroyed.");
return;
}
- // LOG(VERBOSE) << "Setting gl interop support for Vk to: " << supported;
- sVkEmulation->deviceInfo.glInteropSupported = supported;
-}
+ AutoLock lock(sVkEmulationLock);
+ INFO("Initializing VkEmulation features:");
+ INFO(" glInteropSupported: %s", features.glInteropSupported ? "true" : "false");
+ INFO(" useDeferredCommands: %s", features.deferredCommands ? "true" : "false");
+ INFO(" createResourceWithRequirements: %s",
+ features.createResourceWithRequirements ? "true" : "false");
+ INFO(" useVulkanNativeSwapchain: %s", features.useVulkanNativeSwapchain ? "true" : "false");
+ sVkEmulation->deviceInfo.glInteropSupported = features.glInteropSupported;
+ sVkEmulation->useDeferredCommands = features.deferredCommands;
+ sVkEmulation->useCreateResourcesWithRequirements = features.createResourceWithRequirements;
-void setUseDeferredCommands(VkEmulation* emu, bool useDeferredCommands) {
- if (!emu) return;
- if (!emu->live) return;
-
- // LOG(VERBOSE) << "Using deferred Vulkan commands: " << useDeferredCommands;
- emu->useDeferredCommands = useDeferredCommands;
-}
-
-void setUseCreateResourcesWithRequirements(VkEmulation* emu, bool useCreateResourcesWithRequirements) {
- if (!emu) return;
- if (!emu->live) return;
-
- /// LOG(VERBOSE) << "Using deferred Vulkan commands: " << useCreateResourcesWithRequirements;
- emu->useCreateResourcesWithRequirements = useCreateResourcesWithRequirements;
+ if (features.useVulkanNativeSwapchain) {
+ if (sVkEmulation->displayVk) {
+ ERR("Reset VkEmulation::displayVk.");
+ }
+ sVkEmulation->displayVk = std::make_unique<DisplayVk>(
+ *sVkEmulation->ivk, sVkEmulation->physdev, sVkEmulation->queueFamilyIndex,
+ sVkEmulation->queueFamilyIndex, sVkEmulation->device, sVkEmulation->queue,
+ sVkEmulation->queueLock, sVkEmulation->queue, sVkEmulation->queueLock);
+ }
}
VkEmulation* getGlobalVkEmulation() {
@@ -1097,6 +1099,8 @@
// Don't try to tear down something that did not set up completely; too risky
if (!sVkEmulation->live) return;
+ sVkEmulation->displayVk.reset();
+
freeExternalMemoryLocked(sVkEmulation->dvk, &sVkEmulation->staging.memory);
sVkEmulation->ivk->vkDestroyDevice(sVkEmulation->device, nullptr);
diff --git a/stream-servers/vulkan/VkCommonOperations.h b/stream-servers/vulkan/VkCommonOperations.h
index 5f2d2d4..3150c6e 100644
--- a/stream-servers/vulkan/VkCommonOperations.h
+++ b/stream-servers/vulkan/VkCommonOperations.h
@@ -22,6 +22,7 @@
#include <unordered_set>
#include <vector>
+#include "DisplayVk.h"
#include "base/Lock.h"
#include "base/Optional.h"
#include "cereal/common/goldfish_vk_private_defs.h"
@@ -336,12 +337,20 @@
// Every command buffer in the pool is associated with a VkFence which is
// signaled only if the command buffer completes.
std::vector<std::tuple<VkCommandBuffer, VkFence>> transferQueueCommandBufferPool;
+
+ // The implementation for Vulkan native swapchain. Only initialized in initVkEmulationFeatures
+ // if useVulkanNativeSwapchain is set.
+ std::unique_ptr<DisplayVk> displayVk;
};
-VkEmulation* createOrGetGlobalVkEmulation(VulkanDispatch* vk);
-void setGlInteropSupported(bool supported);
-void setUseDeferredCommands(VkEmulation* emu, bool useDeferred);
-void setUseCreateResourcesWithRequirements(VkEmulation* emu, bool useCreateResourcesWithRequirements);
+VkEmulation* createGlobalVkEmulation(VulkanDispatch* vk);
+struct VkEmulationFeatures {
+ bool glInteropSupported = false;
+ bool deferredCommands = false;
+ bool createResourceWithRequirements = false;
+ bool useVulkanNativeSwapchain = false;
+};
+void initVkEmulationFeatures(const VkEmulationFeatures&);
VkEmulation* getGlobalVkEmulation();
void teardownGlobalVkEmulation();