[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