Ticket #1801: mplayer_vdpau-surface.2.diff
| File mplayer_vdpau-surface.2.diff, 10.1 KB (added by , 16 years ago) |
|---|
-
libvo/vo_vdpau.c
old new 79 79 /* number of palette entries */ 80 80 #define PALETTE_SIZE 256 81 81 82 /* Initial maximum number of EOSD surfaces */ 83 #define EOSD_SURFACES_INITIAL 512 82 /* Initial maximum number of EOSD surfaces - this should already be more than enough */ 83 #define EOSD_SURFACES_INITIAL 16 84 85 /* Maximum size of vdpau bitmap surface */ 86 #define VDPAU_BITMAP_SURFACE_MAXSIZE 8192 84 87 85 88 /* 86 89 * Global variable declaration - VDPAU specific … … 188 191 // Pool of surfaces 189 192 struct { 190 193 VdpBitmapSurface surface; 191 int w;192 int h;193 charin_use;194 unsigned int w; 195 unsigned int h; 196 unsigned short in_use; 194 197 } *eosd_surfaces; 195 198 196 // List of surfaces to be rendered199 // List of glyphs to be rendered 197 200 struct { 198 201 VdpBitmapSurface surface; 199 202 VdpRect source; … … 201 204 VdpColor color; 202 205 } *eosd_targets; 203 206 207 // counters 204 208 static int eosd_render_count; 205 209 static int eosd_surface_count; 206 210 211 // sizes 212 static int eosd_render_size; 213 207 214 // Video equalizer 208 215 static VdpProcamp procamp; 209 216 … … 854 861 } 855 862 } 856 863 864 static int eosd_invalidGlyph(ASS_Image* i) 865 { 866 // Invalid bitmap sizes 867 if (i->w < 0 || i->h < 0 || i->stride < 0 868 || i->w > VDPAU_BITMAP_SURFACE_MAXSIZE 869 || i->h > VDPAU_BITMAP_SURFACE_MAXSIZE) 870 return -1; 871 return 0; 872 } 873 857 874 static void generate_eosd(EOSD_ImageList *imgs) 858 875 { 859 876 VdpStatus vdp_st; 860 VdpRect destRect;861 int j, found ;877 VdpRect vdp_surface_rect; 878 int j, found, start_x; 862 879 ASS_Image *img = imgs->imgs; 863 880 ASS_Image *i; 881 ASS_Image *i_prev; 864 882 865 883 // Nothing changed, no need to redraw 866 884 if (imgs->changed == 0) 867 885 return; 886 887 // Hide eosd again ... 868 888 eosd_render_count = 0; 889 869 890 // There's nothing to render! 870 891 if (!img) 871 892 return; … … 873 894 if (imgs->changed == 1) 874 895 goto eosd_skip_upload; 875 896 876 for (j = 0; j < eosd_surface_count; j++) 897 // OPTIONAL: No need to try to reuse - simplification 898 for (j = 0; j < eosd_surface_count; j++) { 877 899 eosd_surfaces[j].in_use = 0; 900 //if (eosd_surfaces[j].surface != VDP_INVALID_HANDLE) { 901 // vdp_bitmap_surface_destroy(eosd_surfaces[j].surface); 902 // CHECK_ST_WARNING("Error when calling vdp_bitmap_surface_destroy") 903 // eosd_surfaces[j].surface = VDP_INVALID_HANDLE; 904 //} 905 } 906 907 // Initialize handling of surfaces 908 found = 0; 909 vdp_surface_rect.x1 = 0; 910 vdp_surface_rect.y1 = 0; 878 911 879 912 for (i = img; i; i = i->next) { 880 // Try to reuse a suitable surface 881 found = -1; 882 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) { 885 found = j; 886 break; 887 } 913 if (eosd_invalidGlyph (i)) 914 continue; 915 916 // Create bitmap surface and restart with current glyph 917 if (vdp_surface_rect.x1 + i->w > VDPAU_BITMAP_SURFACE_MAXSIZE) { 918 i = i_prev; 919 920 // Collect glyphs for one surface 921 } else { 922 // Get render count 923 eosd_render_count++; 924 925 i_prev = i; 926 vdp_surface_rect.x1 += i->w; 927 928 if (i->h > vdp_surface_rect.y1) 929 vdp_surface_rect.y1 = i->h; 930 if (i->next) 931 continue; 888 932 } 889 // None found, allocate a new surface 890 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 }933 934 // Allocate new space for surface arrays 935 if (eosd_surface_count <= found) { 936 j = eosd_surface_count; 937 eosd_surface_count = eosd_surface_count ? eosd_surface_count*2 : EOSD_SURFACES_INITIAL; 938 eosd_surfaces = realloc(eosd_surfaces, eosd_surface_count * sizeof(*eosd_surfaces)); 939 for (; j < eosd_surface_count; j++) { 940 eosd_surfaces[j].surface = VDP_INVALID_HANDLE; 941 eosd_surfaces[j].in_use = 0; 898 942 } 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 } 943 } 944 945 // OPTIONAL: No need to try to reuse - simplification 946 if (eosd_surfaces[found].surface == VDP_INVALID_HANDLE || 947 eosd_surfaces[found].w < vdp_surface_rect.x1 || eosd_surfaces[found].h < vdp_surface_rect.y1) { 948 // Destroy surface 949 if (eosd_surfaces[found].surface != VDP_INVALID_HANDLE) { 950 vdp_bitmap_surface_destroy(eosd_surfaces[found].surface); 951 CHECK_ST_WARNING("Error when calling vdp_bitmap_surface_destroy") 952 953 // Increase w or h only - relax oscillation 954 vdp_surface_rect.x1 = (vdp_surface_rect.x1 < eosd_surfaces[found].w) ? eosd_surfaces[found].w : vdp_surface_rect.x1; 955 vdp_surface_rect.y1 = (vdp_surface_rect.y1 < eosd_surfaces[found].h) ? eosd_surfaces[found].h : vdp_surface_rect.y1; 909 956 } 957 958 // Create bigger surface 910 959 vdp_st = vdp_bitmap_surface_create(vdp_device, VDP_RGBA_FORMAT_A8, 911 i->w, i->h, VDP_TRUE, &eosd_surfaces[found].surface);960 vdp_surface_rect.x1, vdp_surface_rect.y1, VDP_TRUE, &eosd_surfaces[found].surface); 912 961 CHECK_ST_WARNING("EOSD: error when creating surface") 913 eosd_surfaces[found].w = i->w; 914 eosd_surfaces[found].h = i->h; 962 eosd_surfaces[found].w = vdp_surface_rect.x1; 963 eosd_surfaces[found].h = vdp_surface_rect.y1; 964 965 //printf ("surface: n:%d w:%d h:%d c:%d ...\n", found, vdp_surface_rect.x1, vdp_surface_rect.y1, eosd_render_count); 915 966 } 916 eosd_surfaces[found].in_use = 1; 967 968 eosd_surfaces[found].in_use = eosd_render_count; 969 970 // Set surface data 971 vdp_surface_rect.x1 = 0; 972 vdp_surface_rect.y1 = 0; 973 974 // Get surface count 975 found++; 976 } 977 978 // Allocate new space for target arrays 979 if (eosd_render_size < eosd_render_count) { 980 eosd_render_size = eosd_render_count; 981 982 eosd_targets = realloc(eosd_targets, eosd_render_count * sizeof(*eosd_targets)); 983 } 984 985 start_x = 0; 986 found = 0; 987 eosd_render_count = 0; 988 989 for (i = img; i; i = i->next) { 990 if (eosd_invalidGlyph (i)) 991 continue; 992 993 if (eosd_render_count == eosd_surfaces[found].in_use) { 994 found++; 995 start_x = 0; 996 } 997 917 998 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; 999 eosd_targets[eosd_render_count].source.x0 = start_x; 1000 eosd_targets[eosd_render_count].source.y0 = 0; 1001 eosd_targets[eosd_render_count].source.x1 = start_x + i->w; 1002 eosd_targets[eosd_render_count].source.y1 = i->h; 1003 1004 //printf ("rect: n:%d w:%d h:%d x:%d y:%d ...\n", found, i->w, i->h, eosd_targets[eosd_render_count].source.x0, eosd_targets[eosd_render_count].source.y0 ); 1005 922 1006 vdp_st = vdp_bitmap_surface_putbits_native(eosd_targets[eosd_render_count].surface, 923 (const void *) &i->bitmap, &i->stride, & destRect);1007 (const void *) &i->bitmap, &i->stride, &eosd_targets[eosd_render_count].source); 924 1008 CHECK_ST_WARNING("EOSD: putbits failed") 1009 1010 start_x += i->w; 925 1011 eosd_render_count++; 926 1012 } 927 1013 928 1014 eosd_skip_upload: 929 1015 eosd_render_count = 0; 930 1016 for (i = img; i; i = i->next) { 931 // Render dest, color, etc. 1017 if (eosd_invalidGlyph (i)) 1018 continue; 1019 1020 // Render dest and color only 932 1021 eosd_targets[eosd_render_count].color.alpha = 1.0 - ((i->color >> 0) & 0xff) / 255.0; 933 1022 eosd_targets[eosd_render_count].color.blue = ((i->color >> 8) & 0xff) / 255.0; 934 1023 eosd_targets[eosd_render_count].color.green = ((i->color >> 16) & 0xff) / 255.0; 935 1024 eosd_targets[eosd_render_count].color.red = ((i->color >> 24) & 0xff) / 255.0; 936 eosd_targets[eosd_render_count].dest.x0 = i->dst_x; 937 eosd_targets[eosd_render_count].dest.y0 = i->dst_y; 938 eosd_targets[eosd_render_count].dest.x1 = i->w + i->dst_x; 939 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; 1025 1026 //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); 1027 1028 eosd_targets[eosd_render_count].dest.x0 = i->dst_x; 1029 eosd_targets[eosd_render_count].dest.y0 = i->dst_y; 1030 eosd_targets[eosd_render_count].dest.x1 = i->dst_x + i->w; 1031 eosd_targets[eosd_render_count].dest.y1 = i->dst_y + i->h; 944 1032 eosd_render_count++; 945 1033 } 946 1034 } … … 1269 1357 index_data_size = 0; 1270 1358 1271 1359 eosd_surface_count = eosd_render_count = 0; 1360 eosd_render_size = 0; 1272 1361 eosd_surfaces = NULL; 1273 1362 eosd_targets = NULL; 1274 1363
