diff options
Diffstat (limited to 'display/rop.c')
-rw-r--r-- | display/rop.c | 379 |
1 files changed, 254 insertions, 125 deletions
diff --git a/display/rop.c b/display/rop.c index 83efdd3..82cd723 100644 --- a/display/rop.c +++ b/display/rop.c @@ -20,6 +20,7 @@ #include "utils.h" #include "res.h" #include "rop.h" +#include "surface.h" enum ROP3type { @@ -382,21 +383,28 @@ ROP3Info rops3[] = { }; -static BOOL DoFill(PDev *pdev, RECTL *area, CLIPOBJ *clip, BRUSHOBJ *brush, POINTL *brush_pos, - ROP3Info *rop_info, SURFOBJ *mask, POINTL *mask_pos, BOOL invers_mask) +static BOOL DoFill(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, BRUSHOBJ *brush, + POINTL *brush_pos, ROP3Info *rop_info, SURFOBJ *mask, POINTL *mask_pos, + BOOL invers_mask) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area && brush); - if (!(drawable = Drawable(pdev, QXL_DRAW_FILL, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_FILL, area, clip, surface_id))) { return FALSE; } - if (!QXLGetBrush(pdev, drawable, &drawable->u.fill.brush, brush, brush_pos) || + width = area->right - area->left; + height = area->bottom - area->top; + + if (!QXLGetBrush(pdev, drawable, &drawable->u.fill.brush, brush, brush_pos, + &drawable->surfaces_dest[0], &drawable->surfaces_rects[0]) || !QXLGetMask(pdev, drawable, &drawable->u.fill.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top)) { + width, height, &drawable->surfaces_dest[1])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } @@ -405,28 +413,37 @@ static BOOL DoFill(PDev *pdev, RECTL *area, CLIPOBJ *clip, BRUSHOBJ *brush, POIN drawable->effect = mask ? QXL_EFFECT_BLEND : rop_info->effect; + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[1], mask_pos, width, height); + } + PushDrawable(pdev, drawable); return TRUE; } static BOOL GetBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *bitmap_phys, SURFOBJ *surf, - SpiceRect *area, XLATEOBJ *color_trans, BOOL use_cache) + SpiceRect *area, XLATEOBJ *color_trans, BOOL use_cache, INT32 *surface_dest) { DEBUG_PRINT((pdev, 9, "%s\n", __FUNCTION__)); if (surf->iType != STYPE_BITMAP) { + UINT32 surface_id; + ASSERT(pdev, (PDev *)surf->dhpdev == pdev); - DEBUG_PRINT((pdev, 9, "%s copy from self\n", __FUNCTION__)); - *bitmap_phys = 0; - drawable->self_bitmap = TRUE; - drawable->self_bitmap_area = *area; - area->right = area->right - area->left; - area->left = 0; - area->bottom = area->bottom - area->top; - area->top = 0; - return TRUE; + surface_id = GetSurfaceId(surf); + if (surface_id == drawable->surface_id) { + DEBUG_PRINT((pdev, 9, "%s copy from self\n", __FUNCTION__)); + *bitmap_phys = 0; + drawable->self_bitmap = TRUE; + drawable->self_bitmap_area = *area; + area->right = area->right - area->left; + area->left = 0; + area->bottom = area->bottom - area->top; + area->top = 0; + return TRUE; + } } return QXLGetBitmap(pdev, drawable, &drawable->u.opaque.src_bitmap, surf, - area, color_trans, NULL, use_cache); + area, color_trans, NULL, use_cache, surface_dest); } static _inline UINT8 GdiScaleModeToQxl(ULONG scale_mode) @@ -435,31 +452,44 @@ static _inline UINT8 GdiScaleModeToQxl(ULONG scale_mode) SPICE_IMAGE_SCALE_MODE_NEAREST; } -static BOOL DoOpaque(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL *src_rect, - XLATEOBJ *color_trans, BRUSHOBJ *brush, POINTL *brush_pos, +static BOOL DoOpaque(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, + RECTL *src_rect, XLATEOBJ *color_trans, BRUSHOBJ *brush, POINTL *brush_pos, UINT16 rop_decriptor, SURFOBJ *mask, POINTL *mask_pos, BOOL invers_mask, ULONG scale_mode) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area && brush && src_rect && src); - if (!(drawable = Drawable(pdev, QXL_DRAW_OPAQUE, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_OPAQUE, area, clip, surface_id))) { return FALSE; } drawable->u.opaque.scale_mode = GdiScaleModeToQxl(scale_mode); CopyRect(&drawable->u.opaque.src_area, src_rect); - if (!QXLGetBrush(pdev, drawable, &drawable->u.opaque.brush, brush, brush_pos) || + + width = area->right - area->left; + height = area->bottom - area->top; + + if (!QXLGetBrush(pdev, drawable, &drawable->u.opaque.brush, brush, brush_pos, + &drawable->surfaces_dest[0], &drawable->surfaces_rects[0]) || !QXLGetMask(pdev, drawable, &drawable->u.opaque.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top) || + width, height, &drawable->surfaces_dest[1]) || !GetBitmap(pdev, drawable, &drawable->u.opaque.src_bitmap, src, - &drawable->u.opaque.src_area, color_trans, TRUE)) { + &drawable->u.opaque.src_area, color_trans, TRUE, + &drawable->surfaces_dest[2])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[1], mask_pos, width, height); + } + CopyRect(&drawable->surfaces_rects[2], src_rect); + drawable->u.opaque.rop_decriptor = rop_decriptor; drawable->effect = mask ? QXL_EFFECT_BLEND : QXL_EFFECT_OPAQUE; PushDrawable(pdev, drawable); @@ -521,7 +551,7 @@ static BOOL StreamTest(PDev *pdev, SURFOBJ *src_surf, XLATEOBJ *color_trans, REC return TRUE; } -static BOOL TestSplitClips(PDev *pdev, RECTL *src_rect, CLIPOBJ *clip, SURFOBJ *mask) +static BOOL TestSplitClips(PDev *pdev, SURFOBJ *src, RECTL *src_rect, CLIPOBJ *clip, SURFOBJ *mask) { UINT32 width; UINT32 height; @@ -533,6 +563,10 @@ static BOOL TestSplitClips(PDev *pdev, RECTL *src_rect, CLIPOBJ *clip, SURFOBJ * return FALSE; } + if (src->iType != STYPE_BITMAP) { + return FALSE; + } + width = src_rect->right - src_rect->left; height = src_rect->bottom - src_rect->top; src_space = width * height; @@ -574,19 +608,24 @@ static BOOL TestSplitClips(PDev *pdev, RECTL *src_rect, CLIPOBJ *clip, SURFOBJ * return FALSE; } -static _inline BOOL DoPartialCopy(PDev *pdev, SURFOBJ *src, RECTL *src_rect, RECTL *area_rect, - RECTL *clip_rect, XLATEOBJ *color_trans, ULONG scale_mode, - UINT16 rop_decriptor) +static _inline BOOL DoPartialCopy(PDev *pdev, UINT32 surface_id, SURFOBJ *src, RECTL *src_rect, + RECTL *area_rect, RECTL *clip_rect, XLATEOBJ *color_trans, + ULONG scale_mode, UINT16 rop_decriptor) { QXLDrawable *drawable; RECTL clip_area; + UINT32 width; + UINT32 height; SectRect(area_rect, clip_rect, &clip_area); if (IsEmptyRect(&clip_area)) { return TRUE; } - if (!(drawable = Drawable(pdev, QXL_DRAW_COPY, &clip_area, NULL))) { + width = clip_area.right - clip_area.left; + height = clip_area.bottom - clip_area.top; + + if (!(drawable = Drawable(pdev, QXL_DRAW_COPY, &clip_area, NULL, surface_id))) { return FALSE; } @@ -603,36 +642,41 @@ static _inline BOOL DoPartialCopy(PDev *pdev, SURFOBJ *src, RECTL *src_rect, REC clip_area.left; if(!GetBitmap(pdev, drawable, &drawable->u.copy.src_bitmap, src, &drawable->u.copy.src_area, - color_trans, FALSE)) { + color_trans, FALSE, &drawable->surfaces_dest[0])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + CopyRect(&drawable->surfaces_rects[0], src_rect); PushDrawable(pdev, drawable); return TRUE; } -static BOOL DoCopy(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL *src_rect, - XLATEOBJ *color_trans, UINT16 rop_decriptor, SURFOBJ *mask, POINTL *mask_pos, - BOOL invers_mask, ULONG scale_mode) +static BOOL DoCopy(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, + RECTL *src_rect, XLATEOBJ *color_trans, UINT16 rop_decriptor, SURFOBJ *mask, + POINTL *mask_pos, BOOL invers_mask, ULONG scale_mode) { QXLDrawable *drawable; BOOL use_cache; + UINT32 width; + UINT32 height; ASSERT(pdev, pdev && area && src_rect && src); DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); + width = area->right - area->left; + height = area->bottom - area->top; + if (mask) { use_cache = TRUE; } else { use_cache = StreamTest(pdev, src, color_trans, src_rect, area); } - if (use_cache && TestSplitClips(pdev, src_rect, clip, mask) && + if (use_cache && TestSplitClips(pdev, src, src_rect, clip, mask) && !CheckIfCacheImage(pdev, src, color_trans)) { - if (clip->iDComplexity == DC_RECT) { - if (!DoPartialCopy(pdev, src, src_rect, area, &clip->rclBounds, color_trans, scale_mode, - rop_decriptor)) { + if (!DoPartialCopy(pdev, surface_id, src, src_rect, area, &clip->rclBounds, color_trans, + scale_mode, rop_decriptor)) { return FALSE; } } else { @@ -649,8 +693,8 @@ static BOOL DoCopy(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL * } buf; more = CLIPOBJ_bEnum(clip, sizeof(buf), (ULONG *)&buf); for(now = buf.rects, end = now + buf.count; now < end; now++) { - if (!DoPartialCopy(pdev, src, src_rect, area, now, color_trans, scale_mode, - rop_decriptor)) { + if (!DoPartialCopy(pdev, surface_id, src, src_rect, area, now, color_trans, + scale_mode, rop_decriptor)) { return FALSE; } } @@ -659,7 +703,7 @@ static BOOL DoCopy(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL * return TRUE; } - if (!(drawable = Drawable(pdev, QXL_DRAW_COPY, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_COPY, area, clip, surface_id))) { return FALSE; } @@ -672,22 +716,29 @@ static BOOL DoCopy(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL * drawable->u.copy.scale_mode = GdiScaleModeToQxl(scale_mode); CopyRect(&drawable->u.copy.src_area, src_rect); if (!QXLGetMask(pdev, drawable, &drawable->u.copy.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top) || + width, height, &drawable->surfaces_dest[0]) || !GetBitmap(pdev, drawable, &drawable->u.copy.src_bitmap, src, &drawable->u.copy.src_area, - color_trans, use_cache)) { + color_trans, use_cache, &drawable->surfaces_dest[1])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[0], mask_pos, width, height); + } + CopyRect(&drawable->surfaces_rects[1], src_rect); + drawable->u.copy.rop_decriptor = rop_decriptor; PushDrawable(pdev, drawable); DEBUG_PRINT((pdev, 7, "%s: done\n", __FUNCTION__)); return TRUE; } -static BOOL DoCopyBits(PDev *pdev, CLIPOBJ *clip, RECTL *area, POINTL *src_pos) +static BOOL DoCopyBits(PDev *pdev, UINT32 surface_id, CLIPOBJ *clip, RECTL *area, POINTL *src_pos) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; ASSERT(pdev, pdev && area && src_pos); DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); @@ -697,144 +748,199 @@ static BOOL DoCopyBits(PDev *pdev, CLIPOBJ *clip, RECTL *area, POINTL *src_pos) return TRUE; } - if (!(drawable = Drawable(pdev, QXL_COPY_BITS, area, clip))) { + width = area->right - area->left; + height = area->bottom - area->top; + + if (!(drawable = Drawable(pdev, QXL_COPY_BITS, area, clip, surface_id))) { return FALSE; } + + drawable->surfaces_dest[0] = surface_id; + CopyRectPoint(&drawable->surfaces_rects[0], src_pos, width, height); + CopyPoint(&drawable->u.copy_bits.src_pos, src_pos); drawable->effect = QXL_EFFECT_OPAQUE; PushDrawable(pdev, drawable); return TRUE; } -static BOOL DoBlend(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL *src_rect, - XLATEOBJ *color_trans, ROP3Info *rop_info, SURFOBJ *mask, POINTL *mask_pos, - BOOL invers_mask, ULONG scale_mode) +static BOOL DoBlend(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, + RECTL *src_rect, XLATEOBJ *color_trans, ROP3Info *rop_info, SURFOBJ *mask, + POINTL *mask_pos, BOOL invers_mask, ULONG scale_mode) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area && src_rect && src); - if (!(drawable = Drawable(pdev, QXL_DRAW_BLEND, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_BLEND, area, clip, surface_id))) { return FALSE; } + width = area->right - area->left; + height = area->bottom - area->top; + drawable->u.blend.scale_mode = GdiScaleModeToQxl(scale_mode); CopyRect(&drawable->u.blend.src_area, src_rect); if (!QXLGetMask(pdev, drawable, &drawable->u.blend.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top) || + width, height, &drawable->surfaces_dest[0]) || !GetBitmap(pdev, drawable, &drawable->u.blend.src_bitmap, src, &drawable->u.blend.src_area, - color_trans, TRUE)) { + color_trans, TRUE, &drawable->surfaces_dest[1])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[0], mask_pos, width, height); + } + CopyRect(&drawable->surfaces_rects[1], src_rect); + drawable->u.blend.rop_decriptor = rop_info->method_data; drawable->effect = mask ? QXL_EFFECT_BLEND : rop_info->effect; PushDrawable(pdev, drawable); return TRUE; } -static BOOL DoBlackness(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *mask, POINTL *mask_pos, - BOOL invers_mask) +static BOOL DoBlackness(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *mask, + POINTL *mask_pos, BOOL invers_mask) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area); - if (!(drawable = Drawable(pdev, QXL_DRAW_BLACKNESS, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_BLACKNESS, area, clip, surface_id))) { return FALSE; } + width = area->right - area->left; + height = area->bottom - area->top; + if (!QXLGetMask(pdev, drawable, &drawable->u.blackness.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top)) { + width, height, &drawable->surfaces_dest[0])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[0], mask_pos, width, height); + } + drawable->effect = mask ? QXL_EFFECT_BLEND : QXL_EFFECT_OPAQUE; PushDrawable(pdev, drawable); return TRUE; } -static BOOL DoWhiteness(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *mask, POINTL *mask_pos, - BOOL invers_mask) +static BOOL DoWhiteness(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *mask, + POINTL *mask_pos, BOOL invers_mask) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area); - if (!(drawable = Drawable(pdev, QXL_DRAW_WHITENESS, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_WHITENESS, area, clip, surface_id))) { return FALSE; } + width = area->right - area->left; + height = area->bottom - area->top; + if (!QXLGetMask(pdev, drawable, &drawable->u.whiteness.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top)) { + width, height, &drawable->surfaces_dest[0])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[0], mask_pos, width, height); + } + drawable->effect = mask ? QXL_EFFECT_BLEND : QXL_EFFECT_OPAQUE; PushDrawable(pdev, drawable); return TRUE; } -static BOOL DoInvers(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *mask, POINTL *mask_pos, - BOOL invers_mask) +static BOOL DoInvers(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *mask, + POINTL *mask_pos, BOOL invers_mask) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area); - if (!(drawable = Drawable(pdev, QXL_DRAW_INVERS, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_INVERS, area, clip, surface_id))) { return FALSE; } + width = area->right - area->left; + height = area->bottom - area->top; + if (!QXLGetMask(pdev, drawable, &drawable->u.invers.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top)) { + width, height, &drawable->surfaces_dest[0])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[0], mask_pos, width, height); + } + drawable->effect = mask ? QXL_EFFECT_BLEND : QXL_EFFECT_REVERT_ON_DUP; PushDrawable(pdev, drawable); return TRUE; } -static BOOL DoROP3(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL *src_rect, - XLATEOBJ *color_trans, BRUSHOBJ *brush, POINTL *brush_pos, UINT8 rop3, - SURFOBJ *mask, POINTL *mask_pos, BOOL invers_mask, ULONG scale_mode) +static BOOL DoROP3(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, + RECTL *src_rect, XLATEOBJ *color_trans, BRUSHOBJ *brush, POINTL *brush_pos, + UINT8 rop3, SURFOBJ *mask, POINTL *mask_pos, BOOL invers_mask, ULONG scale_mode) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area && brush && src_rect && src); - if (!(drawable = Drawable(pdev, QXL_DRAW_ROP3, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_ROP3, area, clip, surface_id))) { return FALSE; } + width = area->right - area->left; + height = area->bottom - area->top; + drawable->u.rop3.scale_mode = GdiScaleModeToQxl(scale_mode); CopyRect(&drawable->u.rop3.src_area, src_rect); - if (!QXLGetBrush(pdev, drawable, &drawable->u.rop3.brush, brush, brush_pos) || + if (!QXLGetBrush(pdev, drawable, &drawable->u.rop3.brush, brush, brush_pos, + &drawable->surfaces_dest[0], &drawable->surfaces_rects[0]) || !QXLGetMask(pdev, drawable, &drawable->u.rop3.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top) || + width, height, &drawable->surfaces_dest[1]) || !GetBitmap(pdev, drawable, &drawable->u.rop3.src_bitmap, src, &drawable->u.rop3.src_area, - color_trans, TRUE)) { + color_trans, TRUE, &drawable->surfaces_dest[2])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[1], mask_pos, width, height); + } + CopyRect(&drawable->surfaces_rects[2], src_rect); + drawable->u.rop3.rop3 = rop3; drawable->effect = mask ? QXL_EFFECT_BLEND : QXL_EFFECT_BLEND; //for now PushDrawable(pdev, drawable); return TRUE; } -static SURFOBJ *Copy16bppArea(PDev *pdev, RECTL *area) +static SURFOBJ *Copy16bppArea(PDev *pdev, SURFOBJ *src, RECTL *area) { SIZEL size; HSURF bitmap; @@ -843,6 +949,9 @@ static SURFOBJ *Copy16bppArea(PDev *pdev, RECTL *area) UINT8 *dest_end_line; LONG src_stride; UINT8 *src_line; + SurfaceInfo *surface; + + surface = (SurfaceInfo *)src->dhsurf; size.cx = area->right - area->left; size.cy = area->bottom - area->top; @@ -864,8 +973,9 @@ static SURFOBJ *Copy16bppArea(PDev *pdev, RECTL *area) dest_line = surf_obj->pvScan0; dest_end_line = dest_line + surf_obj->lDelta * surf_obj->sizlBitmap.cy; - src_stride = pdev->draw_surf->lDelta; - src_line = (UINT8 *)pdev->draw_surf->pvScan0 + area->top * src_stride + (area->left << 2); + src_stride = surface->draw_area.surf_obj->lDelta; + src_line = (UINT8 *)surface->draw_area.surf_obj->pvScan0 + area->top * src_stride + + (area->left << 2); for (; dest_line != dest_end_line; dest_line += surf_obj->lDelta, src_line += src_stride) { UINT16 *dest = (UINT16 *)dest_line; @@ -885,13 +995,16 @@ error: } -static BOOL BitBltFromDev(PDev *pdev, SURFOBJ *dest, SURFOBJ *mask, CLIPOBJ *clip, +static BOOL BitBltFromDev(PDev *pdev, SURFOBJ *src, SURFOBJ *dest, SURFOBJ *mask, CLIPOBJ *clip, XLATEOBJ *color_trans, RECTL *dest_rect, POINTL src_pos, POINTL *mask_pos, BRUSHOBJ *brush, POINTL *brush_pos, ROP4 rop4) { RECTL area; SURFOBJ* surf_obj; BOOL ret; + UINT32 surface_id; + + surface_id = GetSurfaceId(src); DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); @@ -900,17 +1013,20 @@ static BOOL BitBltFromDev(PDev *pdev, SURFOBJ *dest, SURFOBJ *mask, CLIPOBJ *cli area.left = MAX(0, src_pos.x); area.right = MIN(src_pos.x + dest_rect->right - dest_rect->left, pdev->resolution.cx); - UpdateArea(pdev, &area); + UpdateArea(pdev, &area, surface_id); if (pdev->bitmap_format == BMF_16BPP) { - surf_obj = Copy16bppArea(pdev, &area); + surf_obj = Copy16bppArea(pdev, src, &area); if (!surf_obj) { return FALSE; } src_pos.y = src_pos.y - area.top; src_pos.x = src_pos.x - area.left; } else { - surf_obj = pdev->draw_surf; + SurfaceInfo *surface; + + surface = (SurfaceInfo *)src->dhsurf; + surf_obj = surface->draw_area.surf_obj; } if (rop4 == 0xcccc) { @@ -930,9 +1046,10 @@ static BOOL BitBltFromDev(PDev *pdev, SURFOBJ *dest, SURFOBJ *mask, CLIPOBJ *cli return ret; } -BOOL _inline __DrvBitBlt(PDev *pdev, RECTL *dest_rect, CLIPOBJ *clip, SURFOBJ *src, RECTL *src_rect, - XLATEOBJ *color_trans, BRUSHOBJ *brush, POINTL *brush_pos, ULONG rop3, - SURFOBJ *mask, POINTL *mask_pos, BOOL invers_mask, ULONG scale_mode) +BOOL _inline __DrvBitBlt(PDev *pdev, UINT32 surface_id, RECTL *dest_rect, CLIPOBJ *clip, + SURFOBJ *src, RECTL *src_rect, XLATEOBJ *color_trans, BRUSHOBJ *brush, + POINTL *brush_pos, ULONG rop3, SURFOBJ *mask, POINTL *mask_pos, + BOOL invers_mask, ULONG scale_mode) { ROP3Info *rop_info = &rops3[rop3]; @@ -940,26 +1057,27 @@ BOOL _inline __DrvBitBlt(PDev *pdev, RECTL *dest_rect, CLIPOBJ *clip, SURFOBJ *s switch (rop_info->method_type) { case ROP3_TYPE_FILL: - return DoFill(pdev, dest_rect, clip, brush, brush_pos, rop_info, mask, mask_pos, + return DoFill(pdev, surface_id, dest_rect, clip, brush, brush_pos, rop_info, mask, mask_pos, invers_mask); case ROP3_TYPE_OPAQUE: - return DoOpaque(pdev, dest_rect, clip, src, src_rect, color_trans, brush, brush_pos, - rop_info->method_data, mask, mask_pos, invers_mask, scale_mode); + return DoOpaque(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, brush, + brush_pos, rop_info->method_data, mask, mask_pos, invers_mask, scale_mode); case ROP3_TYPE_COPY: - return DoCopy(pdev, dest_rect, clip, src, src_rect, color_trans, rop_info->method_data, - mask, mask_pos, invers_mask, scale_mode); + return DoCopy(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, + rop_info->method_data, mask, mask_pos, invers_mask, scale_mode); case ROP3_TYPE_BLEND: - return DoBlend(pdev, dest_rect, clip, src, src_rect, color_trans, rop_info, mask, mask_pos, - invers_mask, scale_mode); + return DoBlend(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, rop_info, + mask, mask_pos, invers_mask, scale_mode); case ROP3_TYPE_BLACKNESS: - return DoBlackness(pdev, dest_rect, clip, mask, mask_pos, invers_mask); + return DoBlackness(pdev, surface_id, dest_rect, clip, mask, mask_pos, invers_mask); case ROP3_TYPE_WHITENESS: - return DoWhiteness(pdev, dest_rect, clip, mask, mask_pos, invers_mask); + return DoWhiteness(pdev, surface_id, dest_rect, clip, mask, mask_pos, invers_mask); case ROP3_TYPE_INVERS: - return DoInvers(pdev, dest_rect, clip, mask, mask_pos, invers_mask); + return DoInvers(pdev, surface_id, dest_rect, clip, mask, mask_pos, invers_mask); case ROP3_TYPE_ROP3: - return DoROP3(pdev, dest_rect, clip, src, src_rect, color_trans, brush, brush_pos, - (UINT8)rop_info->method_data, mask, mask_pos, invers_mask, scale_mode); + return DoROP3(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, brush, + brush_pos, (UINT8)rop_info->method_data, mask, mask_pos, invers_mask, + scale_mode); case ROP3_TYPE_NOP: return TRUE; default: @@ -1055,14 +1173,20 @@ static QXLRESULT BitBltCommon(PDev *pdev, SURFOBJ *dest, SURFOBJ *src, SURFOBJ * SURFOBJ *brush_mask = NULL; #endif QXLRESULT res; + UINT32 surface_id; + + ASSERT(pdev, dest->iType != STYPE_BITMAP); + + surface_id = GetSurfaceId(dest); if (!PrepareBrush(brush)) { return QXL_FAILED; } if ((rop3 = rop4 & 0xff) == (second_rop3 = ((rop4 >> 8) & 0xff))) { - return __DrvBitBlt(pdev, dest_rect, clip, src, src_rect, color_trans, brush, brush_pos, - rop3, NULL, NULL, FALSE, scale_mode) ? QXL_SUCCESS : QXL_FAILED; + return __DrvBitBlt(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, brush, + brush_pos, rop3, NULL, NULL, FALSE, scale_mode) ? QXL_SUCCESS : + QXL_FAILED; } if (!mask) { @@ -1080,15 +1204,17 @@ static QXLRESULT BitBltCommon(PDev *pdev, SURFOBJ *dest, SURFOBJ *src, SURFOBJ * } DEBUG_PRINT((pdev, 5, "%s: mask, rop4 is 0x%x\n", __FUNCTION__, rop4)); ASSERT(pdev, mask_pos); - res = (__DrvBitBlt(pdev, dest_rect, clip, src, src_rect, color_trans, brush, brush_pos, rop3, - mask, mask_pos, FALSE, scale_mode) && - __DrvBitBlt(pdev, dest_rect, clip, src, src_rect, color_trans, brush, brush_pos, - second_rop3, mask, mask_pos, TRUE, scale_mode)) ? QXL_SUCCESS : QXL_FAILED; + res = (__DrvBitBlt(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, brush, + brush_pos, rop3, mask, mask_pos, FALSE, scale_mode) && + __DrvBitBlt(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, brush, + brush_pos, second_rop3, mask, mask_pos, TRUE, scale_mode)) ? QXL_SUCCESS : + QXL_FAILED; #ifdef SUPPORT_BRUSH_AS_MASK if (brush_mask) { //free brush_mask; } #endif + return res; } @@ -1151,8 +1277,6 @@ static QXLRESULT _BitBlt(PDev *pdev, SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, } #endif - ASSERT(pdev, dest->iType == STYPE_BITMAP || dest->hsurf == pdev->surf); - ASSERT(pdev, !src || src->iType == STYPE_BITMAP || src->hsurf == pdev->surf); ASSERT(pdev, dest_rect && dest_rect->left < dest_rect->right && dest_rect->top < dest_rect->bottom); @@ -1169,12 +1293,14 @@ static QXLRESULT _BitBlt(PDev *pdev, SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, local_pos.y = src_pos->y + (area.top - dest_rect->top); if (dest->iType == STYPE_BITMAP) { - return BitBltFromDev(pdev, dest, mask, clip, color_trans, &area, local_pos, mask_pos, - brush, brush_pos, rop4) ? QXL_SUCCESS : QXL_FAILED; + return BitBltFromDev(pdev, src, dest, mask, clip, color_trans, &area, local_pos, + mask_pos, brush, brush_pos, rop4) ? QXL_SUCCESS : QXL_FAILED; } - if (src->iType != STYPE_BITMAP && rop4 == 0xcccc) { //SRCCOPY no mask - return DoCopyBits(pdev, clip, &area, &local_pos) ? QXL_SUCCESS : QXL_FAILED; + if (src->iType != STYPE_BITMAP + && GetSurfaceId(src) == GetSurfaceId(dest) && rop4 == 0xcccc) { //SRCCOPY no mask + return DoCopyBits(pdev, GetSurfaceId(src), clip, &area, &local_pos) ? + QXL_SUCCESS : QXL_FAILED; } src_rect.left = local_pos.x; @@ -1185,6 +1311,7 @@ static QXLRESULT _BitBlt(PDev *pdev, SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, } else { src_rect_ptr = NULL; } + return BitBltCommon(pdev, dest, src, mask, clip, color_trans, &area, src_rect_ptr, mask_pos, brush, brush_pos, rop4, COLORONCOLOR, NULL); } @@ -1197,14 +1324,13 @@ BOOL APIENTRY DrvBitBlt(SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, CLIPOBJ *cli QXLRESULT res; if (dest->iType == STYPE_BITMAP) { - ASSERT(NULL, src && src->iType != STYPE_BITMAP && src->dhpdev && src_pos); pdev = (PDev *)src->dhpdev; } else { - ASSERT(NULL, dest->dhpdev); pdev = (PDev *)dest->dhpdev; - CountCall(pdev, CALL_COUNTER_BIT_BLT); } + CountCall(pdev, CALL_COUNTER_BIT_BLT); + DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); if ((res = _BitBlt(pdev, dest, src, mask, clip, color_trans, dest_rect, src_pos, mask_pos, brush, brush_pos, rop4))) { @@ -1216,6 +1342,7 @@ BOOL APIENTRY DrvBitBlt(SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, CLIPOBJ *cli return FALSE; } + DEBUG_PRINT((pdev, 4, "%s: done\n", __FUNCTION__)); return TRUE; } @@ -1226,14 +1353,13 @@ BOOL APIENTRY DrvCopyBits(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, PDev *pdev; if (dest->iType == STYPE_BITMAP) { - ASSERT(NULL, src && src->iType != STYPE_BITMAP && src->dhpdev && src_pos); pdev = (PDev *)src->dhpdev; } else { - ASSERT(NULL, dest->dhpdev); pdev = (PDev *)dest->dhpdev; - CountCall(pdev, CALL_COUNTER_BIT_BLT); } + CountCall(pdev, CALL_COUNTER_BIT_BLT); + DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); return _BitBlt(pdev, dest, src, NULL, clip, color_trans, dest_rect, src_pos, NULL, NULL, @@ -1389,13 +1515,12 @@ BOOL APIENTRY DrvStretchBltROP(SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, CLIPO PDev *pdev; QXLRESULT res; - if (!src || src->iType != STYPE_BITMAP) { - ASSERT(NULL, src->dhpdev); + if (src && src->iType != STYPE_BITMAP) { pdev = (PDev *)src->dhpdev; - goto punt; + } else { + pdev = (PDev *)dest->dhpdev; } - ASSERT(NULL, dest && dest->iType != STYPE_BITMAP && dest->dhpdev); pdev = (PDev *)dest->dhpdev; DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); CountCall(pdev, CALL_COUNTER_STRETCH_BLT_ROP); @@ -1425,11 +1550,10 @@ BOOL APIENTRY DrvStretchBlt(SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, CLIPOBJ ASSERT(NULL, src); if (src->iType != STYPE_BITMAP) { - ASSERT(NULL, src->dhpdev); pdev = (PDev *)src->dhpdev; - goto punt; + } else { + pdev = (PDev *)dest->dhpdev; } - ASSERT(NULL, dest && dest->iType != STYPE_BITMAP && dest->dhpdev); pdev = (PDev *)dest->dhpdev; DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); @@ -1522,11 +1646,11 @@ BOOL APIENTRY DrvAlphaBlend(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, XLATEOBJ ASSERT(NULL, src && dest); if (src->iType != STYPE_BITMAP) { - ASSERT(NULL, src->dhpdev); pdev = (PDev *)src->dhpdev; - goto punt; + } else { + pdev = (PDev *)dest->dhpdev; } - ASSERT(NULL, dest->iType != STYPE_BITMAP && dest->dhpdev); + pdev = (PDev *)dest->dhpdev; DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); @@ -1562,7 +1686,7 @@ BOOL APIENTRY DrvAlphaBlend(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, XLATEOBJ return TRUE; } - if (!(drawable = Drawable(pdev, QXL_DRAW_ALPHA_BLEND, &area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_ALPHA_BLEND, &area, clip, GetSurfaceId(dest)))) { DEBUG_PRINT((pdev, 0, "%s: Drawable failed\n", __FUNCTION__)); return FALSE; } @@ -1571,18 +1695,21 @@ BOOL APIENTRY DrvAlphaBlend(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, XLATEOBJ src_rect = &local_src; } + CopyRect(&drawable->surfaces_rects[0], src_rect); CopyRect(&drawable->u.alpha_blend.src_area, src_rect); if (bland->BlendFunction.AlphaFormat == AC_SRC_ALPHA) { ASSERT(pdev, src->iBitmapFormat == BMF_32BPP); if (!QXLGetAlphaBitmap(pdev, drawable, &drawable->u.alpha_blend.src_bitmap, src, - &drawable->u.alpha_blend.src_area)) { + &drawable->u.alpha_blend.src_area, + &drawable->surfaces_dest[0])) { DEBUG_PRINT((pdev, 0, "%s: QXLGetAlphaBitmap failed\n", __FUNCTION__)); ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } } else { if (!QXLGetBitmap(pdev, drawable, &drawable->u.alpha_blend.src_bitmap, src, - &drawable->u.alpha_blend.src_area, color_trans, NULL, TRUE)) { + &drawable->u.alpha_blend.src_area, color_trans, NULL, TRUE, + &drawable->surfaces_dest[0])) { DEBUG_PRINT((pdev, 0, "%s: QXLGetBitmap failed\n", __FUNCTION__)); ReleaseOutput(pdev, drawable->release_info.id); return FALSE; @@ -1613,11 +1740,11 @@ BOOL APIENTRY DrvTransparentBlt(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, XLAT if (src->iType != STYPE_BITMAP) { ASSERT(NULL, src->dhpdev); pdev = (PDev *)src->dhpdev; - goto punt; + } else { + ASSERT(NULL, dest->dhpdev); + pdev = (PDev *)dest->dhpdev; } - ASSERT(NULL, dest->iType != STYPE_BITMAP && dest->dhpdev); - pdev = (PDev *)dest->dhpdev; DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); ASSERT(pdev, src_rect && src_rect->left < src_rect->right && @@ -1643,7 +1770,7 @@ BOOL APIENTRY DrvTransparentBlt(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, XLAT return TRUE; } - if (!(drawable = Drawable(pdev, QXL_DRAW_TRANSPARENT, &area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_TRANSPARENT, &area, clip, GetSurfaceId(dest)))) { DEBUG_PRINT((pdev, 0, "%s: Drawable failed\n", __FUNCTION__)); return FALSE; } @@ -1653,8 +1780,10 @@ BOOL APIENTRY DrvTransparentBlt(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, XLAT } CopyRect(&drawable->u.transparent.src_area, src_rect); + CopyRect(&drawable->surfaces_rects[0], src_rect); if (!QXLGetBitmap(pdev, drawable, &drawable->u.transparent.src_bitmap, src, - &drawable->u.transparent.src_area, color_trans, NULL, TRUE)) { + &drawable->u.transparent.src_area, color_trans, NULL, TRUE, + &drawable->surfaces_dest[0])) { DEBUG_PRINT((pdev, 0, "%s: QXLGetBitmap failed\n", __FUNCTION__)); ReleaseOutput(pdev, drawable->release_info.id); return FALSE; |