include/vcl/bitmap.hxx | 4 include/vcl/bmpacc.hxx | 120 ++++++---- include/vcl/opengl/OpenGLContext.hxx | 8 include/vcl/salbtype.hxx | 10 sc/source/core/data/documen4.cxx | 2 vcl/generic/print/genpspgraphics.cxx | 4 vcl/headless/svpbmp.cxx | 6 vcl/inc/cairotextrender.hxx | 1 vcl/inc/headless/svpbmp.hxx | 4 vcl/inc/impbmp.hxx | 5 vcl/inc/opengl/framebuffer.hxx | 8 vcl/inc/opengl/salbmp.hxx | 4 vcl/inc/openglgdiimpl.hxx | 2 vcl/inc/quartz/salbmp.h | 4 vcl/inc/salbmp.hxx | 5 vcl/inc/unx/salbmp.h | 4 vcl/inc/win/salbmp.h | 4 vcl/opengl/framebuffer.cxx | 26 +- vcl/opengl/gdiimpl.cxx | 36 +-- vcl/opengl/salbmp.cxx | 34 +- vcl/opengl/scale.cxx | 2 vcl/quartz/salbmp.cxx | 6 vcl/source/gdi/bitmap.cxx | 23 + vcl/source/gdi/bmpacc.cxx | 138 ++++++----- vcl/source/gdi/impbmp.cxx | 10 vcl/source/opengl/OpenGLContext.cxx | 271 ++++++++++++++++------- vcl/unx/generic/gdi/cairotextrender.cxx | 4 vcl/unx/generic/gdi/gdiimpl.cxx | 12 - vcl/unx/generic/gdi/openglx11cairotextrender.cxx | 39 +++ vcl/unx/generic/gdi/openglx11cairotextrender.hxx | 1 vcl/unx/generic/gdi/salbmp.cxx | 6 vcl/unx/generic/gdi/x11cairotextrender.cxx | 6 vcl/unx/generic/gdi/x11cairotextrender.hxx | 1 vcl/unx/generic/window/salframe.cxx | 11 vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx | 11 vcl/unx/gtk/window/gtksalframe.cxx | 8 vcl/win/source/gdi/gdiimpl.cxx | 3 vcl/win/source/gdi/salbmp.cxx | 24 +- 38 files changed, 582 insertions(+), 285 deletions(-)
New commits: commit b9c25fcc0d6aff0910348dcf3a53c16179f9ab56 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Thu Dec 4 22:27:38 2014 -0500 vcl: Don't keep a reference to the texture in the FBO object Change-Id: I240d2b44e77d28af3cd5952b6d666a1709c4c54a diff --git a/vcl/inc/opengl/framebuffer.hxx b/vcl/inc/opengl/framebuffer.hxx index e9c9065..915008c 100644 --- a/vcl/inc/opengl/framebuffer.hxx +++ b/vcl/inc/opengl/framebuffer.hxx @@ -18,10 +18,10 @@ class VCL_PLUGIN_PUBLIC OpenGLFramebuffer { private: - GLuint mnId; - OpenGLTexture maAttachedTexture; + GLuint mnId; int mnWidth; int mnHeight; + GLuint mnAttachedTexture; public: OpenGLFramebuffer(); diff --git a/vcl/opengl/framebuffer.cxx b/vcl/opengl/framebuffer.cxx index e760b53..c4dfb05 100644 --- a/vcl/opengl/framebuffer.cxx +++ b/vcl/opengl/framebuffer.cxx @@ -17,6 +17,7 @@ OpenGLFramebuffer::OpenGLFramebuffer() : mnId( 0 ), mnWidth( 0 ), mnHeight( 0 ), + mnAttachedTexture( 0 ), mpPrevFramebuffer( NULL ), mpNextFramebuffer( NULL ) { @@ -45,30 +46,37 @@ void OpenGLFramebuffer::Unbind() bool OpenGLFramebuffer::IsFree() const { - return (!maAttachedTexture); + return (!mnAttachedTexture); } bool OpenGLFramebuffer::IsAttached( const OpenGLTexture& rTexture ) const { - return ( maAttachedTexture == rTexture ); + return ( mnAttachedTexture == rTexture.Id() ); } void OpenGLFramebuffer::AttachTexture( const OpenGLTexture& rTexture ) { + if( rTexture.Id() == mnAttachedTexture ) + return; + SAL_INFO( "vcl.opengl", "Attaching texture " << rTexture.Id() << " to framebuffer " << (int)mnId ); - maAttachedTexture = rTexture; + mnAttachedTexture = rTexture.Id(); mnWidth = rTexture.GetWidth(); mnHeight = rTexture.GetHeight(); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - maAttachedTexture.Id(), 0 ); + mnAttachedTexture, 0 ); CHECK_GL_ERROR(); } void OpenGLFramebuffer::DetachTexture() { - maAttachedTexture = OpenGLTexture(); - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0 ); - CHECK_GL_ERROR(); + if( mnAttachedTexture != 0 ) + { + CHECK_GL_ERROR(); + mnAttachedTexture = 0; + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0 ); + CHECK_GL_ERROR(); + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 01bed8089af907e7c0fb8e053d55bffb1eb81aac Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Thu Dec 4 22:25:56 2014 -0500 vcl: Re-use a framebuffer of the same size when possible Conflicts: include/vcl/opengl/OpenGLContext.hxx Change-Id: Id9c7932976ce9d9282776c20d93d9cca4d290056 diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx index 21f45d2..a98f825 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -208,18 +208,21 @@ public: // use these methods right after setting a context to make sure drawing happens // in the right FBO (default one is for onscreen painting) + bool BindFramebuffer( OpenGLFramebuffer* pFramebuffer ); bool AcquireDefaultFramebuffer(); - bool AcquireFramebuffer( OpenGLFramebuffer* pFramebuffer ); OpenGLFramebuffer* AcquireFramebuffer( const OpenGLTexture& rTexture ); void ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer ); void AddRef(); void DeRef(); + void ReleaseFramebuffer( const OpenGLTexture& rTexture ); + 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 ); bool isCurrent(); + void clearCurrent(); void makeCurrent(); void resetCurrent(); void swapBuffers(); diff --git a/vcl/inc/opengl/framebuffer.hxx b/vcl/inc/opengl/framebuffer.hxx index 4ccc1c5..e9c9065 100644 --- a/vcl/inc/opengl/framebuffer.hxx +++ b/vcl/inc/opengl/framebuffer.hxx @@ -20,12 +20,16 @@ class VCL_PLUGIN_PUBLIC OpenGLFramebuffer private: GLuint mnId; OpenGLTexture maAttachedTexture; + int mnWidth; + int mnHeight; public: OpenGLFramebuffer(); virtual ~OpenGLFramebuffer(); GLuint Id() const { return mnId; }; + int GetWidth() const { return mnWidth; }; + int GetHeight() const { return mnHeight; }; void Bind(); void Unbind(); diff --git a/vcl/opengl/framebuffer.cxx b/vcl/opengl/framebuffer.cxx index 29f9a78..e760b53 100644 --- a/vcl/opengl/framebuffer.cxx +++ b/vcl/opengl/framebuffer.cxx @@ -15,6 +15,8 @@ OpenGLFramebuffer::OpenGLFramebuffer() : mnId( 0 ), + mnWidth( 0 ), + mnHeight( 0 ), mpPrevFramebuffer( NULL ), mpNextFramebuffer( NULL ) { @@ -55,6 +57,8 @@ void OpenGLFramebuffer::AttachTexture( const OpenGLTexture& rTexture ) { SAL_INFO( "vcl.opengl", "Attaching texture " << rTexture.Id() << " to framebuffer " << (int)mnId ); maAttachedTexture = rTexture; + mnWidth = rTexture.GetWidth(); + mnHeight = rTexture.GetHeight(); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, maAttachedTexture.Id(), 0 ); CHECK_GL_ERROR(); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 4edd843..9520c86 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -120,6 +120,8 @@ void OpenGLSalGraphicsImpl::Init() maOffscreenTex.GetWidth() != GetWidth() || maOffscreenTex.GetHeight() != GetHeight() ) { + if( mpContext ) // valid context + mpContext->ReleaseFramebuffer( maOffscreenTex ); maOffscreenTex = OpenGLTexture(); } } @@ -161,15 +163,18 @@ void OpenGLSalGraphicsImpl::PostDraw() mpProgram = NULL; } - mpContext->ReleaseFramebuffer( mpFramebuffer ); - mpFramebuffer = NULL; - CHECK_GL_ERROR(); } void OpenGLSalGraphicsImpl::freeResources() { // TODO Delete shaders, programs and textures if not shared + if( mbOffscreen && mpContext && mpContext->isInitialized() ) + { + mpContext->makeCurrent(); + mpContext->ReleaseFramebuffer( maOffscreenTex ); + } + ReleaseContext(); } void OpenGLSalGraphicsImpl::ImplSetClipBit( const vcl::Region& rClip, GLuint nMask ) @@ -1429,6 +1434,7 @@ void OpenGLSalGraphicsImpl::endPaint() if( mpContext->mnPainting == 0 && !mbOffscreen ) { mpContext->makeCurrent(); + mpContext->AcquireDefaultFramebuffer(); glFlush(); } } diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index 4715025..5e9e942 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -35,6 +35,8 @@ using namespace com::sun::star; +#define MAX_FRAMEBUFFER_COUNT 30 + // TODO use rtl::Static instead of 'static' #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID static std::vector<GLXContext> g_vShareList; @@ -57,6 +59,7 @@ OpenGLContext::OpenGLContext(): mbRequestLegacyContext(false), mbUseDoubleBufferedRendering(true), mbRequestVirtualDevice(false), + mnFramebufferCount(0), mpCurrentFramebuffer(NULL), mpFirstFramebuffer(NULL), mpLastFramebuffer(NULL), @@ -1281,6 +1284,18 @@ bool OpenGLContext::isCurrent() glXGetCurrentDrawable() == nDrawable); #endif } + +void OpenGLContext::clearCurrent() +{ + ImplSVData* pSVData = ImplGetSVData(); + + // release all framebuffers from the old context so we can re-attach the + // texture in the new context + OpenGLContext* pCurrentCtx = pSVData->maGDIData.mpLastContext; + if( pCurrentCtx && pCurrentCtx->isCurrent() ) + pCurrentCtx->ReleaseFramebuffers(); +} + void OpenGLContext::makeCurrent() { ImplSVData* pSVData = ImplGetSVData(); @@ -1288,6 +1303,8 @@ void OpenGLContext::makeCurrent() if (isCurrent()) return; + clearCurrent(); + #if defined( WNT ) if (!wglMakeCurrent(m_aGLWin.hDC, m_aGLWin.hRC)) { @@ -1328,6 +1345,8 @@ void OpenGLContext::makeCurrent() void OpenGLContext::resetCurrent() { + clearCurrent(); + #if defined( WNT ) wglMakeCurrent( m_aGLWin.hDC, 0 ); #elif defined( MACOSX ) @@ -1395,14 +1414,10 @@ NSOpenGLView* OpenGLContext::getOpenGLView() } #endif -bool OpenGLContext::AcquireFramebuffer( OpenGLFramebuffer* pFramebuffer ) +bool OpenGLContext::BindFramebuffer( OpenGLFramebuffer* pFramebuffer ) { if( pFramebuffer != mpCurrentFramebuffer ) { - // release the attached texture so it's available from the other contexts - //if( mpCurrentFramebuffer ) - // mpCurrentFramebuffer->DetachTexture(); - if( pFramebuffer ) pFramebuffer->Bind(); else @@ -1415,13 +1430,14 @@ bool OpenGLContext::AcquireFramebuffer( OpenGLFramebuffer* pFramebuffer ) bool OpenGLContext::AcquireDefaultFramebuffer() { - return AcquireFramebuffer( NULL ); + return BindFramebuffer( NULL ); } OpenGLFramebuffer* OpenGLContext::AcquireFramebuffer( const OpenGLTexture& rTexture ) { OpenGLFramebuffer* pFramebuffer = NULL; - OpenGLFramebuffer* pFreeFramebuffer = NULL; + OpenGLFramebuffer* pFreeFbo = NULL; + OpenGLFramebuffer* pSameSizeFbo = NULL; // check if there is already a framebuffer attached to that texture pFramebuffer = mpLastFramebuffer; @@ -1429,18 +1445,27 @@ OpenGLFramebuffer* OpenGLContext::AcquireFramebuffer( const OpenGLTexture& rText { if( pFramebuffer->IsAttached( rTexture ) ) break; - if( !pFreeFramebuffer && pFramebuffer->IsFree() ) - pFreeFramebuffer = pFramebuffer; + if( !pFreeFbo && pFramebuffer->IsFree() ) + pFreeFbo = pFramebuffer; + if( !pSameSizeFbo && + pFramebuffer->GetWidth() == rTexture.GetWidth() && + pFramebuffer->GetHeight() == rTexture.GetHeight() ) + pSameSizeFbo = pFramebuffer; pFramebuffer = pFramebuffer->mpPrevFramebuffer; } + // else use any framebuffer having the same size + if( !pFramebuffer && pSameSizeFbo ) + pFramebuffer = pSameSizeFbo; + // else use the first free framebuffer - if( !pFramebuffer && pFreeFramebuffer ) - pFramebuffer = pFreeFramebuffer; + if( !pFramebuffer && pFreeFbo ) + pFramebuffer = pFreeFbo; - // if there isn't any free one, create a new one - if( !pFramebuffer ) + // if there isn't any free one, create a new one if the limit isn't reached + if( !pFramebuffer && mnFramebufferCount < MAX_FRAMEBUFFER_COUNT ) { + mnFramebufferCount++; pFramebuffer = new OpenGLFramebuffer(); if( mpLastFramebuffer ) { @@ -1455,9 +1480,14 @@ OpenGLFramebuffer* OpenGLContext::AcquireFramebuffer( const OpenGLTexture& rText } } - AcquireFramebuffer( pFramebuffer ); - if( pFramebuffer->IsFree() ) - pFramebuffer->AttachTexture( rTexture ); + // last try, use any framebuffer + // TODO order the list of framebuffers as a LRU + if( !pFramebuffer ) + pFramebuffer = mpFirstFramebuffer; + + assert( pFramebuffer ); + BindFramebuffer( pFramebuffer ); + pFramebuffer->AttachTexture( rTexture ); glViewport( 0, 0, rTexture.GetWidth(), rTexture.GetHeight() ); return pFramebuffer; @@ -1469,6 +1499,32 @@ void OpenGLContext::ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer ) pFramebuffer->DetachTexture(); } +void OpenGLContext::ReleaseFramebuffer( const OpenGLTexture& rTexture ) +{ + OpenGLFramebuffer* pFramebuffer = mpLastFramebuffer; + + while( pFramebuffer ) + { + if( pFramebuffer->IsAttached( rTexture ) ) + { + BindFramebuffer( pFramebuffer ); + pFramebuffer->DetachTexture(); + } + pFramebuffer = pFramebuffer->mpPrevFramebuffer; + } +} + +void OpenGLContext::ReleaseFramebuffers() +{ + OpenGLFramebuffer* pFramebuffer = mpLastFramebuffer; + while( pFramebuffer ) + { + BindFramebuffer( pFramebuffer ); + pFramebuffer->DetachTexture(); + pFramebuffer = pFramebuffer->mpPrevFramebuffer; + } +} + OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader ) { boost::unordered_map<ProgramKey, OpenGLProgram*>::iterator it; commit 4c424d785275494835287aa3c171ee2fd5c4f884 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Thu Dec 4 22:21:50 2014 -0500 vcl: Keep the same context for VirtualDevice to avoid FBO switches Change-Id: I66496fae902db9df5b8301b00bb779f42adaa7a7 diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 86a5929..4edd843 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -56,8 +56,8 @@ OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl() OpenGLContext* OpenGLSalGraphicsImpl::GetOpenGLContext() { - if( !mpContext ) - AcquireContext(); + if( !AcquireContext() ) + return NULL; return mpContext; } @@ -71,7 +71,11 @@ bool OpenGLSalGraphicsImpl::AcquireContext( ) ImplSVData* pSVData = ImplGetSVData(); if( mpContext ) + { + if( mpContext->isInitialized() ) + return true; mpContext->DeRef(); + } OpenGLContext* pContext = pSVData->maGDIData.mpLastContext; @@ -122,7 +126,7 @@ void OpenGLSalGraphicsImpl::Init() void OpenGLSalGraphicsImpl::PreDraw() { - if( !mpContext && !AcquireContext() ) + if( !AcquireContext() ) { SAL_WARN( "vcl.opengl", "Couldn't acquire context" ); return; @@ -161,11 +165,6 @@ void OpenGLSalGraphicsImpl::PostDraw() mpFramebuffer = NULL; CHECK_GL_ERROR(); - - // release the context as there is no guarantee the underlying window - // will still be valid for the next draw operation - if( mbOffscreen ) - ReleaseContext(); } void OpenGLSalGraphicsImpl::freeResources() @@ -1414,7 +1413,7 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, void OpenGLSalGraphicsImpl::beginPaint() { - if( !mpContext && !AcquireContext() ) + if( !AcquireContext() ) return; mpContext->mnPainting++; @@ -1422,7 +1421,7 @@ void OpenGLSalGraphicsImpl::beginPaint() void OpenGLSalGraphicsImpl::endPaint() { - if( !mpContext && !AcquireContext() ) + if( !AcquireContext() ) return; mpContext->mnPainting--; commit 2e512773095216acbac83e6fd71f6d0444263d70 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Thu Dec 4 22:17:58 2014 -0500 vcl: Reset context when the backend window is destroyed Conflicts: vcl/source/opengl/OpenGLContext.cxx Change-Id: Ie2b93de8efe5ea56b0420adf23639c0153103385 diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx index a78972c..21f45d2 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -204,6 +204,7 @@ public: #elif defined( _WIN32 ) bool init( HDC hDC, HWND hWnd ); #endif + void reset(); // use these methods right after setting a context to make sure drawing happens // in the right FBO (default one is for onscreen painting) @@ -218,6 +219,7 @@ public: OpenGLProgram* GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader ); OpenGLProgram* UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader ); + bool isCurrent(); void makeCurrent(); void resetCurrent(); void swapBuffers(); diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx index 20ef2c4..61d8358 100644 --- a/vcl/opengl/salbmp.cxx +++ b/vcl/opengl/salbmp.cxx @@ -471,6 +471,8 @@ void OpenGLSalBitmap::makeCurrent() // TODO: make sure we can really use the last used context mpContext = pSVData->maGDIData.mpLastContext; + while( mpContext && !mpContext->isInitialized() ) + mpContext = mpContext->mpPrevContext; if( !mpContext ) mpContext = GetBitmapContext(); assert(mpContext && "Couldn't get an OpenGL context"); diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index c068cd8..4715025 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -84,6 +84,8 @@ OpenGLContext::OpenGLContext(): OpenGLContext::~OpenGLContext() { SAL_INFO("vcl.opengl", "delete context: " << this); + reset(); + ImplSVData* pSVData = ImplGetSVData(); if( mpPrevContext ) mpPrevContext->mpNextContext = mpNextContext; @@ -93,39 +95,6 @@ OpenGLContext::~OpenGLContext() mpNextContext->mpPrevContext = mpPrevContext; else pSVData->maGDIData.mpLastContext = mpPrevContext; -#if defined( WNT ) - if (m_aGLWin.hRC) - { - std::vector<HGLRC>::iterator itr = std::remove(g_vShareList.begin(), g_vShareList.end(), m_aGLWin.hRC); - if (itr != g_vShareList.end()) - g_vShareList.erase(itr); - - wglMakeCurrent( m_aGLWin.hDC, 0 ); - wglDeleteContext( m_aGLWin.hRC ); - ReleaseDC( m_aGLWin.hWnd, m_aGLWin.hDC ); - } -#elif defined( MACOSX ) - OpenGLWrapper::resetCurrent(); -#elif defined( IOS ) || defined( ANDROID ) - // nothing -#elif defined( UNX ) - if(m_aGLWin.ctx) - { - std::vector<GLXContext>::iterator itr = std::remove( g_vShareList.begin(), g_vShareList.end(), m_aGLWin.ctx ); - if (itr != g_vShareList.end()) - g_vShareList.erase(itr); - - glXMakeCurrent(m_aGLWin.dpy, None, NULL); - if( glGetError() != GL_NO_ERROR ) - { - SAL_WARN("vcl.opengl", "glError: " << (char *)gluErrorString(glGetError())); - } - glXDestroyContext(m_aGLWin.dpy, m_aGLWin.ctx); - - if (mbPixmap && m_aGLWin.glPix != None) - glXDestroyPixmap(m_aGLWin.dpy, m_aGLWin.glPix); - } -#endif } void OpenGLContext::AddRef() @@ -1162,6 +1131,86 @@ void OpenGLContext::initGLWindow(Visual* pVisual) #endif +void OpenGLContext::reset() +{ + if( !mbInitialized ) + return; + + // reset the clip region + maClipRegion.SetEmpty(); + + // destroy all framebuffers + if( mpLastFramebuffer ) + { + OpenGLFramebuffer* pFramebuffer = mpLastFramebuffer; + + makeCurrent(); + while( pFramebuffer ) + { + OpenGLFramebuffer* pPrevFramebuffer = pFramebuffer->mpPrevFramebuffer; + delete pFramebuffer; + pFramebuffer = pPrevFramebuffer; + } + mpFirstFramebuffer = NULL; + mpLastFramebuffer = NULL; + } + + // 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(); + } + + if( isCurrent() ) + resetCurrent(); + + mbInitialized = false; + + // destroy the context itself +#if defined( WNT ) + if (m_aGLWin.hRC) + { + std::vector<HGLRC>::iterator itr = std::remove(g_vShareList.begin(), g_vShareList.end(), m_aGLWin.hRC); + if (itr != g_vShareList.end()) + g_vShareList.erase(itr); + + wglMakeCurrent( m_aGLWin.hDC, 0 ); + wglDeleteContext( m_aGLWin.hRC ); + ReleaseDC( m_aGLWin.hWnd, m_aGLWin.hDC ); + } +#elif defined( MACOSX ) + OpenGLWrapper::resetCurrent(); +#elif defined( IOS ) || defined( ANDROID ) + // nothing +#elif defined( UNX ) + if(m_aGLWin.ctx) + { + std::vector<GLXContext>::iterator itr = std::remove( g_vShareList.begin(), g_vShareList.end(), m_aGLWin.ctx ); + if (itr != g_vShareList.end()) + g_vShareList.erase(itr); + + glXMakeCurrent(m_aGLWin.dpy, None, NULL); + if( glGetError() != GL_NO_ERROR ) + { + SAL_WARN("vcl.opengl", "glError: " << (char *)gluErrorString(glGetError())); + } + glXDestroyContext(m_aGLWin.dpy, m_aGLWin.ctx); + + if (mbPixmap && m_aGLWin.glPix != None) + glXDestroyPixmap(m_aGLWin.dpy, m_aGLWin.glPix); + } +#endif +} + #if defined( WNT ) || defined( MACOSX ) || defined( IOS ) || defined( ANDROID ) SystemWindowData OpenGLContext::generateWinData(vcl::Window* /*pParent*/, bool bRequestLegacyContext) @@ -1217,17 +1266,33 @@ SystemWindowData OpenGLContext::generateWinData(vcl::Window* pParent, bool) #endif +bool OpenGLContext::isCurrent() +{ +#if defined( WNT ) + return (wglGetCurrentContext() == m_aGLWin.hRC && + wglGetCurrentDC() == m_aGLWin.hDC); +#elif defined( MACOSX ) + return false; +#elif defined( IOS ) || defined( ANDROID ) + return false; +#elif defined( UNX ) + GLXDrawable nDrawable = mbPixmap ? m_aGLWin.glPix : m_aGLWin.win; + return (glXGetCurrentContext() == m_aGLWin.ctx && + glXGetCurrentDrawable() == nDrawable); +#endif +} void OpenGLContext::makeCurrent() { + ImplSVData* pSVData = ImplGetSVData(); + + if (isCurrent()) + return; + #if defined( WNT ) - if (wglGetCurrentContext() == m_aGLWin.hRC && - wglGetCurrentDC() == m_aGLWin.hDC) - { - SAL_INFO("vcl.opengl", "OpenGLContext::makeCurrent(): Avoid setting the same context"); - } - else if (!wglMakeCurrent(m_aGLWin.hDC, m_aGLWin.hRC)) + if (!wglMakeCurrent(m_aGLWin.hDC, m_aGLWin.hRC)) { SAL_WARN("vcl.opengl", "OpenGLContext::makeCurrent(): wglMakeCurrent failed: " << GetLastError()); + return; } #elif defined( MACOSX ) NSOpenGLView* pView = getOpenGLView(); @@ -1236,33 +1301,29 @@ void OpenGLContext::makeCurrent() // nothing #elif defined( UNX ) GLXDrawable nDrawable = mbPixmap ? m_aGLWin.glPix : m_aGLWin.win; - static int nSwitch = 0; - if (glXGetCurrentContext() == m_aGLWin.ctx && - glXGetCurrentDrawable() == nDrawable) + if (!glXMakeCurrent( m_aGLWin.dpy, nDrawable, m_aGLWin.ctx )) { - ; // no-op - } - else if (!glXMakeCurrent( m_aGLWin.dpy, nDrawable, m_aGLWin.ctx )) SAL_WARN("vcl.opengl", "OpenGLContext::makeCurrent failed on drawable " << nDrawable << " pixmap? " << mbPixmap); - else + return; + } +#endif + + // move the context at the end of the contexts list + static int nSwitch = 0; + SAL_INFO("vcl.opengl", "******* CONTEXT SWITCH " << ++nSwitch << " *********"); + if( mpNextContext ) { - SAL_INFO("vcl.opengl", "******* CONTEXT SWITCH " << ++nSwitch << " *********"); - ImplSVData* pSVData = ImplGetSVData(); - if( mpNextContext ) - { - if( mpPrevContext ) - mpPrevContext->mpNextContext = mpNextContext; - else - pSVData->maGDIData.mpFirstContext = mpNextContext; - mpNextContext->mpPrevContext = mpPrevContext; + if( mpPrevContext ) + mpPrevContext->mpNextContext = mpNextContext; + else + pSVData->maGDIData.mpFirstContext = mpNextContext; + mpNextContext->mpPrevContext = mpPrevContext; - mpPrevContext = pSVData->maGDIData.mpLastContext; - mpNextContext = NULL; - pSVData->maGDIData.mpLastContext->mpNextContext = this; - pSVData->maGDIData.mpLastContext = this; - } + mpPrevContext = pSVData->maGDIData.mpLastContext; + mpNextContext = NULL; + pSVData->maGDIData.mpLastContext->mpNextContext = this; + pSVData->maGDIData.mpLastContext = this; } -#endif } void OpenGLContext::resetCurrent() diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx index 4d3c244..5656748 100644 --- a/vcl/unx/generic/window/salframe.cxx +++ b/vcl/unx/generic/window/salframe.cxx @@ -34,6 +34,7 @@ #include "vcl/printerinfomanager.hxx" #include "vcl/settings.hxx" #include "vcl/bmpacc.hxx" +#include "vcl/opengl/OpenGLContext.hxx" #include <prex.h> #include <X11/Xatom.h> @@ -65,6 +66,7 @@ #include <sal/macros.h> #include <com/sun/star/uno/Exception.hpp> +#include "svdata.hxx" #include "svids.hrc" #include "impbmp.hxx" @@ -889,6 +891,15 @@ X11SalFrame::~X11SalFrame() delete pFreeGraphics_; } + // reset all OpenGL contexts using this window + OpenGLContext* pContext = ImplGetSVData()->maGDIData.mpLastContext; + while( pContext ) + { + if( pContext->getOpenGLWindow().win == mhWindow ) + pContext->reset(); + pContext = pContext->mpPrevContext; + } + XDestroyWindow( GetXDisplay(), mhWindow ); /* commit f0f5f50243810762e27f1207b3c08b60ed888ee3 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Thu Dec 4 11:45:55 2014 -0500 vcl: Limit Cairo surface size to the clipping region to improve performance Conflicts: vcl/unx/generic/gdi/openglx11cairotextrender.cxx Change-Id: I469b34c9f1047a274550229391d3dfb578291df6 diff --git a/vcl/inc/cairotextrender.hxx b/vcl/inc/cairotextrender.hxx index e5db2ab..2b8a21e 100644 --- a/vcl/inc/cairotextrender.hxx +++ b/vcl/inc/cairotextrender.hxx @@ -77,6 +77,7 @@ class CairoTextRender : public TextRenderImpl protected: virtual GlyphCache& getPlatformGlyphCache() = 0; virtual cairo_surface_t* getCairoSurface() = 0; + virtual void getSurfaceOffset(double& nDX, double& nDY) = 0; virtual void drawSurface(cairo_t* cr) = 0; bool setFont( const FontSelectPattern *pEntry, int nFallbackLevel ); diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 03d1c23..a8ffe4d 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -129,7 +129,9 @@ public: virtual void freeResources() SAL_OVERRIDE; + virtual const vcl::Region& getClipRegion() const; virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE; + // // get the depth of the device virtual sal_uInt16 GetBitCount() const SAL_OVERRIDE; diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index f4fb17d..86a5929 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -225,6 +225,11 @@ void OpenGLSalGraphicsImpl::ImplInitClipRegion() CHECK_GL_ERROR(); } +const vcl::Region& OpenGLSalGraphicsImpl::getClipRegion() const +{ + return maClipRegion; +} + bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip ) { SAL_INFO( "vcl.opengl", "::setClipRegion " << rClip ); diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx index 5b31b92..589b53a 100644 --- a/vcl/unx/generic/gdi/cairotextrender.cxx +++ b/vcl/unx/generic/gdi/cairotextrender.cxx @@ -222,6 +222,10 @@ void CairoTextRender::DrawServerFontLayout( const ServerFontLayout& rLayout ) if (const void *pOptions = Application::GetSettings().GetStyleSettings().GetCairoFontOptions()) cairo_set_font_options(cr, static_cast<const cairo_font_options_t*>(pOptions)); + double nDX, nDY; + getSurfaceOffset(nDX, nDY); + cairo_translate(cr, nDX, nDY); + clipRegion(cr); cairo_set_source_rgb(cr, diff --git a/vcl/unx/generic/gdi/openglx11cairotextrender.cxx b/vcl/unx/generic/gdi/openglx11cairotextrender.cxx index f16fe96..7b4e664 100644 --- a/vcl/unx/generic/gdi/openglx11cairotextrender.cxx +++ b/vcl/unx/generic/gdi/openglx11cairotextrender.cxx @@ -25,10 +25,32 @@ cairo_surface_t* OpenGLX11CairoTextRender::getCairoSurface() // static size_t id = 0; // OString aFileName = OString("/tmp/libo_logs/text_rendering") + OString::number(id++) + OString(".svg"); // cairo_surface_t* surface = cairo_svg_surface_create(aFileName.getStr(), GetWidth(), GetHeight()); - cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, GetWidth(), GetHeight()); + cairo_surface_t* surface = NULL; + OpenGLSalGraphicsImpl *pImpl = dynamic_cast< OpenGLSalGraphicsImpl* >(mrParent.GetImpl()); + if( pImpl ) + { + Rectangle aClipRect = pImpl->getClipRegion().GetBoundRect(); + if( aClipRect.GetWidth() == 0 || aClipRect.GetHeight() == 0 ) + { + aClipRect.setWidth( GetWidth() ); + aClipRect.setHeight( GetHeight() ); + } + surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, aClipRect.GetWidth(), aClipRect.GetHeight() ); + } return surface; } +void OpenGLX11CairoTextRender::getSurfaceOffset( double& nDX, double& nDY ) +{ + OpenGLSalGraphicsImpl *pImpl = dynamic_cast< OpenGLSalGraphicsImpl* >(mrParent.GetImpl()); + if( pImpl ) + { + Rectangle aClipRect = pImpl->getClipRegion().GetBoundRect(); + nDX = -aClipRect.Left(); + nDY = -aClipRect.Top(); + } +} + void OpenGLX11CairoTextRender::drawSurface(cairo_t* cr) { // XXX: lfrb: GLES 2.0 doesn't support GL_UNSIGNED_INT_8_8_8_8_REV @@ -42,7 +64,20 @@ void OpenGLX11CairoTextRender::drawSurface(cairo_t* cr) cairo_surface_flush( pSurface ); unsigned char *pSrc = cairo_image_surface_get_data( pSurface ); - SalTwoRect aRect(0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight); + // XXX: lfrb: GLES 2.0 doesn't support GL_UNSIGNED_INT_8_8_8_8_REV + Rectangle aClipRect = pImpl->getClipRegion().GetBoundRect(); + + SalTwoRect aRect(0, 0, nWidth, nHeight, + aClipRect.Left(), aClipRect.Top(), nWidth, nHeight); + aRect.mnSrcX = 0; + aRect.mnSrcY = 0; + aRect.mnSrcWidth = nWidth; + aRect.mnSrcHeight = nHeight; + aRect.mnDestX = aClipRect.Left(); + aRect.mnDestY = aClipRect.Top(); + aRect.mnDestWidth = nWidth; + aRect.mnDestHeight = nHeight; + // Cairo surface data is ARGB with premultiplied alpha and is Y-inverted OpenGLTexture aTexture( nWidth, nHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pSrc ); pImpl->PreDraw(); diff --git a/vcl/unx/generic/gdi/openglx11cairotextrender.hxx b/vcl/unx/generic/gdi/openglx11cairotextrender.hxx index 87ef948..1719496 100644 --- a/vcl/unx/generic/gdi/openglx11cairotextrender.hxx +++ b/vcl/unx/generic/gdi/openglx11cairotextrender.hxx @@ -18,6 +18,7 @@ public: OpenGLX11CairoTextRender(bool bPrinter, X11SalGraphics& rParent); virtual cairo_surface_t* getCairoSurface() SAL_OVERRIDE; + virtual void getSurfaceOffset(double& nDX, double& nDY) SAL_OVERRIDE; virtual void drawSurface(cairo_t* cr) SAL_OVERRIDE; }; diff --git a/vcl/unx/generic/gdi/x11cairotextrender.cxx b/vcl/unx/generic/gdi/x11cairotextrender.cxx index 0449b98..f3aa47d 100644 --- a/vcl/unx/generic/gdi/x11cairotextrender.cxx +++ b/vcl/unx/generic/gdi/x11cairotextrender.cxx @@ -77,6 +77,12 @@ cairo_surface_t* X11CairoTextRender::getCairoSurface() return surface; } +void X11CairoTextRender::getSurfaceOffset( double& nDX, double& nDY ) +{ + nDX = 0; + nDY = 0; +} + void X11CairoTextRender::clipRegion(cairo_t* cr) { Region pClipRegion = mrParent.mpClipRegion; diff --git a/vcl/unx/generic/gdi/x11cairotextrender.hxx b/vcl/unx/generic/gdi/x11cairotextrender.hxx index fb0c130..1449b3a 100644 --- a/vcl/unx/generic/gdi/x11cairotextrender.hxx +++ b/vcl/unx/generic/gdi/x11cairotextrender.hxx @@ -41,6 +41,7 @@ public: virtual GlyphCache& getPlatformGlyphCache() SAL_OVERRIDE; virtual cairo_surface_t* getCairoSurface() SAL_OVERRIDE; + virtual void getSurfaceOffset(double& nDX, double& nDY) SAL_OVERRIDE; virtual void clipRegion(cairo_t* cr) SAL_OVERRIDE; virtual void drawSurface(cairo_t* cr) SAL_OVERRIDE; }; commit 6e4a34018473652e981f1b85ebfaedddc9e0aea2 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Wed Dec 3 17:05:01 2014 -0500 vcl: Reset data buffer after resizing bitmap on GPU Change-Id: I516cdbc466f3d6427e36fea8c5cdbe718ce7d0ea diff --git a/vcl/opengl/scale.cxx b/vcl/opengl/scale.cxx index 7bcf7c0..4703c1f 100644 --- a/vcl/opengl/scale.cxx +++ b/vcl/opengl/scale.cxx @@ -192,6 +192,7 @@ bool OpenGLSalBitmap::ImplScale( const double& rScaleX, const double& rScaleY, s { SAL_INFO( "vcl.opengl", "::ImplScale" ); + maUserBuffer.reset(); makeCurrent(); if( nScaleFlag == BMP_SCALE_FAST ) @@ -253,7 +254,6 @@ bool OpenGLSalBitmap::Scale( const double& rScaleX, const double& rScaleY, sal_u nScaleFlag == BMP_SCALE_SUPER || nScaleFlag == BMP_SCALE_LANCZOS ) { - //TODO maUserBuffer.reset(); makeCurrent(); if( mpContext == NULL ) { commit 6ecff9b87e2dd1e5bf72e24003e2a038d497db51 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Wed Dec 3 17:04:15 2014 -0500 vcl: Use right size to draw native GTK window background Change-Id: Id446d20599f072f657c6106d6c6457fce08830e6 diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index 598005d..d0f2bf2 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -1551,13 +1551,11 @@ bool GtkSalGraphics::NWPaintGTKFrame( bool GtkSalGraphics::NWPaintGTKWindowBackground( GdkDrawable* gdkDrawable, ControlType, ControlPart, - const Rectangle& /* rControlRectangle */, + const Rectangle& rControlRectangle, const clipList& rClipList, ControlState /* nState */, const ImplControlValue&, const OUString& ) { - int w,h; - gtk_window_get_size(GTK_WINDOW(m_pWindow),&w,&h); GdkRectangle clipRect; for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it ) { @@ -1566,7 +1564,12 @@ bool GtkSalGraphics::NWPaintGTKWindowBackground( clipRect.width = it->GetWidth(); clipRect.height = it->GetHeight(); - gtk_paint_flat_box(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,GTK_SHADOW_NONE,&clipRect,m_pWindow,"base",0,0,w,h); + gtk_paint_flat_box(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,GTK_SHADOW_NONE,&clipRect, + m_pWindow,"base", + rControlRectangle.Left(), + rControlRectangle.Top(), + rControlRectangle.GetWidth(), + rControlRectangle.GetHeight()); } return true; commit 83861ce123c2d7b1ce9c6acfbc0e457662eac944 Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Wed Dec 3 17:02:37 2014 -0500 vcl: Add BitmapInfoAccess for bitmaps' metadata access Change-Id: Iec9f8c7d8f7cded0aef9e017373e44387dc0b05c diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx index 6e445e3..80b76e4 100644 --- a/include/vcl/bitmap.hxx +++ b/include/vcl/bitmap.hxx @@ -294,6 +294,7 @@ private: } }; +class BitmapInfoAccess; class BitmapReadAccess; class BitmapWriteAccess; class BitmapPalette; @@ -850,9 +851,10 @@ public: public: + BitmapInfoAccess* AcquireInfoAccess(); BitmapReadAccess* AcquireReadAccess(); BitmapWriteAccess* AcquireWriteAccess(); - void ReleaseAccess( BitmapReadAccess* pAccess ); + void ReleaseAccess( BitmapInfoAccess* pAccess ); typedef vcl::ScopedBitmapAccess< BitmapReadAccess, Bitmap, &Bitmap::AcquireReadAccess > ScopedReadAccess; diff --git a/include/vcl/bmpacc.hxx b/include/vcl/bmpacc.hxx index 252599b..bc43dbf 100644 --- a/include/vcl/bmpacc.hxx +++ b/include/vcl/bmpacc.hxx @@ -62,14 +62,14 @@ typedef BitmapColor (*FncGetPixel)( ConstScanline pScanline, long nX, const Colo typedef void (*FncSetPixel)( Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask ); -// - BitmapReadAccess - -class VCL_DLLPUBLIC BitmapReadAccess +// - BitmapInfoAccess - +class VCL_DLLPUBLIC BitmapInfoAccess { - friend class BitmapWriteAccess; + friend class BitmapReadAccess; public: - BitmapReadAccess( Bitmap& rBitmap ); - virtual ~BitmapReadAccess(); + BitmapInfoAccess( Bitmap& rBitmap ); + virtual ~BitmapInfoAccess(); inline bool operator!() const; @@ -87,9 +87,6 @@ public: inline sal_uInt16 GetBitCount() const; inline BitmapColor GetBestMatchingColor( const BitmapColor& rBitmapColor ); - inline Scanline GetBuffer() const; - inline Scanline GetScanline( long nY ) const; - inline bool HasPalette() const; inline const BitmapPalette& GetPalette() const; inline sal_uInt16 GetPaletteEntryCount() const; @@ -100,6 +97,38 @@ public: inline bool HasColorMask() const; inline ColorMask& GetColorMask() const; +private: + + BitmapInfoAccess() {} + BitmapInfoAccess( const BitmapInfoAccess& ) {} + BitmapInfoAccess& operator=( const BitmapInfoAccess& ) { return *this; } + +protected: + Bitmap maBitmap; + BitmapBuffer* mpBuffer; + ColorMask maColorMask; + BitmapAccessMode mnAccessMode; + + SAL_DLLPRIVATE void ImplCreate( Bitmap& rBitmap ); + SAL_DLLPRIVATE void ImplDestroy(); + +protected: + BitmapInfoAccess( Bitmap& rBitmap, BitmapAccessMode nMode ); + +}; + +// - BitmapReadAccess - +class VCL_DLLPUBLIC BitmapReadAccess : public BitmapInfoAccess +{ + friend class BitmapWriteAccess; + +public: + BitmapReadAccess( Bitmap& rBitmap ); + virtual ~BitmapReadAccess(); + + inline Scanline GetBuffer() const; + inline Scanline GetScanline( long nY ) const; + inline BitmapColor GetPixelFromData( const sal_uInt8* pData, long nX ) const; inline void SetPixelOnData( sal_uInt8* pData, long nX, const BitmapColor& rBitmapColor ); inline BitmapColor GetPixel( long nY, long nX ) const; @@ -117,21 +146,16 @@ public: private: BitmapReadAccess() {} - BitmapReadAccess( const BitmapReadAccess& ) {} + BitmapReadAccess( const BitmapReadAccess& ) : BitmapInfoAccess() {} BitmapReadAccess& operator=( const BitmapReadAccess& ) { return *this; } protected: - Bitmap maBitmap; - BitmapBuffer* mpBuffer; Scanline* mpScanBuf; - ColorMask maColorMask; FncGetPixel mFncGetPixel; FncSetPixel mFncSetPixel; - bool mbModify; - - SAL_DLLPRIVATE void ImplCreate( Bitmap& rBitmap ); - SAL_DLLPRIVATE void ImplDestroy(); + SAL_DLLPRIVATE void ImplInitScanBuffer( Bitmap& rBitmap ); + SAL_DLLPRIVATE void ImplClearScanBuffer(); SAL_DLLPRIVATE bool ImplSetAccessPointers( sal_uLong nFormat ); public: @@ -158,7 +182,7 @@ public: DECL_FORMAT( _32BIT_TC_MASK ) protected: - BitmapReadAccess( Bitmap& rBitmap, bool bModify ); + BitmapReadAccess( Bitmap& rBitmap, BitmapAccessMode nMode ); }; @@ -206,61 +230,61 @@ private: }; // - Inlines - -inline bool BitmapReadAccess::operator!() const +inline bool BitmapInfoAccess::operator!() const { return( mpBuffer == NULL ); } -inline long BitmapReadAccess::Width() const +inline long BitmapInfoAccess::Width() const { return( mpBuffer ? mpBuffer->mnWidth : 0L ); } -inline long BitmapReadAccess::Height() const +inline long BitmapInfoAccess::Height() const { return( mpBuffer ? mpBuffer->mnHeight : 0L ); } -inline Point BitmapReadAccess::TopLeft() const +inline Point BitmapInfoAccess::TopLeft() const { return Point(); } -inline Point BitmapReadAccess::BottomRight() const +inline Point BitmapInfoAccess::BottomRight() const { return Point( Width() - 1L, Height() - 1L ); } -inline bool BitmapReadAccess::IsTopDown() const +inline bool BitmapInfoAccess::IsTopDown() const { assert(mpBuffer && "Access is not valid!"); return mpBuffer && ( BMP_SCANLINE_ADJUSTMENT( mpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN ); } -inline bool BitmapReadAccess::IsBottomUp() const +inline bool BitmapInfoAccess::IsBottomUp() const { return !IsTopDown(); } -inline sal_uLong BitmapReadAccess::GetScanlineFormat() const +inline sal_uLong BitmapInfoAccess::GetScanlineFormat() const { assert(mpBuffer && "Access is not valid!"); return( mpBuffer ? BMP_SCANLINE_FORMAT( mpBuffer->mnFormat ) : 0UL ); } -inline sal_uLong BitmapReadAccess::GetScanlineSize() const +inline sal_uLong BitmapInfoAccess::GetScanlineSize() const { assert(mpBuffer && "Access is not valid!"); return( mpBuffer ? mpBuffer->mnScanlineSize : 0UL ); } -inline sal_uInt16 BitmapReadAccess::GetBitCount() const +inline sal_uInt16 BitmapInfoAccess::GetBitCount() const { assert(mpBuffer && "Access is not valid!"); return( mpBuffer ? mpBuffer->mnBitCount : 0 ); } -inline BitmapColor BitmapReadAccess::GetBestMatchingColor( const BitmapColor& rBitmapColor ) +inline BitmapColor BitmapInfoAccess::GetBestMatchingColor( const BitmapColor& rBitmapColor ) { if( HasPalette() ) return BitmapColor( (sal_uInt8) GetBestPaletteIndex( rBitmapColor ) ); @@ -268,50 +292,37 @@ inline BitmapColor BitmapReadAccess::GetBestMatchingColor( const BitmapColor& rB return rBitmapColor; } -inline Scanline BitmapReadAccess::GetBuffer() const -{ - assert(mpBuffer && "Access is not valid!"); - return( mpBuffer ? mpBuffer->mpBits : NULL ); -} - -inline Scanline BitmapReadAccess::GetScanline( long nY ) const -{ - assert(mpBuffer && "Access is not valid!"); - assert(nY < mpBuffer->mnHeight && "y-coordinate out of range!"); - return( mpBuffer ? mpScanBuf[ nY ] : NULL ); -} - -inline bool BitmapReadAccess::HasPalette() const +inline bool BitmapInfoAccess::HasPalette() const { assert(mpBuffer && "Access is not valid!"); return( mpBuffer && !!mpBuffer->maPalette ); } -inline const BitmapPalette& BitmapReadAccess::GetPalette() const +inline const BitmapPalette& BitmapInfoAccess::GetPalette() const { assert(mpBuffer && "Access is not valid!"); return mpBuffer->maPalette; } -inline sal_uInt16 BitmapReadAccess::GetPaletteEntryCount() const +inline sal_uInt16 BitmapInfoAccess::GetPaletteEntryCount() const { assert(HasPalette() && "Bitmap has no palette!"); return( HasPalette() ? mpBuffer->maPalette.GetEntryCount() : 0 ); } -inline const BitmapColor& BitmapReadAccess::GetPaletteColor( sal_uInt16 nColor ) const +inline const BitmapColor& BitmapInfoAccess::GetPaletteColor( sal_uInt16 nColor ) const { assert(mpBuffer && "Access is not valid!"); assert(HasPalette() && "Bitmap has no palette!"); return mpBuffer->maPalette[ nColor ]; } -inline const BitmapColor& BitmapReadAccess::GetBestPaletteColor( const BitmapColor& rBitmapColor ) const +inline const BitmapColor& BitmapInfoAccess::GetBestPaletteColor( const BitmapColor& rBitmapColor ) const { return GetPaletteColor( GetBestPaletteIndex( rBitmapColor ) ); } -inline bool BitmapReadAccess::HasColorMask() const +inline bool BitmapInfoAccess::HasColorMask() const { assert(mpBuffer && "Access is not valid!"); const sal_uLong nFormat = BMP_SCANLINE_FORMAT( mpBuffer->mnFormat ); @@ -323,12 +334,25 @@ inline bool BitmapReadAccess::HasColorMask() const nFormat == BMP_FORMAT_32BIT_TC_MASK ); } -inline ColorMask& BitmapReadAccess::GetColorMask() const +inline ColorMask& BitmapInfoAccess::GetColorMask() const { assert(mpBuffer && "Access is not valid!"); return mpBuffer->maColorMask; } +inline Scanline BitmapReadAccess::GetBuffer() const +{ + assert(mpBuffer && "Access is not valid!"); + return( mpBuffer ? mpBuffer->mpBits : NULL ); +} + +inline Scanline BitmapReadAccess::GetScanline( long nY ) const +{ + assert(mpBuffer && "Access is not valid!"); + assert(nY < mpBuffer->mnHeight && "y-coordinate out of range!"); + return( mpBuffer ? mpScanBuf[ nY ] : NULL ); +} + inline BitmapColor BitmapReadAccess::GetPixel( long nY, long nX ) const { assert(mpBuffer && "Access is not valid!"); diff --git a/include/vcl/salbtype.hxx b/include/vcl/salbtype.hxx index 5c466f0..1dc65fc 100644 --- a/include/vcl/salbtype.hxx +++ b/include/vcl/salbtype.hxx @@ -268,6 +268,16 @@ struct VCL_DLLPUBLIC BitmapBuffer }; +// - Access modes - +typedef enum +{ + BITMAP_INFO_ACCESS, + BITMAP_READ_ACCESS, + BITMAP_WRITE_ACCESS +} +BitmapAccessMode; + + // - StretchAndConvert - diff --git a/vcl/generic/print/genpspgraphics.cxx b/vcl/generic/print/genpspgraphics.cxx index f548cee..1e63ab0 100644 --- a/vcl/generic/print/genpspgraphics.cxx +++ b/vcl/generic/print/genpspgraphics.cxx @@ -509,12 +509,12 @@ void GenPspGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSa Rectangle aDst (Point(rPosAry.mnDestX, rPosAry.mnDestY), Size(rPosAry.mnDestWidth, rPosAry.mnDestHeight)); - BitmapBuffer* pBuffer= const_cast<SalBitmap&>(rSalBitmap).AcquireBuffer(true); + BitmapBuffer* pBuffer= const_cast<SalBitmap&>(rSalBitmap).AcquireBuffer(BITMAP_READ_ACCESS); SalPrinterBmp aBmp (pBuffer); m_pPrinterGfx->DrawBitmap (aDst, aSrc, aBmp); - const_cast<SalBitmap&>(rSalBitmap).ReleaseBuffer (pBuffer, true); + const_cast<SalBitmap&>(rSalBitmap).ReleaseBuffer (pBuffer, BITMAP_READ_ACCESS); } void GenPspGraphics::drawBitmap( const SalTwoRect&, diff --git a/vcl/headless/svpbmp.cxx b/vcl/headless/svpbmp.cxx index 014b0e9..bc2b2b9 100644 --- a/vcl/headless/svpbmp.cxx +++ b/vcl/headless/svpbmp.cxx @@ -133,7 +133,7 @@ sal_uInt16 SvpSalBitmap::GetBitCount() const return nDepth; } -BitmapBuffer* SvpSalBitmap::AcquireBuffer( bool ) +BitmapBuffer* SvpSalBitmap::AcquireBuffer( BitmapAccessMode ) { BitmapBuffer* pBuf = NULL; if( m_aBitmap.get() ) @@ -268,9 +268,9 @@ BitmapBuffer* SvpSalBitmap::AcquireBuffer( bool ) return pBuf; } -void SvpSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) +void SvpSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) { - if( !bReadOnly && pBuffer->maPalette.GetEntryCount() ) + if( nMode == BITMAP_WRITE_ACCESS && pBuffer->maPalette.GetEntryCount() ) { // palette might have changed, clone device (but recycle // memory) diff --git a/vcl/inc/headless/svpbmp.hxx b/vcl/inc/headless/svpbmp.hxx index 61672fc..cb3336d 100644 --- a/vcl/inc/headless/svpbmp.hxx +++ b/vcl/inc/headless/svpbmp.hxx @@ -55,8 +55,8 @@ public: virtual Size GetSize() const SAL_OVERRIDE; virtual sal_uInt16 GetBitCount() const SAL_OVERRIDE; - virtual BitmapBuffer* AcquireBuffer( bool bReadOnly ) SAL_OVERRIDE; - virtual void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) SAL_OVERRIDE; + virtual BitmapBuffer* AcquireBuffer( BitmapAccessMode nMode ) SAL_OVERRIDE; + virtual void ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) SAL_OVERRIDE; virtual bool GetSystemData( BitmapSystemData& rData ) SAL_OVERRIDE; virtual bool Crop( const Rectangle& rRectPixel ) SAL_OVERRIDE; diff --git a/vcl/inc/impbmp.hxx b/vcl/inc/impbmp.hxx index de70989..5e4586d 100644 --- a/vcl/inc/impbmp.hxx +++ b/vcl/inc/impbmp.hxx @@ -20,6 +20,7 @@ #ifndef INCLUDED_VCL_INC_IMPBMP_HXX #define INCLUDED_VCL_INC_IMPBMP_HXX +#include <vcl/salbtype.hxx> #include <tools/gen.hxx> #include <tools/solar.h> @@ -58,8 +59,8 @@ public: Size ImplGetSize() const; sal_uInt16 ImplGetBitCount() const; - BitmapBuffer* ImplAcquireBuffer( bool bReadOnly ); - void ImplReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ); + BitmapBuffer* ImplAcquireBuffer( BitmapAccessMode nMode ); + void ImplReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ); sal_uLong ImplGetRefCount() const { return mnRefCount; } void ImplIncRefCount() { mnRefCount++; } diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx index 2a30764..200698f 100644 --- a/vcl/inc/opengl/salbmp.hxx +++ b/vcl/inc/opengl/salbmp.hxx @@ -74,8 +74,8 @@ public: Size GetSize() const SAL_OVERRIDE; sal_uInt16 GetBitCount() const SAL_OVERRIDE; - BitmapBuffer *AcquireBuffer( bool bReadOnly ) SAL_OVERRIDE; - void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) SAL_OVERRIDE; + BitmapBuffer *AcquireBuffer( BitmapAccessMode nMode ) SAL_OVERRIDE; + void ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) SAL_OVERRIDE; bool GetSystemData( BitmapSystemData& rData ) SAL_OVERRIDE; diff --git a/vcl/inc/quartz/salbmp.h b/vcl/inc/quartz/salbmp.h index b871ffb..1be7b0d 100644 --- a/vcl/inc/quartz/salbmp.h +++ b/vcl/inc/quartz/salbmp.h @@ -70,8 +70,8 @@ public: Size GetSize() const SAL_OVERRIDE; sal_uInt16 GetBitCount() const SAL_OVERRIDE; - BitmapBuffer *AcquireBuffer( bool bReadOnly ) SAL_OVERRIDE; - void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) SAL_OVERRIDE; + BitmapBuffer *AcquireBuffer( BitmapAccessMode nMode ) SAL_OVERRIDE; + void ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) SAL_OVERRIDE; bool GetSystemData( BitmapSystemData& rData ) SAL_OVERRIDE; diff --git a/vcl/inc/salbmp.hxx b/vcl/inc/salbmp.hxx index 16c47e7..b450594 100644 --- a/vcl/inc/salbmp.hxx +++ b/vcl/inc/salbmp.hxx @@ -23,6 +23,7 @@ #include <tools/gen.hxx> #include <tools/solar.h> #include <vcl/dllapi.h> +#include <vcl/salbtype.hxx> #include <com/sun/star/rendering/XBitmapCanvas.hpp> @@ -53,8 +54,8 @@ public: virtual Size GetSize() const = 0; virtual sal_uInt16 GetBitCount() const = 0; - virtual BitmapBuffer* AcquireBuffer( bool bReadOnly ) = 0; - virtual void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) = 0; + virtual BitmapBuffer* AcquireBuffer( BitmapAccessMode nMode ) = 0; + virtual void ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) = 0; virtual bool GetSystemData( BitmapSystemData& rData ) = 0; virtual bool Crop( const Rectangle& rRectPixel ) = 0; diff --git a/vcl/inc/unx/salbmp.h b/vcl/inc/unx/salbmp.h index 0b5cbc7..d840aee 100644 --- a/vcl/inc/unx/salbmp.h +++ b/vcl/inc/unx/salbmp.h @@ -142,8 +142,8 @@ public: virtual Size GetSize() const SAL_OVERRIDE; virtual sal_uInt16 GetBitCount() const SAL_OVERRIDE; - virtual BitmapBuffer* AcquireBuffer( bool bReadOnly ) SAL_OVERRIDE; - virtual void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) SAL_OVERRIDE; + virtual BitmapBuffer* AcquireBuffer( BitmapAccessMode nMode ) SAL_OVERRIDE; + virtual void ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) SAL_OVERRIDE; virtual bool GetSystemData( BitmapSystemData& rData ) SAL_OVERRIDE; virtual bool Crop( const Rectangle& rRectPixel ) SAL_OVERRIDE; diff --git a/vcl/inc/win/salbmp.h b/vcl/inc/win/salbmp.h index 12fd4ca..c1db93b 100644 --- a/vcl/inc/win/salbmp.h +++ b/vcl/inc/win/salbmp.h @@ -93,8 +93,8 @@ public: virtual Size GetSize() const { return maSize; } virtual sal_uInt16 GetBitCount() const { return mnBitCount; } - virtual BitmapBuffer* AcquireBuffer( bool bReadOnly ); - virtual void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ); + virtual BitmapBuffer* AcquireBuffer( BitmapAccessMode nMode ); + virtual void ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ); virtual bool GetSystemData( BitmapSystemData& rData ); virtual bool Crop( const Rectangle& rRectPixel ) SAL_OVERRIDE; diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx index 94c0c87..20ef2c4 100644 --- a/vcl/opengl/salbmp.cxx +++ b/vcl/opengl/salbmp.cxx @@ -477,21 +477,25 @@ void OpenGLSalBitmap::makeCurrent() mpContext->makeCurrent(); } -BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( bool /*bReadOnly*/ ) +BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( BitmapAccessMode nMode ) { - if( !maUserBuffer.get() ) - { - if( !AllocateUserData() ) - return NULL; - if( maTexture && !ReadTexture() ) - return NULL; - } - if( !maPendingOps.empty() ) + if( nMode != BITMAP_INFO_ACCESS ) { - SAL_INFO( "vcl.opengl", "** Creating texture and reading it back immediatly" ); - if( !CreateTexture() || !AllocateUserData() || !ReadTexture() ) - return NULL; + if( !maUserBuffer.get() ) + { + if( !AllocateUserData() ) + return NULL; + if( maTexture && !ReadTexture() ) + return NULL; + } + + if( !maPendingOps.empty() ) + { + SAL_INFO( "vcl.opengl", "** Creating texture and reading it back immediatly" ); + if( !CreateTexture() || !AllocateUserData() || !ReadTexture() ) + return NULL; + } } BitmapBuffer* pBuffer = new BitmapBuffer; @@ -518,9 +522,9 @@ BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( bool /*bReadOnly*/ ) return pBuffer; } -void OpenGLSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) +void OpenGLSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) { - if( !bReadOnly ) + if( nMode == BITMAP_WRITE_ACCESS ) { maTexture = OpenGLTexture(); mbDirtyTexture = true; diff --git a/vcl/quartz/salbmp.cxx b/vcl/quartz/salbmp.cxx index d3fc899..78064c2 100644 --- a/vcl/quartz/salbmp.cxx +++ b/vcl/quartz/salbmp.cxx @@ -702,7 +702,7 @@ const BitmapPalette& GetDefaultPalette( int mnBits, bool bMonochrome ) return aEmptyPalette; } -BitmapBuffer* QuartzSalBitmap::AcquireBuffer( bool /*bReadOnly*/ ) +BitmapBuffer* QuartzSalBitmap::AcquireBuffer( BitmapAccessMode /*nMode*/ ) { if( !maUserBuffer.get() ) // || maContextBuffer.get() && (maUserBuffer.get() != maContextBuffer.get()) ) @@ -741,10 +741,10 @@ BitmapBuffer* QuartzSalBitmap::AcquireBuffer( bool /*bReadOnly*/ ) return pBuffer; } -void QuartzSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) +void QuartzSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) { // invalidate graphic context if we have different data - if( !bReadOnly ) + if( nMode == BITMAP_WRITE_ACCESS ) { maPalette = pBuffer->maPalette; if( mxGraphicContext ) diff --git a/vcl/source/gdi/bitmap.cxx b/vcl/source/gdi/bitmap.cxx index 9915125..050eaa5 100644 --- a/vcl/source/gdi/bitmap.cxx +++ b/vcl/source/gdi/bitmap.cxx @@ -275,12 +275,12 @@ bool Bitmap::HasGreyPalette() const const sal_uInt16 nBitCount = GetBitCount(); bool bRet = nBitCount == 1; - BitmapReadAccess* pRAcc = ( (Bitmap*) this )->AcquireReadAccess(); + BitmapInfoAccess* pIAcc = ( (Bitmap*) this )->AcquireInfoAccess(); - if( pRAcc ) + if( pIAcc ) { - bRet = pRAcc->HasPalette() && pRAcc->GetPalette().IsGreyPalette(); - ( (Bitmap*) this )->ReleaseAccess( pRAcc ); + bRet = pIAcc->HasPalette() && pIAcc->GetPalette().IsGreyPalette(); + ( (Bitmap*) this )->ReleaseAccess( pIAcc ); } return bRet; @@ -399,6 +399,19 @@ void Bitmap::ImplSetImpBitmap( ImpBitmap* pImpBmp ) } } +BitmapInfoAccess* Bitmap::AcquireInfoAccess() +{ + BitmapInfoAccess* pInfoAccess = new BitmapInfoAccess( *this ); + + if( !*pInfoAccess ) + { + delete pInfoAccess; + pInfoAccess = NULL; + } + + return pInfoAccess; +} + BitmapReadAccess* Bitmap::AcquireReadAccess() { BitmapReadAccess* pReadAccess = new BitmapReadAccess( *this ); @@ -425,7 +438,7 @@ BitmapWriteAccess* Bitmap::AcquireWriteAccess() return pWriteAccess; } -void Bitmap::ReleaseAccess( BitmapReadAccess* pBitmapAccess ) +void Bitmap::ReleaseAccess( BitmapInfoAccess* pBitmapAccess ) { delete pBitmapAccess; } diff --git a/vcl/source/gdi/bmpacc.cxx b/vcl/source/gdi/bmpacc.cxx index 0b6a48b..9e4994c 100644 --- a/vcl/source/gdi/bmpacc.cxx +++ b/vcl/source/gdi/bmpacc.cxx @@ -27,32 +27,26 @@ #include <string.h> -BitmapReadAccess::BitmapReadAccess( Bitmap& rBitmap, bool bModify ) : +BitmapInfoAccess::BitmapInfoAccess( Bitmap& rBitmap, BitmapAccessMode nMode ) : mpBuffer ( NULL ), - mpScanBuf ( NULL ), - mFncGetPixel ( NULL ), - mFncSetPixel ( NULL ), - mbModify ( bModify ) + mnAccessMode ( nMode ) { ImplCreate( rBitmap ); } -BitmapReadAccess::BitmapReadAccess( Bitmap& rBitmap ) : +BitmapInfoAccess::BitmapInfoAccess( Bitmap& rBitmap ) : mpBuffer ( NULL ), - mpScanBuf ( NULL ), - mFncGetPixel ( NULL ), - mFncSetPixel ( NULL ), - mbModify ( false ) + mnAccessMode ( BITMAP_INFO_ACCESS ) { ImplCreate( rBitmap ); } -BitmapReadAccess::~BitmapReadAccess() +BitmapInfoAccess::~BitmapInfoAccess() { ImplDestroy(); } -void BitmapReadAccess::ImplCreate( Bitmap& rBitmap ) +void BitmapInfoAccess::ImplCreate( Bitmap& rBitmap ) { ImpBitmap* pImpBmp = rBitmap.ImplGetImpBitmap(); @@ -60,18 +54,19 @@ void BitmapReadAccess::ImplCreate( Bitmap& rBitmap ) if( pImpBmp ) { - if( mbModify && !maBitmap.ImplGetImpBitmap() ) + if( mnAccessMode == BITMAP_WRITE_ACCESS && !maBitmap.ImplGetImpBitmap() ) { rBitmap.ImplMakeUnique(); pImpBmp = rBitmap.ImplGetImpBitmap(); } else { - DBG_ASSERT( !mbModify || pImpBmp->ImplGetRefCount() == 2, + DBG_ASSERT( mnAccessMode != BITMAP_WRITE_ACCESS || + pImpBmp->ImplGetRefCount() == 2, "Unpredictable results: bitmap is referenced more than once!" ); } - mpBuffer = pImpBmp->ImplAcquireBuffer( !mbModify ); + mpBuffer = pImpBmp->ImplAcquireBuffer( mnAccessMode ); if( !mpBuffer ) { @@ -81,59 +76,95 @@ void BitmapReadAccess::ImplCreate( Bitmap& rBitmap ) { pImpBmp = pNewImpBmp; rBitmap.ImplSetImpBitmap( pImpBmp ); - mpBuffer = pImpBmp->ImplAcquireBuffer( !mbModify ); + mpBuffer = pImpBmp->ImplAcquireBuffer( mnAccessMode ); } else delete pNewImpBmp; } - if( mpBuffer ) - { - const long nHeight = mpBuffer->mnHeight; - Scanline pTmpLine = mpBuffer->mpBits; + maBitmap = rBitmap; + } +} - mpScanBuf = new Scanline[ nHeight ]; - maColorMask = mpBuffer->maColorMask; +void BitmapInfoAccess::ImplDestroy() +{ + ImpBitmap* pImpBmp = maBitmap.ImplGetImpBitmap(); - if( BMP_SCANLINE_ADJUSTMENT( mpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN ) - { - for( long nY = 0L; nY < nHeight; nY++, pTmpLine += mpBuffer->mnScanlineSize ) - mpScanBuf[ nY ] = pTmpLine; - } - else - { - for( long nY = nHeight - 1; nY >= 0; nY--, pTmpLine += mpBuffer->mnScanlineSize ) - mpScanBuf[ nY ] = pTmpLine; - } + if( mpBuffer && pImpBmp ) + { + pImpBmp->ImplReleaseBuffer( mpBuffer, mnAccessMode ); + mpBuffer = NULL; + } +} - if( !ImplSetAccessPointers( BMP_SCANLINE_FORMAT( mpBuffer->mnFormat ) ) ) - { - delete[] mpScanBuf; - mpScanBuf = NULL; +sal_uInt16 BitmapInfoAccess::GetBestPaletteIndex( const BitmapColor& rBitmapColor ) const +{ + return( HasPalette() ? mpBuffer->maPalette.GetBestIndex( rBitmapColor ) : 0 ); +} - pImpBmp->ImplReleaseBuffer( mpBuffer, !mbModify ); - mpBuffer = NULL; - } - else - maBitmap = rBitmap; - } - } +BitmapReadAccess::BitmapReadAccess( Bitmap& rBitmap, BitmapAccessMode nMode ) : + BitmapInfoAccess( rBitmap, nMode ), + mpScanBuf ( NULL ), + mFncGetPixel ( NULL ), + mFncSetPixel ( NULL ) +{ + ImplInitScanBuffer( rBitmap ); } -void BitmapReadAccess::ImplDestroy() +BitmapReadAccess::BitmapReadAccess( Bitmap& rBitmap ) : + BitmapInfoAccess( rBitmap, BITMAP_READ_ACCESS ), + mpScanBuf ( NULL ), + mFncGetPixel ( NULL ), + mFncSetPixel ( NULL ) { - ImpBitmap* pImpBmp = maBitmap.ImplGetImpBitmap(); + ImplInitScanBuffer( rBitmap ); +} - delete[] mpScanBuf; - mpScanBuf = NULL; +BitmapReadAccess::~BitmapReadAccess() +{ + ImplClearScanBuffer(); +} - if( mpBuffer && pImpBmp ) +void BitmapReadAccess::ImplInitScanBuffer( Bitmap& rBitmap ) +{ + ImpBitmap* pImpBmp = rBitmap.ImplGetImpBitmap(); + + if( pImpBmp && mpBuffer ) { - pImpBmp->ImplReleaseBuffer( mpBuffer, !mbModify ); - mpBuffer = NULL; + const long nHeight = mpBuffer->mnHeight; + Scanline pTmpLine = mpBuffer->mpBits; + + mpScanBuf = new Scanline[ nHeight ]; + maColorMask = mpBuffer->maColorMask; + + if( BMP_SCANLINE_ADJUSTMENT( mpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN ) + { + for( long nY = 0L; nY < nHeight; nY++, pTmpLine += mpBuffer->mnScanlineSize ) + mpScanBuf[ nY ] = pTmpLine; + } + else + { + for( long nY = nHeight - 1; nY >= 0; nY--, pTmpLine += mpBuffer->mnScanlineSize ) + mpScanBuf[ nY ] = pTmpLine; + } + + if( !ImplSetAccessPointers( BMP_SCANLINE_FORMAT( mpBuffer->mnFormat ) ) ) + { + delete[] mpScanBuf; + mpScanBuf = NULL; + + pImpBmp->ImplReleaseBuffer( mpBuffer, mnAccessMode ); + mpBuffer = NULL; + } } } +void BitmapReadAccess::ImplClearScanBuffer() +{ + delete[] mpScanBuf; + mpScanBuf = NULL; +} + bool BitmapReadAccess::ImplSetAccessPointers( sal_uLong nFormat ) { bool bRet = true; @@ -273,11 +304,6 @@ void BitmapReadAccess::ImplZeroInitUnusedBits() } } -sal_uInt16 BitmapReadAccess::GetBestPaletteIndex( const BitmapColor& rBitmapColor ) const -{ - return( HasPalette() ? mpBuffer->maPalette.GetBestIndex( rBitmapColor ) : 0 ); -} - BitmapColor BitmapReadAccess::GetInterpolatedColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const { // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative @@ -386,7 +412,7 @@ BitmapColor BitmapReadAccess::GetColorWithFallback( double fY, double fX, const } BitmapWriteAccess::BitmapWriteAccess( Bitmap& rBitmap ) : - BitmapReadAccess( rBitmap, true ), + BitmapReadAccess( rBitmap, BITMAP_WRITE_ACCESS ), mpLineColor ( NULL ), mpFillColor ( NULL ) { diff --git a/vcl/source/gdi/impbmp.cxx b/vcl/source/gdi/impbmp.cxx index 5a47845..4f4684d 100644 --- a/vcl/source/gdi/impbmp.cxx +++ b/vcl/source/gdi/impbmp.cxx @@ -80,16 +80,16 @@ sal_uInt16 ImpBitmap::ImplGetBitCount() const return( ( nBitCount <= 1 ) ? 1 : ( nBitCount <= 4 ) ? 4 : ( nBitCount <= 8 ) ? 8 : 24 ); } -BitmapBuffer* ImpBitmap::ImplAcquireBuffer( bool bReadOnly ) +BitmapBuffer* ImpBitmap::ImplAcquireBuffer( BitmapAccessMode nMode ) { - return mpSalBitmap->AcquireBuffer( bReadOnly ); + return mpSalBitmap->AcquireBuffer( nMode ); } -void ImpBitmap::ImplReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) +void ImpBitmap::ImplReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) { - mpSalBitmap->ReleaseBuffer( pBuffer, bReadOnly ); + mpSalBitmap->ReleaseBuffer( pBuffer, nMode ); - if( !bReadOnly ) + if( nMode == BITMAP_WRITE_ACCESS ) mnChecksum = 0; } diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx index f2f909c..5e084ce 100644 --- a/vcl/unx/generic/gdi/gdiimpl.cxx +++ b/vcl/unx/generic/gdi/gdiimpl.cxx @@ -105,7 +105,7 @@ namespace //fdo#33455 and fdo#80160 handle 1 bit depth pngs with palette entries //to set fore/back colors SalBitmap& rBitmap = const_cast<SalBitmap&>(rSalBitmap); - if (BitmapBuffer* pBitmapBuffer = rBitmap.AcquireBuffer(true)) + if (BitmapBuffer* pBitmapBuffer = rBitmap.AcquireBuffer(BITMAP_READ_ACCESS)) { const BitmapPalette& rPalette = pBitmapBuffer->maPalette; if (rPalette.GetEntryCount() == 2) @@ -116,7 +116,7 @@ namespace const BitmapColor aBlack(rPalette[rPalette.GetBestIndex(Color(COL_BLACK))]); rValues.background = rColMap.GetPixel(ImplColorToSal(aBlack)); } - rBitmap.ReleaseBuffer(pBitmapBuffer, true); + rBitmap.ReleaseBuffer(pBitmapBuffer, BITMAP_READ_ACCESS); } } } @@ -704,11 +704,11 @@ void X11SalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, DBG_ASSERT( !mrParent.bPrinter_, "Drawing of transparent bitmaps on printer devices is strictly forbidden" ); // decide if alpha masking or transparency masking is needed - BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rMaskBitmap).AcquireBuffer( true ); + BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rMaskBitmap).AcquireBuffer( BITMAP_READ_ACCESS ); if( pAlphaBuffer != NULL ) { int nMaskFormat = pAlphaBuffer->mnFormat; - const_cast<SalBitmap&>(rMaskBitmap).ReleaseBuffer( pAlphaBuffer, true ); + const_cast<SalBitmap&>(rMaskBitmap).ReleaseBuffer( pAlphaBuffer, BITMAP_READ_ACCESS ); if( nMaskFormat == BMP_FORMAT_8BIT_PAL ) drawAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap ); } @@ -882,7 +882,7 @@ bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR, // TODO: use SalX11Bitmap functionality and caching for the Alpha Pixmap // problem is that they don't provide an 8bit Pixmap on a non-8bit display - BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rAlphaBmp).AcquireBuffer( true ); + BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rAlphaBmp).AcquireBuffer( BITMAP_READ_ACCESS ); // an XImage needs its data top_down // TODO: avoid wrongly oriented images in upper layers! @@ -927,7 +927,7 @@ bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR, if( pAlphaBits != (char*)pAlphaBuffer->mpBits ) delete[] pAlphaBits; - const_cast<SalBitmap&>(rAlphaBmp).ReleaseBuffer( pAlphaBuffer, true ); + const_cast<SalBitmap&>(rAlphaBmp).ReleaseBuffer( pAlphaBuffer, BITMAP_READ_ACCESS ); XRenderPictureAttributes aAttr; aAttr.repeat = int(true); diff --git a/vcl/unx/generic/gdi/salbmp.cxx b/vcl/unx/generic/gdi/salbmp.cxx index e4437a7..f6ac736 100644 --- a/vcl/unx/generic/gdi/salbmp.cxx +++ b/vcl/unx/generic/gdi/salbmp.cxx @@ -814,7 +814,7 @@ sal_uInt16 X11SalBitmap::GetBitCount() const return nBitCount; } -BitmapBuffer* X11SalBitmap::AcquireBuffer( bool ) +BitmapBuffer* X11SalBitmap::AcquireBuffer( BitmapAccessMode /*nMode*/ ) { if( !mpDIB && mpDDB ) { @@ -832,9 +832,9 @@ BitmapBuffer* X11SalBitmap::AcquireBuffer( bool ) return mpDIB; } -void X11SalBitmap::ReleaseBuffer( BitmapBuffer*, bool bReadOnly ) +void X11SalBitmap::ReleaseBuffer( BitmapBuffer*, BitmapAccessMode nMode ) { - if( !bReadOnly ) + if( nMode == BITMAP_WRITE_ACCESS ) { if( mpDDB ) delete mpDDB, mpDDB = NULL; diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx index f1065be..c840cbf 100644 --- a/vcl/unx/gtk/window/gtksalframe.cxx +++ b/vcl/unx/gtk/window/gtksalframe.cxx @@ -1558,11 +1558,11 @@ bitmapToPixbuf( SalBitmap *pSalBitmap, SalBitmap *pSalAlpha ) g_return_val_if_fail( pSalBitmap != NULL, NULL ); g_return_val_if_fail( pSalAlpha != NULL, NULL ); - BitmapBuffer *pBitmap = pSalBitmap->AcquireBuffer( true ); + BitmapBuffer *pBitmap = pSalBitmap->AcquireBuffer( BITMAP_READ_ACCESS ); g_return_val_if_fail( pBitmap != NULL, NULL ); g_return_val_if_fail( pBitmap->mnBitCount == 24, NULL ); - BitmapBuffer *pAlpha = pSalAlpha->AcquireBuffer( true ); + BitmapBuffer *pAlpha = pSalAlpha->AcquireBuffer( BITMAP_READ_ACCESS ); g_return_val_if_fail( pAlpha != NULL, NULL ); g_return_val_if_fail( pAlpha->mnBitCount == 8, NULL ); @@ -1597,8 +1597,8 @@ bitmapToPixbuf( SalBitmap *pSalBitmap, SalBitmap *pSalAlpha ) } } - pSalBitmap->ReleaseBuffer( pBitmap, true ); - pSalAlpha->ReleaseBuffer( pAlpha, true ); + pSalBitmap->ReleaseBuffer( pBitmap, BITMAP_READ_ACCESS ); + pSalAlpha->ReleaseBuffer( pAlpha, BITMAP_READ_ACCESS ); return gdk_pixbuf_new_from_data( pPixbufData, GDK_COLORSPACE_RGB, true, 8, diff --git a/vcl/win/source/gdi/gdiimpl.cxx b/vcl/win/source/gdi/gdiimpl.cxx index e17b3e1..6e6361a 100644 --- a/vcl/win/source/gdi/gdiimpl.cxx +++ b/vcl/win/source/gdi/gdiimpl.cxx @@ -633,7 +633,7 @@ void ImplDrawBitmap( HDC hDC, const SalTwoRect& rPosAry, const WinSalBitmap& rSa COLORREF nTextColor = RGB( 0x00, 0x00, 0x00 ); //fdo#33455 handle 1 bit depth pngs with palette entries //to set fore/back colors - if (const BitmapBuffer* pBitmapBuffer = const_cast<WinSalBitmap&>(rSalBitmap).AcquireBuffer(true)) + if (const BitmapBuffer* pBitmapBuffer = const_cast<WinSalBitmap&>(rSalBitmap).AcquireBuffer(BITMAP_INFO_ACCESS)) { const BitmapPalette& rPalette = pBitmapBuffer->maPalette; if (rPalette.GetEntryCount() == 2) @@ -644,6 +644,7 @@ void ImplDrawBitmap( HDC hDC, const SalTwoRect& rPosAry, const WinSalBitmap& rSa nCol = ImplColorToSal(rPalette[1]); nBkColor = RGB( SALCOLOR_RED(nCol), SALCOLOR_GREEN(nCol), SALCOLOR_BLUE(nCol) ); } + const_cast<WinSalBitmap&>(rSalBitmap).ReleaseBuffer(pBitmapBuffer, BITMAP_INFO_ACCESS); } nOldBkColor = SetBkColor( hDC, nBkColor ); nOldTextColor = ::SetTextColor( hDC, nTextColor ); diff --git a/vcl/win/source/gdi/salbmp.cxx b/vcl/win/source/gdi/salbmp.cxx index b32067d..5ec4c10 100644 --- a/vcl/win/source/gdi/salbmp.cxx +++ b/vcl/win/source/gdi/salbmp.cxx @@ -270,7 +270,7 @@ Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap() pSalRGB = pExtraWinSalRGB; } - BitmapBuffer* pRGB = pSalRGB->AcquireBuffer(true); + BitmapBuffer* pRGB = pSalRGB->AcquireBuffer(BITMAP_READ_ACCESS); BitmapBuffer* pExtraRGB = 0; if(pRGB && BMP_FORMAT_24BIT_TC_BGR != (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN)) @@ -283,7 +283,7 @@ Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap() BMP_FORMAT_24BIT_TC_BGR, 0); - pSalRGB->ReleaseBuffer(pRGB, true); + pSalRGB->ReleaseBuffer(pRGB, BITMAP_WRITE_ACCESS); pRGB = pExtraRGB; } @@ -337,7 +337,7 @@ Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap() } else { - pSalRGB->ReleaseBuffer(pRGB, true); + pSalRGB->ReleaseBuffer(pRGB, BITMAP_READ_ACCESS); } if(pExtraWinSalRGB) @@ -362,7 +362,7 @@ Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap(const WinSalBitmap& rAlph pSalRGB = pExtraWinSalRGB; } - BitmapBuffer* pRGB = pSalRGB->AcquireBuffer(true); + BitmapBuffer* pRGB = pSalRGB->AcquireBuffer(BITMAP_READ_ACCESS); BitmapBuffer* pExtraRGB = 0; if(pRGB && BMP_FORMAT_24BIT_TC_BGR != (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN)) @@ -375,7 +375,7 @@ Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap(const WinSalBitmap& rAlph BMP_FORMAT_24BIT_TC_BGR, 0); - pSalRGB->ReleaseBuffer(pRGB, true); + pSalRGB->ReleaseBuffer(pRGB, BITMAP_READ_ACCESS); pRGB = pExtraRGB; } @@ -390,7 +390,7 @@ Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap(const WinSalBitmap& rAlph pSalA = pExtraWinSalA; } - BitmapBuffer* pA = pSalA->AcquireBuffer(true); + BitmapBuffer* pA = pSalA->AcquireBuffer(BITMAP_READ_ACCESS); BitmapBuffer* pExtraA = 0; if(pA && BMP_FORMAT_8BIT_PAL != (pA->mnFormat & ~BMP_FORMAT_TOP_DOWN)) @@ -405,7 +405,7 @@ Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap(const WinSalBitmap& rAlph BMP_FORMAT_8BIT_PAL, &rTargetPalette); - pSalA->ReleaseBuffer(pA, true); + pSalA->ReleaseBuffer(pA, BITMAP_READ_ACCESS); pA = pExtraA; } @@ -475,7 +475,7 @@ Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap(const WinSalBitmap& rAlph } else { - pSalA->ReleaseBuffer(pA, true); + pSalA->ReleaseBuffer(pA, BITMAP_READ_ACCESS); } if(pExtraWinSalA) @@ -492,7 +492,7 @@ Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap(const WinSalBitmap& rAlph } else { - pSalRGB->ReleaseBuffer(pRGB, true); + pSalRGB->ReleaseBuffer(pRGB, BITMAP_READ_ACCESS); } if(pExtraWinSalRGB) @@ -835,7 +835,7 @@ HANDLE WinSalBitmap::ImplCopyDIBOrDDB( HANDLE hHdl, bool bDIB ) return hCopy; } -BitmapBuffer* WinSalBitmap::AcquireBuffer( bool /*bReadOnly*/ ) +BitmapBuffer* WinSalBitmap::AcquireBuffer( BitmapAccessMode /*nMode*/ ) { BitmapBuffer* pBuffer = NULL; @@ -932,13 +932,13 @@ BitmapBuffer* WinSalBitmap::AcquireBuffer( bool /*bReadOnly*/ ) return pBuffer; } -void WinSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) +void WinSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) { if( pBuffer ) { if( mhDIB ) { - if( !bReadOnly && !!pBuffer->maPalette ) + if( nMode == BITMAP_WRITE_ACCESS && !!pBuffer->maPalette ) { PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( mhDIB ); const sal_uInt16 nCount = pBuffer->maPalette.GetEntryCount(); commit 9f839e9b3cbdca1511961a85b40d1c6825e43ba1 Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Thu Dec 11 07:46:51 2014 +0100 Revert "-Werror,-Wunused-private-field" This reverts commit 3b0db84516503ce72b803bf04b0432b36c1ac70c. diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx index 20731a6..a78972c 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -268,6 +268,7 @@ private: bool mbPixmap; // is a pixmap instead of a window #endif + int mnFramebufferCount; OpenGLFramebuffer* mpCurrentFramebuffer; OpenGLFramebuffer* mpFirstFramebuffer; OpenGLFramebuffer* mpLastFramebuffer; commit 51eeb1424f2034708cc6e1ab1a4a771ce5586211 Author: Deena Francis <deena.fran...@gmail.com> Date: Mon Dec 8 03:35:56 2014 +0530 fdo#81286 : Instant updates in SUM/AVERAGE in status bar Change-Id: I86ec7c73090b93cf080ced2bd5e24d98e2b3ac0e diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx index b29b1b6..1f60868 100644 --- a/sc/source/core/data/documen4.cxx +++ b/sc/source/core/data/documen4.cxx @@ -598,7 +598,7 @@ bool ScDocument::GetSelectionFunction( ScSubTotalFunc eFunc, ScMarkData aMark(rMark); aMark.MarkToMulti(); - if (!aMark.IsMultiMarked()) + if (!aMark.IsMultiMarked() && !aMark.IsCellMarked(rCursor.Col(), rCursor.Row(), false)) aMark.SetMarkArea(rCursor); SCTAB nMax = static_cast<SCTAB>(maTabs.size());
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits