include/vcl/opengl/OpenGLContext.hxx | 51 ++++++--------- include/vcl/opengl/OpenGLHelper.hxx | 2 vcl/inc/opengl/program.hxx | 2 vcl/inc/openglgdiimpl.hxx | 2 vcl/opengl/areaScaleFastFragmentShader.glsl | 13 +++ vcl/opengl/areaScaleFragmentShader.glsl | 19 +++++ vcl/opengl/gdiimpl.cxx | 95 +++++++++++++++++++++++----- vcl/opengl/program.cxx | 4 - vcl/opengl/scale.cxx | 1 vcl/source/app/svdata.cxx | 6 + vcl/source/app/svmain.cxx | 6 + vcl/source/opengl/OpenGLContext.cxx | 60 +++++++++++++---- vcl/source/opengl/OpenGLHelper.cxx | 6 + vcl/workben/vcldemo.cxx | 8 +- 14 files changed, 207 insertions(+), 68 deletions(-)
New commits: commit 62adce318519590ee48fc3f0bf07fd614eeffb99 Author: LuboÅ¡ LuÅák <[email protected]> Date: Tue Jan 20 15:41:51 2015 +0100 when drawing a transformed bitmap in opengl backend, scale it better The plain scaling is rather rough, and in fact drawing a scaled bitmap the normal way gives much better results (because OutputDevice pre-scales the bitmap before it's drawn). This one may be a bit slow perhaps, but hopefully nobody there's no code that'd extensively use bitmap drawing with custom transformations (wishful thinking). Change-Id: I83e05307adfaeac0ed0757f1a0b2603f64caf8f8 Signed-off-by: Michael Meeks <[email protected]> diff --git a/vcl/opengl/areaScaleFastFragmentShader.glsl b/vcl/opengl/areaScaleFastFragmentShader.glsl index b8874d1..10ce9f5 100644 --- a/vcl/opengl/areaScaleFastFragmentShader.glsl +++ b/vcl/opengl/areaScaleFastFragmentShader.glsl @@ -18,6 +18,12 @@ uniform float ratio; // = 1.0/(xscale*yscale) varying vec2 tex_coord; +// This mode makes the scaling work like maskedTextureFragmentShader.glsl +// (instead of like plain textureVertexShader.glsl). +#ifdef MASKED +uniform sampler2D mask; +#endif + /* Just make the resulting color the average of all the source pixels (which is an area (xscale)x(yscale) ). @@ -30,7 +36,14 @@ void main(void) { for( int x = 0; x < xscale; ++x ) { +#ifndef MASKED sum += texture2D( sampler, tex_coord.st + offset ); +#else + vec4 texel; + texel = texture2D( sampler, tex_coord.st + offset ); + texel.a = 1.0 - texture2D( mask, tex_coord.st + offset ).r; + sum += texel; +#endif offset.x += xstep; } offset.y += ystep; diff --git a/vcl/opengl/areaScaleFragmentShader.glsl b/vcl/opengl/areaScaleFragmentShader.glsl index 498b0b5..d72184c 100644 --- a/vcl/opengl/areaScaleFragmentShader.glsl +++ b/vcl/opengl/areaScaleFragmentShader.glsl @@ -27,6 +27,12 @@ uniform float ydestconvert; varying vec2 tex_coord; +// This mode makes the scaling work like maskedTextureFragmentShader.glsl +// (instead of like plain textureVertexShader.glsl). +#ifdef MASKED +uniform sampler2D mask; +#endif + void main(void) { // Convert to pixel coordinates again. @@ -126,7 +132,14 @@ void main(void) for( int x = xstart; x <= xend; ++x, ++xpos ) { vec2 offset = vec2( x * xsrcconvert, y * ysrcconvert ); +#ifndef MASKED tmp += texture2D( sampler, offset ) * xratio[ xpos ]; +#else + vec4 texel; + texel = texture2D( sampler, offset ); + texel.a = 1.0 - texture2D( mask, offset ).r; + tmp += texel * xratio[ xpos ]; +#endif } sum += tmp * yratio[ ypos ]; } diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index b74c763..540a1c8 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -892,9 +892,34 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture( (float) rTexture.GetWidth(), 0, (float) rTexture.GetWidth(), (float) rTexture.GetHeight() }; GLfloat aTexCoord[8]; + // If downscaling at a higher scale ratio, use the area scaling algorithm rather + // than plain OpenGL's scaling, for better results. + // See OpenGLSalBitmap::ImplScaleArea(). + double ixscale = rTexture.GetWidth() / fabs( rX.getX() - rNull.getX()); + double iyscale = rTexture.GetHeight() / fabs( rY.getY() - rNull.getY()); + bool areaScaling = false; + bool fastAreaScaling = false; + OUString textureFragmentShader; + if( ixscale >= 2 && iyscale >= 2 ) // Downscaling to 50% or less? (inverted scale ratios) + { + areaScaling = true; + fastAreaScaling = ( ixscale == int( ixscale ) && iyscale == int( iyscale )); + // The generic case has arrays only up to 100 ratio downscaling, which is hopefully enough + // in practice, but protect against buffer overflows in case such an extreme case happens + // (and in such case the precision of the generic algorithm probably doesn't matter anyway). + if( ixscale > 100 || iyscale > 100 ) + fastAreaScaling = true; + if( fastAreaScaling ) + textureFragmentShader = "areaScaleFastFragmentShader"; + else + textureFragmentShader = "areaScaleFragmentShader"; + } + if( rMask ) { - if( !UseProgram( "transformedTextureVertexShader", "maskedTextureFragmentShader" ) ) + if( !UseProgram( "transformedTextureVertexShader", + textureFragmentShader.isEmpty() ? "maskedTextureFragmentShader" : textureFragmentShader, + "#define MASKED" ) ) return; mpProgram->SetTexture( "mask", rMask ); rMask.SetFilter( GL_LINEAR ); @@ -902,10 +927,40 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture( } else { - if( !UseProgram( "transformedTextureVertexShader", "textureFragmentShader" ) ) + if( !UseProgram( "transformedTextureVertexShader", + textureFragmentShader.isEmpty() ? "textureFragmentShader" : textureFragmentShader ) ) return; } + if( areaScaling ) + { + // From OpenGLSalBitmap::ImplScaleArea(). + if( fastAreaScaling ) + { + int mnWidth = rTexture.GetWidth(); + int mnHeight = rTexture.GetHeight(); + mpProgram->SetUniform1i( "xscale", ixscale ); + mpProgram->SetUniform1i( "yscale", iyscale ); + mpProgram->SetUniform1f( "xstep", 1.0 / mnWidth ); + mpProgram->SetUniform1f( "ystep", 1.0 / mnHeight ); + mpProgram->SetUniform1f( "ratio", 1.0 / ( ixscale * iyscale )); + } + else + { + int mnWidth = rTexture.GetWidth(); + int mnHeight = rTexture.GetHeight(); + mpProgram->SetUniform1f( "xscale", ixscale ); + mpProgram->SetUniform1f( "yscale", iyscale ); + mpProgram->SetUniform1i( "swidth", mnWidth ); + mpProgram->SetUniform1i( "sheight", mnHeight ); + // For converting between <0,mnWidth-1> and <0.0,1.0> coordinate systems. + mpProgram->SetUniform1f( "xsrcconvert", 1.0 / ( mnWidth - 1 )); + mpProgram->SetUniform1f( "ysrcconvert", 1.0 / ( mnHeight - 1 )); + mpProgram->SetUniform1f( "xdestconvert", 1.0 * (( mnWidth / ixscale ) - 1 )); + mpProgram->SetUniform1f( "ydestconvert", 1.0 * (( mnHeight / iyscale ) - 1 )); + } + } + mpProgram->SetUniform2f( "viewport", GetWidth(), GetHeight() ); mpProgram->SetTransform( "transform", rTexture, rNull, rX, rY ); rTexture.GetWholeCoord( aTexCoord ); diff --git a/vcl/opengl/scale.cxx b/vcl/opengl/scale.cxx index 84cf967..a7a05a4 100644 --- a/vcl/opengl/scale.cxx +++ b/vcl/opengl/scale.cxx @@ -225,6 +225,7 @@ bool OpenGLSalBitmap::ImplScaleArea( double rScaleX, double rScaleY ) OpenGLTexture aScratchTex = OpenGLTexture( nNewWidth, nNewHeight ); OpenGLFramebuffer* pFramebuffer = mpContext->AcquireFramebuffer( aScratchTex ); + // NOTE: This setup is also done in OpenGLSalGraphicsImpl::DrawTransformedTexture(). if( fast ) { pProgram->SetUniform1i( "xscale", ixscale ); commit a51481f413a2bf513a171c460fd5522c8fb30361 Author: LuboÅ¡ LuÅák <[email protected]> Date: Tue Jan 20 14:48:48 2015 +0100 make it possible to easily have variants of glsl programs Now it's possible to add a preamble to the compiled program, so there can be just one program with #ifdef's inside and the small variants can be selected using #define in the preamble instead of having several almost identical programs. Change-Id: I6c5112313b91b6269ebdecdfc896e0f96209ea2b Signed-off-by: Michael Meeks <[email protected]> diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx index e2d6b77..670e83f 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -162,8 +162,6 @@ struct GLWindow ~GLWindow(); }; -typedef std::pair<OUString, OUString> ProgramKey; - class VCLOPENGL_DLLPUBLIC OpenGLContext { public: @@ -204,8 +202,8 @@ public: void ReleaseFramebuffers(); // retrieve a program from the cache or compile/link it - OpenGLProgram* GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader ); - OpenGLProgram* UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader ); + OpenGLProgram* GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" ); + OpenGLProgram* UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" ); bool isCurrent(); static void clearCurrent(); @@ -267,6 +265,14 @@ private: OpenGLFramebuffer* mpFirstFramebuffer; OpenGLFramebuffer* mpLastFramebuffer; + struct ProgramKey + { + ProgramKey( const OUString& vertexShader, const OUString& fragmentShader, const OString& preamble ); + bool operator< ( const ProgramKey& other ) const; + OUString vertexShader; + OUString fragmentShader; + OString preamble; + }; boost::ptr_map<ProgramKey, OpenGLProgram> maPrograms; OpenGLProgram* mpCurrentProgram; #ifdef DBG_UTIL diff --git a/include/vcl/opengl/OpenGLHelper.hxx b/include/vcl/opengl/OpenGLHelper.hxx index 2430515..4e11bf8 100644 --- a/include/vcl/opengl/OpenGLHelper.hxx +++ b/include/vcl/opengl/OpenGLHelper.hxx @@ -25,7 +25,7 @@ class VCLOPENGL_DLLPUBLIC OpenGLHelper { public: - static GLint LoadShaders(const OUString& rVertexShaderName, const OUString& rFragmentShaderName); + static GLint LoadShaders(const OUString& rVertexShaderName, const OUString& rFragmentShaderName, const OString& preamble = "" ); /** * The caller is responsible for allocate the memory for the RGBA buffer, before call diff --git a/vcl/inc/opengl/program.hxx b/vcl/inc/opengl/program.hxx index 1e137aa..8c5af10 100644 --- a/vcl/inc/opengl/program.hxx +++ b/vcl/inc/opengl/program.hxx @@ -43,7 +43,7 @@ public: OpenGLProgram(); ~OpenGLProgram(); - bool Load( const OUString& rVertexShader, const OUString& rFragmentShader ); + bool Load( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" ); bool Use(); bool Clean(); diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 7bb4532..bab9690 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -73,7 +73,7 @@ protected: bool CheckOffscreenTexture(); public: - bool UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader ); + bool UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" ); bool UseSolid( SalColor nColor, sal_uInt8 nTransparency ); bool UseSolid( SalColor nColor, double fTransparency ); bool UseSolid( SalColor nColor ); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 5198375..b74c763 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -371,11 +371,11 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() return true; } -bool OpenGLSalGraphicsImpl::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader ) +bool OpenGLSalGraphicsImpl::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble ) { if( mpProgram != NULL ) mpProgram->Clean(); - mpProgram = mpContext->UseProgram( rVertexShader, rFragmentShader ); + mpProgram = mpContext->UseProgram( rVertexShader, rFragmentShader, preamble ); #ifdef DBG_UTIL mProgramIsSolidColor = false; // UseSolid() will set to true if needed #endif diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx index 80c2395..be86be2 100644 --- a/vcl/opengl/program.cxx +++ b/vcl/opengl/program.cxx @@ -31,9 +31,9 @@ OpenGLProgram::~OpenGLProgram() glDeleteProgram( mnId ); } -bool OpenGLProgram::Load( const OUString& rVertexShader, const OUString& rFragmentShader ) +bool OpenGLProgram::Load( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble ) { - mnId = OpenGLHelper::LoadShaders( rVertexShader, rFragmentShader ); + mnId = OpenGLHelper::LoadShaders( rVertexShader, rFragmentShader, preamble ); return ( mnId != 0 ); } diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index cfa8191..99f64e8 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -1536,9 +1536,9 @@ void OpenGLContext::ReleaseFramebuffers() } } -OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader ) +OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble ) { - ProgramKey aKey( rVertexShader, rFragmentShader ); + ProgramKey aKey( rVertexShader, rFragmentShader, preamble ); boost::ptr_map<ProgramKey, OpenGLProgram>::iterator it = maPrograms.find( aKey ); @@ -1546,7 +1546,7 @@ OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const O return it->second; OpenGLProgram* pProgram = new OpenGLProgram; - if( !pProgram->Load( rVertexShader, rFragmentShader ) ) + if( !pProgram->Load( rVertexShader, rFragmentShader, preamble ) ) { delete pProgram; return NULL; @@ -1556,9 +1556,9 @@ OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const O return pProgram; } -OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader ) +OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble ) { - OpenGLProgram* pProgram = GetProgram( rVertexShader, rFragmentShader ); + OpenGLProgram* pProgram = GetProgram( rVertexShader, rFragmentShader, preamble ); if( pProgram == mpCurrentProgram ) return pProgram; @@ -1569,4 +1569,20 @@ OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const O return mpCurrentProgram; } +inline +OpenGLContext::ProgramKey::ProgramKey( const OUString& v, const OUString& f, const OString& p ) +: vertexShader( v ), fragmentShader( f ), preamble( p ) +{ +} + +inline +bool OpenGLContext::ProgramKey::operator< ( const ProgramKey& other ) const +{ + if( vertexShader != other.vertexShader ) + return vertexShader < other.vertexShader; + if( fragmentShader != other.fragmentShader ) + return fragmentShader < other.fragmentShader; + return preamble < other.preamble; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx index a30b9ef..c71380e 100644 --- a/vcl/source/opengl/OpenGLHelper.cxx +++ b/vcl/source/opengl/OpenGLHelper.cxx @@ -98,7 +98,7 @@ namespace { } } -GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString& rFragmentShaderName) +GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString& rFragmentShaderName, const OString& preamble) { // Create the shaders GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); @@ -108,6 +108,8 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString // Compile Vertex Shader OString aVertexShaderSource = loadShader(rVertexShaderName); + if( !preamble.isEmpty()) + aVertexShaderSource = preamble + "\n" + aVertexShaderSource; char const * VertexSourcePointer = aVertexShaderSource.getStr(); glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); glCompileShader(VertexShaderID); @@ -120,6 +122,8 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString // Compile Fragment Shader OString aFragmentShaderSource = loadShader(rFragmentShaderName); + if( !preamble.isEmpty()) + aFragmentShaderSource = preamble + "\n" + aFragmentShaderSource; char const * FragmentSourcePointer = aFragmentShaderSource.getStr(); glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); glCompileShader(FragmentShaderID); commit fadd4a2c740e2abe911d29d00f273d115b2c9b54 Author: Markus Mohrhard <[email protected]> Date: Tue Dec 30 19:16:35 2014 +0100 prefer ptr_container to manual memory management Signed-off-by: Michael Meeks <[email protected]> Conflicts: vcl/source/opengl/OpenGLContext.cxx Change-Id: I11326c2873aad5116fd70bfa31eb94e93fef3f40 diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx index 1ae9ac6..e2d6b77 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -52,6 +52,7 @@ class NSOpenGLView; #include <vcl/vclopengl_dllapi.hxx> #include <boost/scoped_ptr.hpp> #include <boost/unordered_map.hpp> +#include <boost/ptr_container/ptr_map.hpp> #include <vcl/window.hxx> #include <tools/gen.hxx> #include <vcl/syschild.hxx> @@ -161,30 +162,7 @@ struct GLWindow ~GLWindow(); }; -struct ProgramKey -{ - OUString maVertexShader; - OUString maFragmentShader; - - ProgramKey( const OUString& rVertexShader, const OUString& rFragmentShader ): - maVertexShader(rVertexShader), - maFragmentShader(rFragmentShader) - { - } -}; - -inline bool operator==( ProgramKey const& k1, ProgramKey const& k2 ) -{ - return k1.maVertexShader == k2.maVertexShader && k1.maFragmentShader == k2.maFragmentShader; -} - -inline std::size_t hash_value( ProgramKey const& rKey ) -{ - std::size_t nSeed = 0x9e3779b9; - nSeed = rKey.maVertexShader.hashCode(); - nSeed = rKey.maFragmentShader.hashCode() + 0x9e3779b9 + (nSeed << 6) + (nSeed >> 2); - return nSeed; -} +typedef std::pair<OUString, OUString> ProgramKey; class VCLOPENGL_DLLPUBLIC OpenGLContext { @@ -289,7 +267,7 @@ private: OpenGLFramebuffer* mpFirstFramebuffer; OpenGLFramebuffer* mpLastFramebuffer; - boost::unordered_map<ProgramKey, OpenGLProgram*> maPrograms; + boost::ptr_map<ProgramKey, OpenGLProgram> maPrograms; OpenGLProgram* mpCurrentProgram; #ifdef DBG_UTIL std::set<SalGraphicsImpl*> maParents; diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index 6c085fb..cfa8191 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -1179,15 +1179,8 @@ void OpenGLContext::reset() // destroy all programs if( !maPrograms.empty() ) { - boost::unordered_map<ProgramKey, OpenGLProgram*>::iterator it; makeCurrent(); - it = maPrograms.begin(); - while( it != maPrograms.end() ) - { - delete it->second; - it++; - } maPrograms.clear(); } @@ -1545,10 +1538,10 @@ void OpenGLContext::ReleaseFramebuffers() OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader ) { - boost::unordered_map<ProgramKey, OpenGLProgram*>::iterator it; ProgramKey aKey( rVertexShader, rFragmentShader ); - it = maPrograms.find( aKey ); + boost::ptr_map<ProgramKey, OpenGLProgram>::iterator + it = maPrograms.find( aKey ); if( it != maPrograms.end() ) return it->second; @@ -1559,7 +1552,7 @@ OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const O return NULL; } - maPrograms[aKey] = pProgram; + maPrograms.insert(aKey, pProgram); return pProgram; } commit 1313ab6957d8be2fe388af04ecce82a50f0c71c0 Author: Markus Mohrhard <[email protected]> Date: Tue Dec 30 18:49:01 2014 +0100 use constructor initializer list Change-Id: Ieede6dec05f63ed0fa1dde376b2e89c381601cd6 Signed-off-by: Michael Meeks <[email protected]> diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx index 7175023..1ae9ac6 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -166,10 +166,10 @@ struct ProgramKey OUString maVertexShader; OUString maFragmentShader; - ProgramKey( const OUString& rVertexShader, const OUString& rFragmentShader ) + ProgramKey( const OUString& rVertexShader, const OUString& rFragmentShader ): + maVertexShader(rVertexShader), + maFragmentShader(rFragmentShader) { - maVertexShader = rVertexShader; - maFragmentShader = rFragmentShader; } }; commit d2819f2f47f8a98e0ee58242d9a2b54fca383add Author: Markus Mohrhard <[email protected]> Date: Tue Jan 20 04:12:18 2015 +0100 some debug code for finding leaked OpenGLContexts Change-Id: I10e8c344ae6aa2e0a4ef562154f57e2070c70e2f Signed-off-by: Michael Meeks <[email protected]> diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx index 7d72123..7175023 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -56,9 +56,12 @@ class NSOpenGLView; #include <tools/gen.hxx> #include <vcl/syschild.hxx> +#include <set> + class OpenGLFramebuffer; class OpenGLProgram; class OpenGLTexture; +class SalGraphicsImpl; /// Holds the information of our new child window struct GLWindow @@ -212,8 +215,13 @@ public: bool AcquireDefaultFramebuffer(); OpenGLFramebuffer* AcquireFramebuffer( const OpenGLTexture& rTexture ); void ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer ); +#ifdef DBG_UTIL + void AddRef(SalGraphicsImpl*); + void DeRef(SalGraphicsImpl*); +#else void AddRef(); void DeRef(); +#endif void ReleaseFramebuffer( const OpenGLTexture& rTexture ); void ReleaseFramebuffers(); @@ -283,6 +291,9 @@ private: boost::unordered_map<ProgramKey, OpenGLProgram*> maPrograms; OpenGLProgram* mpCurrentProgram; +#ifdef DBG_UTIL + std::set<SalGraphicsImpl*> maParents; +#endif public: vcl::Region maClipRegion; diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 13bfca9..5198375 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -78,7 +78,11 @@ bool OpenGLSalGraphicsImpl::AcquireContext( ) { if( mpContext->isInitialized() ) return true; +#ifdef DBG_UTIL + mpContext->DeRef(this); +#else mpContext->DeRef(); +#endif } @@ -92,7 +96,13 @@ bool OpenGLSalGraphicsImpl::AcquireContext( ) } if( pContext ) + { +#ifdef DBG_UTIL + pContext->AddRef(this); +#else pContext->AddRef(); +#endif + } else pContext = mbOffscreen ? GetDefaultContext() : CreateWinContext(); @@ -103,7 +113,13 @@ bool OpenGLSalGraphicsImpl::AcquireContext( ) bool OpenGLSalGraphicsImpl::ReleaseContext() { if( mpContext ) + { +#ifdef DBG_UTIL + mpContext->DeRef(this); +#else mpContext->DeRef(); +#endif + } mpContext = NULL; return true; } diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx index 1485305..d8934d9 100644 --- a/vcl/source/app/svdata.cxx +++ b/vcl/source/app/svdata.cxx @@ -139,7 +139,13 @@ vcl::Window* ImplGetDefaultWindow() // Add a reference to the default context so it never gets deleted OpenGLContext* pContext = pSVData->mpDefaultWin->GetGraphics()->GetOpenGLContext(); if( pContext ) + { +#ifdef DBG_UTIL + pContext->AddRef(NULL); +#else pContext->AddRef(); +#endif + } } Application::GetSolarMutex().release(); } diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx index 2fc122c..90bca1f 100644 --- a/vcl/source/app/svmain.cxx +++ b/vcl/source/app/svmain.cxx @@ -453,7 +453,13 @@ void DeInitVCL() { OpenGLContext* pContext = pSVData->mpDefaultWin->GetGraphics()->GetOpenGLContext(); if( pContext ) + { +#ifdef DBG_UTIL + pContext->DeRef(NULL); +#else pContext->DeRef(); +#endif + } delete pSVData->mpDefaultWin; pSVData->mpDefaultWin = NULL; } diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index 5cccd73..6c085fb 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -103,6 +103,26 @@ OpenGLContext::~OpenGLContext() pSVData->maGDIData.mpLastContext = mpPrevContext; } +#ifdef DBG_UTIL +void OpenGLContext::AddRef(SalGraphicsImpl* pImpl) +{ + assert(mnRefCount > 0); + mnRefCount++; + + maParents.insert(pImpl); +} + +void OpenGLContext::DeRef(SalGraphicsImpl* pImpl) +{ + assert(mnRefCount > 0); + if( --mnRefCount == 0 ) + delete this; + + auto it = maParents.find(pImpl); + if(it != maParents.end()) + maParents.erase(it); +} +#else void OpenGLContext::AddRef() { assert(mnRefCount > 0); @@ -115,6 +135,7 @@ void OpenGLContext::DeRef() if( --mnRefCount == 0 ) delete this; } +#endif void OpenGLContext::requestLegacyContext() { commit e471f3861bda5575742eac3f1d9747108e5e8e7a Author: Chris Sherlock <[email protected]> Date: Thu Jan 22 11:17:03 2015 +1100 Apply GLSL patch for areaScaleFragmentShader Thanks to Lubos Lunak Change-Id: I9bb72e1a5b11102963481dac7c11ab4a9fe90b0b Signed-off-by: Chris Sherlock <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/14095 Signed-off-by: Michael Meeks <[email protected]> diff --git a/vcl/opengl/areaScaleFragmentShader.glsl b/vcl/opengl/areaScaleFragmentShader.glsl index 03fbe69..498b0b5 100644 --- a/vcl/opengl/areaScaleFragmentShader.glsl +++ b/vcl/opengl/areaScaleFragmentShader.glsl @@ -7,6 +7,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#version 120 +#if __VERSION__ < 130 +int min( int a, int b ) { return a < b ? a : b; } +float min( float a, float b ) { return a < b ? a : b; } +#endif + /* TODO Use textureOffset for newest version of GLSL */ uniform sampler2D sampler; commit db684961b9cfc97d4151c9bee0e58e4f6c9672f3 Author: LuboÅ¡ LuÅák <[email protected]> Date: Thu Dec 18 11:47:28 2014 +0100 there's no bigger or smaller half Change-Id: Ida0e92abd806d017d17365fa2ac53b4f7cb2ebad Signed-off-by: Michael Meeks <[email protected]> diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx index 67bc818..8eea878 100644 --- a/vcl/workben/vcldemo.cxx +++ b/vcl/workben/vcldemo.cxx @@ -251,6 +251,10 @@ public: }; for (size_t i = 0; i < aRegions.size(); i++) { + // Half of them not-anti-aliased .. + if (i >= aRegions.size()/2) + rDev.SetAntialiasing(nOldAA); + static const struct { double nX, nY; } aPoints[] = { @@ -265,10 +269,6 @@ public: aSub.Top() + aSub.GetHeight() * aPoints[j].nY)); } rDev.DrawPolyLine(aPoly, aLineWidths[i], eJoins[i], eLineCaps[i]); - - // Half of them not-anti-aliased .. - if (i > aRegions.size()/2) - rDev.SetAntialiasing(nOldAA); } } else commit 9452c709785eb759923167c24e3e72d88b38f029 Author: LuboÅ¡ LuÅák <[email protected]> Date: Mon Jan 19 22:47:01 2015 +0100 draw polypolygon outline properly (if wanted) Again, polygons can apparently have curved edges. Change-Id: I6519da7bb7f0dde7f1550fe6b03c09be127f77d6 Signed-off-by: Michael Meeks <[email protected]> diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index b286023..13bfca9 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -1212,18 +1212,12 @@ bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rP if( UseSolid( mnFillColor, fTransparency ) ) DrawPolyPolygon( rPolyPolygon ); - if( mnLineColor != mnFillColor && UseSolidAA( mnLineColor ) ) + if( mnLineColor != mnFillColor && UseSolid( mnLineColor, fTransparency )) { - for( sal_uInt32 i = 0; i < rPolyPolygon.count(); i++ ) - { - const basegfx::B2DPolygon& polygon = rPolyPolygon.getB2DPolygon( i ); - for( sal_uInt32 j = 0; j < polygon.count(); ++j ) - { - const basegfx::B2DPoint& rPt1 = polygon.getB2DPoint( j ); - const basegfx::B2DPoint& rPt2 = polygon.getB2DPoint(( j + 1 ) % polygon.count()); - DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); - } - } + basegfx::B2DTrapezoidVector aB2DTrapVector; + basegfx::tools::createLineTrapezoidFromB2DPolyPolygon( aB2DTrapVector, rPolyPolygon ); + for( size_t i = 0; i < aB2DTrapVector.size(); ++i ) + DrawTrapezoid( aB2DTrapVector[ i ] ); } PostDraw();
_______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
