mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-08 07:40:34 +00:00
gtk: add support for surface conversion
Also use CAIRO_FORMAT_RGB24 unconditionally. DisplaySurfaces will never ever see 8bpp surfaces. And using CAIRO_FORMAT_RGB16_565 for the 16bpp case doesn't seem to be a good idea too. <quote src="/usr/include/cairo/cairo.h"> * @CAIRO_FORMAT_RGB16_565: This format value is deprecated. It has * never been properly implemented in cairo and should not be used * by applications. (since 1.2) </quote> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Message-id: 1372150134-8590-1-git-send-email-kraxel@redhat.com Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
12b7f57e2c
commit
f087553653
63
ui/gtk.c
63
ui/gtk.c
@ -147,6 +147,7 @@ typedef struct GtkDisplayState
|
|||||||
GtkWidget *notebook;
|
GtkWidget *notebook;
|
||||||
GtkWidget *drawing_area;
|
GtkWidget *drawing_area;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
|
pixman_image_t *convert;
|
||||||
DisplayChangeListener dcl;
|
DisplayChangeListener dcl;
|
||||||
DisplaySurface *ds;
|
DisplaySurface *ds;
|
||||||
int button_mask;
|
int button_mask;
|
||||||
@ -303,6 +304,11 @@ static void gd_update(DisplayChangeListener *dcl,
|
|||||||
|
|
||||||
DPRINTF("update(x=%d, y=%d, w=%d, h=%d)\n", x, y, w, h);
|
DPRINTF("update(x=%d, y=%d, w=%d, h=%d)\n", x, y, w, h);
|
||||||
|
|
||||||
|
if (s->convert) {
|
||||||
|
pixman_image_composite(PIXMAN_OP_SRC, s->ds->image, NULL, s->convert,
|
||||||
|
x, y, 0, 0, x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
x1 = floor(x * s->scale_x);
|
x1 = floor(x * s->scale_x);
|
||||||
y1 = floor(y * s->scale_y);
|
y1 = floor(y * s->scale_y);
|
||||||
|
|
||||||
@ -388,9 +394,7 @@ static void gd_switch(DisplayChangeListener *dcl,
|
|||||||
DisplaySurface *surface)
|
DisplaySurface *surface)
|
||||||
{
|
{
|
||||||
GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
|
GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
|
||||||
cairo_format_t kind;
|
|
||||||
bool resized = true;
|
bool resized = true;
|
||||||
int stride;
|
|
||||||
|
|
||||||
DPRINTF("resize(width=%d, height=%d)\n",
|
DPRINTF("resize(width=%d, height=%d)\n",
|
||||||
surface_width(surface), surface_height(surface));
|
surface_width(surface), surface_height(surface));
|
||||||
@ -405,29 +409,42 @@ static void gd_switch(DisplayChangeListener *dcl,
|
|||||||
resized = false;
|
resized = false;
|
||||||
}
|
}
|
||||||
s->ds = surface;
|
s->ds = surface;
|
||||||
switch (surface_bits_per_pixel(surface)) {
|
|
||||||
case 8:
|
if (s->convert) {
|
||||||
kind = CAIRO_FORMAT_A8;
|
pixman_image_unref(s->convert);
|
||||||
break;
|
s->convert = NULL;
|
||||||
case 16:
|
|
||||||
kind = CAIRO_FORMAT_RGB16_565;
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
kind = CAIRO_FORMAT_RGB24;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stride = cairo_format_stride_for_width(kind, surface_width(surface));
|
if (surface->format == PIXMAN_x8r8g8b8) {
|
||||||
g_assert(surface_stride(surface) == stride);
|
/*
|
||||||
|
* PIXMAN_x8r8g8b8 == CAIRO_FORMAT_RGB24
|
||||||
s->surface = cairo_image_surface_create_for_data(surface_data(surface),
|
*
|
||||||
kind,
|
* No need to convert, use surface directly. Should be the
|
||||||
surface_width(surface),
|
* common case as this is qemu_default_pixelformat(32) too.
|
||||||
surface_height(surface),
|
*/
|
||||||
surface_stride(surface));
|
s->surface = cairo_image_surface_create_for_data
|
||||||
|
(surface_data(surface),
|
||||||
|
CAIRO_FORMAT_RGB24,
|
||||||
|
surface_width(surface),
|
||||||
|
surface_height(surface),
|
||||||
|
surface_stride(surface));
|
||||||
|
} else {
|
||||||
|
/* Must convert surface, use pixman to do it. */
|
||||||
|
s->convert = pixman_image_create_bits(PIXMAN_x8r8g8b8,
|
||||||
|
surface_width(surface),
|
||||||
|
surface_height(surface),
|
||||||
|
NULL, 0);
|
||||||
|
s->surface = cairo_image_surface_create_for_data
|
||||||
|
((void *)pixman_image_get_data(s->convert),
|
||||||
|
CAIRO_FORMAT_RGB24,
|
||||||
|
pixman_image_get_width(s->convert),
|
||||||
|
pixman_image_get_height(s->convert),
|
||||||
|
pixman_image_get_stride(s->convert));
|
||||||
|
pixman_image_composite(PIXMAN_OP_SRC, s->ds->image, NULL, s->convert,
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
pixman_image_get_width(s->convert),
|
||||||
|
pixman_image_get_height(s->convert));
|
||||||
|
}
|
||||||
|
|
||||||
if (resized) {
|
if (resized) {
|
||||||
gd_update_windowsize(s);
|
gd_update_windowsize(s);
|
||||||
|
Loading…
Reference in New Issue
Block a user