Skip to content

Commit

Permalink
console: remove DisplayAllocator
Browse files Browse the repository at this point in the history
Causes [temporary] preformance regression with 24bpp vga modes @ sdl.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
  • Loading branch information
kraxel committed Nov 1, 2012
1 parent 4dc6a39 commit 187cd1d
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 173 deletions.
52 changes: 19 additions & 33 deletions console.c
Expand Up @@ -1294,23 +1294,26 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type)
return s;
}

static DisplaySurface* defaultallocator_create_displaysurface(int width, int height)
DisplaySurface *qemu_create_displaysurface(DisplayState *ds,
int width, int height)
{
DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));
DisplaySurface *surface = g_new0(DisplaySurface, 1);

int linesize = width * 4;
qemu_alloc_display(surface, width, height, linesize,
qemu_default_pixelformat(32), 0);
return surface;
}

static DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface,
int width, int height)
DisplaySurface *qemu_resize_displaysurface(DisplayState *ds,
int width, int height)
{
int linesize = width * 4;
qemu_alloc_display(surface, width, height, linesize,

trace_displaysurface_resize(ds, ds->surface, width, height);
qemu_alloc_display(ds->surface, width, height, linesize,
qemu_default_pixelformat(32), 0);
return surface;
return ds->surface;
}

void qemu_alloc_display(DisplaySurface *surface, int width, int height,
Expand All @@ -1323,7 +1326,7 @@ void qemu_alloc_display(DisplaySurface *surface, int width, int height,
surface->pf = pf;
if (surface->flags & QEMU_ALLOCATED_FLAG) {
data = g_realloc(surface->data,
surface->linesize * surface->height);
surface->linesize * surface->height);
} else {
data = g_malloc(surface->linesize * surface->height);
}
Expand All @@ -1334,7 +1337,7 @@ void qemu_alloc_display(DisplaySurface *surface, int width, int height,
#endif
}

DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
DisplaySurface *qemu_create_displaysurface_from(int width, int height, int bpp,
int linesize, uint8_t *data)
{
DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));
Expand All @@ -1351,28 +1354,24 @@ DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
return surface;
}

static void defaultallocator_free_displaysurface(DisplaySurface *surface)
void qemu_free_displaysurface(DisplayState *ds)
{
if (surface == NULL)
trace_displaysurface_free(ds, ds->surface);
if (ds->surface == NULL) {
return;
if (surface->flags & QEMU_ALLOCATED_FLAG)
g_free(surface->data);
g_free(surface);
}
if (ds->surface->flags & QEMU_ALLOCATED_FLAG) {
g_free(ds->surface->data);
}
g_free(ds->surface);
}

static struct DisplayAllocator default_allocator = {
defaultallocator_create_displaysurface,
defaultallocator_resize_displaysurface,
defaultallocator_free_displaysurface
};

static void dumb_display_init(void)
{
DisplayState *ds = g_malloc0(sizeof(DisplayState));
int width = 640;
int height = 480;

ds->allocator = &default_allocator;
if (is_fixedsize_console()) {
width = active_console->g_width;
height = active_console->g_height;
Expand Down Expand Up @@ -1402,18 +1401,6 @@ DisplayState *get_displaystate(void)
return display_state;
}

DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
{
if(ds->allocator == &default_allocator) {
DisplaySurface *surf;
surf = da->create_displaysurface(ds_get_width(ds), ds_get_height(ds));
defaultallocator_free_displaysurface(ds->surface);
ds->surface = surf;
ds->allocator = da;
}
return ds->allocator;
}

DisplayState *graphic_console_init(vga_hw_update_ptr update,
vga_hw_invalidate_ptr invalidate,
vga_hw_screen_dump_ptr screen_dump,
Expand All @@ -1424,7 +1411,6 @@ DisplayState *graphic_console_init(vga_hw_update_ptr update,
DisplayState *ds;

ds = (DisplayState *) g_malloc0(sizeof(DisplayState));
ds->allocator = &default_allocator;
ds->surface = qemu_create_displaysurface(ds, 640, 480);

s = new_console(ds, GRAPHIC_CONSOLE);
Expand Down
34 changes: 6 additions & 28 deletions console.h
Expand Up @@ -107,7 +107,6 @@ void kbd_put_keysym(int keysym);

#define QEMU_BIG_ENDIAN_FLAG 0x01
#define QEMU_ALLOCATED_FLAG 0x02
#define QEMU_REALPIXELS_FLAG 0x04

struct PixelFormat {
uint8_t bits_per_pixel;
Expand Down Expand Up @@ -172,20 +171,13 @@ struct DisplayChangeListener {
QLIST_ENTRY(DisplayChangeListener) next;
};

struct DisplayAllocator {
DisplaySurface* (*create_displaysurface)(int width, int height);
DisplaySurface* (*resize_displaysurface)(DisplaySurface *surface, int width, int height);
void (*free_displaysurface)(DisplaySurface *surface);
};

struct DisplayState {
struct DisplaySurface *surface;
void *opaque;
struct QEMUTimer *gui_timer;
bool have_gfx;
bool have_text;

struct DisplayAllocator* allocator;
QLIST_HEAD(, DisplayChangeListener) listeners;

struct DisplayState *next;
Expand All @@ -200,24 +192,11 @@ void qemu_alloc_display(DisplaySurface *surface, int width, int height,
PixelFormat qemu_different_endianness_pixelformat(int bpp);
PixelFormat qemu_default_pixelformat(int bpp);

DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da);

static inline DisplaySurface* qemu_create_displaysurface(DisplayState *ds, int width, int height)
{
return ds->allocator->create_displaysurface(width, height);
}

static inline DisplaySurface* qemu_resize_displaysurface(DisplayState *ds, int width, int height)
{
trace_displaysurface_resize(ds, ds->surface, width, height);
return ds->allocator->resize_displaysurface(ds->surface, width, height);
}

static inline void qemu_free_displaysurface(DisplayState *ds)
{
trace_displaysurface_free(ds, ds->surface);
ds->allocator->free_displaysurface(ds->surface);
}
DisplaySurface *qemu_create_displaysurface(DisplayState *ds,
int width, int height);
DisplaySurface *qemu_resize_displaysurface(DisplayState *ds,
int width, int height);
void qemu_free_displaysurface(DisplayState *ds);

static inline int is_surface_bgr(DisplaySurface *surface)
{
Expand All @@ -229,8 +208,7 @@ static inline int is_surface_bgr(DisplaySurface *surface)

static inline int is_buffer_shared(DisplaySurface *surface)
{
return (!(surface->flags & QEMU_ALLOCATED_FLAG) &&
!(surface->flags & QEMU_REALPIXELS_FLAG));
return !(surface->flags & QEMU_ALLOCATED_FLAG);
}

void gui_setup_refresh(DisplayState *ds);
Expand Down
1 change: 0 additions & 1 deletion qemu-common.h
Expand Up @@ -262,7 +262,6 @@ typedef struct DriveInfo DriveInfo;
typedef struct DisplayState DisplayState;
typedef struct DisplayChangeListener DisplayChangeListener;
typedef struct DisplaySurface DisplaySurface;
typedef struct DisplayAllocator DisplayAllocator;
typedef struct PixelFormat PixelFormat;
typedef struct QemuConsole QemuConsole;
typedef struct CharDriverState CharDriverState;
Expand Down
117 changes: 6 additions & 111 deletions ui/sdl.c
Expand Up @@ -55,7 +55,6 @@ static int absolute_enabled = 0;
static int guest_cursor = 0;
static int guest_x, guest_y;
static SDL_Cursor *guest_sprite = NULL;
static uint8_t allocator;
static SDL_PixelFormat host_format;
static int scaling_active = 0;
static Notifier mouse_mode_notifier;
Expand Down Expand Up @@ -117,108 +116,13 @@ static void do_sdl_resize(int width, int height, int bpp)

static void sdl_resize(DisplayState *ds)
{
if (!allocator) {
if (!scaling_active)
do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
else if (real_screen->format->BitsPerPixel != ds_get_bits_per_pixel(ds))
do_sdl_resize(real_screen->w, real_screen->h, ds_get_bits_per_pixel(ds));
sdl_setdata(ds);
} else {
if (guest_screen != NULL) {
SDL_FreeSurface(guest_screen);
guest_screen = NULL;
}
}
}

static PixelFormat sdl_to_qemu_pixelformat(SDL_PixelFormat *sdl_pf)
{
PixelFormat qemu_pf;

memset(&qemu_pf, 0x00, sizeof(PixelFormat));

qemu_pf.bits_per_pixel = sdl_pf->BitsPerPixel;
qemu_pf.bytes_per_pixel = sdl_pf->BytesPerPixel;
qemu_pf.depth = (qemu_pf.bits_per_pixel) == 32 ? 24 : (qemu_pf.bits_per_pixel);

qemu_pf.rmask = sdl_pf->Rmask;
qemu_pf.gmask = sdl_pf->Gmask;
qemu_pf.bmask = sdl_pf->Bmask;
qemu_pf.amask = sdl_pf->Amask;

qemu_pf.rshift = sdl_pf->Rshift;
qemu_pf.gshift = sdl_pf->Gshift;
qemu_pf.bshift = sdl_pf->Bshift;
qemu_pf.ashift = sdl_pf->Ashift;

qemu_pf.rbits = 8 - sdl_pf->Rloss;
qemu_pf.gbits = 8 - sdl_pf->Gloss;
qemu_pf.bbits = 8 - sdl_pf->Bloss;
qemu_pf.abits = 8 - sdl_pf->Aloss;

qemu_pf.rmax = ((1 << qemu_pf.rbits) - 1);
qemu_pf.gmax = ((1 << qemu_pf.gbits) - 1);
qemu_pf.bmax = ((1 << qemu_pf.bbits) - 1);
qemu_pf.amax = ((1 << qemu_pf.abits) - 1);

return qemu_pf;
}

static DisplaySurface* sdl_create_displaysurface(int width, int height)
{
DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));

surface->width = width;
surface->height = height;

if (scaling_active) {
int linesize;
PixelFormat pf;
if (host_format.BytesPerPixel != 2 && host_format.BytesPerPixel != 4) {
linesize = width * 4;
pf = qemu_default_pixelformat(32);
} else {
linesize = width * host_format.BytesPerPixel;
pf = sdl_to_qemu_pixelformat(&host_format);
}
qemu_alloc_display(surface, width, height, linesize, pf, 0);
return surface;
if (!scaling_active) {
do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
} else if (real_screen->format->BitsPerPixel != ds_get_bits_per_pixel(ds)) {
do_sdl_resize(real_screen->w, real_screen->h,
ds_get_bits_per_pixel(ds));
}

if (host_format.BitsPerPixel == 16)
do_sdl_resize(width, height, 16);
else
do_sdl_resize(width, height, 32);

surface->pf = sdl_to_qemu_pixelformat(real_screen->format);
surface->linesize = real_screen->pitch;
surface->data = real_screen->pixels;

#ifdef HOST_WORDS_BIGENDIAN
surface->flags = QEMU_REALPIXELS_FLAG | QEMU_BIG_ENDIAN_FLAG;
#else
surface->flags = QEMU_REALPIXELS_FLAG;
#endif
allocator = 1;

return surface;
}

static void sdl_free_displaysurface(DisplaySurface *surface)
{
allocator = 0;
if (surface == NULL)
return;

if (surface->flags & QEMU_ALLOCATED_FLAG)
g_free(surface->data);
g_free(surface);
}

static DisplaySurface* sdl_resize_displaysurface(DisplaySurface *surface, int width, int height)
{
sdl_free_displaysurface(surface);
return sdl_create_displaysurface(width, height);
sdl_setdata(ds);
}

/* generic keyboard conversion */
Expand Down Expand Up @@ -949,7 +853,6 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
{
int flags;
uint8_t data = 0;
DisplayAllocator *da;
const SDL_VideoInfo *vi;
char *filename;

Expand Down Expand Up @@ -1022,14 +925,6 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
dcl->dpy_cursor_define = sdl_mouse_define;
register_displaychangelistener(ds, dcl);

da = g_malloc0(sizeof(DisplayAllocator));
da->create_displaysurface = sdl_create_displaysurface;
da->resize_displaysurface = sdl_resize_displaysurface;
da->free_displaysurface = sdl_free_displaysurface;
if (register_displayallocator(ds, da) == da) {
dpy_gfx_resize(ds);
}

mouse_mode_notifier.notify = sdl_mouse_mode_change;
qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier);

Expand Down

0 comments on commit 187cd1d

Please sign in to comment.