Rebased ref, commits from common ancestor: commit b2f5eec073a1f0cbefc4bd789eaa9c8aaa7bca02 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Sat Nov 8 23:05:32 2014 -0500
vcl: Re-enable features in vcldemo Change-Id: If2a17b2c5609b7529d9aa5091ced280dd5ac4176 diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx index cae3fb0b..daa877f 100644 --- a/vcl/workben/vcldemo.cxx +++ b/vcl/workben/vcldemo.cxx @@ -25,10 +25,10 @@ #include <vcl/virdev.hxx> #include <vcl/graphicfilter.hxx> -#if 0 # define FIXME_ALPHA_WORKING # define FIXME_ROUNDED_RECT_WORKING # define FIXME_DRAW_TRANSPARENT_WORKING +#if 0 #endif using namespace css; commit da5ad77083b9a44b4579bdbfec8392b4c45fa9c6 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Sat Nov 8 23:04:46 2014 -0500 vcl: Add support for styled lines rendering with OpenGL Change-Id: Id6117e79d3aec6524598f068500249c9cd286ece diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index d0b1afb..7094727 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -22,9 +22,12 @@ #include <vcl/gradient.hxx> #include <salframe.hxx> #include "salvd.hxx" +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <basegfx/polygon/b2dlinegeometry.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/polygon/b2dpolygontriangulator.hxx> #include <basegfx/polygon/b2dpolypolygoncutter.hxx> +#include <basegfx/polygon/b2dtrapezoid.hxx> #include <vcl/opengl/OpenGLHelper.hxx> #include "opengl/salbmp.hxx" @@ -648,13 +651,84 @@ bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rP } bool OpenGLSalGraphicsImpl::drawPolyLine( - const ::basegfx::B2DPolygon&, - double /*fTransparency*/, - const ::basegfx::B2DVector& /*rLineWidths*/, - basegfx::B2DLineJoin, - com::sun::star::drawing::LineCap) -{ - return false; + const ::basegfx::B2DPolygon& rPolygon, + double fTransparency, + const ::basegfx::B2DVector& rLineWidth, + basegfx::B2DLineJoin eLineJoin, + com::sun::star::drawing::LineCap eLineCap) +{ + SAL_INFO( "vcl.opengl", "::drawPolyLine trans " << fTransparency ); + if( mnLineColor == SALCOLOR_NONE ) + return true; + + const bool bIsHairline = (rLineWidth.getX() == rLineWidth.getY()) && (rLineWidth.getX() <= 1.2); + + // #i101491# + if( !bIsHairline && (rPolygon.count() > 1000) ) + { + // the used basegfx::tools::createAreaGeometry is simply too + // expensive with very big polygons; fallback to caller (who + // should use ImplLineConverter normally) + // AW: ImplLineConverter had to be removed since it does not even + // know LineJoins, so the fallback will now prepare the line geometry + // the same way. + return false; + } + + // #i11575#desc5#b adjust B2D tesselation result to raster positions + basegfx::B2DPolygon aPolygon = rPolygon; + const double fHalfWidth = 0.5 * rLineWidth.getX(); + + // #i122456# This is probably thought to happen to align hairlines to pixel positions, so + // it should be a 0.5 translation, not more. It will definitely go wrong with fat lines + aPolygon.transform( basegfx::tools::createTranslateB2DHomMatrix(0.5, 0.5) ); + + // shortcut for hairline drawing to improve performance + //bool bDrawnOk = true; + if( bIsHairline ) + { + // hairlines can benefit from a simplified tesselation + // e.g. for hairlines the linejoin style can be ignored + /*basegfx::B2DTrapezoidVector aB2DTrapVector; + basegfx::tools::createLineTrapezoidFromB2DPolygon( aB2DTrapVector, aPolygon, rLineWidth.getX() ); + + // draw tesselation result + const int nTrapCount = aB2DTrapVector.size(); + if( nTrapCount > 0 ) + bDrawnOk = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, fTransparency ); + + return bDrawnOk;*/ + } + + // get the area polygon for the line polygon + if( (rLineWidth.getX() != rLineWidth.getY()) + && !basegfx::fTools::equalZero( rLineWidth.getY() ) ) + { + // prepare for createAreaGeometry() with anisotropic linewidth + aPolygon.transform( basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getX() / rLineWidth.getY())); + } + + // create the area-polygon for the line + const basegfx::B2DPolyPolygon aAreaPolyPoly( basegfx::tools::createAreaGeometry(aPolygon, fHalfWidth, eLineJoin, eLineCap) ); + + if( (rLineWidth.getX() != rLineWidth.getY()) + && !basegfx::fTools::equalZero( rLineWidth.getX() ) ) + { + // postprocess createAreaGeometry() for anisotropic linewidth + aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getY() / rLineWidth.getX())); + } + + maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); + BeginSolid( mnLineColor, fTransparency ); + for( sal_uInt32 i = 0; i < aAreaPolyPoly.count(); i++ ) + { + const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( i ) ); + DrawPolyPolygon( aOnePoly ); + } + EndSolid(); + + return true; } bool OpenGLSalGraphicsImpl::drawPolyLineBezier( commit 9fc7b4e59ec52323213cf939d04d2e77f066329c Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Sat Nov 8 23:03:37 2014 -0500 vcl: Fix rendering of polypolygons and self-intersecting polygons with OpenGL Change-Id: I04ed5999360eb43e2a8e2c82a3ecd9b958b16fe0 diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 0e30f6a..d0b1afb 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -24,6 +24,7 @@ #include "salvd.hxx" #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/polygon/b2dpolygontriangulator.hxx> +#include <basegfx/polygon/b2dpolypolygoncutter.hxx> #include <vcl/opengl/OpenGLHelper.hxx> #include "opengl/salbmp.hxx" @@ -354,54 +355,39 @@ void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPt if( ::basegfx::tools::isConvex( aPolygon ) ) { if( nPoints > 2L ) - { DrawConvexPolygon( nPoints, pPtAry ); - } } else { - const ::basegfx::B2DPolygon& aResult( - ::basegfx::triangulator::triangulate( aPolygon ) ); - std::vector<GLfloat> aVertices(aResult.count() * 2); - sal_uInt32 j( 0 ); - - float nHeight = GetHeight(); - float nWidth = GetWidth(); - for( sal_uInt32 i = 0; i < aResult.count(); i++ ) - { - const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint(i) ); - aVertices[j++] = 2 * rPt.getX() / nWidth - 1.0f; - aVertices[j++] = 1.0f - 2 * rPt.getY() / nHeight; - } - - glEnableVertexAttribArray( GL_ATTRIB_POS ); - glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] ); - glDrawArrays( GL_TRIANGLES, 0, aResult.count() ); - glDisableVertexAttribArray( GL_ATTRIB_POS ); + const ::basegfx::B2DPolyPolygon aPolyPolygon( aPolygon ); + DrawPolyPolygon( aPolyPolygon ); } } -void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPolyPolygon ) +void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon ) { sal_uInt32 i, j; - ::std::vector< GLushort > pVertices; + ::std::vector< GLfloat > pVertices; + GLfloat nWidth = GetWidth(); + GLfloat nHeight = GetHeight(); + const ::basegfx::B2DPolyPolygon& aSimplePolyPolygon = ::basegfx::tools::solveCrossovers( rPolyPolygon ); - for( i = 0; i < pPolyPolygon.count(); i++ ) + for( i = 0; i < aSimplePolyPolygon.count(); i++ ) { - const basegfx::B2DPolygon& pPolygon( pPolyPolygon.getB2DPolygon( i ) ); + const basegfx::B2DPolygon& rPolygon( aSimplePolyPolygon.getB2DPolygon( i ) ); const ::basegfx::B2DPolygon& aResult( - ::basegfx::triangulator::triangulate( pPolygon ) ); + ::basegfx::triangulator::triangulate( rPolygon ) ); for( j = 0; j < aResult.count(); j++ ) { const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint( j ) ); - pVertices.push_back( rPt.getX() ); - pVertices.push_back( rPt.getY() ); + pVertices.push_back( 2 * rPt.getX() / nWidth - 1.0f ); + pVertices.push_back( 1.0f - 2 * rPt.getY() / nHeight ); } } glEnableVertexAttribArray( GL_ATTRIB_POS ); - glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices.data() ); + glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, pVertices.data() ); glDrawArrays( GL_TRIANGLES, 0, pVertices.size() / 2 ); glDisableVertexAttribArray( GL_ATTRIB_POS ); } commit db9134117b690304ecc553ba6fc50f9eb5e1d690 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Sat Nov 8 23:01:27 2014 -0500 vcl: Add support for alpha mask rendering with OpenGL Change-Id: I755c2132f143d5ebd69e53bb4d9ae45121ada22a diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 9368a10..34c2607 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -76,7 +76,7 @@ protected: void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon ); void DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry ); void DrawTexture( GLuint nTexture, const Size& rSize, const SalTwoRect& rPosAry ); - void DrawTextureWithMask( GLuint nTexture, GLuint nMask, const SalTwoRect& rPosAry ); + void DrawTextureWithMask( GLuint nTexture, GLuint nMask, const Size& rSize, const SalTwoRect& rPosAry ); void DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& rPosAry ); protected: diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 74f7252..0e30f6a 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -444,7 +444,7 @@ void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const Size& rSize, con glUseProgram( 0 ); } -void OpenGLSalGraphicsImpl::DrawTextureWithMask( GLuint nTexture, GLuint nMask, const SalTwoRect& /*pPosAry*/ ) +void OpenGLSalGraphicsImpl::DrawTextureWithMask( GLuint nTexture, GLuint nMask, const Size& rSize, const SalTwoRect& pPosAry ) { if( mnMaskedTextureProgram == 0 ) { @@ -460,7 +460,10 @@ void OpenGLSalGraphicsImpl::DrawTextureWithMask( GLuint nTexture, GLuint nMask, glActiveTexture( GL_TEXTURE1 ); glBindTexture( GL_TEXTURE_2D, nMask ); - //DrawTextureRect( pPosAry ); + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + DrawTextureRect( rSize, pPosAry ); + glDisable( GL_BLEND ); glActiveTexture( GL_TEXTURE1 ); glBindTexture( GL_TEXTURE_2D, 0 ); @@ -758,9 +761,10 @@ void OpenGLSalGraphicsImpl::drawBitmap( const GLuint nTexture( rBitmap.GetTexture( maContext ) ); const GLuint nMask( rMask.GetTexture( maContext ) ); - SAL_INFO( "vcl.opengl", "::drawBitmap" ); + SAL_INFO( "vcl.opengl", "::drawBitmap with MASK" ); maContext.makeCurrent(); - DrawTextureWithMask( nTexture, nMask, rPosAry ); + glViewport( 0, 0, GetWidth(), GetHeight() ); + DrawTextureWithMask( nTexture, nMask, rBitmap.GetSize(), rPosAry ); } void OpenGLSalGraphicsImpl::drawMask( @@ -881,8 +885,10 @@ bool OpenGLSalGraphicsImpl::drawAlphaBitmap( const GLuint nTexture( rBitmap.GetTexture( maContext ) ); const GLuint nAlpha( rAlpha.GetTexture( maContext ) ); + SAL_INFO( "vcl.opengl", "::drawAlphaBitmap" ); maContext.makeCurrent(); - DrawTextureWithMask( nTexture, nAlpha, rPosAry ); + glViewport( 0, 0, GetWidth(), GetHeight() ); + DrawTextureWithMask( nTexture, nAlpha, rBitmap.GetSize(), rPosAry ); return true; } diff --git a/vcl/opengl/maskedTextureFragmentShader.glsl b/vcl/opengl/maskedTextureFragmentShader.glsl index 8f8148a..badf91e 100644 --- a/vcl/opengl/maskedTextureFragmentShader.glsl +++ b/vcl/opengl/maskedTextureFragmentShader.glsl @@ -13,10 +13,11 @@ 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; + vec4 texel0, texel1; + texel0 = texture2D(sampler, tex_coord); + texel1 = texture2D(mask, tex_coord); + gl_FragColor = texel0; + gl_FragColor.a = texel1.r; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 018bb34ba00ab0a666e5a59ebe6952476ef50a34 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Sat Nov 8 23:00:16 2014 -0500 vcl: Fix some viewport issues when rendering with OpenGL Change-Id: I99a76baeac07c1d9ec44ed492caa1d3416eb43ac diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index a9a6884..74f7252 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -498,6 +498,7 @@ void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY ) if( mnLineColor != SALCOLOR_NONE ) { maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); BeginSolid( mnLineColor ); DrawPoint( nX, nY ); EndSolid(); @@ -510,6 +511,7 @@ void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor ) if( nSalColor != SALCOLOR_NONE ) { maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); BeginSolid( nSalColor ); DrawPoint( nX, nY ); EndSolid(); @@ -522,6 +524,7 @@ void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 ) if( mnLineColor != SALCOLOR_NONE ) { maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); BeginSolid( mnLineColor ); DrawLine( nX1, nY1, nX2, nY2 ); EndSolid(); @@ -560,6 +563,7 @@ void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pP { SAL_INFO( "vcl.opengl", "::drawPolyLine" ); maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); if( mnLineColor != SALCOLOR_NONE && nPoints > 1 ) { @@ -587,6 +591,7 @@ void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPt } maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); if( mnFillColor != SALCOLOR_NONE ) { @@ -610,6 +615,7 @@ void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* return; maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); if( mnFillColor != SALCOLOR_NONE ) { @@ -767,6 +773,7 @@ void OpenGLSalGraphicsImpl::drawMask( SAL_INFO( "vcl.opengl", "::drawMask" ); maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); DrawMask( nTexture, nMaskColor, rPosAry ); } @@ -788,6 +795,7 @@ SalColor OpenGLSalGraphicsImpl::getPixel( long nX, long nY ) char pixel[3]; maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); glReadPixels( nX, nY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel); return MAKE_SALCOLOR( pixel[0], pixel[1], pixel[2] ); } @@ -803,6 +811,7 @@ void OpenGLSalGraphicsImpl::invert( // * SAL_INVERT_TRACKFRAME (dash-line rectangle?) maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); if( nFlags & SAL_INVERT_TRACKFRAME ) { @@ -823,6 +832,7 @@ void OpenGLSalGraphicsImpl::invert( void OpenGLSalGraphicsImpl::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags ) { maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); if( nFlags & SAL_INVERT_TRACKFRAME ) { commit 7d106f448832c9fed9599bacbfb8e54f85fc47a8 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Sat Nov 8 22:59:09 2014 -0500 vcl: Fix pixel drawing with OpenGL Change-Id: If23255d2a78445d2c28ada00778c95e28cbd0683 diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 27347a8..a9a6884 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -268,10 +268,10 @@ void OpenGLSalGraphicsImpl::EndInvert( void ) void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY ) { - GLushort pPoint[2]; + GLfloat pPoint[2]; - pPoint[0] = nX; - pPoint[1] = GetHeight() - nY; + pPoint[0] = 2 * nX / GetWidth() - 1.0f; + pPoint[1] = 2 * (GetHeight() - nY) / GetHeight() - 1.0f; glEnableVertexAttribArray( GL_ATTRIB_POS ); glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoint ); commit f5e965b6b880741fc5e5fe05d014e67b7c64fd7a Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Sat Nov 8 22:55:58 2014 -0500 vcl: Disable clipping in OpenGL for now because it's broken with VDev Change-Id: Ia1e5de6674e642f428da58164001e8619cd99530 diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 55b6a93..27347a8 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -60,25 +60,38 @@ bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip ) { const basegfx::B2DPolyPolygon aClip( rClip.GetAsB2DPolyPolygon() ); - /*glEnable(GL_STENCIL_TEST); + SAL_INFO( "vcl.opengl", "::setClipRegion" ); + + /*maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); + + 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 ); + BeginSolid( SALCOLOR_NONE ); DrawPolyPolygon( aClip ); + EndSolid(); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glDepthMask( GL_TRUE ); + glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); glStencilMask( 0x00 ); - glStencilFunc(GL_EQUAL, 1, 0xFF);*/ + glStencilFunc( GL_EQUAL, 1, 0xFF );*/ return true; } +// set the clip region to empty +void OpenGLSalGraphicsImpl::ResetClipRegion() +{ + SAL_INFO( "vcl.opengl", "::ResetClipRegion" ); + maContext.makeCurrent(); + glDisable(GL_STENCIL_TEST); +} + // get the depth of the device sal_uInt16 OpenGLSalGraphicsImpl::GetBitCount() const { @@ -91,12 +104,6 @@ long OpenGLSalGraphicsImpl::GetGraphicsWidth() const return GetWidth(); } -// 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() { commit 527d820fd26d8ae95b3191fb764bbae748ea4ee9 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Sat Nov 8 22:55:06 2014 -0500 vcl: Add support for transparent polygon drawing with OpenGL Change-Id: Iaa7cdcf4742d8148507c69c222bff417b9f9426c diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index b05a520..9368a10 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -61,6 +61,7 @@ protected: bool CreateMaskProgram( void ); void BeginSolid( SalColor nColor, sal_uInt8 nTransparency ); + void BeginSolid( SalColor nColor, double fTransparency ); void BeginSolid( SalColor nColor ); void EndSolid( void ); void BeginInvert( void ); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 9288260..55b6a93 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -40,6 +40,13 @@ ((float) SALCOLOR_BLUE( nColor )) / 255, \ (100 - nTransparency) * (1.0 / 100) ) +#define glUniformColorf(nUniform, nColor, fTransparency) \ + glUniform4f( nUniform, \ + ((float) SALCOLOR_RED( nColor )) / 255, \ + ((float) SALCOLOR_GREEN( nColor )) / 255, \ + ((float) SALCOLOR_BLUE( nColor )) / 255, \ + (1.0f - fTransparency) ) + OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl() { } @@ -202,18 +209,41 @@ void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor, sal_uInt8 nTransparency return; } + if( nTransparency > 0 ) + { + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + } glUseProgram( mnSolidProgram ); glUniformColor( mnColorUniform, nColor, nTransparency ); } +void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor, double fTransparency ) +{ + if( mnSolidProgram == 0 ) + { + if( !CreateSolidProgram() ) + return; + } + + if( fTransparency > 0.0f ) + { + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + } + glUseProgram( mnSolidProgram ); + glUniformColorf( mnColorUniform, nColor, fTransparency ); +} + void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor ) { - BeginSolid( nColor, 0 ); + BeginSolid( nColor, 0.0f ); } void OpenGLSalGraphicsImpl::EndSolid( void ) { glUseProgram( 0 ); + glDisable( GL_BLEND ); } void OpenGLSalGraphicsImpl::BeginInvert( void ) @@ -592,9 +622,27 @@ void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* } } -bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ ) +bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency ) { - return false; + SAL_INFO( "vcl.opengl", "::drawPolyPolygon trans " << fTransparency ); + if( rPolyPolygon.count() <= 0 ) + return true; + + maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); + + if( mnFillColor != SALCOLOR_NONE ) + { + BeginSolid( mnFillColor, fTransparency ); + for( sal_uInt32 i = 0; i < rPolyPolygon.count(); i++ ) + { + const ::basegfx::B2DPolyPolygon aOnePoly( rPolyPolygon.getB2DPolygon( i ) ); + DrawPolyPolygon( aOnePoly ); + } + EndSolid(); + } + + return true; } bool OpenGLSalGraphicsImpl::drawPolyLine( @@ -843,6 +891,7 @@ bool OpenGLSalGraphicsImpl::drawAlphaRect( long nWidth, long nHeight, sal_uInt8 nTransparency ) { + SAL_INFO( "vcl.opengl", "::drawAlphaRect" ); if( mnFillColor != SALCOLOR_NONE && nTransparency < 100 ) { BeginSolid( mnFillColor, nTransparency ); diff --git a/vcl/opengl/solidFragmentShader.glsl b/vcl/opengl/solidFragmentShader.glsl index 94d0de0..af75336 100644 --- a/vcl/opengl/solidFragmentShader.glsl +++ b/vcl/opengl/solidFragmentShader.glsl @@ -11,7 +11,7 @@ uniform vec4 color; void main() { - gl_FragColor = color; + gl_FragColor = color; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/outdev/polygon.cxx b/vcl/source/outdev/polygon.cxx index 39c2b68..03fa168 100644 --- a/vcl/source/outdev/polygon.cxx +++ b/vcl/source/outdev/polygon.cxx @@ -231,7 +231,7 @@ void OutputDevice::DrawPolygon( const Polygon& rPoly ) // Caution: This method is nearly the same as // OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency), -// so when changes are made here do not forget to make change sthere, too +// so when changes are made here do not forget to make changes there, too void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly ) { commit e94421aae7fa75e53159096f1143ccc00d90e3d8 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Sat Nov 8 20:13:28 2014 -0500 vcl: Fix getBitmap operation Change-Id: Id78065081bbde97738afd0f4da09b502afe468f4 diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx index 0736773..40be728 100644 --- a/vcl/opengl/salbmp.cxx +++ b/vcl/opengl/salbmp.cxx @@ -71,6 +71,7 @@ bool OpenGLSalBitmap::Create( OpenGLContext& rContext, long nX, long nY, long nW maPalette = aEmptyPalette; mpTexture.reset( new OpenGLTexture( nX, nY, nWidth, nHeight ) ); + mbDirtyTexture = false; return true; } @@ -107,6 +108,7 @@ bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount if( isValidBitCount( nNewBitCount ) ) { + // TODO: lfrb: What about the pending operations?! mnBits = nNewBitCount; mnBytesPerRow = rSourceBitmap.mnBytesPerRow; mnWidth = rSourceBitmap.mnWidth; @@ -116,6 +118,7 @@ bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount maPalette = rSourceBitmap.maPalette; mpContext = rSourceBitmap.mpContext; mpTexture = rSourceBitmap.mpTexture; + mbDirtyTexture = false; maUserBuffer = rSourceBitmap.maUserBuffer; // TODO Copy buffer data if the bitcount and palette are the same commit c77257fc200f82b21fe61dd644ad655351116921 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Sat Nov 8 19:32:14 2014 -0500 basegfx: Solve crossovers even if there is only one polygon in the polypolygon Change-Id: If4fcb8a2c6ac40a4d694522ce4ed020bcb4466b8 diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx index aaad335..d9eea58 100644 --- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx +++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx @@ -688,7 +688,7 @@ namespace basegfx B2DPolyPolygon solveCrossovers(const B2DPolyPolygon& rCandidate) { - if(rCandidate.count() > 1L) + if(rCandidate.count() > 0L) { solver aSolver(rCandidate); return aSolver.getB2DPolyPolygon(); commit b5a6d9109e2a30b344e22a6c97893bb03b71dadb Author: Michael Meeks <michael.me...@collabora.com> Date: Sat Nov 8 21:41:13 2014 +0000 vcldemo: add a virtualdevice test. Change-Id: I8ff8c74e13a128d778b487ec2818820df9d5058a diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx index 9b314df..cae3fb0b 100644 --- a/vcl/workben/vcldemo.cxx +++ b/vcl/workben/vcldemo.cxx @@ -22,6 +22,7 @@ #include <vcl/svapp.hxx> #include <vcl/pngread.hxx> #include <vcl/wrkwin.hxx> +#include <vcl/virdev.hxx> #include <vcl/graphicfilter.hxx> #if 0 @@ -70,12 +71,12 @@ public: maIntroBW.Filter( BMP_FILTER_EMBOSS_GREY ); } - void drawToDevice(OutputDevice &r); + void drawToDevice(OutputDevice &r, bool bVdev); virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE { fprintf(stderr, "DemoWin::Paint(%ld,%ld,%ld,%ld)\n", rRect.getX(), rRect.getY(), rRect.getWidth(), rRect.getHeight()); - drawToDevice(getOutDev()); + drawToDevice(getOutDev(), false); } std::vector<Rectangle> partitionAndClear(OutputDevice &rDev, @@ -233,8 +234,19 @@ public: rDev.DrawPolyPolygon(aPolyPoly); #endif } - void fetchDrawBitmap(OutputDevice &rDev, Rectangle r) + void drawToVirtualDevice(OutputDevice &rDev, Rectangle r) + { + VirtualDevice aNested; + aNested.SetOutputSize(r.GetSize()); + Rectangle aWhole(Point(0,0), r.GetSize()); + // mini me + drawToDevice(aNested, true); + + Bitmap aBitmap(aNested.GetBitmap(Point(0,0),aWhole.GetSize())); + rDev.DrawBitmap(r.TopLeft(), aBitmap); + } + void fetchDrawBitmap(OutputDevice &rDev, Rectangle r) { // FIXME: should work ... Bitmap aBitmap(GetBitmap(Point(0,0),rDev.GetOutputSizePixel())); @@ -282,7 +294,7 @@ std::vector<Rectangle> DemoWin::partitionAndClear(OutputDevice &rDev, int nX, in return aRegions; } -void DemoWin::drawToDevice(OutputDevice &rDev) +void DemoWin::drawToDevice(OutputDevice &rDev, bool bVdev) { drawBackground(rDev); @@ -297,8 +309,10 @@ void DemoWin::drawToDevice(OutputDevice &rDev) drawBitmap(rDev, aRegions[6]); drawGradient(rDev, aRegions[7]); drawPolyPolgons(rDev, aRegions[8]); + if (!bVdev) + drawToVirtualDevice(rDev, aRegions[9]); // last - thumbnail all the above - fetchDrawBitmap(rDev, aRegions[9]); + fetchDrawBitmap(rDev, aRegions[10]); } class DemoApp : public Application commit 396112002904da353cc88bd090487ba694689d4d Author: Michael Meeks <michael.me...@collabora.com> Date: Sat Nov 8 21:34:10 2014 +0000 vcldemo: re-factor to allow rendering to any outputdevice. Change-Id: Ie3367c004d89043fb78d0b2dcd49254323353a4c diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx index d753c0d..9b314df 100644 --- a/vcl/workben/vcldemo.cxx +++ b/vcl/workben/vcldemo.cxx @@ -32,13 +32,23 @@ using namespace css; -class DemoWin : public WorkWindow +class DemoBase : + public WorkWindow // hide OutputDevice if necessary +{ +public: + DemoBase() : WorkWindow( NULL, WB_APP | WB_STDWORK) + { + } + OutputDevice &getOutDev() { return *this; } +}; + +class DemoWin : public DemoBase { Bitmap maIntroBW; BitmapEx maIntro; public: - DemoWin() : WorkWindow( NULL, WB_APP | WB_STDWORK) + DemoWin() : DemoBase() { // Needed to find images OUString aPath; @@ -60,32 +70,39 @@ public: maIntroBW.Filter( BMP_FILTER_EMBOSS_GREY ); } - virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE; + void drawToDevice(OutputDevice &r); - std::vector<Rectangle> partitionAndClear(int nX, int nY); + virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE + { + fprintf(stderr, "DemoWin::Paint(%ld,%ld,%ld,%ld)\n", rRect.getX(), rRect.getY(), rRect.getWidth(), rRect.getHeight()); + drawToDevice(getOutDev()); + } - void drawBackground() + std::vector<Rectangle> partitionAndClear(OutputDevice &rDev, + int nX, int nY); + + void drawBackground(OutputDevice &rDev) { - Rectangle r(Point(0,0), GetSizePixel()); + Rectangle r(Point(0,0), rDev.GetOutputSizePixel()); Gradient aGradient; aGradient.SetStartColor(COL_BLUE); aGradient.SetEndColor(COL_GREEN); aGradient.SetStyle(GradientStyle_LINEAR); // aGradient.SetBorder(r.GetSize().Width()/20); - DrawGradient(r, aGradient); + rDev.DrawGradient(r, aGradient); } - void drawRadialLines(Rectangle r) + void drawRadialLines(OutputDevice &rDev, Rectangle r) { - SetFillColor(Color(COL_LIGHTRED)); - SetLineColor(Color(COL_BLACK)); - DrawRect( r ); + rDev.SetFillColor(Color(COL_LIGHTRED)); + rDev.SetLineColor(Color(COL_BLACK)); + rDev.DrawRect( r ); // FIXME: notice these appear reflected at the bottom not the top. for(int i=0; i<r.GetHeight(); i+=15) - DrawLine( Point(r.Left(), r.Top()+i), Point(r.Right(), r.Bottom()-i) ); + rDev.DrawLine( Point(r.Left(), r.Top()+i), Point(r.Right(), r.Bottom()-i) ); for(int i=0; i<r.GetWidth(); i+=15) - DrawLine( Point(r.Left()+i, r.Bottom()), Point(r.Right()-i, r.Top()) ); + rDev.DrawLine( Point(r.Left()+i, r.Bottom()), Point(r.Right()-i, r.Top()) ); // Should draw a white-line across the middle Color aLastPixel( COL_WHITE ); @@ -93,23 +110,25 @@ public: (r.Top() + r.Bottom())/2 - 4); for(int i=0; i<8; i++) { - DrawPixel(aCenter, aLastPixel); - aLastPixel = GetPixel(aCenter); + rDev.DrawPixel(aCenter, aLastPixel); + aLastPixel = rDev.GetPixel(aCenter); aCenter.Move(1,1); } } - void drawText(Rectangle r) + void drawText(OutputDevice &rDev, Rectangle r) + { - SetTextColor( Color( COL_BLACK ) ); + rDev.SetTextColor( Color( COL_BLACK ) ); vcl::Font aFont( OUString( "Times" ), Size( 0, 25 ) ); - SetFont( aFont ); - DrawText( r, OUString( "Just a simple text" ) ); + rDev.SetFont( aFont ); + rDev.DrawText( r, OUString( "Just a simple text" ) ); } - void drawPoly(Rectangle r) // pretty + void drawPoly(OutputDevice &rDev, Rectangle r) + // pretty { - drawCheckered(r); + drawCheckered(rDev, r); long nDx = r.GetWidth()/20; long nDy = r.GetHeight()/20; @@ -119,22 +138,25 @@ public: r.GetHeight()-nDy*2)); Polygon aPoly(aShrunk); tools::PolyPolygon aPPoly(aPoly); - SetLineColor(Color(COL_RED)); - SetFillColor(Color(COL_RED)); + rDev.SetLineColor(Color(COL_RED)); + rDev.SetFillColor(Color(COL_RED)); // This hits the optional 'drawPolyPolygon' code-path - DrawTransparent(aPPoly, 64); + rDev.DrawTransparent(aPPoly, 64); } - void drawEllipse(Rectangle r) + void drawEllipse(OutputDevice &rDev, Rectangle r) + { - SetLineColor(Color(COL_RED)); - SetFillColor(Color(COL_GREEN)); - DrawEllipse(r); + rDev.SetLineColor(Color(COL_RED)); + rDev.SetFillColor(Color(COL_GREEN)); + rDev.DrawEllipse(r); } - void drawCheckered(Rectangle r) + void drawCheckered(OutputDevice &rDev, Rectangle r) + { - DrawCheckered(r.TopLeft(), r.GetSize()); + rDev.DrawCheckered(r.TopLeft(), r.GetSize()); } - void drawGradient(Rectangle r) + void drawGradient(OutputDevice &rDev, Rectangle r) + { Gradient aGradient; aGradient.SetStartColor(COL_YELLOW); @@ -142,30 +164,33 @@ public: // aGradient.SetAngle(45); aGradient.SetStyle(GradientStyle_RECT); aGradient.SetBorder(r.GetSize().Width()/20); - DrawGradient(r, aGradient); + rDev.DrawGradient(r, aGradient); } - void drawBitmap(Rectangle r) + void drawBitmap(OutputDevice &rDev, Rectangle r) + { Bitmap aBitmap(maIntroBW); aBitmap.Scale(r.GetSize(), BMP_SCALE_BESTQUALITY); - DrawBitmap(r.TopLeft(), aBitmap); + rDev.DrawBitmap(r.TopLeft(), aBitmap); } - void drawBitmapEx(Rectangle r) + void drawBitmapEx(OutputDevice &rDev, Rectangle r) + { - drawCheckered(r); + drawCheckered(rDev, r); BitmapEx aBitmap(maIntro); aBitmap.Scale(r.GetSize(), BMP_SCALE_BESTQUALITY); #ifdef FIXME_ALPHA_WORKING AlphaMask aSemiTransp(aBitmap.GetSizePixel()); aSemiTransp.Erase(64); - DrawBitmapEx(r.TopLeft(), BitmapEx(aBitmap.GetBitmap(), + rDev.DrawBitmapEx(r.TopLeft(), BitmapEx(aBitmap.GetBitmap(), aSemiTransp)); #else - DrawBitmapEx(r.TopLeft(), aBitmap); + rDev.DrawBitmapEx(r.TopLeft(), aBitmap); #endif } - void drawPolyPolgons(Rectangle r) + void drawPolyPolgons(OutputDevice &rDev, Rectangle r) + { struct { double nX, nY; @@ -191,39 +216,40 @@ public: aSubRect.GetHeight() * aPoints[v].nY), v); } - SetLineColor(Color(COL_YELLOW)); - SetFillColor(Color(COL_BLACK)); - DrawPolygon(aPoly); + rDev.SetLineColor(Color(COL_YELLOW)); + rDev.SetFillColor(Color(COL_BLACK)); + rDev.DrawPolygon(aPoly); // now move and add to the polypolygon aPoly.Move(0, r.GetHeight()/2); aPolyPoly.Insert(aPoly); } } - SetLineColor(Color(COL_LIGHTRED)); - SetFillColor(Color(COL_GREEN)); + rDev.SetLineColor(Color(COL_LIGHTRED)); + rDev.SetFillColor(Color(COL_GREEN)); #ifdef FIXME_DRAW_TRANSPARENT_WORKING - DrawTransparent(aPolyPoly, 50); + rDev.DrawTransparent(aPolyPoly, 50); #else - DrawPolyPolygon(aPolyPoly); + rDev.DrawPolyPolygon(aPolyPoly); #endif } - void fetchDrawBitmap(Rectangle r) + void fetchDrawBitmap(OutputDevice &rDev, Rectangle r) + { // FIXME: should work ... - Bitmap aBitmap(GetBitmap(Point(0,0),GetSizePixel())); + Bitmap aBitmap(GetBitmap(Point(0,0),rDev.GetOutputSizePixel())); aBitmap.Scale(r.GetSize(), BMP_SCALE_BESTQUALITY); - DrawBitmap(r.TopLeft(), aBitmap); + rDev.DrawBitmap(r.TopLeft(), aBitmap); } }; -std::vector<Rectangle> DemoWin::partitionAndClear(int nX, int nY) +std::vector<Rectangle> DemoWin::partitionAndClear(OutputDevice &rDev, int nX, int nY) { Rectangle r; std::vector<Rectangle> aRegions; // Make small cleared area for these guys - Size aSize(GetSizePixel()); + Size aSize(rDev.GetOutputSizePixel()); long nBorderSize = aSize.Width() / 32; long nBoxWidth = (aSize.Width() - nBorderSize*(nX+1)) / nX; long nBoxHeight = (aSize.Height() - nBorderSize*(nY+1)) / nY; @@ -236,16 +262,16 @@ std::vector<Rectangle> DemoWin::partitionAndClear(int nX, int nY) r.SetSize(Size(nBoxWidth, nBoxHeight)); // knock up a nice little border - SetLineColor(COL_GRAY); - SetFillColor(COL_LIGHTGRAY); + rDev.SetLineColor(COL_GRAY); + rDev.SetFillColor(COL_LIGHTGRAY); if ((x + y) % 2) - DrawRect(r); + rDev.DrawRect(r); else { #ifdef FIXME_ROUNDED_RECT_WORKING - DrawRect(r, nBorderSize, nBorderSize); + rDev.DrawRect(r, nBorderSize, nBorderSize); #else - DrawRect(r); + rDev.DrawRect(r); #endif } @@ -256,25 +282,23 @@ std::vector<Rectangle> DemoWin::partitionAndClear(int nX, int nY) return aRegions; } -void DemoWin::Paint( const Rectangle& rRect ) +void DemoWin::drawToDevice(OutputDevice &rDev) { - fprintf(stderr, "DemoWin::Paint(%ld,%ld,%ld,%ld)\n", rRect.getX(), rRect.getY(), rRect.getWidth(), rRect.getHeight()); - - drawBackground(); - - std::vector<Rectangle> aRegions(partitionAndClear(4,3)); - - drawRadialLines(aRegions[0]); - drawText(aRegions[1]); - drawPoly(aRegions[2]); - drawEllipse(aRegions[3]); - drawCheckered(aRegions[4]); - drawBitmapEx(aRegions[5]); - drawBitmap(aRegions[6]); - drawGradient(aRegions[7]); - drawPolyPolgons(aRegions[8]); + drawBackground(rDev); + + std::vector<Rectangle> aRegions(partitionAndClear(rDev, 4, 3)); + + drawRadialLines(rDev, aRegions[0]); + drawText(rDev, aRegions[1]); + drawPoly(rDev, aRegions[2]); + drawEllipse(rDev, aRegions[3]); + drawCheckered(rDev, aRegions[4]); + drawBitmapEx(rDev, aRegions[5]); + drawBitmap(rDev, aRegions[6]); + drawGradient(rDev, aRegions[7]); + drawPolyPolgons(rDev, aRegions[8]); // last - thumbnail all the above - fetchDrawBitmap(aRegions[9]); + fetchDrawBitmap(rDev, aRegions[9]); } class DemoApp : public Application commit 19ddf5f4148499301f2c94e6aafb9582b1811dfd Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Sat Nov 8 13:14:14 2014 -0500 vcl: Initial work to have native widgets rendered with OpenGL Change-Id: I8b244a5bdd12a64a65ca1bab14dfe6917a175ccf diff --git a/include/vcl/opengl/OpenGLHelper.hxx b/include/vcl/opengl/OpenGLHelper.hxx index b237fc8..d49f579 100644 --- a/include/vcl/opengl/OpenGLHelper.hxx +++ b/include/vcl/opengl/OpenGLHelper.hxx @@ -60,6 +60,7 @@ public: #if defined UNX && !defined MACOSX && !defined IOS && !defined ANDROID static bool GetVisualInfo(Display* pDisplay, int nScreen, XVisualInfo& rVI); + static GLXFBConfig GetPixmapFBConfig( Display* pDisplay, bool& bInverted ); #endif }; diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk index 36e52ee..bec6f4c 100644 --- a/vcl/Library_vclplug_gen.mk +++ b/vcl/Library_vclplug_gen.mk @@ -63,6 +63,8 @@ $(eval $(call gb_Library_add_libs,vclplug_gen,\ -lXext \ -lSM \ -lICE \ + -lGL \ + -lGLU \ )) $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\ @@ -104,6 +106,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\ vcl/unx/generic/window/salobj \ vcl/unx/x11/x11sys \ vcl/unx/x11/xlimits \ + vcl/opengl/x11/gdiimpl \ )) # ultimately we want to split the x11 dependencies out diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx new file mode 100644 index 0000000..878c7c2 --- /dev/null +++ b/vcl/inc/opengl/x11/gdiimpl.hxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX +#define INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX + +#include <vcl/dllapi.h> + +#include "unx/salgdi.h" +#include "unx/x11/x11gdiimpl.h" +#include "openglgdiimpl.hxx" + +class VCL_PLUGIN_PUBLIC X11OpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl, public X11GraphicsImpl +{ +private: + X11SalGraphics& mrParent; + +public: + X11OpenGLSalGraphicsImpl( X11SalGraphics& rParent ); + virtual ~X11OpenGLSalGraphicsImpl(); + +protected: + GLfloat GetWidth() const SAL_OVERRIDE; + GLfloat GetHeight() const SAL_OVERRIDE; + +public: + // implementation of X11GraphicsImpl + + void Init() SAL_OVERRIDE; + X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ) SAL_OVERRIDE; + bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE; +}; + +#endif // INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index ef80d34..b05a520 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -30,7 +30,7 @@ class SalVirtualDevice; class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl { -private: +protected: OpenGLContext maContext; SalFrame* mpFrame; @@ -55,9 +55,6 @@ private: GLuint mnMaskUniform; GLuint mnMaskColorUniform; - inline GLfloat GetWidth() const; - inline GLfloat GetHeight() const; - bool CreateSolidProgram( void ); bool CreateTextureProgram( void ); bool CreateMaskedTextureProgram( void ); @@ -81,6 +78,13 @@ private: void DrawTextureWithMask( GLuint nTexture, GLuint nMask, const SalTwoRect& rPosAry ); void DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& rPosAry ); +protected: + // get the width of the device + virtual GLfloat GetWidth() const = 0; + + // get the height of the device + virtual GLfloat GetHeight() const = 0; + public: virtual ~OpenGLSalGraphicsImpl (); @@ -89,9 +93,6 @@ public: virtual void freeResources() SAL_OVERRIDE; - virtual void Init( SalFrame* pFrame ) SAL_OVERRIDE; - virtual void Init( SalVirtualDevice* pVDev ) 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 dc8c580..5d49952 100644 --- a/vcl/inc/salgdiimpl.hxx +++ b/vcl/inc/salgdiimpl.hxx @@ -44,10 +44,6 @@ public: virtual ~SalGraphicsImpl(); - virtual void Init( SalFrame* pFrame ) = 0; - - virtual void Init( SalVirtualDevice* pVDev ) = 0; - virtual void freeResources() = 0; virtual bool setClipRegion( const vcl::Region& ) = 0; diff --git a/vcl/inc/unx/pixmap.hxx b/vcl/inc/unx/pixmap.hxx index f8b23c7..40bc11f 100644 --- a/vcl/inc/unx/pixmap.hxx +++ b/vcl/inc/unx/pixmap.hxx @@ -12,6 +12,7 @@ #include <prex.h> #include <postx.h> +#include <tools/gen.hxx> #include <unx/saltype.h> #include <vclpluginapi.h> @@ -27,6 +28,7 @@ public: Drawable GetDrawable() const { return mpPixmap; }; int GetWidth() const { return mnWidth; }; int GetHeight() const { return mnHeight; }; + Size GetSize() const { return Size( mnWidth, mnHeight ); }; int GetDepth() const { return mnDepth; }; SalX11Screen GetScreen() const { return mnScreen; } diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index 0fa4c00..c288292 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -45,6 +45,7 @@ class SalFrame; class X11Pixmap; class X11SalVirtualDevice; class X11SalGraphicsImpl; +class X11OpenGLSalGraphicsImpl; class PspSalPrinter; class PspSalInfoPrinter; class ServerFont; @@ -63,6 +64,7 @@ class VCLPLUG_GEN_PUBLIC X11SalGraphics : public SalGraphics { friend class ServerFontLayout; friend class X11SalGraphicsImpl; + friend class X11OpenGLSalGraphicsImpl; friend class X11CairoTextRender; private: diff --git a/vcl/inc/unx/x11/x11gdiimpl.h b/vcl/inc/unx/x11/x11gdiimpl.h new file mode 100644 index 0000000..911ea71 --- /dev/null +++ b/vcl/inc/unx/x11/x11gdiimpl.h @@ -0,0 +1,27 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_VCL_INC_UNX_X11_X11GDIIMPL_HXX +#define INCLUDED_VCL_INC_UNX_X11_X11GDIIMPL_HXX + +#include "unx/pixmap.hxx" + +class X11GraphicsImpl +{ +public: + virtual ~X11GraphicsImpl() {}; + + virtual void Init() = 0; + virtual X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ) = 0; + virtual bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) = 0; +}; + +#endif // INCLUDED_VCL_INC_UNX_X11_X11GDIIMPL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 835d344..9288260 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -49,16 +49,6 @@ void OpenGLSalGraphicsImpl::freeResources() // Delete shaders, programs and textures if not shared } -void OpenGLSalGraphicsImpl::Init( SalFrame* pFrame ) -{ - mpFrame = pFrame; -} - -void OpenGLSalGraphicsImpl::Init(SalVirtualDevice* pVDev) -{ - mpVDev = pVDev; -} - bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip ) { const basegfx::B2DPolyPolygon aClip( rClip.GetAsB2DPolyPolygon() ); @@ -94,34 +84,6 @@ long OpenGLSalGraphicsImpl::GetGraphicsWidth() const return GetWidth(); } -inline GLfloat OpenGLSalGraphicsImpl::GetWidth() const -{ - if( mpFrame ) - return mpFrame->maGeometry.nWidth; - else if (mpVDev) - { - long nWidth = 0; - long nHeight = 0; - mpVDev->GetSize(nWidth, nHeight); - return nWidth; - } - return 1; -} - -inline GLfloat OpenGLSalGraphicsImpl::GetHeight() const -{ - if( mpFrame ) - return mpFrame->maGeometry.nHeight; - else if (mpVDev) - { - long nWidth = 0; - long nHeight = 0; - mpVDev->GetSize(nWidth, nHeight); - return nHeight; - } - return 1; -} - // set the clip region to empty void OpenGLSalGraphicsImpl::ResetClipRegion() { diff --git a/vcl/opengl/textureFragmentShader.glsl b/vcl/opengl/textureFragmentShader.glsl index 81d68c7..cc95f2f 100644 --- a/vcl/opengl/textureFragmentShader.glsl +++ b/vcl/opengl/textureFragmentShader.glsl @@ -12,7 +12,7 @@ varying vec2 tex_coord; uniform sampler2D sampler; void main() { - gl_FragColor = texture2D(sampler, tex_coord); + gl_FragColor = texture2D(sampler, tex_coord); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx new file mode 100644 index 0000000..11735edb --- /dev/null +++ b/vcl/opengl/x11/gdiimpl.cxx @@ -0,0 +1,139 @@ +/* -*- 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/. + */ + +#include "vcl/salbtype.hxx" + +#include "unx/pixmap.hxx" +#include "unx/saldisp.hxx" +#include "unx/salframe.h" +#include "unx/salgdi.h" +#include "unx/salvd.h" + +#include "opengl/x11/gdiimpl.hxx" + +#include <vcl/opengl/OpenGLContext.hxx> +#include <vcl/opengl/OpenGLHelper.hxx> + +X11OpenGLSalGraphicsImpl::X11OpenGLSalGraphicsImpl( X11SalGraphics& rParent ): + OpenGLSalGraphicsImpl(), + mrParent(rParent) +{ +} + +X11OpenGLSalGraphicsImpl::~X11OpenGLSalGraphicsImpl() +{ +} + +GLfloat X11OpenGLSalGraphicsImpl::GetWidth() const +{ + if( mrParent.m_pFrame ) + return mrParent.m_pFrame->maGeometry.nWidth; + else if( mrParent.m_pVDev ) + { + long nWidth = 0; + long nHeight = 0; + mrParent.m_pVDev->GetSize( nWidth, nHeight ); + return nWidth; + } + return 1; +} + +GLfloat X11OpenGLSalGraphicsImpl::GetHeight() const +{ + if( mrParent.m_pFrame ) + return mrParent.m_pFrame->maGeometry.nHeight; + else if( mrParent.m_pVDev ) + { + long nWidth = 0; + long nHeight = 0; + mrParent.m_pVDev->GetSize( nWidth, nHeight ); + return nHeight; + } + return 1; +} + +void X11OpenGLSalGraphicsImpl::Init() +{ + if( mrParent.m_pFrame && dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame) ) + { + Window aWin = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame)->GetX11Window(); + maContext.init( mrParent.GetXDisplay(), aWin, mrParent.m_nXScreen.getXScreen()); + } + else if( mrParent.m_pVDev ) + { + maContext.init( mrParent.GetXDisplay(), mrParent.m_pVDev->GetDrawable(), + mrParent.m_pVDev->GetWidth(), mrParent.m_pVDev->GetHeight(), + mrParent.m_nXScreen.getXScreen() ); + } + else + { + SAL_WARN( "vcl.opengl", "what happened here?" ); + } +} + +X11Pixmap* X11OpenGLSalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect ) +{ + Display* pDisplay = mrParent.GetXDisplay(); + SalX11Screen nScreen = mrParent.GetScreenNumber(); + + SAL_INFO( "vcl.opengl", "GetPixmapFromScreen" ); + return new X11Pixmap( pDisplay, nScreen, rRect.GetWidth(), rRect.GetHeight(), 24 ); +} + +bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) +{ + const int aAttribs[] = { + GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, + GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, + None + }; + Display* pDisplay = mrParent.GetXDisplay(); + GLXFBConfig pFbConfig; + GLXPixmap pGlxPixmap; + GLuint nTexture; + SalTwoRect aPosAry; + bool bInverted; + + SAL_INFO( "vcl.opengl", "RenderPixmapToScreen (" << nX << " " << nY << ")" ); + + aPosAry.mnSrcX = 0; + aPosAry.mnSrcY = 0; + aPosAry.mnDestX = nX; + aPosAry.mnDestY = nY; + aPosAry.mnSrcWidth = aPosAry.mnDestWidth = pPixmap->GetWidth(); + aPosAry.mnSrcHeight = aPosAry.mnDestHeight = pPixmap->GetHeight(); + + XSync( pDisplay, 0 ); + pFbConfig = OpenGLHelper::GetPixmapFBConfig( pDisplay, bInverted ); + pGlxPixmap = glXCreatePixmap( pDisplay, pFbConfig, pPixmap->GetPixmap(), aAttribs); + XSync( pDisplay, 0 ); + + maContext.makeCurrent(); + glViewport( 0, 0, GetWidth(), GetHeight() ); + + glGenTextures( 1, &nTexture ); + glActiveTexture( GL_TEXTURE0 ); + glBindTexture( GL_TEXTURE_2D, nTexture ); + + //TODO: lfrb: glXGetProc to get the functions + glXBindTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT, NULL ); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + DrawTexture( nTexture, pPixmap->GetSize(), aPosAry ); + + glXReleaseTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT ); + glDeleteTextures( 1, &nTexture ); + glXDestroyPixmap( pDisplay, pGlxPixmap ); + + return true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx index 4705e3f..5823b80 100644 --- a/vcl/source/opengl/OpenGLHelper.cxx +++ b/vcl/source/opengl/OpenGLHelper.cxx @@ -387,6 +387,56 @@ bool OpenGLHelper::GetVisualInfo(Display* pDisplay, int nScreen, XVisualInfo& rV return true; } +GLXFBConfig OpenGLHelper::GetPixmapFBConfig( Display* pDisplay, bool& bInverted ) +{ + int nScreen = DefaultScreen( pDisplay ); + GLXFBConfig *aFbConfigs; + int i, nFbConfigs, nValue; + + aFbConfigs = glXGetFBConfigs( pDisplay, nScreen, &nFbConfigs ); + for( i = 0; i < nFbConfigs; i++ ) + { + glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_DRAWABLE_TYPE, &nValue ); + if( !(nValue & GLX_PIXMAP_BIT) ) + continue; + + glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &nValue ); + if( !(nValue & GLX_TEXTURE_2D_BIT_EXT) ) + continue; + + glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_DEPTH_SIZE, &nValue ); + if( nValue != 24 ) + continue; + + glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_RED_SIZE, &nValue ); + if( nValue != 8 ) + continue; + SAL_INFO( "vcl.opengl", "Red is " << nValue ); + + // TODO: lfrb: Make it configurable wrt RGB/RGBA + glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_BIND_TO_TEXTURE_RGB_EXT, &nValue ); + if( nValue == False ) + { + glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_BIND_TO_TEXTURE_RGBA_EXT, &nValue ); + if( nValue == False ) + continue; + } + + glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_Y_INVERTED_EXT, &nValue ); + bInverted = (nValue == True) ? true : false; + + break; + } + + if( i == nFbConfigs ) + { + SAL_WARN( "vcl.opengl", "Unable to find FBconfig for pixmap texturing" ); + return 0; + } + + return aFbConfigs[i]; +} + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx index f2ccf90..172ebd6 100644 --- a/vcl/unx/generic/gdi/gdiimpl.cxx +++ b/vcl/unx/generic/gdi/gdiimpl.cxx @@ -153,16 +153,69 @@ X11SalGraphicsImpl::~X11SalGraphicsImpl() { } -void X11SalGraphicsImpl::Init( SalFrame* /*pFrame*/ ) +void X11SalGraphicsImpl::Init() { mnPenPixel = mrParent.GetPixel( mnPenColor ); mnBrushPixel = mrParent.GetPixel( mnBrushColor ); } -void X11SalGraphicsImpl::Init( SalVirtualDevice* /*pVDev*/ ) +X11Pixmap* X11SalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect ) { - mnPenPixel = mrParent.GetPixel( mnPenColor ); - mnBrushPixel = mrParent.GetPixel( mnBrushColor ); + //TODO lfrb: don't hardcode the depth + Display* pDpy = mrParent.GetXDisplay(); + X11Pixmap* pPixmap = new X11Pixmap( pDpy, mrParent.GetScreenNumber(), + rRect.GetWidth(), rRect.GetHeight(), 24 ); + GC aTmpGC = XCreateGC( pDpy, pPixmap->GetPixmap(), 0, NULL ); + + if( !pPixmap || !aTmpGC ) + { + if ( pPixmap ) + delete pPixmap; + if ( aTmpGC ) + XFreeGC( pDpy, aTmpGC ); + SAL_WARN( "vcl", "Could not get valid pixmap from screen" ); + return NULL; + } + + // Copy the background of the screen into a composite pixmap + mrParent.CopyScreenArea( mrParent.GetXDisplay(), + mrParent.GetDrawable(), mrParent.GetScreenNumber(), + mrParent.GetVisual().GetDepth(), + pPixmap->GetDrawable(), pPixmap->GetScreen(), + pPixmap->GetDepth(), + aTmpGC, + rRect.Left(), rRect.Top(), + rRect.GetWidth(), rRect.GetHeight(), + 0, 0 ); + + XFreeGC( pDpy, aTmpGC ); + return pPixmap; +} + +bool X11SalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) +{ + GC aFontGC = mrParent.GetFontGC(); + + // The GC can't be null, otherwise we'd have no clip region + if( aFontGC == NULL ) + { + SAL_WARN( "vcl", "no valid GC to render pixmap" ); + return false; + } + + if( !pPixmap ) + return false; + + mrParent.CopyScreenArea( mrParent.GetXDisplay(), + pPixmap->GetDrawable(), pPixmap->GetScreen(), + pPixmap->GetDepth(), + mrParent.GetDrawable(), mrParent.m_nXScreen, + mrParent.GetVisual().GetDepth(), + aFontGC, + 0, 0, + pPixmap->GetWidth(), pPixmap->GetHeight(), + nX, nY ); + return true; } XID X11SalGraphicsImpl::GetXRenderPicture() diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx index 799e05c..252fe35 100644 --- a/vcl/unx/generic/gdi/gdiimpl.hxx +++ b/vcl/unx/generic/gdi/gdiimpl.hxx @@ -24,6 +24,7 @@ #include <postx.h> #include "unx/saltype.h" +#include "unx/x11/x11gdiimpl.h" #include "salgdiimpl.hxx" @@ -35,10 +36,8 @@ class SalPolyLine; class X11SalGraphics; class Gradient; -class X11SalGraphicsImpl : public SalGraphicsImpl +class X11SalGraphicsImpl : public SalGraphicsImpl, public X11GraphicsImpl { - friend X11SalGraphics; - private: X11SalGraphics& mrParent; @@ -108,10 +107,6 @@ public: virtual ~X11SalGraphicsImpl(); - virtual void Init( SalFrame* pFrame ) SAL_OVERRIDE; - - virtual void Init( SalVirtualDevice* pVDev ) SAL_OVERRIDE; - virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE; // // get the depth of the device @@ -269,6 +264,13 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) SAL_OVERRIDE; virtual bool swapBuffers() SAL_OVERRIDE { return false; } + +public: + // implementation of X11GraphicsImpl + + void Init() SAL_OVERRIDE; + X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ) SAL_OVERRIDE; + bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE; }; #endif diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx index 0607cac..b4df486 100644 --- a/vcl/unx/generic/gdi/salgdi.cxx +++ b/vcl/unx/generic/gdi/salgdi.cxx @@ -48,13 +48,14 @@ #include "unx/salgdi.h" #include "unx/salframe.h" #include "unx/salvd.h" +#include "unx/x11/x11gdiimpl.h" #include <unx/x11/xlimits.hxx> #include "salgdiimpl.hxx" #include "unx/x11windowprovider.hxx" #include "textrender.hxx" #include "gdiimpl.hxx" -#include "openglgdiimpl.hxx" +#include "opengl/x11/gdiimpl.hxx" #include "x11cairotextrender.hxx" #include "generic/printergfx.hxx" @@ -86,7 +87,7 @@ X11SalGraphics::X11SalGraphics(): static bool bOpenGLPossible = OpenGLHelper::supportsVCLOpenGL(); bool bUseOpenGL = bOpenGLPossible ? officecfg::Office::Common::VCL::UseOpenGL::get() : false; if (bUseOpenGL) - mpImpl.reset(new OpenGLSalGraphicsImpl()); + mpImpl.reset(new X11OpenGLSalGraphicsImpl(*this)); else mpImpl.reset(new X11SalGraphicsImpl(*this)); @@ -142,26 +143,7 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen ) if( hDrawable_ ) { - OpenGLSalGraphicsImpl* pOpenGLImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(mpImpl.get()); - if (pOpenGLImpl) - { - if (m_pFrame && dynamic_cast<X11WindowProvider*>(m_pFrame)) - { - Window aWin = dynamic_cast<X11WindowProvider*>(m_pFrame)->GetX11Window(); - pOpenGLImpl->GetOpenGLContext().init(GetXDisplay(), - aWin, m_nXScreen.getXScreen()); - mpImpl->Init( m_pFrame ); - } - else if (m_pVDev) - { - pOpenGLImpl->GetOpenGLContext().init(GetXDisplay(), - m_pVDev->GetDrawable(), m_pVDev->GetWidth(), m_pVDev->GetHeight(), m_nXScreen.getXScreen()); - mpImpl->Init(m_pVDev); - } - else - SAL_WARN("vcl.opengl", "what happened here?"); - } - + dynamic_cast<X11GraphicsImpl*>(mpImpl.get())->Init(); // TODO: moggi: FIXME nTextPixel_ = GetPixel( nTextColor_ ); } } diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx index e4d5b3c..63ab32b 100644 --- a/vcl/unx/generic/gdi/salgdi2.cxx +++ b/vcl/unx/generic/gdi/salgdi2.cxx @@ -31,6 +31,7 @@ #include "unx/salgdi.h" #include "unx/salframe.h" #include "unx/salvd.h" +#include "unx/x11/x11gdiimpl.h" #include <unx/x11/xlimits.hxx> #include "xrender_peer.hxx" @@ -84,59 +85,15 @@ void X11SalGraphics::CopyScreenArea( Display* pDisplay, X11Pixmap* X11SalGraphics::GetPixmapFromScreen( const Rectangle& rRect ) { - Display* pDpy = GetXDisplay(); - X11Pixmap* pPixmap = new X11Pixmap( pDpy, GetScreenNumber(), rRect.GetWidth(), rRect.GetHeight(), 24 ); - GC aTmpGC = XCreateGC( pDpy, pPixmap->GetPixmap(), 0, NULL ); - - if( !pPixmap || !aTmpGC ) - { - if ( pPixmap ) - delete pPixmap; - if ( aTmpGC ) - XFreeGC( pDpy, aTmpGC ); - SAL_WARN( "vcl", "Could not get valid pixmap from screen" ); - return NULL; - } - - // Copy the background of the screen into a composite pixmap - CopyScreenArea( GetXDisplay(), - GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(), - pPixmap->GetDrawable(), pPixmap->GetScreen(), pPixmap->GetDepth(), - aTmpGC, - rRect.Left(), rRect.Top(), rRect.GetWidth(), rRect.GetHeight(), 0, 0 ); - - XFreeGC( pDpy, aTmpGC ); - return pPixmap; + X11GraphicsImpl* pImpl = dynamic_cast<X11GraphicsImpl*>(mpImpl.get()); + return pImpl->GetPixmapFromScreen( rRect ); } bool X11SalGraphics::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) { SAL_INFO( "vcl", "RenderPixmapToScreen" ); - /*if( UseOpenGL() ) - { - X11OpenGLTexture pTexture( pPixmap ); - pTexture.Draw( nX, nY ); - return true; - }*/ - - GC aFontGC = GetFontGC(); - - // The GC can't be null, otherwise we'd have no clip region - if( aFontGC == NULL ) - { - SAL_WARN( "vcl", "no valid GC to render pixmap" ); - return false; - } - - if( !pPixmap ) - return false; - - CopyScreenArea( GetXDisplay(), - pPixmap->GetDrawable(), pPixmap->GetScreen(), pPixmap->GetDepth(), - GetDrawable(), m_nXScreen, GetVisual().GetDepth(), - aFontGC, - 0, 0, pPixmap->GetWidth(), pPixmap->GetHeight(), nX, nY ); - return true; + X11GraphicsImpl* pImpl = dynamic_cast<X11GraphicsImpl*>(mpImpl.get()); + return pImpl->RenderPixmapToScreen( pPixmap, nX, nY ); } extern "C" commit 969e75db2c230cbac21ada63acaf8d2bd1d44681 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Fri Nov 7 17:29:44 2014 -0500 vcl: Add GetPixmapFromScreen and RenderPixmapToScreen to X11SalGraphics Change-Id: I007408885b5752f3abf55075ef025aa6dacbabde diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk index fe9f4f6..36e52ee 100644 --- a/vcl/Library_vclplug_gen.mk +++ b/vcl/Library_vclplug_gen.mk @@ -92,6 +92,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\ vcl/unx/generic/gdi/x11cairotextrender \ vcl/unx/generic/gdi/gcach_xpeer \ vcl/unx/generic/gdi/gdiimpl \ + vcl/unx/generic/gdi/pixmap \ vcl/unx/generic/gdi/salbmp \ vcl/unx/generic/gdi/salgdi2 \ vcl/unx/generic/gdi/salgdi3 \ diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx index b8b145b..05d763c 100644 --- a/vcl/inc/unx/gtk/gtkgdi.hxx +++ b/vcl/inc/unx/gtk/gtkgdi.hxx @@ -114,6 +114,7 @@ private: #else +class GdkX11Pixmap; class GtkSalGraphics : public X11SalGraphics { GtkWidget *m_pWindow; @@ -162,8 +163,8 @@ public: protected: typedef std::list< Rectangle > clipList; - GdkPixmap* NWGetPixmapFromScreen( Rectangle srcRect ); - bool NWRenderPixmapToScreen( GdkPixmap* pPixmap, Rectangle dstRect ); + GdkX11Pixmap* NWGetPixmapFromScreen( Rectangle srcRect ); + bool NWRenderPixmapToScreen( GdkX11Pixmap* pPixmap, Rectangle dstRect ); bool NWPaintGTKArrow( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart, const Rectangle& rControlRectangle, diff --git a/vcl/inc/unx/pixmap.hxx b/vcl/inc/unx/pixmap.hxx new file mode 100644 index 0000000..f8b23c7 --- /dev/null +++ b/vcl/inc/unx/pixmap.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_VCL_INC_UNX_PIXMAP_HXX +#define INCLUDED_VCL_INC_UNX_PIXMAP_HXX + +#include <prex.h> +#include <postx.h> +#include <unx/saltype.h> +#include <vclpluginapi.h> + +class VCLPLUG_GEN_PUBLIC X11Pixmap +{ +public: + X11Pixmap(); + X11Pixmap( Display *pDisplay, SalX11Screen nScreen, int nWidth, int nHeight, int nDepth ); + X11Pixmap( X11Pixmap& rOther ); + virtual ~X11Pixmap(); + + Pixmap GetPixmap() const { return mpPixmap; }; + Drawable GetDrawable() const { return mpPixmap; }; + int GetWidth() const { return mnWidth; }; + int GetHeight() const { return mnHeight; }; + int GetDepth() const { return mnDepth; }; + SalX11Screen GetScreen() const { return mnScreen; } + +protected: + Display* mpDisplay; + SalX11Screen mnScreen; + Pixmap mpPixmap; + int mnWidth; + int mnHeight; + int mnDepth; +}; + +#endif // INCLUDED_VCL_INC_UNX_PIXMAP_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index b4e05bc..0fa4c00 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -42,6 +42,7 @@ class SalBitmap; class SalColormap; class SalDisplay; class SalFrame; +class X11Pixmap; class X11SalVirtualDevice; class X11SalGraphicsImpl; class PspSalPrinter; @@ -264,6 +265,13 @@ public: virtual bool SwapBuffers() SAL_OVERRIDE; + // create a pixmap from a screen region + X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ); + + // render a pixmap to the screen + bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ); + + /* use to handle GraphicsExpose/NoExpose after XCopyArea & friends * if pFrame is not NULL, corresponding Paint events are generated * and dispatched to pFrame diff --git a/vcl/unx/generic/gdi/pixmap.cxx b/vcl/unx/generic/gdi/pixmap.cxx new file mode 100644 index 0000000..beb5589 --- /dev/null +++ b/vcl/unx/generic/gdi/pixmap.cxx @@ -0,0 +1,49 @@ +/* -*- 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/. + */ + +#include "unx/pixmap.hxx" + +X11Pixmap::X11Pixmap() +: mpDisplay( NULL ) +, mnScreen( 0 ) +, mnWidth( -1 ) +, mnHeight( -1 ) +, mnDepth( 0 ) +{ +} + +X11Pixmap::X11Pixmap( Display* pDisplay, SalX11Screen nScreen, int nWidth, int nHeight, int nDepth ) +: mpDisplay( pDisplay ) +, mnScreen( nScreen ) +, mnWidth( nWidth ) +, mnHeight( nHeight ) +, mnDepth( nDepth ) +{ + Window root = RootWindow( pDisplay, 0 ); + mpPixmap = XCreatePixmap( pDisplay, root, nWidth, nHeight, nDepth ); +} + +X11Pixmap::X11Pixmap( X11Pixmap& rOther ) +: mpDisplay( rOther.mpDisplay ) +, mnScreen( rOther.mnScreen ) +, mnWidth( rOther.mnWidth ) +, mnHeight( rOther.mnHeight ) +, mnDepth( rOther.mnDepth ) +{ + mpPixmap = rOther.mpPixmap; + rOther.mpPixmap = 0; +} + +X11Pixmap::~X11Pixmap() +{ + if( mpPixmap ) + XFreePixmap( mpDisplay, mpPixmap ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx index aa2732a..e4d5b3c 100644 --- a/vcl/unx/generic/gdi/salgdi2.cxx +++ b/vcl/unx/generic/gdi/salgdi2.cxx @@ -23,6 +23,7 @@ #include "vcl/salbtype.hxx" +#include "unx/pixmap.hxx" #include "unx/salunx.h" #include "unx/saldata.hxx" #include "unx/saldisp.hxx" @@ -81,6 +82,63 @@ void X11SalGraphics::CopyScreenArea( Display* pDisplay, } } +X11Pixmap* X11SalGraphics::GetPixmapFromScreen( const Rectangle& rRect ) +{ + Display* pDpy = GetXDisplay(); + X11Pixmap* pPixmap = new X11Pixmap( pDpy, GetScreenNumber(), rRect.GetWidth(), rRect.GetHeight(), 24 ); + GC aTmpGC = XCreateGC( pDpy, pPixmap->GetPixmap(), 0, NULL ); + + if( !pPixmap || !aTmpGC ) + { + if ( pPixmap ) + delete pPixmap; + if ( aTmpGC ) + XFreeGC( pDpy, aTmpGC ); + SAL_WARN( "vcl", "Could not get valid pixmap from screen" ); + return NULL; + } + + // Copy the background of the screen into a composite pixmap + CopyScreenArea( GetXDisplay(), + GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(), + pPixmap->GetDrawable(), pPixmap->GetScreen(), pPixmap->GetDepth(), + aTmpGC, + rRect.Left(), rRect.Top(), rRect.GetWidth(), rRect.GetHeight(), 0, 0 ); + + XFreeGC( pDpy, aTmpGC ); + return pPixmap; +} + +bool X11SalGraphics::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) +{ + SAL_INFO( "vcl", "RenderPixmapToScreen" ); + /*if( UseOpenGL() ) + { + X11OpenGLTexture pTexture( pPixmap ); + pTexture.Draw( nX, nY ); + return true; + }*/ + + GC aFontGC = GetFontGC(); + + // The GC can't be null, otherwise we'd have no clip region + if( aFontGC == NULL ) + { + SAL_WARN( "vcl", "no valid GC to render pixmap" ); + return false; + } + + if( !pPixmap ) + return false; + + CopyScreenArea( GetXDisplay(), + pPixmap->GetDrawable(), pPixmap->GetScreen(), pPixmap->GetDepth(), + GetDrawable(), m_nXScreen, GetVisual().GetDepth(), + aFontGC, + 0, 0, pPixmap->GetWidth(), pPixmap->GetHeight(), nX, nY ); + return true; +} + extern "C" { static Bool GraphicsExposePredicate( Display*, XEvent* pEvent, XPointer pFrameWindow ) diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index bab4f5c..50cb193 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -26,6 +26,7 @@ #include "unx/gtk/gtkinst.hxx" #include "unx/gtk/gtkgdi.hxx" +#include "unx/pixmap.hxx" #include "unx/saldata.hxx" #include "unx/saldisp.hxx" @@ -257,6 +258,71 @@ static int getFrameWidth(GtkWidget* widget); static Rectangle NWGetScrollButtonRect( SalX11Screen nScreen, ControlPart nPart, Rectangle aAreaRect ); + +/************************************************************************ + * GDK implementation of X11Pixmap + ************************************************************************/ + +class GdkX11Pixmap : public X11Pixmap +{ +public: + GdkX11Pixmap( int nWidth, int nHeight, int nDepth ); + GdkX11Pixmap( X11Pixmap& rOther, GdkWindow *pWindow ); + virtual ~GdkX11Pixmap(); + + GdkPixmap* GetGdkPixmap() const; + GdkDrawable* GetGdkDrawable() const; + +protected: + GdkPixmap* mpGdkPixmap; +}; + +GdkX11Pixmap::GdkX11Pixmap( int nWidth, int nHeight, int nDepth ) +{ + mpGdkPixmap = gdk_pixmap_new( NULL, nWidth, nHeight, nDepth ); + + //mpDisplay = ? + mnScreen = SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(mpGdkPixmap) ) ) ); + mnWidth = nWidth; + mnHeight = nHeight; + mnDepth = nDepth; + mpPixmap = GDK_PIXMAP_XID( mpGdkPixmap ); +} + +GdkX11Pixmap::GdkX11Pixmap( X11Pixmap& rOther, GdkWindow *pWindow ) +: X11Pixmap( rOther ) +{ + GdkColormap* pColormap; + +#if GTK_CHECK_VERSION(2,10,0) + GdkScreen *pScreen = gdk_window_get_screen( pWindow ); + mpGdkPixmap = gdk_pixmap_foreign_new_for_screen( pScreen, mpPixmap, + mnWidth, mnHeight, + mnDepth ); +#else + mpGdkPixmap = gdk_pixmap_foreign_new( mpPixmap ); +#endif + + pColormap = gdk_drawable_get_colormap( pWindow ); + gdk_drawable_set_colormap( GDK_DRAWABLE (mpGdkPixmap), pColormap ); +} + +GdkX11Pixmap::~GdkX11Pixmap() +{ + g_object_unref( mpGdkPixmap ); +} + +GdkPixmap* GdkX11Pixmap::GetGdkPixmap() const +{ + return mpGdkPixmap; +} + +GdkDrawable* GdkX11Pixmap::GetGdkDrawable() const +{ + return GDK_DRAWABLE( mpGdkPixmap ); +} + + /********************************************************* * PixmapCache *********************************************************/ @@ -271,13 +337,13 @@ class NWPixmapCacheData public: ControlType m_nType; ControlState m_nState; - Rectangle m_pixmapRect; - GdkPixmap* m_pixmap; + Rectangle m_pixmapRect; + GdkX11Pixmap* m_pixmap; NWPixmapCacheData() : m_nType(0), m_nState(0), m_pixmap(0) {} ~NWPixmapCacheData() { SetPixmap( NULL ); }; - void SetPixmap( GdkPixmap* pPixmap ); + void SetPixmap( GdkX11Pixmap* pPixmap ); }; class NWPixmapCache @@ -294,8 +360,8 @@ public: { delete [] pData; m_idx = 0; m_size = n; pData = new NWPixmapCacheData[m_size]; } int GetSize() const { return m_size; } - bool Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap** pPixmap ); - void Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap* pPixmap ); + bool Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkX11Pixmap** pPixmap ); + void Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkX11Pixmap* pPixmap ); void ThemeChanged(); }; @@ -312,15 +378,12 @@ public: // --- implementation --- -void NWPixmapCacheData::SetPixmap( GdkPixmap* pPixmap ) +void NWPixmapCacheData::SetPixmap( GdkX11Pixmap* pPixmap ) { if( m_pixmap ) - g_object_unref( m_pixmap ); + delete m_pixmap; m_pixmap = pPixmap; - - if( m_pixmap ) - g_object_ref( m_pixmap ); } NWPixmapCache::NWPixmapCache( SalX11Screen nScreen ) @@ -346,7 +409,7 @@ void NWPixmapCache::ThemeChanged() pData[i].SetPixmap( NULL ); } -bool NWPixmapCache::Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap** pPixmap ) +bool NWPixmapCache::Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkX11Pixmap** pPixmap ) { aState &= ~CTRL_CACHING_ALLOWED; // mask clipping flag int i; @@ -365,7 +428,7 @@ bool NWPixmapCache::Find( ControlType aType, ControlState aState, const Rectang return false; } -void NWPixmapCache::Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap* pPixmap ) +void NWPixmapCache::Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkX11Pixmap* pPixmap ) { if( !(aState & CTRL_CACHING_ALLOWED) ) return; @@ -801,7 +864,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, clipList aClip; GdkDrawable* gdkDrawable = GDK_DRAWABLE( GetGdkWindow() ); - GdkPixmap* pixmap = NULL; + GdkX11Pixmap* pixmap = NULL; Rectangle aPixmapRect; if( ( bNeedPixmapPaint ) && nType != CTRL_SCROLLBAR @@ -819,7 +882,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, pixmap = NWGetPixmapFromScreen( aPixmapRect ); if( ! pixmap ) return false; - gdkDrawable = GDK_DRAWABLE( pixmap ); + gdkDrawable = pixmap->GetGdkDrawable(); aCtrlRect = Rectangle( Point(1,1), aCtrlRect.GetSize() ); aClip.push_back( aCtrlRect ); } @@ -956,7 +1019,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, if( pixmap ) { returnVal = NWRenderPixmapToScreen( pixmap, aPixmapRect ) && returnVal; - g_object_unref( pixmap ); + delete pixmap; } return( returnVal ); @@ -1742,7 +1805,7 @@ bool GtkSalGraphics::NWPaintGTKScrollbar( ControlType, ControlPart nPart, { assert(aValue.getType() == CTRL_SCROLLBAR); const ScrollbarValue& rScrollbarVal = static_cast<const ScrollbarValue&>(aValue); - GdkPixmap* pixmap = NULL; + GdkX11Pixmap* pixmap = NULL; Rectangle pixmapRect, scrollbarRect; GtkStateType stateType; GtkShadowType shadowType; @@ -1930,7 +1993,7 @@ bool GtkSalGraphics::NWPaintGTKScrollbar( ControlType, ControlPart nPart, w = pixmapRect.GetWidth(); h = pixmapRect.GetHeight(); - GdkDrawable* const &gdkDrawable = GDK_DRAWABLE( pixmap ); + GdkDrawable* const &gdkDrawable = pixmap->GetGdkDrawable(); GdkRectangle* gdkRect = NULL; NWConvertVCLStateToGTKState( nState, &stateType, &shadowType ); @@ -2051,14 +2114,10 @@ bool GtkSalGraphics::NWPaintGTKScrollbar( ControlType, ControlPart nPart, arrowRect.GetWidth(), arrowRect.GetHeight() ); } - if( !NWRenderPixmapToScreen(pixmap, pixmapRect) ) - { - g_object_unref( pixmap ); - return false; - } - g_object_unref( pixmap ); + bool bRet = NWRenderPixmapToScreen( pixmap, pixmapRect ); + delete pixmap; - return true; + return bRet; } static Rectangle NWGetScrollButtonRect( SalX11Screen nScreen, ControlPart nPart, Rectangle aAreaRect ) @@ -2282,7 +2341,8 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart, const ImplControlValue& aValue, const OUString& rCaption ) { - GdkPixmap * pixmap; + GdkX11Pixmap * pixmap; + GdkPixmap * gdkPixmap; Rectangle pixmapRect; GtkStateType stateType; GtkShadowType shadowType; @@ -2326,9 +2386,10 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart, pixmap = NWGetPixmapFromScreen( pixmapRect ); if ( !pixmap ) return false; + gdkPixmap = pixmap->GetGdkPixmap(); // First render background - gtk_paint_flat_box(m_pWindow->style,pixmap,GTK_STATE_NORMAL,GTK_SHADOW_NONE,NULL,m_pWindow,"base", + gtk_paint_flat_box(m_pWindow->style,gdkPixmap,GTK_STATE_NORMAL,GTK_SHADOW_NONE,NULL,m_pWindow,"base", -pixmapRect.Left(), -pixmapRect.Top(), pixmapRect.Right(), @@ -2348,7 +2409,7 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart, aEditBoxRect.setX( 0 ); aEditBoxRect.setY( 0 ); - NWPaintOneEditBox( m_nXScreen, pixmap, NULL, nType, nPart, aEditBoxRect, nState, aValue, rCaption ); + NWPaintOneEditBox( m_nXScreen, gdkPixmap, NULL, nType, nPart, aEditBoxRect, nState, aValue, rCaption ); } NWSetWidgetState( gWidgetData[m_nXScreen].gSpinButtonWidget, nState, stateType ); @@ -2359,23 +2420,19 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart, Rectangle shadowRect( upBtnRect ); shadowRect.Union( downBtnRect ); - gtk_paint_box( gWidgetData[m_nXScreen].gSpinButtonWidget->style, pixmap, GTK_STATE_NORMAL, shadowType, NULL, + gtk_paint_box( gWidgetData[m_nXScreen].gSpinButtonWidget->style, gdkPixmap, GTK_STATE_NORMAL, shadowType, NULL, gWidgetData[m_nXScreen].gSpinButtonWidget, "spinbutton", (shadowRect.Left() - pixmapRect.Left()), (shadowRect.Top() - pixmapRect.Top()), shadowRect.GetWidth(), shadowRect.GetHeight() ); } - NWPaintOneSpinButton( m_nXScreen, pixmap, nType, upBtnPart, pixmapRect, upBtnState, aValue, rCaption ); - NWPaintOneSpinButton( m_nXScreen, pixmap, nType, downBtnPart, pixmapRect, downBtnState, aValue, rCaption ); + NWPaintOneSpinButton( m_nXScreen, gdkPixmap, nType, upBtnPart, pixmapRect, upBtnState, aValue, rCaption ); + NWPaintOneSpinButton( m_nXScreen, gdkPixmap, nType, downBtnPart, pixmapRect, downBtnState, aValue, rCaption ); - if( !NWRenderPixmapToScreen(pixmap, pixmapRect) ) - { - g_object_unref( pixmap ); - return false; - } + bool bRet = NWRenderPixmapToScreen( pixmap, pixmapRect ); + delete pixmap; - g_object_unref( pixmap ); - return true; + return bRet; } static Rectangle NWGetSpinButtonRect( SalX11Screen nScreen, @@ -2609,7 +2666,8 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart, const OUString& ) { OSL_ASSERT( nType != CTRL_TAB_ITEM || aValue.getType() == CTRL_TAB_ITEM ); - GdkPixmap * pixmap; + GdkX11Pixmap * pixmap; + GdkPixmap * gdkPixmap; Rectangle pixmapRect; Rectangle tabRect; GtkStateType stateType; @@ -2681,14 +2739,15 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart, return NWRenderPixmapToScreen( pixmap, pixmapRect ); } - pixmap = gdk_pixmap_new( NULL, pixmapRect.GetWidth(), pixmapRect.GetHeight(), - GetGenericData()->GetSalDisplay()->GetVisual( m_nXScreen ).GetDepth() ); + pixmap = new GdkX11Pixmap( pixmapRect.GetWidth(), pixmapRect.GetHeight(), + GetGenericData()->GetSalDisplay()->GetVisual( m_nXScreen ).GetDepth() ); + gdkPixmap = pixmap->GetGdkPixmap(); GdkRectangle paintRect; paintRect.x = paintRect.y = 0; paintRect.width = pixmapRect.GetWidth(); paintRect.height = pixmapRect.GetHeight(); - gtk_paint_flat_box( m_pWindow->style, pixmap, GTK_STATE_NORMAL, + gtk_paint_flat_box( m_pWindow->style, gdkPixmap, GTK_STATE_NORMAL, GTK_SHADOW_NONE, &paintRect, m_pWindow, "base", -rControlRectangle.Left(), -rControlRectangle.Top(), @@ -2703,7 +2762,7 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart, break; case CTRL_TAB_PANE: - gtk_paint_box_gap( gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget, + gtk_paint_box_gap( gWidgetData[m_nXScreen].gNotebookWidget->style, gdkPixmap, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget, (char *)"notebook", 0, 0, pixmapRect.GetWidth(), pixmapRect.GetHeight(), GTK_POS_TOP, 0, 0 ); break; @@ -2712,7 +2771,7 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart, stateType = ( nState & CTRL_STATE_SELECTED ) ? GTK_STATE_NORMAL : GTK_STATE_ACTIVE; // First draw the background - gtk_paint_flat_box(gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap, + gtk_paint_flat_box(gWidgetData[m_nXScreen].gNotebookWidget->style, gdkPixmap, GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, m_pWindow, "base", -rControlRectangle.Left(), -rControlRectangle.Top(), @@ -2721,17 +2780,17 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart, // Now the tab itself if( nState & CTRL_STATE_ROLLOVER ) - g_object_set_data(G_OBJECT(pixmap),tabPrelitDataName,reinterpret_cast<gpointer>(TRUE)); + g_object_set_data(G_OBJECT(gdkPixmap),tabPrelitDataName,reinterpret_cast<gpointer>(TRUE)); - gtk_paint_extension( gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap, stateType, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget, + gtk_paint_extension( gWidgetData[m_nXScreen].gNotebookWidget->style, gdkPixmap, stateType, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget, (char *)"tab", (tabRect.Left() - pixmapRect.Left()), (tabRect.Top() - pixmapRect.Top()), tabRect.GetWidth(), tabRect.GetHeight(), GTK_POS_BOTTOM ); - g_object_steal_data(G_OBJECT(pixmap),tabPrelitDataName); + g_object_steal_data(G_OBJECT(gdkPixmap),tabPrelitDataName); if ( nState & CTRL_STATE_SELECTED ) { - gtk_paint_flat_box( m_pWindow->style, pixmap, stateType, GTK_SHADOW_NONE, NULL, m_pWindow, + gtk_paint_flat_box( m_pWindow->style, gdkPixmap, stateType, GTK_SHADOW_NONE, NULL, m_pWindow, "base", 0, (pixmapRect.GetHeight() - 1), pixmapRect.GetWidth(), 1 ); } break; @@ -2747,8 +2806,7 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart, else aCachePage.Fill( nType, nState, pixmapRect, pixmap ); - bool bSuccess = NWRenderPixmapToScreen(pixmap, pixmapRect); - g_object_unref( pixmap ); + bool bSuccess = NWRenderPixmapToScreen( pixmap, pixmapRect ); return bSuccess; } @@ -3324,11 +3382,11 @@ bool GtkSalGraphics::NWPaintGTKListNode( break; } - GdkPixmap* pixmap = NWGetPixmapFromScreen( aRect ); + GdkX11Pixmap* pixmap = NWGetPixmapFromScreen( aRect ); if( ! pixmap ) return false; - GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap ); + GdkDrawable* const &pixDrawable = pixmap->GetGdkDrawable(); gtk_paint_expander( gWidgetData[m_nXScreen].gTreeView->style, pixDrawable, stateType, @@ -3339,7 +3397,7 @@ bool GtkSalGraphics::NWPaintGTKListNode( eStyle ); bool bRet = NWRenderPixmapToScreen( pixmap, aRect ); - g_object_unref( pixmap ); + delete pixmap; return bRet; } @@ -3360,11 +3418,11 @@ bool GtkSalGraphics::NWPaintGTKProgress( long nProgressWidth = rValue.getNumericVal(); - GdkPixmap* pixmap = NWGetPixmapFromScreen( Rectangle( Point( 0, 0 ), Size( w, h ) ) ); + GdkX11Pixmap* pixmap = NWGetPixmapFromScreen( Rectangle( Point( 0, 0 ), Size( w, h ) ) ); if( ! pixmap ) return false; - GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap ); + GdkDrawable* const &pixDrawable = pixmap->GetGdkDrawable(); // paint background gtk_paint_flat_box(gWidgetData[m_nXScreen].gProgressBar->style, pixDrawable, @@ -3408,7 +3466,7 @@ bool GtkSalGraphics::NWPaintGTKProgress( } bool bRet = NWRenderPixmapToScreen( pixmap, rControlRectangle ); - g_object_unref( pixmap ); + delete pixmap; return bRet; } @@ -3430,11 +3488,11 @@ bool GtkSalGraphics::NWPaintGTKSlider( const SliderValue* pVal = static_cast<const SliderValue*>(&rValue); - GdkPixmap* pixmap = NWGetPixmapFromScreen( rControlRectangle ); + GdkX11Pixmap* pixmap = NWGetPixmapFromScreen( rControlRectangle ); if( ! pixmap ) return false; - GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap ); + GdkDrawable* const &pixDrawable = pixmap->GetGdkDrawable(); GtkWidget* pWidget = (nPart == PART_TRACK_HORZ_AREA) ? GTK_WIDGET(gWidgetData[m_nXScreen].gHScale) : GTK_WIDGET(gWidgetData[m_nXScreen].gVScale); @@ -3496,7 +3554,7 @@ bool GtkSalGraphics::NWPaintGTKSlider( } bool bRet = NWRenderPixmapToScreen( pixmap, rControlRectangle ); - g_object_unref( pixmap ); + delete pixmap; return bRet; } @@ -4070,62 +4128,28 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings ) * Create a GdkPixmap filled with the contents of an area of an Xlib window ************************************************************************/ -GdkPixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect ) +GdkX11Pixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect ) { - // Create a new pixmap to hold the composite of the window background and the control - GdkPixmap * pPixmap = gdk_pixmap_new( GDK_DRAWABLE(GetGdkWindow()), srcRect.GetWidth(), srcRect.GetHeight(), -1 ); - GdkGC * pPixmapGC = gdk_gc_new( pPixmap ); - - if( !pPixmap || !pPixmapGC ) - { - if ( pPixmap ) - g_object_unref( pPixmap ); - if ( pPixmapGC ) - g_object_unref( pPixmapGC ); - std::fprintf( stderr, "salnativewidgets-gtk.cxx: could not get valid pixmap from screen\n" ); - return( NULL ); - } - - // Copy the background of the screen into a composite pixmap - CopyScreenArea( GetXDisplay(), - GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(), - gdk_x11_drawable_get_xid(pPixmap), - SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap) ) ) ), - gdk_drawable_get_depth( GDK_DRAWABLE( pPixmap ) ), - gdk_x11_gc_get_xgc(pPixmapGC), - srcRect.Left(), srcRect.Top(), srcRect.GetWidth(), srcRect.GetHeight(), 0, 0 ); - - g_object_unref( pPixmapGC ); - return( pPixmap ); + X11Pixmap* pPixmap; + GdkX11Pixmap* pResult; + + pPixmap = GetPixmapFromScreen( srcRect ); + if( pPixmap == NULL ) + return NULL; + + pResult = new GdkX11Pixmap( *pPixmap, GetGdkWindow() ); + delete pPixmap; + + return pResult; } /************************************************************************ * Copy an alpha pixmap to screen using a gc with clipping ************************************************************************/ -bool GtkSalGraphics::NWRenderPixmapToScreen( GdkPixmap* pPixmap, Rectangle dstRect ) +bool GtkSalGraphics::NWRenderPixmapToScreen( GdkX11Pixmap* pPixmap, Rectangle dstRect ) { - // The GC can't be null, otherwise we'd have no clip region - GC aFontGC = GetFontGC(); - if( aFontGC == NULL ) - { - std::fprintf(stderr, "salnativewidgets.cxx: no valid GC\n" ); - return false; - } - - if ( !pPixmap ) - return false; - - // Copy the background of the screen into a composite pixmap - CopyScreenArea( GetXDisplay(), - GDK_DRAWABLE_XID(pPixmap), - SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap) ) ) ), - gdk_drawable_get_depth( GDK_DRAWABLE(pPixmap) ), - GetDrawable(), m_nXScreen, GetVisual().GetDepth(), - aFontGC, - 0, 0, dstRect.GetWidth(), dstRect.GetHeight(), dstRect.Left(), dstRect.Top() ); - - return true; + return RenderPixmapToScreen( pPixmap, dstRect.Left(), dstRect.Top() ); } /************************************************************************ commit 8f9a75d1a2e94ea2a31949484581b97e50e0c14c Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Sat Nov 8 20:17:29 2014 +0100 fix line position Change-Id: Ic604eb7b0d663928ab614fe85530e4f925bcff8f diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index a92682a..835d344 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -302,8 +302,8 @@ void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAr for( i = 0, j = 0; i < nPoints; i++ ) { - aPoints[j++] = (2 * pPtAry[i].mnX) / GetWidth() - 1.0; - aPoints[j++] = (2 * pPtAry[i].mnY) / GetHeight() - 1.0; + aPoints[j++] = (2 * pPtAry[i].mnX) / GetWidth() - 1.0f; + aPoints[j++] = 1.0f - (2 * pPtAry[i].mnY) / GetHeight(); } glEnableVertexAttribArray( GL_ATTRIB_POS ); commit 681eafcbe1bf13cdb7cbc1bf7d5a37b820caebdb Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Sat Nov 8 20:15:33 2014 +0100 fix ellipse rendering completely Change-Id: I861ab0442f85f54d4a390d46c784bcf03545ae15 diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 161de3a..a92682a 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -372,7 +372,7 @@ void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPt { const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint(i) ); aVertices[j++] = 2 * rPt.getX() / nWidth - 1.0f; - aVertices[j++] = 2 * rPt.getY() / nHeight - 1.0f; + aVertices[j++] = 1.0f - 2 * rPt.getY() / nHeight; } glEnableVertexAttribArray( GL_ATTRIB_POS ); commit 79d3cc082de625a6691302c4b0bc0bfe3dcf2a9c Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Sat Nov 8 20:12:34 2014 +0100 improvement for ellipse rendering Change-Id: I0ce74b77e0b08ddde5b93cf9e9da2ee7e0a1fdea diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index d9a676f..161de3a 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -363,18 +363,20 @@ void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPt { const ::basegfx::B2DPolygon& aResult( ::basegfx::triangulator::triangulate( aPolygon ) ); - std::vector<GLushort> aVertices(aResult.count() * 2); + std::vector<GLfloat> aVertices(aResult.count() * 2); sal_uInt32 j( 0 ); + float nHeight = GetHeight(); + float nWidth = GetWidth(); for( sal_uInt32 i = 0; i < aResult.count(); i++ ) { const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint(i) ); - aVertices[j++] = rPt.getX(); - aVertices[j++] = rPt.getY(); + aVertices[j++] = 2 * rPt.getX() / nWidth - 1.0f; + aVertices[j++] = 2 * rPt.getY() / nHeight - 1.0f; } glEnableVertexAttribArray( GL_ATTRIB_POS ); - glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, &aVertices[0] ); + glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] ); glDrawArrays( GL_TRIANGLES, 0, aResult.count() ); glDisableVertexAttribArray( GL_ATTRIB_POS ); } commit 817d12955d114c502a5c4b355dce34f9f95a837e Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Sat Nov 8 19:57:41 2014 +0100 use different line and fill colors makes it easier to see if one is missing Change-Id: I983fdf2edf22c431d601a63dbf90902a3f8657f2 diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx index 2d457de..d753c0d 100644 --- a/vcl/workben/vcldemo.cxx +++ b/vcl/workben/vcldemo.cxx @@ -126,6 +126,8 @@ public: } void drawEllipse(Rectangle r) { + SetLineColor(Color(COL_RED)); + SetFillColor(Color(COL_GREEN)); DrawEllipse(r); } void drawCheckered(Rectangle r) commit eeb338abd203c06969d2d7d9734624551a79f371 Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Sat Nov 8 19:38:15 2014 +0100 fix comment Change-Id: I5d0f4a1ae8ac56e9da8d19b7b433513271e7a705 diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx index 2ab4b3f..2d457de 100644 --- a/vcl/workben/vcldemo.cxx +++ b/vcl/workben/vcldemo.cxx @@ -121,8 +121,7 @@ public: tools::PolyPolygon aPPoly(aPoly); SetLineColor(Color(COL_RED)); SetFillColor(Color(COL_RED)); - // This hits the 'drawAlphaRect' code-path - // FIXME: not alpha ... + // This hits the optional 'drawPolyPolygon' code-path DrawTransparent(aPPoly, 64); } void drawEllipse(Rectangle r) commit c311d0269f6437ebb6ca88a483ecd8b4ec7537de Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Sat Nov 8 19:23:16 2014 +0100 get size correct for virtual devices Change-Id: I8fff04f561d57083c65a87ad5bd0e04cb9b9ed2c diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 688a8d9..ef80d34 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -26,6 +26,7 @@ #include <vcl/opengl/OpenGLContext.hxx> class SalFrame; +class SalVirtualDevice; class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl { @@ -33,6 +34,7 @@ private: OpenGLContext maContext; SalFrame* mpFrame; + SalVirtualDevice* mpVDev; SalColor mnLineColor; SalColor mnFillColor; @@ -88,6 +90,7 @@ public: virtual void freeResources() SAL_OVERRIDE; virtual void Init( SalFrame* pFrame ) SAL_OVERRIDE; + virtual void Init( SalVirtualDevice* pVDev ) SAL_OVERRIDE; virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE; // diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx index ba54f9f..dc8c580 100644 --- a/vcl/inc/salgdiimpl.hxx +++ b/vcl/inc/salgdiimpl.hxx @@ -36,6 +36,7 @@ class SalGraphics; class SalBitmap; class SalFrame; class Gradient; +class SalVirtualDevice; class VCL_PLUGIN_PUBLIC SalGraphicsImpl { @@ -45,6 +46,8 @@ public: virtual void Init( SalFrame* pFrame ) = 0; + virtual void Init( SalVirtualDevice* pVDev ) = 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 4865379..d9a676f 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -21,6 +21,7 @@ #include <vcl/gradient.hxx> #include <salframe.hxx> +#include "salvd.hxx" #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/polygon/b2dpolygontriangulator.hxx> @@ -53,6 +54,11 @@ void OpenGLSalGraphicsImpl::Init( SalFrame* pFrame ) mpFrame = pFrame; } +void OpenGLSalGraphicsImpl::Init(SalVirtualDevice* pVDev) +{ + mpVDev = pVDev; +} + bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip ) { const basegfx::B2DPolyPolygon aClip( rClip.GetAsB2DPolyPolygon() ); @@ -92,14 +98,28 @@ inline GLfloat OpenGLSalGraphicsImpl::GetWidth() const { if( mpFrame ) return mpFrame->maGeometry.nWidth; - return 0; + else if (mpVDev) + { + long nWidth = 0; + long nHeight = 0; + mpVDev->GetSize(nWidth, nHeight); + return nWidth; + } + return 1; } inline GLfloat OpenGLSalGraphicsImpl::GetHeight() const { if( mpFrame ) return mpFrame->maGeometry.nHeight; - return 0; + else if (mpVDev) + { + long nWidth = 0; + long nHeight = 0; + mpVDev->GetSize(nWidth, nHeight); + return nHeight; + } + return 1; } // set the clip region to empty diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx index 6b90220..f2ccf90 100644 --- a/vcl/unx/generic/gdi/gdiimpl.cxx +++ b/vcl/unx/generic/gdi/gdiimpl.cxx @@ -159,6 +159,12 @@ void X11SalGraphicsImpl::Init( SalFrame* /*pFrame*/ ) mnBrushPixel = mrParent.GetPixel( mnBrushColor ); } +void X11SalGraphicsImpl::Init( SalVirtualDevice* /*pVDev*/ ) +{ + mnPenPixel = mrParent.GetPixel( mnPenColor ); + mnBrushPixel = mrParent.GetPixel( mnBrushColor ); +} + XID X11SalGraphicsImpl::GetXRenderPicture() { XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); ... etc. - the rest is truncated
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits