Bug 1690340 - Part 5: Remove the menu separators from the developer tools menu. r...
[gecko.git] / widget / GfxInfoX11.cpp
blobc0c8bd40c347818787bcbc0d88937b99e5358f2b
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: sw=2 ts=8 et :
3 */
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/. */
8 #include <unistd.h>
9 #include <sys/types.h>
10 #include <sys/wait.h>
11 #include <errno.h>
12 #include <sys/utsname.h>
13 #include <string>
14 #include <cctype>
15 #include "nsCRTGlue.h"
16 #include "nsExceptionHandler.h"
17 #include "nsUnicharUtils.h"
18 #include "prenv.h"
19 #include "nsPrintfCString.h"
20 #include "nsWhitespaceTokenizer.h"
21 #include "mozilla/Telemetry.h"
22 #include "mozilla/gfx/Logging.h"
24 #include "GfxInfoX11.h"
26 #include <gdk/gdkx.h>
27 #ifdef MOZ_WAYLAND
28 # include "mozilla/widget/nsWaylandDisplay.h"
29 # include "mozilla/widget/DMABufLibWrapper.h"
30 #endif
32 #define EXIT_STATUS_BUFFER_TOO_SMALL 2
33 #ifdef DEBUG
34 bool fire_glxtest_process();
35 #endif
37 namespace mozilla::widget {
39 #ifdef DEBUG
40 NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug)
41 #endif
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() {
48 mGLMajorVersion = 0;
49 mGLMinorVersion = 0;
50 mHasTextureFromPixmap = false;
51 mIsMesa = false;
52 mIsAccelerated = true;
53 mIsWayland = false;
54 mIsWaylandDRM = false;
55 mIsXWayland = false;
56 mHasMultipleGPUs = false;
57 mGlxTestError = false;
58 return GfxInfoBase::Init();
61 void GfxInfo::AddCrashReportAnnotations() {
62 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
63 mVendorId);
64 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
65 mDeviceId);
66 CrashReporter::AnnotateCrashReport(
67 CrashReporter::Annotation::AdapterDriverVendor, mDriverVendor);
68 CrashReporter::AnnotateCrashReport(
69 CrashReporter::Annotation::AdapterDriverVersion, mDriverVersion);
70 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::IsWayland,
71 mIsWayland);
72 CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::IsWaylandDRM,
73 mIsWaylandDRM);
74 CrashReporter::AnnotateCrashReport(
75 CrashReporter::Annotation::DesktopEnvironment, mDesktopEnvironment);
77 if (mHasMultipleGPUs) {
78 nsAutoCString note;
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 };
100 char buf[buf_size];
101 ssize_t bytesread = read(glxtest_pipe, &buf,
102 buf_size - 1); // -1 because we'll append a zero
103 close(glxtest_pipe);
104 glxtest_pipe = -1;
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
108 // anyway.
109 if (bytesread < 0) {
110 bytesread = 0;
111 } else if (bytesread == buf_size - 1) {
112 gfxCriticalNote << "glxtest: read from pipe exceeded buffer size";
115 // let buf be a zero-terminated string
116 buf[bytesread] = 0;
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;
131 } else {
132 // Bug 718629
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 ||
153 received_signal;
154 bool errorLog = false;
156 nsCString glVendor;
157 nsCString glRenderer;
158 nsCString glVersion;
159 nsCString textureFromPixmap;
160 nsCString testType;
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.
167 nsCString driDriver;
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;
179 char* bufptr = buf;
180 while (true) {
181 char* line = NS_strtok("\n", &bufptr);
182 if (!line) break;
183 if (stringToFill) {
184 stringToFill->Assign(line);
185 stringToFill = nullptr;
186 } else if (logString) {
187 gfxCriticalNote << "glxtest: " << line;
188 logString = false;
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")) {
218 logString = true;
219 } else if (!strcmp(line, "ERROR")) {
220 logString = true;
221 errorLog = true;
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) >=
258 2) {
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.
265 mDriverVersion =
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
279 // GL_VENDOR string.
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.
284 if (mIsMesa) {
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")) {
290 CopyUTF16toUTF8(
291 GfxDriverInfo::GetDriverVendor(DriverVendor::MesaLLVMPipe),
292 mDriverVendor);
293 mIsAccelerated = false;
294 } else if (strcasestr(glRenderer.get(), "softpipe")) {
295 CopyUTF16toUTF8(
296 GfxDriverInfo::GetDriverVendor(DriverVendor::MesaSoftPipe),
297 mDriverVendor);
298 mIsAccelerated = false;
299 } else if (strcasestr(glRenderer.get(), "software rasterizer") ||
300 !mIsAccelerated) {
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),
304 mDriverVendor);
305 mIsAccelerated = false;
306 } else if (!driDriver.IsEmpty()) {
307 mDriverVendor = nsPrintfCString("mesa/%s", driDriver.get());
308 } else {
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),
312 mDriverVendor);
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),
324 mVendorId);
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),
329 mVendorId);
330 mDriverVendor.AssignLiteral("ati/unknown");
331 // TODO: Look into ways to find the device ID on FGLRX.
332 } else {
333 NS_WARNING("Failed to detect GL vendor!");
336 if (!screenInfo.IsEmpty()) {
337 PRInt32 start = 0;
338 PRInt32 loc = screenInfo.Find(";", PR_FALSE, start);
339 while (loc != kNotFound) {
340 int isDefault = 0;
341 nsCString line(screenInfo.get() + start, loc - start);
342 ScreenInfo info;
343 if (sscanf(line.get(), "%ux%u:%u", &info.mWidth, &info.mHeight,
344 &isDefault) == 3) {
345 info.mIsDefault = isDefault != 0;
346 mScreenInfo.AppendElement(info);
349 start = loc + 1;
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),
364 mVendorId);
365 break;
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),
375 mVendorId);
376 break;
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),
387 mVendorId);
388 break;
393 if (mVendorId.IsEmpty()) {
394 if (driDriver.EqualsLiteral("freedreno")) {
395 CopyUTF16toUTF8(GfxDriverInfo::GetDeviceVendor(DeviceVendor::Qualcomm),
396 mVendorId);
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";
407 } else {
408 gfxCriticalNote
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
414 // PCI device list.
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];
420 } else {
421 gfxCriticalNote << "More than 1 GPU from same vendor detected via "
422 "PCI, cannot deduce device";
423 mDeviceId.Truncate();
424 break;
430 // Assuming we know the vendor, we should check for a secondary card.
431 if (!mVendorId.IsEmpty()) {
432 if (pciLen > 2) {
433 gfxCriticalNote
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];
441 break;
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);
463 #ifdef MOZ_WAYLAND
464 mIsWayland = gdk_display_get_default() &&
465 !GDK_IS_X11_DISPLAY(gdk_display_get_default());
466 if (mIsWayland) {
467 mIsWaylandDRM = GetDMABufDevice()->IsDMABufVAAPIEnabled() ||
468 GetDMABufDevice()->IsDMABufWebGLEnabled() ||
469 GetDMABufDevice()->IsDMABufTexturesEnabled();
471 #endif
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
475 // using X11.
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");
489 if (!desktopEnv) {
490 desktopEnv = getenv("DESKTOP_SESSION");
493 if (desktopEnv) {
494 std::string currentDesktop(desktopEnv);
495 for (auto& c : currentDesktop) {
496 c = std::tolower(c);
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.
502 CopyUTF16toUTF8(
503 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Budgie),
504 mDesktopEnvironment);
505 } else if (currentDesktop.find("gnome") != std::string::npos) {
506 CopyUTF16toUTF8(
507 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::GNOME),
508 mDesktopEnvironment);
509 } else if (currentDesktop.find("kde") != std::string::npos) {
510 CopyUTF16toUTF8(
511 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::KDE),
512 mDesktopEnvironment);
513 } else if (currentDesktop.find("xfce") != std::string::npos) {
514 CopyUTF16toUTF8(
515 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::XFCE),
516 mDesktopEnvironment);
517 } else if (currentDesktop.find("cinnamon") != std::string::npos) {
518 CopyUTF16toUTF8(
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) {
527 CopyUTF16toUTF8(
528 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::LXDE),
529 mDesktopEnvironment);
530 } else if (currentDesktop.find("openbox") != std::string::npos) {
531 CopyUTF16toUTF8(
532 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Openbox),
533 mDesktopEnvironment);
534 } else if (currentDesktop.find("i3") != std::string::npos) {
535 CopyUTF16toUTF8(
536 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::i3),
537 mDesktopEnvironment);
538 } else if (currentDesktop.find("mate") != std::string::npos) {
539 CopyUTF16toUTF8(
540 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Mate),
541 mDesktopEnvironment);
542 } else if (currentDesktop.find("unity") != std::string::npos) {
543 CopyUTF16toUTF8(
544 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Unity),
545 mDesktopEnvironment);
546 } else if (currentDesktop.find("pantheon") != std::string::npos) {
547 CopyUTF16toUTF8(
548 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Pantheon),
549 mDesktopEnvironment);
550 } else if (currentDesktop.find("lxqt") != std::string::npos) {
551 CopyUTF16toUTF8(
552 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::LXQT),
553 mDesktopEnvironment);
554 } else if (currentDesktop.find("deepin") != std::string::npos) {
555 CopyUTF16toUTF8(
556 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Deepin),
557 mDesktopEnvironment);
558 } else if (currentDesktop.find("dwm") != std::string::npos) {
559 CopyUTF16toUTF8(
560 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Dwm),
561 mDesktopEnvironment);
565 if (mDesktopEnvironment.IsEmpty()) {
566 if (getenv("GNOME_DESKTOP_SESSION_ID")) {
567 CopyUTF16toUTF8(
568 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::GNOME),
569 mDesktopEnvironment);
570 } else if (getenv("KDE_FULL_SESSION")) {
571 CopyUTF16toUTF8(
572 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::KDE),
573 mDesktopEnvironment);
574 } else if (getenv("MATE_DESKTOP_SESSION_ID")) {
575 CopyUTF16toUTF8(
576 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Mate),
577 mDesktopEnvironment);
578 } else if (getenv("LXQT_SESSION_CONFIG")) {
579 CopyUTF16toUTF8(
580 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::LXQT),
581 mDesktopEnvironment);
582 } else {
583 CopyUTF16toUTF8(
584 GfxDriverInfo::GetDesktopEnvironment(DesktopEnvironment::Unknown),
585 mDesktopEnvironment);
589 if (error || errorLog || mTestType.IsEmpty()) {
590 if (!mAdapterDescription.IsEmpty()) {
591 mAdapterDescription.AppendLiteral(" (See failure log)");
592 } else {
593 mAdapterDescription.AppendLiteral("See failure log");
596 mGlxTestError = true;
599 if (error) {
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)");
609 } else {
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 ////////////////////////////////////
651 // FEATURE_WEBRENDER
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", "");
676 #else
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");
684 #endif
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",
702 "Mesa 17.3.0.0");
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",
731 "Mesa 17.0.0.0");
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",
765 "Mesa 17.0.0.0");
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",
774 "Mesa 18.2.0.0");
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");
791 #endif
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", "");
803 # endif
804 #endif
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", "");
815 return *sDriverInfo;
818 bool GfxInfo::DoesWindowProtocolMatch(const nsAString& aBlocklistWindowProtocol,
819 const nsAString& aWindowProtocol) {
820 if (mIsWayland &&
821 aBlocklistWindowProtocol.Equals(
822 GfxDriverInfo::GetWindowProtocol(WindowProtocol::WaylandAll),
823 nsCaseInsensitiveStringComparator)) {
824 return true;
826 if (!mIsWayland &&
827 aBlocklistWindowProtocol.Equals(
828 GfxDriverInfo::GetWindowProtocol(WindowProtocol::X11All),
829 nsCaseInsensitiveStringComparator)) {
830 return true;
832 return GfxInfoBase::DoesWindowProtocolMatch(aBlocklistWindowProtocol,
833 aWindowProtocol);
836 bool GfxInfo::DoesDriverVendorMatch(const nsAString& aBlocklistVendor,
837 const nsAString& aDriverVendor) {
838 if (mIsMesa) {
839 if (aBlocklistVendor.Equals(
840 GfxDriverInfo::GetDriverVendor(DriverVendor::MesaAll),
841 nsCaseInsensitiveStringComparator)) {
842 return true;
844 if (mIsAccelerated &&
845 aBlocklistVendor.Equals(
846 GfxDriverInfo::GetDriverVendor(DriverVendor::HardwareMesaAll),
847 nsCaseInsensitiveStringComparator)) {
848 return true;
850 if (!mIsAccelerated &&
851 aBlocklistVendor.Equals(
852 GfxDriverInfo::GetDriverVendor(DriverVendor::SoftwareMesaAll),
853 nsCaseInsensitiveStringComparator)) {
854 return true;
857 if (!mIsMesa && aBlocklistVendor.Equals(
858 GfxDriverInfo::GetDriverVendor(DriverVendor::NonMesaAll),
859 nsCaseInsensitiveStringComparator)) {
860 return true;
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;
875 if (aOS) *aOS = os;
877 if (sShutdownOccurred) {
878 return NS_OK;
881 GetData();
883 if (mGlxTestError) {
884 // If glxtest failed, block all features by default.
885 *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE;
886 aFailureId = "FEATURE_FAILURE_GLXTEST_FAILED";
887 return NS_OK;
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";
896 return NS_OK;
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";
905 return NS_OK;
908 return GfxInfoBase::GetFeatureStatusImpl(
909 aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, aFailureId, &os);
912 NS_IMETHODIMP
913 GfxInfo::GetD2DEnabled(bool* aEnabled) { return NS_ERROR_FAILURE; }
915 NS_IMETHODIMP
916 GfxInfo::GetDWriteEnabled(bool* aEnabled) { return NS_ERROR_FAILURE; }
918 NS_IMETHODIMP
919 GfxInfo::GetDWriteVersion(nsAString& aDwriteVersion) {
920 return NS_ERROR_FAILURE;
923 NS_IMETHODIMP GfxInfo::GetHasBattery(bool* aHasBattery) {
924 return NS_ERROR_NOT_IMPLEMENTED;
927 NS_IMETHODIMP
928 GfxInfo::GetEmbeddedInFirefoxReality(bool* aEmbeddedInFirefoxReality) {
929 return NS_ERROR_FAILURE;
932 NS_IMETHODIMP
933 GfxInfo::GetCleartypeParameters(nsAString& aCleartypeParams) {
934 return NS_ERROR_FAILURE;
937 NS_IMETHODIMP
938 GfxInfo::GetWindowProtocol(nsAString& aWindowProtocol) {
939 GetData();
940 if (mIsWayland) {
941 if (mIsWaylandDRM) {
942 aWindowProtocol =
943 GfxDriverInfo::GetWindowProtocol(WindowProtocol::WaylandDRM);
944 } else {
945 aWindowProtocol =
946 GfxDriverInfo::GetWindowProtocol(WindowProtocol::Wayland);
948 } else if (mIsXWayland) {
949 aWindowProtocol =
950 GfxDriverInfo::GetWindowProtocol(WindowProtocol::XWayland);
951 } else {
952 aWindowProtocol = GfxDriverInfo::GetWindowProtocol(WindowProtocol::X11);
954 Telemetry::ScalarSet(Telemetry::ScalarID::GFX_LINUX_WINDOW_PROTOCOL,
955 aWindowProtocol);
956 return NS_OK;
959 NS_IMETHODIMP
960 GfxInfo::GetDesktopEnvironment(nsAString& aDesktopEnvironment) {
961 GetData();
962 AppendASCIItoUTF16(mDesktopEnvironment, aDesktopEnvironment);
963 return NS_OK;
966 NS_IMETHODIMP
967 GfxInfo::GetTestType(nsAString& aTestType) {
968 GetData();
969 AppendASCIItoUTF16(mTestType, aTestType);
970 return NS_OK;
973 NS_IMETHODIMP
974 GfxInfo::GetAdapterDescription(nsAString& aAdapterDescription) {
975 GetData();
976 AppendASCIItoUTF16(mAdapterDescription, aAdapterDescription);
977 return NS_OK;
980 NS_IMETHODIMP
981 GfxInfo::GetAdapterDescription2(nsAString& aAdapterDescription) {
982 return NS_ERROR_FAILURE;
985 NS_IMETHODIMP
986 GfxInfo::GetAdapterRAM(uint32_t* aAdapterRAM) {
987 GetData();
988 *aAdapterRAM = mAdapterRAM;
989 return NS_OK;
992 NS_IMETHODIMP
993 GfxInfo::GetAdapterRAM2(uint32_t* aAdapterRAM) { return NS_ERROR_FAILURE; }
995 NS_IMETHODIMP
996 GfxInfo::GetAdapterDriver(nsAString& aAdapterDriver) {
997 aAdapterDriver.Truncate();
998 return NS_OK;
1001 NS_IMETHODIMP
1002 GfxInfo::GetAdapterDriver2(nsAString& aAdapterDriver) {
1003 return NS_ERROR_FAILURE;
1006 NS_IMETHODIMP
1007 GfxInfo::GetAdapterDriverVendor(nsAString& aAdapterDriverVendor) {
1008 GetData();
1009 CopyASCIItoUTF16(mDriverVendor, aAdapterDriverVendor);
1010 return NS_OK;
1013 NS_IMETHODIMP
1014 GfxInfo::GetAdapterDriverVendor2(nsAString& aAdapterDriverVendor) {
1015 return NS_ERROR_FAILURE;
1018 NS_IMETHODIMP
1019 GfxInfo::GetAdapterDriverVersion(nsAString& aAdapterDriverVersion) {
1020 GetData();
1021 CopyASCIItoUTF16(mDriverVersion, aAdapterDriverVersion);
1022 return NS_OK;
1025 NS_IMETHODIMP
1026 GfxInfo::GetAdapterDriverVersion2(nsAString& aAdapterDriverVersion) {
1027 return NS_ERROR_FAILURE;
1030 NS_IMETHODIMP
1031 GfxInfo::GetAdapterDriverDate(nsAString& aAdapterDriverDate) {
1032 aAdapterDriverDate.Truncate();
1033 return NS_OK;
1036 NS_IMETHODIMP
1037 GfxInfo::GetAdapterDriverDate2(nsAString& aAdapterDriverDate) {
1038 return NS_ERROR_FAILURE;
1041 NS_IMETHODIMP
1042 GfxInfo::GetAdapterVendorID(nsAString& aAdapterVendorID) {
1043 GetData();
1044 CopyUTF8toUTF16(mVendorId, aAdapterVendorID);
1045 return NS_OK;
1048 NS_IMETHODIMP
1049 GfxInfo::GetAdapterVendorID2(nsAString& aAdapterVendorID) {
1050 GetData();
1051 CopyUTF8toUTF16(mSecondaryVendorId, aAdapterVendorID);
1052 return NS_OK;
1055 NS_IMETHODIMP
1056 GfxInfo::GetAdapterDeviceID(nsAString& aAdapterDeviceID) {
1057 GetData();
1058 CopyUTF8toUTF16(mDeviceId, aAdapterDeviceID);
1059 return NS_OK;
1062 NS_IMETHODIMP
1063 GfxInfo::GetAdapterDeviceID2(nsAString& aAdapterDeviceID) {
1064 GetData();
1065 CopyUTF8toUTF16(mSecondaryDeviceId, aAdapterDeviceID);
1066 return NS_OK;
1069 NS_IMETHODIMP
1070 GfxInfo::GetAdapterSubsysID(nsAString& aAdapterSubsysID) {
1071 return NS_ERROR_FAILURE;
1074 NS_IMETHODIMP
1075 GfxInfo::GetAdapterSubsysID2(nsAString& aAdapterSubsysID) {
1076 return NS_ERROR_FAILURE;
1079 NS_IMETHODIMP
1080 GfxInfo::GetDisplayInfo(nsTArray<nsString>& aDisplayInfo) {
1081 GetData();
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;
1093 NS_IMETHODIMP
1094 GfxInfo::GetDisplayWidth(nsTArray<uint32_t>& aDisplayWidth) {
1095 for (auto screenInfo : mScreenInfo) {
1096 aDisplayWidth.AppendElement((uint32_t)screenInfo.mWidth);
1098 return NS_OK;
1101 NS_IMETHODIMP
1102 GfxInfo::GetDisplayHeight(nsTArray<uint32_t>& aDisplayHeight) {
1103 for (auto screenInfo : mScreenInfo) {
1104 aDisplayHeight.AppendElement((uint32_t)screenInfo.mHeight);
1106 return NS_OK;
1109 NS_IMETHODIMP
1110 GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) {
1111 // This is never the case, as the active GPU should be the primary GPU.
1112 *aIsGPU2Active = false;
1113 return NS_OK;
1116 NS_IMETHODIMP
1117 GfxInfo::GetDrmRenderDevice(nsACString& aDrmRenderDevice) {
1118 GetData();
1119 aDrmRenderDevice.Assign(mDrmRenderDevice);
1120 return NS_OK;
1123 #ifdef DEBUG
1125 // Implement nsIGfxInfoDebug
1126 // We don't support spoofing anything on Linux
1128 NS_IMETHODIMP GfxInfo::SpoofVendorID(const nsAString& aVendorID) {
1129 GetData();
1130 CopyUTF16toUTF8(aVendorID, mVendorId);
1131 mIsAccelerated = true;
1132 return NS_OK;
1135 NS_IMETHODIMP GfxInfo::SpoofDeviceID(const nsAString& aDeviceID) {
1136 GetData();
1137 CopyUTF16toUTF8(aDeviceID, mDeviceId);
1138 return NS_OK;
1141 NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString& aDriverVersion) {
1142 GetData();
1143 CopyUTF16toUTF8(aDriverVersion, mDriverVersion);
1144 return NS_OK;
1147 NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion) {
1148 // We don't support OS versioning on Linux. There's just "Linux".
1149 return NS_OK;
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();
1159 return NS_OK;
1162 #endif
1164 } // namespace mozilla::widget