forked from mirrors/gecko-dev
Bug 1710400 - Blocklist HW-WR on Intel DDX driver, r=aosmond
The Intel DDX driver is known to cause troubles with HW-WR and has been deprecated by most distributions, in favor of the glamor based "modesetting" driver. Lets blocklist it. This will mostly affect older/legacy setups. Note: the xrandr boilerplate code in glxtest will be useful for better multi-screen detection in a follow up patch. The current legacy X11 screen detection does not work in composited environments, always reporting one single big screen with the combined size. Xrandr allows for correct detection in such setups. Differential Revision: https://phabricator.services.mozilla.com/D126221
This commit is contained in:
parent
4f5281d096
commit
8b739e8722
3 changed files with 145 additions and 0 deletions
|
|
@ -59,6 +59,71 @@ typedef XID GLXPbuffer;
|
|||
# define GLX_GREEN_SIZE 9
|
||||
# define GLX_BLUE_SIZE 10
|
||||
# define GLX_DOUBLEBUFFER 5
|
||||
|
||||
// xrandr.h
|
||||
typedef XID RRMode;
|
||||
typedef XID RRProvider;
|
||||
typedef unsigned long XRRModeFlags;
|
||||
typedef struct _provider provider_t;
|
||||
|
||||
typedef struct _XRRModeInfo {
|
||||
RRMode id;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned long dotClock;
|
||||
unsigned int hSyncStart;
|
||||
unsigned int hSyncEnd;
|
||||
unsigned int hTotal;
|
||||
unsigned int hSkew;
|
||||
unsigned int vSyncStart;
|
||||
unsigned int vSyncEnd;
|
||||
unsigned int vTotal;
|
||||
char* name;
|
||||
unsigned int nameLength;
|
||||
XRRModeFlags modeFlags;
|
||||
} XRRModeInfo;
|
||||
|
||||
typedef struct _XRRScreenResources {
|
||||
Time timestamp;
|
||||
Time configTimestamp;
|
||||
int ncrtc;
|
||||
void* crtcs;
|
||||
int noutput;
|
||||
void* outputs;
|
||||
int nmode;
|
||||
XRRModeInfo* modes;
|
||||
} XRRScreenResources;
|
||||
|
||||
typedef struct _XRRProviderInfo {
|
||||
unsigned int capabilities;
|
||||
int ncrtcs;
|
||||
void* crtcs;
|
||||
int noutputs;
|
||||
void* outputs;
|
||||
char* name;
|
||||
int nassociatedproviders;
|
||||
RRProvider* associated_providers;
|
||||
unsigned int* associated_capability;
|
||||
int nameLen;
|
||||
} XRRProviderInfo;
|
||||
|
||||
typedef struct {
|
||||
unsigned int kind;
|
||||
char* string;
|
||||
XID xid;
|
||||
int index;
|
||||
} name_t;
|
||||
|
||||
struct _provider {
|
||||
name_t provider;
|
||||
XRRProviderInfo* info;
|
||||
};
|
||||
|
||||
typedef struct _XRRProviderResources {
|
||||
Time timestamp;
|
||||
int nproviders;
|
||||
RRProvider* providers;
|
||||
} XRRProviderResources;
|
||||
#endif
|
||||
|
||||
// stuff from gl.h
|
||||
|
|
@ -146,11 +211,13 @@ typedef struct _drmDevice {
|
|||
# define LIBGLES_FILENAME "libGLESv2.so"
|
||||
# define LIBEGL_FILENAME "libEGL.so"
|
||||
# define LIBDRM_FILENAME "libdrm.so"
|
||||
# define LIBXRANDR_FILENAME "libXrandr.so"
|
||||
#else
|
||||
# define LIBGL_FILENAME "libGL.so.1"
|
||||
# define LIBGLES_FILENAME "libGLESv2.so.2"
|
||||
# define LIBEGL_FILENAME "libEGL.so.1"
|
||||
# define LIBDRM_FILENAME "libdrm.so.2"
|
||||
# define LIBXRANDR_FILENAME "libXrandr.so.2"
|
||||
#endif
|
||||
|
||||
#define EXIT_FAILURE_BUFFER_TOO_SMALL 2
|
||||
|
|
@ -653,6 +720,49 @@ static void get_x11_screen_info(Display* dpy) {
|
|||
}
|
||||
}
|
||||
|
||||
static void get_x11_ddx_info(Display* dpy) {
|
||||
void* libXrandr = dlopen(LIBXRANDR_FILENAME, RTLD_LAZY);
|
||||
if (!libXrandr) {
|
||||
return;
|
||||
}
|
||||
|
||||
typedef XRRProviderResources* (*XRRGETPROVIDERRESOURCES)(Display*, Window);
|
||||
XRRGETPROVIDERRESOURCES XRRGetProviderResources =
|
||||
cast<XRRGETPROVIDERRESOURCES>(
|
||||
dlsym(libXrandr, "XRRGetProviderResources"));
|
||||
|
||||
typedef XRRScreenResources* (*XRRGETSCREENRESOURCESCURRENT)(Display*, Window);
|
||||
XRRGETSCREENRESOURCESCURRENT XRRGetScreenResourcesCurrent =
|
||||
cast<XRRGETSCREENRESOURCESCURRENT>(
|
||||
dlsym(libXrandr, "XRRGetScreenResourcesCurrent"));
|
||||
|
||||
typedef XRRProviderInfo* (*XRRGETPROVIDERINFO)(Display*, XRRScreenResources*,
|
||||
RRProvider);
|
||||
XRRGETPROVIDERINFO XRRGetProviderInfo =
|
||||
cast<XRRGETPROVIDERINFO>(dlsym(libXrandr, "XRRGetProviderInfo"));
|
||||
|
||||
if (!XRRGetProviderResources || !XRRGetScreenResourcesCurrent ||
|
||||
!XRRGetProviderInfo) {
|
||||
dlclose(libXrandr);
|
||||
return;
|
||||
}
|
||||
|
||||
Window root = RootWindow(dpy, DefaultScreen(dpy));
|
||||
XRRProviderResources* pr = XRRGetProviderResources(dpy, root);
|
||||
XRRScreenResources* res = XRRGetScreenResourcesCurrent(dpy, root);
|
||||
int nProviders = pr->nproviders;
|
||||
|
||||
if (nProviders != 0) {
|
||||
record_value("DDX_DRIVER\n");
|
||||
for (int i = 0; i < nProviders; i++) {
|
||||
XRRProviderInfo* info = XRRGetProviderInfo(dpy, res, pr->providers[i]);
|
||||
record_value("%s%s", info->name, i == nProviders - 1 ? ";\n" : ";");
|
||||
}
|
||||
}
|
||||
|
||||
dlclose(libXrandr);
|
||||
}
|
||||
|
||||
static void get_glx_status(int* gotGlxInfo, int* gotDriDriver) {
|
||||
void* libgl = dlopen(LIBGL_FILENAME, RTLD_LAZY);
|
||||
if (!libgl) {
|
||||
|
|
@ -813,6 +923,9 @@ static void get_glx_status(int* gotGlxInfo, int* gotDriDriver) {
|
|||
// Get monitor information
|
||||
get_x11_screen_info(dpy);
|
||||
|
||||
// Get DDX driver information
|
||||
get_x11_ddx_info(dpy);
|
||||
|
||||
///// Clean up. Indeed, the parent process might fail to kill us (e.g. if it
|
||||
///// doesn't need to check GL info) so we might be staying alive for longer
|
||||
///// than expected, so it's important to consume as little memory as
|
||||
|
|
@ -851,8 +964,12 @@ static bool x11_egltest(int pci_count) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Get monitor information
|
||||
get_x11_screen_info(dpy);
|
||||
|
||||
// Get DDX driver information
|
||||
get_x11_ddx_info(dpy);
|
||||
|
||||
// Bug 1715245: Closing the display connection here crashes on NV prop.
|
||||
// drivers. Just leave it open, the process will exit shortly after anyway.
|
||||
// XCloseDisplay(dpy);
|
||||
|
|
|
|||
|
|
@ -164,6 +164,8 @@ void GfxInfo::GetData() {
|
|||
|
||||
nsCString drmRenderDevice;
|
||||
|
||||
nsCString ddxDriver;
|
||||
|
||||
AutoTArray<nsCString, 2> pciVendors;
|
||||
AutoTArray<nsCString, 2> pciDevices;
|
||||
|
||||
|
|
@ -196,6 +198,8 @@ void GfxInfo::GetData() {
|
|||
stringToFill = &mesaAccelerated;
|
||||
} else if (!strcmp(line, "MESA_VRAM")) {
|
||||
stringToFill = &adapterRam;
|
||||
} else if (!strcmp(line, "DDX_DRIVER")) {
|
||||
stringToFill = &ddxDriver;
|
||||
} else if (!strcmp(line, "DRI_DRIVER")) {
|
||||
stringToFill = &driDriver;
|
||||
} else if (!strcmp(line, "SCREEN_INFO")) {
|
||||
|
|
@ -587,6 +591,18 @@ void GfxInfo::GetData() {
|
|||
}
|
||||
}
|
||||
|
||||
if (!ddxDriver.IsEmpty()) {
|
||||
PRInt32 start = 0;
|
||||
PRInt32 loc = ddxDriver.Find(";", PR_FALSE, start);
|
||||
while (loc != kNotFound) {
|
||||
nsCString line(ddxDriver.get() + start, loc - start);
|
||||
mDdxDrivers.AppendElement(std::move(line));
|
||||
|
||||
start = loc + 1;
|
||||
loc = ddxDriver.Find(";", PR_FALSE, start);
|
||||
}
|
||||
}
|
||||
|
||||
if (error || errorLog || mTestType.IsEmpty()) {
|
||||
if (!mAdapterDescription.IsEmpty()) {
|
||||
mAdapterDescription.AppendLiteral(" (See failure log)");
|
||||
|
|
@ -923,6 +939,16 @@ nsresult GfxInfo::GetFeatureStatusImpl(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aFeature == nsIGfxInfo::FEATURE_WEBRENDER) {
|
||||
for (const nsCString& driver : mDdxDrivers) {
|
||||
if (strcasestr(driver.get(), "Intel")) {
|
||||
*aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
|
||||
aFailureId = "FEATURE_FAILURE_DDX_INTEL";
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GfxInfoBase::GetFeatureStatusImpl(
|
||||
aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, aFailureId, &os);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ class GfxInfo final : public GfxInfoBase {
|
|||
|
||||
nsCString mDrmRenderDevice;
|
||||
|
||||
nsTArray<nsCString> mDdxDrivers;
|
||||
|
||||
struct ScreenInfo {
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
|
|
|
|||
Loading…
Reference in a new issue