[Spice-devel] [PATCH] DrvSetPointerShape: handle surface which is not bitmap

Yonit Halperin yhalperi at redhat.com
Tue Apr 13 05:08:39 PDT 2010


BTW, it looks like there is a possible old correctness bug in 
GetColorCursor: the caching is performed only by the unique id of the 
surface and it ignores the mask. So for the same surface we will 
retrieve the same cursor command, even though the mask can be different.


On 04/13/2010 03:00 PM, Yonit Halperin wrote:
> ---
>   display/res.c |   99 +++++++++++++++++++++++++++++++++++++++++++++++---------
>   display/rop.c |    2 +-
>   display/rop.h |    3 ++
>   3 files changed, 87 insertions(+), 17 deletions(-)
>
> diff --git a/display/res.c b/display/res.c
> index 318ea9c..2ea9565 100644
> --- a/display/res.c
> +++ b/display/res.c
> @@ -27,6 +27,7 @@
>   #include "murmur_hash2a.h"
>   #include "surface.h"
>   #include "dd.h"
> +#include "rop.h"
>
>   #if (WINVER<  0x0501)
>   #define WAIT_FOR_EVENT(pdev, event, timeout) (pdev)->WaitForEvent(event, timeout)
> @@ -2738,7 +2739,7 @@ typedef struct NewCursorInfo {
>   #define CURSOR_ALLOC_SIZE (PAGE_SIZE<<  1)
>
>   static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFOBJ *surf,
> -                            UINT16 type, NewCursorInfo *info)
> +                            UINT16 type, NewCursorInfo *info, BOOL *in_cach)
>   {
>       InternalCursor *internal;
>       QXLCursor *cursor;
> @@ -2747,19 +2748,59 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_
>       UINT8 *src;
>       UINT8 *src_end;
>       int line_size;
> -
> +    HSURF bitmap = 0;
> +    SURFOBJ *local_surf = surf;
>
>       DEBUG_PRINT((pdev, 9, "%s\n", __FUNCTION__));
> -
> +    *in_cach = FALSE;
>       unique = (surf->fjBitmap&  BMF_DONTCACHE) ? 0 : surf->iUniq;
>
>       if ((internal = CursorCacheGet(pdev, surf->hsurf, unique))) {
>           res = (Resource *)((UINT8 *)internal - sizeof(Resource));
>           CursorCmdAddRes(pdev, cmd, res);
>           cmd->u.set.shape = PA(pdev,&internal->cursor, pdev->main_mem_slot);
> +        *in_cach = TRUE;
>           return TRUE;
>       }
>
> +    if (surf->iType != STYPE_BITMAP) {
> +        RECTL dest_rect;
> +        POINTL src_pos;
> +        ASSERT(pdev, surf->iBitmapFormat == BMF_32BPP || surf->iBitmapFormat == BMF_16BPP);
> +
> +        /* copying the surface to a bitmap */
> +
> +        bitmap = (HSURF)EngCreateBitmap(surf->sizlBitmap, surf->lDelta, surf->iBitmapFormat,
> +                                        0, NULL);
> +        if (!bitmap) {
> +            DEBUG_PRINT((pdev, 0, "%s: EngCreateBitmap failed\n", __FUNCTION__));
> +            return FALSE;
> +        }
> +
> +        if (!EngAssociateSurface(bitmap, pdev->eng, 0)) {
> +            DEBUG_PRINT((pdev, 0, "%s: EngAssociateSurface failed\n", __FUNCTION__));
> +            goto error;
> +        }
> +
> +        if (!(local_surf = EngLockSurface(bitmap))) {
> +            DEBUG_PRINT((pdev, 0, "%s: EngLockSurface failed\n", __FUNCTION__));
> +            goto error;
> +        }
> +
> +        dest_rect.top = 0;
> +        dest_rect.left = 0;
> +        dest_rect.bottom = surf->sizlBitmap.cy;
> +        dest_rect.right = surf->sizlBitmap.cx;
> +
> +        src_pos.x = 0;
> +        src_pos.y = 0;
> +
> +        if (!BitBltFromDev(pdev, surf, local_surf, NULL, NULL, NULL,&dest_rect, src_pos,
> +                           NULL, NULL, NULL, 0xcccc)) {
> +            goto error;
> +        }
> +    }
> +
>       ASSERT(pdev, sizeof(Resource) + sizeof(InternalCursor)<  CURSOR_ALLOC_SIZE);
>       res = (Resource *)AllocMem(pdev, CURSOR_ALLOC_SIZE);
>       ONDBG(pdev->Res.num_cursor_pages++);
> @@ -2774,9 +2815,9 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_
>       cursor = info->cursor =&internal->cursor;
>       cursor->header.type = type;
>       cursor->header.unique = unique ? ++pdev->Res.last_cursor_id : 0;
> -    cursor->header.width = (UINT16)surf->sizlBitmap.cx;
> -    cursor->header.height = (type == SPICE_CURSOR_TYPE_MONO) ? (UINT16)surf->sizlBitmap.cy>>  1 :
> -                            (UINT16)surf->sizlBitmap.cy;
> +    cursor->header.width = (UINT16)local_surf->sizlBitmap.cx;
> +    cursor->header.height = (type == SPICE_CURSOR_TYPE_MONO) ? (UINT16)local_surf->sizlBitmap.cy>>  1 :
> +                            (UINT16)local_surf->sizlBitmap.cy;
>       cursor->header.hot_spot_x = (UINT16)hot_x;
>       cursor->header.hot_spot_y = (UINT16)hot_y;
>
> @@ -2812,10 +2853,10 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_
>           break;
>       }
>
> -    cursor->data_size = line_size * surf->sizlBitmap.cy;
> -    src = surf->pvScan0;
> -    src_end = src + (surf->lDelta * surf->sizlBitmap.cy);
> -    for (; src != src_end; src += surf->lDelta) {
> +    cursor->data_size = line_size * local_surf->sizlBitmap.cy;
> +    src = local_surf->pvScan0;
> +    src_end = src + (local_surf->lDelta * local_surf->sizlBitmap.cy);
> +    for (; src != src_end; src += local_surf->lDelta) {
>           PutBytes(pdev,&info->chunk,&info->now,&info->end, src, line_size,
>                    &pdev->Res.num_cursor_pages, PAGE_SIZE, FALSE);
>       }
> @@ -2825,25 +2866,42 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_
>       RELEASE_RES(pdev, res);
>       cmd->u.set.shape = PA(pdev,&internal->cursor, pdev->main_mem_slot);
>       DEBUG_PRINT((pdev, 11, "%s: done, data_size %u\n", __FUNCTION__, cursor->data_size));
> +
> +    if (local_surf != surf) {
> +        EngUnlockSurface(local_surf);
> +        EngDeleteSurface(bitmap);
> +    }
> +
> +    return TRUE;
> +error:
> +    if (bitmap) {
> +        ASSERT(pdev, local_surf != surf);
> +        EngDeleteSurface(bitmap);
> +    }
> +
>       return FALSE;
>   }
>
>   BOOL GetAlphaCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFOBJ *surf)
>   {
>       NewCursorInfo info;
> +    BOOL ret;
> +    BOOL in_cache;
>
>       ASSERT(pdev, surf->iBitmapFormat == BMF_32BPP);
>       ASSERT(pdev, surf->sizlBitmap.cx>  0&&  surf->sizlBitmap.cy>  0);
>
>       DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__));
> -    GetCursorCommon(pdev, cmd, hot_x, hot_y, surf, SPICE_CURSOR_TYPE_ALPHA,&info);
> +    ret = GetCursorCommon(pdev, cmd, hot_x, hot_y, surf, SPICE_CURSOR_TYPE_ALPHA,&info,&in_cache);
>       DEBUG_PRINT((pdev, 8, "%s: done\n", __FUNCTION__));
> -    return TRUE;
> +    return ret;
>   }
>
>   BOOL GetMonoCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFOBJ *surf)
>   {
>       NewCursorInfo info;
> +    BOOL ret;
> +    BOOL in_cache;
>
>       ASSERT(pdev, surf->iBitmapFormat == BMF_1BPP);
>       ASSERT(pdev, surf->sizlBitmap.cy>  0&&  (surf->sizlBitmap.cy&  1) == 0);
> @@ -2851,9 +2909,9 @@ BOOL GetMonoCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFOB
>
>       DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__));
>
> -    GetCursorCommon(pdev, cmd, hot_x, hot_y, surf, SPICE_CURSOR_TYPE_MONO,&info);
> +    ret = GetCursorCommon(pdev, cmd, hot_x, hot_y, surf, SPICE_CURSOR_TYPE_MONO,&info,&in_cache);
>       DEBUG_PRINT((pdev, 8, "%s: done\n", __FUNCTION__));
> -    return TRUE;
> +    return ret;
>   }
>
>   BOOL GetColorCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFOBJ *surf,
> @@ -2861,7 +2919,7 @@ BOOL GetColorCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFO
>   {
>       NewCursorInfo info;
>       UINT16 type;
> -
> +    BOOL in_cache;
>
>       DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__));
>
> @@ -2899,7 +2957,12 @@ BOOL GetColorCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFO
>           DEBUG_PRINT((pdev, 0, "%s: unexpected format\n", __FUNCTION__));
>           return FALSE;
>       }
> -    if (!GetCursorCommon(pdev, cmd, hot_x, hot_y, surf, type,&info)) {
> +
> +    if (!GetCursorCommon(pdev, cmd, hot_x, hot_y, surf, type,&info,&in_cache)) {
> +        return FALSE;
> +    }
> +
> +    if (!in_cache) {
>           int line_size;
>           UINT8 *src;
>           UINT8 *src_end;
> @@ -2946,6 +3009,10 @@ BOOL GetColorCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFO
>               }
>               info.cursor->data_size += 16<<  2;
>           }
> +
> +        ASSERT(pdev, mask->iBitmapFormat == BMF_1BPP);
> +        ASSERT(pdev, mask->iType == STYPE_BITMAP);
> +
>           line_size = ALIGN(mask->sizlBitmap.cx, 8)>>  3;
>           info.cursor->data_size += line_size * surf->sizlBitmap.cy;
>           src = mask->pvScan0;
> diff --git a/display/rop.c b/display/rop.c
> index 57a92ab..59b63d5 100644
> --- a/display/rop.c
> +++ b/display/rop.c
> @@ -995,7 +995,7 @@ error:
>
>   }
>
> -static BOOL BitBltFromDev(PDev *pdev, SURFOBJ *src, SURFOBJ *dest, SURFOBJ *mask, CLIPOBJ *clip,
> +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)
>   {
> diff --git a/display/rop.h b/display/rop.h
> index 7519e63..5b3f241 100644
> --- a/display/rop.h
> +++ b/display/rop.h
> @@ -32,4 +32,7 @@ typedef struct ROP3Info {
>
>   extern ROP3Info rops2[];
>
> +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);
>   #endif



More information about the Spice-devel mailing list