UINT32 nWidth, UINT32 nHeight, HGDI_DC hdcSrc,
UINT32 nXSrc, UINT32 nYSrc, DWORD rop, const gdiPalette* palette)
{
+ HGDI_BITMAP hSrcBmp, hDstBmp;
+
if (!hdcDest)
return FALSE;
&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;