[Libreoffice-commits] core.git: Branch 'feature/opengl-vcl2' - 3 commits - include/vcl vcl/generic vcl/headless vcl/inc vcl/opengl vcl/Package_opengl.mk vcl/quartz vcl/source vcl/unx vcl/win

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Tue Nov 18 09:46:27 PST 2014


 include/vcl/outdev.hxx                       |    4 +
 vcl/Package_opengl.mk                        |    2 
 vcl/generic/print/genpspgraphics.cxx         |   10 ++
 vcl/headless/svpgdi.cxx                      |   10 ++
 vcl/inc/generic/genpspgraphics.h             |    6 +
 vcl/inc/headless/svpgdi.hxx                  |    5 +
 vcl/inc/openglgdiimpl.hxx                    |   17 ++++
 vcl/inc/quartz/salgdi.h                      |    8 ++
 vcl/inc/salgdi.hxx                           |   24 ++++++
 vcl/inc/salgdiimpl.hxx                       |   10 ++
 vcl/inc/unx/salgdi.h                         |    8 ++
 vcl/inc/win/salgdi.h                         |    8 ++
 vcl/opengl/blendedTextureFragmentShader.glsl |   27 ++++++
 vcl/opengl/blendedTextureVertexShader.glsl   |   22 +++++
 vcl/opengl/gdiimpl.cxx                       |  107 ++++++++++++++++++++++++++-
 vcl/opengl/scale.cxx                         |    2 
 vcl/opengl/texture.cxx                       |    1 
 vcl/quartz/salgdicommon.cxx                  |   14 +++
 vcl/source/gdi/salgdilayout.cxx              |   30 +++++++
 vcl/source/outdev/bitmap.cxx                 |   27 ++++++
 vcl/unx/generic/gdi/gdiimpl.cxx              |   12 +++
 vcl/unx/generic/gdi/gdiimpl.hxx              |   12 +++
 vcl/unx/generic/gdi/salgdi2.cxx              |   14 +++
 vcl/win/source/gdi/gdiimpl.cxx               |   16 ++++
 vcl/win/source/gdi/gdiimpl.hxx               |   10 ++
 vcl/win/source/gdi/salgdi_gdiplus.cxx        |   16 ++++
 26 files changed, 417 insertions(+), 5 deletions(-)

New commits:
commit eb080a838353c2c82baaa2124e489d02a83c4ef1
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Tue Nov 18 12:44:34 2014 -0500

    vcl: Make sure the texture unit is the right one before binding
    
    Change-Id: I392190a6927a6eb725c86bcf5278e3cd4491eb5c

diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
index 938de54..c8f4684 100644
--- a/vcl/opengl/texture.cxx
+++ b/vcl/opengl/texture.cxx
@@ -244,6 +244,7 @@ bool OpenGLTexture::Draw()
         aTexCoord[3] = aTexCoord[5] = maRect.Bottom() / (double) mpImpl->mnHeight;
     }
 
+    glActiveTexture( GL_TEXTURE0 );
     glBindTexture( GL_TEXTURE_2D, mpImpl->mnTexture );
     glEnableVertexAttribArray( 0 );
     glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, aPosition );
commit 282d83a0cf5dd69de0a74d76693d4a844b9a585b
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Tue Nov 18 12:43:45 2014 -0500

    vcl: Update current context before executing scale operation
    
    Change-Id: I332c954259bdc7e34718449023f5aa82323987cc

diff --git a/vcl/opengl/scale.cxx b/vcl/opengl/scale.cxx
index 741bdd1..c4e32db 100644
--- a/vcl/opengl/scale.cxx
+++ b/vcl/opengl/scale.cxx
@@ -252,6 +252,8 @@ bool OpenGLSalBitmap::ImplScale( const double& rScaleX, const double& rScaleY, s
 {
     SAL_INFO( "vcl.opengl", "::ImplScale" );
 
+    makeCurrent();
+
     if( nScaleFlag == BMP_SCALE_FAST )
     {
         return ImplScaleFilter( rScaleX, rScaleY, GL_NEAREST );
commit 29153ff21cd70449418105269d33b78754d53136
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Tue Nov 18 12:34:53 2014 -0500

    vcl: Add support for backend-dependent blending of bitmaps (mask and alpha)
    
    Change-Id: Iba64eb42965c86ca5655b9a105ef3f397e033ecf

diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index d80d394..8d28680 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -1410,6 +1410,10 @@ private:
                                     const Point& rSrcPtPixel,
                                     const Size& rSrcSizePixel );
 
+    SAL_DLLPRIVATE bool         BlendBitmap(
+                                    const SalTwoRect&   rPosAry,
+                                    const Bitmap&       rBmp );
+
     SAL_DLLPRIVATE Bitmap       BlendBitmap(
                                     Bitmap&             aBmp,
                                     BitmapReadAccess*   pP,
diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk
index 9151d94..4a4f30f 100644
--- a/vcl/Package_opengl.mk
+++ b/vcl/Package_opengl.mk
@@ -10,6 +10,8 @@
 $(eval $(call gb_Package_Package,vcl_opengl_shader,$(SRCDIR)/vcl/opengl))
 
 $(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
+	blendedTextureFragmentShader.glsl \
+	blendedTextureVertexShader.glsl \
 	convolutionFragmentShader.glsl \
 	linearGradientFragmentShader.glsl \
 	maskFragmentShader.glsl \
diff --git a/vcl/generic/print/genpspgraphics.cxx b/vcl/generic/print/genpspgraphics.cxx
index db904da..f548cee 100644
--- a/vcl/generic/print/genpspgraphics.cxx
+++ b/vcl/generic/print/genpspgraphics.cxx
@@ -1166,6 +1166,16 @@ void GenPspGraphics::AnnounceFonts( PhysicalFontCollection* pFontCollection, con
     pFontCollection->Add( pFD );
 }
 
+bool GenPspGraphics::blendBitmap( const SalTwoRect&, const SalBitmap& )
+{
+    return false;
+}
+
+bool GenPspGraphics::blendAlphaBitmap( const SalTwoRect&, const SalBitmap&, const SalBitmap&, const SalBitmap& )
+{
+    return false;
+}
+
 bool GenPspGraphics::drawAlphaBitmap( const SalTwoRect&,
                                    const SalBitmap&,
                                    const SalBitmap& )
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index 9ad4c7b..a72c901 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -61,6 +61,16 @@ rDevice
 
 #ifndef IOS
 
+bool SvpSalGraphics::blendBitmap( const SalTwoRect&, const SalBitmap& /*rBitmap*/ )
+{
+    return false;
+}
+
+bool SvpSalGraphics::blendAlphaBitmap( const SalTwoRect&, const SalBitmap&, const SalBitmap&, const SalBitmap& )
+{
+    return false;
+}
+
 bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect&, const SalBitmap& /*rSourceBitmap*/, const SalBitmap& /*rAlphaBitmap*/ )
 {
     // TODO(P3) implement alpha blending
diff --git a/vcl/inc/generic/genpspgraphics.h b/vcl/inc/generic/genpspgraphics.h
index 382a693..18a434f 100644
--- a/vcl/inc/generic/genpspgraphics.h
+++ b/vcl/inc/generic/genpspgraphics.h
@@ -180,6 +180,12 @@ public:
 
     virtual bool            drawEPS( long nX, long nY, long nWidth, long nHeight,
                                      void* pPtr, sal_uIntPtr nSize ) SAL_OVERRIDE;
+    virtual bool            blendBitmap( const SalTwoRect&,
+                                         const SalBitmap& rBitmap ) SAL_OVERRIDE;
+    virtual bool            blendAlphaBitmap( const SalTwoRect&,
+                                              const SalBitmap& rSrcBitmap,
+                                              const SalBitmap& rMaskBitmap,
+                                              const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
     virtual bool            drawAlphaBitmap( const SalTwoRect&,
                                              const SalBitmap& rSourceBitmap,
                                              const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx
index 4da3ffa..9ae3d05 100644
--- a/vcl/inc/headless/svpgdi.hxx
+++ b/vcl/inc/headless/svpgdi.hxx
@@ -124,6 +124,11 @@ protected:
     vcl::Region                               m_aClipRegion;
 
 protected:
+    virtual bool blendBitmap( const SalTwoRect&, const SalBitmap& rBitmap ) SAL_OVERRIDE;
+    virtual bool blendAlphaBitmap( const SalTwoRect&,
+                                   const SalBitmap& rSrcBitmap,
+                                   const SalBitmap& rMaskBitmap,
+                                   const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
     virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
     virtual bool drawTransformedBitmap(
         const basegfx::B2DPoint& rNull,
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 29bc7a2..761b405 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -71,6 +71,11 @@ protected:
     GLuint mnMaskedSamplerUniform;
     GLuint mnMaskSamplerUniform;
 
+    GLuint mnBlendedTextureProgram;
+    GLuint mnBlendedTextureUniform;
+    GLuint mnBlendedMaskUniform;
+    GLuint mnBlendedAlphaUniform;
+
     GLuint mnMaskProgram;
     GLuint mnMaskUniform;
     GLuint mnMaskColorUniform;
@@ -92,6 +97,7 @@ protected:
     bool CreateTextureProgram( void );
     bool CreateTransformedTextureProgram( void );
     bool CreateMaskedTextureProgram( void );
+    bool CreateBlendedTextureProgram( void );
     bool CreateTransformedMaskedTextureProgram( void );
     bool CreateMaskProgram( void );
     bool CreateLinearGradientProgram( void );
@@ -119,6 +125,7 @@ public:
     void DrawTransformedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, const basegfx::B2DPoint& rY );
     void DrawAlphaTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false, bool pPremultiplied = false );
     void DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry );
+    void DrawBlendedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, OpenGLTexture& rAlpha, const SalTwoRect& rPosAry );
     void DrawMask( OpenGLTexture& rTexture, SalColor nMaskColor, const SalTwoRect& rPosAry );
     void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect );
     void DrawAxialGradient( const Gradient& rGradient, const Rectangle& rRect );
@@ -232,6 +239,16 @@ public:
     // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
     void DoCopyBits( const SalTwoRect& rPosAry, OpenGLSalGraphicsImpl *pSrcImpl );
 
+    virtual bool blendBitmap(
+                const SalTwoRect&,
+                const SalBitmap& rBitmap ) SAL_OVERRIDE;
+
+    virtual bool blendAlphaBitmap(
+                const SalTwoRect&,
+                const SalBitmap& rSrcBitmap,
+                const SalBitmap& rMaskBitmap,
+                const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
+
     virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) SAL_OVERRIDE;
 
     virtual void drawBitmap(
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index d25b093..9a5d4da 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -268,6 +268,14 @@ public:
 
     virtual bool            drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uLong nSize ) SAL_OVERRIDE;
 
+    virtual bool            blendBitmap( const SalTwoRect&,
+                                         const SalBitmap& rBitmap ) SAL_OVERRIDE;
+
+    virtual bool            blendAlphaBitmap( const SalTwoRect&,
+                                              const SalBitmap& rSrcBitmap,
+                                              const SalBitmap& rMaskBitmap,
+                                              const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
+
     virtual bool            drawAlphaBitmap( const SalTwoRect&,
                                              const SalBitmap& rSourceBitmap,
                                              const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index 95920a0..ff6271c 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -399,6 +399,18 @@ public:
                                     Rectangle &rNativeContentRegion,
                                     const OutputDevice *pOutDev );
 
+    bool                        BlendBitmap(
+                                    const SalTwoRect& rPosAry,
+                                    const SalBitmap& rSalBitmap,
+                                    const OutputDevice *pOutDev );
+
+    bool                        BlendAlphaBitmap(
+                                    const SalTwoRect& rPosAry,
+                                    const SalBitmap& rSalSrcBitmap,
+                                    const SalBitmap& rSalMaskBitmap,
+                                    const SalBitmap& rSalAlphaBitmap,
+                                    const OutputDevice *pOutDev );
+
     bool                        DrawAlphaBitmap(
                                     const SalTwoRect&,
                                     const SalBitmap& rSourceBitmap,
@@ -541,6 +553,18 @@ protected:
                                     Rectangle &rNativeBoundingRegion,
                                     Rectangle &rNativeContentRegion );
 
+    /** Blend the bitmap with the current buffer */
+    virtual bool                blendBitmap(
+                                    const SalTwoRect&,
+                                    const SalBitmap& rBitmap ) = 0;
+
+    /** Draw the bitmap by blending using the mask and alpha channel */
+    virtual bool                blendAlphaBitmap(
+                                    const SalTwoRect&,
+                                    const SalBitmap& rSrcBitmap,
+                                    const SalBitmap& rMaskBitmap,
+                                    const SalBitmap& rAlphaBitmap ) = 0;
+
     /** Render bitmap with alpha channel
 
         @param rSourceBitmap
diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx
index 09ea28f..2fd7f56 100644
--- a/vcl/inc/salgdiimpl.hxx
+++ b/vcl/inc/salgdiimpl.hxx
@@ -164,6 +164,16 @@ public:
                 void* pPtr,
                 sal_uLong nSize ) = 0;
 
+    virtual bool blendBitmap(
+                const SalTwoRect&,
+                const SalBitmap& rBitmap ) = 0;
+
+    virtual bool blendAlphaBitmap(
+                const SalTwoRect&,
+                const SalBitmap& rSrcBitmap,
+                const SalBitmap& rMaskBitmap,
+                const SalBitmap& rAlphaBitmap ) = 0;
+
     /** Render bitmap with alpha channel
 
         @param rSourceBitmap
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index 5caf7b9..97f9d60 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -249,6 +249,14 @@ public:
 
     virtual bool            drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uIntPtr nSize ) SAL_OVERRIDE;
 
+    virtual bool            blendBitmap( const SalTwoRect&,
+                                         const SalBitmap& rBitmap ) SAL_OVERRIDE;
+
+    virtual bool            blendAlphaBitmap( const SalTwoRect&,
+                                              const SalBitmap& rSrcBitmap,
+                                              const SalBitmap& rMaskBitmap,
+                                              const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
+
     virtual bool            drawAlphaBitmap( const SalTwoRect&,
                                              const SalBitmap& rSourceBitmap,
                                              const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 74e8fe0..2c39b8b 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -270,6 +270,14 @@ protected:
                                                 const ImplControlValue& aValue, const OUString& aCaption,
                                                 Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion );
 
+    virtual bool        blendBitmap( const SalTwoRect&,
+                                     const SalBitmap& rBitmap ) SAL_OVERRIDE;
+
+    virtual bool        blendAlphaBitmap( const SalTwoRect&,
+                                          const SalBitmap& rSrcBitmap,
+                                          const SalBitmap& rMaskBitmap,
+                                          const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
+
     virtual bool        drawAlphaBitmap( const SalTwoRect&,
                                          const SalBitmap& rSourceBitmap,
                                          const SalBitmap& rAlphaBitmap );
diff --git a/vcl/opengl/blendedTextureFragmentShader.glsl b/vcl/opengl/blendedTextureFragmentShader.glsl
new file mode 100644
index 0000000..b46f6ce
--- /dev/null
+++ b/vcl/opengl/blendedTextureFragmentShader.glsl
@@ -0,0 +1,27 @@
+/* -*- 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 tex_coord;
+varying vec2 alpha_coord;
+uniform sampler2D sampler;
+uniform sampler2D mask;
+uniform sampler2D alpha;
+
+void main() {
+    vec4 texel0, texel1, texel2;
+    texel0 = texture2D(sampler, tex_coord);
+    texel1 = texture2D(mask, tex_coord);
+    texel2 = texture2D(alpha, alpha_coord);
+    gl_FragColor = texel0;
+
+    /* Only blend if the the alpha texture wasn't fully transparent */
+    gl_FragColor.a = 1.0 - (1.0 - floor(texel2.r)) * texel1.r;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/blendedTextureVertexShader.glsl b/vcl/opengl/blendedTextureVertexShader.glsl
new file mode 100644
index 0000000..bc8972c
--- /dev/null
+++ b/vcl/opengl/blendedTextureVertexShader.glsl
@@ -0,0 +1,22 @@
+/* -*- 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/.
+ */
+
+attribute vec4 position;
+attribute vec2 tex_coord_in;
+attribute vec2 alpha_coord_in;
+varying vec2 tex_coord;
+varying vec2 alpha_coord;
+
+void main() {
+   gl_Position = position;
+   tex_coord = tex_coord_in;
+   alpha_coord = alpha_coord_in;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 8bd1b35..5883e7c8 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -37,8 +37,9 @@
 #include <glm/gtc/type_ptr.hpp>
 #include <vector>
 
-#define GL_ATTRIB_POS 0
-#define GL_ATTRIB_TEX 1
+#define GL_ATTRIB_POS  0
+#define GL_ATTRIB_TEX  1
+#define GL_ATTRIB_TEX2 2
 
 #define glUniformColor(nUniform, nColor, nTransparency)    \
     glUniform4f( nUniform,                                 \
@@ -86,6 +87,10 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl()
     , mnMaskedTextureProgram(0)
     , mnMaskedSamplerUniform(0)
     , mnMaskSamplerUniform(0)
+    , mnBlendedTextureProgram(0)
+    , mnBlendedTextureUniform(0)
+    , mnBlendedMaskUniform(0)
+    , mnBlendedAlphaUniform(0)
     , mnMaskProgram(0)
     , mnMaskUniform(0)
     , mnMaskColorUniform(0)
@@ -399,6 +404,23 @@ bool OpenGLSalGraphicsImpl::CreateTransformedMaskedTextureProgram( void )
     return true;
 }
 
+bool OpenGLSalGraphicsImpl::CreateBlendedTextureProgram( void )
+{
+    mnBlendedTextureProgram = OpenGLHelper::LoadShaders( "blendedTextureVertexShader", "blendedTextureFragmentShader" );
+    if( mnBlendedTextureProgram == 0 )
+        return false;
+
+    glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_POS, "position" );
+    glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
+    glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_TEX2, "alpha_coord_in" );
+    mnBlendedTextureUniform = glGetUniformLocation( mnBlendedTextureProgram, "sampler" );
+    mnBlendedMaskUniform = glGetUniformLocation( mnBlendedTextureProgram, "mask" );
+    mnBlendedAlphaUniform = glGetUniformLocation( mnBlendedTextureProgram, "alpha" );
+
+    CHECK_GL_ERROR();
+    return true;
+}
+
 bool OpenGLSalGraphicsImpl::CreateMaskProgram( void )
 {
     mnMaskProgram = OpenGLHelper::LoadShaders( "maskVertexShader", "maskFragmentShader" );
@@ -846,6 +868,50 @@ void OpenGLSalGraphicsImpl::DrawTextureWithMask( OpenGLTexture& rTexture, OpenGL
     CHECK_GL_ERROR();
 }
 
+void OpenGLSalGraphicsImpl::DrawBlendedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, OpenGLTexture& rAlpha, const SalTwoRect& rPosAry )
+{
+    GLfloat aTexCoord[8];
+
+    if( mnBlendedTextureProgram == 0 )
+    {
+        if( !CreateBlendedTextureProgram() )
+            return;
+    }
+
+    glUseProgram( mnBlendedTextureProgram );
+    glUniform1i( mnBlendedTextureUniform, 0 );
+    glUniform1i( mnBlendedMaskUniform, 1 );
+    glUniform1i( mnBlendedAlphaUniform, 2 );
+    glActiveTexture( GL_TEXTURE0 );
+    rTexture.Bind();
+    glActiveTexture( GL_TEXTURE1 );
+    rMask.Bind();
+    glActiveTexture( GL_TEXTURE2 );
+    rAlpha.Bind();
+
+    rAlpha.GetCoord( aTexCoord, rPosAry );
+    glEnableVertexAttribArray( GL_ATTRIB_TEX2 );
+    glVertexAttribPointer( GL_ATTRIB_TEX2, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
+
+    glEnable( GL_BLEND );
+    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+    DrawTextureRect( rTexture, rPosAry );
+    glDisable( GL_BLEND );
+
+    glDisableVertexAttribArray( GL_ATTRIB_TEX2 );
+
+    glActiveTexture( GL_TEXTURE0 );
+    rTexture.Unbind();
+    glActiveTexture( GL_TEXTURE1 );
+    rMask.Unbind();
+    glActiveTexture( GL_TEXTURE2 );
+    rAlpha.Unbind();
+    glActiveTexture( GL_TEXTURE0 );
+    glUseProgram( 0 );
+
+    CHECK_GL_ERROR();
+}
+
 void OpenGLSalGraphicsImpl::DrawMask( OpenGLTexture& rMask, SalColor nMaskColor, const SalTwoRect& pPosAry )
 {
     if( mnMaskProgram == 0 )
@@ -1475,6 +1541,43 @@ bool OpenGLSalGraphicsImpl::drawEPS(
     return false;
 }
 
+bool OpenGLSalGraphicsImpl::blendBitmap(
+            const SalTwoRect& rPosAry,
+            const SalBitmap& rSalBitmap )
+{
+    const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
+    OpenGLTexture& rTexture( rBitmap.GetTexture() );
+
+    SAL_INFO( "vcl.opengl", "::blendBitmap" );
+    PreDraw();
+    glEnable( GL_BLEND );
+    glBlendFunc( GL_ZERO, GL_SRC_COLOR );
+    DrawTexture( rTexture, rPosAry );
+    glDisable( GL_BLEND );
+    PostDraw();
+    return true;
+}
+
+bool OpenGLSalGraphicsImpl::blendAlphaBitmap(
+            const SalTwoRect& rPosAry,
+            const SalBitmap& rSalSrcBitmap,
+            const SalBitmap& rSalMaskBitmap,
+            const SalBitmap& rSalAlphaBitmap )
+{
+    const OpenGLSalBitmap& rSrcBitmap = static_cast<const OpenGLSalBitmap&>(rSalSrcBitmap);
+    const OpenGLSalBitmap& rMaskBitmap = static_cast<const OpenGLSalBitmap&>(rSalMaskBitmap);
+    const OpenGLSalBitmap& rAlphaBitmap = static_cast<const OpenGLSalBitmap&>(rSalAlphaBitmap);
+    OpenGLTexture& rTexture( rSrcBitmap.GetTexture() );
+    OpenGLTexture& rMask( rMaskBitmap.GetTexture() );
+    OpenGLTexture& rAlpha( rAlphaBitmap.GetTexture() );
+
+    SAL_INFO( "vcl.opengl", "::blendAlphaBitmap" );
+    PreDraw();
+    DrawBlendedTexture( rTexture, rMask, rAlpha, rPosAry );
+    PostDraw();
+    return true;
+}
+
 /** Render bitmap with alpha channel
 
     @param rSourceBitmap
diff --git a/vcl/quartz/salgdicommon.cxx b/vcl/quartz/salgdicommon.cxx
index 6a8d953..21c8d2a 100644
--- a/vcl/quartz/salgdicommon.cxx
+++ b/vcl/quartz/salgdicommon.cxx
@@ -562,6 +562,20 @@ void AquaSalGraphics::copyResolution( AquaSalGraphics& rGraphics )
 
 #endif
 
+bool AquaSalGraphics::blendBitmap( const SalTwoRect&,
+                                   const SalBitmap& )
+{
+    return false;
+}
+
+bool AquaSalGraphics::blendAlphaBitmap( const SalTwoRect&,
+                                        const SalBitmap&,
+                                        const SalBitmap&,
+                                        const SalBitmap& )
+{
+    return false;
+}
+
 bool AquaSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
                                        const SalBitmap& rSrcBitmap,
                                        const SalBitmap& rAlphaBmp )
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index da02043..a075b4d 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -762,6 +762,36 @@ bool SalGraphics::GetNativeControlRegion( ControlType nType, ControlPart nPart,
                                                 rNativeBoundingRegion, rNativeContentRegion );
 }
 
+bool SalGraphics::BlendBitmap( const SalTwoRect& rPosAry,
+                               const SalBitmap& rBitmap,
+                               const OutputDevice *pOutDev )
+{
+    if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
+    {
+        SalTwoRect aPosAry2 = rPosAry;
+        mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev );
+        return blendBitmap( aPosAry2, rBitmap );
+    }
+    else
+        return blendBitmap( rPosAry, rBitmap );
+}
+
+bool SalGraphics::BlendAlphaBitmap( const SalTwoRect& rPosAry,
+                                    const SalBitmap& rSrcBitmap,
+                                    const SalBitmap& rMaskBitmap,
+                                    const SalBitmap& rAlphaBitmap,
+                                    const OutputDevice *pOutDev )
+{
+    if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
+    {
+        SalTwoRect aPosAry2 = rPosAry;
+        mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev );
+        return blendAlphaBitmap( aPosAry2, rSrcBitmap, rMaskBitmap, rAlphaBitmap );
+    }
+    else
+        return blendAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap, rAlphaBitmap );
+}
+
 bool SalGraphics::DrawAlphaBitmap( const SalTwoRect& rPosAry,
                                    const SalBitmap& rSourceBitmap,
                                    const SalBitmap& rAlphaBitmap,
diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx
index 4b0583b..f4304ac 100644
--- a/vcl/source/outdev/bitmap.cxx
+++ b/vcl/source/outdev/bitmap.cxx
@@ -659,7 +659,7 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r
         static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
         // #i83087# Naturally, system alpha blending cannot work with
         // separate alpha VDev
-        bool bTryDirectPaint(!mpAlphaVDev && !pDisableNative && !bHMirr && !bVMirr);
+        bool bTryDirectPaint(!pDisableNative && !bHMirr && !bVMirr);
 
         if (bTryDirectPaint)
         {
@@ -684,8 +684,22 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r
             SalBitmap* pSalSrcBmp = rBmp.ImplGetImpBitmap()->ImplGetSalBitmap();
             SalBitmap* pSalAlphaBmp = rAlpha.ImplGetImpBitmap()->ImplGetSalBitmap();
 
-            if (mpGraphics->DrawAlphaBitmap( aTR, *pSalSrcBmp, *pSalAlphaBmp, this ))
-                return;
+            // try the blen the alpha bitmap with the alpha virtual device
+            if( mpAlphaVDev )
+            {
+                Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( aRelPt, aOutSz ) );
+                SalBitmap* pSalAlphaBmp2 = aAlphaBitmap.ImplGetImpBitmap()->ImplGetSalBitmap();
+                if( mpGraphics->BlendAlphaBitmap( aTR, *pSalSrcBmp, *pSalAlphaBmp, *pSalAlphaBmp2, this ) )
+                {
+                    mpAlphaVDev->BlendBitmap( aTR, rAlpha );
+                    return;
+                }
+            }
+            else
+            {
+                if (mpGraphics->DrawAlphaBitmap( aTR, *pSalSrcBmp, *pSalAlphaBmp, this ))
+                    return;
+            }
         }
 
         // we need to make sure OpenGL never reaches this slow code path
@@ -1216,6 +1230,13 @@ namespace
     }
 }
 
+bool OutputDevice::BlendBitmap(
+            const SalTwoRect&   rPosAry,
+            const Bitmap&       rBmp )
+{
+    return mpGraphics->BlendBitmap( rPosAry, *rBmp.ImplGetImpBitmap()->ImplGetSalBitmap(), this );
+}
+
 Bitmap OutputDevice::BlendBitmapWithAlpha(
             Bitmap&             aBmp,
             BitmapReadAccess*   pP,
diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx
index ee7e596..bcf8d05 100644
--- a/vcl/unx/generic/gdi/gdiimpl.cxx
+++ b/vcl/unx/generic/gdi/gdiimpl.cxx
@@ -821,6 +821,18 @@ void X11SalGraphicsImpl::drawMaskedBitmap( const SalTwoRect& rPosAry,
         XFreePixmap( pXDisp, aBG );
 }
 
+bool X11SalGraphicsImpl::blendBitmap( const SalTwoRect&,
+    const SalBitmap& )
+{
+    return false;
+}
+
+bool X11SalGraphicsImpl::blendAlphaBitmap( const SalTwoRect&,
+    const SalBitmap&, const SalBitmap&, const SalBitmap& )
+{
+    return false;
+}
+
 bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR,
     const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp )
 {
diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx
index 2d9294a..20c995f 100644
--- a/vcl/unx/generic/gdi/gdiimpl.hxx
+++ b/vcl/unx/generic/gdi/gdiimpl.hxx
@@ -225,6 +225,18 @@ public:
                 void* pPtr,
                 sal_uLong nSize ) SAL_OVERRIDE;
 
+    /** Blend bitmap with color channels */
+    virtual bool blendBitmap(
+                const SalTwoRect&,
+                const SalBitmap& rBitmap ) SAL_OVERRIDE;
+
+    /** Render bitmap by blending using the mask and alpha channel */
+    virtual bool blendAlphaBitmap(
+                const SalTwoRect&,
+                const SalBitmap& rSrcBitmap,
+                const SalBitmap& rMaskBitmap,
+                const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
+
     /** Render bitmap with alpha channel
 
         @param rSourceBitmap
diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx
index 9ef50b8..b848d660 100644
--- a/vcl/unx/generic/gdi/salgdi2.cxx
+++ b/vcl/unx/generic/gdi/salgdi2.cxx
@@ -167,6 +167,20 @@ void X11SalGraphics::copyArea ( long nDestX,    long nDestY,
     mpImpl->copyArea( nDestX, nDestY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, n );
 }
 
+bool X11SalGraphics::blendBitmap( const SalTwoRect& rTR,
+                                  const SalBitmap& rBitmap )
+{
+    return mpImpl->blendBitmap( rTR, rBitmap );
+}
+
+bool X11SalGraphics::blendAlphaBitmap( const SalTwoRect& rTR,
+                                       const SalBitmap& rSrcBitmap,
+                                       const SalBitmap& rMaskBitmap,
+                                       const SalBitmap& rAlphaBitmap )
+{
+    return mpImpl->blendAlphaBitmap( rTR, rSrcBitmap, rMaskBitmap, rAlphaBitmap );
+}
+
 void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
 {
     mpImpl->drawBitmap( rPosAry, rSalBitmap );
diff --git a/vcl/win/source/gdi/gdiimpl.cxx b/vcl/win/source/gdi/gdiimpl.cxx
index 03ad554..8a4b390 100644
--- a/vcl/win/source/gdi/gdiimpl.cxx
+++ b/vcl/win/source/gdi/gdiimpl.cxx
@@ -2252,6 +2252,22 @@ bool WinSalGraphicsImpl::tryDrawBitmapGdiPlus(const SalTwoRect& rTR, const SalBi
     return false;
 }
 
+bool WinSalGraphicsImpl::blendBitmap(
+    const SalTwoRect&,
+    const SalBitmap&)
+{
+    return false;
+}
+
+bool WinSalGraphicsImpl::blendAlphaBitmap(
+    const SalTwoRect&,
+    const SalBitmap&,
+    const SalBitmap&,
+    const SalBitmap&)
+{
+    return false;
+}
+
 bool WinSalGraphicsImpl::drawAlphaBitmap(
     const SalTwoRect& rTR,
     const SalBitmap& rSrcBitmap,
diff --git a/vcl/win/source/gdi/gdiimpl.hxx b/vcl/win/source/gdi/gdiimpl.hxx
index a1c781a..ded35ac 100644
--- a/vcl/win/source/gdi/gdiimpl.hxx
+++ b/vcl/win/source/gdi/gdiimpl.hxx
@@ -172,6 +172,16 @@ public:
                 void* pPtr,
                 sal_uLong nSize ) SAL_OVERRIDE;
 
+    virtual bool blendBitmap(
+                const SalTwoRect&,
+                const SalBitmap& rBitmap ) SAL_OVERRIDE;
+
+    virtual bool blendAlphaBitmap(
+                const SalTwoRect&,
+                const SalBitmap& rSrcBitmap,
+                const SalBitmap& rMaskBitmap,
+                const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
+
     /** Render bitmap with alpha channel
 
         @param rSourceBitmap
diff --git a/vcl/win/source/gdi/salgdi_gdiplus.cxx b/vcl/win/source/gdi/salgdi_gdiplus.cxx
index 65dbdd8..094a05c 100644
--- a/vcl/win/source/gdi/salgdi_gdiplus.cxx
+++ b/vcl/win/source/gdi/salgdi_gdiplus.cxx
@@ -43,6 +43,22 @@ bool WinSalGraphics::drawPolyLine(
             eLineJoin, eLineCap);
 }
 
+bool WinSalGraphics::blendBitmap(
+    const SalTwoRect& rTR,
+    const SalBitmap& rBmp)
+{
+    return mpImpl->blendBitmap(rTR, rBmp);
+}
+
+bool WinSalGraphics::blendAlphaBitmap(
+    const SalTwoRect& rTR,
+    const SalBitmap& rSrcBmp,
+    const SalBitmap& rMaskBmp,
+    const SalBitmap& rAlphaBmp)
+{
+    return mpImpl->blendAlphaBitmap(rTR, rSrcBmp, rMaskBmp, rAlphaBmp);
+}
+
 bool WinSalGraphics::drawAlphaBitmap(
     const SalTwoRect& rTR,
     const SalBitmap& rSrcBitmap,


More information about the Libreoffice-commits mailing list