[Libreoffice-commits] core.git: Branch 'feature/fixes22' - 3 commits - vcl/inc vcl/Library_vcl.mk vcl/opengl

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Mon May 30 09:49:05 UTC 2016


 vcl/Library_vcl.mk                     |    1 
 vcl/inc/opengl/AccumulatedTextures.hxx |   35 --
 vcl/inc/opengl/RenderList.hxx          |  101 ++++++++
 vcl/inc/opengl/VertexUtils.hxx         |  138 +++++++++++
 vcl/inc/opengl/program.hxx             |    6 
 vcl/inc/opengl/texture.hxx             |    9 
 vcl/inc/openglgdiimpl.hxx              |    7 
 vcl/opengl/RenderList.cxx              |  216 ++++++++++++++++++
 vcl/opengl/combinedFragmentShader.glsl |   17 +
 vcl/opengl/combinedVertexShader.glsl   |    9 
 vcl/opengl/gdiimpl.cxx                 |  387 ++++++++++++++-------------------
 vcl/opengl/program.cxx                 |   12 -
 vcl/opengl/texture.cxx                 |   52 ++--
 13 files changed, 709 insertions(+), 281 deletions(-)

New commits:
commit 4abd0a6fcd81b242fde3abbb19c6c4336f3dc34a
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Sun May 29 15:36:39 2016 +0900

    opengl: batch draw polypolygons
    
    Change-Id: Ie9c41f95815a57c3a9e68ce7b7b0c1e09291988b

diff --git a/vcl/inc/opengl/RenderList.hxx b/vcl/inc/opengl/RenderList.hxx
index 0ba977a..d533ad4 100644
--- a/vcl/inc/opengl/RenderList.hxx
+++ b/vcl/inc/opengl/RenderList.hxx
@@ -91,6 +91,9 @@ public:
                           const SalColor& rLineColor, const SalColor& rFillColor);
 
     void addDrawLine(long nX1, long nY1, long nX2, long nY2, const SalColor& rLineColor, bool bUseAA);
+
+    void addDrawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency,
+                            const SalColor& rLineColor, const SalColor& rFillColor, bool bUseAA);
 };
 
 #endif // INCLUDED_VCL_INC_OPENGL_RENDERLIST_H
diff --git a/vcl/inc/opengl/VertexUtils.hxx b/vcl/inc/opengl/VertexUtils.hxx
index c64340b..d99998c 100644
--- a/vcl/inc/opengl/VertexUtils.hxx
+++ b/vcl/inc/opengl/VertexUtils.hxx
@@ -39,6 +39,20 @@ inline void addRectangle<GL_TRIANGLE_FAN>(std::vector<GLfloat>& rVertices, GLflo
     });
 }
 
+template<GLenum TYPE>
+inline void addTrapezoid(std::vector<GLfloat>& rVertices, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
+                                                          GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4);
+
+template<>
+inline void addTrapezoid<GL_TRIANGLES>(std::vector<GLfloat>& rVertices, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
+                                                                        GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4)
+{
+    rVertices.insert(rVertices.end(), {
+        x1, y1, x2, y2, x3, y3,
+        x3, y3, x2, y2, x4, y4
+    });
+}
+
 inline glm::vec4 createGLColor(const SalColor& rColor, GLfloat rTransparency)
 {
     return glm::vec4(SALCOLOR_RED(rColor)   / 255.0f,
diff --git a/vcl/opengl/RenderList.cxx b/vcl/opengl/RenderList.cxx
index 008be02..de5a9d6 100644
--- a/vcl/opengl/RenderList.cxx
+++ b/vcl/opengl/RenderList.cxx
@@ -11,6 +11,11 @@
 #include "opengl/RenderList.hxx"
 #include "opengl/VertexUtils.hxx"
 
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygontriangulator.hxx>
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+#include <basegfx/polygon/b2dtrapezoid.hxx>
+
 namespace
 {
 
@@ -119,4 +124,93 @@ void RenderList::addDrawLine(long nX1, long nY1, long nX2, long nY2, const SalCo
     lclAddLineSegmentVertices(rRenderParameter, nX1, nY1, nX2, nY2, rLineColor, 0.0f);
 }
 
+void RenderList::addDrawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency,
+                        const SalColor& rLineColor, const SalColor& rFillColor, bool bUseAA)
+{
+    if (rPolyPolygon.count() <= 0)
+        return;
+    if (rLineColor == SALCOLOR_NONE && rFillColor == SALCOLOR_NONE)
+        return;
+    if (fTransparency == 1.0)
+        return;
+
+    checkOverlapping(rPolyPolygon.getB2DRange());
+
+    RenderParameters& rLineParameter = maRenderEntries.back().maLineParameters;
+    RenderParameters& rLineAAParameter = maRenderEntries.back().maLineAAParameters;
+
+    if (rFillColor != SALCOLOR_NONE)
+    {
+        RenderParameters& rTriangleParameter = maRenderEntries.back().maTriangleParameters;
+
+        const basegfx::B2DPolyPolygon& aSimplePolyPolygon = ::basegfx::tools::solveCrossovers(rPolyPolygon);
+        basegfx::B2DTrapezoidVector aTrapezoidVector;
+        basegfx::tools::trapezoidSubdivide(aTrapezoidVector, aSimplePolyPolygon);
+
+        if (!aTrapezoidVector.empty())
+        {
+            for (basegfx::B2DTrapezoid & rTrapezoid : aTrapezoidVector)
+            {
+                GLfloat topX1 = rTrapezoid.getTopXLeft();
+                GLfloat topX2 = rTrapezoid.getTopXRight();
+                GLfloat topY  = rTrapezoid.getTopY();
+
+                GLfloat bottomX1 = rTrapezoid.getBottomXLeft();
+                GLfloat bottomX2 = rTrapezoid.getBottomXRight();
+                GLfloat bottomY  = rTrapezoid.getBottomY();
+
+                vcl::vertex::addTrapezoid<GL_TRIANGLES>(rTriangleParameter.maVertices,
+                                                         topX1,    topY,
+                                                         topX2,    topY,
+                                                         bottomX1, bottomY,
+                                                         bottomX2, bottomY);
+                vcl::vertex::addQuadColors<GL_TRIANGLES>(rTriangleParameter.maColors, rFillColor, fTransparency);
+                vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rTriangleParameter.maExtrusionVectors);
+
+                if (bUseAA)
+                {
+                    lclAddLineSegmentVertices(rLineAAParameter, topX1, topY, topX2, topY,
+                                              rFillColor, fTransparency);
+                    lclAddLineSegmentVertices(rLineAAParameter, topX2, topY, bottomX2, bottomY,
+                                              rFillColor, fTransparency);
+                    lclAddLineSegmentVertices(rLineAAParameter, bottomX2, bottomY, bottomX1, bottomY,
+                                              rFillColor, fTransparency);
+                    lclAddLineSegmentVertices(rLineAAParameter, bottomX1, bottomY, topX1, topY,
+                                              rFillColor, fTransparency);
+                }
+            }
+        }
+    }
+
+    if (rLineColor != SALCOLOR_NONE && rLineColor != rFillColor)
+    {
+        RenderParameters& rParameter = bUseAA ? rLineAAParameter : rLineParameter;
+
+        for (const basegfx::B2DPolygon& rPolygon : rPolyPolygon)
+        {
+            basegfx::B2DPolygon aPolygon(rPolygon);
+            if (rPolygon.areControlPointsUsed())
+                aPolygon = rPolygon.getDefaultAdaptiveSubdivision();
+
+            sal_uInt32 nPoints = aPolygon.count();
+
+            GLfloat x1, y1, x2, y2;
+            sal_uInt32 index1, index2;
+
+            for (sal_uInt32 i = 0; i <= nPoints; ++i)
+            {
+                index1 = (i)     % nPoints;
+                index2 = (i + 1) % nPoints;
+
+                x1 = aPolygon.getB2DPoint(index1).getX();
+                y1 = aPolygon.getB2DPoint(index1).getY();
+                x2 = aPolygon.getB2DPoint(index2).getX();
+                y2 = aPolygon.getB2DPoint(index2).getY();
+
+                lclAddLineSegmentVertices(rParameter, x1, y1, x2, y2, rLineColor, fTransparency);
+            }
+        }
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index e4a2e3e..5020626 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -1777,27 +1777,10 @@ void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32*
     drawPolyPolygon(aPolyPoly, 0.0);
 }
 
-bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency )
+bool OpenGLSalGraphicsImpl::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency)
 {
-    VCL_GL_INFO( "::drawPolyPolygon trans " << fTransparency );
-    if( rPolyPolygon.count() <= 0 )
-        return true;
-
-    PreDraw( XOROption::IMPLEMENT_XOR );
-
-    if( UseSolid( mnFillColor, fTransparency ) )
-        DrawPolyPolygon( rPolyPolygon );
-
-    if( mnLineColor != mnFillColor && UseSolid( mnLineColor, fTransparency ))
-    {
-        basegfx::B2DTrapezoidVector aB2DTrapVector;
-        basegfx::tools::createLineTrapezoidFromB2DPolyPolygon( aB2DTrapVector, rPolyPolygon );
-        for( size_t i = 0; i < aB2DTrapVector.size(); ++i )
-            DrawTrapezoid( aB2DTrapVector[ i ] );
-    }
-
-    PostDraw();
-
+    VCL_GL_INFO("::drawPolyPolygon " << rPolyPolygon.getB2DRange());
+    mpRenderList->addDrawPolyPolygon(rPolyPolygon, fTransparency, mnLineColor, mnFillColor, mrParent.getAntiAliasB2DDraw());
     return true;
 }
 
commit be865d9b82c4c02566123323b70da0d6073208ef
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Sun May 29 12:37:41 2016 +0900

    opengl: batch drawing of pixel, line, rect draw calls
    
    Change-Id: Ib1619fa476f488c5315411b1ad4d1b7464c70c69

diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 7f0b95d..e4c9e6a 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -137,6 +137,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
 	vcl/opengl/FixedTextureAtlas \
     vcl/opengl/PackedTextureAtlas \
     vcl/source/opengl/OpenGLContext \
+    vcl/opengl/RenderList \
     vcl/source/opengl/OpenGLHelper \
     vcl/source/window/cairo_cairo \
     vcl/source/window/openglwin \
diff --git a/vcl/inc/opengl/RenderList.hxx b/vcl/inc/opengl/RenderList.hxx
new file mode 100644
index 0000000..0ba977a
--- /dev/null
+++ b/vcl/inc/opengl/RenderList.hxx
@@ -0,0 +1,98 @@
+/* -*- 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_RENDERLIST_H
+#define INCLUDED_VCL_INC_OPENGL_RENDERLIST_H
+
+#include <glm/glm.hpp>
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+#include <vcl/salgtype.hxx>
+#include <basegfx/range/b2drange.hxx>
+
+struct RenderParameters
+{
+    std::vector<GLfloat>   maVertices;
+    std::vector<GLfloat>   maExtrusionVectors;
+    std::vector<glm::vec4> maColors;
+};
+
+struct RenderEntry
+{
+    RenderParameters maTriangleParameters;
+    RenderParameters maLineParameters;
+    RenderParameters maLineAAParameters;
+
+    bool hasTriangles()
+    {
+        return !maTriangleParameters.maVertices.empty();
+    }
+
+    bool hasLines()
+    {
+        return !maLineParameters.maVertices.empty();
+    }
+
+    bool hasLinesAA()
+    {
+        return !maLineAAParameters.maVertices.empty();
+    }
+};
+
+class RenderList
+{
+private:
+    basegfx::B2DRange maOverlapTrackingRectangle;
+    std::vector<RenderEntry> maRenderEntries;
+
+    void checkOverlapping(const basegfx::B2DRange& rDrawRectangle)
+    {
+        if (maRenderEntries.empty() || maOverlapTrackingRectangle.overlaps(rDrawRectangle))
+        {
+            maRenderEntries.resize(maRenderEntries.size() + 1);
+            maOverlapTrackingRectangle = rDrawRectangle;
+        }
+        else
+        {
+            maOverlapTrackingRectangle.expand(rDrawRectangle);
+        }
+    }
+
+public:
+
+    RenderList() = default;
+
+    bool empty()
+    {
+        return maRenderEntries.empty();
+    }
+
+    void clear()
+    {
+        maRenderEntries.clear();
+        maOverlapTrackingRectangle.reset();
+    }
+
+    std::vector<RenderEntry>& getEntries()
+    {
+        return maRenderEntries;
+    }
+
+    void addDrawPixel(long nX, long nY, const SalColor& rColor);
+
+    void addDrawRectangle(long nX, long nY, long nWidth, long nHeight,
+                          const SalColor& rLineColor, const SalColor& rFillColor);
+
+    void addDrawLine(long nX1, long nY1, long nX2, long nY2, const SalColor& rLineColor, bool bUseAA);
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_RENDERLIST_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/VertexUtils.hxx b/vcl/inc/opengl/VertexUtils.hxx
index becc62b..c64340b 100644
--- a/vcl/inc/opengl/VertexUtils.hxx
+++ b/vcl/inc/opengl/VertexUtils.hxx
@@ -39,6 +39,44 @@ inline void addRectangle<GL_TRIANGLE_FAN>(std::vector<GLfloat>& rVertices, GLflo
     });
 }
 
+inline glm::vec4 createGLColor(const SalColor& rColor, GLfloat rTransparency)
+{
+    return glm::vec4(SALCOLOR_RED(rColor)   / 255.0f,
+                     SALCOLOR_GREEN(rColor) / 255.0f,
+                     SALCOLOR_BLUE(rColor)  / 255.0f,
+                     1.0f - rTransparency);
+}
+
+template<GLenum TYPE>
+inline void addQuadColors(std::vector<glm::vec4>& rColors, const SalColor& rColor, GLfloat rTransparency);
+
+template<>
+inline void addQuadColors<GL_TRIANGLES>(std::vector<glm::vec4>& rColors, const SalColor& rColor, GLfloat rTransparency)
+{
+    glm::vec4 color = createGLColor(rColor, rTransparency);
+
+    rColors.insert(rColors.end(), {
+        color, color, color,
+        color, color, color
+    });
+}
+
+template<GLenum TYPE>
+inline void addQuadEmptyExtrusionVectors(std::vector<GLfloat>& rExtrusions);
+
+template<>
+inline void addQuadEmptyExtrusionVectors<GL_TRIANGLES>(std::vector<GLfloat>& rExtrusions)
+{
+    rExtrusions.insert(rExtrusions.end(), {
+        0.0f, 0.0f, 0.0f,
+        0.0f, 0.0f, 0.0f,
+        0.0f, 0.0f, 0.0f,
+        0.0f, 0.0f, 0.0f,
+        0.0f, 0.0f, 0.0f,
+        0.0f, 0.0f, 0.0f,
+    });
+}
+
 inline void addLineVertex(std::vector<GLfloat>& rVertices, std::vector<GLfloat>& rExtrusionVectors, glm::vec2 point, glm::vec2 extrusionVector, float length)
 {
     rVertices.push_back(point.x);
diff --git a/vcl/inc/opengl/program.hxx b/vcl/inc/opengl/program.hxx
index 2fab98c..8c25e17 100644
--- a/vcl/inc/opengl/program.hxx
+++ b/vcl/inc/opengl/program.hxx
@@ -22,6 +22,7 @@
 #include <tools/color.hxx>
 #include <opengl/texture.hxx>
 
+#include <glm/glm.hpp>
 #include <unordered_map>
 
 typedef std::unordered_map< OString, GLuint, OStringHash > UniformCache;
@@ -52,7 +53,9 @@ private:
     GLuint          mnTexCoordAttrib;
     GLuint          mnAlphaCoordAttrib;
     GLuint          mnMaskCoordAttrib;
-    GLuint          mnNormalAttrib;
+    GLuint          mnExtrusionVectorsAttrib;
+    GLuint          mnVertexColorsAttrib;
+
     TextureList     maTextures;
     bool            mbBlending;
 
@@ -79,6 +82,7 @@ public:
     void SetAlphaCoord( const GLvoid* pData );
     void SetMaskCoord(const GLvoid* pData);
     void SetExtrusionVectors(const GLvoid* pData);
+    void SetVertexColors(std::vector<glm::vec4>& rColorVector);
 
     void SetUniform1f( const OString& rName, GLfloat v1 );
     void SetUniform2f( const OString& rName, GLfloat v1, GLfloat v2 );
diff --git a/vcl/inc/opengl/texture.hxx b/vcl/inc/opengl/texture.hxx
index 6afc176..7c2f873 100644
--- a/vcl/inc/opengl/texture.hxx
+++ b/vcl/inc/opengl/texture.hxx
@@ -73,6 +73,8 @@ private:
     ImplOpenGLTexture* mpImpl;
     int mnSlotNumber;
 
+    inline bool GetTextureRect(const SalTwoRect& rPosAry, bool bInverted, GLfloat& x1, GLfloat& x2, GLfloat& y1, GLfloat& y2) const;
+
 public:
                     OpenGLTexture();
                     OpenGLTexture(ImplOpenGLTexture* pImpl, Rectangle aRectangle, int nSlotNumber);
@@ -116,6 +118,13 @@ public:
     void FillCoords(std::vector<GLfloat>& aCoordVector, const SalTwoRect& rPosAry, bool bInverted) const;
 };
 
+template<> void OpenGLTexture::FillCoords<GL_TRIANGLES>(
+    std::vector<GLfloat>& aCoord, const SalTwoRect& rPosAry, bool bInverted)
+    const;
+
+template<> void OpenGLTexture::FillCoords<GL_TRIANGLE_FAN>(
+    std::vector<GLfloat>& aCoord, const SalTwoRect& rPosAry, bool bInverted)
+    const;
 #endif // INCLUDED_VCL_INC_OPENGL_TEXTURE_H
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index df7b9e9..fdc4601 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -29,6 +29,7 @@
 #include "opengl/texture.hxx"
 #include "regionband.hxx"
 #include "opengl/AccumulatedTextures.hxx"
+#include "opengl/RenderList.hxx"
 
 #include <vcl/opengl/OpenGLContext.hxx>
 
@@ -100,7 +101,8 @@ protected:
     SalColor mProgramSolidColor;
     double mProgramSolidTransparency;
 
-    std::unique_ptr<AccumulatedTextures> mpAccumulatedTextures;
+    std::unique_ptr<AccumulatedTextures>  mpAccumulatedTextures;
+    std::unique_ptr<RenderList> mpRenderList;
 
     void ImplInitClipRegion();
     void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask );
@@ -114,11 +116,12 @@ public:
     bool UseSolid( SalColor nColor, sal_uInt8 nTransparency );
     bool UseSolid( SalColor nColor, double fTransparency );
     bool UseSolid( SalColor nColor );
+    bool UseSolid();
     bool UseLine(SalColor nColor, double fTransparency, GLfloat fLineWidth, bool bUseAA);
+    bool UseLine(GLfloat fLineWidth, bool bUseAA);
     bool UseInvert50();
     bool UseInvert(SalInvert nFlags);
 
-    void DrawPoint( long nX, long nY );
     void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry, bool blockAA = false );
     void DrawConvexPolygon( const tools::Polygon& rPolygon, bool blockAA = false );
     void DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoid, bool blockAA = false );
diff --git a/vcl/opengl/RenderList.cxx b/vcl/opengl/RenderList.cxx
new file mode 100644
index 0000000..008be02
--- /dev/null
+++ b/vcl/opengl/RenderList.cxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include "opengl/RenderList.hxx"
+#include "opengl/VertexUtils.hxx"
+
+namespace
+{
+
+inline void lclAddLineSegmentVertices(RenderParameters& rRenderParameter, GLfloat fX1, GLfloat fY1, GLfloat fX2, GLfloat fY2,
+                                   const SalColor& rColor, double fTransparency)
+{
+    glm::vec2 aPoint1(fX1, fY1);
+    glm::vec2 aPoint2(fX2, fY2);
+
+    glm::vec2 aLineVector = vcl::vertex::normalize(aPoint2 - aPoint1);
+    glm::vec2 aNormal = glm::vec2(-aLineVector.y, aLineVector.x);
+
+    vcl::vertex::addLinePointFirst(rRenderParameter.maVertices, rRenderParameter.maExtrusionVectors,
+                                   aPoint1, aNormal, 1.0f);
+    vcl::vertex::addLinePointNext (rRenderParameter.maVertices, rRenderParameter.maExtrusionVectors,
+                                   aPoint1, aNormal, 1.0f,
+                                   aPoint2, aNormal, 1.0f);
+
+    vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rColor, fTransparency);
+}
+
+} // end anonymous namespace
+
+void RenderList::addDrawPixel(long nX, long nY, const SalColor& rColor)
+{
+    if (rColor == SALCOLOR_NONE)
+        return;
+
+    checkOverlapping(basegfx::B2DRange(nX, nY, nX, nY));
+
+    RenderParameters& rRenderParameter = maRenderEntries.back().maTriangleParameters;
+    vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, nX - 0.5f, nY - 0.5f, nX + 0.5f, nY + 0.5f);
+    vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rColor, 0.0f);
+    vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
+}
+
+void RenderList::addDrawRectangle(long nX, long nY, long nWidth, long nHeight, const SalColor& rLineColor, const SalColor& rFillColor)
+{
+    if (rLineColor == SALCOLOR_NONE && rFillColor == SALCOLOR_NONE)
+        return;
+
+    GLfloat fX1(nX);
+    GLfloat fY1(nY);
+    GLfloat fX2(nX + nWidth  - 1);
+    GLfloat fY2(nY + nHeight - 1);
+
+    checkOverlapping(basegfx::B2DRange(fX1, fY1, fX2, fY2));
+
+    RenderParameters& rRenderParameter = maRenderEntries.back().maTriangleParameters;
+
+    // Draw rectangle stroke with line color
+    if (rLineColor != SALCOLOR_NONE)
+    {
+        vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 - 0.5f, fY1 - 0.5f, fX1 + 0.5f, fY2 + 0.5f);
+        vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 - 0.5f, fY1 - 0.5f, fX2 + 0.5f, fY1 + 0.5f);
+        vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX2 - 0.5f, fY1 - 0.5f, fX2 + 0.5f, fY2 + 0.5f);
+        vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 - 0.5f, fY2 - 0.5f, fX2 + 0.5f, fY2 + 0.5f);
+
+        vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rLineColor, 0.0f);
+        vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rLineColor, 0.0f);
+        vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rLineColor, 0.0f);
+        vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rLineColor, 0.0f);
+
+        vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
+        vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
+        vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
+        vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
+    }
+
+    if (rFillColor != SALCOLOR_NONE)
+    {
+        if (rLineColor == SALCOLOR_NONE)
+        {
+            // Draw rectangle stroke with fill color
+            vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 - 0.5f, fY1 - 0.5f, fX1 + 0.5f, fY2 + 0.5f);
+            vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 - 0.5f, fY1 - 0.5f, fX2 + 0.5f, fY1 + 0.5f);
+            vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX2 - 0.5f, fY1 - 0.5f, fX2 + 0.5f, fY2 + 0.5f);
+            vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 - 0.5f, fY2 - 0.5f, fX2 + 0.5f, fY2 + 0.5f);
+
+            vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rFillColor, 0.0f);
+            vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rFillColor, 0.0f);
+            vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rFillColor, 0.0f);
+            vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rFillColor, 0.0f);
+
+            vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
+            vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
+            vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
+            vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
+        }
+        // Draw rectangle fill with fill color
+        vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 + 0.5f, fY1 + 0.5f, fX2 - 0.5f, fY2 - 0.5f);
+        vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rFillColor, 0.0f);
+        vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
+    }
+}
+
+void RenderList::addDrawLine(long nX1, long nY1, long nX2, long nY2, const SalColor& rLineColor, bool bUseAA)
+{
+    if (rLineColor == SALCOLOR_NONE)
+        return;
+
+    checkOverlapping(basegfx::B2DRange(nX1, nY1, nX2, nY2));
+
+    RenderParameters& rRenderParameter = bUseAA ? maRenderEntries.back().maLineAAParameters :
+                                                  maRenderEntries.back().maLineParameters;
+    lclAddLineSegmentVertices(rRenderParameter, nX1, nY1, nX2, nY2, rLineColor, 0.0f);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/combinedFragmentShader.glsl b/vcl/opengl/combinedFragmentShader.glsl
index c44e75c..79360d3 100644
--- a/vcl/opengl/combinedFragmentShader.glsl
+++ b/vcl/opengl/combinedFragmentShader.glsl
@@ -8,8 +8,12 @@
  */
 
 varying float fade_factor; // 0->1 fade factor used for AA
-uniform vec4 color;
 
+#ifdef USE_VERTEX_COLORS
+varying vec4 vertex_color;
+#endif
+
+uniform vec4 color;
 uniform float line_width;
 uniform float feather;
 
@@ -22,6 +26,12 @@ void main()
 {
     float alpha = 1.0;
 
+#ifdef USE_VERTEX_COLORS
+    vec4 result = vertex_color;
+#else
+    vec4 result = color;
+#endif
+
     if (type == TYPE_LINE)
     {
         float start = (line_width / 2.0) - feather; // where we start to apply alpha
@@ -36,10 +46,9 @@ void main()
         alpha = clamp(dist, 0.0, 1.0);
     }
 
-    vec4 result_color = color;
-    result_color.a = result_color.a * alpha;
+    result.a = result.a * alpha;
 
-    gl_FragColor = result_color;
+    gl_FragColor = result;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/combinedVertexShader.glsl b/vcl/opengl/combinedVertexShader.glsl
index 9272544..8c6a856 100644
--- a/vcl/opengl/combinedVertexShader.glsl
+++ b/vcl/opengl/combinedVertexShader.glsl
@@ -9,8 +9,14 @@
 
 attribute vec2 position;
 attribute vec4 extrusion_vectors;
+#ifdef USE_VERTEX_COLORS
+attribute vec4 vertex_color_in;
+#endif
 
 varying float fade_factor; // fade factor for anti-aliasing
+#ifdef USE_VERTEX_COLORS
+varying vec4 vertex_color;
+#endif
 
 uniform float line_width;
 uniform float feather; // width where we fade the line
@@ -42,6 +48,9 @@ void main()
    }
 
    gl_Position = mvp * final_position;
+#ifdef USE_VERTEX_COLORS
+   vertex_color = vertex_color_in;
+#endif
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index fe11485..e4a2e3e 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -86,6 +86,7 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryPr
     , mProgramSolidColor(SALCOLOR_NONE)
     , mProgramSolidTransparency(0.0)
     , mpAccumulatedTextures(new AccumulatedTextures)
+    , mpRenderList(new RenderList)
 {
 }
 
@@ -547,9 +548,7 @@ bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, sal_uInt8 nTransparency )
 {
     if( nColor == SALCOLOR_NONE )
         return false;
-    if (!UseProgram("combinedVertexShader", "combinedFragmentShader"))
-        return false;
-    mpProgram->SetShaderType(DrawShaderType::Normal);
+    UseSolid();
     mpProgram->SetColor( "color", nColor, nTransparency );
 #ifdef DBG_UTIL
     mProgramIsSolidColor = true;
@@ -564,9 +563,7 @@ bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, double fTransparency )
 {
     if( nColor == SALCOLOR_NONE )
         return false;
-    if (!UseProgram("combinedVertexShader", "combinedFragmentShader"))
-        return false;
-    mpProgram->SetShaderType(DrawShaderType::Normal);
+    UseSolid();
     mpProgram->SetColorf( "color", nColor, fTransparency );
 #ifdef DBG_UTIL
     mProgramIsSolidColor = true;
@@ -576,6 +573,14 @@ bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, double fTransparency )
     return true;
 }
 
+bool OpenGLSalGraphicsImpl::UseSolid()
+{
+    if (!UseProgram("combinedVertexShader", "combinedFragmentShader"))
+        return false;
+    mpProgram->SetShaderType(DrawShaderType::Normal);
+    return true;
+}
+
 bool OpenGLSalGraphicsImpl::UseInvert50()
 {
     if( !UseProgram( "dumbVertexShader", "invert50FragmentShader" ) )
@@ -610,24 +615,9 @@ bool OpenGLSalGraphicsImpl::UseInvert( SalInvert nFlags )
     return true;
 }
 
-void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
-{
-    OpenGLZone aZone;
-
-    std::vector<GLfloat> pPoint {
-        GLfloat(nX), GLfloat(nY)
-    };
-
-    std::vector<GLfloat> aExtrusion(3, 0);
-    mpProgram->SetExtrusionVectors(aExtrusion.data());
-    ApplyProgramMatrices(0.5f);
-    mpProgram->DrawArrays(GL_POINTS, pPoint);
-    CHECK_GL_ERROR();
-}
-
 namespace
 {
-SAL_CONSTEXPR float constMiterMinimumAngle = 15.0f;
+    SAL_CONSTEXPR float constMiterMinimumAngle = 15.0f;
 } // end anonymous namespace
 
 void OpenGLSalGraphicsImpl::DrawLineCap(float x1, float y1, float x2, float y2, css::drawing::LineCap eLineCap, float fLineWidth)
@@ -895,21 +885,27 @@ bool OpenGLSalGraphicsImpl::UseLine(SalColor nColor, double fTransparency, GLflo
 {
     if( nColor == SALCOLOR_NONE )
         return false;
+    UseLine(fLineWidth, bUseAA);
+    mpProgram->SetColorf("color", nColor, fTransparency);
+#ifdef DBG_UTIL
+    mProgramIsSolidColor = true;
+#endif
+    mProgramSolidColor = nColor;
+    mProgramSolidTransparency = fTransparency;
+    return true;
+}
+
+bool OpenGLSalGraphicsImpl::UseLine(GLfloat fLineWidth, bool bUseAA)
+{
     if (!UseProgram("combinedVertexShader", "combinedFragmentShader"))
         return false;
     mpProgram->SetShaderType(DrawShaderType::Line);
-    mpProgram->SetColorf("color", nColor, fTransparency);
     mpProgram->SetUniform1f("line_width", fLineWidth);
     // The width of the feather - area we make lineary transparent in VS.
     // Good AA value is 0.5, 0.0 means the no AA will be done.
     mpProgram->SetUniform1f("feather", bUseAA ? 0.5f : 0.0f);
     // We need blending or AA won't work correctly
-    mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
-#ifdef DBG_UTIL
-    mProgramIsSolidColor = true;
-#endif
-    mProgramSolidColor = nColor;
-    mProgramSolidTransparency = fTransparency;
+    mpProgram->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     return true;
 }
 
@@ -1512,75 +1508,101 @@ void OpenGLSalGraphicsImpl::DeferredTextDraw(OpenGLTexture& rTexture, SalColor a
 
 void OpenGLSalGraphicsImpl::FlushDeferredDrawing()
 {
-    if (mpAccumulatedTextures->empty())
+    if (mpAccumulatedTextures->empty() && mpRenderList->empty())
         return;
 
-    InitializePreDrawState();
+    VCL_GL_INFO("FlushDeferredDrawing: " << mpRenderList->getEntries().size());
 
-    VCL_GL_INFO("FlushDeferredDrawing");
+    if (!mpAccumulatedTextures->empty())
+    {
+        InitializePreDrawState();
 
-    OpenGLZone aZone;
+        OpenGLZone aZone;
 
-#if 0 // Draw a background rect under text for debugging - same color shows text from the same texture
-    static sal_uInt8 r = 0xBE;
-    static sal_uInt8 g = 0xF0;
-    static sal_uInt8 b = 0xFF;
-    static std::unordered_map<GLuint, Color> aColorForTextureMap;
+        if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader"))
+            return;
+        mpProgram->SetShaderType(TextureShaderType::MaskedColor);
+        mpProgram->SetIdentityTransform("transform");
+        mpProgram->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-    for (auto& rPair : mpAccumulatedTextures->getAccumulatedTexturesMap())
-    {
-        OpenGLTexture& rTexture = rPair.second->maTexture;
-        Color aUseColor;
-        if (aColorForTextureMap.find(rTexture.Id()) == aColorForTextureMap.end())
+        for (auto& rPair : mpAccumulatedTextures->getAccumulatedTexturesMap())
         {
-            Color aColor(r, g, b);
-            sal_uInt16 h,s,br;
-            aColor.RGBtoHSB(h, s, br);
-            aColor = Color::HSBtoRGB((h + 40) % 360, s, br);
-            r = aColor.GetRed();
-            g = aColor.GetGreen();
-            b = aColor.GetBlue();
-            aColorForTextureMap[rTexture.Id()] = aColor;
+            OpenGLTexture& rTexture = rPair.second->maTexture;
+            mpProgram->SetTexture("texture", rTexture);
+            for (auto& rColorTwoRectPair: rPair.second->maColorTextureDrawParametersMap)
+            {
+                mpProgram->SetColor("color", rColorTwoRectPair.first, 0);
+                TextureDrawParameters& rParameters = rColorTwoRectPair.second;
+                ApplyProgramMatrices();
+                mpProgram->SetTextureCoord(rParameters.maTextureCoords.data());
+                mpProgram->SetMaskCoord(rParameters.maTextureCoords.data());
+                mpProgram->SetAlphaCoord(rParameters.maTextureCoords.data());
+                mpProgram->DrawArrays(GL_TRIANGLES, rParameters.maVertices);
+            }
         }
-        aUseColor = aColorForTextureMap[rTexture.Id()];
+        mpProgram->Clean();
+        mpAccumulatedTextures->clear();
 
-        if (!UseSolid(MAKE_SALCOLOR(aUseColor.GetRed(), aUseColor.GetGreen(), aUseColor.GetBlue())))
-            return;
-        for (auto rColorTwoRectPair: rPair.second->maColorTextureDrawParametersMap)
-        {
-            TextureDrawParameters& rParameters = rColorTwoRectPair.second;
-            ApplyProgramMatrices();
-            mpProgram->SetTextureCoord(rParameters.maTextureCoords.data());
-            mpProgram->DrawArrays(GL_TRIANGLES, rParameters.maVertices);
-        }
+        PostDraw();
     }
-#endif
 
-    if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader"))
-        return;
-    mpProgram->SetShaderType(TextureShaderType::MaskedColor);
-    mpProgram->SetIdentityTransform("transform");
-    mpProgram->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-    for (auto& rPair : mpAccumulatedTextures->getAccumulatedTexturesMap())
+    if (!mpRenderList->empty())
     {
-        OpenGLTexture& rTexture = rPair.second->maTexture;
-        mpProgram->SetTexture("texture", rTexture);
-        for (auto& rColorTwoRectPair: rPair.second->maColorTextureDrawParametersMap)
+        InitializePreDrawState(XOROption::IMPLEMENT_XOR);
+
+        OpenGLZone aZone;
+        for (RenderEntry& rRenderEntry : mpRenderList->getEntries())
         {
-            mpProgram->SetColor("color", rColorTwoRectPair.first, 0);
-            TextureDrawParameters& rParameters = rColorTwoRectPair.second;
-            ApplyProgramMatrices();
-            mpProgram->SetTextureCoord(rParameters.maTextureCoords.data());
-            mpProgram->SetMaskCoord(rParameters.maTextureCoords.data());
-            mpProgram->SetAlphaCoord(rParameters.maTextureCoords.data());
-            mpProgram->DrawArrays(GL_TRIANGLES, rParameters.maVertices);
+            if (rRenderEntry.hasTriangles() && UseProgram("combinedVertexShader", "combinedFragmentShader", "#define USE_VERTEX_COLORS"))
+            {
+                RenderParameters& rParameters = rRenderEntry.maTriangleParameters;
+                VCL_GL_INFO("Flush Triangles: " << rParameters.maVertices.size());
+                mpProgram->SetShaderType(DrawShaderType::Normal);
+                ApplyProgramMatrices(0.5f);
+                mpProgram->SetExtrusionVectors(rParameters.maExtrusionVectors.data());
+                mpProgram->SetVertexColors(rParameters.maColors);
+                mpProgram->DrawArrays(GL_TRIANGLES, rParameters.maVertices);
+                CHECK_GL_ERROR();
+                mpProgram->Clean();
+            }
+            if (rRenderEntry.hasLines() && UseProgram("combinedVertexShader", "combinedFragmentShader", "#define USE_VERTEX_COLORS"))
+            {
+                RenderParameters& rParameters = rRenderEntry.maLineParameters;
+                VCL_GL_INFO("Flush Lines: " << rParameters.maVertices.size());
+                mpProgram->SetShaderType(DrawShaderType::Line);
+                mpProgram->SetUniform1f("line_width", 1.0f);
+                mpProgram->SetUniform1f("feather", 0.0f); // Anti-Aliasing disabled
+                mpProgram->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                ApplyProgramMatrices(0.5f);
+                mpProgram->SetExtrusionVectors(rParameters.maExtrusionVectors.data());
+                mpProgram->SetVertexColors(rParameters.maColors);
+                mpProgram->DrawArrays(GL_TRIANGLES, rParameters.maVertices);
+                CHECK_GL_ERROR();
+                mpProgram->Clean();
+            }
+            if (rRenderEntry.hasLinesAA() && UseProgram("combinedVertexShader", "combinedFragmentShader", "#define USE_VERTEX_COLORS"))
+            {
+                RenderParameters& rParameters = rRenderEntry.maLineAAParameters;
+                VCL_GL_INFO("Flush Lines AA: " << rParameters.maVertices.size());
+                mpProgram->SetShaderType(DrawShaderType::Line);
+                mpProgram->SetUniform1f("line_width", 1.0f);
+                mpProgram->SetUniform1f("feather", 0.5f); // Anti-Aliasing enabled
+                mpProgram->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                ApplyProgramMatrices(0.5f);
+                mpProgram->SetExtrusionVectors(rParameters.maExtrusionVectors.data());
+                mpProgram->SetVertexColors(rParameters.maColors);
+                mpProgram->DrawArrays(GL_TRIANGLES, rParameters.maVertices);
+                CHECK_GL_ERROR();
+                mpProgram->Clean();
+            }
         }
+
+        mpRenderList->clear();
+        PostDraw();
     }
-    mpProgram->Clean();
-    mpAccumulatedTextures->clear();
 
-    PostDraw();
+    VCL_GL_INFO("End FlushDeferredDrawing");
+
 }
 
 void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect )
@@ -1689,72 +1711,28 @@ void OpenGLSalGraphicsImpl::DrawRadialGradient( const Gradient& rGradient, const
     DrawRect( rRect );
 }
 
-
-// draw --> LineColor and FillColor and RasterOp and ClipRegion
-void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY )
+void OpenGLSalGraphicsImpl::drawPixel(long nX, long nY)
 {
-    VCL_GL_INFO( "::drawPixel" );
-    if( mnLineColor != SALCOLOR_NONE )
-    {
-        PreDraw( XOROption::IMPLEMENT_XOR );
-        if( UseSolid( mnLineColor ) )
-            DrawPoint( nX, nY );
-        PostDraw();
-    }
+    VCL_GL_INFO("::drawPixel: (" << nX << ", " << nY << ")");
+    mpRenderList->addDrawPixel(nX, nY, mnLineColor);
 }
 
-void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor )
+void OpenGLSalGraphicsImpl::drawPixel(long nX, long nY, SalColor nSalColor)
 {
-    VCL_GL_INFO( "::drawPixel" );
-    if( nSalColor != SALCOLOR_NONE )
-    {
-        PreDraw( XOROption::IMPLEMENT_XOR );
-        if( UseSolid( nSalColor ) )
-            DrawPoint( nX, nY );
-        PostDraw();
-    }
+    VCL_GL_INFO("::drawPixel: (" << nX << ", " << nY << ")");
+    mpRenderList->addDrawPixel(nX, nY, nSalColor);
 }
 
-void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
+void OpenGLSalGraphicsImpl::drawLine(long nX1, long nY1, long nX2, long nY2)
 {
-    VCL_GL_INFO( "::drawLine" );
-    if( mnLineColor != SALCOLOR_NONE )
-    {
-        PreDraw( XOROption::IMPLEMENT_XOR );
-        if (UseLine(mnLineColor, 0.0, 1.0f, mrParent.getAntiAliasB2DDraw()))
-            DrawLineSegment(nX1, nY1, nX2, nY2);
-        PostDraw();
-    }
+    VCL_GL_INFO("::drawLine (" << nX1 << ", " << nY1 << ") (" << nX2 << ", " << nY2 << ")");
+    mpRenderList->addDrawLine(nX1, nY1, nX2, nY2, mnLineColor, mrParent.getAntiAliasB2DDraw());
 }
 
 void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeight )
 {
-    VCL_GL_INFO( "::drawRect" );
-    PreDraw( XOROption::IMPLEMENT_XOR );
-
-    if( UseSolid( mnFillColor ) )
-        DrawRect( nX, nY, nWidth, nHeight );
-
-    if( UseSolid( mnLineColor ) )
-    {
-        GLfloat fX1(nX);
-        GLfloat fY1(nY);
-        GLfloat fX2(nX + nWidth - 1);
-        GLfloat fY2(nY + nHeight - 1);
-
-        std::vector<GLfloat> pPoints {
-            fX1, fY1,
-            fX2, fY1,
-            fX2, fY2,
-            fX1, fY2
-        };
-
-        ApplyProgramMatrices(0.5f);
-        mpProgram->DrawArrays(GL_LINE_LOOP, pPoints);
-        CHECK_GL_ERROR();
-    }
-
-    PostDraw();
+    VCL_GL_INFO("::drawRect (" << nX << ", " << nY << ") [" << nWidth << ", " << nHeight << "]");
+    mpRenderList->addDrawRectangle(nX, nY, nWidth, nHeight, mnLineColor, mnFillColor);
 }
 
 void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx
index 563a295..d752284 100644
--- a/vcl/opengl/program.cxx
+++ b/vcl/opengl/program.cxx
@@ -24,8 +24,9 @@ OpenGLProgram::OpenGLProgram() :
     mnTexCoordAttrib( SAL_MAX_UINT32 ),
     mnAlphaCoordAttrib( SAL_MAX_UINT32 ),
     mnMaskCoordAttrib( SAL_MAX_UINT32 ),
-    mnNormalAttrib( SAL_MAX_UINT32 ),
-    mbBlending( false ),
+    mnExtrusionVectorsAttrib( SAL_MAX_UINT32 ),
+    mnVertexColorsAttrib( SAL_MAX_UINT32 ),
+    mbBlending(false),
     mfLastWidth(0.0),
     mfLastHeight(0.0),
     mfLastPixelOffset(0.0)
@@ -132,7 +133,12 @@ void OpenGLProgram::SetMaskCoord(const GLvoid* pData)
 
 void OpenGLProgram::SetExtrusionVectors(const GLvoid* pData)
 {
-    SetVertexAttrib(mnNormalAttrib, "extrusion_vectors", pData, 3);
+    SetVertexAttrib(mnExtrusionVectorsAttrib, "extrusion_vectors", pData, 3);
+}
+
+void OpenGLProgram::SetVertexColors(std::vector<glm::vec4>& rColorVector)
+{
+    SetVertexAttrib(mnVertexColorsAttrib, "vertex_color_in", glm::value_ptr(rColorVector[0]), 4);
 }
 
 void OpenGLProgram::SetShaderType(TextureShaderType eTextureShaderType)
diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
index 63e39b8..1cd3ecd 100644
--- a/vcl/opengl/texture.cxx
+++ b/vcl/opengl/texture.cxx
@@ -401,18 +401,8 @@ void OpenGLTexture::GetCoord( GLfloat* pCoord, const SalTwoRect& rPosAry, bool b
     }
 }
 
-template <>
-void OpenGLTexture::FillCoords<GL_TRIANGLES>(std::vector<GLfloat>& aCoord, const SalTwoRect& rPosAry, bool bInverted) const
+bool OpenGLTexture::GetTextureRect(const SalTwoRect& rPosAry, bool bInverted, GLfloat& x1, GLfloat& x2, GLfloat& y1, GLfloat& y2) const
 {
-    VCL_GL_INFO("Add coord " << Id() << " [" << maRect.Left() << "," << maRect.Top() << "] " << GetWidth() << "x" << GetHeight() );
-    VCL_GL_INFO("   With 2Rect Src  [" << rPosAry.mnSrcX << ", " << rPosAry.mnSrcY << "] wh (" << rPosAry.mnSrcWidth << ", " << rPosAry.mnSrcHeight << ")");
-    VCL_GL_INFO("   With 2Rect Dest [" << rPosAry.mnDestX << ", " << rPosAry.mnDestY << "] wh (" << rPosAry.mnDestWidth << ", " << rPosAry.mnDestHeight << ")");
-
-    GLfloat x1 = 0.0f;
-    GLfloat x2 = 0.0f;
-    GLfloat y1 = 0.0f;
-    GLfloat y2 = 0.0f;
-
     if (mpImpl)
     {
         double fTextureWidth(mpImpl->mnWidth);
@@ -431,25 +421,41 @@ void OpenGLTexture::FillCoords<GL_TRIANGLES>(std::vector<GLfloat>& aCoord, const
             y1 = 1.0f - (maRect.Top() + rPosAry.mnSrcY) / fTextureHeight;
             y2 = 1.0f - (maRect.Top() + rPosAry.mnSrcY + rPosAry.mnSrcHeight) / fTextureHeight;
         }
+        return true;
     }
+    return false;
+}
 
-    aCoord.push_back(x1);
-    aCoord.push_back(y1);
+template <>
+void OpenGLTexture::FillCoords<GL_TRIANGLE_FAN>(std::vector<GLfloat>& rCoords, const SalTwoRect& rPosAry, bool bInverted) const
+{
+    GLfloat x1 = 0.0f;
+    GLfloat x2 = 0.0f;
+    GLfloat y1 = 0.0f;
+    GLfloat y2 = 0.0f;
 
-    aCoord.push_back(x2);
-    aCoord.push_back(y1);
+    GetTextureRect(rPosAry, bInverted, x1, x2, y1, y2);
 
-    aCoord.push_back(x1);
-    aCoord.push_back(y2);
+    rCoords.insert(rCoords.end(), {
+        x1, y2, x1, y1,
+        x2, y1, x2, y2
+    });
+}
 
-    aCoord.push_back(x1);
-    aCoord.push_back(y2);
+template <>
+void OpenGLTexture::FillCoords<GL_TRIANGLES>(std::vector<GLfloat>& rCoords, const SalTwoRect& rPosAry, bool bInverted) const
+{
+    GLfloat x1 = 0.0f;
+    GLfloat x2 = 0.0f;
+    GLfloat y1 = 0.0f;
+    GLfloat y2 = 0.0f;
 
-    aCoord.push_back(x2);
-    aCoord.push_back(y1);
+    GetTextureRect(rPosAry, bInverted, x1, x2, y1, y2);
 
-    aCoord.push_back(x2);
-    aCoord.push_back(y2);
+    rCoords.insert(rCoords.end(), {
+        x1, y1, x2, y1, x1, y2,
+        x1, y2, x2, y1, x2, y2
+    });
 }
 
 void OpenGLTexture::GetWholeCoord( GLfloat* pCoord ) const
commit 1c4492ffef303523bdec84cc9697697408e72917
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri May 27 19:43:12 2016 +0900

    opengl: VertexUtils, deferred flush update, remove unneeded calls
    
    VertexUtils - collection of utils for working with Vertices.
    
    Add deferred flush to some places directly where it is called
    indirectly. This is to assure that we don't produce regressions
    if we change the behavior in the future.
    
    drawAlphaBitmap is the same as drawBitmap so when drawBitmap is
    called just redirect to drawAlphaBitmap
    
    Change-Id: Ibef1ba88865856d92d9e93734cf5d6561af785c0

diff --git a/vcl/inc/opengl/AccumulatedTextures.hxx b/vcl/inc/opengl/AccumulatedTextures.hxx
index 882a694..504cf6a 100644
--- a/vcl/inc/opengl/AccumulatedTextures.hxx
+++ b/vcl/inc/opengl/AccumulatedTextures.hxx
@@ -15,16 +15,13 @@
 
 #include <o3tl/make_unique.hxx>
 #include "opengl/texture.hxx"
+#include "opengl/VertexUtils.hxx"
 #include <memory>
 
 struct TextureDrawParameters
 {
     std::vector<GLfloat> maVertices;
     std::vector<GLfloat> maTextureCoords;
-    GLint getNumberOfVertices()
-    {
-        return maVertices.size() / 2;
-    }
 };
 
 struct AccumulatedTexturesEntry
@@ -41,29 +38,13 @@ struct AccumulatedTexturesEntry
         TextureDrawParameters& aDrawParameters = maColorTextureDrawParametersMap[aColor];
         rTexture.FillCoords<GL_TRIANGLES>(aDrawParameters.maTextureCoords, r2Rect, false);
 
-        GLfloat nX1 = r2Rect.mnDestX;
-        GLfloat nY1 = r2Rect.mnDestY;
-        GLfloat nX2 = r2Rect.mnDestX + r2Rect.mnDestWidth;
-        GLfloat nY2 = r2Rect.mnDestY + r2Rect.mnDestHeight;
-
-        auto& rVertices = aDrawParameters.maVertices;
-        rVertices.push_back(nX1);
-        rVertices.push_back(nY1);
-
-        rVertices.push_back(nX2);
-        rVertices.push_back(nY1);
-
-        rVertices.push_back(nX1);
-        rVertices.push_back(nY2);
-
-        rVertices.push_back(nX1);
-        rVertices.push_back(nY2);
-
-        rVertices.push_back(nX2);
-        rVertices.push_back(nY1);
+        GLfloat fX1 = r2Rect.mnDestX;
+        GLfloat fY1 = r2Rect.mnDestY;
+        GLfloat fX2 = fX1 + r2Rect.mnDestWidth;
+        GLfloat fY2 = fY1 + r2Rect.mnDestHeight;
 
-        rVertices.push_back(nX2);
-        rVertices.push_back(nY2);
+        std::vector<GLfloat>& rVertices = aDrawParameters.maVertices;
+        vcl::vertex::addRectangle<GL_TRIANGLES>(rVertices, fX1, fY1, fX2, fY2);
     }
 };
 
@@ -113,6 +94,6 @@ public:
     }
 };
 
-#endif // INCLUDED_VCL_INC_OPENGL_TEXTURE_H
+#endif // INCLUDED_VCL_INC_OPENGL_ACCUMULATEDTEXTURES_H
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/VertexUtils.hxx b/vcl/inc/opengl/VertexUtils.hxx
new file mode 100644
index 0000000..becc62b
--- /dev/null
+++ b/vcl/inc/opengl/VertexUtils.hxx
@@ -0,0 +1,86 @@
+/* -*- 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_VERTEXUTILS_H
+#define INCLUDED_VCL_INC_OPENGL_VERTEXUTILS_H
+
+#include <glm/gtx/norm.hpp>
+
+namespace vcl
+{
+namespace vertex
+{
+
+template<GLenum TYPE>
+inline void addRectangle(std::vector<GLfloat>& rVertices, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
+
+template<>
+inline void addRectangle<GL_TRIANGLES>(std::vector<GLfloat>& rVertices, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+    rVertices.insert(rVertices.end(), {
+        x1, y1, x2, y1, x1, y2,
+        x1, y2, x2, y1, x2, y2
+    });
+}
+
+template<>
+inline void addRectangle<GL_TRIANGLE_FAN>(std::vector<GLfloat>& rVertices, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+    rVertices.insert(rVertices.end(), {
+        x1, y2, x1, y1,
+        x2, y1, x2, y2
+    });
+}
+
+inline void addLineVertex(std::vector<GLfloat>& rVertices, std::vector<GLfloat>& rExtrusionVectors, glm::vec2 point, glm::vec2 extrusionVector, float length)
+{
+    rVertices.push_back(point.x);
+    rVertices.push_back(point.y);
+
+    rExtrusionVectors.push_back(extrusionVector.x);
+    rExtrusionVectors.push_back(extrusionVector.y);
+    rExtrusionVectors.push_back(length);
+}
+
+inline void addLineVertexPair(std::vector<GLfloat>& rVertices, std::vector<GLfloat>& rExtrusionVectors, const glm::vec2& point, const glm::vec2& extrusionVector, float length)
+{
+    addLineVertex(rVertices, rExtrusionVectors, point, -extrusionVector, -length);
+    addLineVertex(rVertices, rExtrusionVectors, point,  extrusionVector,  length);
+}
+
+inline void addLinePointFirst(std::vector<GLfloat>& rVertices, std::vector<GLfloat>& rExtrusionVectors,
+                               glm::vec2 point, glm::vec2 extrusionVector, float length)
+{
+    addLineVertex(rVertices, rExtrusionVectors, point, -extrusionVector, -length);
+    addLineVertex(rVertices, rExtrusionVectors, point,  extrusionVector,  length);
+}
+
+inline void addLinePointNext(std::vector<GLfloat>& rVertices, std::vector<GLfloat>& rExtrusionVectors,
+                             glm::vec2 prevPoint, glm::vec2 prevExtrusionVector, float prevLength,
+                             glm::vec2 currPoint, glm::vec2 currExtrusionVector, float currLength)
+{
+    addLineVertex(rVertices, rExtrusionVectors, currPoint, -currExtrusionVector, -currLength);
+    addLineVertex(rVertices, rExtrusionVectors, currPoint, -currExtrusionVector, -currLength);
+    addLineVertex(rVertices, rExtrusionVectors, prevPoint,  prevExtrusionVector,  prevLength);
+    addLineVertex(rVertices, rExtrusionVectors, currPoint,  currExtrusionVector,  currLength);
+}
+
+inline glm::vec2 normalize(const glm::vec2& vector)
+{
+    if (glm::length(vector) > 0.0)
+        return glm::normalize(vector);
+    return vector;
+}
+
+}} // end vcl::vertex
+
+#endif // INCLUDED_VCL_INC_OPENGL_VERTEXUTILS_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 9292b59..fe11485 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -35,6 +35,7 @@
 #include "opengl/zone.hxx"
 #include "opengl/salbmp.hxx"
 #include "opengl/RenderState.hxx"
+#include "opengl/VertexUtils.hxx"
 
 #include <vector>
 
@@ -170,6 +171,10 @@ void OpenGLSalGraphicsImpl::Init()
 // Currently only used to get windows ordering right.
 void OpenGLSalGraphicsImpl::DeInit()
 {
+    VCL_GL_INFO("::DeInit");
+
+    FlushDeferredDrawing();
+
     // tdf#93839:
     // Our window handles and resources are being free underneath us.
     // These can be bound into a context, which relies on them. So
@@ -622,32 +627,7 @@ void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
 
 namespace
 {
-
-inline void addVertex(std::vector<GLfloat>& rVertices, std::vector<GLfloat>& rExtrusionVectors, glm::vec2 point, glm::vec2 extrusionVector, float length)
-{
-    rVertices.push_back(point.x);
-    rVertices.push_back(point.y);
-
-    rExtrusionVectors.push_back(extrusionVector.x);
-    rExtrusionVectors.push_back(extrusionVector.y);
-    rExtrusionVectors.push_back(length);
-}
-
-inline void addVertexPair(std::vector<GLfloat>& rVertices, std::vector<GLfloat>& rExtrusionVectors, glm::vec2 point, glm::vec2 extrusionVector, float length)
-{
-    addVertex(rVertices, rExtrusionVectors, point, -extrusionVector, -length);
-    addVertex(rVertices, rExtrusionVectors, point,  extrusionVector,  length);
-}
-
-inline glm::vec2 normalize(const glm::vec2& vector)
-{
-    if (glm::length(vector) > 0.0)
-        return glm::normalize(vector);
-    return vector;
-}
-
 SAL_CONSTEXPR float constMiterMinimumAngle = 15.0f;
-
 } // end anonymous namespace
 
 void OpenGLSalGraphicsImpl::DrawLineCap(float x1, float y1, float x2, float y2, css::drawing::LineCap eLineCap, float fLineWidth)
@@ -664,7 +644,7 @@ void OpenGLSalGraphicsImpl::DrawLineCap(float x1, float y1, float x2, float y2,
 
     glm::vec2 p1(x1, y1);
     glm::vec2 p2(x2, y2);
-    glm::vec2 lineVector = normalize(p2 - p1);
+    glm::vec2 lineVector = vcl::vertex::normalize(p2 - p1);
     glm::vec2 normal = glm::vec2(-lineVector.y, lineVector.x);
 
     if (eLineCap == css::drawing::LineCap_ROUND)
@@ -675,15 +655,15 @@ void OpenGLSalGraphicsImpl::DrawLineCap(float x1, float y1, float x2, float y2,
             glm::vec2 roundNormal(normal.x * glm::cos(angle) - normal.y * glm::sin(angle),
                                   normal.x * glm::sin(angle) + normal.y * glm::cos(angle));
 
-            addVertexPair(aVertices, aExtrusionVectors, p1, roundNormal, 1.0f);
+            vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, p1, roundNormal, 1.0f);
         }
     }
     else if (eLineCap == css::drawing::LineCap_SQUARE)
     {
         glm::vec2 extrudedPoint = p1 + -lineVector * (fLineWidth / 2.0f);
 
-        addVertexPair(aVertices, aExtrusionVectors, extrudedPoint, normal, 1.0f);
-        addVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f);
+        vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, extrudedPoint, normal, 1.0f);
+        vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f);
     }
 
     ApplyProgramMatrices(0.5f);
@@ -698,20 +678,20 @@ void OpenGLSalGraphicsImpl::DrawLineSegment(float x1, float y1, float x2, float
     glm::vec2 p1(x1, y1);
     glm::vec2 p2(x2, y2);
 
-    std::vector<GLfloat> aPoints;
+    std::vector<GLfloat> aVertices;
     std::vector<GLfloat> aExtrusionVectors;
 
     OpenGLZone aZone;
 
-    glm::vec2 lineVector = normalize(p2 - p1);
+    glm::vec2 lineVector = vcl::vertex::normalize(p2 - p1);
     glm::vec2 normal = glm::vec2(-lineVector.y, lineVector.x);
 
-    addVertexPair(aPoints, aExtrusionVectors, p1, normal, 1.0f);
-    addVertexPair(aPoints, aExtrusionVectors, p2, normal, 1.0f);
+    vcl::vertex::addLinePointFirst(aVertices, aExtrusionVectors, p1, normal, 1.0f);
+    vcl::vertex::addLinePointNext (aVertices, aExtrusionVectors, p1, normal, 1.0f, p2, normal, 1.0f);
 
     ApplyProgramMatrices(0.5f);
     mpProgram->SetExtrusionVectors(aExtrusionVectors.data());
-    mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aPoints);
+    mpProgram->DrawArrays(GL_TRIANGLES, aVertices);
 
     CHECK_GL_ERROR();
 }
@@ -790,12 +770,12 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl
         glm::vec2 p1(rPolygon.getB2DPoint(0).getX(), rPolygon.getB2DPoint(0).getY());
         glm::vec2 p2(rPolygon.getB2DPoint(1).getX(), rPolygon.getB2DPoint(1).getY());
 
-        nextLineVector = normalize(p2 - p1);
+        nextLineVector = vcl::vertex::normalize(p2 - p1);
 
         if (!bClosed)
         {
             normal = glm::vec2(-nextLineVector.y, nextLineVector.x); // make perpendicular
-            addVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f);
+            vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f);
 
             i++; // first point done already
             lastPoint--; // last point will be calculated separatly from the loop
@@ -807,7 +787,7 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl
         {
             lastPoint++; // we need to connect last point to first point so one more line segment to calculate
 
-            previousLineVector = normalize(p1 - p0);
+            previousLineVector = vcl::vertex::normalize(p1 - p0);
         }
 
         for (; i < lastPoint; ++i)
@@ -821,7 +801,7 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl
             if (p1 == p2) // skip equal points, normals could div-by-0
                 continue;
 
-            nextLineVector = normalize(p2 - p1);
+            nextLineVector = vcl::vertex::normalize(p2 - p1);
 
             if (eLineJoin == basegfx::B2DLineJoin::Miter)
             {
@@ -845,11 +825,11 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl
 
                 normal = glm::vec2(-previousLineVector.y, previousLineVector.x);
 
-                glm::vec2 tangent = normalize(nextLineVector + previousLineVector);
+                glm::vec2 tangent = vcl::vertex::normalize(nextLineVector + previousLineVector);
                 glm::vec2 extrusionVector(-tangent.y, tangent.x);
                 GLfloat length = glm::dot(extrusionVector, normal);
 
-                addVertexPair(aVertices, aExtrusionVectors, p1, extrusionVector, length);
+                vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, p1, extrusionVector, length);
             }
             else if (eLineJoin == basegfx::B2DLineJoin::Bevel)
             {
@@ -861,8 +841,8 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl
                 glm::vec2 previousNormal = glm::vec2(-previousLineVector.y, previousLineVector.x);
                 glm::vec2 nextNormal = glm::vec2(-nextLineVector.y, nextLineVector.x);
 
-                addVertexPair(aVertices, aExtrusionVectors, p1, previousNormal, 1.0f);
-                addVertexPair(aVertices, aExtrusionVectors, p1, nextNormal, 1.0f);
+                vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, p1, previousNormal, 1.0f);
+                vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, p1, nextNormal, 1.0f);
             }
             else if (eLineJoin == basegfx::B2DLineJoin::Round)
             {
@@ -877,15 +857,15 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl
                 glm::vec2 previousNormal = glm::vec2(-previousLineVector.y, previousLineVector.x);
                 glm::vec2 nextNormal = glm::vec2(-nextLineVector.y, nextLineVector.x);
 
-                glm::vec2 middle = normalize(previousNormal + nextNormal);
-                glm::vec2 middleLeft  = normalize(previousNormal + middle);
-                glm::vec2 middleRight = normalize(middle + nextNormal);
+                glm::vec2 middle = vcl::vertex::normalize(previousNormal + nextNormal);
+                glm::vec2 middleLeft  = vcl::vertex::normalize(previousNormal + middle);
+                glm::vec2 middleRight = vcl::vertex::normalize(middle + nextNormal);
 
-                addVertexPair(aVertices, aExtrusionVectors, p1, previousNormal, 1.0f);
-                addVertexPair(aVertices, aExtrusionVectors, p1, middleLeft, 1.0f);
-                addVertexPair(aVertices, aExtrusionVectors, p1, middle, 1.0f);
-                addVertexPair(aVertices, aExtrusionVectors, p1, middleRight, 1.0f);
-                addVertexPair(aVertices, aExtrusionVectors, p1, nextNormal, 1.0f);
+                vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, p1, previousNormal, 1.0f);
+                vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, p1, middleLeft, 1.0f);
+                vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, p1, middle, 1.0f);
+                vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, p1, middleRight, 1.0f);
+                vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, p1, nextNormal, 1.0f);
             }
             p0 = p1;
             previousLineVector = nextLineVector;
@@ -900,7 +880,7 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl
 
             normal = glm::vec2(-previousLineVector.y, previousLineVector.x);
 
-            addVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f);
+            vcl::vertex::addLineVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f);
         }
 
         ApplyProgramMatrices(0.5f);
@@ -1169,7 +1149,18 @@ void OpenGLSalGraphicsImpl::DrawTextureRect( OpenGLTexture& /*rTexture*/, const
 
     SAL_INFO("vcl.opengl", "draw texture rect");
 
-    DrawRect( rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight );
+    long nX = rPosAry.mnDestX;
+    long nY = rPosAry.mnDestY;
+    long nWidth  = rPosAry.mnDestWidth;
+    long nHeight = rPosAry.mnDestHeight;
+
+    std::vector<GLfloat> aVertices;
+    aVertices.reserve(8);
+    vcl::vertex::addRectangle<GL_TRIANGLE_FAN>(aVertices, nX, nY, nX + nWidth, nY + nHeight);
+
+    ApplyProgramMatrices();
+    mpProgram->DrawArrays(GL_TRIANGLE_FAN, aVertices);
+    CHECK_GL_ERROR();
 }
 
 void OpenGLSalGraphicsImpl::DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted )
@@ -1460,7 +1451,7 @@ void OpenGLSalGraphicsImpl::DrawTextureWithMask( OpenGLTexture& rTexture, OpenGL
     rMask.GetCoord(aMaskCoord, rPosAry);
     mpProgram->SetMaskCoord(aMaskCoord);
 
-    DrawRect(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight);
+    DrawTextureRect(rTexture, rPosAry);
     mpProgram->Clean();
 }
 
@@ -1961,17 +1952,8 @@ void OpenGLSalGraphicsImpl::drawBitmap(
             const SalBitmap& rSalBitmap,
             const SalBitmap& rMaskBitmap )
 {
-    OpenGLZone aZone;
-
-    const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
-    const OpenGLSalBitmap& rMask = static_cast<const OpenGLSalBitmap&>(rMaskBitmap);
-    OpenGLTexture& rTexture( rBitmap.GetTexture() );
-    OpenGLTexture& rMaskTex( rMask.GetTexture() );
-
-    VCL_GL_INFO( "::drawBitmap with MASK" );
-    PreDraw();
-    DrawTextureWithMask( rTexture, rMaskTex, rPosAry );
-    PostDraw();
+    VCL_GL_INFO("::drawBitmap with MASK -> redirect to ::drawAlphaBitmap");
+    drawAlphaBitmap(rPosAry, rSalBitmap, rMaskBitmap);
 }
 
 void OpenGLSalGraphicsImpl::drawMask(
@@ -1992,6 +1974,8 @@ void OpenGLSalGraphicsImpl::drawMask(
 
 SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long nX, long nY, long nWidth, long nHeight )
 {
+    FlushDeferredDrawing();
+
     OpenGLZone aZone;
 
     OpenGLSalBitmap* pBitmap = new OpenGLSalBitmap;


More information about the Libreoffice-commits mailing list