commit d6db2682feb94220e6ccb266976816314ee69368 Author: greg Date: Wed Feb 25 08:06:29 2009 +0100 More efficient BitmapSurface handling. diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c index 04df788..4107a48 100644 --- a/libvo/vo_vdpau.c +++ b/libvo/vo_vdpau.c @@ -81,8 +81,11 @@ LIBVO_EXTERN(vdpau) /* number of palette entries */ #define PALETTE_SIZE 256 -/* Initial maximum number of EOSD surfaces */ -#define EOSD_SURFACES_INITIAL 512 +/* Initial maximum number of EOSD render targets */ +#define EOSD_TARGETS_INITIAL 512 + +/* Size of the surfaces the EOSD bitmaps will be placed into */ +#define EOSD_SURFACE_SIZE 1024 /* * Global variable declaration - VDPAU specific @@ -177,9 +180,8 @@ static uint32_t palette[PALETTE_SIZE]; // Pool of surfaces struct { VdpBitmapSurface surface; - int w; - int h; - char in_use; + int x, y; + int max_y; } *eosd_surfaces; // List of surfaces to be rendered @@ -192,6 +194,7 @@ struct { static int eosd_render_count; static int eosd_surface_count; +static int eosd_target_count; // Video equalizer static VdpProcamp procamp; @@ -645,7 +648,7 @@ static void draw_eosd(void) { static void generate_eosd(mp_eosd_images_t *imgs) { VdpStatus vdp_st; - VdpRect destRect; + VdpRect dest_rect; int j, found; ass_image_t *img = imgs->imgs; ass_image_t *i; @@ -661,54 +664,59 @@ static void generate_eosd(mp_eosd_images_t *imgs) { if (imgs->changed == 1) goto eosd_skip_upload; - for (j=0; jnext) { - // Try to reuse a suitable surface + // Find surface with enough free space found = -1; - for (j=0; j= i->w && eosd_surfaces[j].h >= i->h) { + for (j=0; jh < EOSD_SURFACE_SIZE && eosd_surfaces[j].x + i->w < EOSD_SURFACE_SIZE) + || (eosd_surfaces[j].max_y + i->h < EOSD_SURFACE_SIZE)){ found = j; break; } - } - // None found, allocate a new surface + // No free space; allocate a new surface if (found < 0) { - for (j=0; jw, i->h, VDP_TRUE, &eosd_surfaces[found].surface); + EOSD_SURFACE_SIZE, EOSD_SURFACE_SIZE, VDP_TRUE, &eosd_surfaces[found].surface); CHECK_ST_WARNING("EOSD: error when creating surface") - eosd_surfaces[found].w = i->w; - eosd_surfaces[found].h = i->h; } - eosd_surfaces[found].in_use = 1; + // Allocate new space for targets, if needed + if (eosd_render_count >= eosd_target_count) { + eosd_target_count = eosd_target_count ? eosd_target_count*2 : EOSD_TARGETS_INITIAL; + eosd_targets = realloc(eosd_targets, eosd_target_count * sizeof(*eosd_targets)); + } + // Set up render target eosd_targets[eosd_render_count].surface = eosd_surfaces[found].surface; - destRect.x0 = 0; - destRect.y0 = 0; - destRect.x1 = i->w; - destRect.y1 = i->h; - vdp_st = vdp_bitmap_surface_putbits_native(eosd_targets[eosd_render_count].surface, - (const void *) &i->bitmap, &i->stride, &destRect); + if ((eosd_surfaces[found].x + i->w) >= EOSD_SURFACE_SIZE) { + eosd_surfaces[found].y = eosd_surfaces[found].max_y; + eosd_surfaces[found].x = 0; + } + eosd_surfaces[found].max_y = FFMAX(eosd_surfaces[found].max_y, eosd_surfaces[found].y + i->h); + dest_rect.x0 = eosd_surfaces[found].x; + dest_rect.y0 = eosd_surfaces[found].y; + dest_rect.x1 = dest_rect.x0 + i->w; + dest_rect.y1 = dest_rect.y0 + i->h; + eosd_surfaces[found].x += i->w; + // Render destination and color + eosd_targets[eosd_render_count].source.x0 = dest_rect.x0; + eosd_targets[eosd_render_count].source.y0 = dest_rect.y0; + eosd_targets[eosd_render_count].source.x1 = dest_rect.x1; + eosd_targets[eosd_render_count].source.y1 = dest_rect.y1; + eosd_targets[eosd_render_count].color.alpha = 1.0 - ((i->color >> 0) & 0xff) / 255.0; + eosd_targets[eosd_render_count].color.blue = ((i->color >> 8) & 0xff) / 255.0; + eosd_targets[eosd_render_count].color.green = ((i->color >> 16) & 0xff) / 255.0; + eosd_targets[eosd_render_count].color.red = ((i->color >> 24) & 0xff) / 255.0; + vdp_st = vdp_bitmap_surface_putbits_native(eosd_surfaces[found].surface, + (const void *) &i->bitmap, &i->stride, &dest_rect); CHECK_ST_WARNING("EOSD: putbits failed") eosd_render_count++; } @@ -716,19 +724,10 @@ static void generate_eosd(mp_eosd_images_t *imgs) { eosd_skip_upload: eosd_render_count = 0; for (i = img; i; i = i->next) { - // Render dest, color, etc. - eosd_targets[eosd_render_count].color.alpha = 1.0 - ((i->color >> 0) & 0xff) / 255.0; - eosd_targets[eosd_render_count].color.blue = ((i->color >> 8) & 0xff) / 255.0; - eosd_targets[eosd_render_count].color.green = ((i->color >> 16) & 0xff) / 255.0; - eosd_targets[eosd_render_count].color.red = ((i->color >> 24) & 0xff) / 255.0; eosd_targets[eosd_render_count].dest.x0 = i->dst_x; eosd_targets[eosd_render_count].dest.y0 = i->dst_y; eosd_targets[eosd_render_count].dest.x1 = i->w + i->dst_x; eosd_targets[eosd_render_count].dest.y1 = i->h + i->dst_y; - eosd_targets[eosd_render_count].source.x0 = 0; - eosd_targets[eosd_render_count].source.y0 = 0; - eosd_targets[eosd_render_count].source.x1 = i->w; - eosd_targets[eosd_render_count].source.y1 = i->h; eosd_render_count++; } } @@ -901,11 +900,8 @@ static void DestroyVdpauObjects(void) } for (i = 0; i