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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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(); } }
_______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
