Commit 92db3c68 by Ian Elliott Committed by Commit Bot

Vulkan: Disable rotating damage rectangles on Android

This fixes visual problems with Android games that use eglSwapBuffersWithDamageKHR(). In 90/270-degree cases, the damage rectangles are being double-rotated, leaving them 90-degrees out of alignment with the window. On Android, VK_KHR_incremental_present is built on top of the same platform code as eglSwapBuffersWithDamageKHR(). The platform code rotates all damage rectangles (assuming they are application-provided). Therefore, ANGLE should not also pre-rotate damage rectangles. Test: Black Desert Mobile Test: Grand Theft Auto: San Andreas Test: Extreme Car Driving Simulator Bug: b/181796746 Change-Id: I6510e7540bb00afc75863e8ae8a9ea3841d1641d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2744984Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Commit-Queue: Ian Elliott <ianelliott@google.com>
parent 36770173
...@@ -90,6 +90,16 @@ struct FeaturesVk : FeatureSetBase ...@@ -90,6 +90,16 @@ struct FeaturesVk : FeatureSetBase
"supportsIncrementalPresent", FeatureCategory::VulkanFeatures, "supportsIncrementalPresent", FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_KHR_incremental_present extension", &members}; "VkDevice supports the VK_KHR_incremental_present extension", &members};
// Whether the Vulkan presentation engine rotates the present region rectangles of the
// VK_KHR_incremental_present extension in pre-rotation situations. The Android presentation
// engine assumes that these rectangles need to be rotated, and thus ANGLE should not also
// pre-rotate them.
Feature disablePreRotateIncrementalPresentRectangles = {
"disablePreRotateIncrementalPresentRectangles", FeatureCategory::VulkanFeatures,
"Presentation engine performs necessary rotation for present region rectangles of the "
"VK_KHR_incremental_present extension",
&members};
// Whether texture copies on cube map targets should be done on GPU. This is a workaround for // Whether texture copies on cube map targets should be done on GPU. This is a workaround for
// Intel drivers on windows that have an issue with creating single-layer views on cube map // Intel drivers on windows that have an issue with creating single-layer views on cube map
// textures. // textures.
......
...@@ -1935,6 +1935,13 @@ void RendererVk::initFeatures(DisplayVk *displayVk, ...@@ -1935,6 +1935,13 @@ void RendererVk::initFeatures(DisplayVk *displayVk,
&mFeatures, supportsIncrementalPresent, &mFeatures, supportsIncrementalPresent,
ExtensionFound(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME, deviceExtensionNames)); ExtensionFound(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME, deviceExtensionNames));
// The Vulkan specification for the VK_KHR_incremental_present extension does not address
// rotation. In Android, this extension is implemented on top of the same platform code as
// eglSwapBuffersWithDamageKHR(), which code assumes that it should rotate each rectangle. To
// avoid double-rotating damage rectangles on Android, we must avoid pre-rotating
// application-provided rectangles. See: https://issuetracker.google.com/issues/181796746
ANGLE_FEATURE_CONDITION(&mFeatures, disablePreRotateIncrementalPresentRectangles, IsAndroid());
#if defined(ANGLE_PLATFORM_ANDROID) #if defined(ANGLE_PLATFORM_ANDROID)
ANGLE_FEATURE_CONDITION( ANGLE_FEATURE_CONDITION(
&mFeatures, supportsAndroidHardwareBuffer, &mFeatures, supportsAndroidHardwareBuffer,
......
...@@ -1253,29 +1253,7 @@ egl::Error WindowSurfaceVk::swapWithDamage(const gl::Context *context, ...@@ -1253,29 +1253,7 @@ egl::Error WindowSurfaceVk::swapWithDamage(const gl::Context *context,
{ {
DisplayVk *displayVk = vk::GetImpl(context->getDisplay()); DisplayVk *displayVk = vk::GetImpl(context->getDisplay());
angle::Result result; angle::Result result;
if (n_rects == 1 && rects[0] == 0 && rects[1] == 0 && rects[2] == getWidth() && result = swapImpl(context, rects, n_rects, nullptr);
rects[3] == getHeight())
{
// Work-around a defect on at least the Pixel 4 family, likely in the hardware composer
// (HWC) driver that SurfaceFlinger (SF) uses to composite results to the display. When
// some games switch FROM one EGLSurface and using eglSwapBuffers() TO a new EGLSurface and
// using eglSwapBuffersWithDamageKHR(), the user will frequently see the right half of the
// window stick with previous contents. Causing SF to composite the window differently
// (e.g. swiping to show the nagivation buttons or to show the list of apps) immediately
// stops the problem, further pointing to a HWC bug.
//
// In this case, the "damage area" is the entire window, which means that a normal
// eglSwapBuffers() should be functionally identical (except for whatever SW/HWC will do
// differently for compositing).
//
// TODO: Remove this work-around when we no longer support affected devices (at least Pixel
// 4 XL, but not Arm-GPU devices). https://issuetracker.google.com/issues/182213414
result = swapImpl(context, nullptr, 0, nullptr);
}
else
{
result = swapImpl(context, rects, n_rects, nullptr);
}
return angle::ToEGL(result, displayVk, EGL_BAD_SURFACE); return angle::ToEGL(result, displayVk, EGL_BAD_SURFACE);
} }
...@@ -1439,7 +1417,8 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk, ...@@ -1439,7 +1417,8 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
rect.extent.width = gl::clamp(*eglRects++, 0, width - rect.offset.x); rect.extent.width = gl::clamp(*eglRects++, 0, width - rect.offset.x);
rect.extent.height = gl::clamp(*eglRects++, 0, height - rect.offset.y); rect.extent.height = gl::clamp(*eglRects++, 0, height - rect.offset.y);
rect.layer = 0; rect.layer = 0;
if (Is90DegreeRotation(getPreTransform())) if (Is90DegreeRotation(getPreTransform()) &&
!contextVk->getFeatures().disablePreRotateIncrementalPresentRectangles.enabled)
{ {
std::swap(rect.offset.x, rect.offset.y); std::swap(rect.offset.x, rect.offset.y);
std::swap(rect.extent.width, rect.extent.height); std::swap(rect.extent.width, rect.extent.height);
......
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