diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2022-10-12 18:02:45 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2022-10-12 18:02:45 +0000 |
commit | 595fedbd3ad8b5158aa892f2936d608573e0dfbe (patch) | |
tree | 46fadf99b0f34b620aa9520ea614325e191346e4 | |
parent | 12a7d979fecae3a804251b382a4480c00a9baa6f (diff) | |
parent | a34429d666f8caf299703866f08188a8dc57ccd7 (diff) | |
download | vulkan-cereal-595fedbd3ad8b5158aa892f2936d608573e0dfbe.tar.gz |
Merge "Revert "Add Display, DisplaySurface, and DisplaySurfaceVk""
-rw-r--r-- | stream-servers/Android.bp | 2 | ||||
-rw-r--r-- | stream-servers/CMakeLists.txt | 2 | ||||
-rw-r--r-- | stream-servers/Display.cpp | 50 | ||||
-rw-r--r-- | stream-servers/Display.h | 43 | ||||
-rw-r--r-- | stream-servers/DisplaySurface.cpp | 66 | ||||
-rw-r--r-- | stream-servers/DisplaySurface.h | 67 | ||||
-rw-r--r-- | stream-servers/FrameBuffer.cpp | 46 | ||||
-rw-r--r-- | stream-servers/FrameBuffer.h | 8 | ||||
-rw-r--r-- | stream-servers/PostWorker.cpp | 17 | ||||
-rw-r--r-- | stream-servers/tests/DisplayVk_unittest.cpp | 25 | ||||
-rw-r--r-- | stream-servers/vulkan/Android.bp | 1 | ||||
-rw-r--r-- | stream-servers/vulkan/CMakeLists.txt | 1 | ||||
-rw-r--r-- | stream-servers/vulkan/DisplaySurfaceVk.cpp | 61 | ||||
-rw-r--r-- | stream-servers/vulkan/DisplaySurfaceVk.h | 43 | ||||
-rw-r--r-- | stream-servers/vulkan/DisplayVk.cpp | 93 | ||||
-rw-r--r-- | stream-servers/vulkan/DisplayVk.h | 24 | ||||
-rw-r--r-- | stream-servers/vulkan/VkCommonOperations.cpp | 18 | ||||
-rw-r--r-- | stream-servers/vulkan/VkCommonOperations.h | 3 |
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); |