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

_______________________________________________
Spice-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/spice-devel

Reply via email to