[Libreoffice-commits] core.git: 10 commits - include/vcl sc/source vcl/generic vcl/headless vcl/inc vcl/opengl vcl/quartz vcl/source vcl/unx vcl/win

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Wed Dec 10 22:58:16 PST 2014


 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 <lfrb at 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 <lfrb at 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 <lfrb at 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 <lfrb at 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 <lfrb at 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 <lfrb at 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 <lfrb at 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 <lfrb at 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.mohrhard at 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.francis at 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());


More information about the Libreoffice-commits mailing list