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 <l...@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 <l...@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 <l...@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 );
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits