From 2b716911c122299046960302293fcb2b46aaaf3f Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy@redhat.com>
Date: Sun, 18 Mar 2012 12:17:52 +0100
Subject: [PATCH 9/9] qxl: properly handle upright and non-shared surfaces

RH-Author: Alon Levy <alevy@redhat.com>
Message-id: <1332073072-27934-9-git-send-email-alevy@redhat.com>
Patchwork-id: 38606
O-Subject: [PATCHv2 RHEL-6.3 qemu-kvm 8/8] qxl: properly handle upright and non-shared surfaces
Bugzilla: 747011
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
RH-Acked-by: Hans de Goede <hdegoede@redhat.com>
RH-Acked-by: Yonit Halperin <yhalperi@redhat.com>

From: Gerd Hoffmann <kraxel@redhat.com>

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>
(cherry picked from commit e2efc0a3267811a2b9459116b2310325ef011f6e)
---
 hw/qxl-render.c |   20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 hw/qxl-render.c |   20 +++++++++++++-------
 1 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index db410a1..bb5f1db 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -21,25 +21,31 @@
 
 #include "qxl.h"
 
-static void qxl_flip(PCIQXLDevice *qxl, QXLRect *rect)
+static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
 {
     uint8_t *src;
     uint8_t *dst = qxl->vga.ds->surface->data;
     int len, i;
 
-    if (qxl->guest_primary.qxl_stride > 0) {
+    if (is_buffer_shared(qxl->vga.ds->surface)) {
         return;
     }
     if (!qxl->guest_primary.data) {
         dprint(qxl, 1, "%s: initializing guest_primary.data\n", __func__);
         qxl->guest_primary.data = qemu_get_ram_ptr(qxl->vga.vram_offset);
     }
-    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,
             rect->left, rect->right, rect->top, rect->bottom);
     src = qxl->guest_primary.data;
-    src += (qxl->guest_primary.surface.height - rect->top - 1) *
-        qxl->guest_primary.abs_stride;
+    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) *
+            qxl->guest_primary.abs_stride;
+    } else {
+        src += rect->top * qxl->guest_primary.abs_stride;
+    }
     dst += rect->top  * qxl->guest_primary.abs_stride;
     src += 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++) {
         memcpy(dst, src, len);
         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)) {
             break;
         }
-        qxl_flip(qxl, qxl->dirty+i);
+        qxl_blit(qxl, qxl->dirty+i);
         dpy_update(vga->ds,
                    qxl->dirty[i].left, qxl->dirty[i].top,
                    qxl->dirty[i].right - qxl->dirty[i].left,
-- 
1.7.7.6

