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/. */
14 #include <sys/types.h>
15 #include <sys/utsname.h>
18 #include "mozilla/gfx/Logging.h"
19 #include "mozilla/SSE.h"
20 #include "mozilla/Telemetry.h"
21 #include "nsCRTGlue.h"
22 #include "nsExceptionHandler.h"
23 #include "nsPrintfCString.h"
24 #include "nsUnicharUtils.h"
25 #include "nsWhitespaceTokenizer.h"
27 #include "WidgetUtilsGtk.h"
29 #define EXIT_STATUS_BUFFER_TOO_SMALL 2
31 bool fire_glxtest_process();
34 namespace mozilla::widget
{
37 NS_IMPL_ISUPPORTS_INHERITED(GfxInfo
, GfxInfoBase
, nsIGfxInfoDebug
)
40 // these global variables will be set when firing the glxtest process
41 int glxtest_pipe
= -1;
42 pid_t glxtest_pid
= 0;
44 nsresult
GfxInfo::Init() {
47 mHasTextureFromPixmap
= false;
49 mIsAccelerated
= true;
52 mHasMultipleGPUs
= false;
53 mGlxTestError
= false;
54 return GfxInfoBase::Init();
57 void GfxInfo::AddCrashReportAnnotations() {
58 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID
,
60 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID
,
62 CrashReporter::AnnotateCrashReport(
63 CrashReporter::Annotation::AdapterDriverVendor
, mDriverVendor
);
64 CrashReporter::AnnotateCrashReport(
65 CrashReporter::Annotation::AdapterDriverVersion
, mDriverVersion
);
66 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::IsWayland
,
68 CrashReporter::AnnotateCrashReport(
69 CrashReporter::Annotation::DesktopEnvironment
, mDesktopEnvironment
);
71 if (mHasMultipleGPUs
) {
73 note
.AppendLiteral("Has dual GPUs.");
74 if (!mSecondaryVendorId
.IsEmpty()) {
75 note
.AppendLiteral(" GPU #2: AdapterVendorID2: ");
76 note
.Append(mSecondaryVendorId
);
77 note
.AppendLiteral(", AdapterDeviceID2: ");
78 note
.Append(mSecondaryDeviceId
);
80 CrashReporter::AppendAppNotesToCrashReport(note
);
84 void GfxInfo::GetData() {
85 GfxInfoBase::GetData();
87 // to understand this function, see bug 639842. We retrieve the OpenGL driver
88 // information in a separate process to protect against bad drivers.
90 // if glxtest_pipe == -1, that means that we already read the information
91 if (glxtest_pipe
== -1) return;
93 enum { buf_size
= 2048 };
95 ssize_t bytesread
= read(glxtest_pipe
, &buf
,
96 buf_size
- 1); // -1 because we'll append a zero
100 // bytesread < 0 would mean that the above read() call failed.
101 // This should never happen. If it did, the outcome would be to blocklist
105 } else if (bytesread
== buf_size
- 1) {
106 gfxCriticalNote
<< "glxtest: read from pipe exceeded buffer size";
109 // let buf be a zero-terminated string
112 // Wait for the glxtest process to finish. This serves 2 purposes:
113 // * avoid having a zombie glxtest process laying around
114 // * get the glxtest process status info.
115 int glxtest_status
= 0;
116 bool wait_for_glxtest_process
= true;
117 bool waiting_for_glxtest_process_failed
= false;
118 int waitpid_errno
= 0;
119 while (wait_for_glxtest_process
) {
120 wait_for_glxtest_process
= false;
121 if (waitpid(glxtest_pid
, &glxtest_status
, 0) == -1) {
122 waitpid_errno
= errno
;
123 if (waitpid_errno
== EINTR
) {
124 wait_for_glxtest_process
= true;
127 // ECHILD happens when the glxtest process got reaped got reaped after a
128 // PR_CreateProcess as per bug 227246. This shouldn't matter, as we
129 // still seem to get the data from the pipe, and if we didn't, the
130 // outcome would be to blocklist anyway.
131 waiting_for_glxtest_process_failed
= (waitpid_errno
!= ECHILD
);
136 int exit_code
= EXIT_FAILURE
;
137 bool exited_with_error_code
= false;
138 if (!waiting_for_glxtest_process_failed
&& WIFEXITED(glxtest_status
)) {
139 exit_code
= WEXITSTATUS(glxtest_status
);
140 exited_with_error_code
= exit_code
!= EXIT_SUCCESS
;
143 bool received_signal
=
144 !waiting_for_glxtest_process_failed
&& WIFSIGNALED(glxtest_status
);
146 bool error
= waiting_for_glxtest_process_failed
|| exited_with_error_code
||
148 bool errorLog
= false;
151 nsCString glRenderer
;
153 nsCString textureFromPixmap
;
156 // Available if GLX_MESA_query_renderer is supported.
157 nsCString mesaVendor
;
158 nsCString mesaDevice
;
159 nsCString mesaAccelerated
;
160 // Available if using a DRI-based libGL stack.
162 nsCString screenInfo
;
163 nsCString adapterRam
;
165 nsCString drmRenderDevice
;
169 AutoTArray
<nsCString
, 2> pciVendors
;
170 AutoTArray
<nsCString
, 2> pciDevices
;
172 nsCString
* stringToFill
= nullptr;
173 bool logString
= false;
177 char* line
= NS_strtok("\n", &bufptr
);
180 stringToFill
->Assign(line
);
181 stringToFill
= nullptr;
182 } else if (logString
) {
183 gfxCriticalNote
<< "glxtest: " << line
;
185 } else if (!strcmp(line
, "VENDOR")) {
186 stringToFill
= &glVendor
;
187 } else if (!strcmp(line
, "RENDERER")) {
188 stringToFill
= &glRenderer
;
189 } else if (!strcmp(line
, "VERSION")) {
190 stringToFill
= &glVersion
;
191 } else if (!strcmp(line
, "TFP")) {
192 stringToFill
= &textureFromPixmap
;
193 } else if (!strcmp(line
, "MESA_VENDOR_ID")) {
194 stringToFill
= &mesaVendor
;
195 } else if (!strcmp(line
, "MESA_DEVICE_ID")) {
196 stringToFill
= &mesaDevice
;
197 } else if (!strcmp(line
, "MESA_ACCELERATED")) {
198 stringToFill
= &mesaAccelerated
;
199 } else if (!strcmp(line
, "MESA_VRAM")) {
200 stringToFill
= &adapterRam
;
201 } else if (!strcmp(line
, "DDX_DRIVER")) {
202 stringToFill
= &ddxDriver
;
203 } else if (!strcmp(line
, "DRI_DRIVER")) {
204 stringToFill
= &driDriver
;
205 } else if (!strcmp(line
, "SCREEN_INFO")) {
206 stringToFill
= &screenInfo
;
207 } else if (!strcmp(line
, "PCI_VENDOR_ID")) {
208 stringToFill
= pciVendors
.AppendElement();
209 } else if (!strcmp(line
, "PCI_DEVICE_ID")) {
210 stringToFill
= pciDevices
.AppendElement();
211 } else if (!strcmp(line
, "DRM_RENDERDEVICE")) {
212 stringToFill
= &drmRenderDevice
;
213 } else if (!strcmp(line
, "TEST_TYPE")) {
214 stringToFill
= &testType
;
215 } else if (!strcmp(line
, "WARNING")) {
217 } else if (!strcmp(line
, "ERROR")) {
223 MOZ_ASSERT(pciDevices
.Length() == pciVendors
.Length(),
224 "Missing PCI vendors/devices");
226 size_t pciLen
= std::min(pciVendors
.Length(), pciDevices
.Length());
227 mHasMultipleGPUs
= pciLen
> 1;
229 if (!strcmp(textureFromPixmap
.get(), "TRUE")) mHasTextureFromPixmap
= true;
231 // only useful for Linux kernel version check for FGLRX driver.
232 // assumes X client == X server, which is sad.
233 struct utsname unameobj
{};
234 if (uname(&unameobj
) >= 0) {
235 mOS
.Assign(unameobj
.sysname
);
236 mOSRelease
.Assign(unameobj
.release
);
239 const char* spoofedVendor
= PR_GetEnv("MOZ_GFX_SPOOF_GL_VENDOR");
240 if (spoofedVendor
) glVendor
.Assign(spoofedVendor
);
241 const char* spoofedRenderer
= PR_GetEnv("MOZ_GFX_SPOOF_GL_RENDERER");
242 if (spoofedRenderer
) glRenderer
.Assign(spoofedRenderer
);
243 const char* spoofedVersion
= PR_GetEnv("MOZ_GFX_SPOOF_GL_VERSION");
244 if (spoofedVersion
) glVersion
.Assign(spoofedVersion
);
245 const char* spoofedOS
= PR_GetEnv("MOZ_GFX_SPOOF_OS");
246 if (spoofedOS
) mOS
.Assign(spoofedOS
);
247 const char* spoofedOSRelease
= PR_GetEnv("MOZ_GFX_SPOOF_OS_RELEASE");
248 if (spoofedOSRelease
) mOSRelease
.Assign(spoofedOSRelease
);
250 // Scan the GL_VERSION string for the GL and driver versions.
251 nsCWhitespaceTokenizer
tokenizer(glVersion
);
252 while (tokenizer
.hasMoreTokens()) {
253 nsCString
token(tokenizer
.nextToken());
254 unsigned int major
= 0, minor
= 0, revision
= 0, patch
= 0;
255 if (sscanf(token
.get(), "%u.%u.%u.%u", &major
, &minor
, &revision
, &patch
) >=
257 // A survey of GL_VENDOR strings indicates that the first version is
258 // always the GL version, the second is usually the driver version.
259 if (mGLMajorVersion
== 0) {
260 mGLMajorVersion
= major
;
261 mGLMinorVersion
= minor
;
262 } else if (mDriverVersion
.IsEmpty()) { // Not already spoofed.
264 nsPrintfCString("%u.%u.%u.%u", major
, minor
, revision
, patch
);
269 if (mGLMajorVersion
== 0) {
270 NS_WARNING("Failed to parse GL version!");
273 mDrmRenderDevice
= std::move(drmRenderDevice
);
274 mTestType
= std::move(testType
);
276 // Mesa always exposes itself in the GL_VERSION string, but not always the
278 mIsMesa
= glVersion
.Find("Mesa") != -1;
280 // We need to use custom driver vendor IDs for mesa so we can treat them
281 // differently than the proprietary drivers.
283 mIsAccelerated
= !mesaAccelerated
.Equals("FALSE");
284 // Process software rasterizers before the DRI driver string; we may be
285 // forcing software rasterization on a DRI-accelerated X server by using
286 // LIBGL_ALWAYS_SOFTWARE or a similar restriction.
287 if (strcasestr(glRenderer
.get(), "llvmpipe")) {
289 GfxDriverInfo::GetDriverVendor(DriverVendor::MesaLLVMPipe
),
291 mIsAccelerated
= false;
292 } else if (strcasestr(glRenderer
.get(), "softpipe")) {
294 GfxDriverInfo::GetDriverVendor(DriverVendor::MesaSoftPipe
),
296 mIsAccelerated
= false;
297 } else if (strcasestr(glRenderer
.get(), "software rasterizer")) {
298 CopyUTF16toUTF8(GfxDriverInfo::GetDriverVendor(DriverVendor::MesaSWRast
),
300 mIsAccelerated
= false;
301 } else if (!mIsAccelerated
) {
303 GfxDriverInfo::GetDriverVendor(DriverVendor::MesaSWUnknown
),
305 } else if (!driDriver
.IsEmpty()) {
306 mDriverVendor
= nsPrintfCString("mesa/%s", driDriver
.get());
308 // Some other mesa configuration where we couldn't get enough info.
309 NS_WARNING("Failed to detect Mesa driver being used!");
310 CopyUTF16toUTF8(GfxDriverInfo::GetDriverVendor(DriverVendor::MesaUnknown
),
314 if (!mesaVendor
.IsEmpty()) {
315 mVendorId
= mesaVendor
;
318 if (!mesaDevice
.IsEmpty()) {
319 mDeviceId
= mesaDevice
;
322 if (!mIsAccelerated
&& mVendorId
.IsEmpty()) {
323 mVendorId
.Assign(glVendor
.get());
326 if (!mIsAccelerated
&& mDeviceId
.IsEmpty()) {
327 mDeviceId
.Assign(glRenderer
.get());
329 } else if (glVendor
.EqualsLiteral("NVIDIA Corporation")) {
330 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::NVIDIA
),
332 mDriverVendor
.AssignLiteral("nvidia/unknown");
333 // TODO: Use NV-CONTROL X11 extension to query Device ID and VRAM.
334 } else if (glVendor
.EqualsLiteral("ATI Technologies Inc.")) {
335 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::ATI
),
337 mDriverVendor
.AssignLiteral("ati/unknown");
338 // TODO: Look into ways to find the device ID on FGLRX.
340 NS_WARNING("Failed to detect GL vendor!");
343 if (!screenInfo
.IsEmpty()) {
345 PRInt32 loc
= screenInfo
.Find(";", PR_FALSE
, start
);
346 while (loc
!= kNotFound
) {
348 nsCString
line(screenInfo
.get() + start
, loc
- start
);
350 if (sscanf(line
.get(), "%ux%u:%u", &info
.mWidth
, &info
.mHeight
,
352 info
.mIsDefault
= isDefault
!= 0;
353 mScreenInfo
.AppendElement(info
);
357 loc
= screenInfo
.Find(";", PR_FALSE
, start
);
361 if (!adapterRam
.IsEmpty()) {
362 mAdapterRAM
= (uint32_t)atoi(adapterRam
.get());
365 // If we have the DRI driver, we can derive the vendor ID from that if needed.
366 if (mVendorId
.IsEmpty() && !driDriver
.IsEmpty()) {
367 const char* nvidiaDrivers
[] = {"nouveau", "tegra", nullptr};
368 for (size_t i
= 0; nvidiaDrivers
[i
]; ++i
) {
369 if (driDriver
.Equals(nvidiaDrivers
[i
])) {
370 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::NVIDIA
),
376 if (mVendorId
.IsEmpty()) {
377 const char* intelDrivers
[] = {"iris", "i915", "i965",
378 "i810", "intel", nullptr};
379 for (size_t i
= 0; intelDrivers
[i
]; ++i
) {
380 if (driDriver
.Equals(intelDrivers
[i
])) {
381 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::Intel
),
388 if (mVendorId
.IsEmpty()) {
389 const char* amdDrivers
[] = {"r600", "r200", "r100",
390 "radeon", "radeonsi", nullptr};
391 for (size_t i
= 0; amdDrivers
[i
]; ++i
) {
392 if (driDriver
.Equals(amdDrivers
[i
])) {
393 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::ATI
),
400 if (mVendorId
.IsEmpty()) {
401 if (driDriver
.EqualsLiteral("freedreno")) {
402 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::Qualcomm
),
408 // If we still don't have a vendor ID, we can try the PCI vendor list.
409 if (mVendorId
.IsEmpty()) {
410 if (pciVendors
.IsEmpty()) {
411 gfxCriticalNote
<< "No GPUs detected via PCI";
413 for (size_t i
= 0; i
< pciVendors
.Length(); ++i
) {
414 if (mVendorId
.IsEmpty()) {
415 mVendorId
= pciVendors
[i
];
416 } else if (mVendorId
!= pciVendors
[i
]) {
417 gfxCriticalNote
<< "More than 1 GPU vendor detected via PCI, cannot "
419 mVendorId
.Truncate();
426 // If we know the vendor ID, but didn't get a device ID, we can guess from the
428 if (mDeviceId
.IsEmpty() && !mVendorId
.IsEmpty()) {
429 for (size_t i
= 0; i
< pciLen
; ++i
) {
430 if (mVendorId
.Equals(pciVendors
[i
])) {
431 if (mDeviceId
.IsEmpty()) {
432 mDeviceId
= pciDevices
[i
];
433 } else if (mDeviceId
!= pciDevices
[i
]) {
434 gfxCriticalNote
<< "More than 1 GPU from same vendor detected via "
435 "PCI, cannot deduce device";
436 mDeviceId
.Truncate();
443 // Assuming we know the vendor, we should check for a secondary card.
444 if (!mVendorId
.IsEmpty()) {
447 << "More than 2 GPUs detected via PCI, secondary GPU is arbitrary";
449 for (size_t i
= 0; i
< pciLen
; ++i
) {
450 if (!mVendorId
.Equals(pciVendors
[i
]) ||
451 (!mDeviceId
.IsEmpty() && !mDeviceId
.Equals(pciDevices
[i
]))) {
452 mSecondaryVendorId
= pciVendors
[i
];
453 mSecondaryDeviceId
= pciDevices
[i
];
459 // If we couldn't choose, log them.
460 if (mVendorId
.IsEmpty()) {
461 for (size_t i
= 0; i
< pciLen
; ++i
) {
462 gfxCriticalNote
<< "PCI candidate " << pciVendors
[i
].get() << "/"
463 << pciDevices
[i
].get();
467 // Fallback to GL_VENDOR and GL_RENDERER.
468 if (mVendorId
.IsEmpty()) {
469 mVendorId
.Assign(glVendor
.get());
471 if (mDeviceId
.IsEmpty()) {
472 mDeviceId
.Assign(glRenderer
.get());
475 mAdapterDescription
.Assign(glRenderer
);
477 // Make a best effort guess at whether or not we are using the XWayland compat
478 // layer. For all intents and purposes, we should otherwise believe we are
480 mIsWayland
= GdkIsWaylandDisplay();
481 const char* waylandDisplay
= getenv("WAYLAND_DISPLAY");
482 mIsXWayland
= !mIsWayland
&& waylandDisplay
;
484 // Make a best effort guess at the desktop environment in use. Sadly there
485 // does not appear to be a standard way to do this, so we check a few
486 // different environment variables and search for relevant keywords.
488 // Note that some users manually change these values. Some applications check
489 // the environment variable like we are here, and either not work or restrict
490 // functionality. There may be some heroics we could go through to determine
491 // the truth, but for the moment, this is the best we can do. This is
492 // something to keep in mind when updating the blocklist.
493 const char* desktopEnv
= getenv("XDG_CURRENT_DESKTOP");
495 desktopEnv
= getenv("DESKTOP_SESSION");
499 std::string
currentDesktop(desktopEnv
);
500 for (auto& c
: currentDesktop
) {
504 if (currentDesktop
.find("budgie") != std::string::npos
) {
505 // We need to check for Budgie first, because it might incorporate GNOME
506 // into the environment variable value.
508 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Budgie
),
509 mDesktopEnvironment
);
510 } else if (currentDesktop
.find("gnome") != std::string::npos
) {
512 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::GNOME
),
513 mDesktopEnvironment
);
514 } else if (currentDesktop
.find("kde") != std::string::npos
) {
516 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::KDE
),
517 mDesktopEnvironment
);
518 } else if (currentDesktop
.find("xfce") != std::string::npos
) {
520 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::XFCE
),
521 mDesktopEnvironment
);
522 } else if (currentDesktop
.find("cinnamon") != std::string::npos
) {
524 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Cinnamon
),
525 mDesktopEnvironment
);
526 } else if (currentDesktop
.find("enlightenment") != std::string::npos
) {
527 CopyUTF16toUTF8(GfxDriverInfo::GetDesktopEnvironment(
528 DesktopEnvironment::Enlightenment
),
529 mDesktopEnvironment
);
530 } else if (currentDesktop
.find("lxde") != std::string::npos
||
531 currentDesktop
.find("lubuntu") != std::string::npos
) {
533 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::LXDE
),
534 mDesktopEnvironment
);
535 } else if (currentDesktop
.find("openbox") != std::string::npos
) {
537 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Openbox
),
538 mDesktopEnvironment
);
539 } else if (currentDesktop
.find("i3") != std::string::npos
) {
541 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::i3
),
542 mDesktopEnvironment
);
543 } else if (currentDesktop
.find("sway") != std::string::npos
) {
545 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Sway
),
546 mDesktopEnvironment
);
547 } else if (currentDesktop
.find("mate") != std::string::npos
) {
549 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Mate
),
550 mDesktopEnvironment
);
551 } else if (currentDesktop
.find("unity") != std::string::npos
) {
553 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Unity
),
554 mDesktopEnvironment
);
555 } else if (currentDesktop
.find("pantheon") != std::string::npos
) {
557 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Pantheon
),
558 mDesktopEnvironment
);
559 } else if (currentDesktop
.find("lxqt") != std::string::npos
) {
561 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::LXQT
),
562 mDesktopEnvironment
);
563 } else if (currentDesktop
.find("deepin") != std::string::npos
) {
565 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Deepin
),
566 mDesktopEnvironment
);
567 } else if (currentDesktop
.find("dwm") != std::string::npos
) {
569 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Dwm
),
570 mDesktopEnvironment
);
574 if (mDesktopEnvironment
.IsEmpty()) {
575 if (getenv("GNOME_DESKTOP_SESSION_ID")) {
577 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::GNOME
),
578 mDesktopEnvironment
);
579 } else if (getenv("KDE_FULL_SESSION")) {
581 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::KDE
),
582 mDesktopEnvironment
);
583 } else if (getenv("MATE_DESKTOP_SESSION_ID")) {
585 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Mate
),
586 mDesktopEnvironment
);
587 } else if (getenv("LXQT_SESSION_CONFIG")) {
589 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::LXQT
),
590 mDesktopEnvironment
);
593 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Unknown
),
594 mDesktopEnvironment
);
598 if (!ddxDriver
.IsEmpty()) {
600 PRInt32 loc
= ddxDriver
.Find(";", PR_FALSE
, start
);
601 while (loc
!= kNotFound
) {
602 nsCString
line(ddxDriver
.get() + start
, loc
- start
);
603 mDdxDrivers
.AppendElement(std::move(line
));
606 loc
= ddxDriver
.Find(";", PR_FALSE
, start
);
610 if (error
|| errorLog
|| mTestType
.IsEmpty()) {
611 if (!mAdapterDescription
.IsEmpty()) {
612 mAdapterDescription
.AppendLiteral(" (See failure log)");
614 mAdapterDescription
.AppendLiteral("See failure log");
617 mGlxTestError
= true;
621 nsAutoCString
msg("glxtest: process failed");
622 if (waiting_for_glxtest_process_failed
) {
623 msg
.AppendPrintf(" (waitpid failed with errno=%d for pid %d)",
624 waitpid_errno
, glxtest_pid
);
627 if (exited_with_error_code
) {
628 if (exit_code
== EXIT_STATUS_BUFFER_TOO_SMALL
) {
629 msg
.AppendLiteral(" (buffer too small)");
631 msg
.AppendPrintf(" (exited with status %d)",
632 WEXITSTATUS(glxtest_status
));
635 if (received_signal
) {
636 msg
.AppendPrintf(" (received signal %d)", WTERMSIG(glxtest_status
));
639 gfxCriticalNote
<< msg
.get();
642 AddCrashReportAnnotations();
645 const nsTArray
<GfxDriverInfo
>& GfxInfo::GetGfxDriverInfo() {
646 if (!sDriverInfo
->Length()) {
647 // Mesa 10.0 provides the GLX_MESA_query_renderer extension, which allows us
648 // to query device IDs backing a GL context for blocklisting.
649 APPEND_TO_DRIVER_BLOCKLIST_EXT(
650 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
651 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
652 DeviceFamily::All
, GfxDriverInfo::allFeatures
,
653 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
654 V(10, 0, 0, 0), "FEATURE_FAILURE_OLD_MESA", "Mesa 10.0");
656 // NVIDIA Mesa baseline (see bug 1714391).
657 APPEND_TO_DRIVER_BLOCKLIST_EXT(
658 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
659 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaNouveau
,
660 DeviceFamily::All
, GfxDriverInfo::allFeatures
,
661 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
662 V(11, 0, 0, 0), "FEATURE_FAILURE_OLD_NV_MESA", "Mesa 11.0");
664 // NVIDIA baseline (ported from old blocklist)
665 APPEND_TO_DRIVER_BLOCKLIST_EXT(
666 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
667 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::NonMesaAll
,
668 DeviceFamily::NvidiaAll
, GfxDriverInfo::allFeatures
,
669 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
670 V(257, 21, 0, 0), "FEATURE_FAILURE_OLD_NVIDIA", "NVIDIA 257.21");
672 // fglrx baseline (chosen arbitrarily as 2013-07-22 release).
673 APPEND_TO_DRIVER_BLOCKLIST(
674 OperatingSystem::Linux
, DeviceFamily::AtiAll
,
675 GfxDriverInfo::allFeatures
, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
,
676 DRIVER_LESS_THAN
, V(13, 15, 100, 1), "FEATURE_FAILURE_OLD_FGLRX",
677 "fglrx 13.15.100.1");
679 ////////////////////////////////////
682 // All Mesa software drivers, they should get Software WebRender instead.
683 APPEND_TO_DRIVER_BLOCKLIST_EXT(
684 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
685 DesktopEnvironment::All
, WindowProtocol::All
,
686 DriverVendor::SoftwareMesaAll
, DeviceFamily::All
,
687 nsIGfxInfo::FEATURE_WEBRENDER
, nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
688 DRIVER_COMPARISON_IGNORED
, V(0, 0, 0, 0), "FEATURE_FAILURE_SOFTWARE_GL",
691 APPEND_TO_DRIVER_BLOCKLIST(
692 OperatingSystem::Linux
, DeviceFamily::IntelWebRenderBlocked
,
693 nsIGfxInfo::FEATURE_WEBRENDER
, nsIGfxInfo::FEATURE_BLOCKED_DEVICE
,
694 DRIVER_COMPARISON_IGNORED
, V(0, 0, 0, 0), "INTEL_DEVICE_GEN5_OR_OLDER",
697 // Nvidia Mesa baseline, see bug 1563859.
698 APPEND_TO_DRIVER_BLOCKLIST_EXT(
699 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
700 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
701 DeviceFamily::NvidiaAll
, nsIGfxInfo::FEATURE_WEBRENDER
,
702 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
703 V(18, 2, 0, 0), "FEATURE_FAILURE_WEBRENDER_OLD_MESA", "Mesa 18.2.0.0");
705 // Disable on all older Nvidia drivers due to stability issues.
706 APPEND_TO_DRIVER_BLOCKLIST_EXT(
707 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
708 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::NonMesaAll
,
709 DeviceFamily::NvidiaAll
, nsIGfxInfo::FEATURE_WEBRENDER
,
710 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_LESS_THAN
, V(460, 32, 3, 0),
711 "FEATURE_FAILURE_WEBRENDER_OLD_NVIDIA", "460.32.03");
713 // ATI Mesa baseline, chosen arbitrarily.
714 APPEND_TO_DRIVER_BLOCKLIST_EXT(
715 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
716 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
717 DeviceFamily::AtiAll
, nsIGfxInfo::FEATURE_WEBRENDER
,
718 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
719 V(17, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_OLD_MESA", "Mesa 17.0.0.0");
721 // Bug 1690568 / Bug 1393793 - Require Mesa 17.3.0+ for devices using the
722 // r600 driver to avoid shader compilation issues.
723 APPEND_TO_DRIVER_BLOCKLIST_EXT(
724 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
725 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaR600
,
726 DeviceFamily::All
, nsIGfxInfo::FEATURE_WEBRENDER
,
727 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
728 V(17, 3, 0, 0), "FEATURE_FAILURE_WEBRENDER_OLD_MESA_R600",
731 // Disable on all ATI devices not using Mesa for now.
732 APPEND_TO_DRIVER_BLOCKLIST_EXT(
733 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
734 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::NonMesaAll
,
735 DeviceFamily::AtiAll
, nsIGfxInfo::FEATURE_WEBRENDER
,
736 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_COMPARISON_IGNORED
,
737 V(0, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_NO_LINUX_ATI", "");
739 // Bug 1673939 - Garbled text on RS880 GPUs with Mesa drivers.
740 APPEND_TO_DRIVER_BLOCKLIST_EXT(
741 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
742 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
743 DeviceFamily::AmdR600
, nsIGfxInfo::FEATURE_WEBRENDER
,
744 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_COMPARISON_IGNORED
,
745 V(0, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_BUG_1673939",
746 "https://gitlab.freedesktop.org/mesa/mesa/-/issues/3720");
748 // Bug 1635186 - Poor performance with video playing in a background window
749 // on XWayland. Keep in sync with FEATURE_X11_EGL below to only enable them
750 // together by default. Only Mesa and Nvidia binary drivers are expected
751 // on Wayland rigth now.
752 APPEND_TO_DRIVER_BLOCKLIST_EXT(
753 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
754 DesktopEnvironment::All
, WindowProtocol::XWayland
,
755 DriverVendor::MesaAll
, DeviceFamily::All
, nsIGfxInfo::FEATURE_WEBRENDER
,
756 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
757 V(21, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_BUG_1635186",
760 ////////////////////////////////////
761 // FEATURE_WEBRENDER - ALLOWLIST
763 #if defined(EARLY_BETA_OR_EARLIER)
764 APPEND_TO_DRIVER_BLOCKLIST_EXT(
765 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
766 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
767 DeviceFamily::All
, nsIGfxInfo::FEATURE_WEBRENDER
,
768 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
, DRIVER_GREATER_THAN_OR_EQUAL
,
769 V(21, 0, 0, 0), "FEATURE_MESA", "Mesa 21.0.0.0");
772 // Intel Mesa baseline, chosen arbitrarily.
773 APPEND_TO_DRIVER_BLOCKLIST_EXT(
774 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
775 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
776 DeviceFamily::IntelAll
, nsIGfxInfo::FEATURE_WEBRENDER
,
777 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
, DRIVER_GREATER_THAN_OR_EQUAL
,
778 V(17, 0, 0, 0), "FEATURE_ROLLOUT_INTEL_MESA", "Mesa 17.0.0.0");
780 // Nvidia Mesa baseline, see bug 1563859.
781 APPEND_TO_DRIVER_BLOCKLIST_EXT(
782 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
783 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
784 DeviceFamily::NvidiaRolloutWebRender
, nsIGfxInfo::FEATURE_WEBRENDER
,
785 nsIGfxInfo::FEATURE_ALLOW_QUALIFIED
, DRIVER_GREATER_THAN_OR_EQUAL
,
786 V(18, 2, 0, 0), "FEATURE_ROLLOUT_NVIDIA_MESA", "Mesa 18.2.0.0");
788 // Nvidia proprietary driver baseline, see bug 1742994.
789 APPEND_TO_DRIVER_BLOCKLIST_EXT(
790 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
791 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::NonMesaAll
,
792 DeviceFamily::NvidiaAll
, nsIGfxInfo::FEATURE_WEBRENDER
,
793 nsIGfxInfo::FEATURE_ALLOW_QUALIFIED
, DRIVER_GREATER_THAN_OR_EQUAL
,
794 V(470, 82, 0, 0), "FEATURE_ROLLOUT_NVIDIA_BINARY", "470.82.0");
796 // ATI Mesa baseline, chosen arbitrarily.
797 APPEND_TO_DRIVER_BLOCKLIST_EXT(
798 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
799 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
800 DeviceFamily::AtiRolloutWebRender
, nsIGfxInfo::FEATURE_WEBRENDER
,
801 nsIGfxInfo::FEATURE_ALLOW_ALWAYS
, DRIVER_GREATER_THAN_OR_EQUAL
,
802 V(17, 0, 0, 0), "FEATURE_ROLLOUT_ATI_MESA", "Mesa 17.0.0.0");
804 ////////////////////////////////////
805 // FEATURE_WEBRENDER_COMPOSITOR
806 APPEND_TO_DRIVER_BLOCKLIST(
807 OperatingSystem::Linux
, DeviceFamily::All
,
808 nsIGfxInfo::FEATURE_WEBRENDER_COMPOSITOR
,
809 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_COMPARISON_IGNORED
,
810 V(0, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_COMPOSITOR_DISABLED", "");
812 ////////////////////////////////////
814 APPEND_TO_DRIVER_BLOCKLIST_EXT(
815 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
816 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaAll
,
817 DeviceFamily::All
, nsIGfxInfo::FEATURE_X11_EGL
,
818 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
819 V(21, 0, 0, 0), "FEATURE_ROLLOUT_X11_EGL_MESA", "Mesa 21.0.0.0");
821 APPEND_TO_DRIVER_BLOCKLIST_EXT(
822 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
823 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::NonMesaAll
,
824 DeviceFamily::NvidiaAll
, nsIGfxInfo::FEATURE_X11_EGL
,
825 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
826 V(470, 82, 0, 0), "FEATURE_ROLLOUT_X11_EGL_NVIDIA_BINARY", "470.82.0");
828 // Disable on all AMD devices not using Mesa.
829 APPEND_TO_DRIVER_BLOCKLIST_EXT(
830 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
831 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::NonMesaAll
,
832 DeviceFamily::AtiAll
, nsIGfxInfo::FEATURE_X11_EGL
,
833 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_COMPARISON_IGNORED
,
834 V(0, 0, 0, 0), "FEATURE_FAILURE_X11_EGL_NO_LINUX_ATI", "");
836 ////////////////////////////////////
838 APPEND_TO_DRIVER_BLOCKLIST_EXT(
839 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
840 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::NonMesaAll
,
841 DeviceFamily::NvidiaAll
, nsIGfxInfo::FEATURE_DMABUF
,
842 nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION
, DRIVER_LESS_THAN
,
843 V(495, 44, 0, 0), "FEATURE_FAILURE_NO_GBM", "495.44.0");
845 ////////////////////////////////////
846 // FEATURE_WEBRENDER_PARTIAL_PRESENT
847 APPEND_TO_DRIVER_BLOCKLIST_EXT(
848 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
849 DesktopEnvironment::All
, WindowProtocol::X11
, DriverVendor::NonMesaAll
,
850 DeviceFamily::NvidiaAll
, nsIGfxInfo::FEATURE_WEBRENDER_PARTIAL_PRESENT
,
851 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_COMPARISON_IGNORED
,
852 V(0, 0, 0, 0), "FEATURE_ROLLOUT_WR_PARTIAL_PRESENT_NVIDIA_BINARY", "");
854 ////////////////////////////////////
856 APPEND_TO_DRIVER_BLOCKLIST_EXT(
857 OperatingSystem::Linux
, ScreenSizeStatus::All
, BatteryStatus::All
,
858 DesktopEnvironment::All
, WindowProtocol::All
, DriverVendor::MesaNouveau
,
859 DeviceFamily::All
, nsIGfxInfo::FEATURE_THREADSAFE_GL
,
860 nsIGfxInfo::FEATURE_BLOCKED_DEVICE
, DRIVER_COMPARISON_IGNORED
,
861 V(0, 0, 0, 0), "FEATURE_FAILURE_THREADSAFE_GL", "");
866 bool GfxInfo::DoesWindowProtocolMatch(const nsAString
& aBlocklistWindowProtocol
,
867 const nsAString
& aWindowProtocol
) {
869 aBlocklistWindowProtocol
.Equals(
870 GfxDriverInfo::GetWindowProtocol(WindowProtocol::WaylandAll
),
871 nsCaseInsensitiveStringComparator
)) {
875 aBlocklistWindowProtocol
.Equals(
876 GfxDriverInfo::GetWindowProtocol(WindowProtocol::X11All
),
877 nsCaseInsensitiveStringComparator
)) {
880 return GfxInfoBase::DoesWindowProtocolMatch(aBlocklistWindowProtocol
,
884 bool GfxInfo::DoesDriverVendorMatch(const nsAString
& aBlocklistVendor
,
885 const nsAString
& aDriverVendor
) {
887 if (aBlocklistVendor
.Equals(
888 GfxDriverInfo::GetDriverVendor(DriverVendor::MesaAll
),
889 nsCaseInsensitiveStringComparator
)) {
892 if (mIsAccelerated
&&
893 aBlocklistVendor
.Equals(
894 GfxDriverInfo::GetDriverVendor(DriverVendor::HardwareMesaAll
),
895 nsCaseInsensitiveStringComparator
)) {
898 if (!mIsAccelerated
&&
899 aBlocklistVendor
.Equals(
900 GfxDriverInfo::GetDriverVendor(DriverVendor::SoftwareMesaAll
),
901 nsCaseInsensitiveStringComparator
)) {
905 if (!mIsMesa
&& aBlocklistVendor
.Equals(
906 GfxDriverInfo::GetDriverVendor(DriverVendor::NonMesaAll
),
907 nsCaseInsensitiveStringComparator
)) {
910 return GfxInfoBase::DoesDriverVendorMatch(aBlocklistVendor
, aDriverVendor
);
913 nsresult
GfxInfo::GetFeatureStatusImpl(
914 int32_t aFeature
, int32_t* aStatus
, nsAString
& aSuggestedDriverVersion
,
915 const nsTArray
<GfxDriverInfo
>& aDriverInfo
, nsACString
& aFailureId
,
916 OperatingSystem
* aOS
/* = nullptr */)
919 NS_ENSURE_ARG_POINTER(aStatus
);
920 *aStatus
= nsIGfxInfo::FEATURE_STATUS_UNKNOWN
;
921 aSuggestedDriverVersion
.SetIsVoid(true);
922 OperatingSystem os
= OperatingSystem::Linux
;
925 if (sShutdownOccurred
) {
932 // If glxtest failed, block all features by default.
933 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
934 aFailureId
= "FEATURE_FAILURE_GLXTEST_FAILED";
938 if (mGLMajorVersion
== 1) {
939 // We're on OpenGL 1. In most cases that indicates really old hardware.
940 // We better block them, rather than rely on them to fail gracefully,
941 // because they don't! see bug 696636
942 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
943 aFailureId
= "FEATURE_FAILURE_OPENGL_1";
947 // Blocklist software GL implementations from using layers acceleration.
948 // On the test infrastructure, we'll force-enable layers acceleration.
949 if (aFeature
== nsIGfxInfo::FEATURE_OPENGL_LAYERS
&& !mIsAccelerated
&&
950 !PR_GetEnv("MOZ_LAYERS_ALLOW_SOFTWARE_GL")) {
951 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
952 aFailureId
= "FEATURE_FAILURE_SOFTWARE_GL";
956 if (aFeature
== nsIGfxInfo::FEATURE_WEBRENDER
) {
957 // Don't try Webrender on devices where we are guaranteed to fail.
958 if (mGLMajorVersion
< 3) {
959 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
960 aFailureId
= "FEATURE_FAILURE_OPENGL_LESS_THAN_3";
964 // Bug 1710400: Disable Webrender on the deprecated Intel DDX driver
965 for (const nsCString
& driver
: mDdxDrivers
) {
966 if (strcasestr(driver
.get(), "Intel")) {
967 *aStatus
= nsIGfxInfo::FEATURE_BLOCKED_DEVICE
;
968 aFailureId
= "FEATURE_FAILURE_DDX_INTEL";
974 return GfxInfoBase::GetFeatureStatusImpl(
975 aFeature
, aStatus
, aSuggestedDriverVersion
, aDriverInfo
, aFailureId
, &os
);
979 GfxInfo::GetD2DEnabled(bool* aEnabled
) { return NS_ERROR_FAILURE
; }
982 GfxInfo::GetDWriteEnabled(bool* aEnabled
) { return NS_ERROR_FAILURE
; }
985 GfxInfo::GetDWriteVersion(nsAString
& aDwriteVersion
) {
986 return NS_ERROR_FAILURE
;
989 NS_IMETHODIMP
GfxInfo::GetHasBattery(bool* aHasBattery
) {
990 return NS_ERROR_NOT_IMPLEMENTED
;
994 GfxInfo::GetEmbeddedInFirefoxReality(bool* aEmbeddedInFirefoxReality
) {
995 return NS_ERROR_FAILURE
;
999 GfxInfo::GetCleartypeParameters(nsAString
& aCleartypeParams
) {
1000 return NS_ERROR_FAILURE
;
1004 GfxInfo::GetWindowProtocol(nsAString
& aWindowProtocol
) {
1007 aWindowProtocol
= GfxDriverInfo::GetWindowProtocol(WindowProtocol::Wayland
);
1008 } else if (mIsXWayland
) {
1010 GfxDriverInfo::GetWindowProtocol(WindowProtocol::XWayland
);
1012 aWindowProtocol
= GfxDriverInfo::GetWindowProtocol(WindowProtocol::X11
);
1014 Telemetry::ScalarSet(Telemetry::ScalarID::GFX_LINUX_WINDOW_PROTOCOL
,
1020 GfxInfo::GetDesktopEnvironment(nsAString
& aDesktopEnvironment
) {
1022 AppendASCIItoUTF16(mDesktopEnvironment
, aDesktopEnvironment
);
1027 GfxInfo::GetTestType(nsAString
& aTestType
) {
1029 AppendASCIItoUTF16(mTestType
, aTestType
);
1034 GfxInfo::GetAdapterDescription(nsAString
& aAdapterDescription
) {
1036 AppendASCIItoUTF16(mAdapterDescription
, aAdapterDescription
);
1041 GfxInfo::GetAdapterDescription2(nsAString
& aAdapterDescription
) {
1042 return NS_ERROR_FAILURE
;
1046 GfxInfo::GetAdapterRAM(uint32_t* aAdapterRAM
) {
1048 *aAdapterRAM
= mAdapterRAM
;
1053 GfxInfo::GetAdapterRAM2(uint32_t* aAdapterRAM
) { return NS_ERROR_FAILURE
; }
1056 GfxInfo::GetAdapterDriver(nsAString
& aAdapterDriver
) {
1057 aAdapterDriver
.Truncate();
1062 GfxInfo::GetAdapterDriver2(nsAString
& aAdapterDriver
) {
1063 return NS_ERROR_FAILURE
;
1067 GfxInfo::GetAdapterDriverVendor(nsAString
& aAdapterDriverVendor
) {
1069 CopyASCIItoUTF16(mDriverVendor
, aAdapterDriverVendor
);
1074 GfxInfo::GetAdapterDriverVendor2(nsAString
& aAdapterDriverVendor
) {
1075 return NS_ERROR_FAILURE
;
1079 GfxInfo::GetAdapterDriverVersion(nsAString
& aAdapterDriverVersion
) {
1081 CopyASCIItoUTF16(mDriverVersion
, aAdapterDriverVersion
);
1086 GfxInfo::GetAdapterDriverVersion2(nsAString
& aAdapterDriverVersion
) {
1087 return NS_ERROR_FAILURE
;
1091 GfxInfo::GetAdapterDriverDate(nsAString
& aAdapterDriverDate
) {
1092 aAdapterDriverDate
.Truncate();
1097 GfxInfo::GetAdapterDriverDate2(nsAString
& aAdapterDriverDate
) {
1098 return NS_ERROR_FAILURE
;
1102 GfxInfo::GetAdapterVendorID(nsAString
& aAdapterVendorID
) {
1104 CopyUTF8toUTF16(mVendorId
, aAdapterVendorID
);
1109 GfxInfo::GetAdapterVendorID2(nsAString
& aAdapterVendorID
) {
1111 CopyUTF8toUTF16(mSecondaryVendorId
, aAdapterVendorID
);
1116 GfxInfo::GetAdapterDeviceID(nsAString
& aAdapterDeviceID
) {
1118 CopyUTF8toUTF16(mDeviceId
, aAdapterDeviceID
);
1123 GfxInfo::GetAdapterDeviceID2(nsAString
& aAdapterDeviceID
) {
1125 CopyUTF8toUTF16(mSecondaryDeviceId
, aAdapterDeviceID
);
1130 GfxInfo::GetAdapterSubsysID(nsAString
& aAdapterSubsysID
) {
1131 return NS_ERROR_FAILURE
;
1135 GfxInfo::GetAdapterSubsysID2(nsAString
& aAdapterSubsysID
) {
1136 return NS_ERROR_FAILURE
;
1140 GfxInfo::GetDisplayInfo(nsTArray
<nsString
>& aDisplayInfo
) {
1143 for (auto screenInfo
: mScreenInfo
) {
1144 nsString infoString
;
1145 infoString
.AppendPrintf("%dx%d %s", screenInfo
.mWidth
, screenInfo
.mHeight
,
1146 screenInfo
.mIsDefault
? "default" : "");
1147 aDisplayInfo
.AppendElement(infoString
);
1150 return aDisplayInfo
.IsEmpty() ? NS_ERROR_FAILURE
: NS_OK
;
1154 GfxInfo::GetDisplayWidth(nsTArray
<uint32_t>& aDisplayWidth
) {
1155 for (auto screenInfo
: mScreenInfo
) {
1156 aDisplayWidth
.AppendElement((uint32_t)screenInfo
.mWidth
);
1162 GfxInfo::GetDisplayHeight(nsTArray
<uint32_t>& aDisplayHeight
) {
1163 for (auto screenInfo
: mScreenInfo
) {
1164 aDisplayHeight
.AppendElement((uint32_t)screenInfo
.mHeight
);
1170 GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active
) {
1171 // This is never the case, as the active GPU should be the primary GPU.
1172 *aIsGPU2Active
= false;
1177 GfxInfo::GetDrmRenderDevice(nsACString
& aDrmRenderDevice
) {
1179 aDrmRenderDevice
.Assign(mDrmRenderDevice
);
1185 // Implement nsIGfxInfoDebug
1186 // We don't support spoofing anything on Linux
1188 NS_IMETHODIMP
GfxInfo::SpoofVendorID(const nsAString
& aVendorID
) {
1190 CopyUTF16toUTF8(aVendorID
, mVendorId
);
1191 mIsAccelerated
= true;
1195 NS_IMETHODIMP
GfxInfo::SpoofDeviceID(const nsAString
& aDeviceID
) {
1197 CopyUTF16toUTF8(aDeviceID
, mDeviceId
);
1201 NS_IMETHODIMP
GfxInfo::SpoofDriverVersion(const nsAString
& aDriverVersion
) {
1203 CopyUTF16toUTF8(aDriverVersion
, mDriverVersion
);
1207 NS_IMETHODIMP
GfxInfo::SpoofOSVersion(uint32_t aVersion
) {
1208 // We don't support OS versioning on Linux. There's just "Linux".
1212 NS_IMETHODIMP
GfxInfo::FireTestProcess() {
1213 // If the pid is zero, then we have never run the test process to query for
1214 // driver information. This would normally be run on startup, but we need to
1215 // manually invoke it for XPC shell tests.
1216 if (glxtest_pid
== 0) {
1217 fire_glxtest_process();
1224 } // namespace mozilla::widget