[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - 52 commits - desktop/Library_sofficeapp.mk desktop/unx include/vcl svx/Executable_gengal.mk sw/Executable_tiledrendering.mk vcl/CppunitTest_vcl_outdev.mk vcl/Executable_icontest.mk vcl/Executable_ui-previewer.mk vcl/Executable_vcldemo.mk vcl/generic vcl/headless vcl/inc vcl/Library_vcl.mk vcl/Library_vclplug_gen.mk vcl/Module_vcl.mk vcl/opengl vcl/Package_opengl.mk vcl/qa vcl/quartz vcl/source vcl/StaticLibrary_glxtest.mk vcl/unx vcl/win vcl/workben

Markus Mohrhard markus.mohrhard at googlemail.com
Tue Dec 2 06:49:39 PST 2014


 desktop/Library_sofficeapp.mk                    |    4 
 desktop/unx/source/glxtest.cxx                   |  282 -----
 include/vcl/opengl/OpenGLContext.hxx             |   56 +
 include/vcl/opengl/glxtest.hxx                   |    2 
 include/vcl/outdev.hxx                           |    4 
 include/vcl/salgtype.hxx                         |    8 
 svx/Executable_gengal.mk                         |    7 
 sw/Executable_tiledrendering.mk                  |   16 
 vcl/CppunitTest_vcl_outdev.mk                    |   52 +
 vcl/Executable_icontest.mk                       |    9 
 vcl/Executable_ui-previewer.mk                   |   15 
 vcl/Executable_vcldemo.mk                        |   15 
 vcl/Library_vcl.mk                               |    4 
 vcl/Library_vclplug_gen.mk                       |    1 
 vcl/Module_vcl.mk                                |    2 
 vcl/Package_opengl.mk                            |    7 
 vcl/StaticLibrary_glxtest.mk                     |   45 
 vcl/generic/print/genpspgraphics.cxx             |   10 
 vcl/headless/svpgdi.cxx                          |   10 
 vcl/headless/svpvd.cxx                           |   12 
 vcl/inc/generic/genpspgraphics.h                 |    6 
 vcl/inc/headless/svpgdi.hxx                      |    5 
 vcl/inc/headless/svpvd.hxx                       |    5 
 vcl/inc/opengl/framebuffer.hxx                   |   45 
 vcl/inc/opengl/program.hxx                       |   71 +
 vcl/inc/opengl/salbmp.hxx                        |   12 
 vcl/inc/opengl/texture.hxx                       |    4 
 vcl/inc/opengl/win/WinDeviceInfo.hxx             |  190 +++
 vcl/inc/opengl/win/gdiimpl.hxx                   |   10 
 vcl/inc/opengl/x11/gdiimpl.hxx                   |   11 
 vcl/inc/opengl/x11/salvd.hxx                     |   56 +
 vcl/inc/openglgdiimpl.hxx                        |  110 +-
 vcl/inc/quartz/salgdi.h                          |    8 
 vcl/inc/quartz/salvd.h                           |    1 
 vcl/inc/regionband.hxx                           |    2 
 vcl/inc/salframe.hxx                             |    9 
 vcl/inc/salgdi.hxx                               |   24 
 vcl/inc/salgdiimpl.hxx                           |   12 
 vcl/inc/salgeom.hxx                              |   12 
 vcl/inc/salvd.hxx                                |    8 
 vcl/inc/svdata.hxx                               |    5 
 vcl/inc/unx/gtk/gtkgdi.hxx                       |   14 
 vcl/inc/unx/salbmp.h                             |    2 
 vcl/inc/unx/salgdi.h                             |   16 
 vcl/inc/unx/salvd.h                              |   24 
 vcl/inc/unx/x11/x11gdiimpl.h                     |    3 
 vcl/inc/win/salgdi.h                             |   13 
 vcl/inc/win/salvd.h                              |    7 
 vcl/opengl/blendedTextureFragmentShader.glsl     |   27 
 vcl/opengl/blendedTextureVertexShader.glsl       |   22 
 vcl/opengl/diffTextureFragmentShader.glsl        |   26 
 vcl/opengl/dumbVertexShader.glsl                 |   16 
 vcl/opengl/framebuffer.cxx                       |   70 +
 vcl/opengl/gdiimpl.cxx                           |  984 +++++++-------------
 vcl/opengl/maskVertexShader.glsl                 |   19 
 vcl/opengl/maskedTextureVertexShader.glsl        |   19 
 vcl/opengl/program.cxx                           |  237 ++++
 vcl/opengl/salbmp.cxx                            |   24 
 vcl/opengl/scale.cxx                             |  125 --
 vcl/opengl/solidVertexShader.glsl                |   16 
 vcl/opengl/texture.cxx                           |   39 
 vcl/opengl/win/WinDeviceInfo.cxx                 | 1126 +++++++++++++++++++++++
 vcl/opengl/win/gdiimpl.cxx                       |   58 -
 vcl/opengl/x11/X11DeviceInfo.cxx                 |    5 
 vcl/opengl/x11/gdiimpl.cxx                       |  145 +-
 vcl/opengl/x11/salvd.cxx                         |   97 +
 vcl/qa/cppunit/outdev.cxx                        |   82 +
 vcl/quartz/salbmp.cxx                            |    6 
 vcl/quartz/salgdicommon.cxx                      |   14 
 vcl/quartz/salvd.cxx                             |   16 
 vcl/source/gdi/regionband.cxx                    |    2 
 vcl/source/gdi/salgdilayout.cxx                  |   32 
 vcl/source/gdi/virdev.cxx                        |   17 
 vcl/source/opengl/OpenGLContext.cxx              |  193 +++
 vcl/source/opengl/OpenGLHelper.cxx               |   18 
 vcl/source/outdev/bitmap.cxx                     |   85 -
 vcl/source/outdev/gradient.cxx                   |   19 
 vcl/source/outdev/mask.cxx                       |   14 
 vcl/source/outdev/outdev.cxx                     |   54 -
 vcl/source/salmain/salmain.cxx                   |    7 
 vcl/source/window/window.cxx                     |   11 
 vcl/unx/generic/gdi/gdiimpl.cxx                  |   40 
 vcl/unx/generic/gdi/gdiimpl.hxx                  |   14 
 vcl/unx/generic/gdi/openglx11cairotextrender.cxx |   31 
 vcl/unx/generic/gdi/salbmp.cxx                   |    8 
 vcl/unx/generic/gdi/salgdi.cxx                   |   22 
 vcl/unx/generic/gdi/salgdi2.cxx                  |   27 
 vcl/unx/generic/gdi/salvd.cxx                    |  157 +--
 vcl/unx/generic/gdi/x11cairotextrender.cxx       |   36 
 vcl/unx/generic/window/salframe.cxx              |    9 
 vcl/unx/glxtest.cxx                              |  280 +++++
 vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx         |  685 ++++++++-----
 vcl/unx/kde/salnativewidgets-kde.cxx             |    2 
 vcl/win/source/gdi/gdiimpl.cxx                   |   20 
 vcl/win/source/gdi/gdiimpl.hxx                   |   12 
 vcl/win/source/gdi/salbmp.cxx                    |   20 
 vcl/win/source/gdi/salgdi.cxx                    |   15 
 vcl/win/source/gdi/salgdi_gdiplus.cxx            |   16 
 vcl/win/source/gdi/salnativewidgets-luna.cxx     |    2 
 vcl/win/source/gdi/salprn.cxx                    |    2 
 vcl/win/source/gdi/salvd.cxx                     |   26 
 vcl/win/source/window/salframe.cxx               |    4 
 vcl/workben/vcldemo.cxx                          |   66 +
 103 files changed, 4412 insertions(+), 1953 deletions(-)

New commits:
commit 214ab2c15e1fcdd0b1d6fa32ee0e101fb53a988c
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Tue Dec 2 00:47:10 2014 +0100

    request a stencil on windows
    
    Change-Id: Ib8f337d80c5576380344893c49c4fa0284f1dc4b

diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 8a04cc2..2160c6e 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -850,7 +850,7 @@ bool OpenGLContext::ImplInit()
         0,                              // No Accumulation Buffer
         0, 0, 0, 0,                     // Accumulation Bits Ignored
         64,                             // 32 bit Z-BUFFER
-        0,                              // 0 bit stencil buffer
+        8,                              // stencil buffer
         0,                              // No Auxiliary Buffer
         0,                              // now ignored
         0,                              // Reserved
commit dcf988aca5e7f19f995b9e4d1c6fd799bc304da7
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Mon Dec 1 01:18:25 2014 +0100

    introduce SAL_FORCEGL and document the variables
    
    SAL_FORCEGL can force OpenGL even if the driver is blacklisted.
    
    Change-Id: Idc763d81fef6dbdf915154995205fbf2b1f060b4

diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index daee089..3c08c03 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -401,6 +401,17 @@ bool OpenGLHelper::supportsVCLOpenGL()
 
 bool OpenGLHelper::isVCLOpenGLEnabled()
 {
+    /*
+     * There are a number of cases that these environment variables cover:
+     *  * SAL_FORCEGL forces OpenGL independent of any other option
+     *  * SAL_DISABLEGL or a blacklisted driver avoid the use of OpenGL if SAL_FORCEGL is not set
+     *  * SAL_ENABLEGL overrides VCL_HIDE_WINDOWS and the configuration variable
+     *  * the configuration variable is checked if no environment variable is set
+     */
+    static bool bForceOpenGL = !!getenv("SAL_FORCEGL");
+    if (bForceOpenGL)
+        return true;
+
     if (!supportsVCLOpenGL())
         return false;
 
@@ -411,7 +422,6 @@ bool OpenGLHelper::isVCLOpenGLEnabled()
     static bool bDuringBuild = getenv("VCL_HIDE_WINDOWS");
     if (bDuringBuild && !bEnable /* env. enable overrides */)
         bEnable = false;
-
     else if (officecfg::Office::Common::VCL::UseOpenGL::get())
         bEnable = true;
 
commit 5d879e4a174054f3aa103b933e940b6bbd1c5076
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sun Nov 30 21:01:35 2014 +0100

    whitelist some drivers
    
    Especially the ones from our developer machines as they are better tested than anything else.
    
    Change-Id: Id6ff6bcae314c03453d82ee4e64aaef1bd5ed84a

diff --git a/vcl/inc/opengl/win/WinDeviceInfo.hxx b/vcl/inc/opengl/win/WinDeviceInfo.hxx
index 9abddd0..21f14d9 100644
--- a/vcl/inc/opengl/win/WinDeviceInfo.hxx
+++ b/vcl/inc/opengl/win/WinDeviceInfo.hxx
@@ -82,7 +82,7 @@ struct DriverInfo
 
     DriverInfo(OperatingSystem os, const OUString& vendor, DeviceFamilyVector* devices,
             VersionComparisonOp op,
-            uint64_t driverVersion, const char *suggestedVersion = nullptr,
+            uint64_t driverVersion, bool bWhiteListed = false, const char *suggestedVersion = nullptr,
             bool ownDevices = false);
 
     DriverInfo();
@@ -101,6 +101,8 @@ struct DriverInfo
     // deallocated. False by default.
     bool mbDeleteDevices;
 
+    bool mbWhitelisted;
+
     VersionComparisonOp meComparisonOp;
 
     /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
diff --git a/vcl/opengl/win/WinDeviceInfo.cxx b/vcl/opengl/win/WinDeviceInfo.cxx
index c9bf1ff..824d0fc 100644
--- a/vcl/opengl/win/WinDeviceInfo.cxx
+++ b/vcl/opengl/win/WinDeviceInfo.cxx
@@ -12,22 +12,25 @@
 #include <windows.h>
 #include <setupapi.h>
 #include <cstdint>
-#include <rtl/ustrbuf.hxx>
 
 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))
+    maDriverInfo.push_back(wgl::DriverInfo(os, vendor, devices, driverComparator, driverVersion, false, 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_WHITELIST(os, vendor, devices, driverComparator, driverVersion) \
+    maDriverInfo.push_back(wgl::DriverInfo(os, vendor, devices, driverComparator, driverVersion, true))
+
 #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); \
+        wgl::DriverInfo info(os, vendor, devices, driverComparator, driverVersion, false, suggestedVersion); \
         info.mnDriverVersionMax = driverVersionMax; \
         maDriverInfo.push_back(info); \
     } while (false)
@@ -373,6 +376,7 @@ DriverInfo::DriverInfo()
     maAdapterVendor(WinOpenGLDeviceInfo::GetDeviceVendor(VendorAll)),
     mpDevices(allDevices),
     mbDeleteDevices(false),
+    mbWhitelisted(false),
     meComparisonOp(DRIVER_COMPARISON_IGNORED),
     mnDriverVersion(0),
     mnDriverVersionMax(0)
@@ -382,6 +386,7 @@ DriverInfo::DriverInfo(OperatingSystem os, const OUString& vendor,
         DeviceFamilyVector* devices,
         VersionComparisonOp op,
         uint64_t driverVersion,
+        bool bWhitelisted,
         const char *suggestedVersion /* = nullptr */,
         bool ownDevices /* = false */)
     : meOperatingSystem(os),
@@ -389,6 +394,7 @@ DriverInfo::DriverInfo(OperatingSystem os, const OUString& vendor,
     maAdapterVendor(vendor),
     mpDevices(devices),
     mbDeleteDevices(ownDevices),
+    mbWhitelisted(bWhitelisted),
     meComparisonOp(op),
     mnDriverVersion(driverVersion),
     mnDriverVersionMax(0)
@@ -401,6 +407,7 @@ DriverInfo::DriverInfo(const DriverInfo& aOrig)
     : meOperatingSystem(aOrig.meOperatingSystem),
     mnOperatingSystemVersion(aOrig.mnOperatingSystemVersion),
     maAdapterVendor(aOrig.maAdapterVendor),
+    mbWhitelisted(aOrig.mbWhitelisted),
     meComparisonOp(aOrig.meComparisonOp),
     mnDriverVersion(aOrig.mnDriverVersion),
     mnDriverVersionMax(aOrig.mnDriverVersionMax)
@@ -657,6 +664,13 @@ bool WinOpenGLDeviceInfo::FindBlocklistedDeviceInList()
         }
 
         if (match || maDriverInfo[i].mnDriverVersion == wgl::DriverInfo::allDriverVersions) {
+            // white listed drivers
+            if (maDriverInfo[i].mbWhitelisted)
+            {
+                SAL_WARN("vcl.opengl", "whitelisted driver");
+                return false;
+            }
+
             match = true;
             SAL_WARN("vcl.opengl", "use : " << maDriverInfo[i].maSuggestedVersion);
             break;
@@ -980,6 +994,12 @@ OUString WinOpenGLDeviceInfo::GetDeviceVendor(wgl::DeviceVendor id)
 void WinOpenGLDeviceInfo::FillBlacklist()
 {
     /*
+     * Implement whitelist entries first as they will be used first to stop early;
+     */
+
+    APPEND_TO_DRIVER_WHITELIST( wgl::DRIVER_OS_WINDOWS_7, GetDeviceVendor(wgl::VendorIntel),
+            wgl::DriverInfo::allDevices, wgl::DRIVER_EQUAL, wgl::V(10,18,10,3412));
+    /*
      * 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
commit a915cfcf5c200f521fe8f8724d57c18b5eb4ca6f
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sun Nov 30 21:00:31 2014 +0100

    block all RDP sessions from using OpenGL
    
    Normally you only get the Microsoft OpenGL 1.1 driver for RDP so it is save to just block it.
    
    Change-Id: Id9b3af23d56926b09316fbf8b873e271060d2c6a

diff --git a/vcl/opengl/win/WinDeviceInfo.cxx b/vcl/opengl/win/WinDeviceInfo.cxx
index 41f1a2b..c9bf1ff 100644
--- a/vcl/opengl/win/WinDeviceInfo.cxx
+++ b/vcl/opengl/win/WinDeviceInfo.cxx
@@ -682,6 +682,12 @@ bool WinOpenGLDeviceInfo::isDeviceBlocked()
     // 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).
 
+    if (mbRDP)
+    {
+        SAL_WARN("vcl.opengl", "all OpenGL blocked for RDP sessions");
+        return true;
+    }
+
     return FindBlocklistedDeviceInList();
 }
 
commit 1ac0c5ef3f63e864cc018564a3057a7d26c85146
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 f8c86e3..41f1a2b 100644
--- a/vcl/opengl/win/WinDeviceInfo.cxx
+++ b/vcl/opengl/win/WinDeviceInfo.cxx
@@ -344,6 +344,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;
@@ -573,6 +574,7 @@ WinOpenGLDeviceInfo::WinOpenGLDeviceInfo():
     mbRDP(false)
 {
     GetData();
+    FillBlacklist();
 }
 
 WinOpenGLDeviceInfo::~WinOpenGLDeviceInfo()
@@ -617,36 +619,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;
@@ -654,11 +655,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 8c377eab73c9a6d09fb7b05fd5639369ee86dc99
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 2c478ee..9abddd0 100644
--- a/vcl/inc/opengl/win/WinDeviceInfo.hxx
+++ b/vcl/inc/opengl/win/WinDeviceInfo.hxx
@@ -111,7 +111,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) \
@@ -169,6 +169,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 bab420c..f8c86e3 100644
--- a/vcl/opengl/win/WinDeviceInfo.cxx
+++ b/vcl/opengl/win/WinDeviceInfo.cxx
@@ -88,7 +88,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) \
@@ -202,6 +203,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;
@@ -322,7 +346,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)
@@ -367,7 +391,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),
@@ -552,6 +579,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);
@@ -562,7 +680,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 ea4394c57d43bf3eea797faccb52a89370b47300
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 db91687..2c478ee 100644
--- a/vcl/inc/opengl/win/WinDeviceInfo.hxx
+++ b/vcl/inc/opengl/win/WinDeviceInfo.hxx
@@ -73,6 +73,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
@@ -107,12 +168,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 21ea19f..bab420c 100644
--- a/vcl/opengl/win/WinDeviceInfo.cxx
+++ b/vcl/opengl/win/WinDeviceInfo.cxx
@@ -15,6 +15,22 @@
 #include <rtl/ustrbuf.hxx>
 
 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 {
 
@@ -319,6 +335,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),
@@ -630,5 +851,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 914915ac6d23373500ee584edeaaabc00fdd6aea
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sun Nov 23 01:39:02 2014 +0100

    block my OpenGL driver
    
    Kendy and I both ahve the same issue related to the driver returning the
    wrong attribute location in some shaders
    
    Change-Id: I496c0f545f7c28c71a94ca8a9ff9fb0b0df46005

diff --git a/vcl/opengl/x11/X11DeviceInfo.cxx b/vcl/opengl/x11/X11DeviceInfo.cxx
index cf04d43..c678d4a 100644
--- a/vcl/opengl/x11/X11DeviceInfo.cxx
+++ b/vcl/opengl/x11/X11DeviceInfo.cxx
@@ -281,6 +281,11 @@ bool X11OpenGLDeviceInfo::isDeviceBlocked()
             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;
commit 1d7c80e01429125b0f9f55d130203a8326207e1d
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Nov 22 16:55:44 2014 +0100

    fix glx resource leak
    
    Change-Id: I013676d2f4caa0479c917a7f833966be8f0b8009

diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 17c2c69..8a04cc2 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -116,8 +116,8 @@ OpenGLContext::~OpenGLContext()
         }
         glXDestroyContext(m_aGLWin.dpy, m_aGLWin.ctx);
 
-        if (mbPixmap)
-            glXDestroyGLXPixmap(m_aGLWin.dpy, m_aGLWin.glPix);
+        if (mbPixmap && m_aGLWin.glPix != None)
+            glXDestroyPixmap(m_aGLWin.dpy, m_aGLWin.glPix);
     }
 #endif
 }
@@ -658,6 +658,12 @@ void OpenGLContext::resetToReInitialize()
     if( !mbInitialized )
         return;
     resetCurrent();
+
+    if (mbPixmap)
+    {
+        glXDestroyPixmap(m_aGLWin.dpy, m_aGLWin.glPix);
+        m_aGLWin.glPix = None;
+    }
     mbInitialized = false;
 }
 
commit f6cda7d91f3c2f3dce9c71eb4263c83a0a6d7e48
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Fri Nov 21 12:45:51 2014 +0100

    make glxtest available in salmain
    
    Change-Id: Ic8bc3f2d5d96506590d35138089ead2eac984314

diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk
index f322a6c..da37f9a 100644
--- a/desktop/Library_sofficeapp.mk
+++ b/desktop/Library_sofficeapp.mk
@@ -95,8 +95,8 @@ $(eval $(call gb_Library_add_exception_objects,sofficeapp,\
 ))
 
 ifeq ($(OS),LINUX)
-$(eval $(call gb_Library_add_exception_objects,sofficeapp,\
-    desktop/unx/source/glxtest \
+$(eval $(call gb_Library_use_static_libraries,sofficeapp,\
+    glxtest \
 ))
 
 $(eval $(call gb_Library_add_libs,sofficeapp,\
diff --git a/include/vcl/opengl/glxtest.hxx b/include/vcl/opengl/glxtest.hxx
index 0889cdd..687038f 100644
--- a/include/vcl/opengl/glxtest.hxx
+++ b/include/vcl/opengl/glxtest.hxx
@@ -16,6 +16,8 @@ VCL_DLLPUBLIC int* getGlxPipe();
 
 VCL_DLLPUBLIC pid_t* getGlxPid();
 
+bool fire_glxtest_process();
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/Executable_gengal.mk b/svx/Executable_gengal.mk
index 55cc2f1..17a57dc 100644
--- a/svx/Executable_gengal.mk
+++ b/svx/Executable_gengal.mk
@@ -65,6 +65,13 @@ ifeq ($(OS),LINUX)
 $(eval $(call gb_Executable_add_libs,gengal,\
 	-ldl \
 	-lpthread \
+    -lGL \
+    -lGLU \
+    -lX11 \
+))
+
+$(eval $(call gb_Executable_use_static_libraries,gengal,\
+	glxtest \
 ))
 endif
 
diff --git a/sw/Executable_tiledrendering.mk b/sw/Executable_tiledrendering.mk
index 089b0f5..f5664da 100644
--- a/sw/Executable_tiledrendering.mk
+++ b/sw/Executable_tiledrendering.mk
@@ -42,4 +42,20 @@ $(eval $(call gb_Executable_add_exception_objects,tiledrendering,\
     sw/qa/tiledrendering/tiledrendering \
 ))
 
+ifeq ($(OS),LINUX)
+
+$(eval $(call gb_Executable_add_libs,tiledrendering,\
+	-lm \
+	-ldl \
+	-lpthread \
+    -lGL \
+    -lGLU \
+    -lX11 \
+))
+
+$(eval $(call gb_Executable_use_static_libraries,tiledrendering,\
+	glxtest \
+))
+endif
+
 # vim: set noet sw=4 ts=4:
diff --git a/vcl/Executable_icontest.mk b/vcl/Executable_icontest.mk
index d7962d8..00dc906 100644
--- a/vcl/Executable_icontest.mk
+++ b/vcl/Executable_icontest.mk
@@ -24,7 +24,16 @@ $(eval $(call gb_Executable_use_api,icontest,\
 ifeq ($(OS),LINUX)
 
 $(eval $(call gb_Executable_add_libs,icontest,\
+	-lm \
+	-ldl \
+	-lpthread \
     -lGL \
+    -lGLU \
+    -lX11 \
+))
+
+$(eval $(call gb_Executable_use_static_libraries,icontest,\
+	glxtest \
 ))
 
 else ifeq ($(OS),WNT)
diff --git a/vcl/Executable_ui-previewer.mk b/vcl/Executable_ui-previewer.mk
index 444ded1..665f683 100644
--- a/vcl/Executable_ui-previewer.mk
+++ b/vcl/Executable_ui-previewer.mk
@@ -34,4 +34,19 @@ $(eval $(call gb_Executable_add_exception_objects,ui-previewer,\
     vcl/source/uipreviewer/previewer \
 ))
 
+ifeq ($(OS),LINUX)
+$(eval $(call gb_Executable_add_libs,ui-previewer,\
+	-lm \
+	-ldl \
+	-lpthread \
+    -lGL \
+    -lGLU \
+    -lX11 \
+))
+
+$(eval $(call gb_Executable_use_static_libraries,ui-previewer,\
+	glxtest \
+))
+endif
+
 # vim: set noet sw=4 ts=4:
diff --git a/vcl/Executable_vcldemo.mk b/vcl/Executable_vcldemo.mk
index 721605f..44f13b2 100644
--- a/vcl/Executable_vcldemo.mk
+++ b/vcl/Executable_vcldemo.mk
@@ -41,4 +41,19 @@ $(eval $(call gb_Executable_use_static_libraries,vcldemo,\
     vclmain \
 ))
 
+ifeq ($(OS),LINUX)
+$(eval $(call gb_Executable_add_libs,vcldemo,\
+	-lm \
+	-ldl \
+	-lpthread \
+    -lGL \
+    -lGLU \
+    -lX11 \
+))
+
+$(eval $(call gb_Executable_use_static_libraries,vcldemo,\
+	glxtest \
+))
+endif
+
 # vim: set noet sw=4 ts=4:
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index 655aadb..329740a 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -47,6 +47,7 @@ $(eval $(call gb_Module_add_targets,vcl,\
     Library_vclplug_gen \
     Library_desktop_detector \
     StaticLibrary_headless \
+	StaticLibrary_glxtest \
     Package_fontunxppds \
     Package_fontunxpsprint \
 ))
diff --git a/vcl/StaticLibrary_glxtest.mk b/vcl/StaticLibrary_glxtest.mk
new file mode 100644
index 0000000..1e28775
--- /dev/null
+++ b/vcl/StaticLibrary_glxtest.mk
@@ -0,0 +1,45 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+#   Licensed to the Apache Software Foundation (ASF) under one or more
+#   contributor license agreements. See the NOTICE file distributed
+#   with this work for additional information regarding copyright
+#   ownership. The ASF licenses this file to you under the Apache
+#   License, Version 2.0 (the "License"); you may not use this file
+#   except in compliance with the License. You may obtain a copy of
+#   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,glxtest))
+
+$(eval $(call gb_StaticLibrary_set_include,glxtest,\
+    $$(INCLUDE) \
+    -I$(SRCDIR)/vcl/inc \
+))
+
+$(eval $(call gb_StaticLibrary_use_api,glxtest,\
+    offapi \
+    udkapi \
+))
+
+$(eval $(call gb_StaticLibrary_add_libs,glxtest,\
+	-lm \
+	-ldl \
+	-lpthread \
+    -lGL \
+    -lGLU \
+    -lX11 \
+))
+
+$(eval $(call gb_StaticLibrary_add_exception_objects,glxtest,\
+    vcl/unx/glxtest \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/source/salmain/salmain.cxx b/vcl/source/salmain/salmain.cxx
index 7f0f90a..e7318e8 100644
--- a/vcl/source/salmain/salmain.cxx
+++ b/vcl/source/salmain/salmain.cxx
@@ -28,7 +28,14 @@
 
 #include "salinst.hxx"
 
+#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
+#include <vcl/opengl/glxtest.hxx>
+#endif
+
 SAL_IMPLEMENT_MAIN() {
+#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
+    fire_glxtest_process();
+#endif
     tools::extendApplicationEnvironment();
     vclmain::createApplication();
     return SVMain();
diff --git a/desktop/unx/source/glxtest.cxx b/vcl/unx/glxtest.cxx
similarity index 99%
rename from desktop/unx/source/glxtest.cxx
rename to vcl/unx/glxtest.cxx
index df9603a..d1f9591 100644
--- a/desktop/unx/source/glxtest.cxx
+++ b/vcl/unx/glxtest.cxx
@@ -5,8 +5,6 @@
  * 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 "app.hxx"
-
 //////////////////////////////////////////////////////////////////////////////
 //
 // Explanation: See bug 639842. Safely getting GL driver info on X11 is hard, because the only way to do
commit a1394adeee866bd9dc16691af7961b4aa02c4d0e
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue Dec 2 13:23:47 2014 +0200

    WaE: private field 'mnAttribIndex' is not used
    
    Change-Id: I939e184f6706fc0135f6906f0c183e5166aba5bb

diff --git a/vcl/inc/opengl/program.hxx b/vcl/inc/opengl/program.hxx
index 4b2b26f..2aeb2fd 100644
--- a/vcl/inc/opengl/program.hxx
+++ b/vcl/inc/opengl/program.hxx
@@ -29,7 +29,6 @@ private:
     GLuint          mnId;
     UniformCache    maUniformLocations;
     sal_uInt32      mnEnabledAttribs;
-    GLuint          mnAttribIndex;
     GLuint          mnPositionAttrib;
     GLuint          mnTexCoordAttrib;
     GLuint          mnAlphaCoordAttrib;
diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx
index c9542c7..320b06f 100644
--- a/vcl/opengl/program.cxx
+++ b/vcl/opengl/program.cxx
@@ -17,7 +17,6 @@
 OpenGLProgram::OpenGLProgram() :
     mnId( 0 ),
     mnEnabledAttribs( 0 ),
-    mnAttribIndex( 0 ),
     mnPositionAttrib( SAL_MAX_UINT32 ),
     mnTexCoordAttrib( SAL_MAX_UINT32 ),
     mnAlphaCoordAttrib( SAL_MAX_UINT32 ),
commit 5060b4485469525310980990ca8df7e82f68206d
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Tue Dec 2 06:54:27 2014 +0000

    vcl: use resetToReInitialize to avoid context problems on Windows.
    
    It appears that we have to do this for VirtualDevices, where we have
    freed / re-allocated the underlying resource, or we fail to switch the
    current context, and render to the wrong place, before blatting a
    blank texture over the top of it.
    
    Change-Id: I0253f216ea7dc9786374dc83ca38f4f6295e3035

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 462a479..46d72dc6 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -105,6 +105,15 @@ void OpenGLSalGraphicsImpl::Init()
         maOffscreenTex.GetHeight() != GetHeight() )
     {
         maOffscreenTex = OpenGLTexture();
+#if defined(WNT)
+        // URGH ... VirtualDevice may have destroyed the underlying resource
+        // our context is associated with - FIXME: can we do better here ?
+        if (mpContext)
+        {
+            mpContext->resetToReInitialize();
+            ReleaseContext();
+        }
+#endif
     }
 }
 
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index c02573d..17c2c69 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -622,6 +622,17 @@ bool OpenGLContext::init(SystemChildWindow* pChildWindow)
     return ImplInit();
 }
 
+#if defined( WNT )
+// FIXME share resetToReInitialize() across platforms...
+void OpenGLContext::resetToReInitialize()
+{
+    if( !mbInitialized )
+        return;
+    resetCurrent();
+    mbInitialized = false;
+}
+#endif
+
 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
 bool OpenGLContext::init(Display* dpy, Window win, int screen)
 {
commit 4642bb86dce6f5e820bf8921b731db1adf4d40c3
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Tue Dec 2 06:30:38 2014 +0000

    vcl: OpenGL texture creation debug.
    
    Change-Id: I6a21c89329d9e9396ed16ce58b184339719adab7

diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
index 0c45d77..cc5be78 100644
--- a/vcl/opengl/texture.cxx
+++ b/vcl/opengl/texture.cxx
@@ -41,6 +41,8 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, bool bAllocate )
         glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
     glBindTexture( GL_TEXTURE_2D, 0 );
 
+    SAL_INFO( "vcl.opengl", "OpenGLTexture " << mnTexture << " " << nWidth << "x" << nHeight << " allocate" );
+
     CHECK_GL_ERROR();
 }
 
@@ -65,6 +67,8 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nX, int nY, int nWidth, int nHeight )
     CHECK_GL_ERROR();
     glBindTexture( GL_TEXTURE_2D, 0 );
 
+    SAL_INFO( "vcl.opengl", "OpenGLTexture " << mnTexture << " " << nWidth << "x" << nHeight << " from x" << nX << ", y" << nY );
+
     CHECK_GL_ERROR();
 }
 
@@ -87,6 +91,8 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, int nFormat, int
     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, mnWidth, mnHeight, 0, nFormat, nType, pData );
     glBindTexture( GL_TEXTURE_2D, 0 );
 
+    SAL_INFO( "vcl.opengl", "OpenGLTexture " << mnTexture << " " << nWidth << "x" << nHeight << " from data" );
+
     CHECK_GL_ERROR();
 }
 
commit f4527d8f17285a139ef8aa626c50c3b492108af9
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Fri Nov 28 14:58:53 2014 -0500

    vcl: Fix a coordinate issue when getting a bitmap from a VirtualDevice
    
    Change-Id: I06fef2765f2dc9d64a991385a984a4c75a1fd424

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 4d362b1..462a479 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -1113,8 +1113,8 @@ SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long nX, long nY, long nWidth, long
     OpenGLSalBitmap* pBitmap = new OpenGLSalBitmap;
     SAL_INFO( "vcl.opengl", "::getBitmap " << nX << "," << nY <<
               " " << nWidth << "x" << nHeight );
+    //TODO really needed?
     PreDraw();
-    nY = GetHeight() - nHeight - nY;
     if( !pBitmap->Create( maOffscreenTex, nX, nY, nWidth, nHeight ) )
     {
         delete pBitmap;
@@ -1129,6 +1129,7 @@ SalColor OpenGLSalGraphicsImpl::getPixel( long nX, long nY )
     char pixel[3] = { 0, 0, 0 };
 
     PreDraw();
+    nY = GetHeight() - nY;
     glReadPixels( nX, nY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
     PostDraw();
 
diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
index 7618c04..0c45d77 100644
--- a/vcl/opengl/texture.cxx
+++ b/vcl/opengl/texture.cxx
@@ -52,6 +52,9 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nX, int nY, int nWidth, int nHeight )
     mnHeight( nHeight ),
     mnFilter( GL_NEAREST )
 {
+    // FIXME We need the window height here
+    // nY = GetHeight() - nHeight - nY;
+
     glGenTextures( 1, &mnTexture );
     glBindTexture( GL_TEXTURE_2D, mnTexture );
     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
commit 5933c72dd39d597037528f8473fa2bf67e59a757
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Fri Nov 28 14:56:08 2014 -0500

    vcl: Only load OpenGL shaders once for each context
    
    Change-Id: Idbf9026c5e64ef41d4c913153dfddf36923ff7de

diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index 6d99488..843821d 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -51,11 +51,13 @@ class NSOpenGLView;
 
 #include <vcl/vclopengl_dllapi.hxx>
 #include <boost/scoped_ptr.hpp>
+#include <boost/unordered_map.hpp>
 #include <vcl/window.hxx>
 #include <tools/gen.hxx>
 #include <vcl/syschild.hxx>
 
 class OpenGLFramebuffer;
+class OpenGLProgram;
 class OpenGLTexture;
 
 /// Holds the information of our new child window
@@ -156,6 +158,31 @@ struct GLWindow
     ~GLWindow();
 };
 
+struct ProgramKey
+{
+    OUString maVertexShader;
+    OUString maFragmentShader;
+
+    ProgramKey( const OUString& rVertexShader, const OUString& rFragmentShader )
+    {
+        maVertexShader = rVertexShader;
+        maFragmentShader = rFragmentShader;
+    }
+};
+
+inline bool operator==( ProgramKey const& k1, ProgramKey const& k2 )
+{
+    return k1.maVertexShader == k2.maVertexShader && k1.maFragmentShader == k2.maFragmentShader;
+}
+
+inline std::size_t hash_value( ProgramKey const& rKey )
+{
+    std::size_t nSeed = 0x9e3779b9;
+    nSeed = rKey.maVertexShader.hashCode();
+    nSeed = rKey.maFragmentShader.hashCode() + 0x9e3779b9 + (nSeed << 6) + (nSeed >> 2);
+    return nSeed;
+}
+
 class VCLOPENGL_DLLPUBLIC OpenGLContext
 {
 public:
@@ -185,6 +212,10 @@ public:
     OpenGLFramebuffer* AcquireFramebuffer( const OpenGLTexture& rTexture );
     void               ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer );
 
+    // retrieve a program from the cache or compile/link it
+    OpenGLProgram*      GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader );
+    OpenGLProgram*      UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader );
+
     void makeCurrent();
     void resetCurrent();
     void swapBuffers();
@@ -241,6 +272,9 @@ private:
     OpenGLFramebuffer* mpFirstFramebuffer;
     OpenGLFramebuffer* mpLastFramebuffer;
 
+    boost::unordered_map<ProgramKey, OpenGLProgram*> maPrograms;
+    OpenGLProgram* mpCurrentProgram;
+
 public:
     vcl::Region maClipRegion;
     int mnPainting;
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index a7b901f..ccf3ddb 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -127,6 +127,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
 	vcl/opengl/salbmp \
 	vcl/opengl/scale \
 	vcl/opengl/framebuffer \
+	vcl/opengl/program \
 	vcl/opengl/texture \
     vcl/source/opengl/OpenGLContext \
     vcl/source/opengl/OpenGLHelper \
diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk
index d81c0ec..98ff78b 100644
--- a/vcl/Package_opengl.mk
+++ b/vcl/Package_opengl.mk
@@ -12,16 +12,14 @@ $(eval $(call gb_Package_Package,vcl_opengl_shader,$(SRCDIR)/vcl/opengl))
 $(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
 	blendedTextureFragmentShader.glsl \
 	blendedTextureVertexShader.glsl \
+	dumbVertexShader.glsl \
 	diffTextureFragmentShader.glsl \
 	convolutionFragmentShader.glsl \
 	linearGradientFragmentShader.glsl \
 	maskFragmentShader.glsl \
-	maskVertexShader.glsl \
 	maskedTextureFragmentShader.glsl \
-	maskedTextureVertexShader.glsl \
 	radialGradientFragmentShader.glsl \
 	solidFragmentShader.glsl \
-	solidVertexShader.glsl \
 	textureFragmentShader.glsl \
 	textureVertexShader.glsl \
 	transformedTextureVertexShader.glsl \
diff --git a/vcl/inc/opengl/program.hxx b/vcl/inc/opengl/program.hxx
new file mode 100644
index 0000000..4b2b26f
--- /dev/null
+++ b/vcl/inc/opengl/program.hxx
@@ -0,0 +1,72 @@
+/* -*- 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_INC_OPENGL_PROGRAM_H
+#define INCLUDED_VCL_INC_OPENGL_PROGRAM_H
+
+#include <GL/glew.h>
+#include <vcl/dllapi.h>
+
+#include <basegfx/point/b2dpoint.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/color.hxx>
+#include <opengl/texture.hxx>
+
+#include <boost/unordered_map.hpp>
+
+typedef boost::unordered_map< OString, GLuint, OStringHash > UniformCache;
+typedef std::list< OpenGLTexture > TextureList;
+
+class VCL_PLUGIN_PUBLIC OpenGLProgram
+{
+private:
+    GLuint          mnId;
+    UniformCache    maUniformLocations;
+    sal_uInt32      mnEnabledAttribs;
+    GLuint          mnAttribIndex;
+    GLuint          mnPositionAttrib;
+    GLuint          mnTexCoordAttrib;
+    GLuint          mnAlphaCoordAttrib;
+    TextureList     maTextures;
+    bool            mbBlending;
+
+public:
+    OpenGLProgram();
+    ~OpenGLProgram();
+
+    bool Load( const OUString& rVertexShader, const OUString& rFragmentShader );
+    bool Use();
+    bool Clean();
+
+    void SetVertices( const GLvoid* pData );
+    void SetTextureCoord( const GLvoid* pData );
+    void SetAlphaCoord( const GLvoid* pData );
+
+    void SetUniform2f( const OString& rName, GLfloat v1, GLfloat v2 );
+    void SetUniform1fv( const OString& rName, GLsizei nCount, GLfloat* aValues );
+    void SetUniform2fv( const OString& rName, GLsizei nCount, GLfloat* aValues );
+    void SetColor( const OString& rName, SalColor nColor, sal_uInt8 nTransparency );
+    void SetColorf( const OString& rName, SalColor nColor, double fTransparency );
+    void SetColorWithIntensity( const OString& rName, const Color& rColor, long nFactor );
+    void SetTexture( const OString& rName, OpenGLTexture& rTexture );
+    void SetTransform( const OString& rName, const OpenGLTexture& rTexture,
+                       const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX,
+                       const basegfx::B2DPoint& rY );
+    void SetBlendMode( GLenum nSFactor, GLenum nDFactor );
+
+    bool DrawTexture( OpenGLTexture& rTexture );
+
+protected:
+    void SetVertexAttrib( GLuint& rAttrib, const OString& rName, const GLvoid* pData );
+    GLuint GetUniformLocation( const OString& rName );
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_PROGRAM_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx
index bc232b1..6938a22 100644
--- a/vcl/inc/opengl/salbmp.hxx
+++ b/vcl/inc/opengl/salbmp.hxx
@@ -99,17 +99,6 @@ private:
 
 private:
 
-    GLuint          ImplGetTextureProgram();
-    GLuint          mnTexProgram;
-    GLuint          mnTexSamplerUniform;
-
-    GLuint          ImplGetConvolutionProgram();
-    GLuint          mnConvProgram;
-    GLuint          mnConvSamplerUniform;
-    GLuint          mnConvKernelUniform;
-    GLuint          mnConvKernelSizeUniform;
-    GLuint          mnConvOffsetsUniform;
-
     bool ImplScaleFilter( const double& rScaleX, const double& rScaleY, GLenum nFilter );
     void ImplCreateKernel( const double& fScale, const Kernel& rKernel, GLfloat*& pWeights, sal_uInt32& aKernelSize );
     bool ImplScaleConvolution( const double& rScaleX, const double& rScaleY, const Kernel& aKernel );
diff --git a/vcl/inc/opengl/texture.hxx b/vcl/inc/opengl/texture.hxx
index ad4738a..3d99526 100644
--- a/vcl/inc/opengl/texture.hxx
+++ b/vcl/inc/opengl/texture.hxx
@@ -65,6 +65,7 @@ public:
     int             GetWidth() const;
     int             GetHeight() const;
     void            GetCoord( GLfloat* pCoord, const SalTwoRect& rPosAry, bool bInverted=false ) const;
+    void            GetWholeCoord( GLfloat* pCoord ) const;
 
     void            Bind();
     void            Unbind();
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 39e39fc..3f3ef4e 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -25,6 +25,7 @@
 #include <vcl/dllapi.h>
 
 #include "opengl/framebuffer.hxx"
+#include "opengl/program.hxx"
 #include "opengl/texture.hxx"
 #include "regionband.hxx"
 
@@ -44,6 +45,7 @@ protected:
     /// Pointer to the SalFrame or SalVirtualDevice
     SalGeometryProvider* mpParent;
     OpenGLFramebuffer* mpFramebuffer;
+    OpenGLProgram* mpProgram;
 
     // clipping
     vcl::Region maClipRegion;
@@ -56,72 +58,17 @@ protected:
     SalColor mnLineColor;
     SalColor mnFillColor;
 
-    GLuint mnSolidProgram;
-    GLuint mnColorUniform;
-
-    GLuint mnTextureProgram;
-    GLuint mnSamplerUniform;
-
-    GLuint mnTransformedTextureProgram;
-    GLuint mnTransformedViewportUniform;
-    GLuint mnTransformedTransformUniform;
-    GLuint mnTransformedSamplerUniform;
-
-    GLuint mnTransformedMaskedTextureProgram;
-    GLuint mnTransformedMaskedViewportUniform;
-    GLuint mnTransformedMaskedTransformUniform;
-    GLuint mnTransformedMaskedSamplerUniform;
-    GLuint mnTransformedMaskedMaskUniform;
-
-    GLuint mnDiffTextureProgram;
-    GLuint mnDiffTextureUniform;
-    GLuint mnDiffMaskUniform;
-
-    GLuint mnMaskedTextureProgram;
-    GLuint mnMaskedSamplerUniform;
-    GLuint mnMaskSamplerUniform;
-
-    GLuint mnBlendedTextureProgram;
-    GLuint mnBlendedTextureUniform;
-    GLuint mnBlendedMaskUniform;
-    GLuint mnBlendedAlphaUniform;
-
-    GLuint mnMaskProgram;
-    GLuint mnMaskUniform;
-    GLuint mnMaskColorUniform;
-
-    GLuint mnLinearGradientProgram;
-    GLuint mnLinearGradientStartColorUniform;
-    GLuint mnLinearGradientEndColorUniform;
-
-    GLuint mnRadialGradientProgram;
-    GLuint mnRadialGradientStartColorUniform;
-    GLuint mnRadialGradientEndColorUniform;
-    GLuint mnRadialGradientCenterUniform;
-
     void ImplInitClipRegion();
     void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask );
 
     bool CheckOffscreenTexture();
 
-    bool CreateSolidProgram( void );
-    bool CreateTextureProgram( void );
-    bool CreateTransformedTextureProgram( void );
-    bool CreateDiffTextureProgram( void );
-    bool CreateMaskedTextureProgram( void );
-    bool CreateBlendedTextureProgram( void );
-    bool CreateTransformedMaskedTextureProgram( void );
-    bool CreateMaskProgram( void );
-    bool CreateLinearGradientProgram( void );
-    bool CreateRadialGradientProgram( void );
-
 public:
-    void BeginSolid( SalColor nColor, sal_uInt8 nTransparency );
-    void BeginSolid( SalColor nColor, double fTransparency );
-    void BeginSolid( SalColor nColor );
-    void EndSolid( void );
-    void BeginInvert( void );
-    void EndInvert( void );
+    bool UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader );
+    bool UseSolid( SalColor nColor, sal_uInt8 nTransparency );
+    bool UseSolid( SalColor nColor, double fTransparency );
+    bool UseSolid( SalColor nColor );
+    bool UseInvert();
 
     void DrawPoint( long nX, long nY );
     void DrawLine( long nX1, long nY1, long nX2, long nY2 );
diff --git a/vcl/opengl/solidVertexShader.glsl b/vcl/opengl/dumbVertexShader.glsl
similarity index 100%
rename from vcl/opengl/solidVertexShader.glsl
rename to vcl/opengl/dumbVertexShader.glsl
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index acc84a1..4d362b1 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -34,77 +34,18 @@
 #include "svdata.hxx"
 #include "opengl/salbmp.hxx"
 
-#include <glm/glm.hpp>
-#include <glm/gtc/type_ptr.hpp>
 #include <vector>
 
-#define GL_ATTRIB_POS  0
-#define GL_ATTRIB_TEX  1
-#define GL_ATTRIB_TEX2 2
-
-#define glUniformColor(nUniform, nColor, nTransparency)    \
-    glUniform4f( nUniform,                                 \
-                 ((float) SALCOLOR_RED( nColor )) / 255,   \
-                 ((float) SALCOLOR_GREEN( nColor )) / 255, \
-                 ((float) SALCOLOR_BLUE( nColor )) / 255,  \
-                 (100 - nTransparency) * (1.0 / 100) )
-
-#define glUniformColorf(nUniform, nColor, fTransparency)   \
-    glUniform4f( nUniform,                                 \
-                 ((float) SALCOLOR_RED( nColor )) / 255,   \
-                 ((float) SALCOLOR_GREEN( nColor )) / 255, \
-                 ((float) SALCOLOR_BLUE( nColor )) / 255,  \
-                 (1.0f - fTransparency) )
-
-#define glUniformColorIntensity(nUniform, aColor, nFactor)      \
-    glUniform4f( nUniform,                                      \
-                 ((float) aColor.GetRed()) * nFactor / 25500.0,   \
-                 ((float) aColor.GetGreen()) * nFactor / 25500.0, \
-                 ((float) aColor.GetBlue()) * nFactor / 25500.0,  \
-                 1.0f )
-
 OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGeometryProvider* pParent)
     : mpContext(0)
     , mpParent(pParent)
     , mpFramebuffer(NULL)
+    , mpProgram(NULL)
     , mbUseScissor(false)
     , mbUseStencil(false)
     , mbOffscreen(false)
     , mnLineColor(SALCOLOR_NONE)
     , mnFillColor(SALCOLOR_NONE)
-    , mnSolidProgram(0)
-    , mnColorUniform(0)
-    , mnTextureProgram(0)
-    , mnSamplerUniform(0)
-    , mnTransformedTextureProgram(0)
-    , mnTransformedViewportUniform(0)
-    , mnTransformedTransformUniform(0)
-    , mnTransformedSamplerUniform(0)
-    , mnTransformedMaskedTextureProgram(0)
-    , mnTransformedMaskedViewportUniform(0)
-    , mnTransformedMaskedTransformUniform(0)
-    , mnTransformedMaskedSamplerUniform(0)
-    , mnTransformedMaskedMaskUniform(0)
-    , mnDiffTextureProgram(0)
-    , mnDiffTextureUniform(0)
-    , mnDiffMaskUniform(0)
-    , mnMaskedTextureProgram(0)
-    , mnMaskedSamplerUniform(0)
-    , mnMaskSamplerUniform(0)
-    , mnBlendedTextureProgram(0)
-    , mnBlendedTextureUniform(0)
-    , mnBlendedMaskUniform(0)
-    , mnBlendedAlphaUniform(0)
-    , mnMaskProgram(0)
-    , mnMaskUniform(0)
-    , mnMaskColorUniform(0)
-    , mnLinearGradientProgram(0)
-    , mnLinearGradientStartColorUniform(0)
-    , mnLinearGradientEndColorUniform(0)
-    , mnRadialGradientProgram(0)
-    , mnRadialGradientStartColorUniform(0)
-    , mnRadialGradientEndColorUniform(0)
-    , mnRadialGradientCenterUniform(0)
 {
 }
 
@@ -198,6 +139,11 @@ void OpenGLSalGraphicsImpl::PostDraw()
         glDisable( GL_SCISSOR_TEST );
     if( mbUseStencil )
         glDisable( GL_STENCIL_TEST );
+    if( mpProgram )
+    {
+        mpProgram->Clean();
+        mpProgram = NULL;
+    }
 
     mpContext->ReleaseFramebuffer( mpFramebuffer );
     mpFramebuffer = NULL;
@@ -219,12 +165,13 @@ void OpenGLSalGraphicsImpl::ImplSetClipBit( const vcl::Region& rClip, GLuint nMa
     glStencilOp( GL_REPLACE, GL_KEEP, GL_KEEP );
 
     glClear( GL_STENCIL_BUFFER_BIT );
-    BeginSolid( MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) );
-    if( rClip.getRegionBand() )
-        DrawRegionBand( *rClip.getRegionBand() );
-    else
-        DrawPolyPolygon( rClip.GetAsB2DPolyPolygon() );
-    EndSolid();
+    if( UseSolid( MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) ) )
+    {
+        if( rClip.getRegionBand() )
+            DrawRegionBand( *rClip.getRegionBand() );
+        else
+            DrawPolyPolygon( rClip.GetAsB2DPolyPolygon() );
+    }
 
     glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
     glStencilMask( 0x00 );
@@ -375,231 +322,45 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
     return true;
 }
 
-bool OpenGLSalGraphicsImpl::CreateSolidProgram( void )
-{
-    SAL_INFO( "vcl.opengl", "::CreateSolidProgram" );
-    mnSolidProgram = OpenGLHelper::LoadShaders( "solidVertexShader", "solidFragmentShader" );
-    if( mnSolidProgram == 0 )
-        return false;
-
-    SAL_INFO( "vcl.opengl", "Solid Program Created" );
-    glBindAttribLocation( mnSolidProgram, GL_ATTRIB_POS, "position" );
-    mnColorUniform = glGetUniformLocation( mnSolidProgram, "color" );
-
-    CHECK_GL_ERROR();
-    return true;
-}
-
-bool OpenGLSalGraphicsImpl::CreateTextureProgram( void )
-{
-    mnTextureProgram = OpenGLHelper::LoadShaders( "textureVertexShader", "textureFragmentShader" );
-    if( mnTextureProgram == 0 )
-        return false;
-
-    glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" );
-    glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
-    mnSamplerUniform = glGetUniformLocation( mnTextureProgram, "sampler" );
-
-    CHECK_GL_ERROR();
-    return true;
-}
-
-bool OpenGLSalGraphicsImpl::CreateTransformedTextureProgram( void )
-{
-    mnTransformedTextureProgram = OpenGLHelper::LoadShaders( "transformedTextureVertexShader", "textureFragmentShader" );
-    if( mnTransformedTextureProgram == 0 )
-        return false;
-
-    glBindAttribLocation( mnTransformedTextureProgram, GL_ATTRIB_POS, "position" );
-    glBindAttribLocation( mnTransformedTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
-    mnTransformedViewportUniform = glGetUniformLocation( mnTransformedTextureProgram, "viewport" );
-    mnTransformedTransformUniform = glGetUniformLocation( mnTransformedTextureProgram, "transform" );
-    mnTransformedSamplerUniform = glGetUniformLocation( mnTransformedTextureProgram, "sampler" );
-
-    CHECK_GL_ERROR();
-    return true;
-}
-
-bool OpenGLSalGraphicsImpl::CreateDiffTextureProgram( void )
+bool OpenGLSalGraphicsImpl::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader )
 {
-    mnDiffTextureProgram = OpenGLHelper::LoadShaders( "textureVertexShader", "diffTextureFragmentShader" );
-    if( mnDiffTextureProgram == 0 )
-        return false;
-
-    glBindAttribLocation( mnDiffTextureProgram, GL_ATTRIB_POS, "position" );
-    glBindAttribLocation( mnDiffTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
-    mnDiffTextureUniform = glGetUniformLocation( mnDiffTextureProgram, "texture" );
-    mnDiffMaskUniform = glGetUniformLocation( mnDiffTextureProgram, "mask" );
-
-    CHECK_GL_ERROR();
-    return true;
+    mpProgram = mpContext->UseProgram( rVertexShader, rFragmentShader );
+    return ( mpProgram != NULL );
 }
 
-bool OpenGLSalGraphicsImpl::CreateMaskedTextureProgram( void )
+bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, sal_uInt8 nTransparency )
 {
-    mnMaskedTextureProgram = OpenGLHelper::LoadShaders( "maskedTextureVertexShader", "maskedTextureFragmentShader" );
-    if( mnMaskedTextureProgram == 0 )
+    if( nColor == SALCOLOR_NONE )
         return false;
-
-    glBindAttribLocation( mnMaskedTextureProgram, GL_ATTRIB_POS, "position" );
-    glBindAttribLocation( mnMaskedTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
-    mnMaskedSamplerUniform = glGetUniformLocation( mnMaskedTextureProgram, "sampler" );
-    mnMaskSamplerUniform = glGetUniformLocation( mnMaskedTextureProgram, "mask" );
-
-    CHECK_GL_ERROR();
-    return true;
-}
-
-bool OpenGLSalGraphicsImpl::CreateTransformedMaskedTextureProgram( void )
-{
-    mnTransformedMaskedTextureProgram = OpenGLHelper::LoadShaders( "transformedTextureVertexShader", "maskedTextureFragmentShader" );
-    if( mnTransformedMaskedTextureProgram == 0 )
+    if( !UseProgram( "dumbVertexShader", "solidFragmentShader" ) )
         return false;
-
-    glBindAttribLocation( mnTransformedMaskedTextureProgram, GL_ATTRIB_POS, "position" );
-    glBindAttribLocation( mnTransformedMaskedTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
-    mnTransformedMaskedViewportUniform = glGetUniformLocation( mnTransformedMaskedTextureProgram, "viewport" );
-    mnTransformedMaskedTransformUniform = glGetUniformLocation( mnTransformedMaskedTextureProgram, "transform" );
-    mnTransformedMaskedSamplerUniform = glGetUniformLocation( mnTransformedMaskedTextureProgram, "sampler" );
-    mnTransformedMaskedMaskUniform = glGetUniformLocation( mnTransformedMaskedTextureProgram, "mask" );
-
-    CHECK_GL_ERROR();
+    mpProgram->SetColor( "color", nColor, nTransparency );
     return true;
 }
 
-bool OpenGLSalGraphicsImpl::CreateBlendedTextureProgram( void )
+bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, double fTransparency )
 {
-    mnBlendedTextureProgram = OpenGLHelper::LoadShaders( "blendedTextureVertexShader", "blendedTextureFragmentShader" );
-    if( mnBlendedTextureProgram == 0 )
+    if( nColor == SALCOLOR_NONE )
         return false;
-
-    glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_POS, "position" );
-    glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
-    glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_TEX2, "alpha_coord_in" );
-    mnBlendedTextureUniform = glGetUniformLocation( mnBlendedTextureProgram, "sampler" );
-    mnBlendedMaskUniform = glGetUniformLocation( mnBlendedTextureProgram, "mask" );
-    mnBlendedAlphaUniform = glGetUniformLocation( mnBlendedTextureProgram, "alpha" );
-
-    CHECK_GL_ERROR();
-    return true;
-}
-
-bool OpenGLSalGraphicsImpl::CreateMaskProgram( void )
-{
-    mnMaskProgram = OpenGLHelper::LoadShaders( "maskVertexShader", "maskFragmentShader" );
-    if( mnMaskProgram == 0 )
+    if( !UseProgram( "dumbVertexShader", "solidFragmentShader" ) )
         return false;
-
-    glBindAttribLocation( mnMaskProgram, GL_ATTRIB_POS, "position" );
-    glBindAttribLocation( mnMaskProgram, GL_ATTRIB_TEX, "tex_coord_in" );
-    mnMaskUniform = glGetUniformLocation( mnMaskProgram, "sampler" );
-    mnMaskColorUniform = glGetUniformLocation( mnMaskProgram, "color" );
-
-    CHECK_GL_ERROR();
+    mpProgram->SetColorf( "color", nColor, fTransparency );
     return true;
 }
 
-bool OpenGLSalGraphicsImpl::CreateLinearGradientProgram( void )
+bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor )
 {
-    mnLinearGradientProgram = OpenGLHelper::LoadShaders( "textureVertexShader", "linearGradientFragmentShader" );
-    if( mnLinearGradientProgram == 0 )
-        return false;
-
-    glBindAttribLocation( mnLinearGradientProgram, GL_ATTRIB_POS, "position" );
-    glBindAttribLocation( mnLinearGradientProgram, GL_ATTRIB_TEX, "tex_coord_in" );
-    mnLinearGradientStartColorUniform = glGetUniformLocation( mnLinearGradientProgram, "start_color" );
-    mnLinearGradientEndColorUniform = glGetUniformLocation( mnLinearGradientProgram, "end_color" );
-
-    CHECK_GL_ERROR();
-    return true;
+    return UseSolid( nColor, 0.0f );
 }
 
-bool OpenGLSalGraphicsImpl::CreateRadialGradientProgram( void )
+bool OpenGLSalGraphicsImpl::UseInvert()
 {
-    mnRadialGradientProgram = OpenGLHelper::LoadShaders( "textureVertexShader", "radialGradientFragmentShader" );
-    if( mnRadialGradientProgram == 0 )
+    if( !UseSolid( MAKE_SALCOLOR( 255, 255, 255 ) ) )
         return false;
-
-    glBindAttribLocation( mnRadialGradientProgram, GL_ATTRIB_POS, "position" );
-    glBindAttribLocation( mnRadialGradientProgram, GL_ATTRIB_TEX, "tex_coord_in" );
-    mnRadialGradientStartColorUniform = glGetUniformLocation( mnRadialGradientProgram, "start_color" );
-    mnRadialGradientEndColorUniform = glGetUniformLocation( mnRadialGradientProgram, "end_color" );
-    mnRadialGradientCenterUniform = glGetUniformLocation( mnRadialGradientProgram, "center" );
-
-    CHECK_GL_ERROR();
+    mpProgram->SetBlendMode( GL_ONE_MINUS_DST_COLOR, GL_ZERO );
     return true;
 }
 
-void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor, sal_uInt8 nTransparency )
-{
-    if( mnSolidProgram == 0 )
-    {
-        glClearColor( 1, 1, 1, 1 );
-        glClear( GL_COLOR_BUFFER_BIT );
-        if( !CreateSolidProgram() )
-            return;
-    }
-
-    if( nTransparency > 0 )
-    {
-        glEnable( GL_BLEND );
-        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
-    }
-    glUseProgram( mnSolidProgram );
-    glUniformColor( mnColorUniform, nColor, nTransparency );
-
-    CHECK_GL_ERROR();
-}
-
-void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor, double fTransparency )
-{
-    if( mnSolidProgram == 0 )
-    {
-        if( !CreateSolidProgram() )
-            return;
-    }
-
-    if( fTransparency > 0.0f )
-    {
-        glEnable( GL_BLEND );
-        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
-    }
-    glUseProgram( mnSolidProgram );
-    glUniformColorf( mnColorUniform, nColor, fTransparency );
-
-    CHECK_GL_ERROR();
-}
-
-void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor )
-{
-    BeginSolid( nColor, 0.0f );
-}
-
-void OpenGLSalGraphicsImpl::EndSolid( void )
-{
-    glUseProgram( 0 );
-    glDisable( GL_BLEND );
-
-    CHECK_GL_ERROR();
-}
-
-void OpenGLSalGraphicsImpl::BeginInvert( void )
-{
-    glEnable( GL_BLEND );
-    glBlendFunc( GL_ONE_MINUS_DST_COLOR, GL_ZERO );
-    BeginSolid( MAKE_SALCOLOR( 255, 255, 255 ) );
-
-    CHECK_GL_ERROR();
-}
-
-void OpenGLSalGraphicsImpl::EndInvert( void )
-{
-    EndSolid();
-    glDisable( GL_BLEND );
-
-    CHECK_GL_ERROR();
-}
-
 void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
 {
     GLfloat pPoint[2];
@@ -607,12 +368,8 @@ void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
     pPoint[0] = 2 * nX / GetWidth() - 1.0f;
     pPoint[1] = 1.0f - 2 * nY / GetHeight();
 
-    glEnableVertexAttribArray( GL_ATTRIB_POS );
-    glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, pPoint );
+    mpProgram->SetVertices( pPoint );
     glDrawArrays( GL_POINTS, 0, 1 );
-    glDisableVertexAttribArray( GL_ATTRIB_POS );
-
-    CHECK_GL_ERROR();
 }
 
 void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 )
@@ -624,12 +381,8 @@ void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 )
     pPoints[2] = (2 * nX2) / GetWidth() - 1.0;;
     pPoints[3] = 1.0f - 2 * nY2 / GetHeight();
 
-    glEnableVertexAttribArray( GL_ATTRIB_POS );
-    glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, pPoints );
+    mpProgram->SetVertices( pPoints );
     glDrawArrays( GL_LINES, 0, 2 );
-    glDisableVertexAttribArray( GL_ATTRIB_POS );
-
-    CHECK_GL_ERROR();
 }
 
 void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose )
@@ -643,15 +396,11 @@ void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAr
         aPoints[j++] = 1.0f - (2 * pPtAry[i].mnY) / GetHeight();
     }
 
-    glEnableVertexAttribArray( GL_ATTRIB_POS );
-    glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aPoints[0] );
+    mpProgram->SetVertices( &aPoints[0] );
     if( bClose )
         glDrawArrays( GL_LINE_LOOP, 0, nPoints );
     else
         glDrawArrays( GL_LINE_STRIP, 0, nPoints );
-    glDisableVertexAttribArray( GL_ATTRIB_POS );
-
-    CHECK_GL_ERROR();
 }
 
 void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
@@ -665,12 +414,8 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin
         aVertices[j+1] = 1.0 - (2 * pPtAry[i].mnY / GetHeight());
     }
 
-    glEnableVertexAttribArray( GL_ATTRIB_POS );
-    glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] );
+    mpProgram->SetVertices( &aVertices[0] );
     glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
-    glDisableVertexAttribArray( GL_ATTRIB_POS );
-
-    CHECK_GL_ERROR();
 }
 
 void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon )
@@ -686,12 +431,8 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon )
         aVertices[j+1] = 1.0 - (2 * rPt.Y() / GetHeight());
     }
 
-    glEnableVertexAttribArray( GL_ATTRIB_POS );
-    glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] );
+    mpProgram->SetVertices( &aVertices[0] );
     glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
-    glDisableVertexAttribArray( GL_ATTRIB_POS );
-
-    CHECK_GL_ERROR();
 }
 
 void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeight )
@@ -759,10 +500,8 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPol
         }
     }
 
-    glEnableVertexAttribArray( GL_ATTRIB_POS );
-    glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, aVertices.data() );
+    mpProgram->SetVertices( aVertices.data() );
     glDrawArrays( GL_TRIANGLES, 0, aVertices.size() / 2 );
-    glDisableVertexAttribArray( GL_ATTRIB_POS );
 
     CHECK_GL_ERROR();
 }
@@ -794,50 +533,25 @@ void OpenGLSalGraphicsImpl::DrawRegionBand( const RegionBand& rRegion )
 
 #undef ADD_VERTICE
 
-    glEnableVertexAttribArray( GL_ATTRIB_POS );
-    glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] );
+    mpProgram->SetVertices( &aVertices[0] );
     glDrawArrays( GL_TRIANGLES, 0, aVertices.size() / 2 );
-    glDisableVertexAttribArray( GL_ATTRIB_POS );
-
-    CHECK_GL_ERROR();
 }
 
 void OpenGLSalGraphicsImpl::DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted )
 {
     GLfloat aTexCoord[8];
-
     rTexture.GetCoord( aTexCoord, rPosAry, bInverted );
-    glEnableVertexAttribArray( GL_ATTRIB_TEX );
-    glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
-
+    mpProgram->SetTextureCoord( aTexCoord );
     DrawRect( rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight );
-
-    glDisableVertexAttribArray( GL_ATTRIB_TEX );
-
-    CHECK_GL_ERROR();
 }
 
 void OpenGLSalGraphicsImpl::DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& pPosAry, bool bInverted )
 {
-    if( mnTextureProgram == 0 )
-    {
-        if( !CreateTextureProgram() )
-            return;
-    }
-
-    glUseProgram( mnTextureProgram );
-    glUniform1i( mnSamplerUniform, 0 );
-    glActiveTexture( GL_TEXTURE0 );
-    CHECK_GL_ERROR();
-
-    rTexture.Bind();
+    if( !UseProgram( "textureVertexShader", "textureFragmentShader" ) )
+        return;
+    mpProgram->SetTexture( "sampler", rTexture );
     DrawTextureRect( rTexture, pPosAry, bInverted );
-    rTexture.Unbind();
-    CHECK_GL_ERROR();
-
-    glUseProgram( 0 );
-
-    CHECK_GL_ERROR();
+    mpProgram->Clean();
 }
 
 void OpenGLSalGraphicsImpl::DrawTransformedTexture(
@@ -847,14 +561,6 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture(
     const basegfx::B2DPoint& rX,
     const basegfx::B2DPoint& rY )
 {
-    const basegfx::B2DVector aXRel = rX - rNull;
-    const basegfx::B2DVector aYRel = rY - rNull;
-    const float aValues[] = {
-        (float) aXRel.getX()/rTexture.GetWidth(),  (float) aXRel.getY()/rTexture.GetWidth(),  0, 0,
-        (float) aYRel.getX()/rTexture.GetHeight(), (float) aYRel.getY()/rTexture.GetHeight(), 0, 0,
-        0,                                         0,                                         1, 0,
-        (float) rNull.getX(),                      (float) rNull.getY(),                      0, 1 };
-    glm::mat4 mMatrix = glm::make_mat4( aValues );
     GLfloat aVertices[8] = {
         0, (float) rTexture.GetHeight(), 0, 0,
         (float) rTexture.GetWidth(), 0, (float) rTexture.GetWidth(), (float) rTexture.GetHeight() };
@@ -862,222 +568,98 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture(
 
     if( rMask )
     {
-        if( mnTransformedMaskedTextureProgram == 0 )
-        {
-            if( !CreateTransformedMaskedTextureProgram() )
-                return;
-        }
-        glUseProgram( mnTransformedMaskedTextureProgram );
-        glUniform2f( mnTransformedMaskedViewportUniform, GetWidth(), GetHeight() );
-        glUniformMatrix4fv( mnTransformedMaskedTransformUniform, 1, GL_FALSE, glm::value_ptr( mMatrix ) );
-        glUniform1i( mnTransformedMaskedSamplerUniform, 0 );
-        glUniform1i( mnTransformedMaskedMaskUniform, 1 );
-        glActiveTexture( GL_TEXTURE1 );
-        rMask.Bind();
+        if( !UseProgram( "transformedTextureVertexShader", "maskedTextureFragmentShader" ) )
+            return;
+        mpProgram->SetTexture( "mask", rMask );
         rMask.SetFilter( GL_LINEAR );
-        glEnable( GL_BLEND );
-        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+        mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
     }
     else
     {
-        if( mnTransformedTextureProgram == 0 )
-        {
-            if( !CreateTransformedTextureProgram() )
-                return;
-        }
-        glUseProgram( mnTransformedTextureProgram );
-        glUniform2f( mnTransformedViewportUniform, GetWidth(), GetHeight() );
-        glUniformMatrix4fv( mnTransformedTransformUniform, 1, GL_FALSE, glm::value_ptr( mMatrix ) );
-        glUniform1i( mnTransformedSamplerUniform, 0 );
+        if( !UseProgram( "transformedTextureVertexShader", "textureFragmentShader" ) )
+            return;
     }
 
-    glActiveTexture( GL_TEXTURE0 );
-    rTexture.Bind();
+    mpProgram->SetUniform2f( "viewport", GetWidth(), GetHeight() );
+    mpProgram->SetTransform( "transform", rTexture, rNull, rX, rY );
+    rTexture.GetWholeCoord( aTexCoord );
+    mpProgram->SetTexture( "sampler", rTexture );
     rTexture.SetFilter( GL_LINEAR );
-    CHECK_GL_ERROR();
-
-    GLfloat fWidth = rTexture.GetWidth();
-    GLfloat fHeight = rTexture.GetHeight();
-    SalTwoRect aPosAry(0, 0, fWidth, fHeight, 0, 0, fWidth, fHeight);
-    rTexture.GetCoord( aTexCoord, aPosAry );
-    glEnableVertexAttribArray( GL_ATTRIB_TEX );
-    glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
-    glEnableVertexAttribArray( GL_ATTRIB_POS );
-    glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] );
+    mpProgram->SetTextureCoord( aTexCoord );
+    mpProgram->SetVertices( &aVertices[0] );
     glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
-    glDisableVertexAttribArray( GL_ATTRIB_POS );
-    glDisableVertexAttribArray( GL_ATTRIB_TEX );
-
-    if( rMask )
-    {
-        glDisable( GL_BLEND );
-        glActiveTexture( GL_TEXTURE1 );
-        rMask.Unbind();
-    }
-
-    glActiveTexture( GL_TEXTURE0 );
-    rTexture.Unbind();
-    glUseProgram( 0 );
-    CHECK_GL_ERROR();
+    mpProgram->Clean();
 }
 
 void OpenGLSalGraphicsImpl::DrawAlphaTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted, bool bPremultiplied )
 {
-    glEnable( GL_BLEND );
-    if( bPremultiplied )
-        glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
-    else
-        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
-    DrawTexture( rTexture, rPosAry, bInverted );
-    glDisable( GL_BLEND );
-    CHECK_GL_ERROR();
+    if( !UseProgram( "textureVertexShader", "textureFragmentShader" ) )
+        return;
+    mpProgram->SetTexture( "sampler", rTexture );
+    mpProgram->SetBlendMode( bPremultiplied ? GL_ONE : GL_SRC_ALPHA,
+                             GL_ONE_MINUS_SRC_ALPHA );
+    DrawTextureRect( rTexture, rPosAry, bInverted );
+    mpProgram->Clean();
 }
 
 void OpenGLSalGraphicsImpl::DrawTextureDiff( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry, bool bInverted )
 {
-    if( mnDiffTextureProgram == 0 )
-    {
-        if( !CreateDiffTextureProgram() )
-            return;
-    }
-
-    glUseProgram( mnDiffTextureProgram );
-    glUniform1i( mnDiffTextureUniform, 0 );
-    glUniform1i( mnDiffMaskUniform, 1 );
-    glActiveTexture( GL_TEXTURE0 );
-    rTexture.Bind();
-    glActiveTexture( GL_TEXTURE1 );
-    rMask.Bind();
-
-    glEnable( GL_BLEND );
-    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+    if( !UseProgram( "textureVertexShader", "diffTextureFragmentShader" ) )
+        return;
+    mpProgram->SetTexture( "texture", rTexture );
+    mpProgram->SetTexture( "mask", rMask );
+    mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
     DrawTextureRect( rTexture, rPosAry, bInverted );
-    glDisable( GL_BLEND );
-
-    glActiveTexture( GL_TEXTURE1 );
-    rMask.Unbind();
-    glActiveTexture( GL_TEXTURE0 );
-    rTexture.Unbind();
-    glUseProgram( 0 );
-
-    CHECK_GL_ERROR();
+    mpProgram->Clean();
 }
 
 void OpenGLSalGraphicsImpl::DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& pPosAry )
 {
-    if( mnMaskedTextureProgram == 0 )
-    {
-        if( !CreateMaskedTextureProgram() )
-            return;
-    }
-
-    glUseProgram( mnMaskedTextureProgram );
-    glUniform1i( mnMaskedSamplerUniform, 0 );
-    glUniform1i( mnMaskSamplerUniform, 1 );
-    glActiveTexture( GL_TEXTURE0 );
-    rTexture.Bind();
-    glActiveTexture( GL_TEXTURE1 );
-    rMask.Bind();
-
-    glEnable( GL_BLEND );
-    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+    if( !UseProgram( "textureVertexShader", "maskedTextureFragmentShader" ) )
+        return;
+    mpProgram->SetTexture( "sampler", rTexture );
+    mpProgram->SetTexture( "mask", rMask );
+    mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
     DrawTextureRect( rTexture, pPosAry );
-    glDisable( GL_BLEND );
-
-    glActiveTexture( GL_TEXTURE1 );
-    rMask.Unbind();
-    glActiveTexture( GL_TEXTURE0 );
-    rTexture.Unbind();
-    glUseProgram( 0 );
-
-    CHECK_GL_ERROR();
+    mpProgram->Clean();
 }
 
 void OpenGLSalGraphicsImpl::DrawBlendedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, OpenGLTexture& rAlpha, const SalTwoRect& rPosAry )
 {
     GLfloat aTexCoord[8];
-
-    if( mnBlendedTextureProgram == 0 )
-    {
-        if( !CreateBlendedTextureProgram() )
-            return;
-    }
-
-    glUseProgram( mnBlendedTextureProgram );
-    glUniform1i( mnBlendedTextureUniform, 0 );
-    glUniform1i( mnBlendedMaskUniform, 1 );
-    glUniform1i( mnBlendedAlphaUniform, 2 );
-    glActiveTexture( GL_TEXTURE0 );
-    rTexture.Bind();
-    glActiveTexture( GL_TEXTURE1 );
-    rMask.Bind();
-    glActiveTexture( GL_TEXTURE2 );
-    rAlpha.Bind();
-
+    if( !UseProgram( "blendedTextureVertexShader", "blendedTextureFragmentShader" ) )
+        return;
+    mpProgram->SetTexture( "sampler", rTexture );
+    mpProgram->SetTexture( "mask", rMask );
+    mpProgram->SetTexture( "alpha", rAlpha );
     rAlpha.GetCoord( aTexCoord, rPosAry );
-    glEnableVertexAttribArray( GL_ATTRIB_TEX2 );
-    glVertexAttribPointer( GL_ATTRIB_TEX2, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
-
-    glEnable( GL_BLEND );
-    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+    mpProgram->SetAlphaCoord( aTexCoord );
+    mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
     DrawTextureRect( rTexture, rPosAry );
-    glDisable( GL_BLEND );
-
-    glDisableVertexAttribArray( GL_ATTRIB_TEX2 );
-
-    glActiveTexture( GL_TEXTURE0 );
-    rTexture.Unbind();
-    glActiveTexture( GL_TEXTURE1 );
-    rMask.Unbind();
-    glActiveTexture( GL_TEXTURE2 );
-    rAlpha.Unbind();
-    glActiveTexture( GL_TEXTURE0 );
-    glUseProgram( 0 );
-
-    CHECK_GL_ERROR();
+    mpProgram->Clean();
 }
 
 void OpenGLSalGraphicsImpl::DrawMask( OpenGLTexture& rMask, SalColor nMaskColor, const SalTwoRect& pPosAry )
 {
-    if( mnMaskProgram == 0 )
-    {
-        if( !CreateMaskProgram() )
-            return;
-    }
-
-    glUseProgram( mnMaskProgram );
-    glUniformColor( mnMaskColorUniform, nMaskColor, 0 );
-    glUniform1i( mnMaskUniform, 0 );
-    glActiveTexture( GL_TEXTURE0 );
-    rMask.Bind();
-
-    glEnable( GL_BLEND );
-    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+    if( !UseProgram( "textureVertexShader", "maskFragmentShader" ) )
+        return;
+    mpProgram->SetColor( "color", nMaskColor, 0 );
+    mpProgram->SetTexture( "sampler", rMask );
+    mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
     DrawTextureRect( rMask, pPosAry );
-    glDisable( GL_BLEND );
-
-    rMask.Unbind();
-    glUseProgram( 0 );
-
-    CHECK_GL_ERROR();
+    mpProgram->Clean();
 }
 
 void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect )
 {
-    if( mnLinearGradientProgram == 0 )
-    {
-        if( !CreateLinearGradientProgram() )
-            return;
-    }
-
-    glUseProgram( mnLinearGradientProgram );
-
+    if( !UseProgram( "textureVertexShader", "linearGradientFragmentShader" ) )
+        return;
     Color aStartCol = rGradient.GetStartColor();
     Color aEndCol = rGradient.GetEndColor();
     long nFactor = rGradient.GetStartIntensity();
-    glUniformColorIntensity( mnLinearGradientStartColorUniform, aStartCol, nFactor );
+    mpProgram->SetColorWithIntensity( "start_color", aStartCol, nFactor );
     nFactor = rGradient.GetEndIntensity();
-    glUniformColorIntensity( mnLinearGradientEndColorUniform, aEndCol, nFactor );
+    mpProgram->SetColorWithIntensity( "end_color", aEndCol, nFactor );
 
     Rectangle aBoundRect;
     Point aCenter;
@@ -1088,35 +670,20 @@ void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const
     GLfloat aTexCoord[8] = { 0, 1, 1, 1, 1, 0, 0, 0 };
     GLfloat fMin = 1.0 - 100.0 / (100.0 - rGradient.GetBorder());
     aTexCoord[5] = aTexCoord[7] = fMin;
-    glEnableVertexAttribArray( GL_ATTRIB_TEX );
-    glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
-
+    mpProgram->SetTextureCoord( aTexCoord );
     DrawConvexPolygon( aPoly );
-
-    glDisableVertexAttribArray( GL_ATTRIB_TEX );
-    CHECK_GL_ERROR();
-
-    glUseProgram( 0 );
-
-    CHECK_GL_ERROR();
 }
 
 void OpenGLSalGraphicsImpl::DrawAxialGradient( const Gradient& rGradient, const Rectangle& rRect )
 {
-    if( mnLinearGradientProgram == 0 )
-    {
-        if( !CreateLinearGradientProgram() )
-            return;
-    }
-
-    glUseProgram( mnLinearGradientProgram );
-
+    if( !UseProgram( "textureVertexShader", "linearGradientFragmentShader" ) )
+        return;
     Color aStartCol = rGradient.GetStartColor();
     Color aEndCol = rGradient.GetEndColor();
     long nFactor = rGradient.GetStartIntensity();
-    glUniformColorIntensity( mnLinearGradientStartColorUniform, aStartCol, nFactor );
+    mpProgram->SetColorWithIntensity( "start_color", aStartCol, nFactor );
     nFactor = rGradient.GetEndIntensity();
-    glUniformColorIntensity( mnLinearGradientEndColorUniform, aEndCol, nFactor );
+    mpProgram->SetColorWithIntensity( "end_color", aEndCol, nFactor );
 
     /**
      * Draw two rectangles with linear gradient.
@@ -1153,33 +720,20 @@ void OpenGLSalGraphicsImpl::DrawAxialGradient( const Gradient& rGradient, const
     GLfloat aTexCoord[12] = { 0, 1, 1, 0, 2, 0, 3, 1, 4, 0, 5, 0 };
     GLfloat fMin = 1.0 - 100.0 / (100.0 - rGradient.GetBorder());
     aTexCoord[3] = aTexCoord[5] = aTexCoord[9] = aTexCoord[11] = fMin;
-    glEnableVertexAttribArray( GL_ATTRIB_TEX );
-    glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
-
+    mpProgram->SetTextureCoord( aTexCoord );
     DrawConvexPolygon( aPoly );
-
-    glDisableVertexAttribArray( GL_ATTRIB_TEX );
-    glUseProgram( 0 );
-
-    CHECK_GL_ERROR();
 }
 
 void OpenGLSalGraphicsImpl::DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect )
 {
-    if( mnRadialGradientProgram == 0 )
-    {
-        if( !CreateRadialGradientProgram() )
-            return;
-    }
-
-    glUseProgram( mnRadialGradientProgram );
-
+    if( !UseProgram( "textureVertexShader", "radialGradientFragmentShader" ) )
+        return;
     Color aStartCol = rGradient.GetStartColor();
     Color aEndCol = rGradient.GetEndColor();
     long nFactor = rGradient.GetStartIntensity();
-    glUniformColorIntensity( mnRadialGradientStartColorUniform, aStartCol, nFactor );
+    mpProgram->SetColorWithIntensity( "start_color", aStartCol, nFactor );
     nFactor = rGradient.GetEndIntensity();
-    glUniformColorIntensity( mnRadialGradientEndColorUniform, aEndCol, nFactor );
+    mpProgram->SetColorWithIntensity( "end_color", aEndCol, nFactor );
 

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list