[ros-diffs] [fireball] 47014: - WINENT.DRV: Remove bit copying, it's a job of SWM. - SWM: Create a screen DC, and copy window's contents when changing position (significantly faster than doing it from winent.drv, not to say that doing so without interaction with a window manager is not possible). - SWM: Invalidate areas after changing moving a window or changing its size. - GDIOBJ: Add a missing space for code beautification. See issue #5237 for more details.

fireball at svn.reactos.org fireball at svn.reactos.org
Sun Apr 25 15:28:15 CEST 2010


Author: fireball
Date: Sun Apr 25 15:28:14 2010
New Revision: 47014

URL: http://svn.reactos.org/svn/reactos?rev=47014&view=rev
Log:
- WINENT.DRV: Remove bit copying, it's a job of SWM.
- SWM: Create a screen DC, and copy window's contents when changing position (significantly faster than doing it from winent.drv, not to say that doing so without interaction with a window manager is not possible).
- SWM: Invalidate areas after changing moving a window or changing its size.
- GDIOBJ: Add a missing space for code beautification.
See issue #5237 for more details.

Modified:
    branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c
    branches/arwinss/reactos/subsystems/win32/win32k/gre/gdiobj.c
    branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c

Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c?rev=47014&r1=47013&r2=47014&view=diff
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] Sun Apr 25 15:28:14 2010
@@ -83,23 +83,6 @@
         else RedrawWindow( data->hwnd, NULL, rgn, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN );
         DeleteObject( rgn );
     }
-}
-
-void swm_move_whole_window( struct ntdrv_win_data *data, const RECT *old_rect )
-{
-    HDC hdc_src, hdc_dst;
-    HWND parent;
-
-    parent = GetAncestor( data->hwnd, GA_PARENT );
-    hdc_src = GetDCEx( parent, 0, DCX_CACHE );
-    hdc_dst = GetDCEx( data->hwnd, 0, DCX_CACHE | DCX_WINDOW );
-
-    BitBlt( hdc_dst, 0, 0,
-        data->whole_rect.right - data->whole_rect.left, data->whole_rect.bottom - data->whole_rect.top,
-        hdc_src, old_rect->left, old_rect->top, SRCCOPY );
-
-    ReleaseDC( data->hwnd, hdc_dst );
-    ReleaseDC( parent, hdc_src );
 }
 
 HKL CDECL RosDrv_ActivateKeyboardLayout( HKL layout, UINT flags )
@@ -954,10 +937,8 @@
     /* Sync position change */
     if (!(swp_flags & SWP_NOREDRAW)) // HACK: When removing this, explorer's start menu starts to appear partially. Investigate!
     {
+        /* SWM: Change windows position */
         SwmPosChanged(hwnd, &data->whole_rect, &old_whole_rect, insert_after, swp_flags);
-
-        /* SWM: Move whole window bits */
-        swm_move_whole_window( data, &old_whole_rect );
     }
 
     /* Pass show/hide information to the window manager */

Modified: branches/arwinss/reactos/subsystems/win32/win32k/gre/gdiobj.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/gre/gdiobj.c?rev=47014&r1=47013&r2=47014&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/gre/gdiobj.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/gre/gdiobj.c [iso-8859-1] Sun Apr 25 15:28:14 2010
@@ -51,7 +51,7 @@
   {0, 0,                     0,                NULL},             /* 02 reserved entry */
   {0, 0,                     0,                NULL},             /* 03 reserved entry */
   {0, 0,                     0,                NULL},             /* 04 reserved entry */
-  {0, sizeof(SURFACE),       TAG_SURFOBJ,      SURFACE_Cleanup}, /* 05 SURFACE */
+  {0, sizeof(SURFACE),       TAG_SURFOBJ,      SURFACE_Cleanup},  /* 05 SURFACE */
   {0, 0,                     0,                NULL},             /* 06 reserved entry */
   {0, 0,                     0,                NULL},             /* 07 reserved entry */
   {0, sizeof(PALETTE),       TAG_PALETTE,      GDI_CleanupDummy}, /* 08 PAL */

Modified: branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c?rev=47014&r1=47013&r2=47014&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c [iso-8859-1] Sun Apr 25 15:28:14 2010
@@ -34,6 +34,7 @@
 
 LIST_ENTRY SwmWindows;
 ERESOURCE SwmLock;
+HDC SwmDc; /* Screen DC for copying operations */
 
 /* FUNCTIONS *****************************************************************/
 
@@ -53,6 +54,23 @@
     /* Release user resource */
     ExReleaseResourceLite(&SwmLock);
     KeLeaveCriticalRegion();
+}
+
+VOID
+NTAPI
+SwmCreateScreenDc()
+{
+    ROS_DCINFO RosDc;
+
+    /* Create the display DC */
+    RtlZeroMemory(&RosDc, sizeof(ROS_DCINFO));
+    RosDc.dwType = OBJ_DC;
+    SwmDc = (HDC)0;
+    RosGdiCreateDC(&RosDc, &SwmDc, NULL, NULL, NULL, NULL);
+    RosGdiSetDeviceClipping(SwmDc, 0, NULL, NULL);
+
+    /* Make it global */
+    GDIOBJ_SetOwnership(SwmDc, NULL);
 }
 
 VOID
@@ -533,6 +551,18 @@
 
 VOID
 NTAPI
+SwmCopyBits(const RECT *WindowRect, const RECT *OldRect)
+{
+    /* Lazily create a global screen DC */
+    if (!SwmDc) SwmCreateScreenDc();
+
+    /* Copy bits */
+    RosGdiBitBlt(SwmDc, WindowRect->left, WindowRect->top, WindowRect->right - WindowRect->left,
+        WindowRect->bottom - WindowRect->top, SwmDc, OldRect->left, OldRect->top, SRCCOPY);
+}
+
+VOID
+NTAPI
 SwmPosChanging(HWND hWnd, const RECT *WindowRect)
 {
 }
@@ -542,6 +572,10 @@
 SwmPosChanged(HWND hWnd, const RECT *WindowRect, const RECT *OldRect, HWND hWndAfter, UINT SwpFlags)
 {
     PSWM_WINDOW SwmWin, SwmPrev;
+    LONG Width, Height, OldWidth, OldHeight;
+    BOOLEAN IsMove = FALSE;
+    struct region *OldRegion, *DiffRegion;
+    rectangle_t OldRectSafe;
 
     /* Acquire the lock */
     SwmAcquire();
@@ -553,6 +587,25 @@
         /* Release the lock */
         SwmRelease();
         return;
+    }
+
+    /* Save parameters */
+    OldRectSafe.left = OldRect->left; OldRectSafe.top = OldRect->top;
+    OldRectSafe.right = OldRect->right; OldRectSafe.bottom = OldRect->bottom;
+
+    Width = WindowRect->right - WindowRect->left;
+    Height = WindowRect->bottom - WindowRect->top;
+
+    OldWidth = OldRect->right - OldRect->left;
+    OldHeight = OldRect->bottom - OldRect->top;
+
+    /* Detect if it's a move without resizing */
+    if ((WindowRect->top != OldRect->top ||
+        WindowRect->left != OldRect->left) &&
+        Width == OldWidth &&
+        Height == OldHeight)
+    {
+        IsMove = TRUE;
     }
 
     /* Check if window really moved anywhere (origin, size or z order) */
@@ -590,6 +643,36 @@
 
     /* Recalculate all clipping */
     SwmClipAllWindows();
+
+    /* Copy bitmap bits if it's a move */
+    if (IsMove)
+    {
+        /* FIXME: The window MUST be foreground, otherwise bits will be
+                  copied incorrectly */
+        SwmCopyBits(WindowRect, OldRect);
+    }
+
+    /* Paint area changed after moving or resizing */
+    if (Width < OldWidth ||
+        Height < OldHeight ||
+        IsMove)
+    {
+        /* Subtract new visible rect from the old one,
+           and invalidate the result */
+        OldRegion = create_empty_region();
+        set_region_rect(OldRegion, &OldRectSafe);
+
+        /* Compute the difference into the temp region */
+        DiffRegion = create_empty_region();
+        subtract_region(DiffRegion, OldRegion, SwmWin->Visible);
+
+        /* Paint it */
+        SwmPaintRegion(DiffRegion);
+
+        /* Free temporary regions */
+        free_region(OldRegion);
+        free_region(DiffRegion);
+    }
 
     /* Release the lock */
     SwmRelease();




More information about the Ros-diffs mailing list