[Libreoffice-commits] core.git: Branch 'feature/lfrb-vcl-opengl' - 5 commits - include/vcl vcl/inc vcl/Library_vcl.mk vcl/opengl vcl/unx

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Thu Oct 30 19:01:59 PDT 2014


 include/vcl/opengl/OpenGLContext.hxx |    2 
 vcl/Library_vcl.mk                   |    1 
 vcl/inc/opengl/salbmp.hxx            |   90 ++++++
 vcl/inc/openglgdiimpl.hxx            |    5 
 vcl/opengl/gdiimpl.cxx               |   71 +++-
 vcl/opengl/salbmp.cxx                |  521 +++++++++++++++++++++++++++++++++++
 vcl/opengl/solidFragmentShader.glsl  |    2 
 vcl/opengl/solidVertexShader.glsl    |    2 
 vcl/unx/generic/gdi/salbmp.cxx       |    8 
 9 files changed, 673 insertions(+), 29 deletions(-)

New commits:
commit a37529d87e34022266ffb90a287390ba1f5c95e0
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Thu Oct 30 22:01:25 2014 -0400

    vcl: Remove the extra colon at the end of shader
    
    Change-Id: I0a1a2346176a9f2f4d62ca80a9485d720b522cef

diff --git a/vcl/opengl/solidVertexShader.glsl b/vcl/opengl/solidVertexShader.glsl
index c3de9c5..47061f6 100644
--- a/vcl/opengl/solidVertexShader.glsl
+++ b/vcl/opengl/solidVertexShader.glsl
@@ -10,7 +10,7 @@
 attribute vec4 position;
 void main() {
    gl_Position = position;
-};
+}
 
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 4be854675106b7c99e9369bc728e05cdc939cdc6
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Thu Oct 30 22:00:37 2014 -0400

    vcl: Add OpenGLSalBitmap implementation
    
    Change-Id: I0deebaedf6fe5b23f50a448eea0d5d9e99ebd391

diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 8580701..c085df8 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -123,6 +123,7 @@ $(eval $(call gb_Library_use_externals,vcl,\
 
 $(eval $(call gb_Library_add_exception_objects,vcl,\
 	vcl/opengl/gdiimpl \
+	vcl/opengl/salbmp \
     vcl/source/opengl/OpenGLContext \
     vcl/source/opengl/OpenGLHelper \
     vcl/source/window/openglwin \
diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx
new file mode 100644
index 0000000..5661e56
--- /dev/null
+++ b/vcl/inc/opengl/salbmp.hxx
@@ -0,0 +1,90 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_SALBMP_H
+#define INCLUDED_VCL_INC_OPENGL_SALBMP_H
+
+#include <basebmp/bitmapdevice.hxx>
+#include <vcl/opengl/OpenGLContext.hxx>
+
+#include "vcl/salbtype.hxx"
+
+#include <salbmp.hxx>
+
+// - SalBitmap  -
+
+struct  BitmapBuffer;
+class   BitmapPalette;
+
+class VCL_PLUGIN_PUBLIC OpenGLSalBitmap : public SalBitmap
+{
+private:
+    OpenGLContext*                  mpContext;
+    GLuint                          mnTexture;
+    bool                            mbDirtyTexture;
+    BitmapPalette                   maPalette;
+    basebmp::RawMemorySharedArray   maUserBuffer;
+    sal_uInt16                      mnBits;
+    sal_uInt16                      mnBytesPerRow;
+    int                             mnWidth;
+    int                             mnHeight;
+
+public:
+    OpenGLSalBitmap();
+    virtual ~OpenGLSalBitmap();
+
+public:
+
+    // SalBitmap methods
+    bool            Create( const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal ) SAL_OVERRIDE;
+    bool            Create( const SalBitmap& rSalBmp ) SAL_OVERRIDE;
+    bool            Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics ) SAL_OVERRIDE;
+    bool            Create( const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount ) SAL_OVERRIDE;
+    virtual bool    Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > xBitmapCanvas,
+                            Size& rSize,
+                            bool bMask = false ) SAL_OVERRIDE;
+
+    void            Destroy() SAL_OVERRIDE;
+
+    Size            GetSize() const SAL_OVERRIDE;
+    sal_uInt16      GetBitCount() const SAL_OVERRIDE;
+
+    BitmapBuffer   *AcquireBuffer( bool bReadOnly ) SAL_OVERRIDE;
+    void            ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) SAL_OVERRIDE;
+
+    bool            GetSystemData( BitmapSystemData& rData ) SAL_OVERRIDE;
+
+public:
+
+    bool            Create( OpenGLContext& rContext, long nX, long nY, long nWidth, long nHeight );
+    bool            Draw( OpenGLContext& rContext, const SalTwoRect& rPosAry );
+    GLuint          GetTexture( OpenGLContext& rContext ) const;
+
+private:
+
+    GLuint          CreateTexture();
+    void            DeleteTexture();
+    void            DrawTexture( GLuint nTexture, const SalTwoRect& rPosAry );
+    bool            AllocateUserData();
+    bool            ReadTexture();
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_SALBMP_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 9259468..3066242 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -23,6 +23,7 @@
 #include <basegfx/polygon/b2dpolygontriangulator.hxx>
 
 #include <vcl/opengl/OpenGLHelper.hxx>
+#include "opengl/salbmp.hxx"
 
 #define GL_ATTRIB_POS 0
 #define GL_ATTRIB_TEX 1
@@ -653,8 +654,9 @@ void OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* /*
 void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
 {
     const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
-    GLuint nTexture = rBitmap.GetTexture();
+    GLuint nTexture = rBitmap.GetTexture( maContext );
 
+    SAL_INFO( "vcl.opengl", "::drawBitmap" );
     maContext.makeCurrent();
     DrawTexture( nTexture, rPosAry );
 }
@@ -674,9 +676,10 @@ void OpenGLSalGraphicsImpl::drawBitmap(
 {
     const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
     const OpenGLSalBitmap& rMask = static_cast<const OpenGLSalBitmap&>(rMaskBitmap);
-    const GLuint nTexture( rBitmap.GetTexture() );
-    const GLuint nMask( rMask.GetTexture() );
+    const GLuint nTexture( rBitmap.GetTexture( maContext ) );
+    const GLuint nMask( rMask.GetTexture( maContext ) );
 
+    SAL_INFO( "vcl.opengl", "::drawBitmap" );
     maContext.makeCurrent();
     DrawTextureWithMask( nTexture, nMask, rPosAry );
 }
@@ -687,22 +690,16 @@ void OpenGLSalGraphicsImpl::drawMask(
             SalColor nMaskColor )
 {
     const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
-    const GLuint nTexture( rBitmap.GetTexture() );
+    const GLuint nTexture( rBitmap.GetTexture( maContext ) );
 
+    maContext.makeCurrent();
     DrawMask( nTexture, nMaskColor, rPosAry );
 }
 
 SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long nX, long nY, long nWidth, long nHeight )
 {
-    GLuint nTexture;
-
-    /*glGenTexture( 1, &nTexture );
-    glBindTexture( GL_TEXTURE_2D, nTexture );
-    glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, nX, nY, nWidth, nHeight, 0 );
-    glBindTexture( GL_TEXTURE_2D, 0 );*/
-
     OpenGLSalBitmap* pBitmap = new OpenGLSalBitmap;
-    if( !pBitmap->Create( nX, nY, nWidth, nHeight ) )
+    if( !pBitmap->Create( maContext, nX, nY, nWidth, nHeight ) )
     {
         delete pBitmap;
         pBitmap = NULL;
@@ -795,8 +792,8 @@ bool OpenGLSalGraphicsImpl::drawAlphaBitmap(
 {
     const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
     const OpenGLSalBitmap& rAlpha = static_cast<const OpenGLSalBitmap&>(rAlphaBitmap);
-    const GLuint nTexture( rBitmap.GetTexture() );
-    const GLuint nAlpha( rAlpha.GetTexture() );
+    const GLuint nTexture( rBitmap.GetTexture( maContext ) );
+    const GLuint nAlpha( rAlpha.GetTexture( maContext ) );
 
     maContext.makeCurrent();
     DrawTextureWithMask( nTexture, nAlpha, rPosAry );
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
new file mode 100644
index 0000000..84ada34
--- /dev/null
+++ b/vcl/opengl/salbmp.cxx
@@ -0,0 +1,521 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+#include "vcl/bitmap.hxx"
+#include "vcl/salbtype.hxx"
+#include "salgdi.hxx"
+
+#include "opengl/salbmp.hxx"
+#include "unx/salbmp.h"
+
+static bool isValidBitCount( sal_uInt16 nBitCount )
+{
+    return (nBitCount == 1) || (nBitCount == 4) || (nBitCount == 8) || (nBitCount == 16) || (nBitCount == 24) || (nBitCount == 32);
+}
+
+OpenGLSalBitmap::OpenGLSalBitmap()
+: mnTexture(0)
+, mbDirtyTexture(true)
+, mnBits(0)
+, mnBytesPerRow(0)
+, mnWidth(0)
+, mnHeight(0)
+{
+}
+
+OpenGLSalBitmap::~OpenGLSalBitmap()
+{
+    Destroy();
+}
+
+bool OpenGLSalBitmap::Create( OpenGLContext& rContext, long nX, long nY, long nWidth, long nHeight )
+{
+    static const BitmapPalette aEmptyPalette;
+
+    Destroy();
+
+    mpContext = &rContext;
+    mpContext->makeCurrent();
+    mnWidth = nWidth;
+    mnHeight = nHeight;
+
+    // TODO Check the framebuffer configuration
+    mnBits = 32;
+    maPalette = aEmptyPalette;
+
+    glGenTextures( 1, &mnTexture );
+    glBindTexture( GL_TEXTURE_2D, mnTexture );
+    glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nX, nY, nWidth, nHeight, 0 );
+    glBindTexture( GL_TEXTURE_2D, 0 );
+
+    return true;
+}
+
+bool OpenGLSalBitmap::Create( const Size& rSize, sal_uInt16 nBits, const BitmapPalette& rBitmapPalette )
+{
+    Destroy();
+
+    if( !isValidBitCount( nBits ) )
+        return false;
+    maPalette = rBitmapPalette;
+    mnBits = nBits;
+    mnWidth = rSize.Width();
+    mnHeight = rSize.Height();
+    return false;
+}
+
+bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp )
+{
+    return Create( rSalBmp, rSalBmp.GetBitCount() );
+}
+
+bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics )
+{
+    return Create( rSalBmp, pGraphics ? pGraphics->GetBitCount() : rSalBmp.GetBitCount() );
+}
+
+bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount )
+{
+    const OpenGLSalBitmap& rSourceBitmap = static_cast<const OpenGLSalBitmap&>(rSalBmp);
+
+    if( isValidBitCount( nNewBitCount ) )
+    {
+        mnBits = nNewBitCount;
+        mnWidth = rSourceBitmap.mnWidth;
+        mnHeight = rSourceBitmap.mnHeight;
+        maPalette = rSourceBitmap.maPalette;
+        mnTexture = rSourceBitmap.mnTexture;
+
+        // TODO Copy buffer data if the bitcount and palette are the same
+        return true;
+    }
+    return false;
+}
+
+bool OpenGLSalBitmap::Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > /*xBitmapCanvas*/, Size& /*rSize*/, bool /*bMask*/ )
+{
+    // TODO Is this method needed?
+    return false;
+}
+
+bool OpenGLSalBitmap::Draw( OpenGLContext& rContext, const SalTwoRect& rPosAry )
+{
+    if( !mpContext )
+        mpContext = &rContext;
+
+    if( !mnTexture || mbDirtyTexture )
+    {
+        if( !CreateTexture() )
+            return false;
+    }
+
+    DrawTexture( mnTexture, rPosAry );
+    return true;
+}
+
+GLuint OpenGLSalBitmap::GetTexture( OpenGLContext& rContext ) const
+{
+    if( !mpContext )
+        const_cast<OpenGLSalBitmap*>(this)->mpContext = &rContext;
+    if( !mnTexture || mbDirtyTexture )
+        const_cast<OpenGLSalBitmap*>(this)->CreateTexture();
+    return mnTexture;
+}
+
+void OpenGLSalBitmap::Destroy()
+{
+    DeleteTexture();
+    maUserBuffer.reset();
+}
+
+bool OpenGLSalBitmap::AllocateUserData()
+{
+    Destroy();
+
+    if( mnWidth && mnHeight )
+    {
+        mnBytesPerRow =  0;
+
+        switch( mnBits )
+        {
+        case 1:     mnBytesPerRow = (mnWidth + 7) >> 3; break;
+        case 4:     mnBytesPerRow = (mnWidth + 1) >> 1; break;
+        case 8:     mnBytesPerRow = mnWidth; break;
+        case 16:    mnBytesPerRow = mnWidth << 1; break;
+        case 24:    mnBytesPerRow = (mnWidth << 1) + mnWidth; break;
+        case 32:    mnBytesPerRow = mnWidth << 2; break;
+        default:
+            OSL_FAIL("vcl::OpenGLSalBitmap::AllocateUserData(), illegal bitcount!");
+        }
+    }
+
+    bool alloc = false;
+    if (mnBytesPerRow != 0
+        && mnBytesPerRow <= std::numeric_limits<sal_uInt32>::max() / mnHeight)
+    {
+        try
+        {
+            maUserBuffer.reset( new sal_uInt8[mnBytesPerRow * mnHeight] );
+            alloc = true;
+        }
+        catch (std::bad_alloc &) {}
+    }
+    if (!alloc)
+    {
+        SAL_WARN(
+            "vcl.opengl", "bad alloc " << mnBytesPerRow << "x" << mnHeight);
+        maUserBuffer.reset( static_cast<sal_uInt8*>(NULL) );
+        mnBytesPerRow = 0;
+    }
+#ifdef DBG_UTIL
+    else
+    {
+        for (size_t i = 0; i < mnBytesPerRow * mnHeight; i++)
+            maUserBuffer.get()[i] = (i & 0xFF);
+    }
+#endif
+
+    return maUserBuffer.get() != 0;
+}
+
+class ImplPixelFormat
+{
+protected:
+    sal_uInt8* mpData;
+public:
+    static ImplPixelFormat* GetFormat( sal_uInt16 nBits, const BitmapPalette& rPalette );
+
+    virtual void StartLine( sal_uInt8* pLine ) { mpData = pLine; }
+    virtual const BitmapColor& ReadPixel() = 0;
+    virtual ~ImplPixelFormat() { }
+};
+
+class ImplPixelFormat8 : public ImplPixelFormat
+{
+private:
+    const BitmapPalette& mrPalette;
+
+public:
+    ImplPixelFormat8( const BitmapPalette& rPalette )
+    : mrPalette( rPalette )
+    {
+    }
+    virtual const BitmapColor& ReadPixel() SAL_OVERRIDE
+    {
+        return mrPalette[ *mpData++ ];
+    }
+};
+
+class ImplPixelFormat4 : public ImplPixelFormat
+{
+private:
+    const BitmapPalette& mrPalette;
+    sal_uInt32 mnX;
+    sal_uInt32 mnShift;
+
+public:
+    ImplPixelFormat4( const BitmapPalette& rPalette )
+    : mrPalette( rPalette )
+    {
+    }
+    virtual void StartLine( sal_uInt8* pLine ) SAL_OVERRIDE
+    {
+        mpData = pLine;
+        mnX = 0;
+        mnShift = 4;
+    }
+    virtual const BitmapColor& ReadPixel() SAL_OVERRIDE
+    {
+        const BitmapColor& rColor = mrPalette[( mpData[mnX >> 1] >> mnShift) & 0x0f];
+        mnX++;
+        mnShift ^= 4;
+        return rColor;
+    }
+};
+
+class ImplPixelFormat1 : public ImplPixelFormat
+{
+private:
+    const BitmapPalette& mrPalette;
+    sal_uInt32 mnX;
+
+public:
+    ImplPixelFormat1( const BitmapPalette& rPalette )
+    : mrPalette( rPalette )
+    {
+    }
+    virtual void StartLine( sal_uInt8* pLine ) SAL_OVERRIDE
+    {
+        mpData = pLine;
+        mnX = 0;
+    }
+    virtual const BitmapColor& ReadPixel() SAL_OVERRIDE
+    {
+        const BitmapColor& rColor = mrPalette[ (mpData[mnX >> 3 ] >> ( 7 - ( mnX & 7 ) )) & 1];
+        mnX++;
+        return rColor;
+    }
+};
+
+ImplPixelFormat* ImplPixelFormat::GetFormat( sal_uInt16 nBits, const BitmapPalette& rPalette )
+{
+    switch( nBits )
+    {
+    case 1: return new ImplPixelFormat1( rPalette );
+    case 4: return new ImplPixelFormat4( rPalette );
+    case 8: return new ImplPixelFormat8( rPalette );
+    }
+
+    return 0;
+}
+
+Size OpenGLSalBitmap::GetSize() const
+{
+    return Size( mnWidth, mnHeight );
+}
+
+GLuint OpenGLSalBitmap::CreateTexture()
+{
+    GLenum nFormat, nType;
+    sal_uInt8* pData( NULL );
+    bool bAllocated( false );
+
+    if( maUserBuffer.get() != 0 )
+    {
+        if( mnBits == 16 || mnBits == 24 || mnBits == 32 )
+        {
+            // no conversion needed for truecolor
+            pData = maUserBuffer.get();
+
+            switch( mnBits )
+            {
+            case 16:    nFormat = GL_RGB;
+                        nType = GL_UNSIGNED_SHORT_5_6_5;
+                        break;
+            case 24:    nFormat = GL_RGB;
+                        nType = GL_UNSIGNED_BYTE;
+                        break;
+            case 32:    nFormat = GL_RGBA;
+                        nType = GL_UNSIGNED_BYTE;
+                        break;
+            }
+        }
+        else if( mnBits == 8 && maPalette.IsGreyPalette() )
+        {
+            // no conversion needed for grayscale
+            pData = maUserBuffer.get();
+            nFormat = GL_LUMINANCE;
+            nType = GL_UNSIGNED_BYTE;
+        }
+        else
+        {
+            // convert to 32 bits RGBA using palette
+            pData = new sal_uInt8[ mnHeight * (mnWidth << 2) ];
+            bAllocated = true;
+            nFormat = GL_RGBA;
+            nType = GL_UNSIGNED_BYTE;
+
+            ImplPixelFormat* pSrcFormat = ImplPixelFormat::GetFormat( mnBits, maPalette );
+            sal_uInt8* pSrcData = maUserBuffer.get();
+            sal_uInt8* pDstData = pData;
+
+            sal_uInt32 nY = mnHeight;
+            while( nY-- )
+            {
+                pSrcFormat->StartLine( pSrcData );
+
+                sal_uInt32 nX = mnWidth;
+                while( nX-- )
+                {
+                    const BitmapColor& c = pSrcFormat->ReadPixel();
+
+                    *pDstData++ = c.GetRed();
+                    *pDstData++ = c.GetGreen();
+                    *pDstData++ = c.GetBlue();
+                    *pDstData++ = 255;
+                }
+
+                pSrcData += mnBytesPerRow;
+            }
+        }
+    }
+
+    mpContext->makeCurrent();
+    if( !mnTexture )
+        glGenTextures( 1, &mnTexture );
+    glBindTexture( GL_TEXTURE_2D, mnTexture );
+    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, mnWidth, mnHeight, 0, nFormat, nType, pData );
+    glBindTexture( GL_TEXTURE_2D, 0 );
+
+    if( bAllocated )
+        delete pData;
+
+    mbDirtyTexture = false;
+    return mnTexture;
+}
+
+void OpenGLSalBitmap::DeleteTexture()
+{
+    if( mnTexture )
+    {
+        mpContext->makeCurrent();
+        glDeleteTextures( 1, &mnTexture );
+        mnTexture = 0;
+    }
+}
+
+void OpenGLSalBitmap::DrawTexture( GLuint nTexture, const SalTwoRect& /*rPosAry*/ )
+{
+    GLushort aTexCoord[8];
+    GLushort aVertices[8];
+
+    /*if( mnTextureProgram == 0 )
+    {
+        if( !CreateTextureProgram() )
+            return;
+    }*/
+
+    //glUseProgram( mnTextureProgram );
+    //glUniform1i( mnSamplerUniform, 0 );
+    glActiveTexture( GL_TEXTURE0 );
+    glBindTexture( GL_TEXTURE_2D, nTexture );
+    glEnableVertexAttribArray( 0 );
+    glVertexAttribPointer( 0, 8, GL_UNSIGNED_SHORT, GL_FALSE, 0, aTexCoord );
+    glEnableVertexAttribArray( 1 );
+    glVertexAttribPointer( 1, 8, GL_UNSIGNED_SHORT, GL_FALSE, 0, aVertices );
+    glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
+    glDisableVertexAttribArray( 0 );
+    glDisableVertexAttribArray( 1 );
+    glBindTexture( GL_TEXTURE_2D, 0 );
+    glUseProgram( 0 );
+}
+
+bool OpenGLSalBitmap::ReadTexture()
+{
+    SalTwoRect aPosAry;
+    GLuint nFramebufferId, nRenderbufferDepthId, nRenderbufferColorId;
+    sal_uInt8* pData = maUserBuffer.get();
+
+    mpContext->makeCurrent();
+    OpenGLHelper::createFramebuffer( mnWidth, mnHeight, nFramebufferId,
+        nRenderbufferDepthId, nRenderbufferColorId, true );
+    glBindFramebuffer( GL_FRAMEBUFFER, nFramebufferId );
+
+    aPosAry.mnSrcX = aPosAry.mnDestX = 0;
+    aPosAry.mnSrcY = aPosAry.mnDestY = 0;
+    aPosAry.mnSrcWidth = aPosAry.mnDestWidth = mnWidth;
+    aPosAry.mnSrcHeight = aPosAry.mnDestHeight = mnHeight;
+
+    DrawTexture( mnTexture, aPosAry );
+    glReadPixels( 0, 0, mnWidth, mnHeight, GL_RGBA, GL_UNSIGNED_BYTE, pData );
+
+    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+    glDeleteFramebuffers( 1, &nFramebufferId );
+    glDeleteRenderbuffers( 1, &nRenderbufferDepthId );
+    glDeleteRenderbuffers( 1, &nRenderbufferColorId );
+
+    return true;
+}
+
+sal_uInt16 OpenGLSalBitmap::GetBitCount() const
+{
+    return mnBits;
+}
+
+BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( bool /*bReadOnly*/ )
+{
+    if( !maUserBuffer.get() )
+    {
+        if( !AllocateUserData() )
+            return NULL;
+        if( mnTexture && !ReadTexture() )
+            return NULL;
+    }
+
+    BitmapBuffer* pBuffer = new BitmapBuffer;
+    pBuffer->mnWidth = mnWidth;
+    pBuffer->mnHeight = mnHeight;
+    pBuffer->maPalette = maPalette;
+    pBuffer->mnScanlineSize = mnBytesPerRow;
+    pBuffer->mpBits = maUserBuffer.get();
+    pBuffer->mnBitCount = mnBits;
+    switch( mnBits )
+    {
+    case 1:     pBuffer->mnFormat = BMP_FORMAT_1BIT_MSB_PAL; break;
+    case 4:     pBuffer->mnFormat = BMP_FORMAT_4BIT_MSN_PAL; break;
+    case 8:     pBuffer->mnFormat = BMP_FORMAT_8BIT_PAL; break;
+    case 16:    pBuffer->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK;
+                pBuffer->maColorMask  = ColorMask( 0xf800, 0x07e0, 0x001f );
+                break;
+    case 24:    pBuffer->mnFormat = BMP_FORMAT_24BIT_TC_BGR; break;
+    case 32:    pBuffer->mnFormat = BMP_FORMAT_32BIT_TC_ARGB;
+                pBuffer->maColorMask  = ColorMask( 0x00ff0000, 0x0000ff00, 0x000000ff );
+                break;
+    }
+    // FIXME pBuffer->mnFormat |= BMP_FORMAT_BOTTOM_UP;
+
+    return pBuffer;
+}
+
+void OpenGLSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly )
+{
+    if( !bReadOnly )
+    {
+        mbDirtyTexture = true;
+    }
+    delete pBuffer;
+}
+
+bool OpenGLSalBitmap::GetSystemData( BitmapSystemData& /*rData*/ )
+{
+#if 0
+    // TODO Implement for ANDROID/OSX/IOS/WIN32
+    X11SalBitmap rBitmap;
+    BitmapBuffer* pBuffer;
+
+    rBitmap.Create( GetSize(), mnBits, maPalette );
+    pBuffer = rBitmap.AcquireBuffer( false );
+    if( pBuffer == NULL )
+        return false;
+
+    if( !maUserBuffer.get() )
+    {
+        if( !AllocateUserData() || !ReadTexture() )
+        {
+            rBitmap.ReleaseBuffer( pBuffer, false );
+            return false;
+        }
+    }
+
+    // TODO Might be more efficient to add a static method to SalBitmap
+    //      to get system data from a buffer
+    memcpy( pBuffer->mpBits, maUserBuffer.get(), mnBytesPerRow * mnHeight );
+
+    rBitmap.ReleaseBuffer( pBuffer, false );
+    return rBitmap.GetSystemData( rData );
+#else
+    return false;
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/salbmp.cxx b/vcl/unx/generic/gdi/salbmp.cxx
index e68078e..8468b4d 100644
--- a/vcl/unx/generic/gdi/salbmp.cxx
+++ b/vcl/unx/generic/gdi/salbmp.cxx
@@ -43,6 +43,8 @@
 #include <unx/salinst.h>
 #include <unx/x11/xlimits.hxx>
 
+#include <opengl/salbmp.hxx>
+
 #if defined HAVE_VALGRIND_HEADERS
 #include <valgrind/memcheck.h>
 #endif
@@ -53,7 +55,11 @@
 
 SalBitmap* X11SalInstance::CreateSalBitmap()
 {
-    return new X11SalBitmap();
+    static const char* pOpenGL = getenv("USE_OPENGL");
+    if (pOpenGL)
+        return new OpenGLSalBitmap();
+    else
+        return new X11SalBitmap();
 }
 
 ImplSalBitmapCache* X11SalBitmap::mpCache = NULL;
commit 74ff268b3bf6cbec53b36c6749ba12f7bfb037df
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Thu Oct 30 21:57:22 2014 -0400

    vcl: Update OpenGL context before drawing
    
    Change-Id: I7575881d8d9a2026a74692ca562a340231d946bd

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index f03911c..9259468 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -452,6 +452,7 @@ void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY )
 {
     if( mnLineColor != SALCOLOR_NONE )
     {
+        maContext.makeCurrent();
         BeginSolid( mnLineColor );
         DrawPoint( nX, nY );
         EndSolid();
@@ -462,6 +463,7 @@ void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor )
 {
     if( nSalColor != SALCOLOR_NONE )
     {
+        maContext.makeCurrent();
         BeginSolid( nSalColor );
         DrawPoint( nX, nY );
         EndSolid();
@@ -472,6 +474,7 @@ void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
 {
     if( mnLineColor != SALCOLOR_NONE )
     {
+        maContext.makeCurrent();
         BeginSolid( mnLineColor );
         DrawLine( nX1, nY1, nX2, nY2 );
         EndSolid();
@@ -480,6 +483,8 @@ void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
 
 void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeight )
 {
+    maContext.makeCurrent();
+
     if( mnFillColor != SALCOLOR_NONE )
     {
         BeginSolid( mnFillColor );
@@ -504,6 +509,8 @@ void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeigh
 
 void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
 {
+    maContext.makeCurrent();
+
     if( mnLineColor != SALCOLOR_NONE && nPoints > 1 )
     {
         BeginSolid( mnLineColor );
@@ -528,6 +535,8 @@ void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPt
         return;
     }
 
+    maContext.makeCurrent();
+
     if( mnFillColor != SALCOLOR_NONE )
     {
         BeginSolid( mnFillColor );
@@ -548,6 +557,8 @@ void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32*
     if( nPoly <= 0 )
         return;
 
+    maContext.makeCurrent();
+
     if( mnFillColor != SALCOLOR_NONE )
     {
         BeginSolid( mnFillColor );
@@ -644,6 +655,7 @@ void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitm
     const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
     GLuint nTexture = rBitmap.GetTexture();
 
+    maContext.makeCurrent();
     DrawTexture( nTexture, rPosAry );
 }
 
@@ -665,6 +677,7 @@ void OpenGLSalGraphicsImpl::drawBitmap(
     const GLuint nTexture( rBitmap.GetTexture() );
     const GLuint nMask( rMask.GetTexture() );
 
+    maContext.makeCurrent();
     DrawTextureWithMask( nTexture, nMask, rPosAry );
 }
 
@@ -701,6 +714,7 @@ SalColor OpenGLSalGraphicsImpl::getPixel( long nX, long nY )
 {
     char pixel[3];
 
+    maContext.makeCurrent();
     glReadPixels( nX, nY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
     return MAKE_SALCOLOR( pixel[0], pixel[1], pixel[2] );
 }
@@ -715,6 +729,8 @@ void OpenGLSalGraphicsImpl::invert(
     //   * SAL_INVERT_50 (50/50 pattern?)
     //   * SAL_INVERT_TRACKFRAME (dash-line rectangle?)
 
+    maContext.makeCurrent();
+
     if( nFlags & SAL_INVERT_TRACKFRAME )
     {
 
@@ -733,6 +749,8 @@ void OpenGLSalGraphicsImpl::invert(
 
 void OpenGLSalGraphicsImpl::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags )
 {
+    maContext.makeCurrent();
+
     if( nFlags & SAL_INVERT_TRACKFRAME )
     {
 
@@ -780,6 +798,7 @@ bool OpenGLSalGraphicsImpl::drawAlphaBitmap(
     const GLuint nTexture( rBitmap.GetTexture() );
     const GLuint nAlpha( rAlpha.GetTexture() );
 
+    maContext.makeCurrent();
     DrawTextureWithMask( nTexture, nAlpha, rPosAry );
     return true;
 }
diff --git a/vcl/opengl/solidFragmentShader.glsl b/vcl/opengl/solidFragmentShader.glsl
index 917cafc..94d0de0 100644
--- a/vcl/opengl/solidFragmentShader.glsl
+++ b/vcl/opengl/solidFragmentShader.glsl
@@ -7,7 +7,7 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-precision mediump float;
+/*precision mediump float;*/
 
 uniform vec4 color;
 void main() {
commit bd17a766150770118f83883dd0292a08ab90c057
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Thu Oct 30 21:54:22 2014 -0400

    vcl: Add methods to get size of OpenGLSalGraphicsImpl
    
    Change-Id: I7eecbc236db12fb9453384985245eb5ca781e0f5

diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index a99e6c3..f392363 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -172,7 +172,7 @@ public:
 
     void setWinPosAndSize(const Point &rPos, const Size& rSize);
     void setWinSize(const Size& rSize);
-    GLWindow& getOpenGLWindow() { return m_aGLWin;}
+    const GLWindow& getOpenGLWindow() const { return m_aGLWin;}
 
     SystemChildWindow* getChildWindow();
     const SystemChildWindow* getChildWindow() const;
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index e02911b..7189905 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -50,6 +50,9 @@ private:
     GLuint mnMaskUniform;
     GLuint mnMaskColorUniform;
 
+    inline GLfloat GetWidth() const;
+    inline GLfloat GetHeight() const;
+
     bool CreateSolidProgram( void );
     bool CreateTextureProgram( void );
     bool CreateMaskedTextureProgram( void );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 6fa8153..f03911c 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -75,7 +75,17 @@ sal_uInt16 OpenGLSalGraphicsImpl::GetBitCount() const
 // get the width of the device
 long OpenGLSalGraphicsImpl::GetGraphicsWidth() const
 {
-    return 0;
+    return maContext.getOpenGLWindow().Width;
+}
+
+inline GLfloat OpenGLSalGraphicsImpl::GetWidth() const
+{
+    return maContext.getOpenGLWindow().Width;
+}
+
+inline GLfloat OpenGLSalGraphicsImpl::GetHeight() const
+{
+    return maContext.getOpenGLWindow().Height;
 }
 
 // set the clip region to empty
@@ -276,8 +286,8 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin
 
     for( i = 0, j = 0; i < nPoints; i++, j += 2 )
     {
-        pVertices[j] = pPtAry[i].mnX;
-        pVertices[j+1] = pPtAry[i].mnY;
+        pVertices[j] = (2 * pPtAry[i].mnX) / GetWidth() - 1.0;
+        pVertices[j+1] = (2 * pPtAry[i].mnY) / GetHeight() - 1.0;
     }
 
     glEnableVertexAttribArray( GL_ATTRIB_POS );
commit ea694d266d65a472eb7e2d64a354c14522315205
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Thu Oct 30 21:51:39 2014 -0400

    vcl: Some fixes to the OpenGL impl
    
    Change-Id: I58466142e0a47beb892e10113c1bc34d5ac3abcd

diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 40d3f9d..e02911b 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -65,7 +65,7 @@ private:
     void DrawLine( long nX1, long nY1, long nX2, long nY2 );
     void DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
     void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
-    void DrawRect( long nX, long nY, long nWidth, nHeight );
+    void DrawRect( long nX, long nY, long nWidth, long nHeight );
     void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
     void DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPolyPolygon );
     void DrawTextureRect( const SalTwoRect& pPosAry );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 02bba63..6fa8153 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -85,7 +85,6 @@ void OpenGLSalGraphicsImpl::ResetClipRegion()
 }
 
 // set the line color to transparent (= don't draw lines)
-
 void OpenGLSalGraphicsImpl::SetLineColor()
 {
     if( mnLineColor != SALCOLOR_NONE )
@@ -150,9 +149,7 @@ bool OpenGLSalGraphicsImpl::CreateSolidProgram( void )
 
 bool OpenGLSalGraphicsImpl::CreateTextureProgram( void )
 {
-    static const char aFragShaderSrc[] =
-
-    mnTextureProgram = OpenGLHelper::( "textureVertexShader", "textureFragmentShader" );
+    mnTextureProgram = OpenGLHelper::LoadShaders( "textureVertexShader", "textureFragmentShader" );
     if( mnTextureProgram == 0 )
         return false;
 
@@ -357,7 +354,7 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPol
     }
 
     glEnableVertexAttribArray( GL_ATTRIB_POS );
-    glVertexAttribPointer( GL_ATTRIB_POS, pVertices.size(), GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices.size() );
+    glVertexAttribPointer( GL_ATTRIB_POS, pVertices.size(), GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices.data() );
     glDrawArrays( GL_TRIANGLES, 0, pVertices.size() / 2 );
     glDisableVertexAttribArray( GL_ATTRIB_POS );
 }
@@ -610,7 +607,7 @@ void OpenGLSalGraphicsImpl::copyArea(
 
 // CopyBits and DrawBitmap --> RasterOp and ClipRegion
 // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
-void OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
+void OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* /*pSrcGraphics*/ )
 {
     // TODO Check if SalGraphicsImpl is the same
     const bool bSameGraphics( false );
@@ -719,7 +716,7 @@ void OpenGLSalGraphicsImpl::invert(
     else // just invert
     {
         BeginInvert();
-        DrawPolygon( 4, aPoints );
+        DrawRect( nX, nY, nWidth, nHeight );
         EndInvert();
     }
 }


More information about the Libreoffice-commits mailing list