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

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Wed Nov 12 10:17:15 PST 2014


 vcl/inc/opengl/contextprovider.hxx |   28 ++++++++++++++++
 vcl/inc/opengl/salbmp.hxx          |    2 -
 vcl/inc/unx/salgdi.h               |    7 +++-
 vcl/opengl/salbmp.cxx              |   63 +++++++++++++++++++++++++++----------
 vcl/opengl/scale.cxx               |   15 ++++++--
 vcl/opengl/x11/gdiimpl.cxx         |    6 +--
 vcl/unx/generic/gdi/salgdi.cxx     |    9 +++++
 7 files changed, 105 insertions(+), 25 deletions(-)

New commits:
commit f8abb13216f451693488f93843f0714a67f9ca66
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Wed Nov 12 13:16:29 2014 -0500

    vcl: Add support for GPU scaling when no rendering is involved
    
    Change-Id: Id5aa4c1e843d286026a7bcd1297670db467dcbbc

diff --git a/vcl/inc/opengl/contextprovider.hxx b/vcl/inc/opengl/contextprovider.hxx
new file mode 100644
index 0000000..47eb98c
--- /dev/null
+++ b/vcl/inc/opengl/contextprovider.hxx
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_CONTEXTPROVIDER_HXX
+#define INCLUDED_VCL_INC_OPENGL_CONTEXTPROVIDER_HXX
+
+#include "vclpluginapi.h"
+
+#include <vcl/opengl/OpenGLContext.hxx>
+
+class VCLPLUG_GEN_PUBLIC OpenGLContextProvider
+{
+public:
+    virtual ~OpenGLContextProvider() {};
+
+    /* Get the OpenGL context provided by this instance */
+    virtual OpenGLContext* GetOpenGLContext() const = 0;
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_CONTEXTPROVIDER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index 743fc5d..6fc4f72 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -32,6 +32,8 @@
 #include "sallayout.hxx"
 #include "vclpluginapi.h"
 
+#include "opengl/contextprovider.hxx"
+
 #include <boost/scoped_ptr.hpp>
 
 #include <deque>
@@ -60,7 +62,7 @@ namespace basegfx {
     class B2DTrapezoid;
 }
 
-class VCLPLUG_GEN_PUBLIC X11SalGraphics : public SalGraphics
+class VCLPLUG_GEN_PUBLIC X11SalGraphics : public SalGraphics, public OpenGLContextProvider
 {
     friend class ServerFontLayout;
     friend class X11SalGraphicsImpl;
@@ -298,6 +300,9 @@ public:
                                 unsigned int w, unsigned int h,
                                 int dest_x, int dest_y );
     static void releaseGlyphPeer();
+
+public:
+    virtual OpenGLContext* GetOpenGLContext() const SAL_OVERRIDE;
 };
 
 inline const SalDisplay *X11SalGraphics::GetDisplay() const
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
index ad794b1..1401fb8 100644
--- a/vcl/opengl/salbmp.cxx
+++ b/vcl/opengl/salbmp.cxx
@@ -22,9 +22,12 @@
 #include <vcl/opengl/OpenGLHelper.hxx>
 
 #include "vcl/bitmap.hxx"
+#include "vcl/outdev.hxx"
 #include "vcl/salbtype.hxx"
+#include "svdata.hxx"
 #include "salgdi.hxx"
 
+#include "opengl/contextprovider.hxx"
 #include "opengl/salbmp.hxx"
 
 static bool isValidBitCount( sal_uInt16 nBitCount )
@@ -420,31 +423,43 @@ GLuint OpenGLSalBitmap::CreateTexture()
 
 bool OpenGLSalBitmap::ReadTexture()
 {
-    SalTwoRect aPosAry;
-    GLuint nFramebufferId, nRenderbufferDepthId, nRenderbufferColorId;
+    GLuint nFramebufferId;
     sal_uInt8* pData = maUserBuffer.get();
+    GLenum nFormat, nType;
 
-    SAL_INFO( "vcl.opengl", "::ReadTexture" );
+    SAL_INFO( "vcl.opengl", "::ReadTexture " << mnWidth << "x" << mnHeight );
 
-    // TODO Check mnTexWidth and mnTexHeight
+    if( pData == NULL )
+        return false;
+
+    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;
+        }
+    }
 
     mpContext->makeCurrent();
-    OpenGLHelper::createFramebuffer( mnWidth, mnHeight, nFramebufferId,
-        nRenderbufferDepthId, nRenderbufferColorId, true );
+    glGenFramebuffers( 1, &nFramebufferId );
     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 );
+    glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mpTexture->Id(), 0 );
+    glReadPixels( 0, 0, mnWidth, mnHeight, nFormat, nType, pData );
 
     glBindFramebuffer( GL_FRAMEBUFFER, 0 );
     glDeleteFramebuffers( 1, &nFramebufferId );
-    glDeleteRenderbuffers( 1, &nRenderbufferDepthId );
-    glDeleteRenderbuffers( 1, &nRenderbufferColorId );
 
     CHECK_GL_ERROR();
     return true;
@@ -465,6 +480,22 @@ BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( bool /*bReadOnly*/ )
             return NULL;
     }
 
+    if( !maPendingOps.empty() )
+    {
+        OpenGLContextProvider *pProvider;
+        pProvider = dynamic_cast< OpenGLContextProvider* >( ImplGetDefaultWindow()->GetGraphics() );
+        if( pProvider == NULL )
+        {
+            SAL_WARN( "vcl.opengl", "Couldn't get default OpenGL context provider" );
+            return NULL;
+        }
+        mpContext = pProvider->GetOpenGLContext();
+        mpContext->makeCurrent();
+        SAL_INFO( "vcl.opengl", "** Creating texture and reading it back immediatly" );
+        if( !CreateTexture() || !AllocateUserData() || !ReadTexture() )
+            return NULL;
+    }
+
     BitmapBuffer* pBuffer = new BitmapBuffer;
     pBuffer->mnWidth = mnWidth;
     pBuffer->mnHeight = mnHeight;
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 62e8989..2723db4 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -167,6 +167,15 @@ void X11SalGraphics::DeInit()
     SetDrawable( None, m_nXScreen );
 }
 
+OpenGLContext* X11SalGraphics::GetOpenGLContext() const
+{
+    OpenGLSalGraphicsImpl *pImpl;
+    pImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(mpImpl.get());
+    if( pImpl )
+        return &pImpl->GetOpenGLContext();
+    return NULL;
+}
+
 void X11SalGraphics::SetClipRegion( GC pGC, Region pXReg ) const
 {
     Display *pDisplay = GetXDisplay();
commit cd1abbcc1033a41a2d290155ef3bfb7eea4b3103
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Wed Nov 12 12:53:09 2014 -0500

    vcl: Use new size when scaling with filter in OpenGL backend
    
    Change-Id: Ib5d12b0e57b537bbd1798121e80cd517d9c8f751

diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx
index 77ac90b..c1f0cdb 100644
--- a/vcl/inc/opengl/salbmp.hxx
+++ b/vcl/inc/opengl/salbmp.hxx
@@ -106,7 +106,7 @@ private:
     GLuint          mnConvKernelSizeUniform;
     GLuint          mnConvOffsetsUniform;
 
-    bool ImplScaleFilter( GLenum nFilter );
+    bool ImplScaleFilter( const double& rScaleX, const double& rScaleY, GLenum nFilter );
     void ImplCreateKernel( const double& fScale, const Kernel& rKernel, GLfloat*& pWeights, sal_uInt32& aKernelSize );
     bool ImplScaleConvolution( const double& rScaleX, const double& rScaleY, const Kernel& aKernel );
 
diff --git a/vcl/opengl/scale.cxx b/vcl/opengl/scale.cxx
index da73786..d1b85a5 100644
--- a/vcl/opengl/scale.cxx
+++ b/vcl/opengl/scale.cxx
@@ -81,12 +81,17 @@ GLuint OpenGLSalBitmap::ImplGetConvolutionProgram()
     return mnConvProgram;
 }
 
-bool OpenGLSalBitmap::ImplScaleFilter( GLenum nFilter )
+bool OpenGLSalBitmap::ImplScaleFilter(
+    const double& rScaleX,
+    const double& rScaleY,
+    GLenum        nFilter )
 {
     OpenGLTexture* pNewTex;
     GLuint nProgram;
     GLuint nFramebufferId;
     GLenum nOldFilter;
+    int nNewWidth( mnWidth * rScaleX );
+    int nNewHeight( mnHeight * rScaleY );
 
     nProgram = ImplGetTextureProgram();
     if( nProgram == 0 )
@@ -97,7 +102,7 @@ bool OpenGLSalBitmap::ImplScaleFilter( GLenum nFilter )
     glUseProgram( nProgram );
     glUniform1i( mnTexSamplerUniform, 0 );
 
-    pNewTex = new OpenGLTexture( mnWidth, mnHeight );
+    pNewTex = new OpenGLTexture( nNewWidth, nNewHeight );
     glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pNewTex->Id(), 0 );
 
     mpTexture->Bind();
@@ -111,6 +116,8 @@ bool OpenGLSalBitmap::ImplScaleFilter( GLenum nFilter )
     glBindFramebuffer( GL_FRAMEBUFFER, 0 );
     glDeleteFramebuffers( 1, &nFramebufferId );
 
+    mnWidth = nNewWidth;
+    mnHeight = nNewHeight;
     mpTexture.reset( pNewTex );
 
     CHECK_GL_ERROR();
@@ -241,11 +248,11 @@ bool OpenGLSalBitmap::ImplScale( const double& rScaleX, const double& rScaleY, s
 
     if( nScaleFlag == BMP_SCALE_FAST )
     {
-        return ImplScaleFilter( GL_NEAREST );
+        return ImplScaleFilter( rScaleX, rScaleY, GL_NEAREST );
     }
     if( nScaleFlag == BMP_SCALE_BILINEAR )
     {
-        return ImplScaleFilter( GL_LINEAR );
+        return ImplScaleFilter( rScaleX, rScaleY, GL_LINEAR );
     }
     else if( nScaleFlag == BMP_SCALE_SUPER )
     {
commit 4fe34e9cd0a88fd7fa46185df421d03d9b693f16
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date:   Wed Nov 12 12:51:03 2014 -0500

    vcl: Fix memory free bugs
    
    Change-Id: Ic8c507014f0b02c7a0baa40f3f48070301604ca4

diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
index 18d713d..ad794b1 100644
--- a/vcl/opengl/salbmp.cxx
+++ b/vcl/opengl/salbmp.cxx
@@ -403,7 +403,7 @@ GLuint OpenGLSalBitmap::CreateTexture()
     SAL_INFO( "vcl.opengl", "Created texture " << mpTexture->Id() );
 
     if( bAllocated )
-        delete pData;
+        delete[] pData;
 
     while( !maPendingOps.empty() )
     {
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index 13b7049..184abab 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -86,7 +86,7 @@ X11Pixmap* X11OpenGLSalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect
     XVisualInfo aVisualInfo;
     X11Pixmap* pPixmap;
     XImage* pImage;
-    sal_uInt8* pData;
+    char* pData;
 
     SAL_INFO( "vcl.opengl", "GetPixmapFromScreen" );
     // TODO: lfrb: Use context depth
@@ -100,12 +100,12 @@ X11Pixmap* X11OpenGLSalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect
     glXWaitX();
 
     // TODO: lfrb: What if offscreen?
-    pData = new sal_uInt8[rRect.GetWidth() * rRect.GetHeight() * 4];
+    pData = (char*) malloc( rRect.GetWidth() * rRect.GetHeight() * 4 );
     glPixelStorei( GL_PACK_ALIGNMENT, 1 );
     glReadPixels( rRect.Left(), GetHeight() - rRect.Top(), rRect.GetWidth(), rRect.GetHeight(),
                   GL_RGBA, GL_UNSIGNED_BYTE, pData );
 
-    pImage = XCreateImage( pDisplay, aVisualInfo.visual, 24, ZPixmap, 0, (char*) pData,
+    pImage = XCreateImage( pDisplay, aVisualInfo.visual, 24, ZPixmap, 0, pData,
                            rRect.GetWidth(), rRect.GetHeight(), 8, 0 );
     XInitImage( pImage );
     GC aGC = XCreateGC( pDisplay, pPixmap->GetPixmap(), 0, NULL );


More information about the Libreoffice-commits mailing list