[Libreoffice-commits] core.git: 6 commits - canvas/Library_oglcanvas.mk canvas/Module_canvas.mk canvas/opengl canvas/Package_opengl.mk canvas/source configure.ac include/vcl vcl/source

Markus Mohrhard markus.mohrhard at collabora.co.uk
Fri Aug 8 00:32:59 PDT 2014


 canvas/Library_oglcanvas.mk                                    |    3 
 canvas/Module_canvas.mk                                        |    1 
 canvas/Package_opengl.mk                                       |   22 
 canvas/opengl/dummyVertexShader.glsl                           |   17 
 canvas/opengl/linearMultiColorGradientFragmentShader.glsl      |   45 
 canvas/opengl/linearTwoColorGradientFragmentShader.glsl        |   26 
 canvas/opengl/radialMultiColorGradientFragmentShader.glsl      |   48 
 canvas/opengl/radialTwoColorGradientFragmentShader.glsl        |   28 
 canvas/opengl/rectangularMultiColorGradientFragmentShader.glsl |   44 
 canvas/opengl/rectangularTwoColorGradientFragmentShader.glsl   |   25 
 canvas/source/opengl/ogl_buffercontext.hxx                     |    9 
 canvas/source/opengl/ogl_canvascustomsprite.cxx                |   12 
 canvas/source/opengl/ogl_canvashelper.cxx                      |    4 
 canvas/source/opengl/ogl_canvastools.cxx                       |    5 
 canvas/source/opengl/ogl_spritecanvas.cxx                      |    3 
 canvas/source/opengl/ogl_spritedevicehelper.cxx                |  802 ----------
 canvas/source/opengl/ogl_spritedevicehelper.hxx                |   36 
 canvas/source/opengl/ogl_texturecache.cxx                      |    4 
 canvas/source/opengl/ogl_tools.hxx                             |    2 
 configure.ac                                                   |    3 
 include/vcl/opengl/OpenGLContext.hxx                           |    3 
 include/vcl/opengl/OpenGLHelper.hxx                            |    6 
 vcl/source/opengl/OpenGLContext.cxx                            |   10 
 vcl/source/opengl/OpenGLHelper.cxx                             |   40 
 24 files changed, 399 insertions(+), 799 deletions(-)

New commits:
commit 396fa3b663efb2f0b125c6328732263133590b3f
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Fri Aug 8 05:28:02 2014 +0200

    reimplement custom sprite rendering with FBO
    
    Change-Id: I8d7a54fac61a3072d4f34615e71e37c70dec4e50

diff --git a/canvas/source/opengl/ogl_buffercontext.hxx b/canvas/source/opengl/ogl_buffercontext.hxx
index 7d85e9a..a99446b 100644
--- a/canvas/source/opengl/ogl_buffercontext.hxx
+++ b/canvas/source/opengl/ogl_buffercontext.hxx
@@ -10,20 +10,25 @@
 #ifndef INCLUDED_CANVAS_SOURCE_OPENGL_OGL_BUFFERCONTEXT_HXX
 #define INCLUDED_CANVAS_SOURCE_OPENGL_OGL_BUFFERCONTEXT_HXX
 
+#include <GL/glew.h>
+
 #include <sal/config.h>
 #include <boost/shared_ptr.hpp>
 
+
 namespace oglcanvas
 {
     struct IBufferContext
     {
         virtual ~IBufferContext() {}
 
-        /// start render to buffer. changes gl current context
+        /// start render to buffer. changes current framebuffer
         virtual bool startBufferRendering() = 0;
 
-        /// end render to buffer. switches to window context, and selects rendered texture
+        /// end render to buffer. switches to default framebuffer
         virtual bool endBufferRendering() = 0;
+
+        virtual GLuint getTextureId() = 0;
     };
 
     typedef ::boost::shared_ptr<IBufferContext> IBufferContextSharedPtr;
diff --git a/canvas/source/opengl/ogl_canvascustomsprite.cxx b/canvas/source/opengl/ogl_canvascustomsprite.cxx
index 86cbac6..2f2853e 100644
--- a/canvas/source/opengl/ogl_canvascustomsprite.cxx
+++ b/canvas/source/opengl/ogl_canvascustomsprite.cxx
@@ -159,9 +159,8 @@ namespace oglcanvas
                 // composite that to screen
 
                 // TODO(P3): buffer texture
-                // TODO: moggi: reimplement as FBO with rendering to texture
-                pBufferContext = NULL;
-                // pBufferContext->startBufferRendering();
+                pBufferContext = maCanvasHelper.getDeviceHelper()->createBufferContext(aSpriteSizePixel);
+                pBufferContext->startBufferRendering();
             }
 
             // this ends up in pBufferContext, if that one's "current"
@@ -174,6 +173,8 @@ namespace oglcanvas
                 // screen now. Calls below switches us back to window
                 // context, and binds to generated, dynamic texture
                 pBufferContext->endBufferRendering();
+                GLuint nTexture = pBufferContext->getTextureId();
+                glBindTexture(GL_TEXTURE_2D, nTexture);
 
                 glEnable(GL_TEXTURE_2D);
                 glTexParameteri(GL_TEXTURE_2D,
diff --git a/canvas/source/opengl/ogl_spritedevicehelper.cxx b/canvas/source/opengl/ogl_spritedevicehelper.cxx
index cd29f37..3f6b534 100644
--- a/canvas/source/opengl/ogl_spritedevicehelper.cxx
+++ b/canvas/source/opengl/ogl_spritedevicehelper.cxx
@@ -537,21 +537,29 @@ namespace oglcanvas
     namespace
     {
 
-        /*
-         * TODO: mogg: reimplement through FBO with texture as backend
         class BufferContextImpl : public IBufferContext
         {
             ::basegfx::B2IVector       maSize;
             const SpriteDeviceHelper&  mrDeviceHelper;
+            GLuint mnFrambufferId;
+            GLuint mnDepthId;
+            GLuint mnTextureId;
 
             virtual bool startBufferRendering() SAL_OVERRIDE
             {
-                return false;
+                glBindFramebuffer(GL_FRAMEBUFFER, mnFrambufferId);
+                return true;
             }
 
             virtual bool endBufferRendering() SAL_OVERRIDE
             {
-                return false;
+                glBindFramebuffer(GL_FRAMEBUFFER, 0);
+                return true;
+            }
+
+            virtual GLuint getTextureId() SAL_OVERRIDE
+            {
+                return mnTextureId;
             }
 
         public:
@@ -559,20 +567,26 @@ namespace oglcanvas
                               const ::basegfx::B2IVector& rSize) :
                 maSize(rSize),
                 mrDeviceHelper(rDeviceHelper),
-                mnTexture(0)
+                mnFrambufferId(0),
+                mnDepthId(0),
+                mnTextureId(0)
             {
+                OpenGLHelper::createFramebuffer(maSize.getX(), maSize.getY(), mnFrambufferId,
+                        mnDepthId, mnTextureId, false);
             }
 
             virtual ~BufferContextImpl()
             {
+                glDeleteTextures(1, &mnTextureId);
+                glDeleteRenderbuffers(1, &mnDepthId);
+                glDeleteFramebuffers(1, &mnFrambufferId);
             }
         };
-        */
     }
 
-    IBufferContextSharedPtr SpriteDeviceHelper::createBufferContext(const ::basegfx::B2IVector& ) const
+    IBufferContextSharedPtr SpriteDeviceHelper::createBufferContext(const ::basegfx::B2IVector& rSize) const
     {
-        return NULL;
+        return IBufferContextSharedPtr(new BufferContextImpl(*this, rSize));
     }
 
     TextureCache& SpriteDeviceHelper::getTextureCache() const
commit d4b80b6c3ea3bddd041d84dacb990ddf343aa0ad
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Fri Aug 8 05:05:11 2014 +0200

    fix variable name
    
    Change-Id: I1cfd6d59e5569177d8ad23245435073d30fe1374

diff --git a/include/vcl/opengl/OpenGLHelper.hxx b/include/vcl/opengl/OpenGLHelper.hxx
index 0134697..52093c2 100644
--- a/include/vcl/opengl/OpenGLHelper.hxx
+++ b/include/vcl/opengl/OpenGLHelper.hxx
@@ -34,7 +34,7 @@ public:
      *          This also affects whether to free with glDeleteRenderbuffers or glDeleteTextures
      */
     static void createFramebuffer(long nWidth, long nHeight, GLuint& nFramebufferId,
-            GLuint& nRenderbufferTextId, GLuint& nRenderbufferColorId, bool bRenderbuffer = true);
+            GLuint& nRenderbufferDepthId, GLuint& nRenderbufferColorId, bool bRenderbuffer = true);
 
     // Get OpenGL version (needs a context)
     static float getGLVersion();
commit 5ace9183ba92ad44207f8f8e57a1665bd52062ae
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Fri Aug 8 04:52:38 2014 +0200

    add possibility to generate FBO with texture
    
    The caller is responsible to delete the buffers. Depending on bRenderbuffer either with glDeleteRenderbuffers or with glDeleteTextures.
    
    Change-Id: I5ccbd49862c381abf04e812765cced485a083f89

diff --git a/include/vcl/opengl/OpenGLHelper.hxx b/include/vcl/opengl/OpenGLHelper.hxx
index f80d34b..0134697 100644
--- a/include/vcl/opengl/OpenGLHelper.hxx
+++ b/include/vcl/opengl/OpenGLHelper.hxx
@@ -30,9 +30,11 @@ public:
     /**
      * The caller is responsible for deleting the buffer objects identified by
      * nFramebufferId, nRenderbufferDepthId and nRenderbufferColorId
+     * @param bRenderbuffer true => off-screen rendering, false => rendering to texture
+     *          This also affects whether to free with glDeleteRenderbuffers or glDeleteTextures
      */
-    static void createFramebuffer(long nWidth, long nHeight,
-            GLuint& nFramebufferId, GLuint& nRenderbufferTextId, GLuint& nRenderbufferColorId);
+    static void createFramebuffer(long nWidth, long nHeight, GLuint& nFramebufferId,
+            GLuint& nRenderbufferTextId, GLuint& nRenderbufferColorId, bool bRenderbuffer = true);
 
     // Get OpenGL version (needs a context)
     static float getGLVersion();
diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index a34ad75..d58b537 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -275,8 +275,8 @@ std::ostream& operator<<(std::ostream& rStrm, const glm::mat4& rMatrix)
     return rStrm;
 }
 
-void OpenGLHelper::createFramebuffer(long nWidth, long nHeight,
-        GLuint& nFramebufferId, GLuint& nRenderbufferDepthId, GLuint& nRenderbufferColorId)
+void OpenGLHelper::createFramebuffer(long nWidth, long nHeight, GLuint& nFramebufferId,
+        GLuint& nRenderbufferDepthId, GLuint& nRenderbufferColorId, bool bRenderbuffer)
 {
     // create a renderbuffer for depth attachment
     glGenRenderbuffers(1, &nRenderbufferDepthId);
@@ -284,13 +284,31 @@ void OpenGLHelper::createFramebuffer(long nWidth, long nHeight,
     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, nWidth, nHeight);
     glBindRenderbuffer(GL_RENDERBUFFER, 0);
 
-    // create a renderbuffer for color attachment
-    glGenRenderbuffers(1, &nRenderbufferColorId);
-    glBindRenderbuffer(GL_RENDERBUFFER, nRenderbufferColorId);
-    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, nWidth, nHeight);
-    glBindRenderbuffer(GL_RENDERBUFFER, 0);
+    if(bRenderbuffer)
+    {
+        // create a renderbuffer for color attachment
+        glGenRenderbuffers(1, &nRenderbufferColorId);
+        glBindRenderbuffer(GL_RENDERBUFFER, nRenderbufferColorId);
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, nWidth, nHeight);
+        glBindRenderbuffer(GL_RENDERBUFFER, 0);
+    }
+    else
+    {
+        glGenTextures(1, &nRenderbufferColorId);
+        glBindTexture(GL_TEXTURE_2D, nRenderbufferColorId);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, nWidth, nHeight, 0,
+                             GL_RGBA, GL_UNSIGNED_BYTE, 0);
+        glBindTexture(GL_TEXTURE_2D, 0);
+
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                GL_TEXTURE_2D, nRenderbufferColorId, 0);
+    }
 
-    // create a framebuffer object and attach renderbuffer and texture
+    // create a framebuffer object and attach renderbuffer
     glGenFramebuffers(1, &nFramebufferId);
     glCheckFramebufferStatus(GL_FRAMEBUFFER);
     glBindFramebuffer(GL_FRAMEBUFFER, nFramebufferId);
commit 779ae371b152748aecf2ea81eca1bdbbf0226389
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Fri Aug 8 01:55:33 2014 +0200

    reuse OpenGLContext in OGL canvas
    
    The only thing that needs to be reimplemented is the pbuffer based
    custom sprite rendering. We should use a FBO with a texture backend
    for that. This will also save several OpenGL context switches!
    
    Change-Id: I4aef33ae2499e44c8b5f41c296d8721cb94a37a1

diff --git a/canvas/Library_oglcanvas.mk b/canvas/Library_oglcanvas.mk
index b179e3b..a5efb6b 100644
--- a/canvas/Library_oglcanvas.mk
+++ b/canvas/Library_oglcanvas.mk
@@ -43,12 +43,12 @@ $(eval $(call gb_Library_add_exception_objects,oglcanvas,\
 
 $(eval $(call gb_Library_use_externals,oglcanvas,\
 	boost_headers \
+	glew \
 ))
 
 ifeq ($(strip $(OS)),MACOSX)
 $(eval $(call gb_Library_use_system_darwin_frameworks,oglcanvas,\
     Cocoa \
-    GLUT \
     OpenGL \
 ))
 
diff --git a/canvas/source/opengl/ogl_canvascustomsprite.cxx b/canvas/source/opengl/ogl_canvascustomsprite.cxx
index 2943f8a..86cbac6 100644
--- a/canvas/source/opengl/ogl_canvascustomsprite.cxx
+++ b/canvas/source/opengl/ogl_canvascustomsprite.cxx
@@ -25,10 +25,7 @@
 #include <basegfx/polygon/b2dpolygontriangulator.hxx>
 #include <basegfx/polygon/b2dpolypolygontools.hxx>
 
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <GL/glext.h>
-
+#include <GL/glew.h>
 
 using namespace ::com::sun::star;
 
@@ -161,10 +158,10 @@ namespace oglcanvas
                 // drats. need to render to temp surface before, and then
                 // composite that to screen
 
-                // TODO(P3): buffer pbuffer, maybe even keep content
-                // (in a texture?)
-                pBufferContext=maCanvasHelper.getDeviceHelper()->createBufferContext(aSpriteSizePixel);
-                pBufferContext->startBufferRendering();
+                // TODO(P3): buffer texture
+                // TODO: moggi: reimplement as FBO with rendering to texture
+                pBufferContext = NULL;
+                // pBufferContext->startBufferRendering();
             }
 
             // this ends up in pBufferContext, if that one's "current"
diff --git a/canvas/source/opengl/ogl_canvashelper.cxx b/canvas/source/opengl/ogl_canvashelper.cxx
index d6db4db..f869179 100644
--- a/canvas/source/opengl/ogl_canvashelper.cxx
+++ b/canvas/source/opengl/ogl_canvashelper.cxx
@@ -36,9 +36,7 @@
 #include "ogl_texturecache.hxx"
 #include "ogl_tools.hxx"
 
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <GL/glext.h>
+#include <GL/glew.h>
 
 #include <boost/scoped_array.hpp>
 
diff --git a/canvas/source/opengl/ogl_canvastools.cxx b/canvas/source/opengl/ogl_canvastools.cxx
index 36693f3..bc5a147 100644
--- a/canvas/source/opengl/ogl_canvastools.cxx
+++ b/canvas/source/opengl/ogl_canvastools.cxx
@@ -22,10 +22,7 @@
 
 #include <com/sun/star/rendering/ARGBColor.hpp>
 
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <GL/glext.h>
-
+#include <GL/glew.h>
 
 using namespace ::com::sun::star;
 
diff --git a/canvas/source/opengl/ogl_spritecanvas.cxx b/canvas/source/opengl/ogl_spritecanvas.cxx
index 32f1db4..3073e2b 100644
--- a/canvas/source/opengl/ogl_spritecanvas.cxx
+++ b/canvas/source/opengl/ogl_spritecanvas.cxx
@@ -27,9 +27,6 @@
 
 #include "ogl_canvascustomsprite.hxx"
 
-#include <GL/gl.h>
-#include <GL/glext.h>
-
 #define SPRITECANVAS_SERVICE_NAME        "com.sun.star.rendering.SpriteCanvas.OGL"
 #define SPRITECANVAS_IMPLEMENTATION_NAME "com.sun.star.comp.rendering.SpriteCanvas.OGL"
 
diff --git a/canvas/source/opengl/ogl_spritedevicehelper.cxx b/canvas/source/opengl/ogl_spritedevicehelper.cxx
index c7d3bea..cd29f37 100644
--- a/canvas/source/opengl/ogl_spritedevicehelper.cxx
+++ b/canvas/source/opengl/ogl_spritedevicehelper.cxx
@@ -30,29 +30,10 @@
 #include <vcl/canvastools.hxx>
 #include <toolkit/helper/vclunohelper.hxx>
 
-#define GL_GLEXT_PROTOTYPES
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <GL/glext.h>
-
-namespace unx
-{
- #include <X11/keysym.h>
- #include <X11/X.h>
- #include <GL/glx.h>
- #include <GL/glxext.h>
-}
-
+#include <vcl/opengl/OpenGLHelper.hxx>
 
 using namespace ::com::sun::star;
 
-static bool lcl_bErrorTriggered=false;
-static int lcl_XErrorHandler( unx::Display*, unx::XErrorEvent* )
-{
-    lcl_bErrorTriggered = true;
-    return 0;
-}
-
 static void initContext()
 {
     // need the backside for mirror effects
@@ -92,251 +73,14 @@ static void initTransformation(const ::Size& rSize, bool bMirror=false)
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 }
 
-static boost::shared_ptr<SystemChildWindow> createChildWindow( unx::XVisualInfo*& viWin,
-                                                               unx::XVisualInfo*& viPB,
-                                                               void*&             fbConfig,
-                                                               Window&            rWindow,
-                                                               unx::Display*      pDisplay,
-                                                               int                nScreen )
-{
-    // select appropriate visual
-    static int winAttrList3[] =
-        {
-            GLX_RGBA,//only TrueColor or DirectColor
-            //single buffered
-            GLX_RED_SIZE,4,//use the maximum red bits, with a minimum of 4 bits
-            GLX_GREEN_SIZE,4,//use the maximum green bits, with a minimum of 4 bits
-            GLX_BLUE_SIZE,4,//use the maximum blue bits, with a minimum of 4 bits
-            GLX_DEPTH_SIZE,0,//no depth buffer
-            None
-        };
-    static int pBufAttrList3[] =
-        {
-            GLX_DOUBLEBUFFER,False,// never doublebuffer pbuffer
-            GLX_RED_SIZE,4,//use the maximum red bits, with a minimum of 4 bits
-            GLX_GREEN_SIZE,4,//use the maximum green bits, with a minimum of 4 bits
-            GLX_BLUE_SIZE,4,//use the maximum blue bits, with a minimum of 4 bits
-            GLX_ALPHA_SIZE,4,
-            GLX_DEPTH_SIZE,0,//no depth buffer
-            GLX_RENDER_TYPE,   GLX_RGBA_BIT,
-            GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
-            None
-        };
-    static int winAttrList2[] =
-        {
-            GLX_RGBA,//only TrueColor or DirectColor
-            /// single buffered
-            GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
-            GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
-            GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits
-            GLX_DEPTH_SIZE,1,/// use the maximum depth bits, making sure there is a depth buffer
-            None
-        };
-    static int pBufAttrList2[] =
-        {
-            GLX_DOUBLEBUFFER,False,// never doublebuffer pbuffer
-            GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
-            GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
-            GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits
-            GLX_ALPHA_SIZE,4,
-            GLX_DEPTH_SIZE,1,/// use the maximum depth bits, making sure there is a depth buffer
-            GLX_RENDER_TYPE,   GLX_RGBA_BIT,
-            GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
-            None
-        };
-    static int winAttrList1[] =
-        {
-            GLX_RGBA,//only TrueColor or DirectColor
-            GLX_DOUBLEBUFFER,/// only double buffer
-            GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
-            GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
-            GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits
-            GLX_DEPTH_SIZE,0,/// no depth buffer
-            None
-        };
-    static int pBufAttrList1[] =
-        {
-            GLX_DOUBLEBUFFER,False,// never doublebuffer pbuffer
-            GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
-            GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
-            GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits
-            GLX_ALPHA_SIZE,4,
-            GLX_DEPTH_SIZE,0,/// no depth buffer
-            GLX_RENDER_TYPE,   GLX_RGBA_BIT,
-            GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
-            None
-        };
-    static int winAttrList0[] =
-        {
-            GLX_RGBA,//only TrueColor or DirectColor
-            GLX_DOUBLEBUFFER,// only double buffer
-            GLX_RED_SIZE,4,// use the maximum red bits, with a minimum of 4 bits
-            GLX_GREEN_SIZE,4,// use the maximum green bits, with a minimum of 4 bits
-            GLX_BLUE_SIZE,4,// use the maximum blue bits, with a minimum of 4 bits
-            GLX_DEPTH_SIZE,1,// use the maximum depth bits, making sure there is a depth buffer
-            None
-        };
-    static int pBufAttrList0[] =
-        {
-            GLX_DOUBLEBUFFER,False,// never doublebuffer pbuffer
-            GLX_RED_SIZE,4,// use the maximum red bits, with a minimum of 4 bits
-            GLX_GREEN_SIZE,4,// use the maximum green bits, with a minimum of 4 bits
-            GLX_BLUE_SIZE,4,// use the maximum blue bits, with a minimum of 4 bits
-            GLX_ALPHA_SIZE,4,
-            GLX_DEPTH_SIZE,1,// use the maximum depth bits, making sure there is a depth buffer
-            GLX_RENDER_TYPE,   GLX_RGBA_BIT,
-            GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
-            None
-        };
-    static int* winAttrTable[] =
-        {
-            winAttrList0,
-            winAttrList1,
-            winAttrList2,
-            winAttrList3,
-            NULL
-        };
-    static int* pBufAttrTable[] =
-        {
-            pBufAttrList0,
-            pBufAttrList1,
-            pBufAttrList2,
-            pBufAttrList3,
-            NULL
-        };
-    int** pWinAttributeTable = winAttrTable;
-    int** pBufAttributeTable = pBufAttrTable;
-
-    boost::shared_ptr<SystemChildWindow> pResult;
-    unx::GLXFBConfig* fbConfigs=NULL;
-    int nConfigs, nVal;
-    while( *pWinAttributeTable && *pBufAttributeTable )
-    {
-        // try to find a window visual for the current set of
-        // attributes
-        viWin = unx::glXChooseVisual( pDisplay,
-                                      nScreen,
-                                      *pWinAttributeTable );
-        if( viWin )
-        {
-            // try to find a framebuffer config for the current set of
-            // attributes
-            fbConfigs = glXChooseFBConfig( pDisplay,
-                                           nScreen,
-                                           *pBufAttributeTable,
-                                           &nConfigs );
-            // don't use glXGetFBConfigs, that does not list alpha-configs
-            // fbConfigs = unx::glXGetFBConfigs(pDisplay, nScreen, &nConfigs);
-            for(int i=0; i<nConfigs; i++)
-            {
-                viPB = glXGetVisualFromFBConfig(pDisplay, fbConfigs[i]);
-                if( viPB && viPB->visualid != viWin->visualid )
-                {
-                    glXGetFBConfigAttrib(pDisplay,
-                                         fbConfigs[i],
-                                         GLX_DRAWABLE_TYPE,
-                                         &nVal);
-
-                    if( (GLX_PBUFFER_BIT|GLX_WINDOW_BIT|GLX_PIXMAP_BIT)
-                        == (nVal & (GLX_PBUFFER_BIT|GLX_WINDOW_BIT|GLX_PIXMAP_BIT)) )
-                    {
-                        SystemWindowData winData;
-                        winData.nSize = sizeof(winData);
-                        SAL_INFO("canvas.ogl", "using VisualID " << viWin->visualid << " for OpenGL canvas");
-                        winData.pVisual = (void*)(viWin->visual);
-                        pResult.reset( new SystemChildWindow(&rWindow, 0, &winData, false) );
-
-                        if( pResult->GetSystemData() )
-                        {
-                            fbConfig = &fbConfigs[i];
-                            return pResult;
-                        }
-
-                        pResult.reset();
-                    }
-
-                    XFree(viPB);
-                }
-            }
-
-            XFree(viWin);
-        }
-
-        ++pWinAttributeTable;
-        ++pBufAttributeTable;
-    }
-
-    return pResult;
-}
-
-
 namespace oglcanvas
 {
-    /** Compile shader program
-
-        Code courtesy rodo
-     */
-    void SpriteDeviceHelper::compileShader(unsigned int& o_rShaderHandle,
-                                           unsigned int  eShaderType,
-                                           const char*   pShaderSourceCode)
-    {
-        GLint nCompileStatus;
-        char log[1024];
-
-        o_rShaderHandle = glCreateShader( eShaderType );
-        glShaderSource( o_rShaderHandle, 1, &pShaderSourceCode, NULL );
-        glCompileShader( o_rShaderHandle );
-        glGetShaderInfoLog( o_rShaderHandle, sizeof(log), NULL, log );
-        SAL_INFO("canvas.ogl", "shader compile log: " << log);
-
-        glGetShaderiv( o_rShaderHandle, GL_COMPILE_STATUS, &nCompileStatus );
-        if( !nCompileStatus )
-        {
-            glDeleteShader(o_rShaderHandle);
-            o_rShaderHandle=0;
-        }
-    }
-
-    /** Link vertex & fragment shaders
-
-        Code courtesy rodo
-     */
-    void SpriteDeviceHelper::linkShaders(unsigned int& o_rProgramHandle,
-                                         unsigned int  nVertexProgramId,
-                                         unsigned int  nFragmentProgramId)
-    {
-        if( !nVertexProgramId || !nFragmentProgramId )
-            return;
-
-        o_rProgramHandle = glCreateProgram();
-        glAttachShader( o_rProgramHandle, nVertexProgramId );
-        glAttachShader( o_rProgramHandle, nFragmentProgramId );
-
-        char log[1024];
-        GLint nProgramLinked;
-
-        glLinkProgram( o_rProgramHandle );
-        glGetProgramInfoLog( o_rProgramHandle, sizeof(log), NULL, log );
-        SAL_INFO("canvas.ogl", "shader program link log: " << log);
-        glGetProgramiv( o_rProgramHandle, GL_LINK_STATUS, &nProgramLinked );
-
-        if( !nProgramLinked )
-        {
-            glDeleteProgram(o_rProgramHandle);
-            o_rProgramHandle=0;
-        }
-    }
 
     SpriteDeviceHelper::SpriteDeviceHelper() :
         mpDevice(NULL),
         mpSpriteCanvas(NULL),
         maActiveSprites(),
         maLastUpdate(),
-        mpChildWindow(),
-        mpDisplay(NULL),
-        mpGLContext(NULL),
-        mpGLPBufContext(NULL),
-        mpFBConfig(NULL),
         mpTextureCache(new TextureCache()),
         mnLinearTwoColorGradientProgram(0),
         mnLinearMultiColorGradientProgram(0),
@@ -357,126 +101,31 @@ namespace oglcanvas
                 VCLUnoHelper::GetInterface(&rWindow),
                 uno::UNO_QUERY_THROW) );
 
-        // init OpenGL
-        const SystemEnvData* sysData(rWindow.GetSystemData());
-        unx::Display* pDisplay=reinterpret_cast<unx::Display*>(sysData->pDisplay);
-        mpDisplay=pDisplay;
-        if( !unx::glXQueryExtension(pDisplay, NULL, NULL) )
-            return;
-
-        unx::Window xWindow = sysData->aWindow;
-        unx::XWindowAttributes xAttr;
-        unx::XGetWindowAttributes( pDisplay, xWindow, &xAttr );
-        int nScreen = XScreenNumberOfScreen( xAttr.screen );
-
-        unx::Window childXWindow=0;
-        unx::XVisualInfo* viWin=NULL;
-        unx::XVisualInfo* viPB=NULL;
-        mpChildWindow=createChildWindow(viWin,viPB,mpFBConfig,
-                                        rWindow,pDisplay,nScreen);
-
-        // tweak SysChild window to act as an input-transparent
-        // overlay
-        if( mpChildWindow )
-        {
-            childXWindow=mpChildWindow->GetSystemData()->aWindow;
-            mpChildWindow->SetMouseTransparent(true);
-            mpChildWindow->SetParentClipMode( PARENTCLIPMODE_NOCLIP );
-            mpChildWindow->EnableEraseBackground(false);
-            mpChildWindow->SetControlForeground();
-            mpChildWindow->SetControlBackground();
-            mpChildWindow->EnablePaint(false);
-
-            unx::GLXContext pContext1 =
-                glXCreateContext(pDisplay,
-                                 viWin,
-                                 0,
-                                 GL_TRUE);
-            mpGLContext = pContext1;
-
-            unx::GLXContext pContext2 =
-                glXCreateContext( pDisplay,
-                                  viPB,
-                                  pContext1,
-                                  GL_TRUE );
-            mpGLPBufContext = pContext2;
-
-            XFree(viWin);
-            XFree(viPB);
-
-            if( !glXMakeCurrent( pDisplay,
-                                 childXWindow,
-                                 pContext1) )
-            {
-                glXDestroyContext(pDisplay, pContext1);
-                glXDestroyContext(pDisplay, pContext2);
-                throw lang::NoSupportException("Could not select OpenGL context!");
-            }
-
-            const GLubyte* extensions=glGetString( GL_EXTENSIONS );
-            if( gluCheckExtension((const GLubyte*)"GLX_SGI_swap_control", extensions) )
-            {
-                // try to enable vsync
-                typedef GLint (*glXSwapIntervalProc)(GLint);
-                glXSwapIntervalProc glXSwapInterval =
-                    (glXSwapIntervalProc) unx::glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI");
-                if( glXSwapInterval )
-                {
-                    int (*oldHandler)(unx::Display*, unx::XErrorEvent*);
-
-                    // synchronize on global mutex - no other ogl
-                    // canvas instance permitted to enter here
-                    {
-                        ::osl::MutexGuard aGuard( *::osl::Mutex::getGlobalMutex() );
-
-                        // replace error handler temporarily
-                        oldHandler = unx::XSetErrorHandler( lcl_XErrorHandler );
-
-                        lcl_bErrorTriggered = false;
-
-                        // Note: if this fails, so be it. Buggy
-                        // drivers will then not have vsync.
-                        glXSwapInterval(1);
-
-                        // sync so that we possibly get an XError
-                        unx::glXWaitGL();
-                        XSync(pDisplay, false);
-
-                        unx::XSetErrorHandler( oldHandler );
-                    }
-                }
-            }
-
-            // init window context
-            initContext();
-
-            mnLinearMultiColorGradientProgram =
-                OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "linearMultiColorGradientFragmentShader.glsl");
+        maContext.init(&rWindow);
+        // init window context
+        initContext();
 
-            mnLinearTwoColorGradientProgram =
-                OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "linearTwoColorGradientFragmentShader.glsl");
+        mnLinearMultiColorGradientProgram =
+            OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "linearMultiColorGradientFragmentShader.glsl");
 
-            mnRadialMultiColorGradientProgram =
-                OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "radialMultiColorGradientFragmentShader.glsl");
+        mnLinearTwoColorGradientProgram =
+            OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "linearTwoColorGradientFragmentShader.glsl");
 
-            mnRadialTwoColorGradientProgram =
-                OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "radialTwoColorGradientFragmentShader.glsl");
+        mnRadialMultiColorGradientProgram =
+            OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "radialMultiColorGradientFragmentShader.glsl");
 
-            mnRectangularMultiColorGradientProgram =
-                OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "rectangularMultiColorGradientFragmentShader.glsl");
+        mnRadialTwoColorGradientProgram =
+            OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "radialTwoColorGradientFragmentShader.glsl");
 
-            mnRectangularTwoColorGradientProgram =
-                OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "rectangularTwoColorGradientFragmentShader.glsl");
+        mnRectangularMultiColorGradientProgram =
+            OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "rectangularMultiColorGradientFragmentShader.glsl");
 
-            glXMakeCurrent(pDisplay, None, NULL);
-        }
+        mnRectangularTwoColorGradientProgram =
+            OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "rectangularTwoColorGradientFragmentShader.glsl");
 
-        if( !mpGLContext || glGetError() != GL_NO_ERROR )
-            throw lang::NoSupportException(
-                "Could not create OpenGL context, or an error occurred doing so!");
+        maContext.makeCurrent();
 
         notifySizeUpdate(rViewArea);
-        mpChildWindow->Show();
         // TODO(E3): check for GL_ARB_imaging extension
     }
 
@@ -487,7 +136,7 @@ namespace oglcanvas
         mpDevice = NULL;
         mpTextureCache.reset();
 
-        if( mpGLContext )
+        if( maContext.isInitialized() )
         {
             glDeleteProgram( mnRectangularTwoColorGradientProgram );
             glDeleteProgram( mnRectangularMultiColorGradientProgram );
@@ -495,40 +144,35 @@ namespace oglcanvas
             glDeleteProgram( mnRadialMultiColorGradientProgram );
             glDeleteProgram( mnLinearTwoColorGradientProgram );
             glDeleteProgram( mnLinearMultiColorGradientProgram );
-
-            glXDestroyContext(reinterpret_cast<unx::Display*>(mpDisplay),
-                              reinterpret_cast<unx::GLXContext>(mpGLContext));
         }
-
-        mpDisplay = NULL;
-        mpGLContext = NULL;
-        mpChildWindow.reset();
     }
 
     geometry::RealSize2D SpriteDeviceHelper::getPhysicalResolution()
     {
-        if( !mpChildWindow )
+        if( !maContext.isInitialized() )
             return ::canvas::tools::createInfiniteSize2D(); // we're disposed
 
         // Map a one-by-one millimeter box to pixel
-        const MapMode aOldMapMode( mpChildWindow->GetMapMode() );
-        mpChildWindow->SetMapMode( MapMode(MAP_MM) );
-        const Size aPixelSize( mpChildWindow->LogicToPixel(Size(1,1)) );
-        mpChildWindow->SetMapMode( aOldMapMode );
+        SystemChildWindow* pChildWindow = maContext.getChildWindow();
+        const MapMode aOldMapMode( pChildWindow->GetMapMode() );
+        pChildWindow->SetMapMode( MapMode(MAP_MM) );
+        const Size aPixelSize( pChildWindow->LogicToPixel(Size(1,1)) );
+        pChildWindow->SetMapMode( aOldMapMode );
 
         return ::vcl::unotools::size2DFromSize( aPixelSize );
     }
 
     geometry::RealSize2D SpriteDeviceHelper::getPhysicalSize()
     {
-        if( !mpChildWindow )
+        if( !maContext.isInitialized() )
             return ::canvas::tools::createInfiniteSize2D(); // we're disposed
 
         // Map the pixel dimensions of the output window to millimeter
-        const MapMode aOldMapMode( mpChildWindow->GetMapMode() );
-        mpChildWindow->SetMapMode( MapMode(MAP_MM) );
-        const Size aLogSize( mpChildWindow->PixelToLogic(mpChildWindow->GetOutputSizePixel()) );
-        mpChildWindow->SetMapMode( aOldMapMode );
+        SystemChildWindow* pChildWindow = maContext.getChildWindow();
+        const MapMode aOldMapMode( pChildWindow->GetMapMode() );
+        pChildWindow->SetMapMode( MapMode(MAP_MM) );
+        const Size aLogSize( pChildWindow->PixelToLogic(pChildWindow->GetOutputSizePixel()) );
+        pChildWindow->SetMapMode( aOldMapMode );
 
         return ::vcl::unotools::size2DFromSize( aLogSize );
     }
@@ -650,13 +294,14 @@ namespace oglcanvas
     bool SpriteDeviceHelper::showBuffer( bool bIsVisible, bool /*bUpdateAll*/ )
     {
         // hidden or disposed?
-        if( !bIsVisible || !mpChildWindow || !mpSpriteCanvas )
+        if( !bIsVisible || !maContext.isInitialized() || !mpSpriteCanvas )
             return false;
 
         if( !activateWindowContext() )
             return false;
 
-        const ::Size& rOutputSize=mpChildWindow->GetSizePixel();
+        SystemChildWindow* pChildWindow = maContext.getChildWindow();
+        const ::Size& rOutputSize = pChildWindow->GetSizePixel();
         initTransformation(rOutputSize);
 
         // render the actual spritecanvas content
@@ -695,13 +340,17 @@ namespace oglcanvas
         aVec.push_back(mpTextureCache->getCacheHitCount());
         renderOSD( aVec, 20 );
 
+        /*
+         * TODO: moggi: fix it!
         // switch buffer, sync etc.
-        const unx::Window aXWindow=mpChildWindow->GetSystemData()->aWindow;
+        const unx::Window aXWindow=pChildWindow->GetSystemData()->aWindow;
         unx::glXSwapBuffers(reinterpret_cast<unx::Display*>(mpDisplay),
                             aXWindow);
-        mpChildWindow->Show();
+        pChildWindow->Show();
         unx::glXWaitGL();
         XSync( reinterpret_cast<unx::Display*>(mpDisplay), false );
+        */
+        maContext.swapBuffers();
 
         // flush texture cache, such that it does not build up
         // indefinitely.
@@ -725,7 +374,8 @@ namespace oglcanvas
 
     uno::Any SpriteDeviceHelper::getDeviceHandle() const
     {
-        return uno::makeAny( reinterpret_cast< sal_Int64 >(mpChildWindow.get()) );
+        const SystemChildWindow* pChildWindow = maContext.getChildWindow();
+        return uno::makeAny( reinterpret_cast< sal_Int64 >(pChildWindow) );
     }
 
     uno::Any SpriteDeviceHelper::getSurfaceHandle() const
@@ -743,9 +393,12 @@ namespace oglcanvas
 
     void SpriteDeviceHelper::notifySizeUpdate( const awt::Rectangle& rBounds )
     {
-        if( mpChildWindow )
-            mpChildWindow->setPosSizePixel(
+        if( maContext.isInitialized() )
+        {
+            SystemChildWindow* pChildWindow = maContext.getChildWindow();
+            pChildWindow->setPosSizePixel(
                 0,0,rBounds.Width,rBounds.Height);
+        }
     }
 
     void SpriteDeviceHelper::dumpScreenContent() const
@@ -875,146 +528,51 @@ namespace oglcanvas
             setupUniforms(mnRectangularTwoColorGradientProgram, pColors[0], pColors[1], rTexTransform);
     }
 
-    bool SpriteDeviceHelper::activatePBufferContext(const ::basegfx::B2IVector& rSize,
-                                                    unsigned int                PBuffer) const
+    bool SpriteDeviceHelper::activateWindowContext()
     {
-        if( !glXMakeCurrent( reinterpret_cast<unx::Display*>(mpDisplay),
-                             PBuffer,
-                             reinterpret_cast<unx::GLXContext>(mpGLPBufContext)) )
-        {
-            SAL_INFO("canvas.ogl", "SpriteDeviceHelper::activatePBufferContext(): cannot activate GL context");
-            return false;
-        }
-
-        initContext();
-        initTransformation(
-            ::Size(
-                rSize.getX(),
-                rSize.getY()),
-            true);
-
-        return true;
-    }
-
-    bool SpriteDeviceHelper::activateWindowContext() const
-    {
-        const unx::Window aXWindow=mpChildWindow->GetSystemData()->aWindow;
-        if( !glXMakeCurrent( reinterpret_cast<unx::Display*>(mpDisplay),
-                             aXWindow,
-                             reinterpret_cast<unx::GLXContext>(mpGLContext)) )
-        {
-            SAL_INFO("canvas.ogl", "SpriteDeviceHelper::activateWindowContext(): cannot activate GL context");
-            return false;
-        }
-
-        return true;
-    }
-
-    bool SpriteDeviceHelper::updatePBufferTexture( const ::basegfx::B2IVector& rSize,
-                                                   unsigned int                nTextId ) const
-    {
-        glBindTexture( GL_TEXTURE_2D, nTextId );
-        glEnable(GL_TEXTURE_2D);
-        glCopyTexSubImage2D( GL_TEXTURE_2D,
-                             0, 0, 0, 0, 0,
-                             rSize.getX(),
-                             rSize.getY() );
-        glBindTexture(GL_TEXTURE_2D, 0);
-
+        maContext.makeCurrent();
         return true;
     }
 
     namespace
     {
+
+        /*
+         * TODO: mogg: reimplement through FBO with texture as backend
         class BufferContextImpl : public IBufferContext
         {
             ::basegfx::B2IVector       maSize;
             const SpriteDeviceHelper&  mrDeviceHelper;
-            unx::GLXPbuffer            mpPBuffer;
-#if 0
-            unx::Display*              mpDisplay;
-#endif
-            unsigned int               mnTexture;
 
             virtual bool startBufferRendering() SAL_OVERRIDE
             {
-                return mrDeviceHelper.activatePBufferContext(maSize,mpPBuffer);
+                return false;
             }
 
             virtual bool endBufferRendering() SAL_OVERRIDE
             {
-                mrDeviceHelper.updatePBufferTexture(maSize,mnTexture);
-                if( !mrDeviceHelper.activateWindowContext() )
-                    return false;
-
-                glBindTexture( GL_TEXTURE_2D, mnTexture );
-
-                return true;
+                return false;
             }
 
         public:
             BufferContextImpl(const SpriteDeviceHelper&   rDeviceHelper,
-                              unx::GLXPbuffer             pBuffer,
-                              unx::Display*
-#if 0
-                                                          pDisplay
-#endif
-                              ,
                               const ::basegfx::B2IVector& rSize) :
                 maSize(rSize),
                 mrDeviceHelper(rDeviceHelper),
-                mpPBuffer(pBuffer),
-#if 0
-                mpDisplay(pDisplay),
-#endif
                 mnTexture(0)
             {
-                glGenTextures( 1, &mnTexture );
-#if 1
-                glBindTexture( GL_TEXTURE_2D, mnTexture );
-                glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
-                glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
-                glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA,
-                              maSize.getX(), maSize.getY(),
-                              0, GL_RGBA, GL_UNSIGNED_BYTE, new int[maSize.getX()*maSize.getY()] );
-#endif
             }
 
             virtual ~BufferContextImpl()
             {
-#if 0
-                glBindTexture(GL_TEXTURE_2D, 0);
-                glDeleteTextures( 1, &mnTexture );
-                glXDestroyPbuffer( mpDisplay, mpPBuffer );
-#endif
             }
         };
+        */
     }
 
-    IBufferContextSharedPtr SpriteDeviceHelper::createBufferContext(const ::basegfx::B2IVector& rSize) const
+    IBufferContextSharedPtr SpriteDeviceHelper::createBufferContext(const ::basegfx::B2IVector& ) const
     {
-        int pBufAttribs[] =
-            {
-                GLX_PBUFFER_WIDTH,   rSize.getX(),
-                GLX_PBUFFER_HEIGHT,  rSize.getY(),
-                GLX_LARGEST_PBUFFER, False,
-                None
-            };
-
-        unx::GLXPbuffer pBuffer;
-        pBuffer = unx::glXCreatePbuffer( reinterpret_cast<unx::Display*>(mpDisplay),
-                                         *reinterpret_cast<unx::GLXFBConfig*>(mpFBConfig),
-                                         pBufAttribs );
-
-        IBufferContextSharedPtr pRet;
-        if( pBuffer )
-            pRet.reset(new BufferContextImpl(
-                           *this,
-                           pBuffer,
-                           reinterpret_cast<unx::Display*>(mpDisplay),
-                           rSize));
-
-        return pRet;
+        return NULL;
     }
 
     TextureCache& SpriteDeviceHelper::getTextureCache() const
diff --git a/canvas/source/opengl/ogl_spritedevicehelper.hxx b/canvas/source/opengl/ogl_spritedevicehelper.hxx
index 5fe9ed1..f43a3af 100644
--- a/canvas/source/opengl/ogl_spritedevicehelper.hxx
+++ b/canvas/source/opengl/ogl_spritedevicehelper.hxx
@@ -10,6 +10,8 @@
 #ifndef INCLUDED_CANVAS_SOURCE_OPENGL_OGL_SPRITEDEVICEHELPER_HXX
 #define INCLUDED_CANVAS_SOURCE_OPENGL_OGL_SPRITEDEVICEHELPER_HXX
 
+#include <vcl/opengl/OpenGLContext.hxx>
+
 #include <rtl/ref.hxx>
 #include <canvas/elapsedtime.hxx>
 #include <com/sun/star/rendering/XGraphicDevice.hpp>
@@ -20,7 +22,6 @@
 
 #include <set>
 
-
 class Window;
 class SystemChildWindow;
 namespace basegfx{ class B2IVector; class B2DHomMatrix; }
@@ -113,26 +114,11 @@ namespace oglcanvas
         /// Get instance of internal texture cache
         TextureCache& getTextureCache() const;
 
-
-
-        // nobody except IBufferContext implementations are supposed
-        // to use this
-        bool activatePBufferContext(const ::basegfx::B2IVector& rSize,
-                                    unsigned int                PBuffer) const;
-        bool activateWindowContext() const;
-        bool updatePBufferTexture( const ::basegfx::B2IVector&,
-                                   unsigned int ) const;
+        bool activateWindowContext();
 
     private:
         void resize( const ::basegfx::B2IVector& rNewSize );
 
-        void compileShader(unsigned int& o_rShaderHandle,
-                           unsigned int  eShaderType,
-                           const char*   pShaderSourceCode);
-        void linkShaders(unsigned int& o_rProgramHandle,
-                         unsigned int  nVertexProgramId,
-                         unsigned int  nFragmentProgramId);
-
         /** Phyical output device
 
             Deliberately not a refcounted reference, because of
@@ -149,28 +135,16 @@ namespace oglcanvas
         /// For the frame counter timings
         ::canvas::tools::ElapsedTime                       maLastUpdate;
 
-        boost::shared_ptr<SystemChildWindow>               mpChildWindow;
-        void*                                              mpDisplay;
-        void*                                              mpGLContext;
-        void*                                              mpGLPBufContext;
-        void*                                              mpFBConfig;
-
         boost::shared_ptr<TextureCache>                    mpTextureCache;
 
-        unsigned int                                       mnDummyVertexProgram;
-
-        unsigned int                                       mnLinearTwoColorGradientFragmentProgram;
-        unsigned int                                       mnLinearMultiColorGradientFragmentProgram;
-        unsigned int                                       mnRadialTwoColorGradientFragmentProgram;
-        unsigned int                                       mnRadialMultiColorGradientFragmentProgram;
-        unsigned int                                       mnRectangularTwoColorGradientFragmentProgram;
-        unsigned int                                       mnRectangularMultiColorGradientFragmentProgram;
         unsigned int                                       mnLinearTwoColorGradientProgram;
         unsigned int                                       mnLinearMultiColorGradientProgram;
         unsigned int                                       mnRadialTwoColorGradientProgram;
         unsigned int                                       mnRadialMultiColorGradientProgram;
         unsigned int                                       mnRectangularTwoColorGradientProgram;
         unsigned int                                       mnRectangularMultiColorGradientProgram;
+
+        OpenGLContext maContext;
     };
 }
 
diff --git a/canvas/source/opengl/ogl_texturecache.cxx b/canvas/source/opengl/ogl_texturecache.cxx
index 952f36a..426e69c 100644
--- a/canvas/source/opengl/ogl_texturecache.cxx
+++ b/canvas/source/opengl/ogl_texturecache.cxx
@@ -13,9 +13,7 @@
 
 #include <com/sun/star/geometry/IntegerSize2D.hpp>
 
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <GL/glext.h>
+#include <GL/glew.h>
 
 using namespace ::com::sun::star;
 
diff --git a/canvas/source/opengl/ogl_tools.hxx b/canvas/source/opengl/ogl_tools.hxx
index 6c23be7..8133212 100644
--- a/canvas/source/opengl/ogl_tools.hxx
+++ b/canvas/source/opengl/ogl_tools.hxx
@@ -11,7 +11,7 @@
 #define INCLUDED_CANVAS_SOURCE_OPENGL_OGL_TOOLS_HXX
 
 #include <sal/config.h>
-#include <GL/gl.h>
+#include <GL/glew.h>
 
 
 namespace oglcanvas
diff --git a/configure.ac b/configure.ac
index ee388ea..38cb6bd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10556,8 +10556,7 @@ if test "x$enable_opengl" = "xno"; then
 elif test "$_os" = "Darwin"; then
     # We use frameworks on Mac OS X, no need for detail checks
     ENABLE_OPENGL=TRUE
-    ENABLE_OPENGL_CANVAS=
-    add_warning "openGL canvas not adapted for Mac yet - disabling"
+    ENABLE_OPENGL_CANVAS=TRUE
     SYSTEM_MESA_HEADERS=TRUE
     AC_MSG_RESULT([yes])
 elif test $_os = WINNT; then
diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index 0dc0fa5..8faaf7b 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -162,6 +162,9 @@ public:
     void setWinSize(const Size& rSize);
     GLWindow& getOpenGLWindow() { return m_aGLWin;}
 
+    SystemChildWindow* getChildWindow();
+    const SystemChildWindow* getChildWindow() const;
+
     void renderToFile();
 
     bool isInitialized()
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index c17bcac..ca61f0e 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -898,4 +898,14 @@ void OpenGLContext::show()
         m_pWindow->Show();
 }
 
+SystemChildWindow* OpenGLContext::getChildWindow()
+{
+    return m_pChildWindow;
+}
+
+const SystemChildWindow* OpenGLContext::getChildWindow() const
+{
+    return m_pChildWindow;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit a7f3c73fd76b6955862a77cbb403b7b5b47582bd
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu Aug 7 00:01:02 2014 +0200

    extract shaders to own file and use shared shader loading
    
    Change-Id: I1af7e03a3e46f3cb49162be9351ce22f54d08c52

diff --git a/canvas/Library_oglcanvas.mk b/canvas/Library_oglcanvas.mk
index fca6996..b179e3b 100644
--- a/canvas/Library_oglcanvas.mk
+++ b/canvas/Library_oglcanvas.mk
@@ -20,6 +20,7 @@ $(eval $(call gb_Library_use_libraries,oglcanvas,\
 	cppuhelper \
 	comphelper \
 	vcl \
+	vclopengl \
 	tk \
 	tl \
 	i18nlangtag \
diff --git a/canvas/Module_canvas.mk b/canvas/Module_canvas.mk
index 310ad2a..a655ed1 100644
--- a/canvas/Module_canvas.mk
+++ b/canvas/Module_canvas.mk
@@ -24,6 +24,7 @@ $(eval $(call gb_Module_add_targets,canvas,\
 	Library_canvastools \
 	Library_simplecanvas \
 	Library_vclcanvas \
+	Package_opengl \
 ))
 
 ifeq ($(ENABLE_CAIRO_CANVAS),TRUE)
diff --git a/canvas/Package_opengl.mk b/canvas/Package_opengl.mk
new file mode 100644
index 0000000..af256bf
--- /dev/null
+++ b/canvas/Package_opengl.mk
@@ -0,0 +1,22 @@
+# -*- 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/.
+#
+
+$(eval $(call gb_Package_Package,canvas_opengl_shader,$(SRCDIR)/canvas/opengl))
+
+$(eval $(call gb_Package_add_files,canvas_opengl_shader,$(LIBO_BIN_FOLDER)/opengl,\
+	dummyVertexShader.glsl \
+	linearMultiColorGradientFragmentShader.glsl \
+	linearTwoColorGradientFragmentShader.glsl \
+	radialMultiColorGradientFragmentShader.glsl \
+	radialTwoColorGradientFragmentShader.glsl \
+	rectangularMultiColorGradientFragmentShader.glsl \
+	rectangularTwoColorGradientFragmentShader.glsl \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/canvas/opengl/dummyVertexShader.glsl b/canvas/opengl/dummyVertexShader.glsl
new file mode 100644
index 0000000..2948ee9
--- /dev/null
+++ b/canvas/opengl/dummyVertexShader.glsl
@@ -0,0 +1,17 @@
+/* -*- 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/.
+ */
+
+varying vec2 v_textureCoords2d;
+void main(void)
+{
+    gl_Position = ftransform();
+    v_textureCoords2d = gl_MultiTexCoord0.st;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/opengl/linearMultiColorGradientFragmentShader.glsl b/canvas/opengl/linearMultiColorGradientFragmentShader.glsl
new file mode 100644
index 0000000..a3f3358
--- /dev/null
+++ b/canvas/opengl/linearMultiColorGradientFragmentShader.glsl
@@ -0,0 +1,45 @@
+/* -*- 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/.
+ */
+
+#version 120
+
+uniform int       i_nColors;
+uniform sampler1D t_colorArray4d;
+uniform sampler1D t_stopArray1d;
+uniform mat3x2    m_transform;
+varying vec2      v_textureCoords2d;
+
+int findBucket(float t)
+{
+    int nMinBucket=0;
+    while( nMinBucket < i_nColors &&
+            texture1D(t_stopArray1d, nMinBucket).s < t )
+        ++nMinBucket;
+    return max(nMinBucket-1,0);
+}
+
+void main(void)
+{
+    const float fAlpha =
+        clamp( (m_transform * vec3(v_textureCoords2d,1)).s,
+                0.0, 1.0 );
+
+    const int nMinBucket=findBucket( fAlpha );
+
+    const float fLerp =
+        (fAlpha-texture1D(t_stopArray1d, nMinBucket).s) /
+        (texture1D(t_stopArray1d, nMinBucket+1).s -
+         texture1D(t_stopArray1d, nMinBucket).s);
+
+    gl_FragColor = mix(texture1D(t_colorArray4d, nMinBucket),
+            texture1D(t_colorArray4d, nMinBucket+1),
+            fLerp);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/opengl/linearTwoColorGradientFragmentShader.glsl b/canvas/opengl/linearTwoColorGradientFragmentShader.glsl
new file mode 100644
index 0000000..8659bfd
--- /dev/null
+++ b/canvas/opengl/linearTwoColorGradientFragmentShader.glsl
@@ -0,0 +1,26 @@
+/* -*- 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/.
+ */
+
+#version 120
+
+uniform vec4   v_startColor4d;
+uniform vec4   v_endColor4d;
+uniform mat3x2 m_transform;
+varying vec2   v_textureCoords2d;
+
+void main(void)
+{
+    gl_FragColor = mix(v_startColor4d,
+            v_endColor4d,
+            clamp(
+                (m_transform * vec3(v_textureCoords2d,1)).s,
+                0.0, 1.0));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/opengl/radialMultiColorGradientFragmentShader.glsl b/canvas/opengl/radialMultiColorGradientFragmentShader.glsl
new file mode 100644
index 0000000..6f61a76
--- /dev/null
+++ b/canvas/opengl/radialMultiColorGradientFragmentShader.glsl
@@ -0,0 +1,48 @@
+/* -*- 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/.
+ */
+
+#version 120
+
+uniform int       i_nColors;
+uniform sampler1D t_colorArray4d;
+uniform sampler1D t_stopArray1d;
+uniform mat3x2    m_transform;
+varying vec2      v_textureCoords2d;
+const vec2        v_center2d = vec2(0,0);
+
+int findBucket(float t)
+{
+    int nMinBucket=0;
+    while( nMinBucket < i_nColors &&
+            texture1D(t_stopArray1d, nMinBucket).s < t )
+        ++nMinBucket;
+    return max(nMinBucket-1,0);
+}
+
+void main(void)
+{
+    const float fAlpha =
+        clamp( 1.0 - distance(
+                    vec2( m_transform * vec3(v_textureCoords2d,1)),
+                    v_center2d),
+                0.0, 1.0 );
+
+    const int nMinBucket=findBucket( fAlpha );
+
+    const float fLerp =
+        (fAlpha-texture1D(t_stopArray1d, nMinBucket).s) /
+        (texture1D(t_stopArray1d, nMinBucket+1).s -
+         texture1D(t_stopArray1d, nMinBucket).s);
+
+    gl_FragColor = mix(texture1D(t_colorArray4d, nMinBucket),
+            texture1D(t_colorArray4d, nMinBucket+1),
+            fLerp);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/opengl/radialTwoColorGradientFragmentShader.glsl b/canvas/opengl/radialTwoColorGradientFragmentShader.glsl
new file mode 100644
index 0000000..a5d6134
--- /dev/null
+++ b/canvas/opengl/radialTwoColorGradientFragmentShader.glsl
@@ -0,0 +1,28 @@
+/* -*- 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/.
+ */
+
+#version 120
+
+uniform vec4   v_startColor4d;
+uniform vec4   v_endColor4d;
+uniform mat3x2 m_transform;
+varying vec2   v_textureCoords2d;
+const vec2     v_center2d = vec2(0,0);
+
+void main(void)
+{
+    gl_FragColor = mix(v_startColor4d,
+            v_endColor4d,
+            1.0 - distance(
+                vec2(
+                    m_transform * vec3(v_textureCoords2d,1)),
+                v_center2d));
+    }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/opengl/rectangularMultiColorGradientFragmentShader.glsl b/canvas/opengl/rectangularMultiColorGradientFragmentShader.glsl
new file mode 100644
index 0000000..05a8ae5
--- /dev/null
+++ b/canvas/opengl/rectangularMultiColorGradientFragmentShader.glsl
@@ -0,0 +1,44 @@
+/* -*- 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/.
+ */
+
+#version 120
+
+uniform int       i_nColors;
+uniform sampler1D t_colorArray4d;
+uniform sampler1D t_stopArray1d;
+uniform mat3x2    m_transform;
+varying vec2      v_textureCoords2d;
+
+int findBucket(float t)
+{
+    int nMinBucket=0;
+    while( nMinBucket < i_nColors &&
+            texture1D(t_stopArray1d, nMinBucket).s < t )
+        ++nMinBucket;
+    return max(nMinBucket-1,0);
+}
+
+void main(void)
+{
+    const vec2  v = abs( vec2(m_transform * vec3(v_textureCoords2d,1)) );
+    const float fAlpha = 1 - max(v.x, v.y);
+
+    const int nMinBucket=findBucket( fAlpha );
+
+    const float fLerp =
+        (fAlpha-texture1D(t_stopArray1d, nMinBucket).s) /
+        (texture1D(t_stopArray1d, nMinBucket+1).s -
+         texture1D(t_stopArray1d, nMinBucket).s);
+
+    gl_FragColor = mix(texture1D(t_colorArray4d, nMinBucket),
+            texture1D(t_colorArray4d, nMinBucket+1),
+            fLerp);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/opengl/rectangularTwoColorGradientFragmentShader.glsl b/canvas/opengl/rectangularTwoColorGradientFragmentShader.glsl
new file mode 100644
index 0000000..a92a533
--- /dev/null
+++ b/canvas/opengl/rectangularTwoColorGradientFragmentShader.glsl
@@ -0,0 +1,25 @@
+/* -*- 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/.
+ */
+
+#version 120
+
+uniform vec4   v_startColor4d;
+uniform vec4   v_endColor4d;
+uniform mat3x2 m_transform;
+varying vec2   v_textureCoords2d;
+void main(void)
+{
+    const vec2 v = abs( vec2(m_transform * vec3(v_textureCoords2d,1)) );
+    const float t = max(v.x, v.y);
+    gl_FragColor = mix(v_startColor4d,
+            v_endColor4d,
+            1.0-t);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/source/opengl/ogl_spritedevicehelper.cxx b/canvas/source/opengl/ogl_spritedevicehelper.cxx
index 781beaf..c7d3bea 100644
--- a/canvas/source/opengl/ogl_spritedevicehelper.cxx
+++ b/canvas/source/opengl/ogl_spritedevicehelper.cxx
@@ -53,197 +53,6 @@ static int lcl_XErrorHandler( unx::Display*, unx::XErrorEvent* )
     return 0;
 }
 
-/** Dummy vertex processing. Simply uses default pipeline for vertex
-   transformation, and forwards texture coodinates to fragment shader
- */
-static const char dummyVertexShader[] =
-{
-    "varying vec2 v_textureCoords2d;                                            "
-    "void main(void)                                                            "
-    "{                                                                          "
-    "    gl_Position = ftransform();                                            "
-    "    v_textureCoords2d = gl_MultiTexCoord0.st;                              "
-    "}                                                                          "
-};
-
-/** Two-color linear gradient
- */
-static const char linearTwoColorGradientFragmentShader[] =
-{
-    "#version 120                                                            \n"
-    "uniform vec4   v_startColor4d;                                            "
-    "uniform vec4   v_endColor4d;                                              "
-    "uniform mat3x2 m_transform;                                               "
-    "varying vec2   v_textureCoords2d;                                         "
-    "void main(void)                                                           "
-    "{                                                                         "
-    "    gl_FragColor = mix(v_startColor4d,                                    "
-    "                       v_endColor4d,                                      "
-    "                       clamp(                                             "
-    "                          (m_transform * vec3(v_textureCoords2d,1)).s,    "
-    "                          0.0, 1.0));                                     "
-    "}                                                                         "
-};
-
-/** N-color linear gradient
- */
-static const char linearMultiColorGradientFragmentShader[] =
-{
-    "#version 120                                                            \n"
-    "uniform int       i_nColors;                                              "
-    "uniform sampler1D t_colorArray4d;                                         "
-    "uniform sampler1D t_stopArray1d;                                          "
-    "uniform mat3x2    m_transform;                                            "
-    "varying vec2      v_textureCoords2d;                                      "
-    "                                                                          "
-    "int findBucket(float t)                                                   "
-    "{                                                                         "
-    "    int nMinBucket=0;                                                     "
-    "    while( nMinBucket < i_nColors &&                                      "
-    "           texture1D(t_stopArray1d, nMinBucket).s < t )                   "
-    "        ++nMinBucket;                                                     "
-    "    return max(nMinBucket-1,0);                                           "
-    "}                                                                         "
-    "                                                                          "
-    "void main(void)                                                           "
-    "{                                                                         "
-    "    const float fAlpha =                                                  "
-    "        clamp( (m_transform * vec3(v_textureCoords2d,1)).s,               "
-    "               0.0, 1.0 );                                                "
-    "                                                                          "
-    "    const int nMinBucket=findBucket( fAlpha );                            "
-    "                                                                          "
-    "    const float fLerp =                                                   "
-    "        (fAlpha-texture1D(t_stopArray1d, nMinBucket).s) /                 "
-    "        (texture1D(t_stopArray1d, nMinBucket+1).s -                       "
-    "         texture1D(t_stopArray1d, nMinBucket).s);                         "
-    "                                                                          "
-    "    gl_FragColor = mix(texture1D(t_colorArray4d, nMinBucket),             "
-    "                       texture1D(t_colorArray4d, nMinBucket+1),           "
-    "                       fLerp);                                            "
-    "}                                                                         "
-};
-
-/** Two-color radial gradient
- */
-static const char radialTwoColorGradientFragmentShader[] =
-{
-    "#version 120                                                             \n"
-    "uniform vec4   v_startColor4d;                                             "
-    "uniform vec4   v_endColor4d;                                               "
-    "uniform mat3x2 m_transform;                                                "
-    "varying vec2   v_textureCoords2d;                                          "
-    "const vec2     v_center2d = vec2(0,0);                                     "
-    "void main(void)                                                            "
-    "{                                                                          "
-    "    gl_FragColor = mix(v_startColor4d,                                     "
-    "                       v_endColor4d,                                       "
-    "                       1.0 - distance(                                     "
-    "                          vec2(                                            "
-    "                             m_transform * vec3(v_textureCoords2d,1)),     "
-    "                          v_center2d));                                    "
-    "}                                                                          "
-};
-
-/** Multi-color radial gradient
- */
-static const char radialMultiColorGradientFragmentShader[] =
-{
-    "#version 120                                                             \n"
-    "uniform int       i_nColors;                                              "
-    "uniform sampler1D t_colorArray4d;                                         "
-    "uniform sampler1D t_stopArray1d;                                          "
-    "uniform mat3x2    m_transform;                                            "
-    "varying vec2      v_textureCoords2d;                                      "
-    "const vec2        v_center2d = vec2(0,0);                                 "
-    "                                                                          "
-    "int findBucket(float t)                                                   "
-    "{                                                                         "
-    "    int nMinBucket=0;                                                     "
-    "    while( nMinBucket < i_nColors &&                                      "
-    "           texture1D(t_stopArray1d, nMinBucket).s < t )                   "
-    "        ++nMinBucket;                                                     "
-    "    return max(nMinBucket-1,0);                                           "
-    "}                                                                         "
-    "                                                                          "
-    "void main(void)                                                           "
-    "{                                                                         "
-    "    const float fAlpha =                                                  "
-    "        clamp( 1.0 - distance(                                            "
-    "               vec2( m_transform * vec3(v_textureCoords2d,1)),            "
-    "                     v_center2d),                                         "
-    "               0.0, 1.0 );                                                "
-    "                                                                          "
-    "    const int nMinBucket=findBucket( fAlpha );                            "
-    "                                                                          "
-    "    const float fLerp =                                                   "
-    "        (fAlpha-texture1D(t_stopArray1d, nMinBucket).s) /                 "
-    "        (texture1D(t_stopArray1d, nMinBucket+1).s -                       "
-    "         texture1D(t_stopArray1d, nMinBucket).s);                         "
-    "                                                                          "
-    "    gl_FragColor = mix(texture1D(t_colorArray4d, nMinBucket),             "
-    "                       texture1D(t_colorArray4d, nMinBucket+1),           "
-    "                       fLerp);                                            "
-    "}                                                                         "
-};
-
-/** Two-color rectangular gradient
- */
-static const char rectangularTwoColorGradientFragmentShader[] =
-{
-    "#version 120                                                             \n"
-    "uniform vec4   v_startColor4d;                                             "
-    "uniform vec4   v_endColor4d;                                               "
-    "uniform mat3x2 m_transform;                                                "
-    "varying vec2   v_textureCoords2d;                                          "
-    "void main(void)                                                            "
-    "{                                                                          "
-    "    const vec2 v = abs( vec2(m_transform * vec3(v_textureCoords2d,1)) );   "
-    "    const float t = max(v.x, v.y);                                         "
-    "    gl_FragColor = mix(v_startColor4d,                                     "
-    "                       v_endColor4d,                                       "
-    "                       1.0-t);                                             "
-    "}                                                                          "
-};
-
-/** Multi-color rectangular gradient
- */
-static const char rectangularMultiColorGradientFragmentShader[] =
-{
-    "#version 120                                                             \n"
-    "uniform int       i_nColors;                                              "
-    "uniform sampler1D t_colorArray4d;                                         "
-    "uniform sampler1D t_stopArray1d;                                          "
-    "uniform mat3x2    m_transform;                                            "
-    "varying vec2      v_textureCoords2d;                                      "
-    "                                                                          "
-    "int findBucket(float t)                                                   "
-    "{                                                                         "
-    "    int nMinBucket=0;                                                     "
-    "    while( nMinBucket < i_nColors &&                                      "
-    "           texture1D(t_stopArray1d, nMinBucket).s < t )                   "
-    "        ++nMinBucket;                                                     "
-    "    return max(nMinBucket-1,0);                                           "
-    "}                                                                         "
-    "                                                                          "
-    "void main(void)                                                           "
-    "{                                                                         "
-    "    const vec2  v = abs( vec2(m_transform * vec3(v_textureCoords2d,1)) ); "
-    "    const float fAlpha = 1 - max(v.x, v.y);                               "
-    "                                                                          "
-    "    const int nMinBucket=findBucket( fAlpha );                            "
-    "                                                                          "
-    "    const float fLerp =                                                   "
-    "        (fAlpha-texture1D(t_stopArray1d, nMinBucket).s) /                 "
-    "        (texture1D(t_stopArray1d, nMinBucket+1).s -                       "
-    "         texture1D(t_stopArray1d, nMinBucket).s);                         "
-    "                                                                          "
-    "    gl_FragColor = mix(texture1D(t_colorArray4d, nMinBucket),             "
-    "                       texture1D(t_colorArray4d, nMinBucket+1),           "
-    "                       fLerp);                                            "
-    "}                                                                         "
-};
-
 static void initContext()
 {
     // need the backside for mirror effects
@@ -529,13 +338,6 @@ namespace oglcanvas
         mpGLPBufContext(NULL),
         mpFBConfig(NULL),
         mpTextureCache(new TextureCache()),
-        mnDummyVertexProgram(0),
-        mnLinearTwoColorGradientFragmentProgram(0),
-        mnLinearMultiColorGradientFragmentProgram(0),
-        mnRadialTwoColorGradientFragmentProgram(0),
-        mnRadialMultiColorGradientFragmentProgram(0),
-        mnRectangularTwoColorGradientFragmentProgram(0),
-        mnRectangularMultiColorGradientFragmentProgram(0),
         mnLinearTwoColorGradientProgram(0),
         mnLinearMultiColorGradientProgram(0),
         mnRadialTwoColorGradientProgram(0),
@@ -648,46 +450,23 @@ namespace oglcanvas
             // init window context
             initContext();
 
-            // compile & link shaders - code courtesy rodo
-            compileShader(mnDummyVertexProgram,
-                          GL_VERTEX_SHADER,
-                          dummyVertexShader);
-            compileShader(mnLinearTwoColorGradientFragmentProgram,
-                          GL_FRAGMENT_SHADER,
-                          linearTwoColorGradientFragmentShader);
-            compileShader(mnLinearMultiColorGradientFragmentProgram,
-                          GL_FRAGMENT_SHADER,
-                          linearMultiColorGradientFragmentShader);
-            compileShader(mnRadialTwoColorGradientFragmentProgram,
-                          GL_FRAGMENT_SHADER,
-                          radialTwoColorGradientFragmentShader);
-            compileShader(mnRadialMultiColorGradientFragmentProgram,
-                          GL_FRAGMENT_SHADER,
-                          radialMultiColorGradientFragmentShader);
-            compileShader(mnRectangularTwoColorGradientFragmentProgram,
-                          GL_FRAGMENT_SHADER,
-                          rectangularTwoColorGradientFragmentShader);
-            compileShader(mnRectangularMultiColorGradientFragmentProgram,
-                          GL_FRAGMENT_SHADER,
-                          rectangularMultiColorGradientFragmentShader);
-            linkShaders(mnLinearTwoColorGradientProgram,
-                        mnDummyVertexProgram,
-                        mnLinearTwoColorGradientFragmentProgram);
-            linkShaders(mnLinearMultiColorGradientProgram,
-                        mnDummyVertexProgram,
-                        mnLinearMultiColorGradientFragmentProgram);
-            linkShaders(mnRadialTwoColorGradientProgram,
-                        mnDummyVertexProgram,
-                        mnRadialTwoColorGradientFragmentProgram);
-            linkShaders(mnRadialMultiColorGradientProgram,
-                        mnDummyVertexProgram,
-                        mnRadialMultiColorGradientFragmentProgram);
-            linkShaders(mnRectangularTwoColorGradientProgram,
-                        mnDummyVertexProgram,
-                        mnRectangularTwoColorGradientFragmentProgram);
-            linkShaders(mnRectangularMultiColorGradientProgram,
-                        mnDummyVertexProgram,
-                        mnRectangularMultiColorGradientFragmentProgram);
+            mnLinearMultiColorGradientProgram =
+                OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "linearMultiColorGradientFragmentShader.glsl");
+
+            mnLinearTwoColorGradientProgram =
+                OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "linearTwoColorGradientFragmentShader.glsl");
+
+            mnRadialMultiColorGradientProgram =
+                OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "radialMultiColorGradientFragmentShader.glsl");
+
+            mnRadialTwoColorGradientProgram =
+                OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "radialTwoColorGradientFragmentShader.glsl");
+
+            mnRectangularMultiColorGradientProgram =
+                OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "rectangularMultiColorGradientFragmentShader.glsl");
+
+            mnRectangularTwoColorGradientProgram =
+                OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "rectangularTwoColorGradientFragmentShader.glsl");
 
             glXMakeCurrent(pDisplay, None, NULL);
         }
@@ -716,13 +495,6 @@ namespace oglcanvas
             glDeleteProgram( mnRadialMultiColorGradientProgram );
             glDeleteProgram( mnLinearTwoColorGradientProgram );
             glDeleteProgram( mnLinearMultiColorGradientProgram );
-            glDeleteShader( mnRectangularTwoColorGradientFragmentProgram );
-            glDeleteShader( mnRectangularMultiColorGradientFragmentProgram );
-            glDeleteShader( mnRadialTwoColorGradientFragmentProgram );
-            glDeleteShader( mnRadialMultiColorGradientFragmentProgram );
-            glDeleteShader( mnLinearTwoColorGradientFragmentProgram );
-            glDeleteShader( mnLinearMultiColorGradientFragmentProgram );
-            glDeleteShader( mnDummyVertexProgram );
 
             glXDestroyContext(reinterpret_cast<unx::Display*>(mpDisplay),
                               reinterpret_cast<unx::GLXContext>(mpGLContext));
commit 56d45b721f15946acaf1c6ee7c4c0003fbe1d554
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Aug 6 23:49:30 2014 +0200

    make sure that we always delete the shader and not only the program
    
    Change-Id: Ia02fb20d335e2172f607f13a0de78ea666d094f5

diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index 84a1399..a34ad75 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -122,6 +122,9 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString
     glAttachShader(ProgramID, FragmentShaderID);
     glLinkProgram(ProgramID);
 
+    glDeleteShader(VertexShaderID);
+    glDeleteShader(FragmentShaderID);
+
     // Check the program
     glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
     if ( !Result )
@@ -140,9 +143,6 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString
         return 0;
     }
 
-    glDeleteShader(VertexShaderID);
-    glDeleteShader(FragmentShaderID);
-
     return ProgramID;
 }
 


More information about the Libreoffice-commits mailing list