1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
12 #include <sys/utsname.h>
15 #include "nsCRTGlue.h"
16 #include "nsExceptionHandler.h"
17 #include "nsUnicharUtils.h"
19 #include "nsPrintfCString.h"
20 #include "nsWhitespaceTokenizer.h"
21 #include "mozilla/Telemetry.h"
22 #include "mozilla/gfx/Logging.h"
24 #include "GfxInfoX11.h"
28 # include "mozilla/widget/nsWaylandDisplay.h"
29 # include "mozilla/widget/DMABufLibWrapper.h"
32 #define EXIT_STATUS_BUFFER_TOO_SMALL 2
34 bool fire_glxtest_process();
37 namespace mozilla::widget
{
40 NS_IMPL_ISUPPORTS_INHERITED(GfxInfo
, GfxInfoBase
, nsIGfxInfoDebug
)
43 // these global variables will be set when firing the glxtest process
44 int glxtest_pipe
= -1;
45 pid_t glxtest_pid
= 0;
47 nsresult
GfxInfo::Init() {
50 mHasTextureFromPixmap
= false;
52 mIsAccelerated
= true;
54 mIsWaylandDRM
= false;
56 mHasMultipleGPUs
= false;
57 mGlxTestError
= false;
58 return GfxInfoBase::Init();
61 void GfxInfo::AddCrashReportAnnotations() {
62 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID
,
64 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID
,
66 CrashReporter::AnnotateCrashReport(
67 CrashReporter::Annotation::AdapterDriverVendor
, mDriverVendor
);
68 CrashReporter::AnnotateCrashReport(
69 CrashReporter::Annotation::AdapterDriverVersion
, mDriverVersion
);
70 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::IsWayland
,
72 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::IsWaylandDRM
,
74 CrashReporter::AnnotateCrashReport(
75 CrashReporter::Annotation::DesktopEnvironment
, mDesktopEnvironment
);
77 if (mHasMultipleGPUs
) {
79 note
.AppendLiteral("Has dual GPUs.");
80 if (!mSecondaryVendorId
.IsEmpty()) {
81 note
.AppendLiteral(" GPU #2: AdapterVendorID2: ");
82 note
.Append(mSecondaryVendorId
);
83 note
.AppendLiteral(", AdapterDeviceID2: ");
84 note
.Append(mSecondaryDeviceId
);
86 CrashReporter::AppendAppNotesToCrashReport(note
);
90 void GfxInfo::GetData() {
91 GfxInfoBase::GetData();
93 // to understand this function, see bug 639842. We retrieve the OpenGL driver
94 // information in a separate process to protect against bad drivers.
96 // if glxtest_pipe == -1, that means that we already read the information
97 if (glxtest_pipe
== -1) return;
99 enum { buf_size
= 2048 };
101 ssize_t bytesread
= read(glxtest_pipe
, &buf
,
102 buf_size
- 1); // -1 because we'll append a zero
106 // bytesread < 0 would mean that the above read() call failed.
107 // This should never happen. If it did, the outcome would be to blocklist
111 } else if (bytesread
== buf_size
- 1) {
112 gfxCriticalNote
<< "glxtest: read from pipe exceeded buffer size";
115 // let buf be a zero-terminated string
118 // Wait for the glxtest process to finish. This serves 2 purposes:
119 // * avoid having a zombie glxtest process laying around
120 // * get the glxtest process status info.
121 int glxtest_status
= 0;
122 bool wait_for_glxtest_process
= true;
123 bool waiting_for_glxtest_process_failed
= false;
124 int waitpid_errno
= 0;
125 while (wait_for_glxtest_process
) {
126 wait_for_glxtest_process
= false;
127 if (waitpid(glxtest_pid
, &glxtest_status
, 0) == -1) {
128 waitpid_errno
= errno
;
129 if (waitpid_errno
== EINTR
) {
130 wait_for_glxtest_process
= true;
133 // ECHILD happens when the glxtest process got reaped got reaped after a
134 // PR_CreateProcess as per bug 227246. This shouldn't matter, as we
135 // still seem to get the data from the pipe, and if we didn't, the
136 // outcome would be to blocklist anyway.
137 waiting_for_glxtest_process_failed
= (waitpid_errno
!= ECHILD
);
142 int exit_code
= EXIT_FAILURE
;
143 bool exited_with_error_code
= false;
144 if (!waiting_for_glxtest_process_failed
&& WIFEXITED(glxtest_status
)) {
145 exit_code
= WEXITSTATUS(glxtest_status
);
146 exited_with_error_code
= exit_code
!= EXIT_SUCCESS
;
149 bool received_signal
=
150 !waiting_for_glxtest_process_failed
&& WIFSIGNALED(glxtest_status
);
152 bool error
= waiting_for_glxtest_process_failed
|| exited_with_error_code
||
154 bool errorLog
= false;
157 nsCString glRenderer
;
159 nsCString textureFromPixmap
;
162 // Available if GLX_MESA_query_renderer is supported.
163 nsCString mesaVendor
;
164 nsCString mesaDevice
;
165 nsCString mesaAccelerated
;
166 // Available if using a DRI-based libGL stack.
168 nsCString screenInfo
;
169 nsCString adapterRam
;
171 nsCString drmRenderDevice
;
173 AutoTArray
<nsCString
, 2> pciVendors
;
174 AutoTArray
<nsCString
, 2> pciDevices
;
176 nsCString
* stringToFill
= nullptr;
177 bool logString
= false;
181 char* line
= NS_strtok("\n", &bufptr
);
184 stringToFill
->Assign(line
);
185 stringToFill
= nullptr;
186 } else if (logString
) {
187 gfxCriticalNote
<< "glxtest: " << line
;
189 } else if (!strcmp(line
, "VENDOR")) {
190 stringToFill
= &glVendor
;
191 } else if (!strcmp(line
, "RENDERER")) {
192 stringToFill
= &glRenderer
;
193 } else if (!strcmp(line
, "VERSION")) {
194 stringToFill
= &glVersion
;
195 } else if (!strcmp(line
, "TFP")) {
196 stringToFill
= &textureFromPixmap
;
197 } else if (!strcmp(line
, "MESA_VENDOR_ID")) {
198 stringToFill
= &mesaVendor
;
199 } else if (!strcmp(line
, "MESA_DEVICE_ID")) {
200 stringToFill
= &mesaDevice
;
201 } else if (!strcmp(line
, "MESA_ACCELERATED")) {
202 stringToFill
= &mesaAccelerated
;
203 } else if (!strcmp(line
, "MESA_VRAM")) {
204 stringToFill
= &adapterRam
;
205 } else if (!strcmp(line
, "DRI_DRIVER")) {
206 stringToFill
= &driDriver
;
207 } else if (!strcmp(line
, "SCREEN_INFO")) {
208 stringToFill
= &screenInfo
;
209 } else if (!strcmp(line
, "PCI_VENDOR_ID")) {
210 stringToFill
= pciVendors
.AppendElement();
211 } else if (!strcmp(line
, "PCI_DEVICE_ID")) {
212 stringToFill
= pciDevices
.AppendElement();
213 } else if (!strcmp(line
, "DRM_RENDERDEVICE")) {
214 stringToFill
= &drmRenderDevice
;
215 } else if (!strcmp(line
, "TEST_TYPE")) {
216 stringToFill
= &testType
;
217 } else if (!strcmp(line
, "WARNING")) {
219 } else if (!strcmp(line
, "ERROR")) {
225 MOZ_ASSERT(pciDevices
.Length() == pciVendors
.Length(),
226 "Missing PCI vendors/devices");
228 size_t pciLen
= std::min(pciVendors
.Length(), pciDevices
.Length());
229 mHasMultipleGPUs
= pciLen
> 1;
231 if (!strcmp(textureFromPixmap
.get(), "TRUE")) mHasTextureFromPixmap
= true;
233 // only useful for Linux kernel version check for FGLRX driver.
234 // assumes X client == X server, which is sad.
235 struct utsname unameobj
;
236 if (uname(&unameobj
) >= 0) {
237 mOS
.Assign(unameobj
.sysname
);
238 mOSRelease
.Assign(unameobj
.release
);
241 const char* spoofedVendor
= PR_GetEnv("MOZ_GFX_SPOOF_GL_VENDOR");
242 if (spoofedVendor
) glVendor
.Assign(spoofedVendor
);
243 const char* spoofedRenderer
= PR_GetEnv("MOZ_GFX_SPOOF_GL_RENDERER");
244 if (spoofedRenderer
) glRenderer
.Assign(spoofedRenderer
);
245 const char* spoofedVersion
= PR_GetEnv("MOZ_GFX_SPOOF_GL_VERSION");
246 if (spoofedVersion
) glVersion
.Assign(spoofedVersion
);
247 const char* spoofedOS
= PR_GetEnv("MOZ_GFX_SPOOF_OS");
248 if (spoofedOS
) mOS
.Assign(spoofedOS
);
249 const char* spoofedOSRelease
= PR_GetEnv("MOZ_GFX_SPOOF_OS_RELEASE");
250 if (spoofedOSRelease
) mOSRelease
.Assign(spoofedOSRelease
);
252 // Scan the GL_VERSION string for the GL and driver versions.
253 nsCWhitespaceTokenizer
tokenizer(glVersion
);
254 while (tokenizer
.hasMoreTokens()) {
255 nsCString
token(tokenizer
.nextToken());
256 unsigned int major
= 0, minor
= 0, revision
= 0, patch
= 0;
257 if (sscanf(token
.get(), "%u.%u.%u.%u", &major
, &minor
, &revision
, &patch
) >=
259 // A survey of GL_VENDOR strings indicates that the first version is
260 // always the GL version, the second is usually the driver version.
261 if (mGLMajorVersion
== 0) {
262 mGLMajorVersion
= major
;
263 mGLMinorVersion
= minor
;
264 } else if (mDriverVersion
.IsEmpty()) { // Not already spoofed.
266 nsPrintfCString("%u.%u.%u.%u", major
, minor
, revision
, patch
);
271 if (mGLMajorVersion
== 0) {
272 NS_WARNING("Failed to parse GL version!");
275 mDrmRenderDevice
= std::move(drmRenderDevice
);
276 mTestType
= std::move(testType
);
278 // Mesa always exposes itself in the GL_VERSION string, but not always the
280 mIsMesa
= glVersion
.Find("Mesa") != -1;
282 // We need to use custom driver vendor IDs for mesa so we can treat them
283 // differently than the proprietary drivers.
285 mIsAccelerated
= !mesaAccelerated
.Equals("FALSE");
286 // Process software rasterizers before the DRI driver string; we may be
287 // forcing software rasterization on a DRI-accelerated X server by using
288 // LIBGL_ALWAYS_SOFTWARE or a similar restriction.
289 if (strcasestr(glRenderer
.get(), "llvmpipe")) {
291 GfxDriverInfo::GetDriverVendor(DriverVendor::MesaLLVMPipe
),
293 mIsAccelerated
= false;
294 } else if (strcasestr(glRenderer
.get(), "softpipe")) {
296 GfxDriverInfo::GetDriverVendor(DriverVendor::MesaSoftPipe
),
298 mIsAccelerated
= false;
299 } else if (strcasestr(glRenderer
.get(), "software rasterizer") ||
301 // Fallback to reporting swrast if GLX_MESA_query_renderer tells us
302 // we're using an unaccelerated context.
303 CopyUTF16toUTF8(GfxDriverInfo::GetDriverVendor(DriverVendor::MesaSWRast
),
305 mIsAccelerated
= false;
306 } else if (!driDriver
.IsEmpty()) {
307 mDriverVendor
= nsPrintfCString("mesa/%s", driDriver
.get());
309 // Some other mesa configuration where we couldn't get enough info.
310 NS_WARNING("Failed to detect Mesa driver being used!");
311 CopyUTF16toUTF8(GfxDriverInfo::GetDriverVendor(DriverVendor::MesaUnknown
),
315 if (!mesaVendor
.IsEmpty()) {
316 mVendorId
= mesaVendor
;
319 if (!mesaDevice
.IsEmpty()) {
320 mDeviceId
= mesaDevice
;
322 } else if (glVendor
.EqualsLiteral("NVIDIA Corporation")) {
323 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::NVIDIA
),
325 mDriverVendor
.AssignLiteral("nvidia/unknown");
326 // TODO: Use NV-CONTROL X11 extension to query Device ID and VRAM.
327 } else if (glVendor
.EqualsLiteral("ATI Technologies Inc.")) {
328 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::ATI
),
330 mDriverVendor
.AssignLiteral("ati/unknown");
331 // TODO: Look into ways to find the device ID on FGLRX.
333 NS_WARNING("Failed to detect GL vendor!");
336 if (!screenInfo
.IsEmpty()) {
338 PRInt32 loc
= screenInfo
.Find(";", PR_FALSE
, start
);
339 while (loc
!= kNotFound
) {
341 nsCString
line(screenInfo
.get() + start
, loc
- start
);
343 if (sscanf(line
.get(), "%ux%u:%u", &info
.mWidth
, &info
.mHeight
,
345 info
.mIsDefault
= isDefault
!= 0;
346 mScreenInfo
.AppendElement(info
);
350 loc
= screenInfo
.Find(";", PR_FALSE
, start
);
354 if (!adapterRam
.IsEmpty()) {
355 mAdapterRAM
= (uint32_t)atoi(adapterRam
.get());
358 // If we have the DRI driver, we can derive the vendor ID from that if needed.
359 if (mVendorId
.IsEmpty() && !driDriver
.IsEmpty()) {
360 const char* nvidiaDrivers
[] = {"nouveau", "tegra", nullptr};
361 for (size_t i
= 0; nvidiaDrivers
[i
]; ++i
) {
362 if (driDriver
.Equals(nvidiaDrivers
[i
])) {
363 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::NVIDIA
),
369 if (mVendorId
.IsEmpty()) {
370 const char* intelDrivers
[] = {"iris", "i915", "i965",
371 "i810", "intel", nullptr};
372 for (size_t i
= 0; intelDrivers
[i
]; ++i
) {
373 if (driDriver
.Equals(intelDrivers
[i
])) {
374 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::Intel
),
381 if (mVendorId
.IsEmpty()) {
382 const char* amdDrivers
[] = {"r600", "r200", "r100",
383 "radeon", "radeonsi", nullptr};
384 for (size_t i
= 0; amdDrivers
[i
]; ++i
) {
385 if (driDriver
.Equals(amdDrivers
[i
])) {
386 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::ATI
),
393 if (mVendorId
.IsEmpty()) {
394 if (driDriver
.EqualsLiteral("freedreno")) {
395 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::Qualcomm
),
401 // If we still don't have a vendor ID, we can try the PCI vendor list.
402 if (mVendorId
.IsEmpty()) {
403 if (pciVendors
.Length() == 1) {
404 mVendorId
= pciVendors
[0];
405 } else if (pciVendors
.IsEmpty()) {
406 gfxCriticalNote
<< "No GPUs detected via PCI";
409 << "More than 1 GPU detected via PCI, cannot deduce vendor";
413 // If we know the vendor ID, but didn't get a device ID, we can guess from the
415 if (mDeviceId
.IsEmpty() && !mVendorId
.IsEmpty()) {
416 for (size_t i
= 0; i
< pciLen
; ++i
) {
417 if (mVendorId
.Equals(pciVendors
[i
])) {
418 if (mDeviceId
.IsEmpty()) {
419 mDeviceId
= pciDevices
[i
];
421 gfxCriticalNote
<< "More than 1 GPU from same vendor detected via "
422 "PCI, cannot deduce device";
423 mDeviceId
.Truncate();
430 // Assuming we know the vendor, we should check for a secondary card.
431 if (!mVendorId
.IsEmpty()) {
434 << "More than 2 GPUs detected via PCI, secondary GPU is arbitrary";
436 for (size_t i
= 0; i
< pciLen
; ++i
) {
437 if (!mVendorId
.Equals(pciVendors
[i
]) ||
438 (!mDeviceId
.IsEmpty() && !mDeviceId
.Equals(pciDevices
[i
]))) {
439 mSecondaryVendorId
= pciVendors
[i
];
440 mSecondaryDeviceId
= pciDevices
[i
];
446 // If we couldn't choose, log them.
447 if (mVendorId
.IsEmpty()) {
448 for (size_t i
= 0; i
< pciLen
; ++i
) {
449 gfxCriticalNote
<< "PCI candidate " << pciVendors
[i
].get() << "/"
450 << pciDevices
[i
].get();
454 // Fallback to GL_VENDOR and GL_RENDERER.
455 if (mVendorId
.IsEmpty()) {
456 mVendorId
.Assign(glVendor
.get());
458 if (mDeviceId
.IsEmpty()) {
459 mDeviceId
.Assign(glRenderer
.get());
462 mAdapterDescription
.Assign(glRenderer
);
464 mIsWayland
= gdk_display_get_default() &&
465 !GDK_IS_X11_DISPLAY(gdk_display_get_default());
467 mIsWaylandDRM
= GetDMABufDevice()->IsDMABufVAAPIEnabled() ||
468 GetDMABufDevice()->IsDMABufWebGLEnabled() ||
469 GetDMABufDevice()->IsDMABufTexturesEnabled();
473 // Make a best effort guess at whether or not we are using the XWayland compat
474 // layer. For all intents and purposes, we should otherwise believe we are
476 const char* windowEnv
= getenv("XDG_SESSION_TYPE");
477 mIsXWayland
= windowEnv
&& strcmp(windowEnv
, "wayland") == 0;
479 // Make a best effort guess at the desktop environment in use. Sadly there
480 // does not appear to be a standard way to do this, so we check a few
481 // different environment variables and search for relevant keywords.
483 // Note that some users manually change these values. Some applications check
484 // the environment variable like we are here, and either not work or restrict
485 // functionality. There may be some heroics we could go through to determine
486 // the truth, but for the moment, this is the best we can do. This is
487 // something to keep in mind when updating the blocklist.
488 const char* desktopEnv
= getenv("XDG_CURRENT_DESKTOP");
490 desktopEnv
= getenv("DESKTOP_SESSION");
494 std::string
currentDesktop(desktopEnv
);
495 for (auto& c
: currentDesktop
) {
499 if (currentDesktop
.find("budgie") != std::string::npos
) {
500 // We need to check for Budgie first, because it might incorporate GNOME
501 // into the environment variable value.
503 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Budgie
),
504 mDesktopEnvironment
);
505 } else if (currentDesktop
.find("gnome") != std::string::npos
) {
507 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::GNOME
),
508 mDesktopEnvironment
);
509 } else if (currentDesktop
.find("kde") != std::string::npos
) {
511 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::KDE
),
512 mDesktopEnvironment
);
513 } else if (currentDesktop
.find("xfce") != std::string::npos
) {
515 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::XFCE
),
516 mDesktopEnvironment
);
517 } else if (currentDesktop
.find("cinnamon") != std::string::npos
) {
519 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Cinnamon
),
520 mDesktopEnvironment
);
521 } else if (currentDesktop
.find("enlightenment") != std::string::npos
) {
522 CopyUTF16toUTF8(GfxDriverInfo::GetDesktopEnvironment(
523 DesktopEnvironment::Enlightenment
),
524 mDesktopEnvironment
);
525 } else if (currentDesktop
.find("lxde") != std::string::npos
||
526 currentDesktop
.find("lubuntu") != std::string::npos
) {
528 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::LXDE
),
529 mDesktopEnvironment
);
530 } else if (currentDesktop
.find("openbox") != std::string::npos
) {
532 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Openbox
),
533 mDesktopEnvironment
);
534 } else if (currentDesktop
.find("i3") != std::string::npos
) {
536 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::i3
),
537 mDesktopEnvironment
);
538 } else if (currentDesktop
.find("mate") != std::string::npos
) {
540 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Mate
),
541 mDesktopEnvironment
);
542 } else if (currentDesktop
.find("unity") != std::string::npos
) {
544 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Unity
),
545 mDesktopEnvironment
);
546 } else if (currentDesktop
.find("pantheon") != std::string::npos
) {
548 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Pantheon
),
549 mDesktopEnvironment
);
550 } else if (currentDesktop
.find("lxqt") != std::string::npos
) {
552 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::LXQT
),
553 mDesktopEnvironment
);
554 } else if (currentDesktop
.find("deepin") != std::string::npos
) {
556 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Deepin
),
557 mDesktopEnvironment
);
558 } else if (currentDesktop
.find("dwm") != std::string::npos
) {
560 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Dwm
),
561 mDesktopEnvironment
);
565 if (mDesktopEnvironment
.IsEmpty()) {
566 if (getenv("GNOME_DESKTOP_SESSION_ID")) {
568 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::GNOME
),
569 mDesktopEnvironment
);
570 } else if (getenv("KDE_FULL_SESSION")) {
572 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::KDE
),
573 mDesktopEnvironment
);
574 } else if (getenv("MATE_DESKTOP_SESSION_ID")) {
576 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Mate
),
577 mDesktopEnvironment
);
578 } else if (getenv("LXQT_SESSION_CONFIG")) {
580 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::LXQT
),
581 mDesktopEnvironment
);
584 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Unknown
),
585 mDesktopEnvironment
);
589 if (error
|| errorLog
|| mTestType
.IsEmpty()) {
590 if (!mAdapterDescription
.IsEmpty()) {
591 mAdapterDescription
.AppendLiteral(" (See failure log)");
593 mAdapterDescription
.AppendLiteral("See failure log");
596 mGlxTestError
= true;
600 nsAutoCString
msg("glxtest: process failed");
601 if (waiting_for_glxtest_process_failed
) {
602 msg
.AppendPrintf(" (waitpid failed with errno=%d for pid %d)",
603 waitpid_errno
, glxtest_pid
);
606 if (exited_with_error_code
) {
607 if (exit_code
== EXIT_STATUS_BUFFER_TOO_SMALL
) {
608 msg
.AppendLiteral(" (buffer too small)");
610 msg
.AppendPrintf(" (exited with status %d)",
611 WEXITSTATUS(glxtest_status
));
614 if (received_signal
) {
615 msg
.AppendPrintf(" (received signal %d)", WTERMSIG(glxtest_status
));
618 gfxCriticalNote
<< msg
.get();
621 AddCrashReportAnnotations();
624 const nsTArray
<GfxDriverInfo
>& GfxInfo::GetGfxDriverInfo() {
625 if (!sDriverInfo
->Length()) {
626 // Mesa 10.0 provides the GLX_MESA_query_renderer extension, which allows us
627 // to query device IDs backing a GL context for blocklisting.
628 APPEND_TO_DRIVER_BLOCKLIST_EXT(
629 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
630 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
631 DeviceFamily::All
, GfxDriverInfo::allFeatures
,
632 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
633 V(10, 0, 0, 0), "FEATURE_FAILURE_OLD_MESA", "Mesa 10.0");
635 // NVIDIA baseline (ported from old blocklist)
636 APPEND_TO_DRIVER_BLOCKLIST_EXT(
637 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
638 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::NonMesaAll
,
639 DeviceFamily::NvidiaAll
, GfxDriverInfo::allFeatures
,
640 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
641 V(257, 21, 0, 0), "FEATURE_FAILURE_OLD_NVIDIA", "NVIDIA 257.21");
643 // fglrx baseline (chosen arbitrarily as 2013-07-22 release).
644 APPEND_TO_DRIVER_BLOCKLIST(
645 OperatingSystem::Linux
, DeviceFamily::AtiAll
,
646 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
647 DRIVER_LESS_THAN
, V(13, 15, 100, 1), "FEATURE_FAILURE_OLD_FGLRX",
648 "fglrx 13.15.100.1");
650 ////////////////////////////////////
653 // Intel Mesa baseline, chosen arbitrarily.
654 APPEND_TO_DRIVER_BLOCKLIST(
655 OperatingSystem::Linux
, DeviceFamily::IntelAll
,
656 nsIGfxInfo::FEATURE_WEBRENDER
,
657 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
658 V(17, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_OLD_MESA", "Mesa 17.0.0.0");
660 // Nvidia Mesa baseline, see bug 1563859.
661 APPEND_TO_DRIVER_BLOCKLIST_EXT(
662 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
663 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
664 DeviceFamily::NvidiaAll
, nsIGfxInfo::FEATURE_WEBRENDER
,
665 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
666 V(18, 2, 0, 0), "FEATURE_FAILURE_WEBRENDER_OLD_MESA", "Mesa 18.2.0.0");
668 #ifndef EARLY_BETA_OR_EARLIER
669 // Disable on all Nvidia devices not using Mesa for now.
670 APPEND_TO_DRIVER_BLOCKLIST_EXT(
671 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
672 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::NonMesaAll
,
673 DeviceFamily::NvidiaAll
, nsIGfxInfo::FEATURE_WEBRENDER
,
674 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_COMPARISON_IGNORED
,
675 V(0, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_NO_LINUX_NVIDIA", "");
677 // Disable on all older Nvidia drivers due to stability issues.
678 APPEND_TO_DRIVER_BLOCKLIST_EXT(
679 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
680 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::NonMesaAll
,
681 DeviceFamily::NvidiaAll
, nsIGfxInfo::FEATURE_WEBRENDER
,
682 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_LESS_THAN
, V(460, 32, 3, 0),
683 "FEATURE_FAILURE_WEBRENDER_OLD_NVIDIA", "460.32.03");
686 // ATI Mesa baseline, chosen arbitrarily.
687 APPEND_TO_DRIVER_BLOCKLIST_EXT(
688 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
689 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
690 DeviceFamily::AtiAll
, nsIGfxInfo::FEATURE_WEBRENDER
,
691 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
692 V(17, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_OLD_MESA", "Mesa 17.0.0.0");
694 // Bug 1690568 / Bug 1393793 - Require Mesa 17.3.0+ for devices using the
695 // r600 driver to avoid shader compilation issues.
696 APPEND_TO_DRIVER_BLOCKLIST_EXT(
697 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
698 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaR600
,
699 DeviceFamily::All
, nsIGfxInfo::FEATURE_WEBRENDER
,
700 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
701 V(17, 3, 0, 0), "FEATURE_FAILURE_WEBRENDER_OLD_MESA_R600",
704 // Disable on all ATI devices not using Mesa for now.
705 APPEND_TO_DRIVER_BLOCKLIST_EXT(
706 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
707 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::NonMesaAll
,
708 DeviceFamily::AtiAll
, nsIGfxInfo::FEATURE_WEBRENDER
,
709 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_COMPARISON_IGNORED
,
710 V(0, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_NO_LINUX_ATI", "");
712 // Bug 1673939 - Garbled text on RS880 GPUs with Mesa drivers.
713 APPEND_TO_DRIVER_BLOCKLIST_EXT(
714 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
715 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
716 DeviceFamily::AmdR600
, nsIGfxInfo::FEATURE_WEBRENDER
,
717 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_COMPARISON_IGNORED
,
718 V(0, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_BUG_1673939",
719 "https://gitlab.freedesktop.org/mesa/mesa/-/issues/3720");
721 ////////////////////////////////////
722 // FEATURE_WEBRENDER - ALLOWLIST
724 // Intel Mesa baseline, chosen arbitrarily.
725 APPEND_TO_DRIVER_BLOCKLIST_EXT(
726 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
727 DesktopEnvironment::GNOME
, WindowProtocol::X11
, DriverVendor::MesaAll
,
728 DeviceFamily::IntelRolloutWebRender
, nsIGfxInfo::FEATURE_WEBRENDER
,
729 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
, DRIVER_GREATER_THAN_OR_EQUAL
,
730 V(17, 0, 0, 0), "FEATURE_ROLLOUT_INTEL_GNOME_X11_MESA",
733 APPEND_TO_DRIVER_BLOCKLIST_EXT(
734 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
735 DesktopEnvironment::GNOME
, WindowProtocol::Wayland
,
736 DriverVendor::MesaAll
, DeviceFamily::IntelRolloutWebRender
,
737 nsIGfxInfo::FEATURE_WEBRENDER
, nsIGfxInfo::FEATURE_ALLOW_ALWAYS
,
738 DRIVER_GREATER_THAN_OR_EQUAL
, V(17, 0, 0, 0),
739 "FEATURE_ROLLOUT_INTEL_GNOME_WAYLAND_MESA", "Mesa 17.0.0.0");
741 // ATI Mesa baseline, chosen arbitrarily.
742 APPEND_TO_DRIVER_BLOCKLIST_EXT(
743 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
744 DesktopEnvironment::GNOME
, WindowProtocol::X11
, DriverVendor::MesaAll
,
745 DeviceFamily::AtiRolloutWebRender
, nsIGfxInfo::FEATURE_WEBRENDER
,
746 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
, DRIVER_GREATER_THAN_OR_EQUAL
,
747 V(17, 0, 0, 0), "FEATURE_ROLLOUT_ATI_GNOME_X11_MESA", "Mesa 17.0.0.0");
749 APPEND_TO_DRIVER_BLOCKLIST_EXT(
750 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
751 DesktopEnvironment::GNOME
, WindowProtocol::Wayland
,
752 DriverVendor::MesaAll
, DeviceFamily::AtiRolloutWebRender
,
753 nsIGfxInfo::FEATURE_WEBRENDER
, nsIGfxInfo::FEATURE_ALLOW_ALWAYS
,
754 DRIVER_GREATER_THAN_OR_EQUAL
, V(17, 0, 0, 0),
755 "FEATURE_ROLLOUT_ATI_GNOME_WAYLAND_MESA", "Mesa 17.0.0.0");
757 #ifdef EARLY_BETA_OR_EARLIER
758 // Intel Mesa baseline, chosen arbitrarily.
759 APPEND_TO_DRIVER_BLOCKLIST_EXT(
760 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
761 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
762 DeviceFamily::IntelRolloutWebRender
, nsIGfxInfo::FEATURE_WEBRENDER
,
763 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
, DRIVER_GREATER_THAN_OR_EQUAL
,
764 V(17, 0, 0, 0), "FEATURE_ROLLOUT_EARLY_BETA_INTEL_MESA",
767 // Nvidia Mesa baseline, see bug 1563859.
768 APPEND_TO_DRIVER_BLOCKLIST_EXT(
769 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
770 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
771 DeviceFamily::NvidiaRolloutWebRender
, nsIGfxInfo::FEATURE_WEBRENDER
,
772 nsIGfxInfo::FEATURE_ALLOW_QUALIFIED
, DRIVER_GREATER_THAN_OR_EQUAL
,
773 V(18, 2, 0, 0), "FEATURE_ROLLOUT_EARLY_BETA_NVIDIA_MESA",
776 // Nvidia proprietary driver baseline, see bug 1673752.
777 APPEND_TO_DRIVER_BLOCKLIST_EXT(
778 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
779 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::NonMesaAll
,
780 DeviceFamily::NvidiaAll
, nsIGfxInfo::FEATURE_WEBRENDER
,
781 nsIGfxInfo::FEATURE_ALLOW_QUALIFIED
, DRIVER_GREATER_THAN_OR_EQUAL
,
782 V(460, 32, 3, 0), "FEATURE_FAILURE_WEBRENDER_OLD_NVIDIA", "460.32.03");
784 // ATI Mesa baseline, chosen arbitrarily.
785 APPEND_TO_DRIVER_BLOCKLIST_EXT(
786 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
787 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
788 DeviceFamily::AtiRolloutWebRender
, nsIGfxInfo::FEATURE_WEBRENDER
,
789 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
, DRIVER_GREATER_THAN_OR_EQUAL
,
790 V(17, 0, 0, 0), "FEATURE_ROLLOUT_EARLY_BETA_ATI_MESA", "Mesa 17.0.0.0");
793 ////////////////////////////////////
794 // FEATURE_WEBRENDER_SOFTWARE - ALLOWLIST
795 #ifdef EARLY_BETA_OR_EARLIER
796 # if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
797 defined(__i386) || defined(__amd64__)
798 APPEND_TO_DRIVER_BLOCKLIST(OperatingSystem::Linux
, DeviceFamily::All
,
799 nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE
,
800 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
,
801 DRIVER_COMPARISON_IGNORED
, V(0, 0, 0, 0),
802 "FEATURE_ROLLOUT_EARLY_BETA_SOFTWARE_WR", "");
806 ////////////////////////////////////
808 APPEND_TO_DRIVER_BLOCKLIST_EXT(
809 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
810 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaNouveau
,
811 DeviceFamily::All
, nsIGfxInfo::FEATURE_THREADSAFE_GL
,
812 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_COMPARISON_IGNORED
,
813 V(0, 0, 0, 0), "FEATURE_FAILURE_THREADSAFE_GL", "");
818 bool GfxInfo::DoesWindowProtocolMatch(const nsAString
& aBlocklistWindowProtocol
,
819 const nsAString
& aWindowProtocol
) {
821 aBlocklistWindowProtocol
.Equals(
822 GfxDriverInfo::GetWindowProtocol(WindowProtocol::WaylandAll
),
823 nsCaseInsensitiveStringComparator
)) {
827 aBlocklistWindowProtocol
.Equals(
828 GfxDriverInfo::GetWindowProtocol(WindowProtocol::X11All
),
829 nsCaseInsensitiveStringComparator
)) {
832 return GfxInfoBase::DoesWindowProtocolMatch(aBlocklistWindowProtocol
,
836 bool GfxInfo::DoesDriverVendorMatch(const nsAString
& aBlocklistVendor
,
837 const nsAString
& aDriverVendor
) {
839 if (aBlocklistVendor
.Equals(
840 GfxDriverInfo::GetDriverVendor(DriverVendor::MesaAll
),
841 nsCaseInsensitiveStringComparator
)) {
844 if (mIsAccelerated
&&
845 aBlocklistVendor
.Equals(
846 GfxDriverInfo::GetDriverVendor(DriverVendor::HardwareMesaAll
),
847 nsCaseInsensitiveStringComparator
)) {
850 if (!mIsAccelerated
&&
851 aBlocklistVendor
.Equals(
852 GfxDriverInfo::GetDriverVendor(DriverVendor::SoftwareMesaAll
),
853 nsCaseInsensitiveStringComparator
)) {
857 if (!mIsMesa
&& aBlocklistVendor
.Equals(
858 GfxDriverInfo::GetDriverVendor(DriverVendor::NonMesaAll
),
859 nsCaseInsensitiveStringComparator
)) {
862 return GfxInfoBase::DoesDriverVendorMatch(aBlocklistVendor
, aDriverVendor
);
865 nsresult
GfxInfo::GetFeatureStatusImpl(
866 int32_t aFeature
, int32_t* aStatus
, nsAString
& aSuggestedDriverVersion
,
867 const nsTArray
<GfxDriverInfo
>& aDriverInfo
, nsACString
& aFailureId
,
868 OperatingSystem
* aOS
/* = nullptr */)
871 NS_ENSURE_ARG_POINTER(aStatus
);
872 *aStatus
= nsIGfxInfo::FEATURE_STATUS_UNKNOWN
;
873 aSuggestedDriverVersion
.SetIsVoid(true);
874 OperatingSystem os
= OperatingSystem::Linux
;
877 if (sShutdownOccurred
) {
884 // If glxtest failed, block all features by default.
885 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
886 aFailureId
= "FEATURE_FAILURE_GLXTEST_FAILED";
890 if (mGLMajorVersion
== 1) {
891 // We're on OpenGL 1. In most cases that indicates really old hardware.
892 // We better block them, rather than rely on them to fail gracefully,
893 // because they don't! see bug 696636
894 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
895 aFailureId
= "FEATURE_FAILURE_OPENGL_1";
899 // Blocklist software GL implementations from using layers acceleration.
900 // On the test infrastructure, we'll force-enable layers acceleration.
901 if (aFeature
== nsIGfxInfo::FEATURE_OPENGL_LAYERS
&& !mIsAccelerated
&&
902 !PR_GetEnv("MOZ_LAYERS_ALLOW_SOFTWARE_GL")) {
903 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
904 aFailureId
= "FEATURE_FAILURE_SOFTWARE_GL";
908 return GfxInfoBase::GetFeatureStatusImpl(
909 aFeature
, aStatus
, aSuggestedDriverVersion
, aDriverInfo
, aFailureId
, &os
);
913 GfxInfo::GetD2DEnabled(bool* aEnabled
) { return NS_ERROR_FAILURE
; }
916 GfxInfo::GetDWriteEnabled(bool* aEnabled
) { return NS_ERROR_FAILURE
; }
919 GfxInfo::GetDWriteVersion(nsAString
& aDwriteVersion
) {
920 return NS_ERROR_FAILURE
;
923 NS_IMETHODIMP
GfxInfo::GetHasBattery(bool* aHasBattery
) {
924 return NS_ERROR_NOT_IMPLEMENTED
;
928 GfxInfo::GetEmbeddedInFirefoxReality(bool* aEmbeddedInFirefoxReality
) {
929 return NS_ERROR_FAILURE
;
933 GfxInfo::GetCleartypeParameters(nsAString
& aCleartypeParams
) {
934 return NS_ERROR_FAILURE
;
938 GfxInfo::GetWindowProtocol(nsAString
& aWindowProtocol
) {
943 GfxDriverInfo::GetWindowProtocol(WindowProtocol::WaylandDRM
);
946 GfxDriverInfo::GetWindowProtocol(WindowProtocol::Wayland
);
948 } else if (mIsXWayland
) {
950 GfxDriverInfo::GetWindowProtocol(WindowProtocol::XWayland
);
952 aWindowProtocol
= GfxDriverInfo::GetWindowProtocol(WindowProtocol::X11
);
954 Telemetry::ScalarSet(Telemetry::ScalarID::GFX_LINUX_WINDOW_PROTOCOL
,
960 GfxInfo::GetDesktopEnvironment(nsAString
& aDesktopEnvironment
) {
962 AppendASCIItoUTF16(mDesktopEnvironment
, aDesktopEnvironment
);
967 GfxInfo::GetTestType(nsAString
& aTestType
) {
969 AppendASCIItoUTF16(mTestType
, aTestType
);
974 GfxInfo::GetAdapterDescription(nsAString
& aAdapterDescription
) {
976 AppendASCIItoUTF16(mAdapterDescription
, aAdapterDescription
);
981 GfxInfo::GetAdapterDescription2(nsAString
& aAdapterDescription
) {
982 return NS_ERROR_FAILURE
;
986 GfxInfo::GetAdapterRAM(uint32_t* aAdapterRAM
) {
988 *aAdapterRAM
= mAdapterRAM
;
993 GfxInfo::GetAdapterRAM2(uint32_t* aAdapterRAM
) { return NS_ERROR_FAILURE
; }
996 GfxInfo::GetAdapterDriver(nsAString
& aAdapterDriver
) {
997 aAdapterDriver
.Truncate();
1002 GfxInfo::GetAdapterDriver2(nsAString
& aAdapterDriver
) {
1003 return NS_ERROR_FAILURE
;
1007 GfxInfo::GetAdapterDriverVendor(nsAString
& aAdapterDriverVendor
) {
1009 CopyASCIItoUTF16(mDriverVendor
, aAdapterDriverVendor
);
1014 GfxInfo::GetAdapterDriverVendor2(nsAString
& aAdapterDriverVendor
) {
1015 return NS_ERROR_FAILURE
;
1019 GfxInfo::GetAdapterDriverVersion(nsAString
& aAdapterDriverVersion
) {
1021 CopyASCIItoUTF16(mDriverVersion
, aAdapterDriverVersion
);
1026 GfxInfo::GetAdapterDriverVersion2(nsAString
& aAdapterDriverVersion
) {
1027 return NS_ERROR_FAILURE
;
1031 GfxInfo::GetAdapterDriverDate(nsAString
& aAdapterDriverDate
) {
1032 aAdapterDriverDate
.Truncate();
1037 GfxInfo::GetAdapterDriverDate2(nsAString
& aAdapterDriverDate
) {
1038 return NS_ERROR_FAILURE
;
1042 GfxInfo::GetAdapterVendorID(nsAString
& aAdapterVendorID
) {
1044 CopyUTF8toUTF16(mVendorId
, aAdapterVendorID
);
1049 GfxInfo::GetAdapterVendorID2(nsAString
& aAdapterVendorID
) {
1051 CopyUTF8toUTF16(mSecondaryVendorId
, aAdapterVendorID
);
1056 GfxInfo::GetAdapterDeviceID(nsAString
& aAdapterDeviceID
) {
1058 CopyUTF8toUTF16(mDeviceId
, aAdapterDeviceID
);
1063 GfxInfo::GetAdapterDeviceID2(nsAString
& aAdapterDeviceID
) {
1065 CopyUTF8toUTF16(mSecondaryDeviceId
, aAdapterDeviceID
);
1070 GfxInfo::GetAdapterSubsysID(nsAString
& aAdapterSubsysID
) {
1071 return NS_ERROR_FAILURE
;
1075 GfxInfo::GetAdapterSubsysID2(nsAString
& aAdapterSubsysID
) {
1076 return NS_ERROR_FAILURE
;
1080 GfxInfo::GetDisplayInfo(nsTArray
<nsString
>& aDisplayInfo
) {
1083 for (auto screenInfo
: mScreenInfo
) {
1084 nsString infoString
;
1085 infoString
.AppendPrintf("%dx%d %s", screenInfo
.mWidth
, screenInfo
.mHeight
,
1086 screenInfo
.mIsDefault
? "default" : "");
1087 aDisplayInfo
.AppendElement(infoString
);
1090 return aDisplayInfo
.IsEmpty() ? NS_ERROR_FAILURE
: NS_OK
;
1094 GfxInfo::GetDisplayWidth(nsTArray
<uint32_t>& aDisplayWidth
) {
1095 for (auto screenInfo
: mScreenInfo
) {
1096 aDisplayWidth
.AppendElement((uint32_t)screenInfo
.mWidth
);
1102 GfxInfo::GetDisplayHeight(nsTArray
<uint32_t>& aDisplayHeight
) {
1103 for (auto screenInfo
: mScreenInfo
) {
1104 aDisplayHeight
.AppendElement((uint32_t)screenInfo
.mHeight
);
1110 GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active
) {
1111 // This is never the case, as the active GPU should be the primary GPU.
1112 *aIsGPU2Active
= false;
1117 GfxInfo::GetDrmRenderDevice(nsACString
& aDrmRenderDevice
) {
1119 aDrmRenderDevice
.Assign(mDrmRenderDevice
);
1125 // Implement nsIGfxInfoDebug
1126 // We don't support spoofing anything on Linux
1128 NS_IMETHODIMP
GfxInfo::SpoofVendorID(const nsAString
& aVendorID
) {
1130 CopyUTF16toUTF8(aVendorID
, mVendorId
);
1131 mIsAccelerated
= true;
1135 NS_IMETHODIMP
GfxInfo::SpoofDeviceID(const nsAString
& aDeviceID
) {
1137 CopyUTF16toUTF8(aDeviceID
, mDeviceId
);
1141 NS_IMETHODIMP
GfxInfo::SpoofDriverVersion(const nsAString
& aDriverVersion
) {
1143 CopyUTF16toUTF8(aDriverVersion
, mDriverVersion
);
1147 NS_IMETHODIMP
GfxInfo::SpoofOSVersion(uint32_t aVersion
) {
1148 // We don't support OS versioning on Linux. There's just "Linux".
1152 NS_IMETHODIMP
GfxInfo::FireTestProcess() {
1153 // If the pid is zero, then we have never run the test process to query for
1154 // driver information. This would normally be run on startup, but we need to
1155 // manually invoke it for XPC shell tests.
1156 if (glxtest_pid
== 0) {
1157 fire_glxtest_process();
1164 } // namespace mozilla::widget