comparison libvo/vo_svga.c @ 10924:f531971e44cf

blackbar osd support based on patch send by Dimitar Zhekov <jimmy@is-vn.bg>, page code removed/merged, small updates
author iive
date Sun, 21 Sep 2003 23:59:49 +0000
parents 2390fddbe581
children b99be2c88faf
comparison
equal deleted inserted replaced
10923:443a79eb48f9 10924:f531971e44cf
18 - denoise3d fails to find common colorspace, use -vf denoise3d,scale 18 - denoise3d fails to find common colorspace, use -vf denoise3d,scale
19 19
20 TODO: 20 TODO:
21 - let choose_best_mode take aspect into account 21 - let choose_best_mode take aspect into account
22 - set palette from mpi->palette or mpi->plane[1] 22 - set palette from mpi->palette or mpi->plane[1]
23 - let OSD draw in black bars - need some OSD changes 23 - make faster OSD black bars clear - need some OSD changes
24 - Make nicer CONFIG parsing 24 - Make nicer CONFIG parsing
25 - change video mode logical width to match img->stride[0] - for HW only 25 - change video mode logical width to match img->stride[0] - for HW only
26 */ 26 */
27 27
28 #include <stdio.h> 28 #include <stdio.h>
61 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, 61 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
62 unsigned char *srca, int stride); 62 unsigned char *srca, int stride);
63 static uint32_t get_image(mp_image_t *mpi); 63 static uint32_t get_image(mp_image_t *mpi);
64 64
65 #define MAXPAGES 16 65 #define MAXPAGES 16
66 #define PAGE_EMPTY 0
67 #define PAGE_BUSY 1
66 68
67 #define CAP_ACCEL_CLEAR 8 69 #define CAP_ACCEL_CLEAR 8
68 #define CAP_ACCEL_PUTIMAGE 4 70 #define CAP_ACCEL_PUTIMAGE 4
69 #define CAP_ACCEL_BACKGR 2 71 #define CAP_ACCEL_BACKGR 2
70 #define CAP_LINEAR 1 72 #define CAP_LINEAR 1
73 75
74 static int squarepix; 76 static int squarepix;
75 static int force_vm=0; 77 static int force_vm=0;
76 static int force_native=0; 78 static int force_native=0;
77 static int sync_flip=0; 79 static int sync_flip=0;
78 static int cpage=0, max_pages; 80 static int blackbar_osd=0;
81 static int cpage,max_pages,old_page;
79 82
80 static vga_modeinfo * modeinfo; 83 static vga_modeinfo * modeinfo;
81 static int mode_stride; //keep it in case of vga_setlogicalwidth 84 static int mode_stride; //keep it in case of vga_setlogicalwidth
82 static int stride_granularity; //not yet used 85 static int stride_granularity; //not yet used
83 static int mode_bpp; 86 static int mode_bpp;
84 static int mode_capabilities; 87 static int mode_capabilities;
85 88
86 static int image_width,image_height; // used by OSD 89 static int image_width,image_height; // used by OSD
87 static uint32_t x_pos, y_pos; 90 static int x_pos, y_pos;
88 91
89 static struct { 92 static struct {
90 int yoffset;//y position of the page 93 int yoffset;//y position of the page
91 int doffset;//display start of the page 94 int doffset;//display start of the page
92 void * vbase;//memory start address of the page 95 void * vbase;//memory start address of the page
96 int locks;
93 }PageStore[MAXPAGES]; 97 }PageStore[MAXPAGES];
94 98
95 static vo_info_t info = { 99 static vo_info_t info = {
96 "SVGAlib", 100 "SVGAlib",
97 "svga", 101 "svga",
103 static char vidix_name[32] = ""; 107 static char vidix_name[32] = "";
104 #endif 108 #endif
105 109
106 LIBVO_EXTERN(svga) 110 LIBVO_EXTERN(svga)
107 111
108 /* 112
109 probably this should be in separate pages.c file so 113 //return number of 1'st free page or -1 if no free one
110 all vo_drivers can use it, do it if you like it. 114 static inline int page_find_free(){
111 TODO
112 direct render with IP buffering support - for vo_tdfx_vid
113 */
114
115 #define PAGES_MAX MAXPAGES
116 #define Page_Empty 0
117 #define Page_Durty 1
118
119 static int page_locks[PAGES_MAX];
120 static int pagecurrent;
121 static int pagetoshow;
122 static int pagesmax;
123
124 static void page_init(int max){
125 int i; 115 int i;
126 for(i=0;i<max;i++){ 116 for(i=0;i<max_pages;i++)
127 page_locks[i]=0; 117 if(PageStore[i].locks == PAGE_EMPTY) return i;
128 }
129 pagetoshow=pagecurrent=0;
130 pagesmax=max;
131 }
132 //internal use function
133 //return number of 1'st free page or -1 if no free one
134 static int page_find_free(){
135 int i;
136 for(i=0;i<pagesmax;i++)
137 if(page_locks[i]==Page_Empty) return i;
138 return -1; 118 return -1;
139 } 119 }
140
141 //return the number of page we may draw directly of -1 if no such
142 static int page_get_image(){
143 int pg;
144 pg=page_find_free();
145 if(pg>=0) page_locks[pg]=Page_Durty;
146 return pg;
147 }
148
149 //return the number of page we should draw into.
150 static int page_draw_image(){
151 int pg;
152 pg=page_find_free();
153 if(pg<0) pg=pagecurrent;
154 page_locks[pg]=Page_Durty;
155 pagetoshow=pg;
156 return pg;
157 }
158
159 static void page_draw_gotten_image(int pg){
160 assert((pg>=0)&&(pg<PAGES_MAX));
161 pagetoshow=pg;
162 }
163
164 //return the number of the page to show
165 static int page_flip_page(){
166 page_locks[pagecurrent]=Page_Empty;
167 pagecurrent=pagetoshow;
168 assert(pagecurrent>=0);
169 //movequeue;
170 page_locks[pagecurrent]=Page_Durty;
171 return pagecurrent;
172 }
173 //------------ END OF PAGE CODE -------------
174 120
175 static uint32_t preinit(const char *arg) 121 static uint32_t preinit(const char *arg)
176 { 122 {
177 int i; 123 int i;
178 char s[64]; 124 char s[64];
179 125
180 getch2_disable(); 126 getch2_disable();
181 memset(zerobuf,0,sizeof(zerobuf)); 127 memset(zerobuf,0,sizeof(zerobuf));
182 force_vm=force_native=squarepix=0; 128 force_vm=force_native=squarepix=0;
129 sync_flip=vo_vsync;
130 blackbar_osd=0;
183 131
184 if(arg)while(*arg) { 132 if(arg)while(*arg) {
185 #ifdef CONFIG_VIDIX 133 #ifdef CONFIG_VIDIX
186 if(memcmp(arg,"vidix",5)==0) { 134 if(memcmp(arg,"vidix",5)==0) {
187 i=6; 135 i=6;
202 if(!strncmp(arg,"native",6)) { 150 if(!strncmp(arg,"native",6)) {
203 force_native=1; 151 force_native=1;
204 arg+=6; 152 arg+=6;
205 if( *arg == ':' ) arg++; 153 if( *arg == ':' ) arg++;
206 } 154 }
207 155
156 if(!strncmp(arg,"bbosd",5)) {
157 blackbar_osd=1;
158 arg+=5;
159 if( *arg == ':' ) arg++;
160 }
161
208 if(!strncmp(arg,"retrace",7)) { 162 if(!strncmp(arg,"retrace",7)) {
209 sync_flip=1; 163 sync_flip=1;
210 arg+=7; 164 arg+=7;
211 if( *arg == ':' ) arg++; 165 if( *arg == ':' ) arg++;
212 } 166 }
213 167
214 if(*arg) { 168 if(*arg) {
215 i=0; 169 i=0;
216 while(arg[i] && arg[i]!=':')i++; 170 while(arg[i] && arg[i]!=':')i++;
217 strncpy(s, arg, i); 171 if(i<64){
218 s[i]=0; 172 strncpy(s, arg, i);
173 s[i]=0;
174
175 force_vm=vga_getmodenumber(s);
176 if(force_vm>0) {
177 if(verbose) printf("vo_svga: Forcing mode %i\n",force_vm);
178 }else{
179 force_vm = 0;
180 }
181 }
219 arg+=i; 182 arg+=i;
220 if(*arg==':')arg++; 183 if(*arg==':')arg++;
221 i=vga_getmodenumber(s);
222 if(i>0) {
223 force_vm = i;
224 if(verbose)
225 printf("vo_svga: Forcing mode %i\n",force_vm);
226 }
227 } 184 }
228 } 185 }
229 186
230 vga_init(); 187 vga_init();
231 return 0; 188 return 0;
269 static uint32_t svga_draw_image(mp_image_t *mpi){ 226 static uint32_t svga_draw_image(mp_image_t *mpi){
270 int i,x,y,w,h; 227 int i,x,y,w,h;
271 int stride; 228 int stride;
272 uint8_t *rgbplane, *base; 229 uint8_t *rgbplane, *base;
273 int bytesperline; 230 int bytesperline;
231 int page;
274 232
275 if(mpi->flags & MP_IMGFLAG_DIRECT){ 233 if(mpi->flags & MP_IMGFLAG_DIRECT){
276 if(verbose > 2) 234 if(verbose > 2)
277 printf("vo_svga: drawing direct rendered surface\n"); 235 printf("vo_svga: drawing direct rendered surface\n");
278 cpage=(uint32_t)mpi->priv; 236 cpage=(uint32_t)mpi->priv;
279 page_draw_gotten_image(cpage); 237 assert((cpage>=0)&&(cpage<max_pages));
280 return VO_TRUE; //it's already done 238 return VO_TRUE; //it's already done
281 } 239 }
282 // if (mpi->flags&MP_IMGFLAGS_DRAWBACK) 240 // if (mpi->flags&MP_IMGFLAGS_DRAWBACK)
283 // return VO_TRUE;//direct render method 2 241 // return VO_TRUE;//direct render method 2
284 cpage=page_draw_image(); 242
243 //find a free page to draw into
244 //if there is no one then use the current one
245 page = page_find_free();
246 if(page>=0) cpage=page;
247 PageStore[cpage].locks=PAGE_BUSY;
248
285 // these variables are used in loops 249 // these variables are used in loops
286 x = mpi->x; 250 x = mpi->x;
287 y = mpi->y; 251 y = mpi->y;
288 w = mpi->w; 252 w = mpi->w;
289 h = mpi->h; 253 h = mpi->h;
531 break; 495 break;
532 } 496 }
533 PageStore[i].yoffset = i * modeinfo->height;//starting y offset 497 PageStore[i].yoffset = i * modeinfo->height;//starting y offset
534 PageStore[i].vbase = GRAPH_MEM + i*modeinfo->height*mode_stride; //memory base address 498 PageStore[i].vbase = GRAPH_MEM + i*modeinfo->height*mode_stride; //memory base address
535 PageStore[i].doffset = dof; //display offset 499 PageStore[i].doffset = dof; //display offset
500 PageStore[i].locks = PAGE_EMPTY;
536 } 501 }
537 } 502 }
538 assert(max_pages>0); 503 assert(max_pages>0);
539 printf("vo_svga: video mode have %d page(s)\n",max_pages); 504 printf("vo_svga: video mode have %d page(s)\n",max_pages);
540 page_init(max_pages);
541 //15bpp 505 //15bpp
542 if(modeinfo->bytesperpixel!=0) 506 if(modeinfo->bytesperpixel!=0)
543 vga_claimvideomemory(max_pages * modeinfo->height * modeinfo->width * modeinfo->bytesperpixel); 507 vga_claimvideomemory(max_pages * modeinfo->height * modeinfo->width * modeinfo->bytesperpixel);
544 else 508 else
545 vga_claimvideomemory(max_pages * modeinfo->height * modeinfo->width * mode_bpp / 8); 509 vga_claimvideomemory(max_pages * modeinfo->height * modeinfo->width * mode_bpp / 8);
546 510
511 cpage=old_page=0;
547 svga_clear_box(0,0,modeinfo->width,modeinfo->height * max_pages); 512 svga_clear_box(0,0,modeinfo->width,modeinfo->height * max_pages);
548 513
549 image_height=req_h; 514 image_height=req_h;
550 image_width=req_w; 515 image_width=req_w;
551 x_pos = (modeinfo->width - req_w) / 2; 516 x_pos = (modeinfo->width - req_w) / 2;
584 return VO_ERROR;//this one should not be called 549 return VO_ERROR;//this one should not be called
585 } 550 }
586 551
587 static void draw_osd(void) 552 static void draw_osd(void)
588 { 553 {
589 // for now draw only over the image 554 if(verbose > 3)
590 // vo_draw_text(modeinfo->width, modeinfo->height, draw_alpha);//black bar OSD 555 printf("vo_svga: draw_osd()\n");
591 vo_draw_text(image_width, image_height, draw_alpha); 556 //only modes with bytesperpixel>0 can draw OSD
557 if(modeinfo->bytesperpixel==0) return;
558 if(!(mode_capabilities&CAP_LINEAR)) return;//force_native will remove OSD
559
560 if(blackbar_osd){
561 //111
562 //3 4
563 //222
564 svga_clear_box(0,0 + PageStore[cpage].yoffset,
565 modeinfo->width, y_pos);
566 svga_clear_box(0, image_height + y_pos + PageStore[cpage].yoffset,
567 modeinfo->width, modeinfo->height-(image_height+ y_pos));
568 svga_clear_box(0, y_pos + PageStore[cpage].yoffset,
569 x_pos, image_height);
570 svga_clear_box(image_width + x_pos, y_pos + PageStore[cpage].yoffset,
571 modeinfo->width-(x_pos+image_width), image_height);
572 // vo_remove_text(modeinfo->width, modeinfo->height, clear_alpha);
573 vo_draw_text(modeinfo->width, modeinfo->height, draw_alpha);
574 }else{
575 vo_draw_text(image_width, image_height, draw_alpha);
576 }
592 } 577 }
593 578
594 static void flip_page(void) { 579 static void flip_page(void) {
595 static int oldpage=-1; 580 PageStore[old_page].locks=PAGE_EMPTY;
596 int page; 581 PageStore[cpage].locks=PAGE_BUSY;
597 page = page_flip_page(); 582
598 if(verbose > 2) 583 if(verbose > 2)
599 printf("vo_svga: viewing page %d\n",page); 584 printf("vo_svga: viewing page %d\n",cpage);
600 if(sync_flip && oldpage!=page){ 585 if(sync_flip && old_page!=cpage){
601 if(verbose > 2) printf("vo_svga:vga_waitretrace\n"); 586 if(verbose > 2) printf("vo_svga:vga_waitretrace\n");
602 vga_waitretrace(); 587 vga_waitretrace();
603 } 588 }
604 vga_setdisplaystart(PageStore[cpage].doffset); 589 vga_setdisplaystart(PageStore[cpage].doffset);
605 oldpage=page; 590
591 old_page=cpage;//cpage will be overwriten on next draw_image
606 } 592 }
607 593
608 static void check_events(void) { 594 static void check_events(void) {
609 } 595 }
610 596
662 int bytelen; 648 int bytelen;
663 649
664 if(verbose>2) 650 if(verbose>2)
665 printf("vo_svga: draw_alpha(x0=%d,y0=%d,w=%d,h=%d,src=%p,srca=%p,stride=%d\n", 651 printf("vo_svga: draw_alpha(x0=%d,y0=%d,w=%d,h=%d,src=%p,srca=%p,stride=%d\n",
666 x0,y0,w,h,src,srca,stride); 652 x0,y0,w,h,src,srca,stride);
667 x0+=x_pos;// in case of drawing over image 653 if(!blackbar_osd) {
668 y0+=y_pos; 654 //drawing in the image, so place the stuff there
669 655 x0+=x_pos;
670 //only modes with bytesperpixel>0 can draw OSD 656 y0+=y_pos;
671 if(modeinfo->bytesperpixel==0) return; 657 }
672 if(!(mode_capabilities&CAP_LINEAR)) return;//force_native will remove OSD 658
673 if(verbose>3) 659 if(verbose>3)
674 printf("vo_svga: OSD draw in page %d",cpage); 660 printf("vo_svga: OSD draw in page %d\n",cpage);
675 base=PageStore[cpage].vbase + y0*mode_stride + x0*modeinfo->bytesperpixel; 661 base=PageStore[cpage].vbase + y0*mode_stride + x0*modeinfo->bytesperpixel;
676 bytelen = modeinfo->width * modeinfo->bytesperpixel; 662 bytelen = modeinfo->width * modeinfo->bytesperpixel;
677 switch (mode_bpp) { 663 switch (mode_bpp) {
678 case 32: 664 case 32:
679 vo_draw_alpha_rgb32(w, h, src, srca, stride, base, bytelen); 665 vo_draw_alpha_rgb32(w, h, src, srca, stride, base, bytelen);
706 return(VO_FALSE); 692 return(VO_FALSE);
707 693
708 //reading from video memory is horribly slow 694 //reading from video memory is horribly slow
709 if( !(mpi->flags & MP_IMGFLAG_READABLE) && vo_directrendering && 695 if( !(mpi->flags & MP_IMGFLAG_READABLE) && vo_directrendering &&
710 (mode_capabilities & CAP_LINEAR) ){ 696 (mode_capabilities & CAP_LINEAR) ){
711 page=page_get_image(); 697
698 //find free page and reserve it
699 page=page_find_free();
712 if(page >= 0){ 700 if(page >= 0){
701 PageStore[page].locks=PAGE_BUSY;
702
713 mpi->flags |= MP_IMGFLAG_DIRECT; 703 mpi->flags |= MP_IMGFLAG_DIRECT;
714 mpi->stride[0] = mode_stride; 704 mpi->stride[0] = mode_stride;
715 mpi->planes[0] = PageStore[page].vbase + 705 mpi->planes[0] = PageStore[page].vbase +
716 y_pos*mode_stride + (x_pos*mpi->bpp)/8; 706 y_pos*mode_stride + (x_pos*mpi->bpp)/8;
717 (int)mpi->priv=page; 707 (int)mpi->priv=page;