From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45181) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XOj1M-0005hU-Jn for qemu-devel@nongnu.org; Tue, 02 Sep 2014 04:01:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XOj1F-0004hB-CW for qemu-devel@nongnu.org; Tue, 02 Sep 2014 04:00:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:7649) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XOj1F-0004gi-5M for qemu-devel@nongnu.org; Tue, 02 Sep 2014 04:00:49 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8280l0V018978 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 2 Sep 2014 04:00:48 -0400 From: Gerd Hoffmann Date: Tue, 2 Sep 2014 10:00:25 +0200 Message-Id: <1409644827-26317-13-git-send-email-kraxel@redhat.com> In-Reply-To: <1409644827-26317-1-git-send-email-kraxel@redhat.com> References: <1409644827-26317-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 12/14] [wip] pl110: start using pixman List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann Turn pl110_draw_fn into a struct, carrying both conversion function and pixman format for a given guest framebuffer layout. Create a DisplaySurface backed by guest memory in case pixman can handle the format, thereby collecting the low-hanging fruits. A common case (linux kernel running pl111 with 16bpp, little endian host) runs powered by pixman now. Lot of work left to be able to kill the template stuff completely though. Debug printf left in for now to see what formts the guest is using. Signed-off-by: Gerd Hoffmann --- hw/display/pl110.c | 67 +++++++++++++++----------- hw/display/pl110_template.h | 111 ++++++++++++++++++++++++-------------------- 2 files changed, 101 insertions(+), 77 deletions(-) diff --git a/hw/display/pl110.c b/hw/display/pl110.c index f788382..0dbc526 100644 --- a/hw/display/pl110.c +++ b/hw/display/pl110.c @@ -170,12 +170,13 @@ static void pl110_update_display(void *opaque) } } - if (s->cr & PL110_CR_BEBO) - fn = pl110_draw_fn[s->bpp + 8 + bpp_offset]; - else if (s->cr & PL110_CR_BEPO) - fn = pl110_draw_fn[s->bpp + 16 + bpp_offset]; - else - fn = pl110_draw_fn[s->bpp + bpp_offset]; + if (s->cr & PL110_CR_BEBO) { + bpp_offset += 8 + s->bpp; + } else if (s->cr & PL110_CR_BEPO) { + bpp_offset += 16 + s->bpp; + } else { + bpp_offset += s->bpp; + } src_width = s->cols; switch (s->bpp) { @@ -201,23 +202,39 @@ static void pl110_update_display(void *opaque) } /* handle resize */ - if (surface_width(surface) != s->cols || + if (s->invalidate || + surface_width(surface) != s->cols || surface_height(surface) != s->rows) { - qemu_console_resize(s->con, s->cols, s->rows); - surface = qemu_console_surface(s->con); + if (pl110_draw[bpp_offset].fmt) { + surface = qemu_create_displaysurface_guestmem + (s->cols, s->rows, pl110_draw[bpp_offset].fmt, 0, s->upbase); + dpy_gfx_replace_surface(s->con, surface); + } else { + qemu_console_resize(s->con, s->cols, s->rows); + surface = qemu_console_surface(s->con); + } + fprintf(stderr, "%s: %s memory, %dx%d, bpp_offset %d, format 0x%x\n", + __func__, is_buffer_shared(surface) ? "guest" : "host", + s->cols, s->rows, bpp_offset, surface->format); } - g_assert(surface_bits_per_pixel(surface) == 32); - dest_width = 4 * s->cols; - first = 0; - framebuffer_update_display(surface, sysbus_address_space(sbd), - s->upbase, s->cols, s->rows, - src_width, dest_width, 0, - s->invalidate, - fn, s->palette, - &first, &last); - if (first >= 0) { - dpy_gfx_update(s->con, 0, first, s->cols, last - first + 1); + if (is_buffer_shared(surface)) { + dpy_gfx_update_dirty(s->con, sysbus_address_space(sbd), + s->upbase, s->invalidate); + } else { + g_assert(surface_bits_per_pixel(surface) == 32); + dest_width = 4 * s->cols; + first = 0; + fn = pl110_draw[bpp_offset].fn; + framebuffer_update_display(surface, sysbus_address_space(sbd), + s->upbase, s->cols, s->rows, + src_width, dest_width, 0, + s->invalidate, + fn, s->palette, + &first, &last); + if (first >= 0) { + dpy_gfx_update(s->con, 0, first, s->cols, last - first + 1); + } } s->invalidate = 0; } @@ -235,6 +252,8 @@ static void pl110_update_palette(PL110State *s, int n) uint32_t raw; unsigned int r, g, b; + g_assert(is_buffer_shared(surface) || + surface_bits_per_pixel(surface) == 32); raw = s->raw_palette[n]; n <<= 1; for (i = 0; i < 2; i++) { @@ -245,13 +264,7 @@ static void pl110_update_palette(PL110State *s, int n) b = (raw & 0x1f) << 3; /* The I bit is ignored. */ raw >>= 6; - switch (surface_bits_per_pixel(surface)) { - case 32: - s->palette[n] = rgb_to_pixel32(r, g, b); - break; - default: - g_assert_not_reached(); - } + s->palette[n] = rgb_to_pixel32(r, g, b); n++; } } diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h index 5afc64c..1eee28d 100644 --- a/hw/display/pl110_template.h +++ b/hw/display/pl110_template.h @@ -32,61 +32,72 @@ #include "pl110_template.h" #undef BORDER -static drawfn pl110_draw_fn[48] = -{ - pl110_draw_line1_lblp_bgr, - pl110_draw_line2_lblp_bgr, - pl110_draw_line4_lblp_bgr, - pl110_draw_line8_lblp_bgr, - pl110_draw_line16_555_lblp_bgr, - pl110_draw_line32_lblp_bgr, - pl110_draw_line16_lblp_bgr, - pl110_draw_line12_lblp_bgr, +#ifdef HOST_WORDS_BIGENDIAN +# define LEBE(le, be) (be) +#else +# define LEBE(le, be) (le) +#endif + +static struct { + drawfn fn; + pixman_format_code_t fmt; +} pl110_draw[48] = { + { .fn = pl110_draw_line1_lblp_bgr }, + { .fn = pl110_draw_line2_lblp_bgr }, + { .fn = pl110_draw_line4_lblp_bgr }, + { .fn = pl110_draw_line8_lblp_bgr }, + { .fn = pl110_draw_line16_555_lblp_bgr, .fmt = LEBE(PIXMAN_x1r5g5b5, 0) }, + { .fn = pl110_draw_line32_lblp_bgr, .fmt = LEBE(PIXMAN_x8r8g8b8, + PIXMAN_b8g8r8a8) }, + { .fn = pl110_draw_line16_lblp_bgr, .fmt = LEBE(PIXMAN_r5g6b5, 0) }, + { .fn = pl110_draw_line12_lblp_bgr, .fmt = LEBE(PIXMAN_x4r4g4b4, 0) }, - pl110_draw_line1_bbbp_bgr, - pl110_draw_line2_bbbp_bgr, - pl110_draw_line4_bbbp_bgr, - pl110_draw_line8_bbbp_bgr, - pl110_draw_line16_555_bbbp_bgr, - pl110_draw_line32_bbbp_bgr, - pl110_draw_line16_bbbp_bgr, - pl110_draw_line12_bbbp_bgr, + { .fn = pl110_draw_line1_bbbp_bgr }, + { .fn = pl110_draw_line2_bbbp_bgr }, + { .fn = pl110_draw_line4_bbbp_bgr }, + { .fn = pl110_draw_line8_bbbp_bgr }, + { .fn = pl110_draw_line16_555_bbbp_bgr }, + { .fn = pl110_draw_line32_bbbp_bgr, .fmt = LEBE(PIXMAN_b8g8r8a8, + PIXMAN_x8r8g8b8) }, + { .fn = pl110_draw_line16_bbbp_bgr }, + { .fn = pl110_draw_line12_bbbp_bgr }, - pl110_draw_line1_lbbp_bgr, - pl110_draw_line2_lbbp_bgr, - pl110_draw_line4_lbbp_bgr, - pl110_draw_line8_lbbp_bgr, - pl110_draw_line16_555_lbbp_bgr, - pl110_draw_line32_lbbp_bgr, - pl110_draw_line16_lbbp_bgr, - pl110_draw_line12_lbbp_bgr, + { .fn = pl110_draw_line1_lbbp_bgr }, + { .fn = pl110_draw_line2_lbbp_bgr }, + { .fn = pl110_draw_line4_lbbp_bgr }, + { .fn = pl110_draw_line8_lbbp_bgr }, + { .fn = pl110_draw_line16_555_lbbp_bgr, .fmt = LEBE(PIXMAN_x1r5g5b5, 0) }, + { .fn = pl110_draw_line32_lbbp_bgr, .fmt = LEBE(PIXMAN_x8r8g8b8, + PIXMAN_b8g8r8a8) }, + { .fn = pl110_draw_line16_lbbp_bgr, .fmt = LEBE(PIXMAN_r5g6b5, 0) }, + { .fn = pl110_draw_line12_lbbp_bgr, .fmt = LEBE(PIXMAN_x4r4g4b4, 0) }, - pl110_draw_line1_lblp_rgb, - pl110_draw_line2_lblp_rgb, - pl110_draw_line4_lblp_rgb, - pl110_draw_line8_lblp_rgb, - pl110_draw_line16_555_lblp_rgb, - pl110_draw_line32_lblp_rgb, - pl110_draw_line16_lblp_rgb, - pl110_draw_line12_lblp_rgb, + { .fn = pl110_draw_line1_lblp_rgb }, + { .fn = pl110_draw_line2_lblp_rgb }, + { .fn = pl110_draw_line4_lblp_rgb }, + { .fn = pl110_draw_line8_lblp_rgb }, + { .fn = pl110_draw_line16_555_lblp_rgb }, + { .fn = pl110_draw_line32_lblp_rgb }, + { .fn = pl110_draw_line16_lblp_rgb }, + { .fn = pl110_draw_line12_lblp_rgb }, - pl110_draw_line1_bbbp_rgb, - pl110_draw_line2_bbbp_rgb, - pl110_draw_line4_bbbp_rgb, - pl110_draw_line8_bbbp_rgb, - pl110_draw_line16_555_bbbp_rgb, - pl110_draw_line32_bbbp_rgb, - pl110_draw_line16_bbbp_rgb, - pl110_draw_line12_bbbp_rgb, + { .fn = pl110_draw_line1_bbbp_rgb }, + { .fn = pl110_draw_line2_bbbp_rgb }, + { .fn = pl110_draw_line4_bbbp_rgb }, + { .fn = pl110_draw_line8_bbbp_rgb }, + { .fn = pl110_draw_line16_555_bbbp_rgb }, + { .fn = pl110_draw_line32_bbbp_rgb }, + { .fn = pl110_draw_line16_bbbp_rgb }, + { .fn = pl110_draw_line12_bbbp_rgb }, - pl110_draw_line1_lbbp_rgb, - pl110_draw_line2_lbbp_rgb, - pl110_draw_line4_lbbp_rgb, - pl110_draw_line8_lbbp_rgb, - pl110_draw_line16_555_lbbp_rgb, - pl110_draw_line32_lbbp_rgb, - pl110_draw_line16_lbbp_rgb, - pl110_draw_line12_lbbp_rgb, + { .fn = pl110_draw_line1_lbbp_rgb }, + { .fn = pl110_draw_line2_lbbp_rgb }, + { .fn = pl110_draw_line4_lbbp_rgb }, + { .fn = pl110_draw_line8_lbbp_rgb }, + { .fn = pl110_draw_line16_555_lbbp_rgb }, + { .fn = pl110_draw_line32_lbbp_rgb }, + { .fn = pl110_draw_line16_lbbp_rgb }, + { .fn = pl110_draw_line12_lbbp_rgb }, }; #undef BITS -- 1.8.3.1