Optimized ROP for GDI_SRCCOPY and GDI_DSTCOPY.
authorArmin Novak <armin.novak@thincast.com>
Tue, 11 Oct 2016 11:10:54 +0000 (13:10 +0200)
committerArmin Novak <armin.novak@thincast.com>
Tue, 11 Oct 2016 12:47:26 +0000 (14:47 +0200)
libfreerdp/gdi/bitmap.c

index 6f0d378..0eaa9b8 100644 (file)
@@ -462,6 +462,8 @@ BOOL gdi_BitBlt(HGDI_DC hdcDest, UINT32 nXDest, UINT32 nYDest,
                 UINT32 nWidth, UINT32 nHeight, HGDI_DC hdcSrc,
                 UINT32 nXSrc, UINT32 nYSrc, DWORD rop, const gdiPalette* palette)
 {
+       HGDI_BITMAP hSrcBmp, hDstBmp;
+
        if (!hdcDest)
                return FALSE;
 
@@ -469,10 +471,44 @@ BOOL gdi_BitBlt(HGDI_DC hdcDest, UINT32 nXDest, UINT32 nYDest,
                            &nYSrc))
                return TRUE;
 
-       if (!BitBlt_process(hdcDest, nXDest, nYDest,
-                           nWidth, nHeight, hdcSrc,
-                           nXSrc, nYSrc, gdi_rop_to_string(rop), palette))
-               return FALSE;
+       /* Check which ROP should be performed.
+        * Some specific ROP are used heavily and are resource intensive,
+        * add optimized versions for these here.
+        *
+        * For all others fall back to the generic implementation.
+        */
+       switch (rop)
+       {
+               case GDI_SRCCOPY:
+                       hSrcBmp = (HGDI_BITMAP) hdcSrc->selectedObject;
+                       hDstBmp = (HGDI_BITMAP) hdcDest->selectedObject;
+
+                       if (!freerdp_image_copy(hDstBmp->data, hdcDest->format, hDstBmp->scanline,
+                                               nXDest, nYDest, nWidth, nHeight,
+                                               hSrcBmp->data, hdcSrc->format, hSrcBmp->scanline, nXSrc, nYSrc, palette))
+                               return FALSE;
+
+                       break;
+
+               case GDI_DSTCOPY:
+                       hSrcBmp = (HGDI_BITMAP) hdcDest->selectedObject;
+                       hDstBmp = (HGDI_BITMAP) hdcDest->selectedObject;
+
+                       if (!freerdp_image_copy(hDstBmp->data, hdcDest->format, hDstBmp->scanline,
+                                               nXDest, nYDest, nWidth, nHeight,
+                                               hSrcBmp->data, hdcSrc->format, hSrcBmp->scanline, nXSrc, nYSrc, palette))
+                               return FALSE;
+
+                       break;
+
+               default:
+                       if (!BitBlt_process(hdcDest, nXDest, nYDest,
+                                           nWidth, nHeight, hdcSrc,
+                                           nXSrc, nYSrc, gdi_rop_to_string(rop), palette))
+                               return FALSE;
+
+                       break;
+       }
 
        if (!gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight))
                return FALSE;