@@ -1368,8 +1368,7 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk, bool *anyMat
13681368 if ((mState .attributes .getAsInt (EGL_RENDER_BUFFER, EGL_BACK_BUFFER) == EGL_SINGLE_BUFFER) &&
13691369 supportsPresentMode (vk::PresentMode::SharedDemandRefreshKHR))
13701370 {
1371- std::vector<vk::PresentMode> presentModes = {vk::PresentMode::SharedDemandRefreshKHR};
1372- mDesiredSwapchainPresentMode = GetDesiredPresentMode (presentModes, 0 );
1371+ setDesiredSwapchainPresentMode (vk::PresentMode::SharedDemandRefreshKHR);
13731372 }
13741373
13751374 mCompressionFlags = VK_IMAGE_COMPRESSION_DISABLED_EXT;
@@ -1615,6 +1614,10 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context, const gl::E
16151614 imageUsageFlags |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
16161615 }
16171616
1617+ mSwapchainPresentMode = getDesiredSwapchainPresentMode ();
1618+ mWidth = extents.width ;
1619+ mHeight = extents.height ;
1620+
16181621 VkSwapchainCreateInfoKHR swapchainInfo = {};
16191622 swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
16201623 swapchainInfo.flags = mState .hasProtectedContent () ? VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR : 0 ;
@@ -1631,8 +1634,8 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context, const gl::E
16311634 swapchainInfo.pQueueFamilyIndices = nullptr ;
16321635 swapchainInfo.preTransform = mPreTransform ;
16331636 swapchainInfo.compositeAlpha = mCompositeAlpha ;
1634- swapchainInfo.presentMode = vk::ConvertPresentModeToVkPresentMode (mDesiredSwapchainPresentMode );
1635- swapchainInfo.clipped = VK_TRUE;
1637+ swapchainInfo.presentMode = vk::ConvertPresentModeToVkPresentMode (mSwapchainPresentMode );
1638+ swapchainInfo.clipped = VK_TRUE;
16361639 swapchainInfo.oldSwapchain = mLastSwapchain ;
16371640
16381641 VkImageCompressionControlEXT compressionInfo = {};
@@ -1708,17 +1711,26 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context, const gl::E
17081711 }
17091712
17101713 // The implementation must always return the given present mode as compatible with itself.
1711- ASSERT (IsCompatiblePresentMode (mDesiredSwapchainPresentMode , mCompatiblePresentModes .data (),
1714+ ASSERT (IsCompatiblePresentMode (mSwapchainPresentMode , mCompatiblePresentModes .data (),
17121715 mCompatiblePresentModes .size ()));
17131716
1717+ // On Android we expect VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR and
1718+ // VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR to be compatible.
1719+ ASSERT (!IsAndroid () || !isSharedPresentMode () ||
1720+ IsCompatiblePresentMode (
1721+ mSwapchainPresentMode == vk::PresentMode::SharedDemandRefreshKHR
1722+ ? vk::PresentMode::SharedContinuousRefreshKHR
1723+ : vk::PresentMode::SharedDemandRefreshKHR,
1724+ mCompatiblePresentModes .data (), mCompatiblePresentModes .size ()));
1725+
17141726 // Vulkan spec says "The per-present mode image counts may be less-than or greater-than the
17151727 // image counts returned when VkSurfacePresentModeEXT is not provided.". Use the per present
17161728 // mode imageCount here. Otherwise we may get into
17171729 // VUID-VkSwapchainCreateInfoKHR-presentMode-02839.
17181730 mSurfaceCaps = surfaceCaps2.surfaceCapabilities ;
17191731 }
17201732
1721- mMinImageCount = GetMinImageCount (renderer, mSurfaceCaps , mDesiredSwapchainPresentMode );
1733+ mMinImageCount = GetMinImageCount (renderer, mSurfaceCaps , mSwapchainPresentMode );
17221734 swapchainInfo.minImageCount = mMinImageCount ;
17231735
17241736 VkSwapchainPresentModesCreateInfoEXT compatibleModesInfo = {};
@@ -1740,7 +1752,7 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context, const gl::E
17401752 mCompatiblePresentModes [0 ] = swapchainInfo.presentMode ;
17411753 }
17421754
1743- if (isSharedPresentModeDesired ())
1755+ if (isSharedPresentMode ())
17441756 {
17451757 swapchainInfo.minImageCount = 1 ;
17461758
@@ -1760,9 +1772,6 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context, const gl::E
17601772 VkSwapchainKHR newSwapChain = VK_NULL_HANDLE;
17611773 ANGLE_VK_TRY (context, vkCreateSwapchainKHR (device, &swapchainInfo, nullptr , &newSwapChain));
17621774 mLastSwapchain = newSwapChain;
1763- mSwapchainPresentMode = mDesiredSwapchainPresentMode ;
1764- mWidth = extents.width ;
1765- mHeight = extents.height ;
17661775
17671776 // If frame timestamp was enabled for the surface, [re]enable it when [re]creating the swapchain
17681777 if (renderer->getFeatures ().supportsTimestampSurfaceAttribute .enabled &&
@@ -1896,7 +1905,7 @@ angle::Result WindowSurfaceVk::queryAndAdjustSurfaceCaps(ContextVk *contextVk,
18961905 VkSurfacePresentModeEXT surfacePresentMode = {};
18971906 surfacePresentMode.sType = VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_EXT;
18981907 surfacePresentMode.presentMode =
1899- vk::ConvertPresentModeToVkPresentMode (mDesiredSwapchainPresentMode );
1908+ vk::ConvertPresentModeToVkPresentMode (getDesiredSwapchainPresentMode () );
19001909 vk::AddToPNextChain (&surfaceInfo2, &surfacePresentMode);
19011910
19021911 VkSurfaceCapabilities2KHR surfaceCaps2 = {};
@@ -1933,8 +1942,10 @@ angle::Result WindowSurfaceVk::checkForOutOfDateSwapchain(ContextVk *contextVk,
19331942{
19341943 ASSERT (mAcquireOperation .state != impl::ImageAcquireState::Ready);
19351944
1945+ vk::PresentMode desiredSwapchainPresentMode = getDesiredSwapchainPresentMode ();
1946+
19361947 bool presentModeIncompatible =
1937- !IsCompatiblePresentMode (mDesiredSwapchainPresentMode , mCompatiblePresentModes .data (),
1948+ !IsCompatiblePresentMode (desiredSwapchainPresentMode , mCompatiblePresentModes .data (),
19381949 mCompatiblePresentModes .size ());
19391950 bool swapchainMissing = (mSwapchain == VK_NULL_HANDLE);
19401951 bool needRecreate = forceRecreate || presentModeIncompatible || swapchainMissing;
@@ -1969,7 +1980,7 @@ angle::Result WindowSurfaceVk::checkForOutOfDateSwapchain(ContextVk *contextVk,
19691980 mSurfaceCaps .currentExtent .width != swapchainWidth ||
19701981 mSurfaceCaps .currentExtent .height != swapchainHeight ||
19711982 GetMinImageCount (contextVk->getRenderer (), mSurfaceCaps ,
1972- mDesiredSwapchainPresentMode ) != mMinImageCount ;
1983+ desiredSwapchainPresentMode ) != mMinImageCount ;
19731984 }
19741985
19751986 // If anything has changed, recreate the swapchain.
@@ -2157,7 +2168,7 @@ egl::Error WindowSurfaceVk::swap(const gl::Context *context)
21572168 //
21582169 // Some apps issue eglSwapBuffers after glFlush unnecessary, causing the CPU throttling logic to
21592170 // effectively wait for the just submitted commands.
2160- if (isSharedPresentMode () && mSwapchainPresentMode == mDesiredSwapchainPresentMode )
2171+ if (isSharedPresentMode () && mSwapchainPresentMode == getDesiredSwapchainPresentMode () )
21612172 {
21622173 const angle::Result result = vk::GetImpl (context)->flush (context);
21632174 return angle::ToEGL (result, EGL_BAD_SURFACE);
@@ -2438,19 +2449,20 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
24382449 vk::AddToPNextChain (&presentInfo, &presentFenceInfo);
24392450
24402451 // Update the present mode if necessary and possible
2441- if (mSwapchainPresentMode != mDesiredSwapchainPresentMode &&
2442- IsCompatiblePresentMode (mDesiredSwapchainPresentMode , mCompatiblePresentModes .data (),
2452+ vk::PresentMode desiredSwapchainPresentMode = getDesiredSwapchainPresentMode ();
2453+ if (mSwapchainPresentMode != desiredSwapchainPresentMode &&
2454+ IsCompatiblePresentMode (desiredSwapchainPresentMode, mCompatiblePresentModes .data (),
24432455 mCompatiblePresentModes .size ()))
24442456 {
2445- presentMode = vk::ConvertPresentModeToVkPresentMode (mDesiredSwapchainPresentMode );
2457+ presentMode = vk::ConvertPresentModeToVkPresentMode (desiredSwapchainPresentMode );
24462458
24472459 presentModeInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODE_INFO_EXT;
24482460 presentModeInfo.swapchainCount = 1 ;
24492461 presentModeInfo.pPresentModes = &presentMode;
24502462
24512463 vk::AddToPNextChain (&presentInfo, &presentModeInfo);
24522464
2453- mSwapchainPresentMode = mDesiredSwapchainPresentMode ;
2465+ mSwapchainPresentMode = desiredSwapchainPresentMode ;
24542466 }
24552467 }
24562468
@@ -2882,7 +2894,7 @@ VkResult WindowSurfaceVk::postProcessUnlockedAcquire(vk::Context *context)
28822894 ASSERT (semaphore == acquireImageSemaphore);
28832895 if (primaryCommandBuffer.end () != VK_SUCCESS)
28842896 {
2885- mDesiredSwapchainPresentMode = vk::PresentMode::FifoKHR;
2897+ setDesiredSwapchainPresentMode ( vk::PresentMode::FifoKHR) ;
28862898 return VK_ERROR_OUT_OF_DATE_KHR;
28872899 }
28882900 QueueSerial queueSerial;
@@ -2891,7 +2903,7 @@ VkResult WindowSurfaceVk::postProcessUnlockedAcquire(vk::Context *context)
28912903 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
28922904 &queueSerial) != angle::Result::Continue)
28932905 {
2894- mDesiredSwapchainPresentMode = vk::PresentMode::FifoKHR;
2906+ setDesiredSwapchainPresentMode ( vk::PresentMode::FifoKHR) ;
28952907 return VK_ERROR_OUT_OF_DATE_KHR;
28962908 }
28972909 mUse .setQueueSerial (queueSerial);
@@ -2964,6 +2976,16 @@ egl::Error WindowSurfaceVk::getMscRate(EGLint * /*numerator*/, EGLint * /*denomi
29642976 return egl::EglBadAccess ();
29652977}
29662978
2979+ vk::PresentMode WindowSurfaceVk::getDesiredSwapchainPresentMode () const
2980+ {
2981+ return mDesiredSwapchainPresentMode .load (std::memory_order_relaxed);
2982+ }
2983+
2984+ void WindowSurfaceVk::setDesiredSwapchainPresentMode (vk::PresentMode presentMode)
2985+ {
2986+ mDesiredSwapchainPresentMode .store (presentMode, std::memory_order_relaxed);
2987+ }
2988+
29672989void WindowSurfaceVk::setSwapInterval (DisplayVk *displayVk, EGLint interval)
29682990{
29692991 // Don't let setSwapInterval change presentation mode if using SHARED present.
@@ -2979,7 +3001,7 @@ void WindowSurfaceVk::setSwapInterval(DisplayVk *displayVk, EGLint interval)
29793001
29803002 interval = gl::clamp (interval, minSwapInterval, maxSwapInterval);
29813003
2982- mDesiredSwapchainPresentMode = GetDesiredPresentMode (mPresentModes , interval);
3004+ setDesiredSwapchainPresentMode ( GetDesiredPresentMode (mPresentModes , interval) );
29833005
29843006 // On the next swap, if the desired present mode is different from the current one, the
29853007 // swapchain will be recreated.
@@ -3230,19 +3252,14 @@ egl::Error WindowSurfaceVk::setAutoRefreshEnabled(bool enabled)
32303252 : vk::PresentMode::SharedDemandRefreshKHR;
32313253
32323254 // We only expose EGL_ANDROID_front_buffer_auto_refresh extension on Android with supported
3233- // VK_EXT_swapchain_maintenance1 extension, where present modes expected to be compatible.
3234- if (!IsCompatiblePresentMode (newDesiredSwapchainPresentMode, mCompatiblePresentModes .data (),
3235- mCompatiblePresentModes .size ()))
3236- {
3237- // This should not happen, unless some specific Android platform requires swapchain
3238- // recreation for these present modes, in which case EGL_ANDROID_front_buffer_auto_refresh
3239- // should not be exposed or this code should be updated to support this scenario.
3240- return egl::EglBadMatch ();
3241- }
3255+ // VK_EXT_swapchain_maintenance1 extension, where current and new present modes expected to be
3256+ // compatible. Can't use |mCompatiblePresentModes| here to check if this is true because it is
3257+ // not thread safe. Instead of the check, ASSERT is added to the |createSwapChain| method where
3258+ // |mCompatiblePresentModes| are queried.
32423259
32433260 // Simply change mDesiredSwapchainPresentMode regardless if we are already in single buffer mode
32443261 // or not, since compatible present modes does not require swapchain recreation.
3245- mDesiredSwapchainPresentMode = newDesiredSwapchainPresentMode;
3262+ setDesiredSwapchainPresentMode ( newDesiredSwapchainPresentMode) ;
32463263
32473264 return egl::NoError ();
32483265}
@@ -3333,11 +3350,11 @@ egl::Error WindowSurfaceVk::setRenderBuffer(EGLint renderBuffer)
33333350 {
33343351 return egl::EglBadMatch ();
33353352 }
3336- mDesiredSwapchainPresentMode = presentMode;
3353+ setDesiredSwapchainPresentMode ( presentMode) ;
33373354 }
33383355 else // EGL_BACK_BUFFER
33393356 {
3340- mDesiredSwapchainPresentMode = vk::PresentMode::FifoKHR;
3357+ setDesiredSwapchainPresentMode ( vk::PresentMode::FifoKHR) ;
33413358 }
33423359 return egl::NoError ();
33433360}
0 commit comments