console: pixman switchover continued, add some infrastructure to make it
easier using pixman in display device emulation. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJUCbzxAAoJEEy22O7T6HE4NVIP/1Yw+ieyOxFmWZXFM0JA1EFq GP3CUWiu9RTVQXwDeOGwavRlC+feX4iNuyQVmhrLbKkrraWTxaz4qE/wdLzSTptR JngyGa6lC2rwFYIenEvRRHu//uemow3sGWLCvaADZeeJfm10BKA6qDu7KaaoAxUH DcfycPZH8lbJc8TFUhGQs98VWYG1jFLnmprgeSwrC5YuqjhXDFAMZ+coV7WbZQ8X x7HOHe7gPLDUscezhsEuhZM670ZBtuaRGHUQO88ugXUp2+W37aJym4g9ZURw8Q7E At9mzF051M09WLgRLNf96RjFdCoMwfXkUqhqi4pOsRGkJ3vMdcBQAB6CEtIkeLfH iiO4jf4oNclhYxZcPRnfSW0LkSpk65LPTUCsVyi2V49S2QGosll8WtvZ8s2EQ0PU dnnBxvphy9m/HSkUwWwuoDnIYoivaWqU4O0w9qX+F9N9Ndy62Ay8FP46rir/XpnK ZmHWOl/jYJ2SkyjugoPlLnTUySPxcQ7PA/rKIqCQi6v2Swpf12JKqNMywt5mEata fV4eDZrvmQY63j/zuZE0bUZL2IYqlgLEWvkqy9qhSMySDs9X4qaE+hOyGTipM7EI oeYdZsBCPZP8SpVsC9SaHX8a+ONr2Ajb3Wa5uwyQjcHmMpq7DzmjDKdageTodYQz p8b42rujs1wCqk47/8Ka =TZHU -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/pull-console-20140905-2' into staging console: pixman switchover continued, add some infrastructure to make it easier using pixman in display device emulation. # gpg: Signature made Fri 05 Sep 2014 14:38:57 BST using RSA key ID D3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" * remotes/kraxel/tags/pull-console-20140905-2: console: Remove unused QEMU_BIG_ENDIAN_FLAG console: add qemu_pixman_linebuf_copy console: add dpy_gfx_update_dirty console: add qemu_create_displaysurface_guestmem console: stop using PixelFormat console: reimplement qemu_default_pixelformat console: add qemu_default_pixman_format console: add qemu_pixelformat_from_pixman Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
0dfa7e3012
@ -116,13 +116,14 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||
qxl->guest_primary.bytes_pp,
|
||||
qxl->guest_primary.bits_pp);
|
||||
if (qxl->guest_primary.qxl_stride > 0) {
|
||||
pixman_format_code_t format =
|
||||
qemu_default_pixman_format(qxl->guest_primary.bits_pp, true);
|
||||
surface = qemu_create_displaysurface_from
|
||||
(qxl->guest_primary.surface.width,
|
||||
qxl->guest_primary.surface.height,
|
||||
qxl->guest_primary.bits_pp,
|
||||
format,
|
||||
qxl->guest_primary.abs_stride,
|
||||
qxl->guest_primary.data,
|
||||
false);
|
||||
qxl->guest_primary.data);
|
||||
} else {
|
||||
surface = qemu_create_displaysurface
|
||||
(qxl->guest_primary.surface.width,
|
||||
|
@ -1725,9 +1725,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
||||
height != s->last_height ||
|
||||
s->last_depth != depth) {
|
||||
if (depth == 32 || (depth == 16 && !byteswap)) {
|
||||
pixman_format_code_t format =
|
||||
qemu_default_pixman_format(depth, !byteswap);
|
||||
surface = qemu_create_displaysurface_from(disp_width,
|
||||
height, depth, s->line_offset,
|
||||
s->vram_ptr + (s->start_addr * 4), byteswap);
|
||||
height, format, s->line_offset,
|
||||
s->vram_ptr + (s->start_addr * 4));
|
||||
dpy_gfx_replace_surface(s->con, surface);
|
||||
} else {
|
||||
qemu_console_resize(s->con, disp_width, height);
|
||||
@ -1743,9 +1745,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
||||
} else if (is_buffer_shared(surface) &&
|
||||
(full_update || surface_data(surface) != s->vram_ptr
|
||||
+ (s->start_addr * 4))) {
|
||||
pixman_format_code_t format =
|
||||
qemu_default_pixman_format(depth, !byteswap);
|
||||
surface = qemu_create_displaysurface_from(disp_width,
|
||||
height, depth, s->line_offset,
|
||||
s->vram_ptr + (s->start_addr * 4), byteswap);
|
||||
height, format, s->line_offset,
|
||||
s->vram_ptr + (s->start_addr * 4));
|
||||
dpy_gfx_replace_surface(s->con, surface);
|
||||
}
|
||||
|
||||
|
@ -1052,10 +1052,12 @@ static inline void vmsvga_check_size(struct vmsvga_state_s *s)
|
||||
s->new_height != surface_height(surface) ||
|
||||
s->new_depth != surface_bits_per_pixel(surface)) {
|
||||
int stride = (s->new_depth * s->new_width) / 8;
|
||||
pixman_format_code_t format =
|
||||
qemu_default_pixman_format(s->new_depth, true);
|
||||
trace_vmware_setmode(s->new_width, s->new_height, s->new_depth);
|
||||
surface = qemu_create_displaysurface_from(s->new_width, s->new_height,
|
||||
s->new_depth, stride,
|
||||
s->vga.vram_ptr, false);
|
||||
format, stride,
|
||||
s->vga.vram_ptr);
|
||||
dpy_gfx_replace_surface(s->vga.con, surface);
|
||||
s->invalidated = 1;
|
||||
}
|
||||
|
@ -713,15 +713,17 @@ static void xenfb_update(void *opaque)
|
||||
|
||||
/* resize if needed */
|
||||
if (xenfb->do_resize) {
|
||||
pixman_format_code_t format;
|
||||
|
||||
xenfb->do_resize = 0;
|
||||
switch (xenfb->depth) {
|
||||
case 16:
|
||||
case 32:
|
||||
/* console.c supported depth -> buffer can be used directly */
|
||||
format = qemu_default_pixman_format(xenfb->depth, true);
|
||||
surface = qemu_create_displaysurface_from
|
||||
(xenfb->width, xenfb->height, xenfb->depth,
|
||||
xenfb->row_stride, xenfb->pixels + xenfb->offset,
|
||||
false);
|
||||
(xenfb->width, xenfb->height, format,
|
||||
xenfb->row_stride, xenfb->pixels + xenfb->offset);
|
||||
break;
|
||||
default:
|
||||
/* we must convert stuff */
|
||||
|
@ -102,8 +102,7 @@ struct QemuConsoleClass {
|
||||
ObjectClass parent_class;
|
||||
};
|
||||
|
||||
#define QEMU_BIG_ENDIAN_FLAG 0x01
|
||||
#define QEMU_ALLOCATED_FLAG 0x02
|
||||
#define QEMU_ALLOCATED_FLAG 0x01
|
||||
|
||||
struct PixelFormat {
|
||||
uint8_t bits_per_pixel;
|
||||
@ -119,8 +118,6 @@ struct DisplaySurface {
|
||||
pixman_format_code_t format;
|
||||
pixman_image_t *image;
|
||||
uint8_t flags;
|
||||
|
||||
struct PixelFormat pf;
|
||||
};
|
||||
|
||||
typedef struct QemuUIInfo {
|
||||
@ -188,9 +185,13 @@ struct DisplayChangeListener {
|
||||
};
|
||||
|
||||
DisplayState *init_displaystate(void);
|
||||
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
|
||||
int linesize, uint8_t *data,
|
||||
bool byteswap);
|
||||
DisplaySurface *qemu_create_displaysurface_from(int width, int height,
|
||||
pixman_format_code_t format,
|
||||
int linesize, uint8_t *data);
|
||||
DisplaySurface *qemu_create_displaysurface_guestmem(int width, int height,
|
||||
pixman_format_code_t format,
|
||||
int linesize,
|
||||
uint64_t addr);
|
||||
PixelFormat qemu_different_endianness_pixelformat(int bpp);
|
||||
PixelFormat qemu_default_pixelformat(int bpp);
|
||||
|
||||
@ -199,10 +200,12 @@ void qemu_free_displaysurface(DisplaySurface *surface);
|
||||
|
||||
static inline int is_surface_bgr(DisplaySurface *surface)
|
||||
{
|
||||
if (surface->pf.bits_per_pixel == 32 && surface->pf.rshift == 0)
|
||||
if (PIXMAN_FORMAT_BPP(surface->format) == 32 &&
|
||||
PIXMAN_FORMAT_TYPE(surface->format) == PIXMAN_TYPE_ABGR) {
|
||||
return 1;
|
||||
else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int is_buffer_shared(DisplaySurface *surface)
|
||||
@ -228,6 +231,10 @@ void dpy_text_resize(QemuConsole *con, int w, int h);
|
||||
void dpy_mouse_set(QemuConsole *con, int x, int y, int on);
|
||||
void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor);
|
||||
bool dpy_cursor_define_supported(QemuConsole *con);
|
||||
void dpy_gfx_update_dirty(QemuConsole *con,
|
||||
MemoryRegion *address_space,
|
||||
uint64_t base,
|
||||
bool invalidate);
|
||||
|
||||
static inline int surface_stride(DisplaySurface *s)
|
||||
{
|
||||
|
@ -33,6 +33,8 @@
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format);
|
||||
pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian);
|
||||
int qemu_pixman_get_type(int rshift, int gshift, int bshift);
|
||||
pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf);
|
||||
|
||||
@ -40,6 +42,8 @@ pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format,
|
||||
int width);
|
||||
void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,
|
||||
int width, int x, int y);
|
||||
void qemu_pixman_linebuf_copy(pixman_image_t *fb, int width, int x, int y,
|
||||
pixman_image_t *linebuf);
|
||||
pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
|
||||
pixman_image_t *image);
|
||||
void qemu_pixman_image_unref(pixman_image_t *image);
|
||||
|
@ -1045,7 +1045,7 @@ console_txt_new(int w, int h) "%dx%d"
|
||||
console_select(int nr) "%d"
|
||||
console_refresh(int interval) "interval %d ms"
|
||||
displaysurface_create(void *display_surface, int w, int h) "surface=%p, %dx%d"
|
||||
displaysurface_create_from(void *display_surface, int w, int h, int bpp, int swap) "surface=%p, %dx%d, bpp %d, bswap %d"
|
||||
displaysurface_create_from(void *display_surface, int w, int h, uint32_t format) "surface=%p, %dx%d, format 0x%x"
|
||||
displaysurface_free(void *display_surface) "surface=%p"
|
||||
displaychangelistener_register(void *dcl, const char *name) "%p [ %s ]"
|
||||
displaychangelistener_unregister(void *dcl, const char *name) "%p [ %s ]"
|
||||
|
253
ui/console.c
253
ui/console.c
@ -28,6 +28,7 @@
|
||||
#include "qmp-commands.h"
|
||||
#include "sysemu/char.h"
|
||||
#include "trace.h"
|
||||
#include "exec/memory.h"
|
||||
|
||||
#define DEFAULT_BACKSCROLL 512
|
||||
#define CONSOLE_CURSOR_PERIOD 500
|
||||
@ -1224,61 +1225,77 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
|
||||
return s;
|
||||
}
|
||||
|
||||
static void qemu_alloc_display(DisplaySurface *surface, int width, int height,
|
||||
int linesize, PixelFormat pf, int newflags)
|
||||
static void qemu_alloc_display(DisplaySurface *surface, int width, int height)
|
||||
{
|
||||
surface->pf = pf;
|
||||
|
||||
qemu_pixman_image_unref(surface->image);
|
||||
surface->image = NULL;
|
||||
|
||||
surface->format = qemu_pixman_get_format(&pf);
|
||||
assert(surface->format != 0);
|
||||
surface->format = PIXMAN_x8r8g8b8;
|
||||
surface->image = pixman_image_create_bits(surface->format,
|
||||
width, height,
|
||||
NULL, linesize);
|
||||
NULL, width * 4);
|
||||
assert(surface->image != NULL);
|
||||
|
||||
surface->flags = newflags | QEMU_ALLOCATED_FLAG;
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
surface->flags |= QEMU_BIG_ENDIAN_FLAG;
|
||||
#endif
|
||||
surface->flags = QEMU_ALLOCATED_FLAG;
|
||||
}
|
||||
|
||||
DisplaySurface *qemu_create_displaysurface(int width, int height)
|
||||
{
|
||||
DisplaySurface *surface = g_new0(DisplaySurface, 1);
|
||||
int linesize = width * 4;
|
||||
|
||||
trace_displaysurface_create(surface, width, height);
|
||||
qemu_alloc_display(surface, width, height, linesize,
|
||||
qemu_default_pixelformat(32), 0);
|
||||
qemu_alloc_display(surface, width, height);
|
||||
return surface;
|
||||
}
|
||||
|
||||
DisplaySurface *qemu_create_displaysurface_from(int width, int height, int bpp,
|
||||
int linesize, uint8_t *data,
|
||||
bool byteswap)
|
||||
DisplaySurface *qemu_create_displaysurface_from(int width, int height,
|
||||
pixman_format_code_t format,
|
||||
int linesize, uint8_t *data)
|
||||
{
|
||||
DisplaySurface *surface = g_new0(DisplaySurface, 1);
|
||||
|
||||
trace_displaysurface_create_from(surface, width, height, bpp, byteswap);
|
||||
if (byteswap) {
|
||||
surface->pf = qemu_different_endianness_pixelformat(bpp);
|
||||
} else {
|
||||
surface->pf = qemu_default_pixelformat(bpp);
|
||||
}
|
||||
|
||||
surface->format = qemu_pixman_get_format(&surface->pf);
|
||||
assert(surface->format != 0);
|
||||
trace_displaysurface_create_from(surface, width, height, format);
|
||||
surface->format = format;
|
||||
surface->image = pixman_image_create_bits(surface->format,
|
||||
width, height,
|
||||
(void *)data, linesize);
|
||||
assert(surface->image != NULL);
|
||||
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
surface->flags = QEMU_BIG_ENDIAN_FLAG;
|
||||
#endif
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void qemu_unmap_displaysurface_guestmem(pixman_image_t *image,
|
||||
void *unused)
|
||||
{
|
||||
void *data = pixman_image_get_data(image);
|
||||
uint32_t size = pixman_image_get_stride(image) *
|
||||
pixman_image_get_height(image);
|
||||
cpu_physical_memory_unmap(data, size, 0, 0);
|
||||
}
|
||||
|
||||
DisplaySurface *qemu_create_displaysurface_guestmem(int width, int height,
|
||||
pixman_format_code_t format,
|
||||
int linesize, uint64_t addr)
|
||||
{
|
||||
DisplaySurface *surface;
|
||||
hwaddr size;
|
||||
void *data;
|
||||
|
||||
if (linesize == 0) {
|
||||
linesize = width * PIXMAN_FORMAT_BPP(format) / 8;
|
||||
}
|
||||
|
||||
size = linesize * height;
|
||||
data = cpu_physical_memory_map(addr, &size, 0);
|
||||
if (size != linesize * height) {
|
||||
cpu_physical_memory_unmap(data, size, 0, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface = qemu_create_displaysurface_from
|
||||
(width, height, format, linesize, data);
|
||||
pixman_image_set_destroy_function
|
||||
(surface->image, qemu_unmap_displaysurface_guestmem, NULL);
|
||||
|
||||
return surface;
|
||||
}
|
||||
@ -1557,6 +1574,67 @@ bool dpy_cursor_define_supported(QemuConsole *con)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call dpy_gfx_update for all dirity scanlines. Works for
|
||||
* DisplaySurfaces backed by guest memory (i.e. the ones created
|
||||
* using qemu_create_displaysurface_guestmem).
|
||||
*/
|
||||
void dpy_gfx_update_dirty(QemuConsole *con,
|
||||
MemoryRegion *address_space,
|
||||
hwaddr base,
|
||||
bool invalidate)
|
||||
{
|
||||
DisplaySurface *ds = qemu_console_surface(con);
|
||||
int width = surface_stride(ds);
|
||||
int height = surface_height(ds);
|
||||
hwaddr size = width * height;
|
||||
MemoryRegionSection mem_section;
|
||||
MemoryRegion *mem;
|
||||
ram_addr_t addr;
|
||||
int first, last, i;
|
||||
bool dirty;
|
||||
|
||||
mem_section = memory_region_find(address_space, base, size);
|
||||
mem = mem_section.mr;
|
||||
if (int128_get64(mem_section.size) != size ||
|
||||
!memory_region_is_ram(mem_section.mr)) {
|
||||
goto out;
|
||||
}
|
||||
assert(mem);
|
||||
|
||||
memory_region_sync_dirty_bitmap(mem);
|
||||
addr = mem_section.offset_within_region;
|
||||
|
||||
first = -1;
|
||||
last = -1;
|
||||
for (i = 0; i < height; i++, addr += width) {
|
||||
dirty = invalidate ||
|
||||
memory_region_get_dirty(mem, addr, width, DIRTY_MEMORY_VGA);
|
||||
if (dirty) {
|
||||
if (first == -1) {
|
||||
first = i;
|
||||
}
|
||||
last = i;
|
||||
}
|
||||
if (first != -1 && !dirty) {
|
||||
assert(last != -1 && last >= first);
|
||||
dpy_gfx_update(con, 0, first, surface_width(ds),
|
||||
last - first + 1);
|
||||
first = -1;
|
||||
}
|
||||
}
|
||||
if (first != -1) {
|
||||
assert(last != -1 && last >= first);
|
||||
dpy_gfx_update(con, 0, first, surface_width(ds),
|
||||
last - first + 1);
|
||||
}
|
||||
|
||||
memory_region_reset_dirty(mem, mem_section.offset_within_region, size,
|
||||
DIRTY_MEMORY_VGA);
|
||||
out:
|
||||
memory_region_unref(mem);
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
/* register display */
|
||||
|
||||
@ -1902,124 +1980,15 @@ DisplayState *qemu_console_displaystate(QemuConsole *console)
|
||||
|
||||
PixelFormat qemu_different_endianness_pixelformat(int bpp)
|
||||
{
|
||||
PixelFormat pf;
|
||||
|
||||
memset(&pf, 0x00, sizeof(PixelFormat));
|
||||
|
||||
pf.bits_per_pixel = bpp;
|
||||
pf.bytes_per_pixel = DIV_ROUND_UP(bpp, 8);
|
||||
pf.depth = bpp == 32 ? 24 : bpp;
|
||||
|
||||
switch (bpp) {
|
||||
case 24:
|
||||
pf.rmask = 0x000000FF;
|
||||
pf.gmask = 0x0000FF00;
|
||||
pf.bmask = 0x00FF0000;
|
||||
pf.rmax = 255;
|
||||
pf.gmax = 255;
|
||||
pf.bmax = 255;
|
||||
pf.rshift = 0;
|
||||
pf.gshift = 8;
|
||||
pf.bshift = 16;
|
||||
pf.rbits = 8;
|
||||
pf.gbits = 8;
|
||||
pf.bbits = 8;
|
||||
break;
|
||||
case 32:
|
||||
pf.rmask = 0x0000FF00;
|
||||
pf.gmask = 0x00FF0000;
|
||||
pf.bmask = 0xFF000000;
|
||||
pf.amask = 0x00000000;
|
||||
pf.amax = 255;
|
||||
pf.rmax = 255;
|
||||
pf.gmax = 255;
|
||||
pf.bmax = 255;
|
||||
pf.ashift = 0;
|
||||
pf.rshift = 8;
|
||||
pf.gshift = 16;
|
||||
pf.bshift = 24;
|
||||
pf.rbits = 8;
|
||||
pf.gbits = 8;
|
||||
pf.bbits = 8;
|
||||
pf.abits = 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pixman_format_code_t fmt = qemu_default_pixman_format(bpp, false);
|
||||
PixelFormat pf = qemu_pixelformat_from_pixman(fmt);
|
||||
return pf;
|
||||
}
|
||||
|
||||
PixelFormat qemu_default_pixelformat(int bpp)
|
||||
{
|
||||
PixelFormat pf;
|
||||
|
||||
memset(&pf, 0x00, sizeof(PixelFormat));
|
||||
|
||||
pf.bits_per_pixel = bpp;
|
||||
pf.bytes_per_pixel = DIV_ROUND_UP(bpp, 8);
|
||||
pf.depth = bpp == 32 ? 24 : bpp;
|
||||
|
||||
switch (bpp) {
|
||||
case 15:
|
||||
pf.bits_per_pixel = 16;
|
||||
pf.rmask = 0x00007c00;
|
||||
pf.gmask = 0x000003E0;
|
||||
pf.bmask = 0x0000001F;
|
||||
pf.rmax = 31;
|
||||
pf.gmax = 31;
|
||||
pf.bmax = 31;
|
||||
pf.rshift = 10;
|
||||
pf.gshift = 5;
|
||||
pf.bshift = 0;
|
||||
pf.rbits = 5;
|
||||
pf.gbits = 5;
|
||||
pf.bbits = 5;
|
||||
break;
|
||||
case 16:
|
||||
pf.rmask = 0x0000F800;
|
||||
pf.gmask = 0x000007E0;
|
||||
pf.bmask = 0x0000001F;
|
||||
pf.rmax = 31;
|
||||
pf.gmax = 63;
|
||||
pf.bmax = 31;
|
||||
pf.rshift = 11;
|
||||
pf.gshift = 5;
|
||||
pf.bshift = 0;
|
||||
pf.rbits = 5;
|
||||
pf.gbits = 6;
|
||||
pf.bbits = 5;
|
||||
break;
|
||||
case 24:
|
||||
pf.rmask = 0x00FF0000;
|
||||
pf.gmask = 0x0000FF00;
|
||||
pf.bmask = 0x000000FF;
|
||||
pf.rmax = 255;
|
||||
pf.gmax = 255;
|
||||
pf.bmax = 255;
|
||||
pf.rshift = 16;
|
||||
pf.gshift = 8;
|
||||
pf.bshift = 0;
|
||||
pf.rbits = 8;
|
||||
pf.gbits = 8;
|
||||
pf.bbits = 8;
|
||||
break;
|
||||
case 32:
|
||||
pf.rmask = 0x00FF0000;
|
||||
pf.gmask = 0x0000FF00;
|
||||
pf.bmask = 0x000000FF;
|
||||
pf.rmax = 255;
|
||||
pf.gmax = 255;
|
||||
pf.bmax = 255;
|
||||
pf.rshift = 16;
|
||||
pf.gshift = 8;
|
||||
pf.bshift = 0;
|
||||
pf.rbits = 8;
|
||||
pf.gbits = 8;
|
||||
pf.bbits = 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pixman_format_code_t fmt = qemu_default_pixman_format(bpp, true);
|
||||
PixelFormat pf = qemu_pixelformat_from_pixman(fmt);
|
||||
return pf;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,87 @@
|
||||
#include "qemu-common.h"
|
||||
#include "ui/console.h"
|
||||
|
||||
PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format)
|
||||
{
|
||||
PixelFormat pf;
|
||||
uint8_t bpp;
|
||||
|
||||
bpp = pf.bits_per_pixel = PIXMAN_FORMAT_BPP(format);
|
||||
pf.bytes_per_pixel = PIXMAN_FORMAT_BPP(format) / 8;
|
||||
pf.depth = PIXMAN_FORMAT_DEPTH(format);
|
||||
|
||||
pf.abits = PIXMAN_FORMAT_A(format);
|
||||
pf.rbits = PIXMAN_FORMAT_R(format);
|
||||
pf.gbits = PIXMAN_FORMAT_G(format);
|
||||
pf.bbits = PIXMAN_FORMAT_B(format);
|
||||
|
||||
switch (PIXMAN_FORMAT_TYPE(format)) {
|
||||
case PIXMAN_TYPE_ARGB:
|
||||
pf.ashift = pf.bbits + pf.gbits + pf.rbits;
|
||||
pf.rshift = pf.bbits + pf.gbits;
|
||||
pf.gshift = pf.bbits;
|
||||
pf.bshift = 0;
|
||||
break;
|
||||
case PIXMAN_TYPE_ABGR:
|
||||
pf.ashift = pf.rbits + pf.gbits + pf.bbits;
|
||||
pf.bshift = pf.rbits + pf.gbits;
|
||||
pf.gshift = pf.rbits;
|
||||
pf.rshift = 0;
|
||||
break;
|
||||
case PIXMAN_TYPE_BGRA:
|
||||
pf.bshift = bpp - pf.bbits;
|
||||
pf.gshift = bpp - (pf.bbits + pf.gbits);
|
||||
pf.rshift = bpp - (pf.bbits + pf.gbits + pf.rbits);
|
||||
pf.ashift = 0;
|
||||
break;
|
||||
case PIXMAN_TYPE_RGBA:
|
||||
pf.rshift = bpp - pf.rbits;
|
||||
pf.gshift = bpp - (pf.rbits + pf.gbits);
|
||||
pf.bshift = bpp - (pf.rbits + pf.gbits + pf.bbits);
|
||||
pf.ashift = 0;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
|
||||
pf.amax = (1 << pf.abits) - 1;
|
||||
pf.rmax = (1 << pf.rbits) - 1;
|
||||
pf.gmax = (1 << pf.gbits) - 1;
|
||||
pf.bmax = (1 << pf.bbits) - 1;
|
||||
pf.amask = pf.amax << pf.ashift;
|
||||
pf.rmask = pf.rmax << pf.rshift;
|
||||
pf.gmask = pf.gmax << pf.gshift;
|
||||
pf.bmask = pf.bmax << pf.bshift;
|
||||
|
||||
return pf;
|
||||
}
|
||||
|
||||
pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian)
|
||||
{
|
||||
if (native_endian) {
|
||||
switch (bpp) {
|
||||
case 15:
|
||||
return PIXMAN_x1r5g5b5;
|
||||
case 16:
|
||||
return PIXMAN_r5g6b5;
|
||||
case 24:
|
||||
return PIXMAN_r8g8b8;
|
||||
case 32:
|
||||
return PIXMAN_x8r8g8b8;
|
||||
}
|
||||
} else {
|
||||
switch (bpp) {
|
||||
case 24:
|
||||
return PIXMAN_b8g8r8;
|
||||
case 32:
|
||||
return PIXMAN_b8g8r8a8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
int qemu_pixman_get_type(int rshift, int gshift, int bshift)
|
||||
{
|
||||
int type = PIXMAN_TYPE_OTHER;
|
||||
@ -52,6 +133,7 @@ pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format,
|
||||
return image;
|
||||
}
|
||||
|
||||
/* fill linebuf from framebuffer */
|
||||
void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,
|
||||
int width, int x, int y)
|
||||
{
|
||||
@ -59,6 +141,14 @@ void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,
|
||||
x, y, 0, 0, 0, 0, width, 1);
|
||||
}
|
||||
|
||||
/* copy linebuf to framebuffer */
|
||||
void qemu_pixman_linebuf_copy(pixman_image_t *fb, int width, int x, int y,
|
||||
pixman_image_t *linebuf)
|
||||
{
|
||||
pixman_image_composite(PIXMAN_OP_SRC, linebuf, NULL, fb,
|
||||
0, 0, 0, 0, x, y, width, 1);
|
||||
}
|
||||
|
||||
pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
|
||||
pixman_image_t *image)
|
||||
{
|
||||
|
5
ui/sdl.c
5
ui/sdl.c
@ -127,6 +127,7 @@ static void do_sdl_resize(int width, int height, int bpp)
|
||||
static void sdl_switch(DisplayChangeListener *dcl,
|
||||
DisplaySurface *new_surface)
|
||||
{
|
||||
PixelFormat pf = qemu_pixelformat_from_pixman(new_surface->format);
|
||||
|
||||
/* temporary hack: allows to call sdl_switch to handle scaling changes */
|
||||
if (new_surface) {
|
||||
@ -148,8 +149,8 @@ static void sdl_switch(DisplayChangeListener *dcl,
|
||||
(surface_data(surface),
|
||||
surface_width(surface), surface_height(surface),
|
||||
surface_bits_per_pixel(surface), surface_stride(surface),
|
||||
surface->pf.rmask, surface->pf.gmask,
|
||||
surface->pf.bmask, surface->pf.amask);
|
||||
pf.rmask, pf.gmask,
|
||||
pf.bmask, pf.amask);
|
||||
}
|
||||
|
||||
/* generic keyboard conversion */
|
||||
|
@ -220,8 +220,7 @@ tight_detect_smooth_image24(VncState *vs, int w, int h)
|
||||
unsigned int errors; \
|
||||
unsigned char *buf = vs->tight.tight.buffer; \
|
||||
\
|
||||
endian = 0; /* FIXME: ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) != \
|
||||
(vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); */ \
|
||||
endian = 0; /* FIXME */ \
|
||||
\
|
||||
\
|
||||
max[0] = vs->client_pf.rmax; \
|
||||
@ -563,8 +562,7 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int w, int h)
|
||||
buf32 = (uint32_t *)buf;
|
||||
memset(vs->tight.gradient.buffer, 0, w * 3 * sizeof(int));
|
||||
|
||||
if (1 /* FIXME: (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
|
||||
(vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) */) {
|
||||
if (1 /* FIXME */) {
|
||||
shift[0] = vs->client_pf.rshift;
|
||||
shift[1] = vs->client_pf.gshift;
|
||||
shift[2] = vs->client_pf.bshift;
|
||||
@ -621,8 +619,7 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int w, int h)
|
||||
\
|
||||
memset (vs->tight.gradient.buffer, 0, w * 3 * sizeof(int)); \
|
||||
\
|
||||
endian = 0; /* FIXME: ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) != \
|
||||
(vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); */ \
|
||||
endian = 0; /* FIXME */ \
|
||||
\
|
||||
max[0] = vs->client_pf.rmax; \
|
||||
max[1] = vs->client_pf.gmax; \
|
||||
@ -898,8 +895,7 @@ static void tight_pack24(VncState *vs, uint8_t *buf, size_t count, size_t *ret)
|
||||
|
||||
buf32 = (uint32_t *)buf;
|
||||
|
||||
if (1 /* FIXME: (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
|
||||
(vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) */) {
|
||||
if (1 /* FIXME */) {
|
||||
rshift = vs->client_pf.rshift;
|
||||
gshift = vs->client_pf.gshift;
|
||||
bshift = vs->client_pf.bshift;
|
||||
|
Loading…
Reference in New Issue
Block a user