summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2022-10-12 18:02:45 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-10-12 18:02:45 +0000
commit595fedbd3ad8b5158aa892f2936d608573e0dfbe (patch)
tree46fadf99b0f34b620aa9520ea614325e191346e4
parent12a7d979fecae3a804251b382a4480c00a9baa6f (diff)
parenta34429d666f8caf299703866f08188a8dc57ccd7 (diff)
downloadvulkan-cereal-595fedbd3ad8b5158aa892f2936d608573e0dfbe.tar.gz
Merge "Revert "Add Display, DisplaySurface, and DisplaySurfaceVk""
-rw-r--r--stream-servers/Android.bp2
-rw-r--r--stream-servers/CMakeLists.txt2
-rw-r--r--stream-servers/Display.cpp50
-rw-r--r--stream-servers/Display.h43
-rw-r--r--stream-servers/DisplaySurface.cpp66
-rw-r--r--stream-servers/DisplaySurface.h67
-rw-r--r--stream-servers/FrameBuffer.cpp46
-rw-r--r--stream-servers/FrameBuffer.h8
-rw-r--r--stream-servers/PostWorker.cpp17
-rw-r--r--stream-servers/tests/DisplayVk_unittest.cpp25
-rw-r--r--stream-servers/vulkan/Android.bp1
-rw-r--r--stream-servers/vulkan/CMakeLists.txt1
-rw-r--r--stream-servers/vulkan/DisplaySurfaceVk.cpp61
-rw-r--r--stream-servers/vulkan/DisplaySurfaceVk.h43
-rw-r--r--stream-servers/vulkan/DisplayVk.cpp93
-rw-r--r--stream-servers/vulkan/DisplayVk.h24
-rw-r--r--stream-servers/vulkan/VkCommonOperations.cpp18
-rw-r--r--stream-servers/vulkan/VkCommonOperations.h3
18 files changed, 88 insertions, 482 deletions
diff --git a/stream-servers/Android.bp b/stream-servers/Android.bp
index b425bc6a..983a7112 100644
--- a/stream-servers/Android.bp
+++ b/stream-servers/Android.bp
@@ -59,8 +59,6 @@ cc_library_shared {
"ChannelStream.cpp",
"ColorBuffer.cpp",
"Debug.cpp",
- "Display.cpp",
- "DisplaySurface.cpp",
"FenceSync.cpp",
"Hwc2.cpp",
"PostWorker.cpp",
diff --git a/stream-servers/CMakeLists.txt b/stream-servers/CMakeLists.txt
index c9d159e0..c7881d2a 100644
--- a/stream-servers/CMakeLists.txt
+++ b/stream-servers/CMakeLists.txt
@@ -21,8 +21,6 @@ set(stream-server-core-sources
ChannelStream.cpp
ColorBuffer.cpp
Debug.cpp
- Display.cpp
- DisplaySurface.cpp
FenceSync.cpp
Hwc2.cpp
PostWorker.cpp
diff --git a/stream-servers/Display.cpp b/stream-servers/Display.cpp
deleted file mode 100644
index a89f82d3..00000000
--- a/stream-servers/Display.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "Display.h"
-
-#include "DisplaySurface.h"
-#include "host-common/GfxstreamFatalError.h"
-#include "host-common/logging.h"
-
-namespace gfxstream {
-
-using emugl::ABORT_REASON_OTHER;
-using emugl::FatalError;
-
-Display::~Display() {
- if (mBoundSurface != nullptr) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "Failed to unbind a DisplaySurface before Display destruction.";
- }
-}
-
-void Display::bindToSurface(DisplaySurface* surface) {
- if (mBoundSurface != nullptr) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "Attempting to bind a DisplaySurface while another is already bound.";
- }
-
- this->bindToSurfaceImpl(surface);
- surface->registerBoundDisplay(this);
- mBoundSurface = surface;
-}
-
-void Display::unbindFromSurface() {
- this->unbindFromSurfaceImpl();
- mBoundSurface->unregisterBoundDisplay(this);
- mBoundSurface = nullptr;
-}
-
-} // namespace gfxstream
diff --git a/stream-servers/Display.h b/stream-servers/Display.h
deleted file mode 100644
index 4ed3062d..00000000
--- a/stream-servers/Display.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#pragma once
-
-namespace gfxstream {
-
-class Display;
-class DisplaySurface;
-
-class Display {
- public:
- virtual ~Display();
-
- public:
- void bindToSurface(DisplaySurface* surface);
-
- void unbindFromSurface();
-
- protected:
- virtual void bindToSurfaceImpl(DisplaySurface* surface) = 0;
-
- virtual void unbindFromSurfaceImpl() = 0;
-
- const DisplaySurface* getBoundSurface() const { return mBoundSurface; }
-
- private:
- friend class DisplaySurface;
- DisplaySurface* mBoundSurface = nullptr;
-};
-
-} // namespace gfxstream
diff --git a/stream-servers/DisplaySurface.cpp b/stream-servers/DisplaySurface.cpp
deleted file mode 100644
index 6a62a703..00000000
--- a/stream-servers/DisplaySurface.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "DisplaySurface.h"
-
-#include "Display.h"
-#include "host-common/GfxstreamFatalError.h"
-#include "host-common/logging.h"
-
-namespace gfxstream {
-
-using emugl::ABORT_REASON_OTHER;
-using emugl::FatalError;
-
-DisplaySurface::DisplaySurface(uint32_t width,
- uint32_t height,
- std::unique_ptr<DisplaySurfaceImpl> impl)
- : mWidth(width),
- mHeight(height),
- mImpl(std::move(impl)) {}
-
-DisplaySurface::~DisplaySurface() {
- if (mBoundDisplay) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "DisplaySurface destroyed while still bound to a Display!";
- }
-}
-
-uint32_t DisplaySurface::getWidth() const {
- std::lock_guard<std::mutex> lock(mParamsMutex);
- return mWidth;
-}
-
-uint32_t DisplaySurface::getHeight() const {
- std::lock_guard<std::mutex> lock(mParamsMutex);
- return mHeight;
-}
-
-void DisplaySurface::updateSize(uint32_t newWidth, uint32_t newHeight) {
- std::lock_guard<std::mutex> lock(mParamsMutex);
- mWidth = newHeight;
- mHeight = newHeight;
-}
-
-void DisplaySurface::registerBoundDisplay(Display* display) {
- mBoundDisplay = display;
-}
-
-void DisplaySurface::unregisterBoundDisplay(Display* display) {
- if (display == mBoundDisplay) {
- mBoundDisplay = nullptr;
- }
-}
-
-} // namespace gfxstream
diff --git a/stream-servers/DisplaySurface.h b/stream-servers/DisplaySurface.h
deleted file mode 100644
index 49bfd989..00000000
--- a/stream-servers/DisplaySurface.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-#include <mutex>
-
-namespace gfxstream {
-
-class Display;
-class DisplaySurface;
-
-// Base class used for controlling the lifetime of a particular surface
-// used for a display (e.g. EGLSurface or VkSurfaceKHR).
-class DisplaySurfaceImpl {
- public:
- virtual ~DisplaySurfaceImpl() {}
-};
-
-class DisplaySurface {
- public:
- DisplaySurface(uint32_t width,
- uint32_t height,
- std::unique_ptr<DisplaySurfaceImpl> impl);
- ~DisplaySurface();
-
- DisplaySurface(const DisplaySurface&) = delete;
- DisplaySurface& operator=(const DisplaySurface&) = delete;
-
- // Return the API specific implementation of a DisplaySurface. This
- // should only be called by API specific components such as DisplayGl
- // or DisplayVk.
- const DisplaySurfaceImpl* getImpl() const { return mImpl.get(); }
-
- uint32_t getWidth() const;
- uint32_t getHeight() const;
-
- void updateSize(uint32_t newWidth, uint32_t newHeight);
-
- private:
- friend class Display;
-
- void registerBoundDisplay(Display* display);
- void unregisterBoundDisplay(Display* display);
-
- std::unique_ptr<DisplaySurfaceImpl> mImpl;
- Display* mBoundDisplay = nullptr;
-
- mutable std::mutex mParamsMutex;
- uint32_t mWidth = 0;
- uint32_t mHeight = 0;
-};
-
-} // namespace gfxstream
diff --git a/stream-servers/FrameBuffer.cpp b/stream-servers/FrameBuffer.cpp
index b2d51f6f..92406bad 100644
--- a/stream-servers/FrameBuffer.cpp
+++ b/stream-servers/FrameBuffer.cpp
@@ -349,6 +349,10 @@ void FrameBuffer::finalize() {
}
m_readbackThread.enqueue({ReadbackCmd::Exit});
+ if (m_vkSurface != VK_NULL_HANDLE) {
+ emugl::vkDispatch(false /* not for testing */)
+ ->vkDestroySurfaceKHR(m_vkInstance, m_vkSurface, nullptr);
+ }
}
bool FrameBuffer::initialize(int width, int height, bool useSubWindow,
@@ -1152,6 +1156,25 @@ std::future<void> FrameBuffer::sendPostWorkerCmd(Post post) {
m_postWorker.reset(new PostWorker(
[this]() {
if (m_displayVk) {
+ if (m_vkSurface == VK_NULL_HANDLE) {
+ return false;
+ }
+ INFO("Recreating swapchain...");
+ int maxRetries = 8;
+ while (maxRetries>=0 && !m_displayVk->bindToSurface(
+ m_vkSurface,
+ static_cast<uint32_t>(m_windowWidth),
+ static_cast<uint32_t>(m_windowHeight))) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ --maxRetries;
+ INFO("Swapchain recreation failed, retrying...");
+ }
+ if (maxRetries < 0) {
+ GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+ << "Failed to create Swapchain. w:" << m_windowWidth.load()
+ << " h:" << m_windowHeight.load();
+ }
+ INFO("Recreating swapchain completes.");
return true;
}
if (m_subWin) {
@@ -1352,8 +1375,6 @@ bool FrameBuffer::setupSubWindow(FBNativeWindowType p_window,
#endif
if (deleteExisting) {
- m_displayVk->unbindFromSurface();
- m_displaySurface.reset();
// TODO: look into reusing the existing native window when possible.
removeSubWindow_locked();
}
@@ -1377,15 +1398,17 @@ bool FrameBuffer::setupSubWindow(FBNativeWindowType p_window,
if (m_displayVk != nullptr) {
// create VkSurface from the generated subwindow, and bind to
// the DisplayVk
- m_displaySurface = goldfish_vk::createDisplaySurface(m_subWin,
- m_windowWidth,
- m_windowHeight);
- if (!m_displaySurface) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "Failed to create DisplaySurface.";
- }
- m_displayVk->bindToSurface(m_displaySurface.get());
-
+ // TODO(kaiyili, b/179477624): add support for other platforms
+#ifdef _WIN32
+ VkWin32SurfaceCreateInfoKHR surfaceCi = {};
+ surfaceCi.sType =
+ VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
+ surfaceCi.hinstance = GetModuleHandle(nullptr);
+ surfaceCi.hwnd = m_subWin;
+ VK_CHECK(emugl::vkDispatch(false /* not for testing */)
+ ->vkCreateWin32SurfaceKHR(m_vkInstance, &surfaceCi,
+ nullptr, &m_vkSurface));
+#endif
if (m_renderDoc) {
m_renderDoc->call(emugl::RenderDoc::kSetActiveWindow,
RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(m_vkInstance),
@@ -1432,7 +1455,6 @@ bool FrameBuffer::setupSubWindow(FBNativeWindowType p_window,
success = ::moveSubWindow(m_nativeWindow, m_subWin, m_x, m_y, m_windowWidth,
m_windowHeight);
}
- m_displaySurface->updateSize(m_windowWidth, m_windowHeight);
}
// We are safe to unblock the PostWorker thread now, because we have completed all the
// operations that could modify the state of the m_subWin. We need to unblock the PostWorker
diff --git a/stream-servers/FrameBuffer.h b/stream-servers/FrameBuffer.h
index dc7ab7b0..dd36b9c9 100644
--- a/stream-servers/FrameBuffer.h
+++ b/stream-servers/FrameBuffer.h
@@ -31,8 +31,6 @@
#include "Buffer.h"
#include "ColorBuffer.h"
#include "Compositor.h"
-#include "Display.h"
-#include "DisplaySurface.h"
#include "DisplayVk.h"
#include "Hwc2.h"
#include "PostCommands.h"
@@ -847,13 +845,9 @@ class FrameBuffer {
// calling FrameBuffer::initialize(). DisplayVk is actually owned by VkEmulation.
DisplayVk *m_displayVk = nullptr;
VkInstance m_vkInstance = VK_NULL_HANDLE;
+ VkSurfaceKHR m_vkSurface = VK_NULL_HANDLE;
std::unique_ptr<emugl::RenderDoc> m_renderDoc = nullptr;
- // TODO(b/233939967): Refactor to create DisplayGl and DisplaySurfaceGl
- // and remove usage of non-generic DisplayVk.
- // Display* m_display;
- std::unique_ptr<gfxstream::DisplaySurface> m_displaySurface;
-
// UUIDs of physical devices for Vulkan and GLES, respectively. In most
// cases, this determines whether we can support zero-copy interop.
uint8_t m_vulkanUUID[VK_UUID_SIZE];
diff --git a/stream-servers/PostWorker.cpp b/stream-servers/PostWorker.cpp
index c145984b..d0c0e31e 100644
--- a/stream-servers/PostWorker.cpp
+++ b/stream-servers/PostWorker.cpp
@@ -94,7 +94,22 @@ std::shared_future<void> PostWorker::postImpl(ColorBuffer* cb) {
if (m_displayVk) {
const auto imageInfo = mFb->borrowColorBufferForDisplay(cb->getHndl());
- return m_displayVk->post(imageInfo.get());
+ bool success;
+ Compositor::CompositionFinishedWaitable waitForGpu;
+ std::tie(success, waitForGpu) = m_displayVk->post(imageInfo.get());
+ if (!success) {
+ // Create swapChain and retry
+ if (mBindSubwin()) {
+ const auto imageInfo = mFb->borrowColorBufferForDisplay(cb->getHndl());
+ std::tie(success, waitForGpu) = m_displayVk->post(imageInfo.get());
+ }
+ if (!success) {
+ m_needsToRebindWindow = true;
+ return completedFuture;
+ }
+ m_needsToRebindWindow = false;
+ }
+ return waitForGpu;
}
float dpr = mFb->getDpr();
diff --git a/stream-servers/tests/DisplayVk_unittest.cpp b/stream-servers/tests/DisplayVk_unittest.cpp
index bf4a7efe..c5b464a4 100644
--- a/stream-servers/tests/DisplayVk_unittest.cpp
+++ b/stream-servers/tests/DisplayVk_unittest.cpp
@@ -10,8 +10,6 @@
#include "tests/VkTestUtils.h"
#include "vulkan/VulkanDispatch.h"
-using gfxstream::DisplaySurface;
-
class DisplayVkTest : public ::testing::Test {
protected:
using RenderTexture = emugl::RenderTextureVk;
@@ -43,11 +41,7 @@ class DisplayVkTest : public ::testing::Test {
*k_vk, m_vkPhysicalDevice, m_swapChainQueueFamilyIndex, m_compositorQueueFamilyIndex,
m_vkDevice, m_compositorVkQueue, m_compositorVkQueueLock, m_swapChainVkQueue,
m_swapChainVkQueueLock);
- m_displaySurface = std::make_unique<gfxstream::DisplaySurface>(
- k_width, k_height,
- DisplaySurfaceVk::create(*k_vk, m_vkInstance, m_window->getNativeWindow()));
- ASSERT_NE(m_displaySurface, nullptr);
- m_displayVk->bindToSurface(m_displaySurface.get());
+ m_displayVk->bindToSurface(m_vkSurface, k_width, k_height);
}
void TearDown() override {
@@ -97,7 +91,6 @@ class DisplayVkTest : public ::testing::Test {
std::shared_ptr<android::base::Lock> m_swapChainVkQueueLock;
VkCommandPool m_vkCommandPool = VK_NULL_HANDLE;
std::unique_ptr<DisplayVk> m_displayVk = nullptr;
- std::unique_ptr<DisplaySurface> m_displaySurface = nullptr;
private:
void createInstance() {
@@ -220,7 +213,7 @@ TEST_F(DisplayVkTest, PostWithoutSurfaceShouldntCrash) {
std::vector<uint32_t> pixels(textureWidth * textureHeight, 0);
ASSERT_TRUE(texture->write(pixels));
const auto imageInfo = createBorrowedImageInfo(texture);
- displayVk.post(imageInfo.get());
+ ASSERT_TRUE(std::get<0>(displayVk.post(imageInfo.get())));
}
TEST_F(DisplayVkTest, SimplePost) {
@@ -242,7 +235,8 @@ TEST_F(DisplayVkTest, SimplePost) {
std::vector<std::shared_future<void>> waitForGpuFutures;
for (uint32_t i = 0; i < 10; i++) {
const auto imageInfo = createBorrowedImageInfo(texture);
- auto waitForGpuFuture = m_displayVk->post(imageInfo.get());
+ auto [success, waitForGpuFuture] = m_displayVk->post(imageInfo.get());
+ ASSERT_TRUE(success);
waitForGpuFutures.emplace_back(std::move(waitForGpuFuture));
}
for (auto &waitForGpuFuture : waitForGpuFutures) {
@@ -269,11 +263,12 @@ TEST_F(DisplayVkTest, PostTwoColorBuffers) {
for (uint32_t i = 0; i < 10; i++) {
const auto redImageInfo = createBorrowedImageInfo(redTexture);
const auto greenImageInfo = createBorrowedImageInfo(greenTexture);
- auto waitForRedGpuFuture = m_displayVk->post(redImageInfo.get());
- waitForGpuFutures.emplace_back(std::move(waitForRedGpuFuture));
-
- auto waitForGreenGpuFuture = m_displayVk->post(greenImageInfo.get());
- waitForGpuFutures.emplace_back(std::move(waitForGreenGpuFuture));
+ auto [success, waitForGpuFuture] = m_displayVk->post(redImageInfo.get());
+ ASSERT_TRUE(success);
+ waitForGpuFutures.emplace_back(std::move(waitForGpuFuture));
+ std::tie(success, waitForGpuFuture) = m_displayVk->post(greenImageInfo.get());
+ ASSERT_TRUE(success);
+ waitForGpuFutures.emplace_back(std::move(waitForGpuFuture));
}
for (auto &waitForGpuFuture : waitForGpuFutures) {
waitForGpuFuture.wait();
diff --git a/stream-servers/vulkan/Android.bp b/stream-servers/vulkan/Android.bp
index 275bbf01..e8c9a0c0 100644
--- a/stream-servers/vulkan/Android.bp
+++ b/stream-servers/vulkan/Android.bp
@@ -37,7 +37,6 @@ cc_library_static {
"CompositorVk.cpp",
"DebugUtilsHelper.cpp",
"DisplayVk.cpp",
- "DisplaySurfaceVk.cpp",
"SwapChainStateVk.cpp",
"VkAndroidNativeBuffer.cpp",
"VkCommonOperations.cpp",
diff --git a/stream-servers/vulkan/CMakeLists.txt b/stream-servers/vulkan/CMakeLists.txt
index 3af7c68c..cce79b22 100644
--- a/stream-servers/vulkan/CMakeLists.txt
+++ b/stream-servers/vulkan/CMakeLists.txt
@@ -5,7 +5,6 @@ add_library(gfxstream-vulkan-server
BorrowedImageVk.cpp
CompositorVk.cpp
DisplayVk.cpp
- DisplaySurfaceVk.cpp
DebugUtilsHelper.cpp
SwapChainStateVk.cpp
VkAndroidNativeBuffer.cpp
diff --git a/stream-servers/vulkan/DisplaySurfaceVk.cpp b/stream-servers/vulkan/DisplaySurfaceVk.cpp
deleted file mode 100644
index 7a61a9c8..00000000
--- a/stream-servers/vulkan/DisplaySurfaceVk.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "DisplaySurfaceVk.h"
-
-#include "host-common/GfxstreamFatalError.h"
-#include "host-common/logging.h"
-#include "vk_util.h"
-
-using emugl::ABORT_REASON_OTHER;
-using emugl::FatalError;
-
-std::unique_ptr<DisplaySurfaceVk> DisplaySurfaceVk::create(
- const goldfish_vk::VulkanDispatch& vk,
- VkInstance instance,
- FBNativeWindowType window) {
- VkSurfaceKHR surface = VK_NULL_HANDLE;
-#ifdef _WIN32
- const VkWin32SurfaceCreateInfoKHR surfaceCi = {
- .sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
- .pNext = nullptr,
- .flags = 0,
- .hinstance = GetModuleHandle(nullptr),
- .hwnd = window,
- };
- VK_CHECK(vk.vkCreateWin32SurfaceKHR(instance, &surfaceCi, nullptr, &surface));
-#else
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "Unimplemented.";
-#endif
- if (surface == VK_NULL_HANDLE) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "No VkSurfaceKHR created?";
- }
-
- return std::unique_ptr<DisplaySurfaceVk>(new DisplaySurfaceVk(vk, instance, surface));
-}
-
-DisplaySurfaceVk::DisplaySurfaceVk(const goldfish_vk::VulkanDispatch& vk,
- VkInstance instance,
- VkSurfaceKHR surface)
- : mVk(vk),
- mInstance(instance),
- mSurface(surface) {}
-
-DisplaySurfaceVk::~DisplaySurfaceVk() {
- if (mSurface != VK_NULL_HANDLE) {
- mVk.vkDestroySurfaceKHR(mInstance, mSurface, nullptr);
- }
-}
diff --git a/stream-servers/vulkan/DisplaySurfaceVk.h b/stream-servers/vulkan/DisplaySurfaceVk.h
deleted file mode 100644
index 2ff8ff77..00000000
--- a/stream-servers/vulkan/DisplaySurfaceVk.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-
-#include "DisplaySurface.h"
-#include "render-utils/render_api_platform_types.h"
-#include "vulkan/cereal/common/goldfish_vk_dispatch.h"
-
-class DisplaySurfaceVk : public gfxstream::DisplaySurfaceImpl {
- public:
- static std::unique_ptr<DisplaySurfaceVk> create(
- const goldfish_vk::VulkanDispatch& vk,
- VkInstance vkInstance,
- FBNativeWindowType window);
-
- ~DisplaySurfaceVk();
-
- VkSurfaceKHR getSurface() const { return mSurface; }
-
- private:
- DisplaySurfaceVk(const goldfish_vk::VulkanDispatch& vk,
- VkInstance vkInstance,
- VkSurfaceKHR vkSurface);
-
- const goldfish_vk::VulkanDispatch& mVk;
- VkInstance mInstance = VK_NULL_HANDLE;
- VkSurfaceKHR mSurface = VK_NULL_HANDLE;
-};
diff --git a/stream-servers/vulkan/DisplayVk.cpp b/stream-servers/vulkan/DisplayVk.cpp
index 04c4b435..8ac608bd 100644
--- a/stream-servers/vulkan/DisplayVk.cpp
+++ b/stream-servers/vulkan/DisplayVk.cpp
@@ -61,7 +61,8 @@ DisplayVk::DisplayVk(const goldfish_vk::VulkanDispatch& vk, VkPhysicalDevice vkP
m_swapChainVkQueue(swapChainVkqueue),
m_swapChainVkQueueLock(swapChainVkQueueLock),
m_vkCommandPool(VK_NULL_HANDLE),
- m_swapChainStateVk(nullptr) {
+ m_swapChainStateVk(nullptr),
+ m_surfaceState(nullptr) {
// TODO(kaiyili): validate the capabilites of the passed in Vulkan
// components.
VkCommandPoolCreateInfo commandPoolCi = {
@@ -82,6 +83,7 @@ DisplayVk::~DisplayVk() {
m_imageBorrowResources.clear();
m_freePostResources.clear();
m_postResourceFutures.clear();
+ m_surfaceState.reset();
m_swapChainStateVk.reset();
m_vk.vkDestroyCommandPool(m_vkDevice, m_vkCommandPool, nullptr);
}
@@ -100,40 +102,20 @@ void DisplayVk::drainQueues() {
}
}
-void DisplayVk::bindToSurfaceImpl(gfxstream::DisplaySurface* surface) {
- m_needToRecreateSwapChain = true;
-}
-
-void DisplayVk::unbindFromSurfaceImpl() {
- drainQueues();
- m_freePostResources.clear();
- m_postResourceFutures.clear();
- m_swapChainStateVk.reset();
- m_needToRecreateSwapChain = true;
-}
-
-bool DisplayVk::recreateSwapchain() {
+bool DisplayVk::bindToSurface(VkSurfaceKHR surface, uint32_t width, uint32_t height) {
drainQueues();
m_freePostResources.clear();
m_postResourceFutures.clear();
m_swapChainStateVk.reset();
- const auto* surface = getBoundSurface();
- if (!surface) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "DisplayVk can't create VkSwapchainKHR without a VkSurfaceKHR";
- }
- const auto* surfaceVk = static_cast<const DisplaySurfaceVk*>(surface->getImpl());
-
- if (!SwapChainStateVk::validateQueueFamilyProperties(m_vk, m_vkPhysicalDevice,
- surfaceVk->getSurface(),
+ if (!SwapChainStateVk::validateQueueFamilyProperties(m_vk, m_vkPhysicalDevice, surface,
m_swapChainQueueFamilyIndex)) {
GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
<< "DisplayVk can't create VkSwapchainKHR with given VkDevice and VkSurfaceKHR.";
}
auto swapChainCi = SwapChainStateVk::createSwapChainCi(
- m_vk, surfaceVk->getSurface(), m_vkPhysicalDevice, surface->getWidth(),
- surface->getHeight(), {m_swapChainQueueFamilyIndex, m_compositorQueueFamilyIndex});
+ m_vk, surface, m_vkPhysicalDevice, width, height,
+ {m_swapChainQueueFamilyIndex, m_compositorQueueFamilyIndex});
if (!swapChainCi) {
return false;
}
@@ -156,55 +138,15 @@ bool DisplayVk::recreateSwapchain() {
}
m_inFlightFrameIndex = 0;
- m_needToRecreateSwapChain = false;
- return true;
-}
-
-std::shared_future<void> DisplayVk::post(const BorrowedImageInfo* sourceImageInfo) {
- auto completedFuture = std::async(std::launch::deferred, [] {}).share();
- completedFuture.wait();
-
- const auto* surface = getBoundSurface();
- if (!surface) {
- return completedFuture;
- }
-
- constexpr const int kMaxPostRetries = 8;
- for (int i = 0; i < kMaxPostRetries; i++) {
- if (m_needToRecreateSwapChain) {
- INFO("Recreating swapchain...");
-
- constexpr const int kMaxRecreateSwapchainRetries = 8;
- int retriesRemaining = kMaxRecreateSwapchainRetries;
- while (retriesRemaining >= 0 && !recreateSwapchain()) {
- std::this_thread::sleep_for(std::chrono::milliseconds(1));
- --retriesRemaining;
- INFO("Swapchain recreation failed, retrying...");
- }
-
- if (retriesRemaining < 0) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "Failed to create Swapchain."
- << " w:" << surface->getWidth()
- << " h:" << surface->getHeight();
- }
-
- INFO("Recreating swapchain completed.");
- }
- bool success;
- std::shared_future<void> waitable;
- std::tie(success, waitable) = postImpl(sourceImageInfo);
- if (success) {
- return waitable;
- }
- m_needToRecreateSwapChain = true;
- }
-
- return completedFuture;
+ auto surfaceState = std::make_unique<SurfaceState>();
+ surfaceState->m_height = height;
+ surfaceState->m_width = width;
+ m_surfaceState = std::move(surfaceState);
+ return true;
}
-std::tuple<bool, std::shared_future<void>> DisplayVk::postImpl(
+std::tuple<bool, std::shared_future<void>> DisplayVk::post(
const BorrowedImageInfo* sourceImageInfo) {
auto completedFuture = std::async(std::launch::deferred, [] {}).share();
completedFuture.wait();
@@ -347,8 +289,7 @@ std::tuple<bool, std::shared_future<void>> DisplayVk::postImpl(
m_compositorQueueFamilyIndex, *sourceImageInfoVk, *imageBorrowResources[0],
*imageBorrowResources[1]);
- const auto* surface = getBoundSurface();
- if (!m_swapChainStateVk || !surface) {
+ if (!m_swapChainStateVk || !m_surfaceState) {
DISPLAY_VK_ERROR("Haven't bound to a surface, can't post ColorBuffer.");
return std::make_tuple(true, std::move(completedFuture));
}
@@ -447,8 +388,8 @@ std::tuple<bool, std::shared_future<void>> DisplayVk::postImpl(
.baseArrayLayer = 0,
.layerCount = 1},
.dstOffsets = {{0, 0, 0},
- {static_cast<int32_t>(surface->getWidth()),
- static_cast<int32_t>(surface->getHeight()), 1}},
+ {static_cast<int32_t>(m_surfaceState->m_width),
+ static_cast<int32_t>(m_surfaceState->m_height), 1}},
};
VkFormat displayBufferFormat = sourceImageInfoVk->imageCreateInfo.format;
VkImageTiling displayBufferTiling = sourceImageInfoVk->imageCreateInfo.tiling;
@@ -751,4 +692,4 @@ DisplayVk::ImageBorrowResource::ImageBorrowResource(const goldfish_vk::VulkanDis
m_vkCommandBuffer(commandBuffer),
m_vk(vk),
m_vkDevice(device),
- m_vkCommandPool(commandPool) {}
+ m_vkCommandPool(commandPool) {} \ No newline at end of file
diff --git a/stream-servers/vulkan/DisplayVk.h b/stream-servers/vulkan/DisplayVk.h
index b73fcc5a..f253e90c 100644
--- a/stream-servers/vulkan/DisplayVk.h
+++ b/stream-servers/vulkan/DisplayVk.h
@@ -12,8 +12,6 @@
#include "BorrowedImage.h"
#include "CompositorVk.h"
-#include "Display.h"
-#include "DisplaySurfaceVk.h"
#include "Hwc2.h"
#include "SwapChainStateVk.h"
#include "aemu/base/synchronization/Lock.h"
@@ -22,32 +20,25 @@
// The DisplayVk class holds the Vulkan and other states required to draw a
// frame in a host window.
-class DisplayVk : public gfxstream::Display {
+class DisplayVk {
public:
DisplayVk(const goldfish_vk::VulkanDispatch&, VkPhysicalDevice,
uint32_t swapChainQueueFamilyIndex, uint32_t compositorQueueFamilyIndex, VkDevice,
VkQueue compositorVkQueue, std::shared_ptr<android::base::Lock> compositorVkQueueLock,
VkQueue swapChainVkQueue, std::shared_ptr<android::base::Lock> swapChainVkQueueLock);
~DisplayVk();
-
- std::shared_future<void> post(const BorrowedImageInfo* info);
+ bool bindToSurface(VkSurfaceKHR, uint32_t width, uint32_t height);
void drainQueues();
- protected:
- void bindToSurfaceImpl(gfxstream::DisplaySurface* surface) override;
- void unbindFromSurfaceImpl() override;
-
- private:
- bool recreateSwapchain();
-
// The first component of the returned tuple is false when the swapchain is no longer valid and
// bindToSurface() needs to be called again. When the first component is true, the second
// component of the returned tuple is a/ future that will complete when the GPU side of work
// completes. The caller is responsible to guarantee the synchronization and the layout of
// ColorBufferCompositionInfo::m_vkImage is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL.
- std::tuple<bool, std::shared_future<void>> postImpl(const BorrowedImageInfo* info);
+ std::tuple<bool, std::shared_future<void>> post(const BorrowedImageInfo* info);
+ private:
VkFormatFeatureFlags getFormatFeatures(VkFormat, VkImageTiling);
bool canPost(const VkImageCreateInfo&);
@@ -106,7 +97,12 @@ class DisplayVk : public gfxstream::Display {
std::vector<std::unique_ptr<ImageBorrowResource>> m_imageBorrowResources;
std::unique_ptr<SwapChainStateVk> m_swapChainStateVk;
- bool m_needToRecreateSwapChain = true;
+
+ struct SurfaceState {
+ uint32_t m_width = 0;
+ uint32_t m_height = 0;
+ };
+ std::unique_ptr<SurfaceState> m_surfaceState;
std::unordered_map<VkFormat, VkFormatProperties> m_vkFormatProperties;
};
diff --git a/stream-servers/vulkan/VkCommonOperations.cpp b/stream-servers/vulkan/VkCommonOperations.cpp
index dfd3bcdb..da03f65a 100644
--- a/stream-servers/vulkan/VkCommonOperations.cpp
+++ b/stream-servers/vulkan/VkCommonOperations.cpp
@@ -1225,24 +1225,6 @@ void teardownGlobalVkEmulation() {
sVkEmulation = nullptr;
}
-std::unique_ptr<gfxstream::DisplaySurface> createDisplaySurface(FBNativeWindowType window,
- uint32_t width,
- uint32_t height) {
- if (!sVkEmulation || !sVkEmulation->live) {
- return nullptr;
- }
-
- auto surfaceVk = DisplaySurfaceVk::create(*sVkEmulation->ivk,
- sVkEmulation->instance,
- window);
- if (!surfaceVk) {
- VK_COMMON_ERROR("Failed to create DisplaySurfaceVk.");
- return nullptr;
- }
-
- return std::make_unique<gfxstream::DisplaySurface>(width, height, std::move(surfaceVk));
-}
-
// Precondition: sVkEmulation has valid device support info
bool allocExternalMemory(VulkanDispatch* vk, VkEmulation::ExternalMemoryInfo* info,
bool actuallyExternal, Optional<uint64_t> deviceAlignment) {
diff --git a/stream-servers/vulkan/VkCommonOperations.h b/stream-servers/vulkan/VkCommonOperations.h
index daefa790..22889959 100644
--- a/stream-servers/vulkan/VkCommonOperations.h
+++ b/stream-servers/vulkan/VkCommonOperations.h
@@ -362,7 +362,6 @@ struct VkEmulation {
// The implementation for Vulkan native swapchain. Only initialized in initVkEmulationFeatures
// if useVulkanNativeSwapchain is set.
std::unique_ptr<DisplayVk> displayVk;
- std::unique_ptr<DisplaySurfaceVk> displaySurfaceVk;
};
VkEmulation* createGlobalVkEmulation(VulkanDispatch* vk);
@@ -383,8 +382,6 @@ void initVkEmulationFeatures(std::unique_ptr<VkEmulationFeatures>);
VkEmulation* getGlobalVkEmulation();
void teardownGlobalVkEmulation();
-std::unique_ptr<gfxstream::DisplaySurface> createDisplaySurface(FBNativeWindowType window, uint32_t width, uint32_t height);
-
bool allocExternalMemory(
VulkanDispatch* vk, VkEmulation::ExternalMemoryInfo* info, bool actuallyExternal = true,
android::base::Optional<uint64_t> deviceAlignment = android::base::kNullopt);