include/vcl/opengl/OpenGLContext.hxx | 2 vcl/Library_vcl.mk | 1 vcl/Module_vcl.mk | 1 vcl/Package_opengl.mk | 23 vcl/inc/opengl/salbmp.hxx | 90 +++ vcl/inc/openglgdiimpl.hxx | 51 ++ vcl/inc/salgdiimpl.hxx | 3 vcl/opengl/gdiimpl.cxx | 646 ++++++++++++++++++++++++++-- vcl/opengl/maskFragmentShader.glsl | 21 vcl/opengl/maskVertexShader.glsl | 19 vcl/opengl/maskedTextureFragmentShader.glsl | 22 vcl/opengl/maskedTextureVertexShader.glsl | 19 vcl/opengl/salbmp.cxx | 521 ++++++++++++++++++++++ vcl/opengl/solidFragmentShader.glsl | 17 vcl/opengl/solidVertexShader.glsl | 16 vcl/opengl/textureFragmentShader.glsl | 18 vcl/opengl/textureVertexShader.glsl | 19 vcl/source/opengl/OpenGLContext.cxx | 9 vcl/unx/generic/gdi/gdiimpl.cxx | 6 vcl/unx/generic/gdi/gdiimpl.hxx | 2 vcl/unx/generic/gdi/salbmp.cxx | 8 vcl/unx/generic/gdi/salgdi.cxx | 21 22 files changed, 1479 insertions(+), 56 deletions(-)
New commits: commit 1931334a0f4ae604467c649eb7d0bcd5d4d85614 Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Tue Nov 4 04:55:44 2014 +0100 fix signed/unsigned comparison warning Change-Id: I0d1ce56514ff9dfff620f11cf987d6d53c4be5e4 diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx index 84ada34..5edeed8 100644 --- a/vcl/opengl/salbmp.cxx +++ b/vcl/opengl/salbmp.cxx @@ -190,7 +190,7 @@ bool OpenGLSalBitmap::AllocateUserData() #ifdef DBG_UTIL else { - for (size_t i = 0; i < mnBytesPerRow * mnHeight; i++) + for (size_t i = 0; i < size_t(mnBytesPerRow * mnHeight); i++) maUserBuffer.get()[i] = (i & 0xFF); } #endif commit a2c4dc3d0e4adf85ba1dcbfab68c318b6d637ead Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Mon Nov 3 11:10:14 2014 -0500 vcl: Fix the vertices calculations for some drawing operations Change-Id: Ida92d77d7f828f5ff53e7cceaf4787beeef0022b diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 65cff6a..d79bce0 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -257,33 +257,32 @@ void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY ) void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 ) { - GLushort pPoints[4]; + GLfloat pPoints[4]; - pPoints[0] = nX1; - pPoints[1] = nY1; - pPoints[2] = nX2; - pPoints[3] = nY2; + pPoints[0] = (2 * nX1) / GetWidth() - 1.0; + pPoints[1] = (2 * nY1) / GetHeight() - 1.0; + pPoints[2] = (2 * nX2) / GetWidth() - 1.0;; + pPoints[3] = (2 * nY2) / GetHeight() - 1.0; glEnableVertexAttribArray( GL_ATTRIB_POS ); - glVertexAttribPointer( GL_ATTRIB_POS, 4, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoints ); + glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, pPoints ); glDrawArrays( GL_LINES, 0, 2 ); glDisableVertexAttribArray( GL_ATTRIB_POS ); } void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose ) { - GLushort *pPoints; + GLfloat pPoints[nPoints * 2]; sal_uInt32 i, j; - pPoints = new GLushort[nPoints * 2]; - for( i = 0, j = 0; i < nPoints; i++, j += 2 ) + for( i = 0, j = 0; i < nPoints; i++ ) { - pPoints[j] = pPtAry[i].mnX; - pPoints[j+1] = pPtAry[i].mnY; + pPoints[j++] = (2 * pPtAry[i].mnX) / GetWidth() - 1.0; + pPoints[j++] = (2 * pPtAry[i].mnY) / GetHeight() - 1.0; } glEnableVertexAttribArray( GL_ATTRIB_POS ); - glVertexAttribPointer( GL_ATTRIB_POS, nPoints * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoints ); + glVertexAttribPointer( GL_ATTRIB_POS, nPoints * 2, GL_FLOAT, GL_FALSE, 0, pPoints ); if( bClose ) glDrawArrays( GL_LINE_LOOP, 0, nPoints ); else @@ -293,7 +292,7 @@ void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAr void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) { - GLushort pVertices[nPoints * 2]; + GLfloat pVertices[nPoints * 2]; sal_uInt32 i, j; for( i = 0, j = 0; i < nPoints; i++, j += 2 ) @@ -303,7 +302,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin } glEnableVertexAttribArray( GL_ATTRIB_POS ); - glVertexAttribPointer( GL_ATTRIB_POS, nPoints * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices ); + glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, pVertices ); glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints ); glDisableVertexAttribArray( GL_ATTRIB_POS ); } @@ -312,8 +311,8 @@ void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeigh { long nX1( nX ); long nY1( nY ); - long nX2( nX + nWidth - 1 ); - long nY2( nY + nHeight - 1 ); + long nX2( nX + nWidth ); + long nY2( nY + nHeight ); const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 }, { nX2, nY1 }, { nX2, nY2 }}; @@ -350,7 +349,7 @@ void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPt } glEnableVertexAttribArray( GL_ATTRIB_POS ); - glVertexAttribPointer( GL_ATTRIB_POS, aResult.count() * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices ); + glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices ); glDrawArrays( GL_TRIANGLES, 0, aResult.count() ); glDisableVertexAttribArray( GL_ATTRIB_POS ); } @@ -367,16 +366,16 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPol const ::basegfx::B2DPolygon& aResult( ::basegfx::triangulator::triangulate( pPolygon ) ); - for( j = 0; i < aResult.count(); j++ ) + for( j = 0; j < aResult.count(); j++ ) { - const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint(i) ); + const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint( j ) ); pVertices.push_back( rPt.getX() ); pVertices.push_back( rPt.getY() ); } } glEnableVertexAttribArray( GL_ATTRIB_POS ); - glVertexAttribPointer( GL_ATTRIB_POS, pVertices.size(), GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices.data() ); + glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices.data() ); glDrawArrays( GL_TRIANGLES, 0, pVertices.size() / 2 ); glDisableVertexAttribArray( GL_ATTRIB_POS ); } @@ -386,7 +385,7 @@ void OpenGLSalGraphicsImpl::DrawTextureRect( const SalTwoRect& pPosAry ) GLushort aTexCoord[8]; glEnableVertexAttribArray( GL_ATTRIB_TEX ); - glVertexAttribPointer( GL_ATTRIB_TEX, 8, GL_UNSIGNED_SHORT, GL_FALSE, 0, aTexCoord ); + glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, aTexCoord ); DrawRect( pPosAry.mnDestX, pPosAry.mnDestY, pPosAry.mnDestWidth, pPosAry.mnDestHeight ); commit 1b057679da586254d3ec8960ea70ee3e101669e9 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Mon Nov 3 11:08:24 2014 -0500 vcl: Get the OpenGL window size from the frame Change-Id: Id1b62d1982e56ef073ebb4ab800356d4dee3d742 diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index cad2c4d..6643546 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -25,11 +25,14 @@ #include <vcl/opengl/OpenGLContext.hxx> +class SalFrame; + class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl { private: OpenGLContext maContext; + SalFrame* mpFrame; SalColor mnLineColor; SalColor mnFillColor; @@ -84,6 +87,8 @@ public: virtual void freeResources() SAL_OVERRIDE; + virtual void Init( SalFrame* pFrame ) SAL_OVERRIDE; + virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE; // // get the depth of the device diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx index ed4f4ba..9802a7b 100644 --- a/vcl/inc/salgdiimpl.hxx +++ b/vcl/inc/salgdiimpl.hxx @@ -34,6 +34,7 @@ class SalGraphics; class SalBitmap; +class SalFrame; class Gradient; class VCL_PLUGIN_PUBLIC SalGraphicsImpl @@ -42,6 +43,8 @@ public: virtual ~SalGraphicsImpl(); + virtual void Init( SalFrame* pFrame ) = 0; + virtual void freeResources() = 0; virtual bool setClipRegion( const vcl::Region& ) = 0; diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 528b1d5..65cff6a 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -20,6 +20,7 @@ #include "openglgdiimpl.hxx" #include <vcl/gradient.hxx> +#include <salframe.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/polygon/b2dpolygontriangulator.hxx> @@ -45,6 +46,11 @@ void OpenGLSalGraphicsImpl::freeResources() // Delete shaders, programs and textures if not shared } +void OpenGLSalGraphicsImpl::Init( SalFrame* pFrame ) +{ + mpFrame = pFrame; +} + bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip ) { const basegfx::B2DPolyPolygon aClip( rClip.GetAsB2DPolyPolygon() ); @@ -77,17 +83,21 @@ sal_uInt16 OpenGLSalGraphicsImpl::GetBitCount() const // get the width of the device long OpenGLSalGraphicsImpl::GetGraphicsWidth() const { - return maContext.getOpenGLWindow().Width; + return GetWidth(); } inline GLfloat OpenGLSalGraphicsImpl::GetWidth() const { - return maContext.getOpenGLWindow().Width; + if( mpFrame ) + return mpFrame->maGeometry.nWidth; + return 0; } inline GLfloat OpenGLSalGraphicsImpl::GetHeight() const { - return maContext.getOpenGLWindow().Height; + if( mpFrame ) + return mpFrame->maGeometry.nHeight; + return 0; } // set the clip region to empty diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index 508bf0b..f1686e3 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -540,10 +540,10 @@ bool OpenGLContext::init(HDC hDC, HWND hWnd) bool OpenGLContext::ImplInit() { SAL_INFO("vcl.opengl", "OpenGLContext::ImplInit----start"); - if(m_pWindow) + /*if(m_pWindow) m_pWindow->setPosSizePixel(0,0,0,0); m_aGLWin.Width = 0; - m_aGLWin.Height = 0; + m_aGLWin.Height = 0;*/ #if defined( WNT ) #elif defined( MACOSX ) @@ -683,6 +683,11 @@ bool OpenGLContext::ImplInit() m_aGLWin.GLExtensions = glGetString( GL_EXTENSIONS ); SAL_INFO("vcl.opengl", "available GL extensions: " << m_aGLWin.GLExtensions); + XWindowAttributes xWinAttr; + XGetWindowAttributes( m_aGLWin.dpy, m_aGLWin.win, &xWinAttr ); + m_aGLWin.Width = xWinAttr.width; + m_aGLWin.Height = xWinAttr.height; + if( m_aGLWin.HasGLXExtension("GLX_SGI_swap_control" ) ) { // enable vsync diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx index 60ed793..6b90220 100644 --- a/vcl/unx/generic/gdi/gdiimpl.cxx +++ b/vcl/unx/generic/gdi/gdiimpl.cxx @@ -153,6 +153,12 @@ X11SalGraphicsImpl::~X11SalGraphicsImpl() { } +void X11SalGraphicsImpl::Init( SalFrame* /*pFrame*/ ) +{ + mnPenPixel = mrParent.GetPixel( mnPenColor ); + mnBrushPixel = mrParent.GetPixel( mnBrushColor ); +} + XID X11SalGraphicsImpl::GetXRenderPicture() { XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx index a6e12ec..e81d16e 100644 --- a/vcl/unx/generic/gdi/gdiimpl.hxx +++ b/vcl/unx/generic/gdi/gdiimpl.hxx @@ -108,6 +108,8 @@ public: virtual ~X11SalGraphicsImpl(); + virtual void Init( SalFrame* pFrame ) SAL_OVERRIDE; + virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE; // // get the depth of the device diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx index c5dd0be..97e060e 100644 --- a/vcl/unx/generic/gdi/salgdi.cxx +++ b/vcl/unx/generic/gdi/salgdi.cxx @@ -148,22 +148,15 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen ) if( hDrawable_ ) { - X11SalGraphicsImpl* pImpl = dynamic_cast<X11SalGraphicsImpl*>(mpImpl.get()); - if (pImpl) + OpenGLSalGraphicsImpl* pOpenGLImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(mpImpl.get()); + if (pOpenGLImpl && m_pFrame && dynamic_cast<X11WindowProvider*>(m_pFrame)) { - pImpl->mnPenPixel = GetPixel( pImpl->mnPenColor ); - pImpl->mnBrushPixel = GetPixel( pImpl->mnBrushColor ); - } - else - { - OpenGLSalGraphicsImpl* pOpenGLImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(mpImpl.get()); - if (pOpenGLImpl && m_pFrame && dynamic_cast<X11WindowProvider*>(m_pFrame)) - { - Window aWin = dynamic_cast<X11WindowProvider*>(m_pFrame)->GetX11Window(); - pOpenGLImpl->GetOpenGLContext().init(GetXDisplay(), - aWin, m_nXScreen.getXScreen()); - } + Window aWin = dynamic_cast<X11WindowProvider*>(m_pFrame)->GetX11Window(); + pOpenGLImpl->GetOpenGLContext().init(GetXDisplay(), + aWin, m_nXScreen.getXScreen()); } + + mpImpl->Init( m_pFrame ); nTextPixel_ = GetPixel( nTextColor_ ); } } commit f5997bb5089a26fddb5556d487a75a31d39e0010 Author: Louis-Francis Ratté-Boulianne <l...@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 4c5b3d836b5fb71cc492a66643e6ac3151c2bf3c Author: Louis-Francis Ratté-Boulianne <l...@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 8bb31b0..528b1d5 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -24,6 +24,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 @@ -654,8 +655,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 ); } @@ -675,9 +677,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 ); } @@ -688,22 +691,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; @@ -796,8 +793,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 8c5df61d2086dfd9ff321f88b293de568cc2ea2d Author: Louis-Francis Ratté-Boulianne <l...@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 9ada69a..8bb31b0 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -453,6 +453,7 @@ void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY ) { if( mnLineColor != SALCOLOR_NONE ) { + maContext.makeCurrent(); BeginSolid( mnLineColor ); DrawPoint( nX, nY ); EndSolid(); @@ -463,6 +464,7 @@ void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor ) { if( nSalColor != SALCOLOR_NONE ) { + maContext.makeCurrent(); BeginSolid( nSalColor ); DrawPoint( nX, nY ); EndSolid(); @@ -473,6 +475,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(); @@ -481,6 +484,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 ); @@ -505,6 +510,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 ); @@ -529,6 +536,8 @@ void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPt return; } + maContext.makeCurrent(); + if( mnFillColor != SALCOLOR_NONE ) { BeginSolid( mnFillColor ); @@ -549,6 +558,8 @@ void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* if( nPoly <= 0 ) return; + maContext.makeCurrent(); + if( mnFillColor != SALCOLOR_NONE ) { BeginSolid( mnFillColor ); @@ -645,6 +656,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 ); } @@ -666,6 +678,7 @@ void OpenGLSalGraphicsImpl::drawBitmap( const GLuint nTexture( rBitmap.GetTexture() ); const GLuint nMask( rMask.GetTexture() ); + maContext.makeCurrent(); DrawTextureWithMask( nTexture, nMask, rPosAry ); } @@ -702,6 +715,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] ); } @@ -716,6 +730,8 @@ void OpenGLSalGraphicsImpl::invert( // * SAL_INVERT_50 (50/50 pattern?) // * SAL_INVERT_TRACKFRAME (dash-line rectangle?) + maContext.makeCurrent(); + if( nFlags & SAL_INVERT_TRACKFRAME ) { @@ -734,6 +750,8 @@ void OpenGLSalGraphicsImpl::invert( void OpenGLSalGraphicsImpl::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags ) { + maContext.makeCurrent(); + if( nFlags & SAL_INVERT_TRACKFRAME ) { @@ -781,6 +799,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 130b43d5c86fcf05d6feb09c54a1e0b275a4edbf Author: Louis-Francis Ratté-Boulianne <l...@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 a8344d6..8e4c257 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -177,7 +177,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 6338ebe..cad2c4d 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 d9e4865..9ada69a 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -76,7 +76,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 @@ -277,8 +287,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 b92cca3a44c26b9d8a514860dc3d71d65f730e81 Author: Louis-Francis Ratté-Boulianne <l...@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 d6f35fd..6338ebe 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 ef49d03..d9e4865 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -86,7 +86,6 @@ void OpenGLSalGraphicsImpl::ResetClipRegion() } // set the line color to transparent (= don't draw lines) - void OpenGLSalGraphicsImpl::SetLineColor() { if( mnLineColor != SALCOLOR_NONE ) @@ -151,9 +150,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; @@ -358,7 +355,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 ); } @@ -611,7 +608,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 ); @@ -720,7 +717,7 @@ void OpenGLSalGraphicsImpl::invert( else // just invert { BeginInvert(); - DrawPolygon( 4, aPoints ); + DrawRect( nX, nY, nWidth, nHeight ); EndInvert(); } } commit e4986c3348b9f3f2bcf60a35cd8f0895d8c5bbdc Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Wed Oct 29 22:30:55 2014 +0100 extract shaders from source code Conflicts: vcl/opengl/gdiimpl.cxx Change-Id: Ifbb55e58e0854cc491703b8ca8d8e582741a9bd9 diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk index 693c625..f61cc7b 100644 --- a/vcl/Module_vcl.mk +++ b/vcl/Module_vcl.mk @@ -22,6 +22,7 @@ $(eval $(call gb_Module_Module,vcl)) $(eval $(call gb_Module_add_targets,vcl,\ CustomTarget_afm_hash \ Library_vcl \ + Package_opengl \ $(if $(filter DESKTOP,$(BUILD_TYPE)), \ StaticLibrary_vclmain \ Executable_ui-previewer \ diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk new file mode 100644 index 0000000..9b8f745 --- /dev/null +++ b/vcl/Package_opengl.mk @@ -0,0 +1,23 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +$(eval $(call gb_Package_Package,vcl_opengl_shader,$(SRCDIR)/vcl/opengl)) + +$(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\ + maskFragmentShader.glsl \ + maskVertexShader.glsl \ + maskedTextureFragmentShader.glsl \ + maskedTextureVertexShader.glsl \ + solidFragmentShader.glsl \ + solidVertexShader.glsl \ + textureFragmentShader.glsl \ + textureVertexShader.glsl \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index d3ee9ef..d6f35fd 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -50,8 +50,6 @@ private: GLuint mnMaskUniform; GLuint mnMaskColorUniform; - GLuint CompileShader( GLenum nType, const char *aSrc ); - GLuint CreateProgram( const char *aVertShaderSrc, const char *aFragShaderSrc ); bool CreateSolidProgram( void ); bool CreateTextureProgram( void ); bool CreateMaskedTextureProgram( void ); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index f59584a..ef49d03 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -23,6 +23,8 @@ #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/polygon/b2dpolygontriangulator.hxx> +#include <vcl/opengl/OpenGLHelper.hxx> + #define GL_ATTRIB_POS 0 #define GL_ATTRIB_TEX 1 @@ -136,99 +138,9 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ ) { } -GLuint OpenGLSalGraphicsImpl::CompileShader( GLenum nType, const char *aSrc ) -{ - GLint nStatus; - GLuint nShader; - GLint nLogLen( 0 ); - char *aLog( NULL ); - - nShader = glCreateShader( nType ); - glShaderSource( nShader, 1, (const GLchar **) &aSrc, NULL ); - glCompileShader( nShader ); - glGetShaderiv( nShader, GL_COMPILE_STATUS, &nStatus ); - if( nStatus ) - return nShader; - - glGetShaderiv( nShader, GL_INFO_LOG_LENGTH, &nLogLen ); - if( nLogLen > 1 ) - aLog = new char[nLogLen]; - if( aLog ) - glGetShaderInfoLog( nShader, nLogLen, NULL, aLog ); - - SAL_WARN( "vcl.opengl", "::CompileShader failed: " << aLog ); - - delete aLog; - glDeleteShader( nShader ); - - return 0; -} - -GLuint OpenGLSalGraphicsImpl::CreateProgram( const char *aVertShaderSrc, const char *aFragShaderSrc ) -{ - GLuint nProgram; - GLuint nVertShader, nFragShader; - GLint nStatus; - - nVertShader = CompileShader( GL_VERTEX_SHADER, aVertShaderSrc ); - nFragShader = CompileShader( GL_FRAGMENT_SHADER, aFragShaderSrc ); - if( !nVertShader || !nFragShader ) - { - SAL_WARN( "vcl.opengl", "::CreateProgram couldn't compile the shaders" ); - return 0; - } - - nProgram = glCreateProgram(); - if( nProgram == 0 ) - { - SAL_WARN( "vcl.opengl", "::CreateProgram couldn't create GL program" ); - return 0; - } - - glAttachShader( nProgram, nVertShader ); - glAttachShader( nProgram, nFragShader ); - glLinkProgram( nProgram ); - glGetProgramiv( nProgram, GL_LINK_STATUS, &nStatus ); - if( !nStatus ) - { - GLint nLogLen( 0 ); - char *aLog( NULL ); - - glDeleteShader( nVertShader ); - glDeleteShader( nFragShader ); - - glGetProgramiv( nProgram, GL_INFO_LOG_LENGTH, &nLogLen ); - if( nLogLen > 0 ) - aLog = new char[nLogLen]; - if( aLog ) - glGetProgramInfoLog( nProgram, nLogLen, NULL, aLog ); - - SAL_WARN( "vcl.opengl", "::CreateSolidShader couldn't link program: " << aLog ); - delete aLog; - - return 0; - } - - maShaders.push_back( nVertShader ); - maShaders.push_back( nFragShader ); - return nProgram; -} - bool OpenGLSalGraphicsImpl::CreateSolidProgram( void ) { - static const char aVertShaderSrc[] = - "attribute vec4 position;\n" - "void main() {\n" - " gl_Position = position;\n" - "}\n"; - static const char aFragShaderSrc[] = - "precision mediump float;\n" - "uniform vec4 color;\n" - "void main() {\n" - " gl_FragColor = color;\n" - "}\n"; - - mnSolidProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc ); + mnSolidProgram = OpenGLHelper::LoadShaders( "solidVertexShader", "solidFragmentShader" ); if( mnSolidProgram == 0 ) return false; @@ -239,23 +151,9 @@ bool OpenGLSalGraphicsImpl::CreateSolidProgram( void ) bool OpenGLSalGraphicsImpl::CreateTextureProgram( void ) { - static const char aVertShaderSrc[] = - "attribute vec4 position;\n" - "attribute vec2 tex_coord_in;\n" - "varying vec2 tex_coord;\n" - "void main() {\n" - " gl_Position = position;\n" - " tex_coord = tex_coord_in;\n" - "}\n"; static const char aFragShaderSrc[] = - "precision mediump float;\n" - "varying vec2 tex_coord;\n" - "uniform sampler2D sampler;\n" - "void main() {\n" - " gl_FragColor = texture2D(sampler, tex_coord);\n" - "}\n"; - - mnTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc ); + + mnTextureProgram = OpenGLHelper::( "textureVertexShader", "textureFragmentShader" ); if( mnTextureProgram == 0 ) return false; @@ -267,27 +165,7 @@ bool OpenGLSalGraphicsImpl::CreateTextureProgram( void ) bool OpenGLSalGraphicsImpl::CreateMaskedTextureProgram( void ) { - static const char aVertShaderSrc[] = - "attribute vec4 position;\n" - "attribute vec2 tex_coord_in;\n" - "varying vec2 tex_coord;\n" - "void main() {\n" - " gl_Position = position;\n" - " tex_coord = tex_coord_in;\n" - "}\n"; - static const char aFragShaderSrc[] = - "precision mediump float;\n" - "varying vec2 tex_coord;\n" - "uniform sampler2D sampler;\n" - "uniform sampler2D mask;\n" - "void main() {\n" - " vec4 texel0, texel1;\n" - " texel0 = texture2D(sampler, tex_coord);\n" - " texel1 = texture2D(mask, tex_coord);\n" - " gl_FragColor = texel0 * texel1.a;\n" - "}\n"; - - mnMaskedTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc ); + mnMaskedTextureProgram = OpenGLHelper::LoadShaders( "maskedTextureVertexShader", "maskedTextureFragmentShader" ); if( mnMaskedTextureProgram == 0 ) return false; @@ -300,26 +178,7 @@ bool OpenGLSalGraphicsImpl::CreateMaskedTextureProgram( void ) bool OpenGLSalGraphicsImpl::CreateMaskProgram( void ) { - static const char aVertShaderSrc[] = - "attribute vec4 position;\n" - "attribute vec2 tex_coord_in;\n" - "varying vec2 tex_coord;\n" - "void main() {\n" - " gl_Position = position;\n" - " tex_coord = tex_coord_in;\n" - "}\n"; - static const char aFragShaderSrc[] = - "precision mediump float;\n" - "varying vec2 tex_coord;\n" - "uniform sampler2D sampler;\n" - "uniform vec4 color;\n" - "void main() {\n" - " vec4 texel0;\n" - " texel0 = texture2D(sampler, tex_coord);\n" - " gl_FragColor = color * texel0.a;\n" - "}\n"; - - mnMaskedTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc ); + mnMaskedTextureProgram = OpenGLHelper::LoadShaders( "maskVertexShader", "maskFragmentShader" ); if( mnMaskedTextureProgram == 0 ) return false; diff --git a/vcl/opengl/maskFragmentShader.glsl b/vcl/opengl/maskFragmentShader.glsl new file mode 100644 index 0000000..35ecbd0 --- /dev/null +++ b/vcl/opengl/maskFragmentShader.glsl @@ -0,0 +1,21 @@ +/* -*- 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/. + */ + +precision mediump float; +varying vec2 tex_coord; +uniform sampler2D sampler; +uniform vec4 color;" + +void main() { + vec4 texel0; + texel0 = texture2D(sampler, tex_coord); + gl_FragColor = color * texel0.a; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/maskVertexShader.glsl b/vcl/opengl/maskVertexShader.glsl new file mode 100644 index 0000000..303ddec --- /dev/null +++ b/vcl/opengl/maskVertexShader.glsl @@ -0,0 +1,19 @@ +/* -*- 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; +varying vec2 tex_coord; + +void main() { + gl_Position = position; + tex_coord = tex_coord_in; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/maskedTextureFragmentShader.glsl b/vcl/opengl/maskedTextureFragmentShader.glsl new file mode 100644 index 0000000..5353250 --- /dev/null +++ b/vcl/opengl/maskedTextureFragmentShader.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/. + */ + +precision mediump float; +varying vec2 tex_coord; +uniform sampler2D sampler; +uniform sampler2D mask; + +void main() { + vec4 texel0, texel1; + texel0 = texture2D(sampler, tex_coord); + texel1 = texture2D(mask, tex_coord); + gl_FragColor = texel0 * texel1.a; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/maskedTextureVertexShader.glsl b/vcl/opengl/maskedTextureVertexShader.glsl new file mode 100644 index 0000000..303ddec --- /dev/null +++ b/vcl/opengl/maskedTextureVertexShader.glsl @@ -0,0 +1,19 @@ +/* -*- 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; +varying vec2 tex_coord; + +void main() { + gl_Position = position; + tex_coord = tex_coord_in; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/solidFragmentShader.glsl b/vcl/opengl/solidFragmentShader.glsl new file mode 100644 index 0000000..917cafc --- /dev/null +++ b/vcl/opengl/solidFragmentShader.glsl @@ -0,0 +1,17 @@ +/* -*- 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/. + */ + +precision mediump float; + +uniform vec4 color; +void main() { + gl_FragColor = color; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/solidVertexShader.glsl b/vcl/opengl/solidVertexShader.glsl new file mode 100644 index 0000000..c3de9c5 --- /dev/null +++ b/vcl/opengl/solidVertexShader.glsl @@ -0,0 +1,16 @@ +/* -*- 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; +void main() { + gl_Position = position; +}; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/textureFragmentShader.glsl b/vcl/opengl/textureFragmentShader.glsl new file mode 100644 index 0000000..eb510d8 --- /dev/null +++ b/vcl/opengl/textureFragmentShader.glsl @@ -0,0 +1,18 @@ +/* -*- 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/. + */ + +precision mediump float; +varying vec2 tex_coord; +uniform sampler2D sampler; + +void main() { + gl_FragColor = texture2D(sampler, tex_coord); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/textureVertexShader.glsl b/vcl/opengl/textureVertexShader.glsl new file mode 100644 index 0000000..303ddec --- /dev/null +++ b/vcl/opengl/textureVertexShader.glsl @@ -0,0 +1,19 @@ +/* -*- 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; +varying vec2 tex_coord; + +void main() { + gl_Position = position; + tex_coord = tex_coord_in; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 72ef9d08ba31689675381693aa49986555bc0139 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Wed Oct 29 13:05:02 2014 -0400 vcl: Implement basic SalGraphics methods for OpenGL backend Change-Id: Iade3960c38f0de5594bc98e535450abcf88e9a6d diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 9ae84ca..d3ee9ef 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -31,6 +31,51 @@ private: OpenGLContext maContext; + SalColor mnLineColor; + SalColor mnFillColor; + + std::vector< GLuint > maShaders; + + GLuint mnSolidProgram; + GLuint mnColorUniform; + + GLuint mnTextureProgram; + GLuint mnSamplerUniform; + + GLuint mnMaskedTextureProgram; + GLuint mnMaskedSamplerUniform; + GLuint mnMaskSamplerUniform; + + GLuint mnMaskProgram; + GLuint mnMaskUniform; + GLuint mnMaskColorUniform; + + GLuint CompileShader( GLenum nType, const char *aSrc ); + GLuint CreateProgram( const char *aVertShaderSrc, const char *aFragShaderSrc ); + bool CreateSolidProgram( void ); + bool CreateTextureProgram( void ); + bool CreateMaskedTextureProgram( void ); + bool CreateMaskProgram( void ); + + void BeginSolid( SalColor nColor, sal_uInt8 nTransparency ); + void BeginSolid( SalColor nColor ); + void EndSolid( void ); + void BeginInvert( void ); + void EndInvert( void ); + + void DrawPoint( long nX, long nY ); + 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 DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ); + void DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPolyPolygon ); + void DrawTextureRect( const SalTwoRect& pPosAry ); + void DrawTexture( GLuint nTexture, const SalTwoRect& pPosAry ); + void DrawTextureWithMask( GLuint nTexture, GLuint nMask, const SalTwoRect& pPosAry ); + void DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& pPosAry ); + + public: virtual ~OpenGLSalGraphicsImpl (); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 6e39d1e..f59584a 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -20,6 +20,18 @@ #include "openglgdiimpl.hxx" #include <vcl/gradient.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygontriangulator.hxx> + +#define GL_ATTRIB_POS 0 +#define GL_ATTRIB_TEX 1 + +#define glUniformColor(nUniform, nColor, nTransparency) \ + glUniform4f( nUniform, \ + ((float) SALCOLOR_RED( nColor )) / 255, \ + ((float) SALCOLOR_GREEN( nColor )) / 255, \ + ((float) SALCOLOR_BLUE( nColor )) / 255, \ + (100 - nTransparency) * (1.0 / 100) ) OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl() { @@ -27,11 +39,30 @@ OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl() void OpenGLSalGraphicsImpl::freeResources() { + // Delete shaders, programs and textures if not shared } -bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& ) +bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip ) { - return false; + const basegfx::B2DPolyPolygon aClip( rClip.GetAsB2DPolyPolygon() ); + + glEnable(GL_STENCIL_TEST); + + glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); + glDepthMask( GL_FALSE ); + glStencilMask( 0xFF ); + glStencilFunc( GL_NEVER, 1, 0xFF ); + glStencilOp( GL_REPLACE, GL_KEEP, GL_KEEP ); + + glClear( GL_STENCIL_BUFFER_BIT ); + DrawPolyPolygon( aClip ); + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthMask( GL_TRUE ); + glStencilMask( 0x00 ); + glStencilFunc(GL_EQUAL, 1, 0xFF); + + return true; } // get the depth of the device @@ -49,28 +80,45 @@ long OpenGLSalGraphicsImpl::GetGraphicsWidth() const // set the clip region to empty void OpenGLSalGraphicsImpl::ResetClipRegion() { + glDisable(GL_STENCIL_TEST); } // set the line color to transparent (= don't draw lines) void OpenGLSalGraphicsImpl::SetLineColor() { + if( mnLineColor != SALCOLOR_NONE ) + { + mnLineColor = SALCOLOR_NONE; + } } // set the line color to a specific color -void OpenGLSalGraphicsImpl::SetLineColor( SalColor /*nSalColor*/ ) +void OpenGLSalGraphicsImpl::SetLineColor( SalColor nSalColor ) { + if( mnLineColor != nSalColor ) + { + mnLineColor = nSalColor; + } } // set the fill color to transparent (= don't fill) void OpenGLSalGraphicsImpl::SetFillColor() { + if( mnFillColor != SALCOLOR_NONE ) + { + mnFillColor = SALCOLOR_NONE; + } } // set the fill color to a specific color, shapes will be // filled accordingly -void OpenGLSalGraphicsImpl::SetFillColor( SalColor /*nSalColor*/ ) +void OpenGLSalGraphicsImpl::SetFillColor( SalColor nSalColor ) { + if( mnFillColor != nSalColor ) + { + mnFillColor = nSalColor; + } } // enable/disable XOR drawing @@ -88,34 +136,571 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ ) { } -// draw --> LineColor and FillColor and RasterOp and ClipRegion -void OpenGLSalGraphicsImpl::drawPixel( long /*nX*/, long /*nY*/ ) +GLuint OpenGLSalGraphicsImpl::CompileShader( GLenum nType, const char *aSrc ) +{ + GLint nStatus; + GLuint nShader; + GLint nLogLen( 0 ); + char *aLog( NULL ); + + nShader = glCreateShader( nType ); + glShaderSource( nShader, 1, (const GLchar **) &aSrc, NULL ); + glCompileShader( nShader ); + glGetShaderiv( nShader, GL_COMPILE_STATUS, &nStatus ); + if( nStatus ) + return nShader; + + glGetShaderiv( nShader, GL_INFO_LOG_LENGTH, &nLogLen ); + if( nLogLen > 1 ) + aLog = new char[nLogLen]; + if( aLog ) + glGetShaderInfoLog( nShader, nLogLen, NULL, aLog ); + + SAL_WARN( "vcl.opengl", "::CompileShader failed: " << aLog ); + + delete aLog; + glDeleteShader( nShader ); + + return 0; +} + +GLuint OpenGLSalGraphicsImpl::CreateProgram( const char *aVertShaderSrc, const char *aFragShaderSrc ) +{ + GLuint nProgram; + GLuint nVertShader, nFragShader; + GLint nStatus; + + nVertShader = CompileShader( GL_VERTEX_SHADER, aVertShaderSrc ); + nFragShader = CompileShader( GL_FRAGMENT_SHADER, aFragShaderSrc ); + if( !nVertShader || !nFragShader ) + { + SAL_WARN( "vcl.opengl", "::CreateProgram couldn't compile the shaders" ); + return 0; + } + + nProgram = glCreateProgram(); + if( nProgram == 0 ) + { + SAL_WARN( "vcl.opengl", "::CreateProgram couldn't create GL program" ); + return 0; + } + + glAttachShader( nProgram, nVertShader ); + glAttachShader( nProgram, nFragShader ); + glLinkProgram( nProgram ); + glGetProgramiv( nProgram, GL_LINK_STATUS, &nStatus ); + if( !nStatus ) + { + GLint nLogLen( 0 ); + char *aLog( NULL ); + + glDeleteShader( nVertShader ); + glDeleteShader( nFragShader ); + + glGetProgramiv( nProgram, GL_INFO_LOG_LENGTH, &nLogLen ); + if( nLogLen > 0 ) + aLog = new char[nLogLen]; + if( aLog ) + glGetProgramInfoLog( nProgram, nLogLen, NULL, aLog ); + + SAL_WARN( "vcl.opengl", "::CreateSolidShader couldn't link program: " << aLog ); + delete aLog; + + return 0; + } + + maShaders.push_back( nVertShader ); + maShaders.push_back( nFragShader ); + return nProgram; +} + +bool OpenGLSalGraphicsImpl::CreateSolidProgram( void ) +{ + static const char aVertShaderSrc[] = + "attribute vec4 position;\n" + "void main() {\n" + " gl_Position = position;\n" + "}\n"; + static const char aFragShaderSrc[] = + "precision mediump float;\n" + "uniform vec4 color;\n" + "void main() {\n" + " gl_FragColor = color;\n" + "}\n"; + + mnSolidProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc ); + if( mnSolidProgram == 0 ) + return false; + + glBindAttribLocation( mnSolidProgram, GL_ATTRIB_POS, "position" ); + mnColorUniform = glGetUniformLocation( mnSolidProgram, "color" ); + return true; +} + +bool OpenGLSalGraphicsImpl::CreateTextureProgram( void ) +{ + static const char aVertShaderSrc[] = + "attribute vec4 position;\n" + "attribute vec2 tex_coord_in;\n" + "varying vec2 tex_coord;\n" + "void main() {\n" + " gl_Position = position;\n" + " tex_coord = tex_coord_in;\n" + "}\n"; + static const char aFragShaderSrc[] = + "precision mediump float;\n" + "varying vec2 tex_coord;\n" + "uniform sampler2D sampler;\n" + "void main() {\n" + " gl_FragColor = texture2D(sampler, tex_coord);\n" + "}\n"; + + mnTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc ); + if( mnTextureProgram == 0 ) + return false; + + glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" ); + glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" ); + mnSamplerUniform = glGetUniformLocation( mnTextureProgram, "sampler" ); + return true; +} + +bool OpenGLSalGraphicsImpl::CreateMaskedTextureProgram( void ) +{ + static const char aVertShaderSrc[] = + "attribute vec4 position;\n" + "attribute vec2 tex_coord_in;\n" + "varying vec2 tex_coord;\n" + "void main() {\n" + " gl_Position = position;\n" + " tex_coord = tex_coord_in;\n" + "}\n"; + static const char aFragShaderSrc[] = + "precision mediump float;\n" + "varying vec2 tex_coord;\n" + "uniform sampler2D sampler;\n" + "uniform sampler2D mask;\n" + "void main() {\n" + " vec4 texel0, texel1;\n" + " texel0 = texture2D(sampler, tex_coord);\n" + " texel1 = texture2D(mask, tex_coord);\n" + " gl_FragColor = texel0 * texel1.a;\n" + "}\n"; + + mnMaskedTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc ); + if( mnMaskedTextureProgram == 0 ) + return false; + + glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" ); + glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" ); + mnMaskedSamplerUniform = glGetUniformLocation( mnMaskedTextureProgram, "sampler" ); + mnMaskSamplerUniform = glGetUniformLocation( mnMaskedTextureProgram, "mask" ); + return true; +} + +bool OpenGLSalGraphicsImpl::CreateMaskProgram( void ) +{ + static const char aVertShaderSrc[] = + "attribute vec4 position;\n" + "attribute vec2 tex_coord_in;\n" + "varying vec2 tex_coord;\n" + "void main() {\n" + " gl_Position = position;\n" + " tex_coord = tex_coord_in;\n" + "}\n"; + static const char aFragShaderSrc[] = + "precision mediump float;\n" + "varying vec2 tex_coord;\n" + "uniform sampler2D sampler;\n" + "uniform vec4 color;\n" + "void main() {\n" + " vec4 texel0;\n" + " texel0 = texture2D(sampler, tex_coord);\n" + " gl_FragColor = color * texel0.a;\n" + "}\n"; + + mnMaskedTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc ); + if( mnMaskedTextureProgram == 0 ) + return false; + + glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" ); + glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" ); + mnMaskUniform = glGetUniformLocation( mnMaskProgram, "sampler" ); + mnMaskColorUniform = glGetUniformLocation( mnMaskProgram, "mask" ); + return true; +} + +void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor, sal_uInt8 nTransparency ) +{ + if( mnSolidProgram == 0 ) + { + if( !CreateSolidProgram() ) + return; + } + + glUseProgram( mnSolidProgram ); + glUniformColor( mnColorUniform, nColor, nTransparency ); +} + +void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor ) +{ + BeginSolid( nColor, 0 ); +} + +void OpenGLSalGraphicsImpl::EndSolid( void ) +{ + glUseProgram( 0 ); +} + +void OpenGLSalGraphicsImpl::BeginInvert( void ) +{ + glEnable( GL_BLEND ); + glBlendFunc( GL_ONE_MINUS_DST_COLOR, GL_ZERO ); + BeginSolid( MAKE_SALCOLOR( 255, 255, 255 ) ); +} + +void OpenGLSalGraphicsImpl::EndInvert( void ) +{ + EndSolid(); + glDisable( GL_BLEND ); +} + +void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY ) +{ + GLushort pPoint[2]; + + pPoint[0] = nX; + pPoint[1] = nY; + + glEnableVertexAttribArray( GL_ATTRIB_POS ); + glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoint ); + glDrawArrays( GL_POINTS, 0, 1 ); + glDisableVertexAttribArray( GL_ATTRIB_POS ); +} + +void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 ) +{ + GLushort pPoints[4]; + + pPoints[0] = nX1; + pPoints[1] = nY1; + pPoints[2] = nX2; + pPoints[3] = nY2; + + glEnableVertexAttribArray( GL_ATTRIB_POS ); + glVertexAttribPointer( GL_ATTRIB_POS, 4, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoints ); + glDrawArrays( GL_LINES, 0, 2 ); + glDisableVertexAttribArray( GL_ATTRIB_POS ); +} + +void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose ) +{ + GLushort *pPoints; + sal_uInt32 i, j; + + pPoints = new GLushort[nPoints * 2]; + for( i = 0, j = 0; i < nPoints; i++, j += 2 ) + { + pPoints[j] = pPtAry[i].mnX; + pPoints[j+1] = pPtAry[i].mnY; + } + + glEnableVertexAttribArray( GL_ATTRIB_POS ); + glVertexAttribPointer( GL_ATTRIB_POS, nPoints * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoints ); + if( bClose ) + glDrawArrays( GL_LINE_LOOP, 0, nPoints ); + else + glDrawArrays( GL_LINE_STRIP, 0, nPoints ); + glDisableVertexAttribArray( GL_ATTRIB_POS ); +} + +void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) { + GLushort pVertices[nPoints * 2]; + sal_uInt32 i, j; + + for( i = 0, j = 0; i < nPoints; i++, j += 2 ) + { + pVertices[j] = pPtAry[i].mnX; + pVertices[j+1] = pPtAry[i].mnY; + } + + glEnableVertexAttribArray( GL_ATTRIB_POS ); + glVertexAttribPointer( GL_ATTRIB_POS, nPoints * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices ); + glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints ); + glDisableVertexAttribArray( GL_ATTRIB_POS ); } -void OpenGLSalGraphicsImpl::drawPixel( long /*nX*/, long /*nY*/, SalColor /*nSalColor*/ ) +void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeight ) { + long nX1( nX ); + long nY1( nY ); + long nX2( nX + nWidth - 1 ); + long nY2( nY + nHeight - 1 ); + const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 }, + { nX2, nY1 }, { nX2, nY2 }}; + + DrawConvexPolygon( 4, aPoints ); } -void OpenGLSalGraphicsImpl::drawLine( long /*nX1*/, long /*nY1*/, long /*nX2*/, long /*nY2*/ ) +void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) { + ::basegfx::B2DPolygon aPolygon; + + for( sal_uInt32 i = 0; i < nPoints; i++ ) + aPolygon.append( ::basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) ); + aPolygon.setClosed( true ); + + if( ::basegfx::tools::isConvex( aPolygon ) ) + { + if( nPoints > 2L ) + { + DrawConvexPolygon( nPoints, pPtAry ); + } + } + else + { + const ::basegfx::B2DPolygon& aResult( + ::basegfx::triangulator::triangulate( aPolygon ) ); + GLushort pVertices[aResult.count() * 2]; + sal_uInt32 j( 0 ); + + for( sal_uInt32 i = 0; i < aResult.count(); i++ ) + { + const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint(i) ); + pVertices[j++] = rPt.getX(); + pVertices[j++] = rPt.getY(); + } + + glEnableVertexAttribArray( GL_ATTRIB_POS ); + glVertexAttribPointer( GL_ATTRIB_POS, aResult.count() * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices ); + glDrawArrays( GL_TRIANGLES, 0, aResult.count() ); + glDisableVertexAttribArray( GL_ATTRIB_POS ); + } } -void OpenGLSalGraphicsImpl::drawRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/ ) +void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPolyPolygon ) { + sal_uInt32 i, j; + ::std::vector< GLushort > pVertices; + + for( i = 0; i < pPolyPolygon.count(); i++ ) + { + const basegfx::B2DPolygon& pPolygon( pPolyPolygon.getB2DPolygon( i ) ); + const ::basegfx::B2DPolygon& aResult( + ::basegfx::triangulator::triangulate( pPolygon ) ); + + for( j = 0; i < aResult.count(); j++ ) + { + const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint(i) ); + pVertices.push_back( rPt.getX() ); + pVertices.push_back( rPt.getY() ); + } + } + + glEnableVertexAttribArray( GL_ATTRIB_POS ); + glVertexAttribPointer( GL_ATTRIB_POS, pVertices.size(), GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices.size() ); + glDrawArrays( GL_TRIANGLES, 0, pVertices.size() / 2 ); + glDisableVertexAttribArray( GL_ATTRIB_POS ); } -void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/ ) +void OpenGLSalGraphicsImpl::DrawTextureRect( const SalTwoRect& pPosAry ) { + GLushort aTexCoord[8]; + + glEnableVertexAttribArray( GL_ATTRIB_TEX ); + glVertexAttribPointer( GL_ATTRIB_TEX, 8, GL_UNSIGNED_SHORT, GL_FALSE, 0, aTexCoord ); + + DrawRect( pPosAry.mnDestX, pPosAry.mnDestY, pPosAry.mnDestWidth, pPosAry.mnDestHeight ); + + glDisableVertexAttribArray( GL_ATTRIB_TEX ); } -void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/ ) +void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const SalTwoRect& pPosAry ) { + if( mnTextureProgram == 0 ) + { + if( !CreateTextureProgram() ) + return; + } + + glUseProgram( mnTextureProgram ); + glUniform1i( mnSamplerUniform, 0 ); + glActiveTexture( GL_TEXTURE0 ); + glBindTexture( GL_TEXTURE_2D, nTexture ); + + DrawTextureRect( pPosAry ); + + glBindTexture( GL_TEXTURE_2D, 0 ); + glUseProgram( 0 ); +} + +void OpenGLSalGraphicsImpl::DrawTextureWithMask( GLuint nTexture, GLuint nMask, const SalTwoRect& pPosAry ) +{ + if( mnMaskedTextureProgram == 0 ) + { + if( !CreateMaskedTextureProgram() ) + return; + } + + glUseProgram( mnMaskedTextureProgram ); + glUniform1i( mnMaskedSamplerUniform, 0 ); + glUniform1i( mnMaskSamplerUniform, 1 ); + glActiveTexture( GL_TEXTURE0 ); + glBindTexture( GL_TEXTURE_2D, nTexture ); + glActiveTexture( GL_TEXTURE1 ); + glBindTexture( GL_TEXTURE_2D, nMask ); + + DrawTextureRect( pPosAry ); + + glActiveTexture( GL_TEXTURE1 ); + glBindTexture( GL_TEXTURE_2D, 0 ); + glActiveTexture( GL_TEXTURE0 ); + glBindTexture( GL_TEXTURE_2D, 0 ); + glUseProgram( 0 ); } -void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 /*nPoly*/, const sal_uInt32* /*pPoints*/, PCONSTSALPOINT* /*pPtAry*/ ) +void OpenGLSalGraphicsImpl::DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& pPosAry ) { + if( mnMaskProgram == 0 ) + { + if( !CreateMaskProgram() ) + return; + } + + glUseProgram( mnMaskProgram ); + glUniformColor( mnMaskColorUniform, nMaskColor, 0 ); + glUniform1i( mnMaskUniform, 0 ); + glActiveTexture( GL_TEXTURE0 ); + glBindTexture( GL_TEXTURE_2D, nMask ); + + DrawTextureRect( pPosAry ); + + glActiveTexture( GL_TEXTURE0 ); + glBindTexture( GL_TEXTURE_2D, 0 ); + glUseProgram( 0 ); } + + +// draw --> LineColor and FillColor and RasterOp and ClipRegion +void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY ) +{ + if( mnLineColor != SALCOLOR_NONE ) + { + BeginSolid( mnLineColor ); + DrawPoint( nX, nY ); + EndSolid(); + } +} + +void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor ) +{ + if( nSalColor != SALCOLOR_NONE ) + { + BeginSolid( nSalColor ); + DrawPoint( nX, nY ); + EndSolid(); + } +} + +void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 ) +{ + if( mnLineColor != SALCOLOR_NONE ) + { + BeginSolid( mnLineColor ); + DrawLine( nX1, nY1, nX2, nY2 ); + EndSolid(); + } +} + +void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeight ) +{ + if( mnFillColor != SALCOLOR_NONE ) + { + BeginSolid( mnFillColor ); + DrawRect( nX, nY, nWidth, nHeight ); + EndSolid(); + } + + if( mnLineColor != SALCOLOR_NONE ) + { + const long nX1( nX ); + const long nY1( nY ); + const long nX2( nX + nWidth - 1 ); + const long nY2( nY + nHeight - 1 ); + const SalPoint aPoints[] = { { nX1, nY1 }, { nX2, nY1 }, + { nX2, nY2 }, { nX1, nY2 } }; + + BeginSolid( mnLineColor ); + DrawLines( 4, aPoints, true ); + EndSolid(); + } +} + +void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry ) +{ + if( mnLineColor != SALCOLOR_NONE && nPoints > 1 ) + { + BeginSolid( mnLineColor ); + DrawLines( nPoints, pPtAry, false ); + EndSolid(); + } +} + +void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) +{ + if( nPoints == 0 ) + return; + if( nPoints == 1 ) + { + drawPixel( pPtAry[0].mnX, pPtAry[0].mnY ); + return; + } + if( nPoints == 2 ) + { + drawLine( pPtAry[0].mnX, pPtAry[0].mnY, + pPtAry[1].mnX, pPtAry[1].mnY ); + return; + } + + if( mnFillColor != SALCOLOR_NONE ) + { + BeginSolid( mnFillColor ); + DrawPolygon( nPoints, pPtAry ); + EndSolid(); + } + + if( mnLineColor != SALCOLOR_NONE ) + { + BeginSolid( mnLineColor ); + DrawLines( nPoints, pPtAry, true ); + EndSolid(); + } +} + +void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ) +{ + if( nPoly <= 0 ) + return; + + if( mnFillColor != SALCOLOR_NONE ) + { + BeginSolid( mnFillColor ); + for( sal_uInt32 i = 0; i < nPoly; i++ ) + DrawPolygon( pPoints[i], pPtAry[i] ); + EndSolid(); + } + + if( mnLineColor != SALCOLOR_NONE ) + { + // TODO Use glMultiDrawElements or primitive restart + BeginSolid( mnLineColor ); + for( sal_uInt32 i = 0; i < nPoly; i++ ) + DrawLines( pPoints[i], pPtAry[i], true ); + EndSolid(); + } +} + bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ ) { return false; @@ -167,12 +752,34 @@ 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 ); + + if( bSameGraphics && + (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) && + (rPosAry.mnSrcHeight == rPosAry.mnDestHeight)) + { + // short circuit if there is nothing to do + if( (rPosAry.mnSrcX == rPosAry.mnDestX) && + (rPosAry.mnSrcY == rPosAry.mnDestY)) + return; + // use copyArea() if source and destination context are identical + copyArea( rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, 0 ); + return; + } + + // TODO Copy from one FBO to the other (glBlitFramebuffer) } -void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& /*rPosAry*/, const SalBitmap& /*rSalBitmap*/ ) +void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) { + const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap); + GLuint nTexture = rBitmap.GetTexture(); + + DrawTexture( nTexture, rPosAry ); } void OpenGLSalGraphicsImpl::drawBitmap( @@ -180,42 +787,101 @@ void OpenGLSalGraphicsImpl::drawBitmap( const SalBitmap& /*rSalBitmap*/, SalColor /*nTransparentColor*/ ) { + OSL_FAIL( "::DrawBitmap with transparent color not supported" ); } void OpenGLSalGraphicsImpl::drawBitmap( - const SalTwoRect& /*rPosAry*/, - const SalBitmap& /*rSalBitmap*/, - const SalBitmap& /*rMaskBitmap*/ ) + const SalTwoRect& rPosAry, + const SalBitmap& rSalBitmap, + const SalBitmap& rMaskBitmap ) { + 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() ); + + DrawTextureWithMask( nTexture, nMask, rPosAry ); } void OpenGLSalGraphicsImpl::drawMask( - const SalTwoRect& /*rPosAry*/, - const SalBitmap& /*rSalBitmap*/, - SalColor /*nMaskColor*/ ) + const SalTwoRect& rPosAry, + const SalBitmap& rSalBitmap, + SalColor nMaskColor ) { + const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap); + const GLuint nTexture( rBitmap.GetTexture() ); + + DrawMask( nTexture, nMaskColor, rPosAry ); } -SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/ ) +SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long nX, long nY, long nWidth, long nHeight ) { - return NULL; + 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 ) ) + { + delete pBitmap; + pBitmap = NULL; + } + return pBitmap; } -SalColor OpenGLSalGraphicsImpl::getPixel( long /*nX*/, long /*nY*/ ) +SalColor OpenGLSalGraphicsImpl::getPixel( long nX, long nY ) { - return 0; + char pixel[3]; + + glReadPixels( nX, nY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel); + return MAKE_SALCOLOR( pixel[0], pixel[1], pixel[2] ); } // invert --> ClipRegion (only Windows or VirDevs) void OpenGLSalGraphicsImpl::invert( - long /*nX*/, long /*nY*/, - long /*nWidth*/, long /*nHeight*/, - SalInvert /*nFlags*/) + long nX, long nY, + long nWidth, long nHeight, + SalInvert nFlags) { + // TODO Figure out what are those: + // * SAL_INVERT_50 (50/50 pattern?) + // * SAL_INVERT_TRACKFRAME (dash-line rectangle?) + + if( nFlags & SAL_INVERT_TRACKFRAME ) + { + + } + else if( nFlags & SAL_INVERT_50 ) + { + + } + else // just invert + { + BeginInvert(); + DrawPolygon( 4, aPoints ); + EndInvert(); + } } -void OpenGLSalGraphicsImpl::invert( sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/, SalInvert /*nFlags*/ ) +void OpenGLSalGraphicsImpl::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags ) { + if( nFlags & SAL_INVERT_TRACKFRAME ) + { + + } + else if( nFlags & SAL_INVERT_50 ) + { + + } + else // just invert + { + BeginInvert(); + DrawPolygon( nPoints, pPtAry ); + EndInvert(); + } } bool OpenGLSalGraphicsImpl::drawEPS( @@ -240,11 +906,17 @@ bool OpenGLSalGraphicsImpl::drawEPS( compositing themselves */ bool OpenGLSalGraphicsImpl::drawAlphaBitmap( - const SalTwoRect&, - const SalBitmap& /*rSourceBitmap*/, - const SalBitmap& /*rAlphaBitmap*/ ) + const SalTwoRect& rPosAry, + const SalBitmap& rSalBitmap, + const SalBitmap& rAlphaBitmap ) { - return false; + 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() ); + + DrawTextureWithMask( nTexture, nAlpha, rPosAry ); + return true; } /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */ @@ -265,11 +937,18 @@ bool OpenGLSalGraphicsImpl::drawTransformedBitmap( fully transparent rectangle */ bool OpenGLSalGraphicsImpl::drawAlphaRect( - long /*nX*/, long /*nY*/, - long /*nWidth*/, long /*nHeight*/, - sal_uInt8 /*nTransparency*/ ) -{ - return false; + long nX, long nY, + long nWidth, long nHeight, + sal_uInt8 nTransparency ) +{ + if( mnFillColor != SALCOLOR_NONE && nTransparency < 100 ) + { + BeginSolid( mnFillColor, nTransparency ); + DrawRect( nX, nY, nWidth, nHeight ); + EndSolid(); + } + + return true; } bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& /*rPolygon*/,
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits