Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_vreg.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_vreg.h	(revision 48324)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_vreg.h	(revision 48325)
@@ -47,4 +47,20 @@
 }
 
+#ifndef IN_RING0
+DECLINLINE(void) VBoxRectStretch(PRTRECT pRect, float xStretch, float yStretch)
+{
+    pRect->xLeft = pRect->xLeft * xStretch;
+    pRect->yTop = pRect->yTop * yStretch;
+    pRect->xRight = pRect->xRight * xStretch;
+    pRect->yBottom = pRect->yBottom * yStretch;
+}
+
+DECLINLINE(void) VBoxRectStretched(const RTRECT *pRect, float xStretch, float yStretch, PRTRECT pResult)
+{
+    *pResult = *pRect;
+    VBoxRectStretch(pResult, xStretch, yStretch);
+}
+#endif
+
 DECLINLINE(void) VBoxRectIntersect(PRTRECT pRect1, const RTRECT * pRect2)
 {
@@ -229,5 +245,5 @@
 
 #define CRBLT_FTYPE_XOR                 CRBLT_F_INVERT_YCOORDS
-#define CRBLT_FTYPE_OR                  CRBLT_F_LINEAR
+#define CRBLT_FTYPE_OR                  (CRBLT_F_LINEAR | CRBLT_F_NOALPHA)
 #define CRBLT_FOP_COMBINE(_f1, _f2)     ((((_f1) ^ (_f2)) & CRBLT_FTYPE_XOR) | (((_f1) | (_f2)) & CRBLT_FTYPE_OR))
 
@@ -420,4 +436,12 @@
 #ifndef IN_RING0
 VBOXVREGDECL(void) CrVrScrCompositorSetStretching(PVBOXVR_SCR_COMPOSITOR pCompositor, float StretchX, float StretchY);
+DECLINLINE(void) CrVrScrCompositorGetStretching(PVBOXVR_SCR_COMPOSITOR pCompositor, float *pStretchX, float *pStretchY)
+{
+    if (pStretchX)
+        *pStretchX = pCompositor->StretchX;
+
+    if (pStretchY)
+        *pStretchY = pCompositor->StretchY;
+}
 #endif
 /* regions are valid until the next CrVrScrCompositor call */
Index: /trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp	(revision 48324)
+++ /trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp	(revision 48325)
@@ -156,4 +156,6 @@
     }
 
+    crWarning("changing mural for entered blitter, is is somewhat expected?");
+
     pBlitter->pDispatch->Flush();
 
Index: /trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m	(revision 48324)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m	(revision 48325)
@@ -32,4 +32,8 @@
 #include <cr_error.h>
 #include <cr_blitter.h>
+#ifdef VBOX_WITH_CRDUMPER_THUMBNAIL
+# include <cr_pixeldata.h>
+#endif
+
 
 #include "renderspu.h"
@@ -326,5 +330,6 @@
 
     /** This is necessary for clipping on the root window */
-    NSPoint          m_RootShift;
+    NSRect           m_RootRect;
+    float            m_yInvRootOffset;
     
     CR_BLITTER *m_pBlitter;
@@ -756,5 +761,6 @@
     m_Pos                     = NSZeroPoint;
     m_Size                    = NSMakeSize(1, 1);
-    m_RootShift               = NSZeroPoint;
+    m_RootRect                = NSMakeRect(0, 0, m_Size.width, m_Size.height);
+    m_yInvRootOffset          = 0;
     m_pBlitter                = nil;
     m_pWinInfo             	  = pWinInfo;
@@ -916,14 +922,11 @@
     DEBUG_MSG(("OVIW(%p): updateViewport\n", (void*)self));
 
-    {
-        /* Update the viewport for our OpenGL view */
-        [m_pSharedGLCtx update];
-
-        [self vboxBlitterSyncWindow];
+    /* Update the viewport for our OpenGL view */
+    [m_pSharedGLCtx update];
+
+    [self vboxBlitterSyncWindow];
         
-        /* Clear background to transparent */
-        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-    }
-}
+    /* Clear background to transparent */
+    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);}
 
 - (void)reshapeLocked
@@ -956,15 +959,31 @@
     newFrame = NSIntersectionRect(parentFrame, childFrame);
 
+    DEBUG_MSG(("[%#p]: parentFrame pos[%f : %f] size[%f : %f]\n",
+          (void*)self, 
+         parentFrame.origin.x, parentFrame.origin.y,
+         parentFrame.size.width, parentFrame.size.height));
+    DEBUG_MSG(("[%#p]: childFrame pos[%f : %f] size[%f : %f]\n",
+          (void*)self, 
+         childFrame.origin.x, childFrame.origin.y,
+         childFrame.size.width, childFrame.size.height));
+         
+    DEBUG_MSG(("[%#p]: newFrame pos[%f : %f] size[%f : %f]\n",
+          (void*)self, 
+         newFrame.origin.x, newFrame.origin.y,
+         newFrame.size.width, newFrame.size.height));
+    
     /* Later we have to correct the texture position in the case the window is
-     * out of the parents window frame. So save the shift values for later use. */
-    if (parentFrame.origin.x > childFrame.origin.x)
-        m_RootShift.x = parentFrame.origin.x - childFrame.origin.x;
-    else
-        m_RootShift.x = 0;
-    if (parentFrame.origin.y > childFrame.origin.y)
-        m_RootShift.y = parentFrame.origin.y - childFrame.origin.y;
-    else
-        m_RootShift.y = 0;
-
+     * out of the parents window frame. So save the shift values for later use. */ 
+    m_RootRect.origin.x = newFrame.origin.x - childFrame.origin.x;
+    m_RootRect.origin.y =  childFrame.size.height + childFrame.origin.y - (newFrame.size.height + newFrame.origin.y);
+    m_RootRect.size = newFrame.size;
+    m_yInvRootOffset = newFrame.origin.y - childFrame.origin.y;
+    
+    DEBUG_MSG(("[%#p]: m_RootRect pos[%f : %f] size[%f : %f]\n",
+         (void*)self, 
+         m_RootRect.origin.x, m_RootRect.origin.y,
+         m_RootRect.size.width, m_RootRect.size.height));
+    
+        
     /*
     NSScrollView *pScrollView = [[[m_pParentView window] contentView] enclosingScrollView];
@@ -1271,12 +1290,43 @@
             /* Render FBO content to the dock tile when necessary. */
             [self vboxPresentToDockTileCS:pCompositor];
-            
+            /* change to #if 0 to see thumbnail image */            
+#if 1
             [self vboxPresentToViewCS:pCompositor];
+#else
+            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+            [m_pSharedGLCtx flushBuffer];
+#endif
+           
         }
 }
 
+DECLINLINE(void) vboxNSRectToRect(const NSRect *pR, RTRECT *pRect)
+{
+    pRect->xLeft = (int)pR->origin.x;
+    pRect->yTop = (int)pR->origin.y;
+    pRect->xRight = (int)(pR->origin.x + pR->size.width);
+    pRect->yBottom = (int)(pR->origin.y + pR->size.height);
+}
+
+DECLINLINE(void) vboxNSRectToRectUnstretched(const NSRect *pR, RTRECT *pRect, float xStretch, float yStretch)
+{
+    pRect->xLeft = (int)(pR->origin.x / xStretch);
+    pRect->yTop = (int)(pR->origin.y / yStretch);
+    pRect->xRight = (int)((pR->origin.x + pR->size.width) / xStretch);
+    pRect->yBottom = (int)((pR->origin.y + pR->size.height) / yStretch);
+}
+
+DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, float xStretch, float yStretch)
+{
+    pRect->xLeft = (int)(pR->origin.x * xStretch);
+    pRect->yTop = (int)(pR->origin.y * yStretch);
+    pRect->xRight = (int)((pR->origin.x + pR->size.width) * xStretch);
+    pRect->yBottom = (int)((pR->origin.y + pR->size.height) * yStretch);
+}
+
 - (void)vboxPresentToViewCS:(PVBOXVR_SCR_COMPOSITOR)pCompositor
 {
     NSRect r = [self frame];
+    float xStretch, yStretch;
     DEBUG_MSG(("OVIW(%p): rF2V frame: [%i, %i, %i, %i]\n", (void*)self, (int)r.origin.x, (int)r.origin.y, (int)r.size.width, (int)r.size.height));
 
@@ -1292,4 +1342,6 @@
     /* Clear background to transparent */
     glClear(GL_COLOR_BUFFER_BIT);
+    
+    CrVrScrCompositorGetStretching(pCompositor, &xStretch, &yStretch);
         
     while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
@@ -1309,22 +1361,22 @@
                     const RTRECT * pSrcRect = &paSrcRegions[i];
                     const RTRECT * pDstRect = &paDstRegions[i];
-                    RTRECT SrcRect, DstRect;
-                    if (m_RootShift.x)
-                    {
-                        DstRect.xLeft = pDstRect->xLeft - m_RootShift.x;
-                        DstRect.yTop = pDstRect->yTop;
-                        DstRect.xRight = pDstRect->xRight - m_RootShift.x;
-                        DstRect.yBottom = pDstRect->yBottom;
-                        pDstRect = &DstRect;
-                    }
+                    RTRECT SrcRect, DstRect, RestrictSrcRect, RestrictDstRect;
                     
-                    if (m_RootShift.y)
-                    {
-                        SrcRect.xLeft = pSrcRect->xLeft;
-                        SrcRect.yTop = pSrcRect->yTop - m_RootShift.y;
-                        SrcRect.xRight = pSrcRect->xRight;
-                        SrcRect.yBottom = pSrcRect->yBottom - m_RootShift.y;
-                        pSrcRect = &SrcRect;
-                    }
+                    vboxNSRectToRect(&m_RootRect, &RestrictDstRect);
+                    VBoxRectIntersected(&RestrictDstRect, pDstRect, &DstRect);
+                    
+                    if (VBoxRectIsZero(&DstRect))
+                        continue;
+
+                    VBoxRectTranslate(&DstRect, -RestrictDstRect.xLeft, -RestrictDstRect.yTop);
+                        
+                    vboxNSRectToRectUnstretched(&m_RootRect, &RestrictSrcRect, xStretch, yStretch);
+                    VBoxRectIntersected(&RestrictSrcRect, pSrcRect, &SrcRect);
+                    
+                    if (VBoxRectIsZero(&SrcRect))
+                        continue;
+
+                    pSrcRect = &SrcRect;
+                    pDstRect = &DstRect;
                     
                     CrBltBlitTexMural(m_pBlitter, true, &pEntry->Tex, pSrcRect, pDstRect, 1, fFlags | CRBLT_F_NOALPHA);
@@ -1370,8 +1422,16 @@
     WinInfo.height = r.size.height;
     
+    Assert(WinInfo.width = m_RootRect.size.width);
+    Assert(WinInfo.height = m_RootRect.size.height);
+
+    CrBltMuralSetCurrent(m_pBlitter, NULL);
+    
     CrBltMuralSetCurrent(m_pBlitter, &WinInfo);
     CrBltCheckUpdateViewport(m_pBlitter);
 }
 
+#ifdef VBOX_WITH_CRDUMPER_THUMBNAIL
+static int g_cVBoxTgaCtr = 0;
+#endif
 - (void)vboxPresentToDockTileCS:(PVBOXVR_SCR_COMPOSITOR)pCompositor
 {
@@ -1380,4 +1440,5 @@
     GLint i         = 0;
     NSDockTile *pDT = nil;
+    float xStretch, yStretch;
 
     if ([m_DockTileView thumbBitmap] != nil)
@@ -1416,4 +1477,6 @@
             rr = [m_DockTileView frame];
             
+            CrVrScrCompositorGetStretching(pCompositor, &xStretch, &yStretch);
+            
             CrVrScrCompositorIterInit(pCompositor, &CIter);
             while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
@@ -1433,24 +1496,26 @@
                             const RTRECT * pSrcRect = &paSrcRegions[i];
                             const RTRECT * pDstRect = &paDstRegions[i];
-                            RTRECT SrcRect, DstRect;
-                            /*if (m_RootShift.x)*/
-                            {
-                                DstRect.xLeft = pDstRect->xLeft * m_FBOThumbScaleX;
-                                DstRect.yTop = (r.size.height - pDstRect->yTop) * m_FBOThumbScaleY;
-                                DstRect.xRight = pDstRect->xRight * m_FBOThumbScaleX;
-                                DstRect.yBottom = (r.size.height - pDstRect->yBottom) * m_FBOThumbScaleY;
-                                pDstRect = &DstRect;
-                            }
+                            RTRECT SrcRect, DstRect, RestrictSrcRect, RestrictDstRect;
                     
-                            if (m_RootShift.y)
-                            {
-                                SrcRect.xLeft = pSrcRect->xLeft;
-                                SrcRect.yTop = pSrcRect->yTop - m_RootShift.y;
-                                SrcRect.xRight = pSrcRect->xRight;
-                                SrcRect.yBottom = pSrcRect->yBottom - m_RootShift.y;
-                                pSrcRect = &SrcRect;
-                            }
+                            vboxNSRectToRect(&m_RootRect, &RestrictDstRect);
+                            VBoxRectIntersected(&RestrictDstRect, pDstRect, &DstRect);
+                            
+                            VBoxRectTranslate(&DstRect, -RestrictDstRect.xLeft, -RestrictDstRect.yTop);
+                            
+                            VBoxRectStretch(&DstRect, m_FBOThumbScaleX, m_FBOThumbScaleY);
                     
-                            CrBltBlitTexMural(m_pBlitter, true, &pEntry->Tex, pSrcRect, pDstRect, 1, fFlags | CRBLT_F_NOALPHA);
+                            if (VBoxRectIsZero(&DstRect))
+                                continue;
+                        
+                            vboxNSRectToRectUnstretched(&m_RootRect, &RestrictSrcRect, xStretch, yStretch);
+                            VBoxRectIntersected(&RestrictSrcRect, pSrcRect, &SrcRect);
+                    
+                            if (VBoxRectIsZero(&SrcRect))
+                                continue;
+
+                            pSrcRect = &SrcRect;
+                            pDstRect = &DstRect;
+                            
+                            CrBltBlitTexMural(m_pBlitter, true, &pEntry->Tex, pSrcRect, pDstRect, 1, fFlags);
                         }
                         CrBltLeave(m_pBlitter);
@@ -1476,9 +1541,15 @@
              * is updated currently. */
             [m_DockTileView lock];
-            glReadPixels(0, 0, rr.size.width, rr.size.height,
+            glReadPixels(0, m_RootRect.size.height - rr.size.height, rr.size.width, rr.size.height,
                          GL_BGRA,
                          GL_UNSIGNED_INT_8_8_8_8,
                          [[m_DockTileView thumbBitmap] bitmapData]);
             [m_DockTileView unlock];
+            
+#ifdef VBOX_WITH_CRDUMPER_THUMBNAIL
+            ++g_cVBoxTgaCtr;
+            crDumpNamedTGAF((GLint)rr.size.width, (GLint)rr.size.height, 
+                [[m_DockTileView thumbBitmap] bitmapData], "/Users/leo/vboxdumps/dump%d.tga", g_cVBoxTgaCtr);
+#endif                
 
             pDT = [[NSApplication sharedApplication] dockTile];
@@ -1550,9 +1621,10 @@
     {
         NSRect dockFrame = [pView frame];
+        /* todo: this is not correct, we should use framebuffer size here, while parent view frame size may differ in case of scrolling */
         NSRect parentFrame = [m_pParentView frame];
 
         m_FBOThumbScaleX = (float)dockFrame.size.width / parentFrame.size.width;
         m_FBOThumbScaleY = (float)dockFrame.size.height / parentFrame.size.height;
-        newFrame = NSMakeRect((int)(m_Pos.x * m_FBOThumbScaleX), (int)(dockFrame.size.height - (m_Pos.y + m_Size.height - m_RootShift.y) * m_FBOThumbScaleY), (int)(m_Size.width * m_FBOThumbScaleX), (int)(m_Size.height * m_FBOThumbScaleY));
+        newFrame = NSMakeRect((int)(m_Pos.x * m_FBOThumbScaleX), (int)(dockFrame.size.height - (m_Pos.y + m_Size.height - m_yInvRootOffset) * m_FBOThumbScaleY), (int)(m_Size.width * m_FBOThumbScaleX), (int)(m_Size.height * m_FBOThumbScaleY));
         /*
         NSRect newFrame = NSMakeRect ((int)roundf(m_Pos.x * m_FBOThumbScaleX), (int)roundf(dockFrame.size.height - (m_Pos.y + m_Size.height) * m_FBOThumbScaleY), (int)roundf(m_Size.width * m_FBOThumbScaleX), (int)roundf(m_Size.height * m_FBOThumbScaleY));
