mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 06:09:19 +00:00
Bug 1843782 - WebGL software rendering when mesa/vmwgfx driver detected r=jgilbert a=RyanVM
Original Revision: https://phabricator.services.mozilla.com/D192039 Differential Revision: https://phabricator.services.mozilla.com/D195330
This commit is contained in:
parent
e942dd7535
commit
aae82b51e3
@ -98,7 +98,8 @@ class gfxVarReceiver;
|
||||
_(AllowBackdropFilter, bool, true) \
|
||||
_(WebglOopAsyncPresentForceSync, bool, true) \
|
||||
_(UseAcceleratedCanvas2D, bool, false) \
|
||||
_(UseWebRenderDCompSwVideoOverlayWin, bool, false)
|
||||
_(UseWebRenderDCompSwVideoOverlayWin, bool, false) \
|
||||
_(WebglUseHardware, bool, true)
|
||||
|
||||
/* Add new entries above this line. */
|
||||
|
||||
|
@ -1139,6 +1139,28 @@ RefPtr<GLContextEGL> GLContextEGL::CreateWithoutSurface(
|
||||
const std::shared_ptr<EglDisplay> egl, const GLContextCreateDesc& desc,
|
||||
nsACString* const out_failureId) {
|
||||
const auto WithUseGles = [&](const bool useGles) -> RefPtr<GLContextEGL> {
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
// First try creating a context with no config and no surface, this is what
|
||||
// we really want, and seems to be the only way to make selecting software
|
||||
// Mesa init properly when it's not the first device.
|
||||
if (egl->IsExtensionSupported(EGLExtension::KHR_no_config_context) &&
|
||||
egl->IsExtensionSupported(EGLExtension::KHR_surfaceless_context)) {
|
||||
// These extensions have been supported by mesa and nvidia drivers
|
||||
// since 2014 or earlier, this is the preferred code path
|
||||
auto fullDesc = GLContextDesc{desc};
|
||||
fullDesc.isOffscreen = true;
|
||||
RefPtr<GLContextEGL> gl = GLContextEGL::CreateGLContext(
|
||||
egl, fullDesc, EGL_NO_CONFIG, EGL_NO_SURFACE, useGles, EGL_NO_CONFIG,
|
||||
out_failureId);
|
||||
if (gl) {
|
||||
return gl;
|
||||
}
|
||||
NS_WARNING(
|
||||
"Failed to create GLContext with no config and no surface, will try "
|
||||
"ChooseConfig");
|
||||
}
|
||||
#endif
|
||||
|
||||
const EGLConfig surfaceConfig = ChooseConfig(*egl, desc, useGles);
|
||||
if (surfaceConfig == EGL_NO_CONFIG) {
|
||||
*out_failureId = "FEATURE_FAILURE_EGL_NO_CONFIG"_ns;
|
||||
|
@ -210,6 +210,44 @@ static std::shared_ptr<EglDisplay> GetAndInitDeviceDisplay(
|
||||
return EglDisplay::Create(egl, display, true, aProofOfLock);
|
||||
}
|
||||
|
||||
static std::shared_ptr<EglDisplay> GetAndInitSoftwareDisplay(
|
||||
GLLibraryEGL& egl, const StaticMutexAutoLock& aProofOfLock) {
|
||||
if (!egl.IsExtensionSupported(EGLLibExtension::EXT_platform_device) ||
|
||||
!egl.IsExtensionSupported(EGLLibExtension::EXT_device_enumeration)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EGLint maxDevices;
|
||||
if (!egl.fQueryDevicesEXT(0, nullptr, &maxDevices)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<EGLDeviceEXT> devices(maxDevices);
|
||||
EGLint numDevices;
|
||||
if (!egl.fQueryDevicesEXT(devices.size(), devices.data(), &numDevices)) {
|
||||
return nullptr;
|
||||
}
|
||||
devices.resize(numDevices);
|
||||
|
||||
EGLDisplay display = EGL_NO_DISPLAY;
|
||||
for (const auto& device : devices) {
|
||||
const char* renderNodeString =
|
||||
egl.fQueryDeviceStringEXT(device, LOCAL_EGL_DRM_RENDER_NODE_FILE_EXT);
|
||||
// We are looking for a device with no file
|
||||
if (!renderNodeString || *renderNodeString == 0) {
|
||||
const EGLAttrib attrib_list[] = {LOCAL_EGL_NONE};
|
||||
display = egl.fGetPlatformDisplay(LOCAL_EGL_PLATFORM_DEVICE_EXT, device,
|
||||
attrib_list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!display) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return EglDisplay::Create(egl, display, true, aProofOfLock);
|
||||
}
|
||||
|
||||
static std::shared_ptr<EglDisplay> GetAndInitSurfacelessDisplay(
|
||||
GLLibraryEGL& egl, const StaticMutexAutoLock& aProofOfLock) {
|
||||
if (!egl.IsExtensionSupported(EGLLibExtension::MESA_platform_surfaceless)) {
|
||||
@ -904,12 +942,17 @@ std::shared_ptr<EglDisplay> GLLibraryEGL::CreateDisplayLocked(
|
||||
} else {
|
||||
void* nativeDisplay = EGL_DEFAULT_DISPLAY;
|
||||
#ifdef MOZ_WAYLAND
|
||||
if (!gdk_display_get_default()) {
|
||||
if (!ret && !gfx::gfxVars::WebglUseHardware()) {
|
||||
// Initialize a swrast egl device such as llvmpipe
|
||||
ret = GetAndInitSoftwareDisplay(*this, aProofOfLock);
|
||||
}
|
||||
// Initialize the display the normal way
|
||||
if (!ret && !gdk_display_get_default()) {
|
||||
ret = GetAndInitDeviceDisplay(*this, aProofOfLock);
|
||||
if (!ret) {
|
||||
ret = GetAndInitSurfacelessDisplay(*this, aProofOfLock);
|
||||
}
|
||||
} else if (widget::GdkIsWaylandDisplay()) {
|
||||
} else if (!ret && widget::GdkIsWaylandDisplay()) {
|
||||
// Wayland does not support EGL_DEFAULT_DISPLAY
|
||||
nativeDisplay = widget::WaylandDisplayGetWLDisplay();
|
||||
if (!nativeDisplay) {
|
||||
|
@ -2931,6 +2931,8 @@ void gfxPlatform::InitWebGLConfig() {
|
||||
IsFeatureOk(nsIGfxInfo::FEATURE_WEBGL_OPENGL));
|
||||
gfxVars::SetAllowWebglAccelAngle(
|
||||
IsFeatureOk(nsIGfxInfo::FEATURE_WEBGL_ANGLE));
|
||||
gfxVars::SetWebglUseHardware(
|
||||
IsFeatureOk(nsIGfxInfo::FEATURE_WEBGL_USE_HARDWARE));
|
||||
|
||||
if (kIsMacOS) {
|
||||
// Avoid crash for Intel HD Graphics 3000 on OSX. (Bug 1413269)
|
||||
|
@ -256,6 +256,11 @@ bool gfxPlatformGtk::InitVAAPIConfig(bool aForceEnabledByUser) {
|
||||
"FEATURE_FAILURE_REQUIRES_EGL"_ns);
|
||||
}
|
||||
|
||||
if (!gfxVars::WebglUseHardware()) {
|
||||
feature.Disable(FeatureStatus::Blocklisted,
|
||||
"DMABuf disabled with software rendering", failureId);
|
||||
}
|
||||
|
||||
// Configure zero-copy playback feature.
|
||||
if (feature.IsEnabled()) {
|
||||
FeatureState& featureZeroCopy =
|
||||
|
@ -266,6 +266,9 @@ static const char* GetPrefNameForFeature(int32_t aFeature) {
|
||||
case nsIGfxInfo::FEATURE_AV1_HW_DECODE:
|
||||
name = BLOCKLIST_PREF_BRANCH "av1.hw-decode";
|
||||
break;
|
||||
case nsIGfxInfo::FEATURE_WEBGL_USE_HARDWARE:
|
||||
name = BLOCKLIST_PREF_BRANCH "webgl-use-hardware";
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected nsIGfxInfo feature?!");
|
||||
break;
|
||||
|
@ -856,6 +856,13 @@ const nsTArray<GfxDriverInfo>& GfxInfo::GetGfxDriverInfo() {
|
||||
nsIGfxInfo::FEATURE_WEBRENDER, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
|
||||
DRIVER_COMPARISON_IGNORED, V(0, 0, 0, 0),
|
||||
"FEATURE_FAILURE_WEBRENDER_MESA_VM", "");
|
||||
// Disable hardware mesa drivers in virtual machines due to instability.
|
||||
APPEND_TO_DRIVER_BLOCKLIST_EXT(
|
||||
OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All,
|
||||
WindowProtocol::All, DriverVendor::MesaVM, DeviceFamily::All,
|
||||
nsIGfxInfo::FEATURE_WEBGL_USE_HARDWARE,
|
||||
nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED,
|
||||
V(0, 0, 0, 0), "FEATURE_FAILURE_WEBGL_MESA_VM", "");
|
||||
|
||||
////////////////////////////////////
|
||||
// FEATURE_WEBRENDER_COMPOSITOR
|
||||
|
@ -185,8 +185,10 @@ interface nsIGfxInfo : nsISupports
|
||||
const long FEATURE_H264_HW_DECODE = 44;
|
||||
/* Whether hardware AV1 decoding is supported, starting in 114; not for downloadable blocking. */
|
||||
const long FEATURE_AV1_HW_DECODE = 45;
|
||||
/* Whether WebGL is allowed to use hardware rendering, otherwise software fallbacks. */
|
||||
const long FEATURE_WEBGL_USE_HARDWARE = 46;
|
||||
/* the maximum feature value. */
|
||||
const long FEATURE_MAX_VALUE = FEATURE_ACCELERATED_CANVAS2D;
|
||||
const long FEATURE_MAX_VALUE = FEATURE_WEBGL_USE_HARDWARE;
|
||||
|
||||
/*
|
||||
* A set of return values from GetFeatureStatus
|
||||
|
Loading…
x
Reference in New Issue
Block a user