vcl/inc/openglgdiimpl.hxx | 9 + vcl/opengl/gdiimpl.cxx | 189 ++++++++++++++++++++++++----------------- vcl/source/outdev/polyline.cxx | 2 3 files changed, 122 insertions(+), 78 deletions(-)
New commits: commit e126f5cb095b2b0e0d3d505a68dfbeb6eefd82e4 Author: LuboÅ¡ LuÅák <[email protected]> Date: Thu Jan 8 18:09:49 2015 +0100 implement optimized hairline drawing for opengl As a side effect, this prevents the lines from looking too wide, because of generic polygon drawing being a bit too generous with AA. Change-Id: I17314c39fd57e33ecbd10b8a8785c600bdc5b212 diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index a284236..0695693 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -1219,17 +1219,19 @@ bool OpenGLSalGraphicsImpl::drawPolyLine( //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;*/ + // hairlines can be drawn in a simpler way (the linejoin and linecap styles can be ignored) + PreDraw(); + if( UseSolidAA( mnLineColor, fTransparency )) + { + for( sal_uInt32 j = 0; j < rPolygon.count() - 1; j++ ) + { + const ::basegfx::B2DPoint& rPt1( rPolygon.getB2DPoint( j ) ); + const ::basegfx::B2DPoint& rPt2( rPolygon.getB2DPoint(( j + 1 )) ); + DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); + } + } + PostDraw(); + return true; } // get the area polygon for the line polygon commit a477b66f1fa0847c716c886ab434d8e38247d641 Author: LuboÅ¡ LuÅák <[email protected]> Date: Wed Jan 7 17:43:39 2015 +0100 do not set Y line width to 0 I'm somewhat confused by why there needs to be a separate line width for X and Y, but apparently there is, and the latter shouldn't be just plain 0 (otherwise a number of drawPolyLine() implementations either skip using a simpler path for the usual case of them being equal, or even plain to refuse work at all and cause a fall back). And I hope this doesn't lead to finding out that some of those implementation are actually buggy. Change-Id: I2dbbd1539c4a96d41935cce9ae6565872e2a459b diff --git a/vcl/source/outdev/polyline.cxx b/vcl/source/outdev/polyline.cxx index ece1d6f..78eb139 100644 --- a/vcl/source/outdev/polyline.cxx +++ b/vcl/source/outdev/polyline.cxx @@ -302,7 +302,7 @@ bool OutputDevice::DrawPolyLineDirect( const basegfx::B2DPolygon& rB2DPolygon, // transform the line width if used if( fLineWidth != 0.0 ) { - aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, 0.0 ); + aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth ); } // transform the polygon commit ca1f918c327f82568e65f7f49e24b7158c63181f Author: LuboÅ¡ LuÅák <[email protected]> Date: Mon Jan 12 13:24:47 2015 +0100 make AA edges of objects look smoother (opengl) Change-Id: I66a04febdbfa673e0883ab6f574bb7768cad7953 diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index cf7392d..2b815ee 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -64,7 +64,7 @@ protected: void ImplInitClipRegion(); void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask ); - + void ImplDrawLineAA( double nX1, double nY1, double nX2, double nY2, bool edge = false ); bool CheckOffscreenTexture(); public: @@ -81,6 +81,7 @@ public: void DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose ); void DrawLineAA( double nX1, double nY1, double nX2, double nY2 ); void DrawLinesAA( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose ); + void DrawEdgeAA( double nX1, double nY1, double nX2, double nY2 ); void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ); void DrawConvexPolygon( const Polygon& rPolygon ); void DrawRect( long nX, long nY, long nWidth, long nHeight ); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index afdb8d9..a284236 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -472,7 +472,11 @@ void OpenGLSalGraphicsImpl::DrawLineAA( double nX1, double nY1, double nX2, doub glDrawArrays( GL_LINES, 0, 2 ); return; } + ImplDrawLineAA( nX1, nY1, nX2, nY2 ); +} +void OpenGLSalGraphicsImpl::ImplDrawLineAA( double nX1, double nY1, double nX2, double nY2, bool edge ) +{ // Draw the line anti-aliased. Based on code with the following notice: /* Drawing nearly perfect 2D line segments in OpenGL * You can use this code however you want. @@ -486,39 +490,52 @@ void OpenGLSalGraphicsImpl::DrawLineAA( double nX1, double nY1, double nX2, doub double y1 = nY1; double x2 = nX2; double y2 = nY2; - const int w = 1; // line width + + // A special hack for drawing lines that are in fact AA edges of a shape. Make the line somewhat + // wider, but (done further below) draw the entire width as a gradient. This would be wrong for a line + // (too wide and seemingly less straight), but it makes the edges look smoother and the width difference + // is almost unnoticeable. + const double w = edge ? 1.4 : 1.0; double t; double R; + double f = w - static_cast<int>(w); //determine parameters t,R - switch( w ) + if ( w>=0.0 && w<1.0 ) { - case 0: - return; - case 1: - t=0.05; - R=0.768; - break; - case 2: - t=0.38; - R=1.08; - break; - case 3: - t=0.96; - R=1.08; - break; - case 4: - t=1.44; - R=1.08; - break; - case 5: - t=1.9; - R=1.08; - break; - default: - t=2.5+(w-6)*0.50; - R=1.08; - break; + t=0.05; + R=0.48+0.32*f; + } + else if ( w>=1.0 && w<2.0 ) + { + t=0.05+f*0.33; + R=0.768+0.312*f; + } + else if ( w>=2.0 && w<3.0 ) + { + t=0.38+f*0.58; + R=1.08; + } + else if ( w>=3.0 && w<4.0 ) + { + t=0.96+f*0.48; + R=1.08; + } + else if ( w>=4.0 && w<5.0 ) + { + t=1.44+f*0.46; + R=1.08; + } + else if ( w>=5.0 && w<6.0 ) + { + t=1.9+f*0.6; + R=1.08; + } + else if ( w>=6.0 ) + { + double ff=w-6.0; + t=2.5+ff*0.50; + R=1.08; } //determine angle of the line to horizontal @@ -526,7 +543,7 @@ void OpenGLSalGraphicsImpl::DrawLineAA( double nX1, double nY1, double nX2, doub double Rx=0,Ry=0; //fading edge of a line double dx=x2-x1; double dy=y2-y1; - if ( w < 3) + if ( w < 3 ) { //approximate to make things even faster double m=dy/dx; //and calculate tx,ty,Rx,Ry @@ -568,6 +585,13 @@ void OpenGLSalGraphicsImpl::DrawLineAA( double nX1, double nY1, double nX2, doub Rx=R*dx; Ry=R*dy; } + if( edge ) + { // See above. + Rx += tx; + Ry += ty; + tx = ty = 0; + } + GLfloat vertices[]= { #define convertX( x ) GLfloat( (2 * (x)) / GetWidth() - 1.0f) @@ -606,6 +630,14 @@ void OpenGLSalGraphicsImpl::DrawLinesAA( sal_uInt32 nPoints, const SalPoint* pPt DrawLineAA( pPtAry[ nPoints - 1 ].mnX, pPtAry[ nPoints - 1 ].mnY, pPtAry[ 0 ].mnX, pPtAry[ 0 ].mnY ); } +void OpenGLSalGraphicsImpl::DrawEdgeAA( double nX1, double nY1, double nX2, double nY2 ) +{ + assert( mrParent.getAntiAliasB2DDraw()); + if( nX1 == nX2 || nY1 == nY2 ) + return; //horizontal/vertical, no need for AA + ImplDrawLineAA( nX1, nY1, nX2, nY2, true ); +} + void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) { std::vector<GLfloat> aVertices(nPoints * 2); @@ -654,9 +686,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon ) { const Point& rPt1 = rPolygon.GetPoint( i ); const Point& rPt2 = rPolygon.GetPoint(( i + 1 ) % nPoints ); - if( rPt1.getX() == rPt2.getX() || rPt1.getY() == rPt2.getY()) - continue; //horizontal/vertical, no need for AA - DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); + DrawEdgeAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); } UseSolid( lastSolidColor, lastSolidTransparency ); } @@ -751,9 +781,7 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPol { const ::basegfx::B2DPoint& rPt1( rPolygon.getB2DPoint( j ) ); const ::basegfx::B2DPoint& rPt2( rPolygon.getB2DPoint(( j + 1 ) % rPolygon.count()) ); - if( rPt1.getX() == rPt2.getX() || rPt1.getY() == rPt2.getY()) - continue; //horizontal/vertical, no need for AA - DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); + DrawEdgeAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); } } UseSolid( lastSolidColor, lastSolidTransparency ); commit 67d6aef4c5970b6fc32617f6ee61512236072c6a Author: LuboÅ¡ LuÅák <[email protected]> Date: Mon Jan 12 13:20:54 2015 +0100 clean up resetting of solid color when using opengl AA 118529d4644a and 011903894 might have been technically correct, but 'mProgramIsSolidLineColor' is clearly a misnomer at best, and they'd have made it even more likely that this would break yet again. Change-Id: I1f01663e2abc0b1b0e557ae7241637a96e1a402a diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 69c211d..cf7392d 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -57,8 +57,10 @@ protected: SalColor mnLineColor; SalColor mnFillColor; #ifdef DBG_UTIL - bool mProgramIsSolidLineColor; + bool mProgramIsSolidColor; #endif + SalColor mProgramSolidColor; + double mProgramSolidTransparency; void ImplInitClipRegion(); void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask ); @@ -84,7 +86,7 @@ public: void DrawRect( long nX, long nY, long nWidth, long nHeight ); void DrawRect( const Rectangle& rRect ); void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ); - void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bLine, bool blockAA = false ); + void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, bool blockAA = false ); void DrawRegionBand( const RegionBand& rRegion ); void DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false ); void DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false ); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index e7149f7..afdb8d9 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -48,7 +48,7 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryPr , mnLineColor(SALCOLOR_NONE) , mnFillColor(SALCOLOR_NONE) #ifdef DBG_UTIL - , mProgramIsSolidLineColor(false) + , mProgramIsSolidColor(false) #endif { } @@ -166,7 +166,7 @@ void OpenGLSalGraphicsImpl::PostDraw() mpProgram->Clean(); mpProgram = NULL; #ifdef DBG_UTIL - mProgramIsSolidLineColor = false; + mProgramIsSolidColor = false; #endif } @@ -198,7 +198,7 @@ void OpenGLSalGraphicsImpl::ImplSetClipBit( const vcl::Region& rClip, GLuint nMa if( rClip.getRegionBand() ) DrawRegionBand( *rClip.getRegionBand() ); else - DrawPolyPolygon( rClip.GetAsB2DPolyPolygon(), false, true ); + DrawPolyPolygon( rClip.GetAsB2DPolyPolygon(), true ); } glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); @@ -361,7 +361,7 @@ bool OpenGLSalGraphicsImpl::UseProgram( const OUString& rVertexShader, const OUS mpProgram->Clean(); mpProgram = mpContext->UseProgram( rVertexShader, rFragmentShader ); #ifdef DBG_UTIL - mProgramIsSolidLineColor = false; // UseSolid() will set to true if needed + mProgramIsSolidColor = false; // UseSolid() will set to true if needed #endif return ( mpProgram != NULL ); } @@ -374,8 +374,10 @@ bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, sal_uInt8 nTransparency ) return false; mpProgram->SetColor( "color", nColor, nTransparency ); #ifdef DBG_UTIL - mProgramIsSolidLineColor = true; + mProgramIsSolidColor = true; #endif + mProgramSolidColor = nColor; + mProgramSolidTransparency = nTransparency / 100.0; return true; } @@ -387,8 +389,10 @@ bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, double fTransparency ) return false; mpProgram->SetColorf( "color", nColor, fTransparency ); #ifdef DBG_UTIL - mProgramIsSolidLineColor = true; + mProgramIsSolidColor = true; #endif + mProgramSolidColor = nColor; + mProgramSolidTransparency = fTransparency; return true; } @@ -640,18 +644,22 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon ) // may be a problem, if that is a real problem, the polygon areas itself needs to be // masked out for this or something. #ifdef DBG_UTIL - assert( mProgramIsSolidLineColor ); + assert( mProgramIsSolidColor ); #endif - UseSolidAA( mnLineColor ); - for( i = 0; i < nPoints; ++i ) + SalColor lastSolidColor = mProgramSolidColor; + double lastSolidTransparency = mProgramSolidTransparency; + if( UseSolidAA( lastSolidColor, lastSolidTransparency )) { - const Point& rPt1 = rPolygon.GetPoint( i ); - const Point& rPt2 = rPolygon.GetPoint(( i + 1 ) % nPoints ); - if( rPt1.getX() == rPt2.getX() || rPt1.getY() == rPt2.getY()) - continue; //horizontal/vertical, no need for AA - DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); + for( i = 0; i < nPoints; ++i ) + { + const Point& rPt1 = rPolygon.GetPoint( i ); + const Point& rPt2 = rPolygon.GetPoint(( i + 1 ) % nPoints ); + if( rPt1.getX() == rPt2.getX() || rPt1.getY() == rPt2.getY()) + continue; //horizontal/vertical, no need for AA + DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); + } + UseSolid( lastSolidColor, lastSolidTransparency ); } - UseSolid( mnLineColor ); } } @@ -695,11 +703,11 @@ void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPt else { const ::basegfx::B2DPolyPolygon aPolyPolygon( aPolygon ); - DrawPolyPolygon( aPolyPolygon, false ); + DrawPolyPolygon( aPolyPolygon ); } } -void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bLine, bool blockAA ) +void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, bool blockAA ) { ::std::vector< GLfloat > aVertices; GLfloat nWidth = GetWidth(); @@ -730,23 +738,26 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPol // may be a problem, if that is a real problem, the polygon areas itself needs to be // masked out for this or something. #ifdef DBG_UTIL - assert( mProgramIsSolidLineColor ); + assert( mProgramIsSolidColor ); #endif - bool bUseLineColor = bLine || mnLineColor != SALCOLOR_NONE; - UseSolidAA( bUseLineColor ? mnLineColor : mnFillColor ); - for( sal_uInt32 i = 0; i < aSimplePolyPolygon.count(); i++ ) + SalColor lastSolidColor = mProgramSolidColor; + double lastSolidTransparency = mProgramSolidTransparency; + if( UseSolidAA( lastSolidColor, lastSolidTransparency )) { - const basegfx::B2DPolygon& rPolygon( aSimplePolyPolygon.getB2DPolygon( i ) ); - for( sal_uInt32 j = 0; j < rPolygon.count(); j++ ) + for( sal_uInt32 i = 0; i < aSimplePolyPolygon.count(); i++ ) { - const ::basegfx::B2DPoint& rPt1( rPolygon.getB2DPoint( j ) ); - const ::basegfx::B2DPoint& rPt2( rPolygon.getB2DPoint(( j + 1 ) % rPolygon.count()) ); - if( rPt1.getX() == rPt2.getX() || rPt1.getY() == rPt2.getY()) - continue; //horizontal/vertical, no need for AA - DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); + const basegfx::B2DPolygon& rPolygon( aSimplePolyPolygon.getB2DPolygon( i ) ); + for( sal_uInt32 j = 0; j < rPolygon.count(); j++ ) + { + const ::basegfx::B2DPoint& rPt1( rPolygon.getB2DPoint( j ) ); + const ::basegfx::B2DPoint& rPt2( rPolygon.getB2DPoint(( j + 1 ) % rPolygon.count()) ); + if( rPt1.getX() == rPt2.getX() || rPt1.getY() == rPt2.getY()) + continue; //horizontal/vertical, no need for AA + DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); + } } + UseSolid( lastSolidColor, lastSolidTransparency ); } - UseSolid( bLine ? mnLineColor : mnFillColor ); } CHECK_GL_ERROR(); @@ -1134,7 +1145,7 @@ bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rP for( sal_uInt32 i = 0; i < rPolyPolygon.count(); i++ ) { const ::basegfx::B2DPolyPolygon aOnePoly( rPolyPolygon.getB2DPolygon( i ) ); - DrawPolyPolygon( aOnePoly, false ); + DrawPolyPolygon( aOnePoly ); } } @@ -1217,7 +1228,7 @@ bool OpenGLSalGraphicsImpl::drawPolyLine( for( sal_uInt32 i = 0; i < aAreaPolyPoly.count(); i++ ) { const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( i ) ); - DrawPolyPolygon( aOnePoly, true ); + DrawPolyPolygon( aOnePoly ); } } PostDraw(); commit b8b49af63ebe91682c8cc049aa05b1ad714a93e3 Author: LuboÅ¡ LuÅák <[email protected]> Date: Wed Jan 7 18:06:25 2015 +0100 fix confusion between transparency and opacity Change-Id: Ifa69f3272ebda2a61ac00d2affb8aebd4524f0fc diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index feb8bdc..e7149f7 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -404,14 +404,14 @@ bool OpenGLSalGraphicsImpl::UseSolidAA( SalColor nColor, double fTransparency ) return UseSolid( nColor ); if( !UseProgram( "textureVertexShader", "linearGradientFragmentShader" ) ) return false; - mpProgram->SetColorf( "start_color", nColor, 0.0f ); - mpProgram->SetColorf( "end_color", nColor, fTransparency ); + mpProgram->SetColorf( "start_color", nColor, fTransparency ); + mpProgram->SetColorf( "end_color", nColor, 1.0f ); return true; } bool OpenGLSalGraphicsImpl::UseSolidAA( SalColor nColor ) { - return UseSolidAA( nColor, 1.0 ); + return UseSolidAA( nColor, 0.0 ); } bool OpenGLSalGraphicsImpl::UseInvert()
_______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
