File indexing completed on 2024-12-15 03:45:04

0001 /*
0002     SPDX-FileCopyrightText: 2017 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: MIT
0005 */
0006 
0007 #ifndef KUSERFEEDBACK_OPENGLINFOSOURCE_P_H
0008 #define KUSERFEEDBACK_OPENGLINFOSOURCE_P_H
0009 
0010 #include <QVariantMap>
0011 
0012 namespace KUserFeedback {
0013 
0014 // Internal functions made accessible for unit tests
0015 class OpenGLInfoSourcePrivate
0016 {
0017 public:
0018     static inline void parseGLVersion(const char *version, QVariantMap &m)
0019     {
0020         auto vendorVersion = QString::fromLocal8Bit(version);
0021         const auto idx = vendorVersion.indexOf(QLatin1Char(' '));
0022 
0023         QString glVersion;
0024         if (idx > 0) {
0025             glVersion = vendorVersion.left(idx);
0026             vendorVersion = vendorVersion.mid(idx + 1);
0027             if (!vendorVersion.isEmpty())
0028                 m.insert(QStringLiteral("vendorVersion"), normalizeVendorVersionString(vendorVersion));
0029         } else {
0030             glVersion = vendorVersion;
0031         }
0032         // in case glGetIntegerv(GL_MAJOR_VERSION) failed...
0033         if (!m.contains(QLatin1String("version")) && !glVersion.isEmpty())
0034             m.insert(QStringLiteral("version"), glVersion);
0035     }
0036 
0037     static inline void parseGLESVersion(const char *version, QVariantMap &m)
0038     {
0039         auto rawVersion = QString::fromLocal8Bit(version);
0040         if (!rawVersion.startsWith(QLatin1String("OpenGL ES "))) {
0041             m.insert(QStringLiteral("version"), QStringLiteral("unknown"));
0042             m.insert(QStringLiteral("vendorVersion"), rawVersion);
0043         } else {
0044             rawVersion = rawVersion.mid(10);
0045             const auto idx = rawVersion.indexOf(QLatin1Char(' '));
0046             if (idx > 0) {
0047                 const auto vendorVersion = rawVersion.mid(idx + 1);
0048                 if (!vendorVersion.isEmpty())
0049                     m.insert(QStringLiteral("vendorVersion"), normalizeVendorVersionString(vendorVersion));
0050                 m.insert(QStringLiteral("version"), rawVersion.left(idx));
0051             } else {
0052                 m.insert(QStringLiteral("version"), rawVersion);
0053             }
0054         }
0055     }
0056 
0057     static inline void parseGLSLVersion(const char *version, QVariantMap &m)
0058     {
0059         auto v = QString::fromLocal8Bit(version);
0060         const auto idx = v.indexOf(QLatin1Char(' '));
0061         if (idx > 0) {
0062             const auto glslVersion = v.left(idx);
0063             if (!glslVersion.isEmpty())
0064                 m.insert(QStringLiteral("glslVersion"), glslVersion);
0065             else
0066                 m.insert(QStringLiteral("glslVersion"), v);
0067         } else {
0068             m.insert(QStringLiteral("glslVersion"), v);
0069         }
0070     }
0071 
0072     static inline void parseESGLSLVersion(const char *version, QVariantMap &m)
0073     {
0074         auto v = QString::fromLocal8Bit(version);
0075         if (!v.startsWith(QLatin1String("OpenGL ES GLSL ES "))) {
0076             m.insert(QStringLiteral("glslVersion"), v);
0077         } else {
0078             v = v.mid(18);
0079             const auto idx = v.indexOf(QLatin1Char(' '));
0080             if (idx > 0) {
0081                 const auto glslVersion = v.left(idx);
0082                 if (!glslVersion.isEmpty())
0083                     m.insert(QStringLiteral("glslVersion"), glslVersion);
0084                 else
0085                     m.insert(QStringLiteral("glslVersion"), v);
0086             } else {
0087                 m.insert(QStringLiteral("glslVersion"), v);
0088             }
0089         }
0090     }
0091 
0092     static inline QString normalizeVendor(const char *vendor)
0093     {
0094         const auto v = QString::fromLocal8Bit(vendor);
0095         if (v.startsWith(QLatin1String("Intel ")))
0096             return QStringLiteral("Intel");
0097         return v;
0098     }
0099 
0100     static inline QString normalizeRenderer(const char *renderer)
0101     {
0102         auto r = QString::fromLocal8Bit(renderer);
0103         // remove trademark indicators
0104         r.remove(QLatin1String("(R)"), Qt::CaseInsensitive);
0105         r.remove(QLatin1String("(TM)"), Qt::CaseInsensitive);
0106 
0107         // remove vendor prefixes, we already have that in the vendor field
0108         if (r.startsWith(QLatin1String("Mesa DRI ")))
0109             r = r.mid(9);
0110         if (r.startsWith(QLatin1String("Mesa ")))
0111             r = r.mid(5);
0112         if (r.startsWith(QLatin1String("Intel ")))
0113             r = r.mid(6);
0114         if (r.startsWith(QLatin1String("NVIDIA ")))
0115             r = r.mid(7);
0116 
0117         // remove excessive details that could enable fingerprinting
0118         if (r.endsWith(QLatin1Char(')'))) {
0119             const auto idx = r.indexOf(QLatin1String(" ("));
0120             if (idx > 0) {
0121                 r = r.left(idx);
0122             }
0123         }
0124 
0125         // strip macOS adding " OpenGL Engine" at the end
0126         if (r.endsWith(QLatin1String(" OpenGL Engine")))
0127             r = r.left(r.size() - 14);
0128 
0129         return r.simplified();
0130     }
0131 
0132 private:
0133     static inline QString normalizeVendorVersionString(const QString &s)
0134     {
0135         if (s.startsWith(QLatin1Char('(')) && s.endsWith(QLatin1Char(')')))
0136             return s.mid(1, s.size() - 2);
0137         if (s.startsWith(QLatin1String("- ")))
0138             return s.mid(2);
0139         if (s.startsWith(QLatin1Char('('))) {
0140             const auto idx = s.indexOf(QLatin1String(") "));
0141             if (idx > 0)
0142                 return s.mid(idx + 2);
0143         }
0144         return s;
0145     }
0146 };
0147 
0148 }
0149 
0150 #endif // KUSERFEEDBACK_OPENGLINFOSOURCE_P_H