Commit 1c6adcad by Ian Elliott Committed by Commit Bot

Reimplement WindowSurfaceVk::checkForOutOfDateSwapchain

Simplified and made faster for devices that return VK_ERROR_OUT_OF_DATE_KHR (and VK_SUBOPTIMAL_KHR). Bug: b/168327817 Change-Id: Iec3dad8d528eb7d3645062a6736b397514432829 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2464921 Commit-Queue: Ian Elliott <ianelliott@google.com> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com>
parent 2aaeb81d
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "libANGLE/Display.h" #include "libANGLE/Display.h"
#include "libANGLE/Overlay.h" #include "libANGLE/Overlay.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h" #include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h" #include "libANGLE/renderer/vulkan/FramebufferVk.h"
...@@ -1010,54 +1011,73 @@ bool WindowSurfaceVk::isMultiSampled() const ...@@ -1010,54 +1011,73 @@ bool WindowSurfaceVk::isMultiSampled() const
return mColorImageMS.valid(); return mColorImageMS.valid();
} }
angle::Result WindowSurfaceVk::queryAndAdjustSurfaceCaps(ContextVk *contextVk,
VkSurfaceCapabilitiesKHR *surfaceCaps)
{
const VkPhysicalDevice &physicalDevice = contextVk->getRenderer()->getPhysicalDevice();
ANGLE_VK_TRY(contextVk,
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, mSurface, surfaceCaps));
if (surfaceCaps->currentExtent.width == kSurfaceSizedBySwapchain)
{
ASSERT(surfaceCaps->currentExtent.height == kSurfaceSizedBySwapchain);
ASSERT(!IsAndroid());
// vkGetPhysicalDeviceSurfaceCapabilitiesKHR does not provide useful extents for some
// platforms (e.g. Fuschia). Therefore, we must query the window size via a
// platform-specific mechanism. Add those extents to the surfaceCaps
gl::Extents currentExtents;
ANGLE_TRY(getCurrentWindowSize(contextVk, &currentExtents));
surfaceCaps->currentExtent.width = currentExtents.width;
surfaceCaps->currentExtent.height = currentExtents.height;
}
return angle::Result::Continue;
}
angle::Result WindowSurfaceVk::checkForOutOfDateSwapchain(ContextVk *contextVk, angle::Result WindowSurfaceVk::checkForOutOfDateSwapchain(ContextVk *contextVk,
bool presentOutOfDate) bool presentOutOfDate)
{ {
bool swapIntervalChanged = mSwapchainPresentMode != mDesiredSwapchainPresentMode; bool swapIntervalChanged = mSwapchainPresentMode != mDesiredSwapchainPresentMode;
presentOutOfDate = presentOutOfDate || swapIntervalChanged;
// If anything has changed, recreate the swapchain. // If there's no change, early out.
if (swapIntervalChanged || presentOutOfDate || if (!contextVk->getRenderer()->getFeatures().perFrameWindowSizeQuery.enabled &&
contextVk->getRenderer()->getFeatures().perFrameWindowSizeQuery.enabled) !presentOutOfDate)
{ {
gl::Extents swapchainExtents(getWidth(), getHeight(), 1); return angle::Result::Continue;
}
gl::Extents currentExtents; // Get the latest surface capabilities.
ANGLE_TRY(getCurrentWindowSize(contextVk, &currentExtents)); ANGLE_TRY(queryAndAdjustSurfaceCaps(contextVk, &mSurfaceCaps));
// If window size has changed, check with surface capabilities. It has been observed on if (contextVk->getRenderer()->getFeatures().perFrameWindowSizeQuery.enabled &&
// Android that `getCurrentWindowSize()` returns 1920x1080 for example, while surface !presentOutOfDate)
// capabilities returns the size the surface was created with. {
const VkPhysicalDevice &physicalDevice = contextVk->getRenderer()->getPhysicalDevice(); // This device generates neither VK_ERROR_OUT_OF_DATE_KHR nor VK_SUBOPTIMAL_KHR. Check for
ANGLE_VK_TRY(contextVk, vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, mSurface, // whether the size and/or rotation have changed since the swapchain was created.
&mSurfaceCaps)); uint32_t swapchainWidth = getWidth();
if (contextVk->getFeatures().enablePreRotateSurfaces.enabled) uint32_t swapchainHeight = getHeight();
{ presentOutOfDate = mSurfaceCaps.currentTransform != mPreTransform ||
// Update the surface's transform, which can change even if the window size does not. mSurfaceCaps.currentExtent.width != swapchainWidth ||
mPreTransform = mSurfaceCaps.currentTransform; mSurfaceCaps.currentExtent.height != swapchainHeight;
} }
if (currentExtents != swapchainExtents) // If anything has changed, recreate the swapchain.
{ if (!presentOutOfDate)
uint32_t width = mSurfaceCaps.currentExtent.width; {
uint32_t height = mSurfaceCaps.currentExtent.height; return angle::Result::Continue;
}
if (width != kSurfaceSizedBySwapchain) gl::Extents newSwapchainExtents(mSurfaceCaps.currentExtent.width,
{ mSurfaceCaps.currentExtent.height, 1);
ASSERT(height != kSurfaceSizedBySwapchain);
currentExtents.width = width;
currentExtents.height = height;
}
}
// Check for window resize and recreate swapchain if necessary. if (contextVk->getFeatures().enablePreRotateSurfaces.enabled)
// Work-around for some device which does not return OUT_OF_DATE after window resizing {
if (swapIntervalChanged || presentOutOfDate || currentExtents != swapchainExtents) // Update the surface's transform, which can change even if the window size does not.
{ mPreTransform = mSurfaceCaps.currentTransform;
ANGLE_TRY(recreateSwapchain(contextVk, currentExtents));
}
} }
return angle::Result::Continue; return recreateSwapchain(contextVk, newSwapchainExtents);
} }
void WindowSurfaceVk::releaseSwapchainImages(ContextVk *contextVk) void WindowSurfaceVk::releaseSwapchainImages(ContextVk *contextVk)
......
...@@ -264,6 +264,8 @@ class WindowSurfaceVk : public SurfaceVk ...@@ -264,6 +264,8 @@ class WindowSurfaceVk : public SurfaceVk
angle::Result createSwapChain(vk::Context *context, angle::Result createSwapChain(vk::Context *context,
const gl::Extents &extents, const gl::Extents &extents,
VkSwapchainKHR oldSwapchain); VkSwapchainKHR oldSwapchain);
angle::Result queryAndAdjustSurfaceCaps(ContextVk *contextVk,
VkSurfaceCapabilitiesKHR *surfaceCaps);
angle::Result checkForOutOfDateSwapchain(ContextVk *contextVk, bool presentOutOfDate); angle::Result checkForOutOfDateSwapchain(ContextVk *contextVk, bool presentOutOfDate);
angle::Result resizeSwapchainImages(vk::Context *context, uint32_t imageCount); angle::Result resizeSwapchainImages(vk::Context *context, uint32_t imageCount);
void releaseSwapchainImages(ContextVk *contextVk); void releaseSwapchainImages(ContextVk *contextVk);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment