diff --git a/libfreerdp/gdi/bitmap.c b/libfreerdp/gdi/bitmap.c index 6f0d3787b..0eaa9b8c2 100644 --- a/libfreerdp/gdi/bitmap.c +++ b/libfreerdp/gdi/bitmap.c @@ -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;