[Libreoffice-commits] core.git: 4 commits - vcl/inc vcl/Library_vcl.mk vcl/opengl vcl/source

Markus Mohrhard markus.mohrhard at googlemail.com
Thu Nov 27 12:19:19 PST 2014


 vcl/Library_vcl.mk                   |    2 
 vcl/inc/opengl/win/WinDeviceInfo.hxx |  186 +++++
 vcl/opengl/win/WinDeviceInfo.cxx     | 1099 +++++++++++++++++++++++++++++++++++
 vcl/source/opengl/OpenGLHelper.cxx   |    5 
 4 files changed, 1292 insertions(+)

New commits:
commit 51171a71169599043bb8cf7255030acf81178b4b
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu Nov 27 21:15:47 2014 +0100

    fix few problems
    
    Change-Id: I4216ec60c7cf07bd92a157f4a86e2560cdbdca93

diff --git a/vcl/opengl/win/WinDeviceInfo.cxx b/vcl/opengl/win/WinDeviceInfo.cxx
index 86614e8..0a11426 100644
--- a/vcl/opengl/win/WinDeviceInfo.cxx
+++ b/vcl/opengl/win/WinDeviceInfo.cxx
@@ -343,6 +343,7 @@ bool ParseDriverVersion(const OUString& aVersion, uint64_t *aNumericVersion)
 
 template<typename T> void appendIntegerWithPadding(OUString& rString, T value, sal_uInt32 nChars)
 {
+    rString += "0x";
     OUString aValue = OUString::number(value, 16);
     sal_Int32 nLength = aValue.getLength();
     sal_uInt32 nPadLength = nChars - nLength;
@@ -572,6 +573,7 @@ WinOpenGLDeviceInfo::WinOpenGLDeviceInfo():
     mbRDP(false)
 {
     GetData();
+    FillBlacklist();
 }
 
 WinOpenGLDeviceInfo::~WinOpenGLDeviceInfo()
@@ -616,36 +618,35 @@ bool WinOpenGLDeviceInfo::FindBlocklistedDeviceInList()
             }
         }
 
-#if defined(XP_WIN) || defined(ANDROID)
         switch (maDriverInfo[i].meComparisonOp) {
-            case DRIVER_LESS_THAN:
+            case wgl::DRIVER_LESS_THAN:
                 match = driverVersion < maDriverInfo[i].mnDriverVersion;
                 break;
-            case DRIVER_LESS_THAN_OR_EQUAL:
+            case wgl::DRIVER_LESS_THAN_OR_EQUAL:
                 match = driverVersion <= maDriverInfo[i].mnDriverVersion;
                 break;
-            case DRIVER_GREATER_THAN:
+            case wgl::DRIVER_GREATER_THAN:
                 match = driverVersion > maDriverInfo[i].mnDriverVersion;
                 break;
-            case DRIVER_GREATER_THAN_OR_EQUAL:
+            case wgl::DRIVER_GREATER_THAN_OR_EQUAL:
                 match = driverVersion >= maDriverInfo[i].mnDriverVersion;
                 break;
-            case DRIVER_EQUAL:
+            case wgl::DRIVER_EQUAL:
                 match = driverVersion == maDriverInfo[i].mnDriverVersion;
                 break;
-            case DRIVER_NOT_EQUAL:
+            case wgl::DRIVER_NOT_EQUAL:
                 match = driverVersion != maDriverInfo[i].mnDriverVersion;
                 break;
-            case DRIVER_BETWEEN_EXCLUSIVE:
+            case wgl::DRIVER_BETWEEN_EXCLUSIVE:
                 match = driverVersion > maDriverInfo[i].mnDriverVersion && driverVersion < maDriverInfo[i].mnDriverVersionMax;
                 break;
-            case DRIVER_BETWEEN_INCLUSIVE:
+            case wgl::DRIVER_BETWEEN_INCLUSIVE:
                 match = driverVersion >= maDriverInfo[i].mnDriverVersion && driverVersion <= maDriverInfo[i].mnDriverVersionMax;
                 break;
-            case DRIVER_BETWEEN_INCLUSIVE_START:
+            case wgl::DRIVER_BETWEEN_INCLUSIVE_START:
                 match = driverVersion >= maDriverInfo[i].mnDriverVersion && driverVersion < maDriverInfo[i].mnDriverVersionMax;
                 break;
-            case DRIVER_COMPARISON_IGNORED:
+            case wgl::DRIVER_COMPARISON_IGNORED:
                 // We don't have a comparison op, so we match everything.
                 match = true;
                 break;
@@ -653,11 +654,6 @@ bool WinOpenGLDeviceInfo::FindBlocklistedDeviceInList()
                 SAL_WARN("vcl.opengl", "Bogus op in GfxDriverInfo");
                 break;
         }
-#else
-        // We don't care what driver version it was. We only check OS version and if
-        // the device matches.
-        match = true;
-#endif
 
         if (match || maDriverInfo[i].mnDriverVersion == wgl::DriverInfo::allDriverVersions) {
             match = true;
commit 5b5d154d0b2de8a3a9d82e0a078cf7e835062d13
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu Nov 27 19:12:31 2014 +0100

    connect all pieces for OpenGL windows blacklist, part 3
    
    Change-Id: Iaaafe7da8e717f7b127ab5806773a5a5d75b82d5

diff --git a/vcl/inc/opengl/win/WinDeviceInfo.hxx b/vcl/inc/opengl/win/WinDeviceInfo.hxx
index 524198b..7e0b80f 100644
--- a/vcl/inc/opengl/win/WinDeviceInfo.hxx
+++ b/vcl/inc/opengl/win/WinDeviceInfo.hxx
@@ -109,7 +109,7 @@ struct DriverInfo
     static const DeviceFamilyVector* GetDeviceFamily(DeviceFamily id);
     static DeviceFamilyVector* mpDeviceFamilies[DeviceFamilyMax];
 
-    OUString maModel, maHardware, maProduct, maManufacturer;
+    OUString maSuggestedVersion;
 };
 
 #define GFX_DRIVER_VERSION(a,b,c,d) \
@@ -167,6 +167,7 @@ private:
 
     void GetData();
     void FillBlacklist();
+    bool FindBlocklistedDeviceInList();
 
     static OUString* mpDeviceVendors[wgl::DeviceVendorMax];
     static std::vector<wgl::DriverInfo> maDriverInfo;
diff --git a/vcl/opengl/win/WinDeviceInfo.cxx b/vcl/opengl/win/WinDeviceInfo.cxx
index e319c43..86614e8 100644
--- a/vcl/opengl/win/WinDeviceInfo.cxx
+++ b/vcl/opengl/win/WinDeviceInfo.cxx
@@ -87,7 +87,8 @@ void GetDLLVersion(const sal_Unicode* aDLLPath, OUString& aVersion)
 template<typename T, size_t N>
 size_t ArrayLength(T (&aArr)[N])
 {
-      return N;
+    (void) aArr;
+    return N;
 }
 
 #define GFX_DRIVER_VERSION(a,b,c,d) \
@@ -201,6 +202,29 @@ enum {
     kWindows10 = 0x60004
 };
 
+
+wgl::OperatingSystem WindowsVersionToOperatingSystem(int32_t aWindowsVersion)
+{
+    switch(aWindowsVersion) {
+        case kWindowsXP:
+            return wgl::DRIVER_OS_WINDOWS_XP;
+        case kWindowsServer2003:
+            return wgl::DRIVER_OS_WINDOWS_SERVER_2003;
+        case kWindowsVista:
+            return wgl::DRIVER_OS_WINDOWS_VISTA;
+        case kWindows7:
+            return wgl::DRIVER_OS_WINDOWS_7;
+        case kWindows8:
+            return wgl::DRIVER_OS_WINDOWS_8;
+        case kWindows8_1:
+            return wgl::DRIVER_OS_WINDOWS_8_1;
+        case kWindowsUnknown:
+        default:
+            return wgl::DRIVER_OS_UNKNOWN;
+    };
+}
+
+
 int32_t WindowsOSVersion()
 {
     static int32_t winVersion = kWindowsUnknown;
@@ -321,7 +345,7 @@ template<typename T> void appendIntegerWithPadding(OUString& rString, T value, s
 {
     OUString aValue = OUString::number(value, 16);
     sal_Int32 nLength = aValue.getLength();
-    sal_Int32 nPadLength = nChars - nLength;
+    sal_uInt32 nPadLength = nChars - nLength;
     assert(nPadLength >= 0);
     OUStringBuffer aBuffer;
     for (sal_uInt32 i = 0; i < nPadLength; ++i)
@@ -366,7 +390,10 @@ DriverInfo::DriverInfo(OperatingSystem os, const OUString& vendor,
     meComparisonOp(op),
     mnDriverVersion(driverVersion),
     mnDriverVersionMax(0)
-{}
+{
+    if (suggestedVersion)
+        maSuggestedVersion = OStringToOUString(OString(suggestedVersion), RTL_TEXTENCODING_UTF8);
+}
 
 DriverInfo::DriverInfo(const DriverInfo& aOrig)
     : meOperatingSystem(aOrig.meOperatingSystem),
@@ -551,6 +578,97 @@ WinOpenGLDeviceInfo::~WinOpenGLDeviceInfo()
 {
 }
 
+bool WinOpenGLDeviceInfo::FindBlocklistedDeviceInList()
+{
+    uint64_t driverVersion;
+    ParseDriverVersion(maDriverVersion, &driverVersion);
+
+    wgl::OperatingSystem eOS = WindowsVersionToOperatingSystem(mnWindowsVersion);
+    bool match = false;
+    uint32_t i = 0;
+    for (; i < maDriverInfo.size(); i++) {
+        if (maDriverInfo[i].meOperatingSystem != wgl::DRIVER_OS_ALL &&
+                maDriverInfo[i].meOperatingSystem != eOS)
+        {
+            continue;
+        }
+
+        if (maDriverInfo[i].mnOperatingSystemVersion && maDriverInfo[i].mnOperatingSystemVersion != mnWindowsVersion) {
+            continue;
+        }
+
+        if (!maDriverInfo[i].maAdapterVendor.equalsIgnoreAsciiCase(GetDeviceVendor(wgl::VendorAll)) &&
+                !maDriverInfo[i].maAdapterVendor.equalsIgnoreAsciiCase(maAdapterVendorID)) {
+            continue;
+        }
+
+        if (maDriverInfo[i].mpDevices != wgl::DriverInfo::allDevices && maDriverInfo[i].mpDevices->size()) {
+            bool deviceMatches = false;
+            for (uint32_t j = 0; j < maDriverInfo[i].mpDevices->size(); j++) {
+                if ((*maDriverInfo[i].mpDevices)[j].equalsIgnoreAsciiCase(maAdapterDeviceID)) {
+                    deviceMatches = true;
+                    break;
+                }
+            }
+
+            if (!deviceMatches) {
+                continue;
+            }
+        }
+
+#if defined(XP_WIN) || defined(ANDROID)
+        switch (maDriverInfo[i].meComparisonOp) {
+            case DRIVER_LESS_THAN:
+                match = driverVersion < maDriverInfo[i].mnDriverVersion;
+                break;
+            case DRIVER_LESS_THAN_OR_EQUAL:
+                match = driverVersion <= maDriverInfo[i].mnDriverVersion;
+                break;
+            case DRIVER_GREATER_THAN:
+                match = driverVersion > maDriverInfo[i].mnDriverVersion;
+                break;
+            case DRIVER_GREATER_THAN_OR_EQUAL:
+                match = driverVersion >= maDriverInfo[i].mnDriverVersion;
+                break;
+            case DRIVER_EQUAL:
+                match = driverVersion == maDriverInfo[i].mnDriverVersion;
+                break;
+            case DRIVER_NOT_EQUAL:
+                match = driverVersion != maDriverInfo[i].mnDriverVersion;
+                break;
+            case DRIVER_BETWEEN_EXCLUSIVE:
+                match = driverVersion > maDriverInfo[i].mnDriverVersion && driverVersion < maDriverInfo[i].mnDriverVersionMax;
+                break;
+            case DRIVER_BETWEEN_INCLUSIVE:
+                match = driverVersion >= maDriverInfo[i].mnDriverVersion && driverVersion <= maDriverInfo[i].mnDriverVersionMax;
+                break;
+            case DRIVER_BETWEEN_INCLUSIVE_START:
+                match = driverVersion >= maDriverInfo[i].mnDriverVersion && driverVersion < maDriverInfo[i].mnDriverVersionMax;
+                break;
+            case DRIVER_COMPARISON_IGNORED:
+                // We don't have a comparison op, so we match everything.
+                match = true;
+                break;
+            default:
+                SAL_WARN("vcl.opengl", "Bogus op in GfxDriverInfo");
+                break;
+        }
+#else
+        // We don't care what driver version it was. We only check OS version and if
+        // the device matches.
+        match = true;
+#endif
+
+        if (match || maDriverInfo[i].mnDriverVersion == wgl::DriverInfo::allDriverVersions) {
+            match = true;
+            SAL_WARN("vcl.opengl", "use : " << maDriverInfo[i].maSuggestedVersion);
+            break;
+        }
+    }
+
+    return match;
+}
+
 bool WinOpenGLDeviceInfo::isDeviceBlocked()
 {
     SAL_INFO("vcl.opengl", maDriverVersion);
@@ -561,7 +679,13 @@ bool WinOpenGLDeviceInfo::isDeviceBlocked()
     SAL_INFO("vcl.opengl", maAdapterSubsysID);
     SAL_INFO("vcl.opengl", maDeviceKey);
     SAL_INFO("vcl.opengl", maDeviceString);
-    return false;
+
+    // Check if the device is blocked from the downloaded blocklist. If not, check
+    // the static list after that. This order is used so that we can later escape
+    // out of static blocks (i.e. if we were wrong or something was patched, we
+    // can back out our static block without doing a release).
+
+    return FindBlocklistedDeviceInList();
 }
 
 void WinOpenGLDeviceInfo::GetData()
commit d8abf4ee547aa9e509ccc2abcc78f1fe6af01c1d
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu Nov 27 15:46:27 2014 +0100

    port blacklist from mozilla code to LibreOffice, part2
    
    Change-Id: Ia5810aa5f9e1e169b5f0217f6f176a253dc1439d

diff --git a/vcl/inc/opengl/win/WinDeviceInfo.hxx b/vcl/inc/opengl/win/WinDeviceInfo.hxx
index 140662e..524198b 100644
--- a/vcl/inc/opengl/win/WinDeviceInfo.hxx
+++ b/vcl/inc/opengl/win/WinDeviceInfo.hxx
@@ -71,6 +71,67 @@ enum DeviceVendor {
     DeviceVendorMax
 };
 
+struct DriverInfo
+{
+    typedef std::vector<OUString> DeviceFamilyVector;
+
+    // If |ownDevices| is true, you are transferring ownership of the devices
+    // array, and it will be deleted when this GfxDriverInfo is destroyed.
+
+    DriverInfo(OperatingSystem os, const OUString& vendor, DeviceFamilyVector* devices,
+            VersionComparisonOp op,
+            uint64_t driverVersion, const char *suggestedVersion = nullptr,
+            bool ownDevices = false);
+
+    DriverInfo();
+    DriverInfo(const DriverInfo&);
+    ~DriverInfo();
+
+    OperatingSystem meOperatingSystem;
+    uint32_t mnOperatingSystemVersion;
+
+    OUString maAdapterVendor;
+
+    static DeviceFamilyVector* const allDevices;
+    DeviceFamilyVector* mpDevices;
+
+    // Whether the mDevices array should be deleted when this structure is
+    // deallocated. False by default.
+    bool mbDeleteDevices;
+
+    VersionComparisonOp meComparisonOp;
+
+    /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
+    uint64_t mnDriverVersion;
+    uint64_t mnDriverVersionMax;
+    static uint64_t allDriverVersions;
+
+    static const DeviceFamilyVector* GetDeviceFamily(DeviceFamily id);
+    static DeviceFamilyVector* mpDeviceFamilies[DeviceFamilyMax];
+
+    OUString maModel, maHardware, maProduct, maManufacturer;
+};
+
+#define GFX_DRIVER_VERSION(a,b,c,d) \
+    ((uint64_t(a)<<48) | (uint64_t(b)<<32) | (uint64_t(c)<<16) | uint64_t(d))
+
+inline uint64_t V(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
+{
+    // We make sure every driver number is padded by 0s, this will allow us the
+    // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
+    // more extensive explanation of this approach.
+    while (b > 0 && b < 1000) {
+        b *= 10;
+    }
+    while (c > 0 && c < 1000) {
+        c *= 10;
+    }
+    while (d > 0 && d < 1000) {
+        d *= 10;
+    }
+    return GFX_DRIVER_VERSION(a, b, c, d);
+}
+
 }
 
 class WinOpenGLDeviceInfo : public OpenGLDeviceInfo
@@ -105,12 +166,15 @@ private:
     bool mbRDP;
 
     void GetData();
-    OUString GetDeviceVendor(wgl::DeviceVendor eVendor);
+    void FillBlacklist();
 
     static OUString* mpDeviceVendors[wgl::DeviceVendorMax];
+    static std::vector<wgl::DriverInfo> maDriverInfo;
 
 public:
     WinOpenGLDeviceInfo();
+
+    static OUString GetDeviceVendor(wgl::DeviceVendor eVendor);
     virtual ~WinOpenGLDeviceInfo();
 
     virtual bool isDeviceBlocked();
diff --git a/vcl/opengl/win/WinDeviceInfo.cxx b/vcl/opengl/win/WinDeviceInfo.cxx
index b1ddf2f..e319c43 100644
--- a/vcl/opengl/win/WinDeviceInfo.cxx
+++ b/vcl/opengl/win/WinDeviceInfo.cxx
@@ -14,6 +14,22 @@
 #include <cstdint>
 
 OUString* WinOpenGLDeviceInfo::mpDeviceVendors[wgl::DeviceVendorMax];
+std::vector<wgl::DriverInfo> WinOpenGLDeviceInfo::maDriverInfo;
+
+#define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, driverComparator, driverVersion, suggestedVersion) \
+    maDriverInfo.push_back(wgl::DriverInfo(os, vendor, devices, driverComparator, driverVersion, suggestedVersion))
+#define APPEND_TO_DRIVER_BLOCKLIST2(os, vendor, devices, driverComparator, driverVersion) \
+    maDriverInfo.push_back(wgl::DriverInfo(os, vendor, devices, driverComparator, driverVersion))
+
+#define APPEND_TO_DRIVER_BLOCKLIST_RANGE(os, vendor, devices, driverComparator, driverVersion, driverVersionMax, suggestedVersion) \
+    do { \
+        assert(driverComparator == wgl::DRIVER_BETWEEN_EXCLUSIVE || \
+                driverComparator == wgl::DRIVER_BETWEEN_INCLUSIVE || \
+                driverComparator == wgl::DRIVER_BETWEEN_INCLUSIVE_START); \
+        wgl::DriverInfo info(os, vendor, devices, driverComparator, driverVersion, suggestedVersion); \
+        info.mnDriverVersionMax = driverVersionMax; \
+        maDriverInfo.push_back(info); \
+    } while (false)
 
 namespace {
 
@@ -318,6 +334,211 @@ template<typename T> void appendIntegerWithPadding(OUString& rString, T value, s
 #define DEVICE_KEY_PREFIX L"\\Registry\\Machine\\"
 }
 
+namespace wgl {
+
+uint64_t DriverInfo::allDriverVersions = ~(uint64_t(0));
+DriverInfo::DeviceFamilyVector* const DriverInfo::allDevices = nullptr;
+
+DriverInfo::DeviceFamilyVector* DriverInfo::mpDeviceFamilies[DeviceFamilyMax];
+
+DriverInfo::DriverInfo()
+    : meOperatingSystem(wgl::DRIVER_OS_UNKNOWN),
+    mnOperatingSystemVersion(0),
+    maAdapterVendor(WinOpenGLDeviceInfo::GetDeviceVendor(VendorAll)),
+    mpDevices(allDevices),
+    mbDeleteDevices(false),
+    meComparisonOp(DRIVER_COMPARISON_IGNORED),
+    mnDriverVersion(0),
+    mnDriverVersionMax(0)
+{}
+
+DriverInfo::DriverInfo(OperatingSystem os, const OUString& vendor,
+        DeviceFamilyVector* devices,
+        VersionComparisonOp op,
+        uint64_t driverVersion,
+        const char *suggestedVersion /* = nullptr */,
+        bool ownDevices /* = false */)
+    : meOperatingSystem(os),
+    mnOperatingSystemVersion(0),
+    maAdapterVendor(vendor),
+    mpDevices(devices),
+    mbDeleteDevices(ownDevices),
+    meComparisonOp(op),
+    mnDriverVersion(driverVersion),
+    mnDriverVersionMax(0)
+{}
+
+DriverInfo::DriverInfo(const DriverInfo& aOrig)
+    : meOperatingSystem(aOrig.meOperatingSystem),
+    mnOperatingSystemVersion(aOrig.mnOperatingSystemVersion),
+    maAdapterVendor(aOrig.maAdapterVendor),
+    meComparisonOp(aOrig.meComparisonOp),
+    mnDriverVersion(aOrig.mnDriverVersion),
+    mnDriverVersionMax(aOrig.mnDriverVersionMax)
+{
+    //If we're managing the lifetime of the device family, we have to make a
+    // copy of the original's device family.
+    if (aOrig.mbDeleteDevices && aOrig.mpDevices) {
+        mpDevices = new DeviceFamilyVector;
+        *mpDevices = *aOrig.mpDevices;
+    } else {
+        mpDevices = aOrig.mpDevices;
+    }
+
+    mbDeleteDevices = aOrig.mbDeleteDevices;
+}
+
+DriverInfo::~DriverInfo()
+{
+    if (mbDeleteDevices)
+        delete mpDevices;
+}
+
+// Macros for appending a device to the DeviceFamily.
+#define APPEND_DEVICE(device) APPEND_DEVICE2(#device)
+#define APPEND_DEVICE2(device) deviceFamily->push_back(OUString("#device"))
+
+const DriverInfo::DeviceFamilyVector* DriverInfo::GetDeviceFamily(DeviceFamily id)
+{
+    // The code here is too sensitive to fall through to the default case if the
+    // code is invalid.
+    assert(id >= 0 && id < DeviceFamilyMax);
+
+    // If it already exists, we must have processed it once, so return it now.
+    if (mpDeviceFamilies[id])
+        return mpDeviceFamilies[id];
+
+    mpDeviceFamilies[id] = new wgl::DriverInfo::DeviceFamilyVector;
+    wgl::DriverInfo::DeviceFamilyVector* deviceFamily = mpDeviceFamilies[id];
+
+    switch (id) {
+        case IntelGMA500:
+            APPEND_DEVICE(0x8108); /* IntelGMA500_1 */
+            APPEND_DEVICE(0x8109); /* IntelGMA500_2 */
+            break;
+        case IntelGMA900:
+            APPEND_DEVICE(0x2582); /* IntelGMA900_1 */
+            APPEND_DEVICE(0x2782); /* IntelGMA900_2 */
+            APPEND_DEVICE(0x2592); /* IntelGMA900_3 */
+            APPEND_DEVICE(0x2792); /* IntelGMA900_4 */
+            break;
+        case IntelGMA950:
+            APPEND_DEVICE(0x2772); /* Intel945G_1 */
+            APPEND_DEVICE(0x2776); /* Intel945G_2 */
+            APPEND_DEVICE(0x27a2); /* Intel945_1 */
+            APPEND_DEVICE(0x27a6); /* Intel945_2 */
+            APPEND_DEVICE(0x27ae); /* Intel945_3 */
+            break;
+        case IntelGMA3150:
+            APPEND_DEVICE(0xa001); /* IntelGMA3150_Nettop_1 */
+            APPEND_DEVICE(0xa002); /* IntelGMA3150_Nettop_2 */
+            APPEND_DEVICE(0xa011); /* IntelGMA3150_Netbook_1 */
+            APPEND_DEVICE(0xa012); /* IntelGMA3150_Netbook_2 */
+            break;
+        case IntelGMAX3000:
+            APPEND_DEVICE(0x2972); /* Intel946GZ_1 */
+            APPEND_DEVICE(0x2973); /* Intel946GZ_2 */
+            APPEND_DEVICE(0x2982); /* IntelG35_1 */
+            APPEND_DEVICE(0x2983); /* IntelG35_2 */
+            APPEND_DEVICE(0x2992); /* IntelQ965_1 */
+            APPEND_DEVICE(0x2993); /* IntelQ965_2 */
+            APPEND_DEVICE(0x29a2); /* IntelG965_1 */
+            APPEND_DEVICE(0x29a3); /* IntelG965_2 */
+            APPEND_DEVICE(0x29b2); /* IntelQ35_1 */
+            APPEND_DEVICE(0x29b3); /* IntelQ35_2 */
+            APPEND_DEVICE(0x29c2); /* IntelG33_1 */
+            APPEND_DEVICE(0x29c3); /* IntelG33_2 */
+            APPEND_DEVICE(0x29d2); /* IntelQ33_1 */
+            APPEND_DEVICE(0x29d3); /* IntelQ33_2 */
+            APPEND_DEVICE(0x2a02); /* IntelGL960_1 */
+            APPEND_DEVICE(0x2a03); /* IntelGL960_2 */
+            APPEND_DEVICE(0x2a12); /* IntelGM965_1 */
+            APPEND_DEVICE(0x2a13); /* IntelGM965_2 */
+            break;
+        case IntelGMAX4500HD:
+            APPEND_DEVICE(0x2a42); /* IntelGMA4500MHD_1 */
+            APPEND_DEVICE(0x2a43); /* IntelGMA4500MHD_2 */
+            APPEND_DEVICE(0x2e42); /* IntelB43_1 */
+            APPEND_DEVICE(0x2e43); /* IntelB43_2 */
+            APPEND_DEVICE(0x2e92); /* IntelB43_3 */
+            APPEND_DEVICE(0x2e93); /* IntelB43_4 */
+            APPEND_DEVICE(0x2e32); /* IntelG41_1 */
+            APPEND_DEVICE(0x2e33); /* IntelG41_2 */
+            APPEND_DEVICE(0x2e22); /* IntelG45_1 */
+            APPEND_DEVICE(0x2e23); /* IntelG45_2 */
+            APPEND_DEVICE(0x2e12); /* IntelQ45_1 */
+            APPEND_DEVICE(0x2e13); /* IntelQ45_2 */
+            APPEND_DEVICE(0x0042); /* IntelHDGraphics */
+            APPEND_DEVICE(0x0046); /* IntelMobileHDGraphics */
+            APPEND_DEVICE(0x0102); /* IntelSandyBridge_1 */
+            APPEND_DEVICE(0x0106); /* IntelSandyBridge_2 */
+            APPEND_DEVICE(0x0112); /* IntelSandyBridge_3 */
+            APPEND_DEVICE(0x0116); /* IntelSandyBridge_4 */
+            APPEND_DEVICE(0x0122); /* IntelSandyBridge_5 */
+            APPEND_DEVICE(0x0126); /* IntelSandyBridge_6 */
+            APPEND_DEVICE(0x010a); /* IntelSandyBridge_7 */
+            APPEND_DEVICE(0x0080); /* IntelIvyBridge */
+            break;
+        case IntelHD3000:
+            APPEND_DEVICE(0x0126);
+            break;
+        case IntelMobileHDGraphics:
+            APPEND_DEVICE(0x0046); /* IntelMobileHDGraphics */
+            break;
+        case NvidiaBlockD3D9Layers:
+            // Glitches whilst scrolling (see bugs 612007, 644787, 645872)
+            APPEND_DEVICE(0x00f3); /* NV43 [GeForce 6200 (TM)] */
+            APPEND_DEVICE(0x0146); /* NV43 [Geforce Go 6600TE/6200TE (TM)] */
+            APPEND_DEVICE(0x014f); /* NV43 [GeForce 6200 (TM)] */
+            APPEND_DEVICE(0x0161); /* NV44 [GeForce 6200 TurboCache (TM)] */
+            APPEND_DEVICE(0x0162); /* NV44 [GeForce 6200SE TurboCache (TM)] */
+            APPEND_DEVICE(0x0163); /* NV44 [GeForce 6200 LE (TM)] */
+            APPEND_DEVICE(0x0164); /* NV44 [GeForce Go 6200 (TM)] */
+            APPEND_DEVICE(0x0167); /* NV43 [GeForce Go 6200/6400 (TM)] */
+            APPEND_DEVICE(0x0168); /* NV43 [GeForce Go 6200/6400 (TM)] */
+            APPEND_DEVICE(0x0169); /* NV44 [GeForce 6250 (TM)] */
+            APPEND_DEVICE(0x0222); /* NV44 [GeForce 6200 A-LE (TM)] */
+            APPEND_DEVICE(0x0240); /* C51PV [GeForce 6150 (TM)] */
+            APPEND_DEVICE(0x0241); /* C51 [GeForce 6150 LE (TM)] */
+            APPEND_DEVICE(0x0244); /* C51 [Geforce Go 6150 (TM)] */
+            APPEND_DEVICE(0x0245); /* C51 [Quadro NVS 210S/GeForce 6150LE (TM)] */
+            APPEND_DEVICE(0x0247); /* C51 [GeForce Go 6100 (TM)] */
+            APPEND_DEVICE(0x03d0); /* C61 [GeForce 6150SE nForce 430 (TM)] */
+            APPEND_DEVICE(0x03d1); /* C61 [GeForce 6100 nForce 405 (TM)] */
+            APPEND_DEVICE(0x03d2); /* C61 [GeForce 6100 nForce 400 (TM)] */
+            APPEND_DEVICE(0x03d5); /* C61 [GeForce 6100 nForce 420 (TM)] */
+            break;
+        case RadeonX1000:
+            // This list is from the ATIRadeonX1000.kext Info.plist
+            APPEND_DEVICE(0x7187);
+            APPEND_DEVICE(0x7210);
+            APPEND_DEVICE(0x71de);
+            APPEND_DEVICE(0x7146);
+            APPEND_DEVICE(0x7142);
+            APPEND_DEVICE(0x7109);
+            APPEND_DEVICE(0x71c5);
+            APPEND_DEVICE(0x71c0);
+            APPEND_DEVICE(0x7240);
+            APPEND_DEVICE(0x7249);
+            APPEND_DEVICE(0x7291);
+            break;
+        case Geforce7300GT:
+            APPEND_DEVICE(0x0393);
+            break;
+        case Nvidia310M:
+            APPEND_DEVICE(0x0A70);
+            break;
+            // This should never happen, but we get a warning if we don't handle this.
+        case DeviceFamilyMax:
+            SAL_WARN("vcl.opengl", "Invalid DeviceFamily id");
+            break;
+    }
+
+    return deviceFamily;
+}
+
+}
+
 WinOpenGLDeviceInfo::WinOpenGLDeviceInfo():
     mbHasDualGPU(false),
     mbHasDriverVersionMismatch(false),
@@ -629,5 +850,130 @@ OUString WinOpenGLDeviceInfo::GetDeviceVendor(wgl::DeviceVendor id)
     return *mpDeviceVendors[id];
 }
 
+void WinOpenGLDeviceInfo::FillBlacklist()
+{
+    /*
+     * It should be noted here that more specialized rules on certain features
+     * should be inserted -before- more generalized restriction. As the first
+     * match for feature/OS/device found in the list will be used for the final
+     * blacklisting call.
+     */
+
+    /*
+     * NVIDIA entries
+     */
+    APPEND_TO_DRIVER_BLOCKLIST( wgl::DRIVER_OS_WINDOWS_XP,
+            GetDeviceVendor(wgl::VendorNVIDIA), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_LESS_THAN, wgl::V(6,14,11,8265), "182.65" );
+    APPEND_TO_DRIVER_BLOCKLIST( wgl::DRIVER_OS_WINDOWS_VISTA,
+            GetDeviceVendor(wgl::VendorNVIDIA), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_LESS_THAN, wgl::V(8,17,11,8265), "182.65" );
+    APPEND_TO_DRIVER_BLOCKLIST( wgl::DRIVER_OS_WINDOWS_7,
+            GetDeviceVendor(wgl::VendorNVIDIA), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_LESS_THAN, wgl::V(8,17,11,8265), "182.65" );
+
+    /*
+     * AMD/ATI entries
+     */
+    APPEND_TO_DRIVER_BLOCKLIST( wgl::DRIVER_OS_ALL,
+            GetDeviceVendor(wgl::VendorATI), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_LESS_THAN, wgl::V(8,62,0,0), "9.6" );
+    APPEND_TO_DRIVER_BLOCKLIST( wgl::DRIVER_OS_ALL,
+            GetDeviceVendor(wgl::VendorAMD), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_LESS_THAN, wgl::V(8,62,0,0), "9.6" );
+
+    /*
+     * Bug 783517 - crashes in AMD driver on Windows 8
+     */
+    APPEND_TO_DRIVER_BLOCKLIST_RANGE( wgl::DRIVER_OS_WINDOWS_8,
+            GetDeviceVendor(wgl::VendorATI), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_BETWEEN_INCLUSIVE_START, wgl::V(8,982,0,0), wgl::V(8,983,0,0), "!= 8.982.*.*" );
+    APPEND_TO_DRIVER_BLOCKLIST_RANGE( wgl::DRIVER_OS_WINDOWS_8,
+            GetDeviceVendor(wgl::VendorAMD), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_BETWEEN_INCLUSIVE_START, wgl::V(8,982,0,0), wgl::V(8,983,0,0), "!= 8.982.*.*" );
+
+    /* OpenGL on any ATI/AMD hardware is discouraged
+     * See:
+     *  bug 619773 - WebGL: Crash with blue screen : "NMI: Parity Check / Memory Parity Error"
+     *  bugs 584403, 584404, 620924 - crashes in atioglxx
+     *  + many complaints about incorrect rendering
+     */
+    APPEND_TO_DRIVER_BLOCKLIST2( wgl::DRIVER_OS_ALL,
+            GetDeviceVendor(wgl::VendorATI), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_LESS_THAN, wgl::DriverInfo::allDriverVersions );
+    APPEND_TO_DRIVER_BLOCKLIST2( wgl::DRIVER_OS_ALL,
+            GetDeviceVendor(wgl::VendorATI), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_LESS_THAN, wgl::DriverInfo::allDriverVersions );
+    APPEND_TO_DRIVER_BLOCKLIST2( wgl::DRIVER_OS_ALL,
+            GetDeviceVendor(wgl::VendorAMD), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_LESS_THAN, wgl::DriverInfo::allDriverVersions );
+    APPEND_TO_DRIVER_BLOCKLIST2( wgl::DRIVER_OS_ALL,
+            GetDeviceVendor(wgl::VendorAMD), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_LESS_THAN, wgl::DriverInfo::allDriverVersions );
+
+    /*
+     * Intel entries
+     */
+
+    /* The driver versions used here come from bug 594877. They might not
+     * be particularly relevant anymore.
+     */
+#define IMPLEMENT_INTEL_DRIVER_BLOCKLIST(winVer, devFamily, driverVer)                                                      \
+    APPEND_TO_DRIVER_BLOCKLIST2( winVer,                                                                                      \
+            GetDeviceVendor(wgl::VendorIntel), (wgl::DriverInfo::DeviceFamilyVector*) wgl::DriverInfo::GetDeviceFamily(devFamily), \
+            wgl::DRIVER_LESS_THAN, driverVer )
+
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_XP, wgl::IntelGMA500,   wgl::V(3,0,20,3200));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_XP, wgl::IntelGMA900,   wgl::V(6,14,10,4764));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_XP, wgl::IntelGMA950,   wgl::V(6,14,10,4926));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_XP, wgl::IntelGMA3150,  wgl::V(6,14,10,5134));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_XP, wgl::IntelGMAX3000, wgl::V(6,14,10,5218));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_XP, wgl::IntelGMAX4500HD, wgl::V(6,14,10,4969));
+
+    // StrechRect seems to suffer from precision issues which leads to artifacting
+    // during content drawing starting with at least version 6.14.10.5082
+    // and going until 6.14.10.5218. See bug 919454 and bug 949275 for more info.
+    APPEND_TO_DRIVER_BLOCKLIST_RANGE(wgl::DRIVER_OS_WINDOWS_XP,
+            GetDeviceVendor(wgl::VendorIntel),
+            const_cast<wgl::DriverInfo::DeviceFamilyVector*>(wgl::DriverInfo::GetDeviceFamily(wgl::IntelGMAX4500HD)),
+            wgl::DRIVER_BETWEEN_EXCLUSIVE, wgl::V(6,14,10,5076), wgl::V(6,14,10,5218), "6.14.10.5218");
+
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_VISTA, wgl::IntelGMA500,   wgl::V(3,0,20,3200));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_VISTA, wgl::IntelGMA900,   wgl::DriverInfo::allDriverVersions);
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_VISTA, wgl::IntelGMA950,   wgl::V(7,14,10,1504));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_VISTA, wgl::IntelGMA3150,  wgl::V(7,14,10,1910));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_VISTA, wgl::IntelGMAX3000, wgl::V(7,15,10,1666));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_VISTA, wgl::IntelGMAX4500HD, wgl::V(7,15,10,1666));
+
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_7, wgl::IntelGMA500,   wgl::V(5,0,0,2026));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_7, wgl::IntelGMA900,   wgl::DriverInfo::allDriverVersions);
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_7, wgl::IntelGMA950,   wgl::V(8,15,10,1930));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_7, wgl::IntelGMA3150,  wgl::V(8,14,10,1972));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_7, wgl::IntelGMAX3000, wgl::V(7,15,10,1666));
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(wgl::DRIVER_OS_WINDOWS_7, wgl::IntelGMAX4500HD, wgl::V(7,15,10,1666));
+
+    /* OpenGL on any Intel hardware is discouraged */
+    APPEND_TO_DRIVER_BLOCKLIST2( wgl::DRIVER_OS_ALL,
+            GetDeviceVendor(wgl::VendorIntel), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_LESS_THAN, wgl::DriverInfo::allDriverVersions );
+    APPEND_TO_DRIVER_BLOCKLIST2( wgl::DRIVER_OS_ALL,
+            GetDeviceVendor(wgl::VendorIntel), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_LESS_THAN, wgl::DriverInfo::allDriverVersions );
+
+    /**
+     * Disable acceleration on Intel HD 3000 for graphics drivers <= 8.15.10.2321.
+     * See bug 1018278 and bug 1060736.
+     */
+    APPEND_TO_DRIVER_BLOCKLIST( wgl::DRIVER_OS_ALL,
+            GetDeviceVendor(wgl::VendorIntel), (wgl::DriverInfo::DeviceFamilyVector*) wgl::DriverInfo::GetDeviceFamily(wgl::IntelHD3000),
+            wgl::DRIVER_LESS_THAN_OR_EQUAL, wgl::V(8,15,10,2321), "8.15.10.2342" );
+
+    /* Microsoft RemoteFX; blocked less than 6.2.0.0 */
+    APPEND_TO_DRIVER_BLOCKLIST( wgl::DRIVER_OS_ALL,
+            GetDeviceVendor(wgl::VendorMicrosoft), wgl::DriverInfo::allDevices,
+            wgl::DRIVER_LESS_THAN, wgl::V(6,2,0,0), "< 6.2.0.0" );
+
+}
+
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 40ad9eea885db925fc7ad8872d529a7c5cb43a5a
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Mon Nov 24 16:46:15 2014 +0100

    implement windows OpenGL blacklist, first step
    
    Change-Id: I408b76855693c64473dba3bb3fa94374fff01fae

diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 5d900e2..3113497 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -647,6 +647,7 @@ endif
 ifeq ($(OS),WNT)
 $(eval $(call gb_Library_add_exception_objects,vcl,\
 	vcl/opengl/win/gdiimpl \
+	vcl/opengl/win/WinDeviceInfo \
     vcl/win/source/app/saldata \
     vcl/win/source/app/salinfo \
     vcl/win/source/app/salinst \
@@ -684,6 +685,7 @@ $(eval $(call gb_Library_use_system_win32_libs,vcl,\
 	uuid \
 	version \
 	winspool \
+	setupapi \
 	shlwapi \
 ))
 
diff --git a/vcl/inc/opengl/win/WinDeviceInfo.hxx b/vcl/inc/opengl/win/WinDeviceInfo.hxx
new file mode 100644
index 0000000..140662e
--- /dev/null
+++ b/vcl/inc/opengl/win/WinDeviceInfo.hxx
@@ -0,0 +1,121 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_VCL_OPENGL_WIN_WINDEVICEINFO_HXX
+#define INCLUDED_VCL_OPENGL_WIN_WINDEVICEINFO_HXX
+
+#include "opengl/DeviceInfo.hxx"
+#include <rtl/ustring.hxx>
+
+namespace wgl {
+
+enum OperatingSystem {
+    DRIVER_OS_UNKNOWN = 0,
+    DRIVER_OS_WINDOWS_XP,
+    DRIVER_OS_WINDOWS_SERVER_2003,
+    DRIVER_OS_WINDOWS_VISTA,
+    DRIVER_OS_WINDOWS_7,
+    DRIVER_OS_WINDOWS_8,
+    DRIVER_OS_WINDOWS_8_1,
+    DRIVER_OS_LINUX,
+    DRIVER_OS_OS_X_10_5,
+    DRIVER_OS_OS_X_10_6,
+    DRIVER_OS_OS_X_10_7,
+    DRIVER_OS_OS_X_10_8,
+    DRIVER_OS_ANDROID,
+    DRIVER_OS_ALL
+};
+
+enum VersionComparisonOp {
+    DRIVER_LESS_THAN,             // driver <  version
+    DRIVER_LESS_THAN_OR_EQUAL,    // driver <= version
+    DRIVER_GREATER_THAN,          // driver >  version
+    DRIVER_GREATER_THAN_OR_EQUAL, // driver >= version
+    DRIVER_EQUAL,                 // driver == version
+    DRIVER_NOT_EQUAL,             // driver != version
+    DRIVER_BETWEEN_EXCLUSIVE,     // driver > version && driver < versionMax
+    DRIVER_BETWEEN_INCLUSIVE,     // driver >= version && driver <= versionMax
+    DRIVER_BETWEEN_INCLUSIVE_START, // driver >= version && driver < versionMax
+    DRIVER_COMPARISON_IGNORED
+};
+
+enum DeviceFamily {
+    IntelGMA500,
+    IntelGMA900,
+    IntelGMA950,
+    IntelGMA3150,
+    IntelGMAX3000,
+    IntelGMAX4500HD,
+    IntelHD3000,
+    IntelMobileHDGraphics,
+    NvidiaBlockD3D9Layers,
+    RadeonX1000,
+    Geforce7300GT,
+    Nvidia310M,
+    DeviceFamilyMax
+};
+
+enum DeviceVendor {
+    VendorAll,
+    VendorIntel,
+    VendorNVIDIA,
+    VendorAMD,
+    VendorATI,
+    VendorMicrosoft,
+    DeviceVendorMax
+};
+
+}
+
+class WinOpenGLDeviceInfo : public OpenGLDeviceInfo
+{
+private:
+    OUString maDriverVersion;
+    OUString maDriverVersion2;
+
+    OUString maDriverDate;
+    OUString maDriverDate2;
+
+    OUString maDeviceID;
+    OUString maDeviceID2;
+
+    OUString maAdapterVendorID;
+    OUString maAdapterDeviceID;
+    OUString maAdapterSubsysID;
+
+    OUString maAdapterVendorID2;
+    OUString maAdapterDeviceID2;
+    OUString maAdapterSubsysID2;
+
+    OUString maDeviceKey;
+    OUString maDeviceKey2;
+
+    OUString maDeviceString;
+    OUString maDeviceString2;
+    uint32_t mnWindowsVersion;
+
+    bool mbHasDualGPU;
+    bool mbHasDriverVersionMismatch;
+    bool mbRDP;
+
+    void GetData();
+    OUString GetDeviceVendor(wgl::DeviceVendor eVendor);
+
+    static OUString* mpDeviceVendors[wgl::DeviceVendorMax];
+
+public:
+    WinOpenGLDeviceInfo();
+    virtual ~WinOpenGLDeviceInfo();
+
+    virtual bool isDeviceBlocked();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/win/WinDeviceInfo.cxx b/vcl/opengl/win/WinDeviceInfo.cxx
new file mode 100644
index 0000000..b1ddf2f
--- /dev/null
+++ b/vcl/opengl/win/WinDeviceInfo.cxx
@@ -0,0 +1,633 @@
+/* -*- 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/win/WinDeviceInfo.hxx"
+
+#include <windows.h>
+#include <setupapi.h>
+#include <cstdint>
+
+OUString* WinOpenGLDeviceInfo::mpDeviceVendors[wgl::DeviceVendorMax];
+
+namespace {
+
+
+void GetDLLVersion(const sal_Unicode* aDLLPath, OUString& aVersion)
+{
+    DWORD versInfoSize, vers[4] = {0};
+    // version info not available case
+    aVersion = OUString("0.0.0.0");
+    versInfoSize = GetFileVersionInfoSizeW(aDLLPath, nullptr);
+    std::vector<char> versionInfo(512, 0);
+
+    if (versInfoSize == 0)
+    {
+        return;
+    }
+    versionInfo.resize(uint32_t(versInfoSize));
+
+    if (!GetFileVersionInfoW(aDLLPath, 0, versInfoSize,
+                LPBYTE(&versionInfo[0])))
+    {
+        return;
+    }
+
+    UINT len = 0;
+    VS_FIXEDFILEINFO *fileInfo = nullptr;
+    if (!VerQueryValue(LPBYTE(&versionInfo[0]), TEXT("\\"),
+                (LPVOID *)&fileInfo, &len) ||
+            len == 0 ||
+            fileInfo == nullptr)
+    {
+        return;
+    }
+
+    DWORD fileVersMS = fileInfo->dwFileVersionMS;
+    DWORD fileVersLS = fileInfo->dwFileVersionLS;
+
+    vers[0] = HIWORD(fileVersMS);
+    vers[1] = LOWORD(fileVersMS);
+    vers[2] = HIWORD(fileVersLS);
+    vers[3] = LOWORD(fileVersLS);
+
+    char buf[256];
+    sprintf(buf, "%d.%d.%d.%d", vers[0], vers[1], vers[2], vers[3]);
+    OString aBuf(buf);
+    aVersion = OStringToOUString(aBuf, RTL_TEXTENCODING_UTF8);
+}
+
+/*
+*  * Compute the length of an array with constant length.  (Use of this method
+*   * with a non-array pointer will not compile.)
+*    *
+*     * Beware of the implicit trailing '\0' when using this with string constants.
+*      */
+template<typename T, size_t N>
+size_t ArrayLength(T (&aArr)[N])
+{
+      return N;
+}
+
+#define GFX_DRIVER_VERSION(a,b,c,d) \
+((uint64_t(a)<<48) | (uint64_t(b)<<32) | (uint64_t(c)<<16) | uint64_t(d))
+
+bool GetKeyValue(const WCHAR* keyLocation, const WCHAR* keyName, OUString& destString, int type)
+{
+    HKEY key;
+    DWORD dwcbData;
+    DWORD dValue;
+    DWORD resultType;
+    LONG result;
+    bool retval = true;
+
+    result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyLocation, 0, KEY_QUERY_VALUE, &key);
+    if (result != ERROR_SUCCESS) {
+        return false;
+    }
+
+    switch (type) {
+        case REG_DWORD:
+            {
+                // We only use this for vram size
+                dwcbData = sizeof(dValue);
+                result = RegQueryValueExW(key, keyName, nullptr, &resultType,
+                        (LPBYTE)&dValue, &dwcbData);
+                if (result == ERROR_SUCCESS && resultType == REG_DWORD) {
+                    dValue = dValue / 1024 / 1024;
+                    destString += OUString::number(int32_t(dValue));
+                } else {
+                    retval = false;
+                }
+                break;
+            }
+        case REG_MULTI_SZ:
+            {
+                // A chain of null-separated strings; we convert the nulls to spaces
+                WCHAR wCharValue[1024];
+                dwcbData = sizeof(wCharValue);
+
+                result = RegQueryValueExW(key, keyName, nullptr, &resultType,
+                        (LPBYTE)wCharValue, &dwcbData);
+                if (result == ERROR_SUCCESS && resultType == REG_MULTI_SZ) {
+                    // This bit here could probably be cleaner.
+                    bool isValid = false;
+
+                    DWORD strLen = dwcbData/sizeof(wCharValue[0]);
+                    for (DWORD i = 0; i < strLen; i++) {
+                        if (wCharValue[i] == '\0') {
+                            if (i < strLen - 1 && wCharValue[i + 1] == '\0') {
+                                isValid = true;
+                                break;
+                            } else {
+                                wCharValue[i] = ' ';
+                            }
+                        }
+                    }
+
+                    // ensure wCharValue is null terminated
+                    wCharValue[strLen-1] = '\0';
+
+                    if (isValid)
+                        destString = OUString(wCharValue);
+
+                } else {
+                    retval = false;
+                }
+
+                break;
+            }
+    }
+    RegCloseKey(key);
+
+    return retval;
+}
+
+// The driver ID is a string like PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD, possibly
+// followed by &REV_XXXX.  We uppercase the string, and strip the &REV_ part
+// from it, if found.
+void normalizeDriverId(OUString& driverid) {
+    driverid = driverid.toAsciiUpperCase();
+    int32_t rev = driverid.indexOf("&REV_");
+    if (rev != -1) {
+        driverid = driverid.copy(0, rev - 1);
+    }
+}
+
+// The device ID is a string like PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD
+// this function is used to extract the id's out of it
+uint32_t ParseIDFromDeviceID(const OUString &key, const char *prefix, int length)
+{
+    OUString id = key.toAsciiUpperCase();
+    OUString aPrefix = OUString::fromUtf8(prefix);
+    int32_t start = id.indexOf(aPrefix);
+    if (start != -1) {
+        id = id.copy(start + aPrefix.getLength(), length);
+    }
+    return id.toUInt32(16);
+}
+
+// OS version in 16.16 major/minor form
+// based on http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
+enum {
+    kWindowsUnknown = 0,
+    kWindowsXP = 0x50001,
+    kWindowsServer2003 = 0x50002,
+    kWindowsVista = 0x60000,
+    kWindows7 = 0x60001,
+    kWindows8 = 0x60002,
+    kWindows8_1 = 0x60003,
+    kWindows10 = 0x60004
+};
+
+int32_t WindowsOSVersion()
+{
+    static int32_t winVersion = kWindowsUnknown;
+
+    OSVERSIONINFO vinfo;
+
+    if (winVersion == kWindowsUnknown) {
+        vinfo.dwOSVersionInfoSize = sizeof (vinfo);
+#pragma warning(push)
+#pragma warning(disable:4996)
+        if (!GetVersionEx(&vinfo)) {
+#pragma warning(pop)
+            winVersion = kWindowsUnknown;
+        } else {
+            winVersion = int32_t(vinfo.dwMajorVersion << 16) + vinfo.dwMinorVersion;
+        }
+    }
+
+    return winVersion;
+}
+
+// This allows us to pad driver version 'substrings' with 0s, this
+// effectively allows us to treat the version numbers as 'decimals'. This is
+// a little strange but this method seems to do the right thing for all
+// different vendor's driver strings. i.e. .98 will become 9800, which is
+// larger than .978 which would become 9780.
+void PadDriverDecimal(char *aString)
+{
+    for (int i = 0; i < 4; i++) {
+        if (!aString[i]) {
+            for (int c = i; c < 4; c++) {
+                aString[c] = '0';
+            }
+            break;
+        }
+    }
+    aString[4] = 0;
+}
+
+// All destination string storage needs to have at least 5 bytes available.
+bool SplitDriverVersion(const char *aSource, char *aAStr, char *aBStr, char *aCStr, char *aDStr)
+{
+    // sscanf doesn't do what we want here to we parse this manually.
+    int len = strlen(aSource);
+    char *dest[4] = { aAStr, aBStr, aCStr, aDStr };
+    unsigned destIdx = 0;
+    unsigned destPos = 0;
+
+    for (int i = 0; i < len; i++) {
+        if (destIdx > ArrayLength(dest)) {
+            // Invalid format found. Ensure we don't access dest beyond bounds.
+            return false;
+        }
+
+        if (aSource[i] == '.') {
+            dest[destIdx++][destPos] = 0;
+            destPos = 0;
+            continue;
+        }
+
+        if (destPos > 3) {
+            // Ignore more than 4 chars. Ensure we never access dest[destIdx]
+            // beyond its bounds.
+            continue;
+        }
+
+        dest[destIdx][destPos++] = aSource[i];
+    }
+
+    // Add last terminator.
+    dest[destIdx][destPos] = 0;
+
+    if (destIdx != ArrayLength(dest) - 1) {
+        return false;
+    }
+    return true;
+}
+
+bool ParseDriverVersion(const OUString& aVersion, uint64_t *aNumericVersion)
+{
+    *aNumericVersion = 0;
+
+#if defined(WIN32)
+    int a, b, c, d;
+    char aStr[8], bStr[8], cStr[8], dStr[8];
+    /* honestly, why do I even bother */
+    OString aOVersion = OUStringToOString(aVersion, RTL_TEXTENCODING_UTF8);
+    if (!SplitDriverVersion(aOVersion.getStr(), aStr, bStr, cStr, dStr))
+        return false;
+
+    PadDriverDecimal(bStr);
+    PadDriverDecimal(cStr);
+    PadDriverDecimal(dStr);
+
+    a = atoi(aStr);
+    b = atoi(bStr);
+    c = atoi(cStr);
+    d = atoi(dStr);
+
+    if (a < 0 || a > 0xffff) return false;
+    if (b < 0 || b > 0xffff) return false;
+    if (c < 0 || c > 0xffff) return false;
+    if (d < 0 || d > 0xffff) return false;
+
+    *aNumericVersion = GFX_DRIVER_VERSION(a, b, c, d);
+    return true;
+#else
+    return false;
+#endif
+}
+/* Other interesting places for info:
+ *   IDXGIAdapter::GetDesc()
+ *   IDirectDraw7::GetAvailableVidMem()
+ *   e->GetAvailableTextureMem()
+ * */
+
+template<typename T> void appendIntegerWithPadding(OUString& rString, T value, sal_uInt32 nChars)
+{
+    OUString aValue = OUString::number(value, 16);
+    sal_Int32 nLength = aValue.getLength();
+    sal_Int32 nPadLength = nChars - nLength;
+    assert(nPadLength >= 0);
+    OUStringBuffer aBuffer;
+    for (sal_uInt32 i = 0; i < nPadLength; ++i)
+    {
+        aBuffer.append("0");
+    }
+    rString += aBuffer.makeStringAndClear() + aValue;
+}
+
+#define DEVICE_KEY_PREFIX L"\\Registry\\Machine\\"
+}
+
+WinOpenGLDeviceInfo::WinOpenGLDeviceInfo():
+    mbHasDualGPU(false),
+    mbHasDriverVersionMismatch(false),
+    mbRDP(false)
+{
+    GetData();
+}
+
+WinOpenGLDeviceInfo::~WinOpenGLDeviceInfo()
+{
+}
+
+bool WinOpenGLDeviceInfo::isDeviceBlocked()
+{
+    SAL_INFO("vcl.opengl", maDriverVersion);
+    SAL_INFO("vcl.opengl", maDriverDate);
+    SAL_INFO("vcl.opengl", maDeviceID);
+    SAL_INFO("vcl.opengl", maAdapterVendorID);
+    SAL_INFO("vcl.opengl", maAdapterDeviceID);
+    SAL_INFO("vcl.opengl", maAdapterSubsysID);
+    SAL_INFO("vcl.opengl", maDeviceKey);
+    SAL_INFO("vcl.opengl", maDeviceString);
+    return false;
+}
+
+void WinOpenGLDeviceInfo::GetData()
+{
+    DISPLAY_DEVICEW displayDevice;
+    displayDevice.cb = sizeof(displayDevice);
+
+    mnWindowsVersion = WindowsOSVersion();
+    int deviceIndex = 0;
+
+    while (EnumDisplayDevicesW(nullptr, deviceIndex, &displayDevice, 0)) {
+        if (displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
+            break;
+        }
+        deviceIndex++;
+    }
+
+    // make sure the string is nullptr terminated
+    if (wcsnlen(displayDevice.DeviceKey, ArrayLength(displayDevice.DeviceKey))
+            == ArrayLength(displayDevice.DeviceKey)) {
+        // we did not find a nullptr
+        SAL_WARN("vcl.opengl", "no null pointer");
+        return;
+    }
+
+    /* DeviceKey is "reserved" according to MSDN so we'll be careful with it */
+    /* check that DeviceKey begins with DEVICE_KEY_PREFIX */
+    /* some systems have a DeviceKey starting with \REGISTRY\Machine\ so we need to compare case insenstively */
+    if (_wcsnicmp(displayDevice.DeviceKey, DEVICE_KEY_PREFIX, ArrayLength(DEVICE_KEY_PREFIX)-1) != 0)
+    {
+        SAL_WARN("vcl.opengl", "incorrect DeviceKey");
+        return;
+    }
+
+    // chop off DEVICE_KEY_PREFIX
+    maDeviceKey = displayDevice.DeviceKey + ArrayLength(DEVICE_KEY_PREFIX)-1;
+
+    maDeviceID = displayDevice.DeviceID;
+    maDeviceString = displayDevice.DeviceString;
+
+    if (maDeviceID.isEmpty() &&
+            maDeviceString == "RDPUDD Chained DD")
+    {
+        // TODO: moggi: we need to block RDP as it does not provide OpenGL 2.1+
+        mbRDP = true;
+        SAL_WARN("vcl.opengl", "RDP => blocked");
+        return;
+    }
+
+    /* create a device information set composed of the current display device */
+    HDEVINFO devinfo = SetupDiGetClassDevsW(nullptr, maDeviceID.getStr(), nullptr,
+            DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES);
+
+    if (devinfo != INVALID_HANDLE_VALUE) {
+        HKEY key;
+        LONG result;
+        WCHAR value[255];
+        DWORD dwcbData;
+        SP_DEVINFO_DATA devinfoData;
+        DWORD memberIndex = 0;
+
+        devinfoData.cbSize = sizeof(devinfoData);
+        OUString aDriverKeyPre("System\\CurrentControlSet\\Control\\Class\\");
+        /* enumerate device information elements in the device information set */
+        while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) {
+            /* get a string that identifies the device's driver key */
+            if (SetupDiGetDeviceRegistryPropertyW(devinfo,
+                        &devinfoData,
+                        SPDRP_DRIVER,
+                        nullptr,
+                        (PBYTE)value,
+                        sizeof(value),
+                        nullptr)) {
+                OUString  driverKey(aDriverKeyPre);
+                driverKey += value;
+                result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey.getStr(), 0, KEY_QUERY_VALUE, &key);
+                if (result == ERROR_SUCCESS) {
+                    /* we've found the driver we're looking for */
+                    dwcbData = sizeof(value);
+                    result = RegQueryValueExW(key, L"DriverVersion", nullptr, nullptr,
+                            (LPBYTE)value, &dwcbData);
+                    if (result == ERROR_SUCCESS) {
+                        maDriverVersion = OUString(value);
+                    } else {
+                        // If the entry wasn't found, assume the worst (0.0.0.0).
+                        maDriverVersion = OUString("0.0.0.0");
+                    }
+                    dwcbData = sizeof(value);
+                    result = RegQueryValueExW(key, L"DriverDate", nullptr, nullptr,
+                            (LPBYTE)value, &dwcbData);
+                    if (result == ERROR_SUCCESS) {
+                        maDriverDate = value;
+                    } else {
+                        // Again, assume the worst
+                        maDriverDate = OUString("01-01-1970");
+                    }
+                    RegCloseKey(key);
+                    break;
+                }
+            }
+        }
+
+        SetupDiDestroyDeviceInfoList(devinfo);
+    }
+    else
+    {
+        SAL_WARN("vcl.opengl", "invalid handle value");
+    }
+
+    appendIntegerWithPadding(maAdapterVendorID, ParseIDFromDeviceID(maDeviceID, "VEN_", 4), 4);
+    appendIntegerWithPadding(maAdapterDeviceID, ParseIDFromDeviceID(maDeviceID, "&DEV_", 4), 4);
+    appendIntegerWithPadding(maAdapterSubsysID, ParseIDFromDeviceID(maDeviceID, "&SUBSYS_", 8), 8);
+
+    // We now check for second display adapter.
+
+    // Device interface class for display adapters.
+    CLSID GUID_DISPLAY_DEVICE_ARRIVAL;
+    HRESULT hresult = CLSIDFromString(L"{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}",
+            &GUID_DISPLAY_DEVICE_ARRIVAL);
+    if (hresult == NOERROR) {
+        devinfo = SetupDiGetClassDevsW(&GUID_DISPLAY_DEVICE_ARRIVAL,
+                nullptr, nullptr,
+                DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
+
+        if (devinfo != INVALID_HANDLE_VALUE) {
+            HKEY key;
+            LONG result;
+            WCHAR value[255];
+            DWORD dwcbData;
+            SP_DEVINFO_DATA devinfoData;
+            DWORD memberIndex = 0;
+            devinfoData.cbSize = sizeof(devinfoData);
+
+            OUString aAdapterDriver2;
+            OUString aDeviceID2;
+            OUString aDriverVersion2;
+            OUString aDriverDate2;
+            uint32_t adapterVendorID2;
+            uint32_t adapterDeviceID2;
+
+            OUString aDriverKeyPre("System\\CurrentControlSet\\Control\\Class\\");
+            /* enumerate device information elements in the device information set */
+            while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) {
+                /* get a string that identifies the device's driver key */
+                if (SetupDiGetDeviceRegistryPropertyW(devinfo,
+                            &devinfoData,
+                            SPDRP_DRIVER,
+                            nullptr,
+                            (PBYTE)value,
+                            sizeof(value),
+                            nullptr)) {
+                    OUString driverKey2(aDriverKeyPre);
+                    driverKey2 += value;
+                    result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey2.getStr(), 0, KEY_QUERY_VALUE, &key);
+                    if (result == ERROR_SUCCESS) {
+                        dwcbData = sizeof(value);
+                        result = RegQueryValueExW(key, L"MatchingDeviceId", nullptr,
+                                nullptr, (LPBYTE)value, &dwcbData);
+                        if (result != ERROR_SUCCESS) {
+                            continue;
+                        }
+                        aDeviceID2 = value;
+                        OUString aAdapterVendorID2String;
+                        OUString aAdapterDeviceID2String;
+                        adapterVendorID2 = ParseIDFromDeviceID(aDeviceID2, "VEN_", 4);
+                        appendIntegerWithPadding(aAdapterVendorID2String, adapterVendorID2, 4);
+                        adapterDeviceID2 = ParseIDFromDeviceID(aDeviceID2, "&DEV_", 4);
+                        appendIntegerWithPadding(aAdapterDeviceID2String, adapterDeviceID2, 4);
+                        if (maAdapterVendorID == aAdapterVendorID2String &&
+                                maAdapterDeviceID == aAdapterDeviceID2String) {
+                            RegCloseKey(key);
+                            continue;
+                        }
+
+                        // If this device is missing driver information, it is unlikely to
+                        // be a real display adapter.
+                        if (!GetKeyValue(driverKey2.getStr(), L"InstalledDisplayDrivers",
+                                        aAdapterDriver2, REG_MULTI_SZ)) {
+                            RegCloseKey(key);
+                            continue;
+                        }
+                        dwcbData = sizeof(value);
+                        result = RegQueryValueExW(key, L"DriverVersion", nullptr, nullptr,
+                                (LPBYTE)value, &dwcbData);
+                        if (result != ERROR_SUCCESS) {
+                            RegCloseKey(key);
+                            continue;
+                        }
+                        aDriverVersion2 = value;
+                        dwcbData = sizeof(value);
+                        result = RegQueryValueExW(key, L"DriverDate", nullptr, nullptr,
+                                (LPBYTE)value, &dwcbData);
+                        if (result != ERROR_SUCCESS) {
+                            RegCloseKey(key);
+                            continue;
+                        }
+                        aDriverDate2 = value;
+                        dwcbData = sizeof(value);
+                        result = RegQueryValueExW(key, L"Device Description", nullptr,
+                                nullptr, (LPBYTE)value, &dwcbData);
+                        if (result != ERROR_SUCCESS) {
+                            dwcbData = sizeof(value);
+                            result = RegQueryValueExW(key, L"DriverDesc", nullptr, nullptr,
+                                    (LPBYTE)value, &dwcbData);
+                        }
+                        RegCloseKey(key);
+                        if (result == ERROR_SUCCESS) {
+                            mbHasDualGPU = true;
+                            maDeviceString2 = value;
+                            maDeviceID2 = aDeviceID2;
+                            maDeviceKey2 = driverKey2;
+                            maDriverVersion2 = aDriverVersion2;
+                            maDriverDate2 = aDriverDate2;
+                            appendIntegerWithPadding(maAdapterVendorID2, adapterVendorID2, 4);
+                            appendIntegerWithPadding(maAdapterDeviceID2, adapterDeviceID2, 4);
+                            appendIntegerWithPadding(maAdapterSubsysID2, ParseIDFromDeviceID(maDeviceID2, "&SUBSYS_", 8), 8);
+                            break;
+                        }
+                    }
+                }
+            }
+
+            SetupDiDestroyDeviceInfoList(devinfo);
+        }
+    }
+
+    mbHasDriverVersionMismatch = false;
+    if (maAdapterVendorID == GetDeviceVendor(wgl::VendorIntel)) {
+        // we've had big crashers (bugs 590373 and 595364) apparently correlated
+        // with bad Intel driver installations where the DriverVersion reported
+        // by the registry was not the version of the DLL.
+        OUString aDLLFileName("igd10umd32.dll");
+        OUString aDLLFileName2("igd10iumd32.dll");
+        OUString aDLLVersion, aDLLVersion2;
+        GetDLLVersion(aDLLFileName.getStr(), aDLLVersion);
+        GetDLLVersion(aDLLFileName2.getStr(), aDLLVersion2);
+
+        uint64_t dllNumericVersion = 0, dllNumericVersion2 = 0,
+                 driverNumericVersion = 0, knownSafeMismatchVersion = 0;
+        ParseDriverVersion(aDLLVersion, &dllNumericVersion);
+        ParseDriverVersion(aDLLVersion2, &dllNumericVersion2);
+        ParseDriverVersion(maDriverVersion, &driverNumericVersion);
+        ParseDriverVersion("9.17.10.0", &knownSafeMismatchVersion);
+
+        // If there's a driver version mismatch, consider this harmful only when
+        // the driver version is less than knownSafeMismatchVersion.  See the
+        // above comment about crashes with old mismatches. If the GetDllVersion
+        // call fails, then they return 0, so that will be considered a mismatch.
+        if (dllNumericVersion != driverNumericVersion &&
+                dllNumericVersion2 != driverNumericVersion &&
+                (driverNumericVersion < knownSafeMismatchVersion ||
+                 std::max(dllNumericVersion, dllNumericVersion2) < knownSafeMismatchVersion)) {
+            mbHasDriverVersionMismatch = true;
+        }
+    }
+}
+
+
+
+// Macro for assigning a device vendor id to a string.
+#define DECLARE_VENDOR_ID(name, deviceId) \
+    case name: \
+        *mpDeviceVendors[id] = OUString(deviceId); \
+break;
+
+OUString WinOpenGLDeviceInfo::GetDeviceVendor(wgl::DeviceVendor id)
+{
+    assert(id >= 0 && id < wgl::DeviceVendorMax);
+
+    if (mpDeviceVendors[id])
+        return *mpDeviceVendors[id];
+
+    mpDeviceVendors[id] = new OUString();
+
+    switch (id) {
+        DECLARE_VENDOR_ID(wgl::VendorAll, "");
+        DECLARE_VENDOR_ID(wgl::VendorIntel, "0x8086");
+        DECLARE_VENDOR_ID(wgl::VendorNVIDIA, "0x10de");
+        DECLARE_VENDOR_ID(wgl::VendorAMD, "0x1022");
+        DECLARE_VENDOR_ID(wgl::VendorATI, "0x1002");
+        DECLARE_VENDOR_ID(wgl::VendorMicrosoft, "0x1414");
+        // Suppress a warning.
+        DECLARE_VENDOR_ID(wgl::DeviceVendorMax, "");
+    }
+
+    return *mpDeviceVendors[id];
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index df8b6d8..d37fc7c 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -24,6 +24,8 @@
 
 #if defined UNX && !defined MACOSX && !defined IOS && !defined ANDROID
 #include "opengl/x11/X11DeviceInfo.hxx"
+#elif defined (_WIN32)
+#include "opengl/win/WinDeviceInfo.hxx"
 #endif
 
 namespace {
@@ -374,6 +376,9 @@ bool OpenGLHelper::isDeviceBlacklisted()
         X11OpenGLDeviceInfo aInfo;
         bBlacklisted = aInfo.isDeviceBlocked();
         SAL_INFO("vcl.opengl", "blacklisted: " << bBlacklisted);
+#elif defined( _WIN32 )
+        WinOpenGLDeviceInfo aInfo;
+        bBlacklisted = aInfo.isDeviceBlocked();
 #else
         bBlacklisted = false;
 #endif


More information about the Libreoffice-commits mailing list