diff options
Diffstat (limited to 'vcl/source/opengl/x11/X11DeviceInfo.cxx')
-rw-r--r-- | vcl/source/opengl/x11/X11DeviceInfo.cxx | 363 |
1 files changed, 0 insertions, 363 deletions
diff --git a/vcl/source/opengl/x11/X11DeviceInfo.cxx b/vcl/source/opengl/x11/X11DeviceInfo.cxx deleted file mode 100644 index f7c979ef77e6..000000000000 --- a/vcl/source/opengl/x11/X11DeviceInfo.cxx +++ /dev/null @@ -1,363 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include <opengl/x11/X11DeviceInfo.hxx> -#include <opengl/x11/glxtest.hxx> - -#include <config_features.h> - -#include <rtl/ustring.hxx> -#include <sal/log.hxx> - -#include <unistd.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <errno.h> -#include <sys/utsname.h> - -#include <desktop/crashreport.hxx> - -namespace glx { - -static int glxtest_pipe = 0; - -static pid_t glxtest_pid = 0; - -} - -pid_t* getGlxPid() -{ - return &glx::glxtest_pid; -} - -int* getGlxPipe() -{ - return &glx::glxtest_pipe; -} - -namespace { - -const char* -strspnp_wrapper(const char* aDelims, const char* aStr) -{ - const char* d; - do - { - for (d = aDelims; *d != '\0'; ++d) - { - if (*aStr == *d) - { - ++aStr; - break; - } - } - } while (*d); - - return aStr; -} - -char* strtok_wrapper(const char* aDelims, char** aStr) -{ - if (!*aStr) - { - return nullptr; - } - - char* ret = const_cast<char*>(strspnp_wrapper(aDelims, *aStr)); - - if (!*ret) - { - *aStr = ret; - return nullptr; - } - - char* i = ret; - do - { - for (const char* d = aDelims; *d != '\0'; ++d) - { - if (*i == *d) { - *i = '\0'; - *aStr = ++i; - return ret; - } - } - ++i; - } while (*i); - - *aStr = nullptr; - return ret; -} - -uint64_t version(uint32_t major, uint32_t minor, uint32_t revision = 0) -{ - return (uint64_t(major) << 32) + (uint64_t(minor) << 16) + uint64_t(revision); -} - -} - -X11OpenGLDeviceInfo::X11OpenGLDeviceInfo(): - mbIsMesa(false), - mbIsNVIDIA(false), - mbIsFGLRX(false), - mbIsNouveau(false), - mbIsIntel(false), - mbIsOldSwrast(false), - mbIsLlvmpipe(false), - mnGLMajorVersion(0), - mnMajorVersion(0), - mnMinorVersion(0), - mnRevisionVersion(0) -{ - GetData(); -} - -void X11OpenGLDeviceInfo::GetData() -{ - if (!glx::glxtest_pipe) - return; - - // to understand this function, see bug moz#639842. We retrieve the OpenGL driver information in a - // separate process to protect against bad drivers. - enum { buf_size = 1024 }; - char buf[buf_size]; - ssize_t bytesread = read(glx::glxtest_pipe, - &buf, - buf_size-1); // -1 because we'll append a zero - close(glx::glxtest_pipe); - glx::glxtest_pipe = 0; - - // bytesread < 0 would mean that the above read() call failed. - // This should never happen. If it did, the outcome would be to denylist anyway. - if (bytesread < 0) - bytesread = 0; - - // let buf be a zero-terminated string - buf[bytesread] = 0; - - // Wait for the glxtest process to finish. This serves 2 purposes: - // * avoid having a zombie glxtest process laying around - // * get the glxtest process status info. - int glxtest_status = 0; - bool wait_for_glxtest_process = true; - bool waiting_for_glxtest_process_failed = false; - int waitpid_errno = 0; - while(wait_for_glxtest_process) - { - wait_for_glxtest_process = false; - if (waitpid(glx::glxtest_pid, &glxtest_status, 0) == -1) - { - waitpid_errno = errno; - if (waitpid_errno == EINTR) - { - wait_for_glxtest_process = true; - } - else - { - // Bug moz#718629 - // ECHILD happens when the glxtest process got reaped got reaped after a PR_CreateProcess - // as per bug moz#227246. This shouldn't matter, as we still seem to get the data - // from the pipe, and if we didn't, the outcome would be to denylist anyway. - waiting_for_glxtest_process_failed = (waitpid_errno != ECHILD); - } - } - } - - bool exited_with_error_code = !waiting_for_glxtest_process_failed && - WIFEXITED(glxtest_status) && - WEXITSTATUS(glxtest_status) != EXIT_SUCCESS; - bool received_signal = !waiting_for_glxtest_process_failed && - WIFSIGNALED(glxtest_status); - - bool error = waiting_for_glxtest_process_failed || exited_with_error_code || received_signal; - - OString textureFromPixmap; - OString *stringToFill = nullptr; - char *bufptr = buf; - if (!error) - { - while(true) - { - char *line = strtok_wrapper("\n", &bufptr); - if (!line) - break; - if (stringToFill) { - *stringToFill = OString(line); - stringToFill = nullptr; - } - else if(!strcmp(line, "VENDOR")) - stringToFill = &maVendor; - else if(!strcmp(line, "RENDERER")) - stringToFill = &maRenderer; - else if(!strcmp(line, "VERSION")) - stringToFill = &maVersion; - else if(!strcmp(line, "TFP")) - stringToFill = &textureFromPixmap; - } - } - - // only useful for Linux kernel version check for FGLRX driver. - // assumes X client == X server, which is sad. - struct utsname unameobj; - if (!uname(&unameobj)) - { - maOS = OString(unameobj.sysname); - maOSRelease = OString(unameobj.release); - } - - // determine the major OpenGL version. That's the first integer in the version string. - mnGLMajorVersion = strtol(maVersion.getStr(), nullptr, 10); - - // determine driver type (vendor) and where in the version string - // the actual driver version numbers should be expected to be found (whereToReadVersionNumbers) - const char *whereToReadVersionNumbers = nullptr; - const char *Mesa_in_version_string = strstr(maVersion.getStr(), "Mesa"); - if (Mesa_in_version_string) - { - mbIsMesa = true; - // with Mesa, the version string contains "Mesa major.minor" and that's all the version information we get: - // there is no actual driver version info. - whereToReadVersionNumbers = Mesa_in_version_string + strlen("Mesa"); - if (strcasestr(maVendor.getStr(), "nouveau")) - mbIsNouveau = true; - if (strcasestr(maRenderer.getStr(), "intel")) // yes, intel is in the renderer string - mbIsIntel = true; - if (strcasestr(maRenderer.getStr(), "llvmpipe")) - mbIsLlvmpipe = true; - if (strcasestr(maRenderer.getStr(), "software rasterizer")) - mbIsOldSwrast = true; - } - else if (strstr(maVendor.getStr(), "NVIDIA Corporation")) - { - mbIsNVIDIA = true; - // with the NVIDIA driver, the version string contains "NVIDIA major.minor" - // note that here the vendor and version strings behave differently, that's why we don't put this above - // alongside Mesa_in_version_string. - const char *NVIDIA_in_version_string = strstr(maVersion.getStr(), "NVIDIA"); - if (NVIDIA_in_version_string) - whereToReadVersionNumbers = NVIDIA_in_version_string + strlen("NVIDIA"); - } - else if (strstr(maVendor.getStr(), "ATI Technologies Inc")) - { - mbIsFGLRX = true; - // with the FGLRX driver, the version string only gives an OpenGL version: so let's return that. - // that can at least give a rough idea of how old the driver is. - whereToReadVersionNumbers = maVersion.getStr(); - } - - // read major.minor version numbers of the driver (not to be confused with the OpenGL version) - if (!whereToReadVersionNumbers) - return; - - // copy into writable buffer, for tokenization - strncpy(buf, whereToReadVersionNumbers, buf_size-1); - buf[buf_size-1] = 0; - bufptr = buf; - - // now try to read major.minor version numbers. In case of failure, gracefully exit: these numbers have - // been initialized as 0 anyways - char *token = strtok_wrapper(".", &bufptr); - if (token) - { - mnMajorVersion = strtol(token, nullptr, 10); - token = strtok_wrapper(".", &bufptr); - if (token) - { - mnMinorVersion = strtol(token, nullptr, 10); - token = strtok_wrapper(".", &bufptr); - if (token) - mnRevisionVersion = strtol(token, nullptr, 10); - } - } -} - -bool X11OpenGLDeviceInfo::isDeviceBlocked() -{ - // don't even try to use OpenGL 1.x - if (mnGLMajorVersion == 1) - return true; - - CrashReporter::addKeyValue("AdapterVendorId", OStringToOUString(maVendor, RTL_TEXTENCODING_UTF8), CrashReporter::AddItem); - CrashReporter::addKeyValue("AdapterDeviceId", OStringToOUString(maRenderer, RTL_TEXTENCODING_UTF8), CrashReporter::Write); - - SAL_INFO("vcl.opengl", "Vendor: " << maVendor); - SAL_INFO("vcl.opengl", "Renderer: " << maRenderer); - SAL_INFO("vcl.opengl", "Version: " << maVersion); - SAL_INFO("vcl.opengl", "OS: " << maOS); - SAL_INFO("vcl.opengl", "OSRelease: " << maOSRelease); - - if (mbIsMesa) - { - if (mbIsNouveau && version(mnMajorVersion, mnMinorVersion) < version(8,0)) - { - SAL_WARN("vcl.opengl", "blocked driver version: old nouveau driver (requires mesa 8.0+)"); - return true; - } - else if (version(mnMajorVersion, mnMinorVersion, mnRevisionVersion) < version(7,10,3)) - { - SAL_WARN("vcl.opengl", "blocked driver version: requires at least mesa 7.10.3"); - return true; - } - else if (mbIsIntel && version(mnMajorVersion, mnMinorVersion, mnRevisionVersion) == version(9,0,2)) - { - SAL_WARN("vcl.opengl", "blocked driver version: my broken intel driver Mesa 9.0.2"); - return true; - } - else if (mbIsOldSwrast) - { - SAL_WARN("vcl.opengl", "blocked driver version: software rasterizer"); - return true; - } - else if (mbIsLlvmpipe && version(mnMajorVersion, mnMinorVersion) < version(9, 1)) - { - // bug moz#791905, Mesa bug 57733, fixed in Mesa 9.1 according to - // https://bugs.freedesktop.org/show_bug.cgi?id=57733#c3 - SAL_WARN("vcl.opengl", "blocked driver version: fdo#57733"); - return true; - } - } - else if (mbIsNVIDIA) - { - if (version(mnMajorVersion, mnMinorVersion, mnRevisionVersion) < version(257,21)) - { - SAL_WARN("vcl.opengl", "blocked driver version: nvidia requires at least 257.21"); - return true; - } - } - else if (mbIsFGLRX) - { - // FGLRX does not report a driver version number, so we have the OpenGL version instead. - // by requiring OpenGL 3, we effectively require recent drivers. - if (version(mnMajorVersion, mnMinorVersion, mnRevisionVersion) < version(3, 0)) - { - SAL_WARN("vcl.opengl", "blocked driver version: require at least OpenGL 3 for fglrx"); - return true; - } - // Bug moz#724640: FGLRX + Linux 2.6.32 is a crashy combo - bool unknownOS = maOS.isEmpty() || maOSRelease.isEmpty(); - bool badOS = maOS.indexOf("Linux") != -1 && - maOSRelease.indexOf("2.6.32") != -1; - if (unknownOS || badOS) - { - SAL_WARN("vcl.opengl", "blocked OS version with fglrx"); - return true; - } - } - else - { - // like on windows, let's block unknown vendors. Think of virtual machines. - // Also, this case is hit whenever the GLXtest probe failed to get driver info or crashed. - SAL_WARN("vcl.opengl", "unknown vendor => blocked"); - return true; - } - - return false; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |