Revision 7b5d76da

b/console.c
1068 1068
        DisplayState *ds = s->ds;
1069 1069
        active_console = s;
1070 1070
        if (ds_get_bits_per_pixel(s->ds)) {
1071
            ds->surface = qemu_resize_displaysurface(ds->surface, s->g_width,
1072
                    s->g_height, 32, 4 * s->g_width);
1071
            ds->surface = qemu_resize_displaysurface(ds, s->g_width, s->g_height);
1073 1072
        } else {
1074 1073
            s->ds->surface->width = s->width;
1075 1074
            s->ds->surface->height = s->height;
......
1277 1276
    DisplayState *ds;
1278 1277

  
1279 1278
    ds = (DisplayState *) qemu_mallocz(sizeof(DisplayState));
1280
    ds->surface = qemu_create_displaysurface(640, 480, 32, 640 * 4);
1279
    ds->allocator = &default_allocator; 
1280
    ds->surface = qemu_create_displaysurface(ds, 640, 480);
1281 1281

  
1282 1282
    s = new_console(ds, GRAPHIC_CONSOLE);
1283 1283
    if (s == NULL) {
1284
        qemu_free_displaysurface(ds->surface);
1284
        qemu_free_displaysurface(ds);
1285 1285
        qemu_free(ds);
1286 1286
        return NULL;
1287 1287
    }
......
1429 1429
    s->g_width = width;
1430 1430
    s->g_height = height;
1431 1431
    if (is_graphic_console()) {
1432
        ds->surface = qemu_resize_displaysurface(ds->surface, width, height, 32, 4 * width);
1432
        ds->surface = qemu_resize_displaysurface(ds, width, height);
1433 1433
        dpy_resize(ds);
1434 1434
    }
1435 1435
}
......
1552 1552
    return pf;
1553 1553
}
1554 1554

  
1555
DisplaySurface* qemu_create_displaysurface(int width, int height, int bpp, int linesize)
1555
DisplaySurface* defaultallocator_create_displaysurface(int width, int height)
1556 1556
{
1557 1557
    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
1558 1558

  
1559 1559
    surface->width = width;
1560 1560
    surface->height = height;
1561
    surface->linesize = linesize;
1562
    surface->pf = qemu_default_pixelformat(bpp);
1561
    surface->linesize = width * 4;
1562
    surface->pf = qemu_default_pixelformat(32);
1563 1563
#ifdef WORDS_BIGENDIAN
1564 1564
    surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
1565 1565
#else
......
1570 1570
    return surface;
1571 1571
}
1572 1572

  
1573
DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface,
1574
                                          int width, int height, int bpp, int linesize)
1573
DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface,
1574
                                          int width, int height)
1575 1575
{
1576 1576
    surface->width = width;
1577 1577
    surface->height = height;
1578
    surface->linesize = linesize;
1579
    surface->pf = qemu_default_pixelformat(bpp);
1578
    surface->linesize = width * 4;
1579
    surface->pf = qemu_default_pixelformat(32);
1580 1580
    if (surface->flags & QEMU_ALLOCATED_FLAG)
1581 1581
        surface->data = (uint8_t*) qemu_realloc(surface->data, surface->linesize * surface->height);
1582 1582
    else
......
1607 1607
    return surface;
1608 1608
}
1609 1609

  
1610
void qemu_free_displaysurface(DisplaySurface *surface)
1610
void defaultallocator_free_displaysurface(DisplaySurface *surface)
1611 1611
{
1612 1612
    if (surface == NULL)
1613 1613
        return;
b/console.h
113 113
    struct DisplayChangeListener *next;
114 114
};
115 115

  
116
struct DisplayAllocator {
117
    DisplaySurface* (*create_displaysurface)(int width, int height);
118
    DisplaySurface* (*resize_displaysurface)(DisplaySurface *surface, int width, int height);
119
    void (*free_displaysurface)(DisplaySurface *surface);
120
};
121

  
116 122
struct DisplayState {
117 123
    struct DisplaySurface *surface;
118 124
    void *opaque;
119 125
    struct QEMUTimer *gui_timer;
120 126

  
127
    struct DisplayAllocator* allocator;
121 128
    struct DisplayChangeListener* listeners;
122 129

  
123 130
    void (*mouse_set)(int x, int y, int on);
......
129 136

  
130 137
void register_displaystate(DisplayState *ds);
131 138
DisplayState *get_displaystate(void);
132
DisplaySurface* qemu_create_displaysurface(int width, int height, int bpp, int linesize);
133
DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface,
134
                                           int width, int height, int bpp, int linesize);
135 139
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
136 140
                                                int linesize, uint8_t *data);
137
void qemu_free_displaysurface(DisplaySurface *surface);
138 141
PixelFormat qemu_different_endianness_pixelformat(int bpp);
139 142
PixelFormat qemu_default_pixelformat(int bpp);
140 143

  
144
extern struct DisplayAllocator default_allocator;
145
DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da);
146
DisplaySurface* defaultallocator_create_displaysurface(int width, int height);
147
DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface, int width, int height);
148
void defaultallocator_free_displaysurface(DisplaySurface *surface);
149

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

  
155
static inline DisplaySurface* qemu_resize_displaysurface(DisplayState *ds, int width, int height)
156
{
157
    return ds->allocator->resize_displaysurface(ds->surface, width, height);
158
}
159

  
160
static inline void qemu_free_displaysurface(DisplayState *ds)
161
{
162
    ds->allocator->free_displaysurface(ds->surface);
163
}
164

  
165
static inline int is_surface_bgr(DisplaySurface *surface)
166
{
167
    if (surface->pf.bits_per_pixel == 32 && surface->pf.rshift == 0)
168
        return 1;
169
    else
170
        return 0;
171
}
172

  
141 173
static inline int is_buffer_shared(DisplaySurface *surface)
142 174
{
143 175
    return (!(surface->flags & QEMU_ALLOCATED_FLAG));
b/curses.c
364 364
    dcl->dpy_refresh = curses_refresh;
365 365
    dcl->dpy_text_cursor = curses_cursor_position;
366 366
    register_displaychangelistener(ds, dcl);
367
    qemu_free_displaysurface(ds->surface);
367
    qemu_free_displaysurface(ds);
368 368
    ds->surface = qemu_create_displaysurface_from(640, 400, 0, 0, (uint8_t*) screen);
369 369

  
370 370
    invalidate = 1;
b/hw/musicpal.c
831 831
        break;
832 832
    LCD_REFRESH(8, rgb_to_pixel8)
833 833
    LCD_REFRESH(16, rgb_to_pixel16)
834
    LCD_REFRESH(32, rgb_to_pixel32)
834
    LCD_REFRESH(32, (is_surface_bgr(s->ds) ? rgb_to_pixel32bgr : rgb_to_pixel32))
835 835
    default:
836 836
        cpu_abort(cpu_single_env, "unsupported colour depth %i\n",
837 837
                  ds_get_bits_per_pixel(s->ds));
b/hw/nseries.c
1362 1362
       will set the size once configured, so this just sets an initial
1363 1363
       size until the guest activates the display.  */
1364 1364
    ds = get_displaystate();
1365
    ds->surface = qemu_resize_displaysurface(ds->surface, 800, 480, 32, 4 * 800);
1365
    ds->surface = qemu_resize_displaysurface(ds, 800, 480);
1366 1366
    dpy_resize(ds);
1367 1367
}
1368 1368

  
b/hw/palm.c
278 278
    /* FIXME: We shouldn't really be doing this here.  The LCD controller
279 279
       will set the size once configured, so this just sets an initial
280 280
       size until the guest activates the display.  */
281
    ds->surface = qemu_resize_displaysurface(ds->surface, 320, 320, 32, 4 * 320);
281
    ds->surface = qemu_resize_displaysurface(ds, 320, 320);
282 282
    dpy_resize(ds);
283 283
}
284 284

  
b/hw/sm501.c
948 948
    case 16:
949 949
        return 2;
950 950
    case 32:
951
        return 3;
951
	if (is_surface_bgr(s->surface))
952
	    return 4;
953
	else
954
	    return 3;
952 955
    }
953 956
}
954 957

  
b/hw/tcx.c
66 66
            s->palette[i] = rgb_to_pixel16(s->r[i], s->g[i], s->b[i]);
67 67
            break;
68 68
        case 32:
69
            s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
69
            if (is_surface_bgr(s->ds->surface))
70
                s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]);
71
            else
72
                s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
70 73
            break;
71 74
        }
72 75
    }
......
124 127
                                     const uint32_t *cplane,
125 128
                                     const uint32_t *s24)
126 129
{
127
    int x, r, g, b;
130
    int x, bgr, r, g, b;
128 131
    uint8_t val, *p8;
129 132
    uint32_t *p = (uint32_t *)d;
130 133
    uint32_t dval;
131 134

  
135
    bgr = is_surface_bgr(s1->ds->surface);
132 136
    for(x = 0; x < width; x++, s++, s24++) {
133 137
        if ((be32_to_cpu(*cplane++) & 0xff000000) == 0x03000000) {
134 138
            // 24-bit direct, BGR order
......
137 141
            b = *p8++;
138 142
            g = *p8++;
139 143
            r = *p8++;
140
            dval = rgb_to_pixel32(r, g, b);
144
            if (bgr)
145
                dval = rgb_to_pixel32bgr(r, g, b);
146
            else
147
                dval = rgb_to_pixel32(r, g, b);
141 148
        } else {
142 149
            val = *s;
143 150
            dval = s1->palette[val];
b/hw/vga.c
1161 1161
    case 16:
1162 1162
        return 2;
1163 1163
    case 32:
1164
        return 3;
1164
        if (is_surface_bgr(s->surface))
1165
            return 4;
1166
        else
1167
            return 3;
1165 1168
    }
1166 1169
}
1167 1170

  
......
1627 1630
        if (depth == 32) {
1628 1631
#endif
1629 1632
            if (is_graphic_console()) {
1630
                qemu_free_displaysurface(s->ds->surface);
1633
                qemu_free_displaysurface(s->ds);
1631 1634
                s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth,
1632 1635
                                                               s->line_offset,
1633 1636
                                                               s->vram_ptr + (s->start_addr * 4));
......
2619 2622
    dcl.dpy_resize = vga_save_dpy_resize;
2620 2623
    dcl.dpy_refresh = vga_save_dpy_refresh;
2621 2624
    register_displaychangelistener(ds, &dcl);
2622
    ds->surface = qemu_create_displaysurface(w, h, 32, 4 * w);
2625
    ds->surface = qemu_create_displaysurface(ds, w, h);
2623 2626

  
2624 2627
    s->ds = ds;
2625 2628
    s->graphic_mode = -1;
......
2627 2630

  
2628 2631
    ppm_save(filename, ds->surface);
2629 2632

  
2630
    qemu_free_displaysurface(ds->surface);
2633
    qemu_free_displaysurface(ds);
2631 2634
    s->ds = saved_ds;
2632 2635
}
2633 2636

  
b/qemu-common.h
162 162
typedef struct DisplayState DisplayState;
163 163
typedef struct DisplayChangeListener DisplayChangeListener;
164 164
typedef struct DisplaySurface DisplaySurface;
165
typedef struct DisplayAllocator DisplayAllocator;
165 166
typedef struct PixelFormat PixelFormat;
166 167
typedef struct TextConsole TextConsole;
167 168
typedef TextConsole QEMUConsole;
b/sdl.c
53 53
static int guest_cursor = 0;
54 54
static int guest_x, guest_y;
55 55
static SDL_Cursor *guest_sprite = 0;
56
static uint8_t allocator;
57
static uint8_t hostbpp;
56 58

  
57 59
static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
58 60
{
59
    SDL_Rect rec;
60
    rec.x = x;
61
    rec.y = y;
62
    rec.w = w;
63
    rec.h = h;
64 61
    //    printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
65

  
66
    SDL_BlitSurface(guest_screen, &rec, real_screen, &rec);
62
    if (guest_screen) {
63
        SDL_Rect rec;
64
        rec.x = x;
65
        rec.y = y;
66
        rec.w = w;
67
        rec.h = h;
68
        SDL_BlitSurface(guest_screen, &rec, real_screen, &rec);
69
    }
67 70
    SDL_UpdateRect(real_screen, x, y, w, h);
68 71
}
69 72

  
......
83 86
                                            ds->surface->pf.bmask, ds->surface->pf.amask);
84 87
}
85 88

  
86
static void sdl_resize(DisplayState *ds)
89
static void do_sdl_resize(int width, int height, int bpp)
87 90
{
88 91
    int flags;
89 92

  
......
95 98
    if (gui_noframe)
96 99
        flags |= SDL_NOFRAME;
97 100

  
98
    width = ds_get_width(ds);
99
    height = ds_get_height(ds);
100
    real_screen = SDL_SetVideoMode(width, height, 0, flags);
101
    real_screen = SDL_SetVideoMode(width, height, bpp, flags);
101 102
    if (!real_screen) {
102 103
        fprintf(stderr, "Could not open SDL display\n");
103 104
        exit(1);
104 105
    }
106
}
107

  
108
static void sdl_resize(DisplayState *ds)
109
{
110
    if  (!allocator) {
111
        do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
112
        sdl_setdata(ds);
113
    } else {
114
        if (guest_screen != NULL) {
115
            SDL_FreeSurface(guest_screen);
116
            guest_screen = NULL;
117
        }
118
    }
119
}
120

  
121
static PixelFormat sdl_to_qemu_pixelformat(SDL_PixelFormat *sdl_pf)
122
{
123
    PixelFormat qemu_pf;
124

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

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

  
131
    qemu_pf.rmask = sdl_pf->Rmask;
132
    qemu_pf.gmask = sdl_pf->Gmask;
133
    qemu_pf.bmask = sdl_pf->Bmask;
134
    qemu_pf.amask = sdl_pf->Amask;
135

  
136
    qemu_pf.rshift = sdl_pf->Rshift;
137
    qemu_pf.gshift = sdl_pf->Gshift;
138
    qemu_pf.bshift = sdl_pf->Bshift;
139
    qemu_pf.ashift = sdl_pf->Ashift;
140

  
141
    qemu_pf.rbits = 8 - sdl_pf->Rloss;
142
    qemu_pf.gbits = 8 - sdl_pf->Gloss;
143
    qemu_pf.bbits = 8 - sdl_pf->Bloss;
144
    qemu_pf.abits = 8 - sdl_pf->Aloss;
145

  
146
    qemu_pf.rmax = ((1 << qemu_pf.rbits) - 1);
147
    qemu_pf.gmax = ((1 << qemu_pf.gbits) - 1);
148
    qemu_pf.bmax = ((1 << qemu_pf.bbits) - 1);
149
    qemu_pf.amax = ((1 << qemu_pf.abits) - 1);
150

  
151
    return qemu_pf;
152
}
153

  
154
static DisplaySurface* sdl_create_displaysurface(int width, int height)
155
{
156
    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
157
    if (surface == NULL) {
158
        fprintf(stderr, "sdl_create_displaysurface: malloc failed\n");
159
        exit(1);
160
    }
161

  
162
    surface->width = width;
163
    surface->height = height;
105 164

  
106
    sdl_setdata(ds);
165
    if (hostbpp == 16)
166
        do_sdl_resize(width, height, 16);
167
    else
168
        do_sdl_resize(width, height, 32);
169

  
170
    surface->pf = sdl_to_qemu_pixelformat(real_screen->format);
171
    surface->linesize = real_screen->pitch;
172
    surface->data = real_screen->pixels;
173

  
174
#ifdef WORDS_BIGENDIAN
175
    surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
176
#else
177
    surface->flags = QEMU_ALLOCATED_FLAG;
178
#endif
179
    allocator = 1;
180

  
181
    return surface;
182
}
183

  
184
static void sdl_free_displaysurface(DisplaySurface *surface)
185
{
186
    allocator = 0;
187
    if (surface == NULL)
188
        return;
189
    qemu_free(surface);
190
}
191

  
192
static DisplaySurface* sdl_resize_displaysurface(DisplaySurface *surface, int width, int height)
193
{
194
    sdl_free_displaysurface(surface);
195
    return sdl_create_displaysurface(width, height);
107 196
}
108 197

  
109 198
/* generic keyboard conversion */
......
391 480
static void toggle_full_screen(DisplayState *ds)
392 481
{
393 482
    gui_fullscreen = !gui_fullscreen;
394
    sdl_resize(ds);
483
    do_sdl_resize(real_screen->w, real_screen->h, real_screen->format->BitsPerPixel);
395 484
    if (gui_fullscreen) {
396 485
        gui_saved_grab = gui_grab;
397 486
        sdl_grab_start();
......
669 758
{
670 759
    int flags;
671 760
    uint8_t data = 0;
761
    DisplayAllocator *da;
762
    const SDL_VideoInfo *vi;
672 763

  
673 764
#if defined(__APPLE__)
674 765
    /* always use generic keymaps */
......
689 780
        fprintf(stderr, "Could not initialize SDL - exiting\n");
690 781
        exit(1);
691 782
    }
783
    vi = SDL_GetVideoInfo();
784
    hostbpp = vi->vfmt->BitsPerPixel;
692 785

  
693 786
    dcl = qemu_mallocz(sizeof(DisplayChangeListener));
694 787
    dcl->dpy_update = sdl_update;
......
700 793
    ds->cursor_define = sdl_mouse_define;
701 794
    register_displaychangelistener(ds, dcl);
702 795

  
796
    da = qemu_mallocz(sizeof(DisplayAllocator));
797
    da->create_displaysurface = sdl_create_displaysurface;
798
    da->resize_displaysurface = sdl_resize_displaysurface;
799
    da->free_displaysurface = sdl_free_displaysurface;
800
    if (register_displayallocator(ds, da) == da) {
801
        DisplaySurface *surf;
802
        surf = sdl_create_displaysurface(ds_get_width(ds), ds_get_height(ds));
803
        defaultallocator_free_displaysurface(ds->surface);
804
        ds->surface = surf;
805
        dpy_resize(ds);
806
    }
807

  
703 808
    sdl_update_caption();
704 809
    SDL_EnableKeyRepeat(250, 50);
705 810
    gui_grab = 0;
b/vl.c
2874 2874
/***********************************************************/
2875 2875
/* register display */
2876 2876

  
2877
struct DisplayAllocator default_allocator = {
2878
    defaultallocator_create_displaysurface,
2879
    defaultallocator_resize_displaysurface,
2880
    defaultallocator_free_displaysurface
2881
};
2882

  
2877 2883
void register_displaystate(DisplayState *ds)
2878 2884
{
2879 2885
    DisplayState **s;
......
2889 2895
    return display_state;
2890 2896
}
2891 2897

  
2898
DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
2899
{
2900
    if(ds->allocator ==  &default_allocator) ds->allocator = da;
2901
    return ds->allocator;
2902
}
2903

  
2892 2904
/* dumb display */
2893 2905

  
2894 2906
static void dumb_display_init(void)
2895 2907
{
2896 2908
    DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
2897
    ds->surface = qemu_create_displaysurface(640, 480, 32, 640 * 4);
2909
    ds->allocator = &default_allocator;
2910
    ds->surface = qemu_create_displaysurface(ds, 640, 480);
2898 2911
    register_displaystate(ds);
2899 2912
}
2900 2913

  

Also available in: Unified diff