Ticket #1801: mplayer_vdpau-surface.diff

File mplayer_vdpau-surface.diff, 8.5 KB (added by h.mth@…, 16 years ago)

use only one surface

  • libvo/vo_vdpau.c

    old new  
    8080#define PALETTE_SIZE 256
    8181
    8282/* Initial maximum number of EOSD surfaces */
    83 #define EOSD_SURFACES_INITIAL 512
     83#define EOSD_SURFACES_INITIAL 4
    8484
    8585/*
    8686 * Global variable declaration - VDPAU specific
     
    193193    char in_use;
    194194} *eosd_surfaces;
    195195
    196 // List of surfaces to be rendered
     196// List of glyphs to be rendered
    197197struct {
    198198    VdpBitmapSurface surface;
    199199    VdpRect source;
     
    857857static void generate_eosd(EOSD_ImageList *imgs)
    858858{
    859859    VdpStatus vdp_st;
    860     VdpRect destRect;
     860    VdpRect vdp_surface_rect;
     861    static int eosd_render_size = 0;
    861862    int j, found;
    862863    ASS_Image *img = imgs->imgs;
    863864    ASS_Image *i;
     
    865866    // Nothing changed, no need to redraw
    866867    if (imgs->changed == 0)
    867868        return;
     869
     870    // Hide eosd again ...
    868871    eosd_render_count = 0;
     872
    869873    // There's nothing to render!
    870874    if (!img)
    871875        return;
     
    876880    for (j = 0; j < eosd_surface_count; j++)
    877881        eosd_surfaces[j].in_use = 0;
    878882
    879     for (i = img; i; i = i->next) {
    880         // Try to reuse a suitable surface
    881         found = -1;
     883    // initialize surface rect
     884    vdp_surface_rect.x0 = img->dst_x;
     885    vdp_surface_rect.y0 = img->dst_y;
     886    vdp_surface_rect.x1 = img->dst_x + img->w;
     887    vdp_surface_rect.y1 = img->dst_y + img->h;
     888
     889    // get surface rect
     890    eosd_render_count = 1;
     891    for (i = img->next; i; i = i->next) {
     892        if (i->dst_x < vdp_surface_rect.x0)
     893            vdp_surface_rect.x0 = i->dst_x;
     894
     895        if (i->dst_y < vdp_surface_rect.y0)
     896            vdp_surface_rect.y0 = i->dst_y;
     897
     898        if ((i->dst_x + i->w) > vdp_surface_rect.x1)
     899            vdp_surface_rect.x1 = i->dst_x + i->w;
     900
     901        if ((i->dst_y + i->h) > vdp_surface_rect.y1)
     902            vdp_surface_rect.y1 = i->dst_y + i->h;
     903
     904        // get render count
     905        eosd_render_count++;
     906    }
     907
     908    // shift: x0/y0 => offset, x1/y1 => w,h
     909    vdp_surface_rect.x1 -= vdp_surface_rect.x0 - 1;
     910    vdp_surface_rect.y1 -= vdp_surface_rect.y0 - 1;
     911
     912    // Try to reuse a suitable surface
     913    found = -1;
     914    for (j = 0; j < eosd_surface_count; j++) {
     915        if (eosd_surfaces[j].surface != VDP_INVALID_HANDLE && !eosd_surfaces[j].in_use &&
     916            eosd_surfaces[j].w >= vdp_surface_rect.x1 && eosd_surfaces[j].h >= vdp_surface_rect.y1) {
     917            found = j;
     918            break;
     919        }
     920    }
     921
     922    // None found, allocate a new surface
     923    if (found < 0) {
    882924        for (j = 0; j < eosd_surface_count; j++) {
    883             if (eosd_surfaces[j].surface != VDP_INVALID_HANDLE && !eosd_surfaces[j].in_use &&
    884                 eosd_surfaces[j].w >= i->w && eosd_surfaces[j].h >= i->h) {
     925            if (!eosd_surfaces[j].in_use) {
     926                if (eosd_surfaces[j].surface != VDP_INVALID_HANDLE)
     927                    vdp_bitmap_surface_destroy(eosd_surfaces[j].surface);
    885928                found = j;
    886929                break;
    887930            }
    888931        }
    889         // None found, allocate a new surface
     932        // Allocate new space for surface arrays
    890933        if (found < 0) {
    891             for (j = 0; j < eosd_surface_count; j++) {
    892                 if (!eosd_surfaces[j].in_use) {
    893                     if (eosd_surfaces[j].surface != VDP_INVALID_HANDLE)
    894                         vdp_bitmap_surface_destroy(eosd_surfaces[j].surface);
    895                     found = j;
    896                     break;
    897                 }
    898             }
    899             // Allocate new space for surface/target arrays
    900             if (found < 0) {
    901                 j = found = eosd_surface_count;
    902                 eosd_surface_count = eosd_surface_count ? eosd_surface_count*2 : EOSD_SURFACES_INITIAL;
    903                 eosd_surfaces = realloc(eosd_surfaces, eosd_surface_count * sizeof(*eosd_surfaces));
    904                 eosd_targets  = realloc(eosd_targets,  eosd_surface_count * sizeof(*eosd_targets));
    905                 for (j = found; j < eosd_surface_count; j++) {
    906                     eosd_surfaces[j].surface = VDP_INVALID_HANDLE;
    907                     eosd_surfaces[j].in_use = 0;
    908                 }
     934            j = found = eosd_surface_count;
     935            eosd_surface_count = eosd_surface_count ? eosd_surface_count*2 : EOSD_SURFACES_INITIAL;
     936            eosd_surfaces = realloc(eosd_surfaces, eosd_surface_count * sizeof(*eosd_surfaces));
     937            for (j = found; j < eosd_surface_count; j++) {
     938                eosd_surfaces[j].surface = VDP_INVALID_HANDLE;
     939                eosd_surfaces[j].in_use = 0;
    909940            }
    910             vdp_st = vdp_bitmap_surface_create(vdp_device, VDP_RGBA_FORMAT_A8,
    911                 i->w, i->h, VDP_TRUE, &eosd_surfaces[found].surface);
    912             CHECK_ST_WARNING("EOSD: error when creating surface")
    913             eosd_surfaces[found].w = i->w;
    914             eosd_surfaces[found].h = i->h;
    915941        }
    916         eosd_surfaces[found].in_use = 1;
     942        vdp_st = vdp_bitmap_surface_create(vdp_device, VDP_RGBA_FORMAT_A8,
     943            vdp_surface_rect.x1, vdp_surface_rect.y1, VDP_TRUE, &eosd_surfaces[found].surface);
     944        CHECK_ST_WARNING("EOSD: error when creating surface")
     945        eosd_surfaces[found].w = vdp_surface_rect.x1;
     946        eosd_surfaces[found].h = vdp_surface_rect.y1;
     947    }
     948
     949    eosd_surfaces[found].in_use = 1;
     950
     951    printf ("surface: n:%d w:%d h:%d x:%d y:%d ...\n", found, vdp_surface_rect.x1, vdp_surface_rect.y1, vdp_surface_rect.x0, vdp_surface_rect.y0);
     952
     953    // Allocate new space for target arrays
     954    if (eosd_render_size < eosd_render_count) {
     955        eosd_render_size = eosd_render_count;
     956
     957        eosd_targets  = realloc(eosd_targets, eosd_render_count * sizeof(*eosd_targets));
     958    }
     959
     960    eosd_render_count = 0;
     961    for (i = img; i; i = i->next) {
    917962        eosd_targets[eosd_render_count].surface = eosd_surfaces[found].surface;
    918         destRect.x0 = 0;
    919         destRect.y0 = 0;
    920         destRect.x1 = i->w;
    921         destRect.y1 = i->h;
     963        eosd_targets[eosd_render_count].source.x0 = i->dst_x - vdp_surface_rect.x0 + 1;
     964        eosd_targets[eosd_render_count].source.y0 = i->dst_y - vdp_surface_rect.y0 + 1;
     965        eosd_targets[eosd_render_count].source.x1 = eosd_targets[eosd_render_count].source.x0 + i->w;
     966        eosd_targets[eosd_render_count].source.y1 = eosd_targets[eosd_render_count].source.y0 + i->h;
     967
     968        printf ("rect: w:%d h:%d x:%d y:%d ...\n", i->w, i->h, eosd_targets[eosd_render_count].source.x0, eosd_targets[eosd_render_count].source.y0 );
     969
    922970        vdp_st = vdp_bitmap_surface_putbits_native(eosd_targets[eosd_render_count].surface,
    923             (const void *) &i->bitmap, &i->stride, &destRect);
     971            (const void *) &i->bitmap, &i->stride, &eosd_targets[eosd_render_count].source);
    924972        CHECK_ST_WARNING("EOSD: putbits failed")
    925973        eosd_render_count++;
    926974    }
     
    928976eosd_skip_upload:
    929977    eosd_render_count = 0;
    930978    for (i = img; i; i = i->next) {
    931         // Render dest, color, etc.
     979        // Render dest and color only
    932980        eosd_targets[eosd_render_count].color.alpha = 1.0 - ((i->color >>  0) & 0xff) / 255.0;
    933981        eosd_targets[eosd_render_count].color.blue  =       ((i->color >>  8) & 0xff) / 255.0;
    934982        eosd_targets[eosd_render_count].color.green =       ((i->color >> 16) & 0xff) / 255.0;
    935983        eosd_targets[eosd_render_count].color.red   =       ((i->color >> 24) & 0xff) / 255.0;
     984
     985        printf ("color: r:%f g:%f b:%f a:%f ...\n", eosd_targets[eosd_render_count].color.red, eosd_targets[eosd_render_count].color.green, eosd_targets[eosd_render_count].color.blue, eosd_targets[eosd_render_count].color.alpha);
     986
    936987        eosd_targets[eosd_render_count].dest.x0     =        i->dst_x;
    937988        eosd_targets[eosd_render_count].dest.y0     =        i->dst_y;
    938989        eosd_targets[eosd_render_count].dest.x1     = i->w + i->dst_x;
    939990        eosd_targets[eosd_render_count].dest.y1     = i->h + i->dst_y;
    940         eosd_targets[eosd_render_count].source.x0   = 0;
    941         eosd_targets[eosd_render_count].source.y0   = 0;
    942         eosd_targets[eosd_render_count].source.x1   = i->w;
    943         eosd_targets[eosd_render_count].source.y1   = i->h;
     991        //eosd_targets[eosd_render_count].source.x0   = i->dst_x - vdp_surface_rect.x0 + 1;
     992        //eosd_targets[eosd_render_count].source.y0   = i->dst_y - vdp_surface_rect.y0 + 1;
     993        //eosd_targets[eosd_render_count].source.x1   = eosd_targets[eosd_render_count].source.x0 + i->w;
     994        //eosd_targets[eosd_render_count].source.y1   = eosd_targets[eosd_render_count].source.y1 + i->h;
    944995        eosd_render_count++;
    945996    }
    946997}