Commit 38833111 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: implement eglSwapInterval

Uses FIFO with interval 1 and mailbox/immediate with interval 0 (with a fallback to FIFO). An end2end test is added to make sure the present mode is correctly set. Bug: angleproject:2932 Change-Id: I45d2b1e551b5c63c42ca3c8964bd5e62abd2d459 Reviewed-on: https://chromium-review.googlesource.com/c/1456622Reviewed-by: 's avatarIan Elliott <ianelliott@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent 3e01a518
...@@ -155,10 +155,15 @@ class WindowSurfaceVk : public SurfaceImpl ...@@ -155,10 +155,15 @@ class WindowSurfaceVk : public SurfaceImpl
void releaseSwapchainImages(RendererVk *renderer); void releaseSwapchainImages(RendererVk *renderer);
angle::Result nextSwapchainImage(DisplayVk *displayVk); angle::Result nextSwapchainImage(DisplayVk *displayVk);
angle::Result swapImpl(DisplayVk *displayVk, EGLint *rects, EGLint n_rects); angle::Result swapImpl(DisplayVk *displayVk, EGLint *rects, EGLint n_rects);
angle::Result resizeSwapHistory(DisplayVk *displayVk, size_t imageCount);
VkSurfaceCapabilitiesKHR mSurfaceCaps;
std::vector<VkPresentModeKHR> mPresentModes;
VkSwapchainKHR mSwapchain; VkSwapchainKHR mSwapchain;
// Cached information used to recreate swapchains. // Cached information used to recreate swapchains.
VkPresentModeKHR mSwapchainPresentMode; VkPresentModeKHR mSwapchainPresentMode; // Current swapchain mode
VkPresentModeKHR mDesiredSwapchainPresentMode; // Desired mode set through setSwapInterval()
uint32_t mMinImageCount; uint32_t mMinImageCount;
VkSurfaceTransformFlagBitsKHR mPreTransform; VkSurfaceTransformFlagBitsKHR mPreTransform;
VkCompositeAlphaFlagBitsKHR mCompositeAlpha; VkCompositeAlphaFlagBitsKHR mCompositeAlpha;
......
...@@ -248,7 +248,7 @@ egl::Config GenerateDefaultConfig(const RendererVk *renderer, ...@@ -248,7 +248,7 @@ egl::Config GenerateDefaultConfig(const RendererVk *renderer,
config.maxPBufferHeight = physicalDeviceProperties.limits.maxImageDimension2D; config.maxPBufferHeight = physicalDeviceProperties.limits.maxImageDimension2D;
config.maxPBufferPixels = ComputeMaximumPBufferPixels(physicalDeviceProperties); config.maxPBufferPixels = ComputeMaximumPBufferPixels(physicalDeviceProperties);
config.maxSwapInterval = 1; config.maxSwapInterval = 1;
config.minSwapInterval = 1; config.minSwapInterval = 0;
config.nativeRenderable = EGL_TRUE; config.nativeRenderable = EGL_TRUE;
config.nativeVisualID = 0; config.nativeVisualID = 0;
config.nativeVisualType = EGL_NONE; config.nativeVisualType = EGL_NONE;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "test_utils/ANGLETest.h" #include "test_utils/ANGLETest.h"
#include "util/EGLWindow.h" #include "util/EGLWindow.h"
#include "util/OSWindow.h" #include "util/OSWindow.h"
#include "util/Timer.h"
#if defined(ANGLE_ENABLE_D3D11) #if defined(ANGLE_ENABLE_D3D11)
# define INITGUID # define INITGUID
...@@ -347,6 +348,70 @@ TEST_P(EGLSurfaceTest, ResizeWindow) ...@@ -347,6 +348,70 @@ TEST_P(EGLSurfaceTest, ResizeWindow)
ASSERT_EQ(64, height); ASSERT_EQ(64, height);
} }
// Test that swap interval works.
TEST_P(EGLSurfaceTest, SwapInterval)
{
// On OSX, the test takes tens of milliseconds, which should be impossible with
// setSwapInterval(1) followed by 240 swaps as done below. http://anglebug.com/3140
ANGLE_SKIP_TEST_IF(IsOSX());
initializeDisplay();
initializeSurfaceWithDefaultConfig();
initializeContext();
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
eglSwapBuffers(mDisplay, mWindowSurface);
ASSERT_EGL_SUCCESS();
EGLint minInterval, maxInterval;
ASSERT_TRUE(eglGetConfigAttrib(mDisplay, mConfig, EGL_MIN_SWAP_INTERVAL, &minInterval));
ASSERT_TRUE(eglGetConfigAttrib(mDisplay, mConfig, EGL_MAX_SWAP_INTERVAL, &maxInterval));
for (int iter = 0; iter < 2; ++iter)
{
if (maxInterval >= 1)
{
std::unique_ptr<Timer> timer(CreateTimer());
eglSwapInterval(mDisplay, 1);
timer->start();
for (int i = 0; i < 180; ++i)
{
eglSwapBuffers(mDisplay, mWindowSurface);
}
timer->stop();
ASSERT_EGL_SUCCESS();
// 120 frames at 60fps should take 3s. At lower fps, it should take even longer. At
// 144fps, it would take 1.25s. Let's use 1s as a lower bound.
ASSERT_GT(timer->getElapsedTime(), 1);
}
if (minInterval <= 0)
{
std::unique_ptr<Timer> timer(CreateTimer());
eglSwapInterval(mDisplay, 0);
timer->start();
for (int i = 0; i < 100; ++i)
{
eglSwapBuffers(mDisplay, mWindowSurface);
}
timer->stop();
ASSERT_EGL_SUCCESS();
// 100 no-op swaps should be fairly fast, though there is no guarantee how fast it can
// be. 10ms per swap is probably a safe upper bound.
//
// TODO(syoussefi): if a surface doesn't truly allow no-vsync, this can fail. Until
// there's a way to query the exact minInterval from the surface, this test cannot be
// enabled.
// ASSERT_LT(timer->getElapsedTime(), 1);
}
}
}
// Test creating a surface that supports a EGLConfig with 16bit // Test creating a surface that supports a EGLConfig with 16bit
// support GL_RGB565 // support GL_RGB565
TEST_P(EGLSurfaceTest, CreateWithEGLConfig5650Support) TEST_P(EGLSurfaceTest, CreateWithEGLConfig5650Support)
......
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