qxl: properly handle upright and non-shared surfaces

Although qxl creates a shared displaysurface when the qxl surface is
upright and doesn't need to be flipped there is no guarantee that the
surface doesn't become unshared for some reason.  Rename qxl_flip to
qxl_blit and fix it to handle both flip and non-flip cases.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Gerd Hoffmann 2012-02-27 11:05:09 +01:00
parent 35c6332914
commit e2efc0a326

View file

@ -21,25 +21,31 @@
#include "qxl.h" #include "qxl.h"
static void qxl_flip(PCIQXLDevice *qxl, QXLRect *rect) static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
{ {
uint8_t *src; uint8_t *src;
uint8_t *dst = qxl->vga.ds->surface->data; uint8_t *dst = qxl->vga.ds->surface->data;
int len, i; int len, i;
if (qxl->guest_primary.qxl_stride > 0) { if (is_buffer_shared(qxl->vga.ds->surface)) {
return; return;
} }
if (!qxl->guest_primary.data) { if (!qxl->guest_primary.data) {
dprint(qxl, 1, "%s: initializing guest_primary.data\n", __func__); dprint(qxl, 1, "%s: initializing guest_primary.data\n", __func__);
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram); qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
} }
dprint(qxl, 1, "%s: stride %d, [%d, %d, %d, %d]\n", __func__, dprint(qxl, 2, "%s: stride %d, [%d, %d, %d, %d]\n", __func__,
qxl->guest_primary.qxl_stride, qxl->guest_primary.qxl_stride,
rect->left, rect->right, rect->top, rect->bottom); rect->left, rect->right, rect->top, rect->bottom);
src = qxl->guest_primary.data; src = qxl->guest_primary.data;
if (qxl->guest_primary.qxl_stride < 0) {
/* qxl surface is upside down, walk src scanlines
* in reverse order to flip it */
src += (qxl->guest_primary.surface.height - rect->top - 1) * src += (qxl->guest_primary.surface.height - rect->top - 1) *
qxl->guest_primary.abs_stride; qxl->guest_primary.abs_stride;
} else {
src += rect->top * qxl->guest_primary.abs_stride;
}
dst += rect->top * qxl->guest_primary.abs_stride; dst += rect->top * qxl->guest_primary.abs_stride;
src += rect->left * qxl->guest_primary.bytes_pp; src += rect->left * qxl->guest_primary.bytes_pp;
dst += rect->left * qxl->guest_primary.bytes_pp; dst += rect->left * qxl->guest_primary.bytes_pp;
@ -48,7 +54,7 @@ static void qxl_flip(PCIQXLDevice *qxl, QXLRect *rect)
for (i = rect->top; i < rect->bottom; i++) { for (i = rect->top; i < rect->bottom; i++) {
memcpy(dst, src, len); memcpy(dst, src, len);
dst += qxl->guest_primary.abs_stride; dst += qxl->guest_primary.abs_stride;
src -= qxl->guest_primary.abs_stride; src += qxl->guest_primary.qxl_stride;
} }
} }
@ -132,7 +138,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
if (qemu_spice_rect_is_empty(qxl->dirty+i)) { if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
break; break;
} }
qxl_flip(qxl, qxl->dirty+i); qxl_blit(qxl, qxl->dirty+i);
dpy_update(vga->ds, dpy_update(vga->ds,
qxl->dirty[i].left, qxl->dirty[i].top, qxl->dirty[i].left, qxl->dirty[i].top,
qxl->dirty[i].right - qxl->dirty[i].left, qxl->dirty[i].right - qxl->dirty[i].left,