commit 04fa562ea8f40290d67bf98fd85af9d246bb91ad
Author: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Date: Tue May 19 15:36:46 2009 +0100
qemu xen upstream synch (Gerd): [PATCH 1/7] xenfb update.
[This is] a series of patches for qemu-xen, making the code identical
to the xen support patches being submitted to upstream qemu. The review
process on qemu-devel resulted in a number of fixes and cleanups in the
backend code, this is where most of the changes come from.
There are also some xenfb changes due to displaystate reorganization and
xenfb being merged in steps due to that.
Signed-off-by: Gerd Hoffmann <kraxel@xxxxxxxxxx>
---
hw/xen_backend.h | 2 +-
hw/xen_machine_pv.c | 2 +-
hw/xenfb.c | 195 ++++++++++++++++++++++++++++++---------------------
3 files changed, 116 insertions(+), 83 deletions(-)
diff --git a/hw/xen_backend.h b/hw/xen_backend.h
index 9aa8d13..8c93c9f 100644
--- a/hw/xen_backend.h
+++ b/hw/xen_backend.h
@@ -89,6 +89,6 @@ extern struct XenDevOps xen_console_ops; /*
xen_console.c */
extern struct XenDevOps xen_kbdmouse_ops; /* xen_framebuffer.c */
extern struct XenDevOps xen_framebuffer_ops; /* xen_framebuffer.c */
-void xen_set_display(int domid);
+void xen_init_display(int domid);
#endif /* QEMU_HW_XEN_BACKEND_H */
diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c
index 6bfafbb..5536842 100644
--- a/hw/xen_machine_pv.c
+++ b/hw/xen_machine_pv.c
@@ -71,7 +71,7 @@ static void xen_init_pv(ram_addr_t ram_size, int vga_ram_size,
xen_be_register("vfb", &xen_framebuffer_ops);
/* setup framebuffer */
- xen_set_display(xen_domid);
+ xen_init_display(xen_domid);
}
QEMUMachine xenpv_machine = {
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 4b71bf2..135764d 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -86,6 +86,8 @@ struct XenFB {
int feature_update;
int refresh_period;
int bug_trigger;
+ int have_console;
+ int do_resize;
struct {
int x,y,w,h;
@@ -129,10 +131,11 @@ static void common_unbind(struct common *c)
/* -------------------------------------------------------------------- */
+#ifdef CONFIG_STUBDOM
/*
- * These two tables are not needed any more here, but left in here
- * intentionally as documentation, to show how scancode2linux[] was
- * generated, and also because xenfbfront needs them.
+ * These two tables are not needed any more, but left in here
+ * intentionally as documentation, to show how scancode2linux[]
+ * was generated.
*
* Tables to map from scancode to Linux input layer keycode.
* Scancodes are hardware-specific. These maps assumes a
@@ -172,6 +175,7 @@ const unsigned char atkbd_unxlate_table[128] = {
19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
};
+#endif
/*
* for (i = 0; i < 128; i++) {
@@ -320,12 +324,14 @@ static void xenfb_mouse_event(void *opaque,
int dx, int dy, int dz, int button_state)
{
struct XenInput *xenfb = opaque;
+ int dw = ds_get_width(xenfb->c.ds);
+ int dh = ds_get_height(xenfb->c.ds);
int i;
if (xenfb->abs_pointer_wanted)
xenfb_send_position(xenfb,
- dx * (ds_get_width(xenfb->c.ds) - 1) / 0x7fff,
- dy * (ds_get_height(xenfb->c.ds) - 1) / 0x7fff,
+ dx * (dw - 1) / 0x7fff,
+ dy * (dh - 1) / 0x7fff,
dz);
else
xenfb_send_motion(xenfb, dx, dy, dz);
@@ -346,6 +352,11 @@ static int input_init(struct XenDevice *xendev)
{
struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
+ if (!in->c.ds) {
+ xen_be_printf(xendev, 1, "ds not set (yet)\n");
+ return -1;
+ }
+
xenstore_write_be_int(xendev, "feature-abs-pointer", 1);
return 0;
}
@@ -547,6 +558,8 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t
fb_len_lim,
xenfb->width = width;
xenfb->height = height;
xenfb->offset = offset;
+ xenfb->up_fullscreen = 1;
+ xenfb->do_resize = 1;
xen_be_printf(&xenfb->c.xendev, 1, "framebuffer %dx%dx%d offset %d stride
%d\n",
width, height, depth, offset, row_stride);
return 0;
@@ -559,9 +572,9 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t
fb_len_lim,
+ xenfb->offset \
+ (line * xenfb->row_stride) \
+ (x * xenfb->depth / 8)); \
- DST_T *dst = (DST_T *)(ds_get_data(xenfb->c.ds)
\
- + (line * ds_get_linesize(xenfb->c.ds))
\
- + (x * ds_get_bytes_per_pixel(xenfb->c.ds)));
\
+ DST_T *dst = (DST_T *)(data \
+ + (line * linesize) \
+ + (x * bpp / 8)); \
int col; \
const int RSS = 32 - (RSB + GSB + BSB); \
const int GSS = 32 - (GSB + BSB); \
@@ -581,55 +594,52 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t
fb_len_lim,
(((spix << GSS) & GSM & GDM) >> GDS) | \
(((spix << BSS) & BSM & BDM) >> BDS); \
src = (SRC_T *) ((unsigned long) src + xenfb->depth / 8); \
- dst = (DST_T *) ((unsigned long) dst +
ds_get_bytes_per_pixel(xenfb->c.ds)); \
+ dst = (DST_T *) ((unsigned long) dst + bpp / 8); \
} \
}
-/* This copies data from the guest framebuffer region, into QEMU's copy
- * NB. QEMU's copy is stored in the pixel format of a) the local X
- * server (SDL case) or b) the current VNC client pixel format.
- * When shifting between colour depths we preserve the MSB.
+/*
+ * This copies data from the guest framebuffer region, into QEMU's
+ * displaysurface. qemu uses 16 or 32 bpp. In case the pv framebuffer
+ * uses something else we must convert and copy, otherwise we can
+ * supply the buffer directly and no thing here.
*/
static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
{
- int line;
+ int line, oops = 0;
+ int bpp = ds_get_bits_per_pixel(xenfb->c.ds);
+ int linesize = ds_get_linesize(xenfb->c.ds);
+ uint8_t *data = ds_get_data(xenfb->c.ds);
if (!is_buffer_shared(xenfb->c.ds->surface)) {
- if (xenfb->depth == ds_get_bits_per_pixel(xenfb->c.ds)) { /* Perfect
match can use fast path */
- for (line = y ; line < (y+h) ; line++) {
- memcpy(ds_get_data(xenfb->c.ds) + (line *
ds_get_linesize(xenfb->c.ds)) + (x * ds_get_bytes_per_pixel(xenfb->c.ds)),
- xenfb->pixels + xenfb->offset + (line *
xenfb->row_stride) + (x * xenfb->depth / 8),
- w * xenfb->depth / 8);
- }
- } else { /* Mismatch requires slow pixel munging */
- /* 8 bit == r:3 g:3 b:2 */
- /* 16 bit == r:5 g:6 b:5 */
- /* 24 bit == r:8 g:8 b:8 */
- /* 32 bit == r:8 g:8 b:8 (padding:8) */
- if (xenfb->depth == 8) {
- if (ds_get_bits_per_pixel(xenfb->c.ds) == 16) {
- BLT(uint8_t, uint16_t, 3, 3, 2, 5, 6, 5);
- } else if (ds_get_bits_per_pixel(xenfb->c.ds) == 32) {
- BLT(uint8_t, uint32_t, 3, 3, 2, 8, 8, 8);
- }
- } else if (xenfb->depth == 16) {
- if (ds_get_bits_per_pixel(xenfb->c.ds) == 8) {
- BLT(uint16_t, uint8_t, 5, 6, 5, 3, 3, 2);
- } else if (ds_get_bits_per_pixel(xenfb->c.ds) == 32) {
- BLT(uint16_t, uint32_t, 5, 6, 5, 8, 8, 8);
- }
- } else if (xenfb->depth == 24 || xenfb->depth == 32) {
- if (ds_get_bits_per_pixel(xenfb->c.ds) == 8) {
- BLT(uint32_t, uint8_t, 8, 8, 8, 3, 3, 2);
- } else if (ds_get_bits_per_pixel(xenfb->c.ds) == 16) {
- BLT(uint32_t, uint16_t, 8, 8, 8, 5, 6, 5);
- } else if (ds_get_bits_per_pixel(xenfb->c.ds) == 32) {
- BLT(uint32_t, uint32_t, 8, 8, 8, 8, 8, 8);
- }
- }
+ switch (xenfb->depth) {
+ case 8:
+ if (bpp == 16) {
+ BLT(uint8_t, uint16_t, 3, 3, 2, 5, 6, 5);
+ } else if (bpp == 32) {
+ BLT(uint8_t, uint32_t, 3, 3, 2, 8, 8, 8);
+ } else {
+ oops = 1;
+ }
+ break;
+ case 24:
+ if (bpp == 16) {
+ BLT(uint32_t, uint16_t, 8, 8, 8, 5, 6, 5);
+ } else if (bpp == 32) {
+ BLT(uint32_t, uint32_t, 8, 8, 8, 8, 8, 8);
+ } else {
+ oops = 1;
+ }
+ break;
+ default:
+ oops = 1;
}
}
+ if (oops) /* should not happen */
+ xen_be_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n",
+ __FUNCTION__, xenfb->depth, bpp);
+
dpy_update(xenfb->c.ds, x, y, w, h);
}
@@ -685,10 +695,12 @@ static void xenfb_send_refresh_period(struct XenFB
*xenfb, int period)
static void xenfb_update(void *opaque)
{
struct XenFB *xenfb = opaque;
- int i;
struct DisplayChangeListener *l;
+ int dw = ds_get_width(xenfb->c.ds);
+ int dh = ds_get_height(xenfb->c.ds);
+ int i;
- if (!xenfb->width || !xenfb->height)
+ if (xenfb->c.xendev.be_state != XenbusStateConnected)
return;
if (xenfb->feature_update) {
@@ -712,11 +724,12 @@ static void xenfb_update(void *opaque)
}
}
if (idle)
- period = XENFB_NO_REFRESH;
+ period = XENFB_NO_REFRESH;
if (xenfb->refresh_period != period) {
xenfb_send_refresh_period(xenfb, period);
xenfb->refresh_period = period;
+ xen_be_printf(&xenfb->c.xendev, 1, "refresh period: %d\n", period);
}
#else
; /* nothing */
@@ -728,11 +741,8 @@ static void xenfb_update(void *opaque)
}
/* resize if needed */
- if (xenfb->width != ds_get_width(xenfb->c.ds) ||
- xenfb->height != ds_get_height(xenfb->c.ds) ||
- xenfb->depth != ds_get_bits_per_pixel(xenfb->c.ds) ||
- xenfb->row_stride != ds_get_linesize(xenfb->c.ds) ||
- xenfb->pixels + xenfb->offset != ds_get_data(xenfb->c.ds)) {
+ if (xenfb->do_resize) {
+ xenfb->do_resize = 0;
switch (xenfb->depth) {
case 16:
case 32:
@@ -747,9 +757,10 @@ static void xenfb_update(void *opaque)
qemu_resize_displaysurface(xenfb->c.ds, xenfb->width,
xenfb->height);
break;
}
+ xen_be_printf(&xenfb->c.xendev, 1, "update: resizing: %dx%d @ %d
bpp%s\n",
+ xenfb->width, xenfb->height, xenfb->depth,
+ is_buffer_shared(xenfb->c.ds->surface) ? " (shared)" :
"");
dpy_resize(xenfb->c.ds);
- xen_be_printf(&xenfb->c.xendev, 1, "update: resizing: %dx%d\n",
- xenfb->width, xenfb->height);
xenfb->up_fullscreen = 1;
}
@@ -881,6 +892,17 @@ static int fb_connect(struct XenDevice *xendev)
if (0 != rc)
return rc;
+#if 0 /* handled in xen_init_display() for now */
+ if (!fb->have_console) {
+ fb->c.ds = graphic_console_init(xenfb_update,
+ xenfb_invalidate,
+ NULL,
+ NULL,
+ fb);
+ fb->have_console = 1;
+ }
+#endif
+
if (-1 == xenstore_read_fe_int(xendev, "feature-update",
&fb->feature_update))
fb->feature_update = 0;
if (fb->feature_update)
@@ -888,7 +910,6 @@ static int fb_connect(struct XenDevice *xendev)
xen_be_printf(xendev, 1, "feature-update=%d, videoram=%d\n",
fb->feature_update, videoram);
-
return 0;
}
@@ -954,31 +975,43 @@ struct XenDevOps xen_framebuffer_ops = {
.frontend_changed = fb_frontend_changed,
};
-static void xen_set_display_type(int domid, const char *type, DisplayState *ds)
+/*
+ * FIXME/TODO: Kill this.
+ * Temporary needed while DisplayState reorganization is in flight.
+ */
+void xen_init_display(int domid)
{
- struct XenDevice *xendev;
- struct common *c;
+ struct XenDevice *xfb, *xin;
+ struct XenFB *fb;
+ struct XenInput *in;
+ int i = 0;
+
+wait_more:
+ i++;
+ main_loop_wait(10); /* miliseconds */
+ xfb = xen_be_find_xendev("vfb", domid, 0);
+ xin = xen_be_find_xendev("vkbd", domid, 0);
+ if (!xfb || !xin) {
+ if (i < 256)
+ goto wait_more;
+ fprintf(stderr, "%s: displaystate setup failed\n", __FUNCTION__);
+ return;
+ }
- xendev = xen_be_find_xendev(type, domid, 0);
- if (!xendev)
- return;
- c = container_of(xendev, struct common, xendev);
- c->ds = ds;
- xen_be_printf(xendev, 1, "ds is %p\n", ds);
- /* retry ->init() */
- xen_be_check_state(xendev);
-}
+ /* vfb */
+ fb = container_of(xfb, struct XenFB, c.xendev);
+ fb->c.ds = graphic_console_init(xenfb_update,
+ xenfb_invalidate,
+ NULL,
+ NULL,
+ fb);
+ fb->have_console = 1;
-void xen_set_display(int domid)
-{
- struct XenDevice *xendev = xen_be_find_xendev("vfb", domid, 0);
- struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
- DisplayState *ds = graphic_console_init(xenfb_update,
- xenfb_invalidate,
- NULL,
- NULL,
- fb);
-
- xen_set_display_type(domid, "vkbd", ds);
- xen_set_display_type(domid, "vfb", ds);
+ /* vkbd */
+ in = container_of(xin, struct XenInput, c.xendev);
+ in->c.ds = fb->c.ds;
+
+ /* retry ->init() */
+ xen_be_check_state(xin);
+ xen_be_check_state(xfb);
}
--
generated by git-patchbot for /home/xen/git/qemu-xen-unstable.git
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|