Commit 9a7b0a2d by Jonah Ryan-Davis Committed by Commit Bot

Workaround bogus MscRate reported by some XWayland drivers.

XWayland defaults to a 1hz refresh rate when the surface is not visible, but this can sometimes cause issues in Chrome. If we see a bogus rate like that, ANGLE can just report 30hz. Bug: chromium:1042393 Change-Id: I554b05b4107cea528525ced6e95a5ce529eec3b1 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2388700 Commit-Queue: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent a3bf9092
...@@ -469,6 +469,12 @@ struct FeaturesGL : FeatureSetBase ...@@ -469,6 +469,12 @@ struct FeaturesGL : FeatureSetBase
"emulate_pack_skip_rows_and_pack_skip_pixels", FeatureCategory::OpenGLWorkarounds, "emulate_pack_skip_rows_and_pack_skip_pixels", FeatureCategory::OpenGLWorkarounds,
"GL_PACK_SKIP_ROWS and GL_PACK_SKIP_PIXELS are ignored in Apple's OpenGL driver.", &members, "GL_PACK_SKIP_ROWS and GL_PACK_SKIP_PIXELS are ignored in Apple's OpenGL driver.", &members,
"https://anglebug.com/4849"}; "https://anglebug.com/4849"};
// Some drivers return bogus/1hz values for GetMscRate, which we may want to clamp
Feature clampMscRate = {
"clamp_msc_rate", FeatureCategory::OpenGLWorkarounds,
"Some drivers return bogus values for GetMscRate, so we clamp it to 30Hz", &members,
"https://crbug.com/1042393"};
}; };
inline FeaturesGL::FeaturesGL() = default; inline FeaturesGL::FeaturesGL() = default;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "libANGLE/renderer/driver_utils.h" #include "libANGLE/renderer/driver_utils.h"
#include "common/platform.h" #include "common/platform.h"
#include "common/system_utils.h"
#if defined(ANGLE_PLATFORM_ANDROID) #if defined(ANGLE_PLATFORM_ANDROID)
# include <sys/system_properties.h> # include <sys/system_properties.h>
...@@ -252,4 +253,33 @@ OSVersion GetLinuxOSVersion() ...@@ -252,4 +253,33 @@ OSVersion GetLinuxOSVersion()
return OSVersion(0, 0, 0); return OSVersion(0, 0, 0);
} }
// There are multiple environment variables that may or may not be set during Wayland
// sessions, including WAYLAND_DISPLAY, XDG_SESSION_TYPE, and DESKTOP_SESSION
bool IsWayland()
{
static bool checked = false;
static bool isWayland = false;
if (!checked)
{
if (IsLinux())
{
if (!angle::GetEnvironmentVar("WAYLAND_DISPLAY").empty())
{
isWayland = true;
}
else if (angle::GetEnvironmentVar("XDG_SESSION_TYPE") == "wayland")
{
isWayland = true;
}
else if (angle::GetEnvironmentVar("DESKTOP_SESSION").find("wayland") !=
std::string::npos)
{
isWayland = true;
}
}
checked = true;
}
return isWayland;
}
} // namespace rx } // namespace rx
...@@ -164,6 +164,8 @@ inline bool IsFuchsia() ...@@ -164,6 +164,8 @@ inline bool IsFuchsia()
#endif #endif
} }
bool IsWayland();
struct OSVersion struct OSVersion
{ {
OSVersion(); OSVersion();
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "common/Optional.h" #include "common/Optional.h"
#include "libANGLE/renderer/gl/DisplayGL.h" #include "libANGLE/renderer/gl/DisplayGL.h"
#include "libANGLE/renderer/gl/RendererGL.h"
#include "libANGLE/renderer/gl/glx/FunctionsGLX.h" #include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
namespace rx namespace rx
...@@ -97,6 +98,8 @@ class DisplayGLX : public DisplayGL ...@@ -97,6 +98,8 @@ class DisplayGLX : public DisplayGL
void populateFeatureList(angle::FeatureList *features) override; void populateFeatureList(angle::FeatureList *features) override;
RendererGL *getRenderer() const { return mRenderer.get(); }
private: private:
egl::Error initializeContext(glx::FBConfig config, egl::Error initializeContext(glx::FBConfig config,
const egl::AttributeMap &eglAttributes, const egl::AttributeMap &eglAttributes,
......
...@@ -262,6 +262,15 @@ egl::Error WindowSurfaceGLX::getMscRate(EGLint *numerator, EGLint *denominator) ...@@ -262,6 +262,15 @@ egl::Error WindowSurfaceGLX::getMscRate(EGLint *numerator, EGLint *denominator)
{ {
return egl::EglBadSurface() << "glXGetMscRateOML failed."; return egl::EglBadSurface() << "glXGetMscRateOML failed.";
} }
if (mGLXDisplay->getRenderer()->getFeatures().clampMscRate.enabled)
{
// Clamp any refresh rate under 2Hz to 30Hz
if (*numerator < *denominator * 2)
{
*numerator = 30;
*denominator = 1;
}
}
return egl::NoError(); return egl::NoError();
} }
......
...@@ -1796,6 +1796,12 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature ...@@ -1796,6 +1796,12 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
// workaround's being restricted to existing desktop GPUs. // workaround's being restricted to existing desktop GPUs.
ANGLE_FEATURE_CONDITION(features, emulatePackSkipRowsAndPackSkipPixels, ANGLE_FEATURE_CONDITION(features, emulatePackSkipRowsAndPackSkipPixels,
IsApple() && (isAMD || isIntel || isNvidia)); IsApple() && (isAMD || isIntel || isNvidia));
// http://crbug.com/1042393
// XWayland defaults to a 1hz refresh rate when the "surface is not visible", which sometimes
// causes issues in Chrome. To get around this, default to a 30Hz refresh rate if we see bogus
// from the driver.
ANGLE_FEATURE_CONDITION(features, clampMscRate, IsLinux() && IsWayland());
} }
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features) void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
......
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