Mercurial > mplayer.hg
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; |