[Spice-devel] [spice-protocol PATCH 21/46] qxlhw: add qxlhw_pci_image_alloc (moved from qxl_image)

Alon Levy alevy at redhat.com
Tue Apr 10 04:50:17 PDT 2012


---
 src/qxl.h       |    7 +++
 src/qxl_image.c |  101 +----------------------------------------
 src/qxlhw.c     |   13 ++++++
 src/qxlhw.h     |   10 +++++
 src/qxlhw_pci.c |  134 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 166 insertions(+), 99 deletions(-)

diff --git a/src/qxl.h b/src/qxl.h
index 03aed28..ef51469 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -350,6 +350,13 @@ static inline void set_surface (PixmapPtr pixmap, qxl_surface_t *surface)
 /*
  * Images
  */
+
+unsigned int
+hash_and_copy (const uint8_t *src, int src_stride,
+	       uint8_t *dest, int dest_stride,
+	       int bytes_per_pixel, int width, int height,
+	       uint32_t hash);
+
 struct QXLImage *qxl_image_create     (qxl_screen_t           *qxl,
 				       const uint8_t          *data,
 				       int                     x,
diff --git a/src/qxl_image.c b/src/qxl_image.c
index 8cd6e49..1f057f7 100644
--- a/src/qxl_image.c
+++ b/src/qxl_image.c
@@ -33,6 +33,7 @@
 #include <assert.h>
 #include <stdlib.h>
 #include "qxl.h"
+#include "qxlhw.h"
 #include "qxl_mem.h"
 #include "murmurhash3.h"
 
@@ -48,7 +49,7 @@ struct image_info_t
 #define HASH_SIZE 4096
 static image_info_t *image_table[HASH_SIZE];
 
-static unsigned int
+unsigned int
 hash_and_copy (const uint8_t *src, int src_stride,
 	       uint8_t *dest, int dest_stride,
 	       int bytes_per_pixel, int width, int height,
@@ -127,104 +128,6 @@ remove_image_info (image_info_t *info)
     free (info);
 }
 
-#define MAX(a,b)  (((a) > (b))? (a) : (b))
-#define MIN(a,b)  (((a) < (b))? (a) : (b))
-
-static struct QXLImage *
-qxlhw_image_alloc(struct qxlhw *base, const uint8_t *data,
-		  int x, int y, int width, int height,
-		  int stride, int Bpp, uint32_t *hash)
-{
-    struct QXLImage *image;
-    struct qxlhw_mem image_mem;
-    struct QXLDataChunk *head;
-    struct QXLDataChunk *tail;
-    int dest_stride = width * Bpp;
-    int h;
-
-    data += y * stride + x * Bpp;
-
-    /* Chunk */
-
-    /* FIXME: Check integer overflow */
-
-    head = tail = NULL;
-
-    *hash = 0;
-    h = height;
-    while (h)
-    {
-        int chunk_size = MAX (512 * 512, dest_stride);
-        int n_lines = MIN ((chunk_size / dest_stride), h);
-        QXLDataChunk *chunk;
-        struct qxlhw_mem chunk_mem =
-            qxlhw_data_alloc (base, sizeof *chunk + n_lines * dest_stride);
-
-        chunk = chunk_mem.addr;
-        chunk->data_size = n_lines * dest_stride;
-        *hash = hash_and_copy (data, stride,
-                               chunk->data, dest_stride,
-                               Bpp, width, n_lines, *hash);
-
-        if (tail)
-        {
-            tail->next_chunk = physical_address(base->qxl, chunk, base->qxl->main_mem_slot);
-            chunk->prev_chunk = physical_address(base->qxl, tail, base->qxl->main_mem_slot);
-            chunk->next_chunk = 0;
-
-            tail = chunk;
-        }
-        else
-        {
-            head = tail = chunk;
-            chunk->next_chunk = 0;
-            chunk->prev_chunk = 0;
-        }
-
-        data += n_lines * stride;
-        h -= n_lines;
-    }
-
-    /* Image */
-    image_mem = qxlhw_data_alloc (base, sizeof *image);
-    image = image_mem.addr;
-
-    image->descriptor.id = 0;
-    image->descriptor.type = SPICE_IMAGE_TYPE_BITMAP;
-
-    image->descriptor.flags = 0;
-    image->descriptor.width = width;
-    image->descriptor.height = height;
-    if (Bpp == 2)
-    {
-        image->bitmap.format = SPICE_BITMAP_FMT_16BIT;
-    }
-    else if (Bpp == 1)
-    {
-        image->bitmap.format = SPICE_BITMAP_FMT_8BIT;
-    }
-    else if (Bpp == 4)
-    {
-        image->bitmap.format = SPICE_BITMAP_FMT_32BIT;
-    }
-    else
-    {
-        abort();
-    }
-
-    image->bitmap.flags = SPICE_BITMAP_FLAGS_TOP_DOWN;
-    image->bitmap.x = width;
-    image->bitmap.y = height;
-    image->bitmap.stride = width * Bpp;
-    image->bitmap.palette = 0;
-    image->bitmap.data = physical_address (base->qxl, head, base->qxl->main_mem_slot);
-
-#if 0
-    ErrorF ("%p has size %d %d\n", image, width, height);
-#endif
-    return image;
-}
-
 struct QXLImage *
 qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
 		  int x, int y, int width, int height,
diff --git a/src/qxlhw.c b/src/qxlhw.c
index ee25dac..b099a25 100644
--- a/src/qxlhw.c
+++ b/src/qxlhw.c
@@ -89,9 +89,22 @@ void qxlhw_push_cursor(struct qxlhw *base, struct QXLCursorCmd *base_cmd)
         base->push_cursor(base, base_cmd);
 }
 
+void qxlhw_push_drawable(struct qxlhw *base, struct QXLDrawable *base_cmd, QXLImage *image)
+{
+    base->push_drawable(base, base_cmd, image);
+}
+
 /* tried to avoid this. but qxl_surface.c wants to check when failing to find
  * a surface in the free list, which it populates using qxl_surface_alloc (should) */
 Bool qxlhw_handle_oom(struct qxlhw *base)
 {
         return base->handle_oom(base);
 }
+
+struct QXLImage *
+qxlhw_image_alloc(struct qxlhw *base, const uint8_t *data,
+		  int x, int y, int width, int height,
+		  int stride, int Bpp, uint32_t *hash)
+{
+    return base->image_alloc(base, data, x, y, width, height, stride, Bpp, hash);
+}
diff --git a/src/qxlhw.h b/src/qxlhw.h
index 3b950e4..f012aa2 100644
--- a/src/qxlhw.h
+++ b/src/qxlhw.h
@@ -26,6 +26,10 @@ struct qxlhw {
     void (*push_surface_cmd)(struct qxlhw *base, QXLSurfaceCmd* base_cmd);
     void (*update_area)(struct qxlhw *base, int surface_id, struct QXLRect rect);
     void (*push_cursor)(struct qxlhw *base, struct QXLCursorCmd *base_cmd);
+    struct QXLImage * (*image_alloc)(struct qxlhw *base, const uint8_t *data,
+                                     int x, int y, int width, int height,
+                                     int stride, int Bpp, uint32_t *hash);
+    void (*push_drawable)(struct qxlhw *base, struct QXLDrawable *base_cmd, struct QXLImage *image);
     /* tried to avoid this. but qxl_surface.c wants to check when failing to
      * find a surface in the free list, which it populates using
      * qxl_surface_alloc (should) */
@@ -75,6 +79,12 @@ void qxlhw_create_primary_surface(struct qxlhw *base, QXLSurfaceCreate *create);
  * and not visible in qxl_surface.c */
 void qxlhw_push_surface_cmd(struct qxlhw *base, QXLSurfaceCmd *base_cmd);
 
+struct QXLImage *qxlhw_image_alloc(struct qxlhw *base, const uint8_t *data,
+                                   int x, int y, int width, int height,
+                                   int stride, int Bpp, uint32_t *hash);
+
+void qxlhw_push_drawable(struct qxlhw *base, QXLDrawable *base_cmd, QXLImage *image);
+
 /* cursor */
 void qxlhw_push_cursor(struct qxlhw *base, QXLCursorCmd *base_cmd);
 
diff --git a/src/qxlhw_pci.c b/src/qxlhw_pci.c
index b3fae49..6950093 100644
--- a/src/qxlhw_pci.c
+++ b/src/qxlhw_pci.c
@@ -674,6 +674,38 @@ qxlhw_pci_push_surface_cmd (struct qxlhw *base, struct QXLSurfaceCmd *base_cmd)
     qxl_ring_push (hw->command_ring, &command);
 }
 
+static struct QXLDrawable *
+qxlhw_make_drawable (struct qxlhw_pci *hw, QXLDrawable *base, QXLImage *image)
+{
+    struct QXLDrawable *drawable;
+
+    drawable = qxlhw_pci_allocnf (hw, hw->mem, sizeof *drawable);
+    memcpy(drawable, base, sizeof(*drawable));
+
+    drawable->release_info.id = pointer_to_u64 (drawable);
+
+    switch (drawable->type) {
+    case QXL_DRAW_COPY:
+        drawable->u.copy.src_bitmap =
+            qxlhw_physical_address (hw, image, hw->main_mem_slot);
+        break;
+    }
+    return drawable;
+}
+
+static void
+qxlhw_pci_push_drawable (struct qxlhw *base, struct QXLDrawable *base_cmd, struct QXLImage *image)
+{
+    struct qxlhw_pci *hw = (struct qxlhw_pci *)base;
+    struct QXLCommand cmd;
+    struct QXLDrawable *drawable = qxlhw_make_drawable(hw, base_cmd, image);
+
+    cmd.type = QXL_CMD_DRAW;
+    cmd.data = qxlhw_physical_address (hw, drawable, hw->main_mem_slot);
+
+    qxl_ring_push (hw->command_ring, &cmd);
+}
+
 static void qxlhw_pci_update_area(struct qxlhw *base, int surface_id, struct QXLRect rect)
 {
     struct qxlhw_pci *hw = (struct qxlhw_pci *)base;
@@ -727,6 +759,106 @@ static void qxlhw_pci_push_cursor(struct qxlhw *base, QXLCursorCmd *base_cmd)
     qxl_ring_push (hw->cursor_ring, &cmd);
 }
 
+#define MAX(a,b)  (((a) > (b))? (a) : (b))
+#define MIN(a,b)  (((a) < (b))? (a) : (b))
+
+static struct QXLImage *
+qxlhw_pci_image_alloc(struct qxlhw *base, const uint8_t *data,
+		  int x, int y, int width, int height,
+		  int stride, int Bpp, uint32_t *hash)
+{
+    struct qxlhw_pci *hw = (struct qxlhw_pci *)base;
+    struct QXLImage *image;
+    struct qxlhw_mem image_mem;
+    struct QXLDataChunk *head;
+    struct QXLDataChunk *tail;
+    int dest_stride = width * Bpp;
+    int h;
+
+    data += y * stride + x * Bpp;
+
+    /* Chunk */
+
+    /* FIXME: Check integer overflow */
+
+    head = tail = NULL;
+
+    *hash = 0;
+    h = height;
+    while (h)
+    {
+        int chunk_size = MAX (512 * 512, dest_stride);
+        int n_lines = MIN ((chunk_size / dest_stride), h);
+        QXLDataChunk *chunk;
+        struct qxlhw_mem chunk_mem =
+            qxlhw_data_alloc (base, sizeof *chunk + n_lines * dest_stride);
+
+        chunk = chunk_mem.addr;
+        chunk->data_size = n_lines * dest_stride;
+        *hash = hash_and_copy (data, stride,
+                               chunk->data, dest_stride,
+                               Bpp, width, n_lines, *hash);
+
+        if (tail)
+        {
+            tail->next_chunk = qxlhw_physical_address(hw, chunk, hw->main_mem_slot);
+            chunk->prev_chunk = qxlhw_physical_address(hw, tail, hw->main_mem_slot);
+            chunk->next_chunk = 0;
+
+            tail = chunk;
+        }
+        else
+        {
+            head = tail = chunk;
+            chunk->next_chunk = 0;
+            chunk->prev_chunk = 0;
+        }
+
+        data += n_lines * stride;
+        h -= n_lines;
+    }
+
+    /* Image */
+    image_mem = qxlhw_data_alloc (base, sizeof *image);
+    image = image_mem.addr;
+
+    image->descriptor.id = 0;
+    image->descriptor.type = SPICE_IMAGE_TYPE_BITMAP;
+
+    image->descriptor.flags = 0;
+    image->descriptor.width = width;
+    image->descriptor.height = height;
+    if (Bpp == 2)
+    {
+        image->bitmap.format = SPICE_BITMAP_FMT_16BIT;
+    }
+    else if (Bpp == 1)
+    {
+        image->bitmap.format = SPICE_BITMAP_FMT_8BIT;
+    }
+    else if (Bpp == 4)
+    {
+        image->bitmap.format = SPICE_BITMAP_FMT_32BIT;
+    }
+    else
+    {
+        abort();
+    }
+
+    image->bitmap.flags = SPICE_BITMAP_FLAGS_TOP_DOWN;
+    image->bitmap.x = width;
+    image->bitmap.y = height;
+    image->bitmap.stride = width * Bpp;
+    image->bitmap.palette = 0;
+    image->bitmap.data = qxlhw_physical_address (hw, head, hw->main_mem_slot);
+
+#if 0
+    ErrorF ("%p has size %d %d\n", image, width, height);
+#endif
+    return image;
+}
+
+
 /* public entry point */
 struct qxlhw *create_qxlhw_pci(qxl_screen_t *qxl, ScrnInfoPtr pScrn)
 {
@@ -748,6 +880,8 @@ struct qxlhw *create_qxlhw_pci(qxl_screen_t *qxl, ScrnInfoPtr pScrn)
     base->push_surface_cmd = qxlhw_pci_push_surface_cmd;
     base->update_area = qxlhw_pci_update_area;
     base->push_cursor = qxlhw_pci_push_cursor;
+    base->image_alloc = qxlhw_pci_image_alloc;
+    base->push_drawable = qxlhw_pci_push_drawable;
     return base;
 }
 
-- 
1.7.9.3



More information about the Spice-devel mailing list