3 Video driver for SVGAlib
4 by Zoltan Mark Vician <se7en@sch.bme.hu>
5 Code started: Mon Apr 1 23:25:47 2001
6 Some changes by Matan Ziv-Av <matan@svgalib.org>
7 Compleat rewrite by Ivan Kalvachev 19 Mar 2003:
10 - 1bpp doesn't work right for me with '-double' and svgalib 1.4.3,
11 but works OK with svgalib 1.9.17
12 - The HW acceleration is not tested - svgalibs supports few chipsets,
13 and i don't have any of them. If it works for you then let me know.
14 I will remove this warning after confirm its status.
15 - retrace sync works only in doublebuffer mode.
16 - the retrace sync may slow down decoding a lot - mplayer is blocked while
18 - denoise3d fails to find common colorspace, use -vf denoise3d,scale
21 - let choose_best_mode take aspect into account
22 - set palette from mpi->palette or mpi->plane[1]
23 - make faster OSD black bars clear - need some OSD changes
24 - Make nicer CONFIG parsing
25 - change video mode logical width to match img->stride[0] - for HW only
37 #include "video_out.h"
38 #include "video_out_internal.h"
39 #include "fastmemcpy.h"
40 #include "osdep/getch2.h"
42 #include "vosub_vidix.h"
49 //#include "mp_image.h"
53 //silence warnings, probably it have to go in some global header
54 #define UNUSED(x) ((void)(x))
57 static void draw_alpha(int x0
, int y0
, int w
, int h
, unsigned char *src
,
58 unsigned char *srca
, int stride
);
59 static uint32_t get_image(mp_image_t
*mpi
);
65 #define CAP_ACCEL_CLEAR 8
66 #define CAP_ACCEL_PUTIMAGE 4
67 #define CAP_ACCEL_BACKGR 2
70 static uint8_t zerobuf
[8192];//used when clear screen with vga_draw
73 static int force_vm
=0;
74 static int force_native
=0;
75 static int sync_flip
=0;
76 static int blackbar_osd
=0;
77 static int cpage
,max_pages
,old_page
;
79 static vga_modeinfo
* modeinfo
;
80 static int mode_stride
; //keep it in case of vga_setlogicalwidth
81 static int stride_granularity
; //not yet used
83 static int mode_capabilities
;
85 static int image_width
,image_height
; // used by OSD
86 static int x_pos
, y_pos
;
89 int yoffset
;//y position of the page
90 int doffset
;//display start of the page
91 uint8_t * vbase
;//memory start address of the page
95 static const vo_info_t info
= {
98 "Ivan Kalvachev <iive@users.sf.net>",
103 static char vidix_name
[32] = "";
104 static vidix_grkey_t gr_key
;
110 //return number of 1'st free page or -1 if no free one
111 static inline int page_find_free(void){
113 for(i
=0;i
<max_pages
;i
++)
114 if(PageStore
[i
].locks
== PAGE_EMPTY
) return i
;
118 static int preinit(const char *arg
)
124 memset(zerobuf
,0,sizeof(zerobuf
));
125 force_vm
=force_native
=squarepix
=0;
131 if(memcmp(arg
,"vidix",5)==0) {
133 while(arg
[i
] && arg
[i
]!=':') i
++;
134 strncpy(vidix_name
, arg
+6, i
-6);
138 vidix_preinit(vidix_name
, &video_out_svga
);
141 if(!strncmp(arg
,"sq",2)) {
144 if( *arg
== ':' ) arg
++;
147 if(!strncmp(arg
,"native",6)) {
150 if( *arg
== ':' ) arg
++;
153 if(!strncmp(arg
,"bbosd",5)) {
156 if( *arg
== ':' ) arg
++;
159 if(!strncmp(arg
,"retrace",7)) {
162 if( *arg
== ':' ) arg
++;
167 while(arg
[i
] && arg
[i
]!=':')i
++;
172 force_vm
=vga_getmodenumber(s
);
174 if( mp_msg_test(MSGT_VO
,MSGL_V
) ) mp_msg(MSGT_VO
,MSGL_V
, "vo_svga: Forcing mode %i\n",force_vm
);
186 mp_msg(MSGT_VO
,MSGL_ERR
, "vo_svga: vga_init() returned error=%d\n",rez
);
191 static void svga_clear_box(int x
,int y
,int w
,int h
){
195 if (mode_capabilities
&CAP_ACCEL_CLEAR
){
196 if( mp_msg_test(MSGT_VO
,MSGL_DBG3
) )
197 mp_msg(MSGT_VO
,MSGL_DBG3
, "vo_svga: clearing box %d,%d - %d,%d with HW acceleration\n",
199 if(mode_capabilities
&CAP_ACCEL_BACKGR
)
200 vga_accel(ACCEL_SYNC
);
201 vga_accel(ACCEL_SETFGCOLOR
,0);//black
202 vga_accel(ACCEL_FILLBOX
,x
,y
,w
,h
);
205 if (mode_capabilities
& CAP_LINEAR
){
206 if( mp_msg_test(MSGT_VO
,MSGL_DBG3
) )
207 mp_msg(MSGT_VO
,MSGL_DBG3
, "vo_svga: clearing box %d,%d - %d,%d with memset\n",x
,y
,w
,h
);
208 rgbplane
=PageStore
[0].vbase
+ (y
*mode_stride
) + (x
*modeinfo
->bytesperpixel
);
210 //i'm afraid that memcpy is better optimized than memset;)
211 fast_memcpy(rgbplane
,zerobuf
,w
*modeinfo
->bytesperpixel
);
212 // memset(rgbplane,0,w*modeinfo->bytesperpixel);
213 rgbplane
+=mode_stride
;
218 if( mp_msg_test(MSGT_VO
,MSGL_DBG3
) )
219 mp_msg(MSGT_VO
,MSGL_DBG3
, "vo_svga: clearing box %d,%d - %d,%d with native draw \n",x
,y
,w
,h
);
220 if(modeinfo
->bytesperpixel
!=0) w
*=modeinfo
->bytesperpixel
;
222 vga_drawscansegment(zerobuf
,x
,y
+i
,w
);
226 static uint32_t svga_draw_image(mp_image_t
*mpi
){
229 uint8_t *rgbplane
, *base
;
233 if(mpi
->flags
& MP_IMGFLAG_DIRECT
){
234 if( mp_msg_test(MSGT_VO
,MSGL_DBG3
) )
235 mp_msg(MSGT_VO
,MSGL_DBG3
, "vo_svga: drawing direct rendered surface\n");
236 cpage
=(uint32_t)mpi
->priv
;
237 assert((cpage
>=0)&&(cpage
<max_pages
));
238 return VO_TRUE
; //it's already done
240 // if (mpi->flags&MP_IMGFLAGS_DRAWBACK)
241 // return VO_TRUE;//direct render method 2
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
;
249 // these variables are used in loops
254 stride
= mpi
->stride
[0];
255 rgbplane
= mpi
->planes
[0] + y
*stride
+ (x
*mpi
->bpp
)/8;
259 if(mpi
->bpp
>= 8){//for modes<8 use only native
260 if( (mode_capabilities
&CAP_ACCEL_PUTIMAGE
) && (x
==0) && (w
==mpi
->width
) &&
261 (stride
== mode_stride
) ){ //only monolite image can be accelerated
262 w
=(stride
*8)/mpi
->bpp
;//we transfer pixels in the stride so the source
264 if( mp_msg_test(MSGT_VO
,MSGL_DBG3
) )
265 mp_msg(MSGT_VO
,MSGL_DBG3
, "vo_svga: using HW PutImage (x=%d,y=%d,w=%d,h=%d)\n",x
,y
,w
,h
);
266 if(mode_capabilities
& CAP_ACCEL_BACKGR
)
267 vga_accel(ACCEL_SYNC
);
269 vga_accel(ACCEL_PUTIMAGE
,x
,y
+PageStore
[cpage
].yoffset
,w
,h
,rgbplane
);
273 if( mode_capabilities
&CAP_LINEAR
){
275 if( mp_msg_test(MSGT_VO
,MSGL_DBG3
) )
276 mp_msg(MSGT_VO
,MSGL_DBG3
, "vo_svga: using Direct memcpy (x=%d,y=%d,w=%d,h=%d)\n",x
,y
,w
,h
);
277 bytesperline
=(w
*mpi
->bpp
)/8;
278 base
=PageStore
[cpage
].vbase
+ (y
*mode_stride
) + (x
*mpi
->bpp
)/8;
281 mem2agpcpy(base
,rgbplane
,bytesperline
);
293 length
=(w
*mpi
->bpp
)/8;
294 //one byte per pixel! svgalib innovation
295 if(mpi
->imgfmt
==IMGFMT_RG4B
|| mpi
->imgfmt
==IMGFMT_BG4B
) length
=w
;
297 if( mp_msg_test(MSGT_VO
,MSGL_DBG3
) )
298 mp_msg(MSGT_VO
,MSGL_DBG3
, "vo_svga: using Native vga_draw(x=%d,y=%d,w=%d,h=%d)\n",x
,y
,w
,h
);
299 y
+=PageStore
[cpage
].yoffset
;//y position of the page beggining
301 vga_drawscansegment(rgbplane
,x
,y
+i
,length
);
308 static int bpp_from_vminfo(vga_modeinfo
*vminfo
){
309 switch(vminfo
->colors
){
313 case 32768: return 15;
314 case 65536: return 16;
315 case 1<<24: return 8*vminfo
->bytesperpixel
;
320 static int find_best_svga_mode(int req_w
,int req_h
, int req_bpp
){
321 int badness
,prev_badness
;
322 int bestmode
,lastmode
;
324 vga_modeinfo
*vminfo
;
325 //int best aspect mode // best linear mode // best normal mode (no modeX)
327 prev_badness
= 0;//take care of special case below
328 bestmode
= 0; //0 is the TEXT mode
329 lastmode
= vga_lastmodenumber();
330 for(i
=1;i
<=lastmode
;i
++){
331 vminfo
= vga_getmodeinfo(i
);
332 if( vminfo
== NULL
) continue;
333 if( mp_msg_test(MSGT_VO
,MSGL_DBG4
) )
334 mp_msg(MSGT_VO
,MSGL_DBG4
, "vo_svga: testing mode %d (%s)\n",i
,vga_getmodename(i
));
335 if( vga_hasmode(i
) == 0 ) continue;
336 if( req_bpp
!= bpp_from_vminfo(vminfo
) )continue;
337 if( (vminfo
->width
< req_w
) || (vminfo
->height
< req_h
) ) continue;
338 badness
=(vminfo
->width
* vminfo
->height
) - (req_h
* req_w
);
339 //put here aspect calculations
341 if( vminfo
->width
*3 != vminfo
->height
*4 ) continue;
343 if( bestmode
==0 || prev_badness
>= badness
){//modeX etc...
344 prev_badness
=badness
;
346 if( mp_msg_test(MSGT_VO
,MSGL_DBG4
) )
347 mp_msg(MSGT_VO
,MSGL_DBG4
, "vo_svga: found good mode %d with badness %d\n",i
,badness
);
353 static int control(uint32_t request
, void *data
, ...)
356 case VOCTRL_QUERY_FORMAT
:
357 return query_format(*((uint32_t*)data
));
358 case VOCTRL_DRAW_IMAGE
:
359 return svga_draw_image( (mp_image_t
*)data
);
360 case VOCTRL_GET_IMAGE
:
361 return get_image(data
);
367 case VOCTRL_SET_EQUALIZER
:
373 value
= va_arg(ap
, int);
376 return vidix_control(request
, data
, value
);
378 case VOCTRL_GET_EQUALIZER
:
384 value
= va_arg(ap
, int*);
387 return vidix_control(request
, data
, value
);
390 return vidix_control(request
, data
);
398 // This function is called to init the video driver for specific mode
400 static int config(uint32_t width
, uint32_t height
, uint32_t d_width
,
401 uint32_t d_height
, uint32_t flags
, char *title
,
403 int32_t req_w
= width
;// (d_width > 0 ? d_width : width);
404 int32_t req_h
= height
;// (d_height > 0 ? d_height : height);
405 uint16_t vid_mode
= 0;
409 if( mp_msg_test(MSGT_VO
,MSGL_V
) )
410 mp_msg(MSGT_VO
,MSGL_V
, "vo_svga: config(%i, %i, %i, %i, %08x, %s, %08x)\n", width
, height
,
411 d_width
, d_height
, flags
, title
, format
);
412 //Only RGB modes supported
413 if (!IMGFMT_IS_RGB(format
) && !IMGFMT_IS_BGR(format
)) {assert(0);return -1;}
414 req_bpp
= IMGFMT_BGR_DEPTH(format
);
416 if( vo_dbpp
!=0 && vo_dbpp
!=req_bpp
) {assert(0);return-1;}
419 if ( mp_msg_test(MSGT_VO
,MSGL_V
) ) {
420 mp_msg(MSGT_VO
,MSGL_V
, "vo_svga: Looking for the best resolution...\n");
421 mp_msg(MSGT_VO
,MSGL_V
, "vo_svga: req_w: %d, req_h: %d, bpp: %d\n",req_w
,req_h
,req_bpp
);
423 vid_mode
=find_best_svga_mode(req_w
,req_h
,req_bpp
);
426 modeinfo
=vga_getmodeinfo(vid_mode
);
429 if(vga_hasmode(vid_mode
) == 0){
430 mp_msg(MSGT_VO
,MSGL_ERR
, MSGTR_LIBVO_SVGA_ForcedVidmodeNotAvailable
,
431 vid_mode
,vga_getmodename(vid_mode
));
434 modeinfo
=vga_getmodeinfo(vid_mode
);
435 if( (modeinfo
->width
< req_w
) || (modeinfo
->height
< req_h
) ){
436 mp_msg(MSGT_VO
,MSGL_ERR
, MSGTR_LIBVO_SVGA_ForcedVidmodeTooSmall
,
437 vid_mode
,vga_getmodename(vid_mode
));
441 mode_bpp
=bpp_from_vminfo(modeinfo
);
443 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_SVGA_Vidmode
,
444 vid_mode
,modeinfo
->width
,modeinfo
->height
,mode_bpp
);
446 if (vga_setmode(vid_mode
) == -1) {
447 mp_msg(MSGT_VO
,MSGL_ERR
, MSGTR_LIBVO_SVGA_VgasetmodeFailed
,vid_mode
);
451 /* set 332 palette for 8 bpp */
455 vga_setpalette(i
, ((i
>>5)&7)*9, ((i
>>2)&7)*9, (i
&3)*21);
457 /* set 121 palette for 4 bpp */
458 else if(mode_bpp
==4){
461 vga_setpalette(i
, ((i
>>3)&1)*63, ((i
>>1)&3)*21, (i
&1)*63);
463 //if we change the logical width, we should know the granularity
464 stride_granularity
=8;//according to man vga_logicalwidth
465 if(modeinfo
->flags
& EXT_INFO_AVAILABLE
){
466 stride_granularity
=modeinfo
->linewidth_unit
;
468 //look for hardware acceleration
469 mode_capabilities
=0;//NATIVE;
470 if(!force_native
){//if we want to use only native drawers
471 if(modeinfo
->flags
& HAVE_EXT_SET
){//support for hwaccel interface
472 accflags
=vga_ext_set(VGA_EXT_AVAILABLE
,VGA_AVAIL_ACCEL
);
473 if(accflags
& ACCELFLAG_FILLBOX
) // clear screen
474 mode_capabilities
|=CAP_ACCEL_CLEAR
;
475 if(accflags
& ACCELFLAG_PUTIMAGE
)//support for mem->vid transfer
476 mode_capabilities
|=CAP_ACCEL_PUTIMAGE
;
477 if((accflags
& ACCELFLAG_SETMODE
) && (accflags
& ACCELFLAG_SYNC
)){
478 vga_accel(ACCEL_SETMODE
,BLITS_IN_BACKGROUND
);
479 mode_capabilities
|=CAP_ACCEL_BACKGR
;//can draw in backgraund
482 if(modeinfo
->flags
& IS_LINEAR
){
483 mode_capabilities
|=CAP_LINEAR
; //don't use bank & vga_draw
486 if(modeinfo
->flags
& CAPABLE_LINEAR
){
488 vid_mem_size
= vga_setlinearaddressing();
489 if(vid_mem_size
!= -1){
490 modeinfo
=vga_getmodeinfo(vid_mode
);//sometimes they change parameters
491 mode_capabilities
|=CAP_LINEAR
;
496 if(mode_capabilities
&CAP_LINEAR
){
497 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_SVGA_VideoModeIsLinearAndMemcpyCouldBeUsed
);
499 if(mode_capabilities
&CAP_ACCEL_PUTIMAGE
){
500 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_SVGA_VideoModeHasHardwareAcceleration
);
501 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_SVGA_IfItWorksForYouIWouldLikeToKnow
);
504 //here is the place to handle strides for accel_ modes;
505 mode_stride
=modeinfo
->linewidth
;
506 //we may try to set a bigger stride for video mode that will match the mpi->stride,
507 //this way we will transfer more data, but HW put_image can do it in backgraund!
509 //now let's see how many pages we can use
510 max_pages
= modeinfo
->maxpixels
/(modeinfo
->height
* modeinfo
->width
);
511 if(max_pages
> MAXPAGES
) max_pages
= MAXPAGES
;
512 if(!vo_doublebuffering
) max_pages
=1;
513 //fill PageStore structs
518 GRAPH_MEM
=vga_getgraphmem();
519 for(i
=0;i
<max_pages
;i
++){
520 //calculate display offset
521 dof
= i
* modeinfo
->height
* modeinfo
->width
;
522 if(modeinfo
->bytesperpixel
!= 0) dof
*=modeinfo
->bytesperpixel
;
523 //check video chip limitations
524 if( dof
!= (dof
& modeinfo
->startaddressrange
) ){
525 max_pages
=i
;//page 0 will never come here
528 PageStore
[i
].yoffset
= i
* modeinfo
->height
;//starting y offset
529 PageStore
[i
].vbase
= GRAPH_MEM
+ i
*modeinfo
->height
*mode_stride
; //memory base address
530 PageStore
[i
].doffset
= dof
; //display offset
531 PageStore
[i
].locks
= PAGE_EMPTY
;
535 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_SVGA_VideoModeHas
,max_pages
);
537 if(modeinfo
->bytesperpixel
!=0)
538 vga_claimvideomemory(max_pages
* modeinfo
->height
* modeinfo
->width
* modeinfo
->bytesperpixel
);
540 vga_claimvideomemory(max_pages
* modeinfo
->height
* modeinfo
->width
* mode_bpp
/ 8);
543 svga_clear_box(0,0,modeinfo
->width
,modeinfo
->height
* max_pages
);
547 x_pos
= (modeinfo
->width
- req_w
) / 2;
548 y_pos
= (modeinfo
->height
- req_h
) / 2;
549 x_pos
&= ~(15); //align x offset position to 16 pixels
550 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_SVGA_CenteringImageStartAt
,x_pos
,y_pos
);
555 vidix_init(width
, height
, x_pos
, y_pos
, modeinfo
->width
, modeinfo
->height
,
556 format
, mode_bpp
, modeinfo
->width
,modeinfo
->height
);
557 mp_msg(MSGT_VO
,MSGL_INFO
, MSGTR_LIBVO_SVGA_UsingVidix
,width
,height
,
558 modeinfo
->width
,modeinfo
->height
);
561 if(vidix_grkey_support()){
562 vidix_grkey_get(&gr_key
);
563 gr_key
.key_op
= KEYS_PUT
;
564 if (!(vo_colorkey
& 0xFF000000)) {
565 gr_key
.ckey
.op
= CKEY_TRUE
;
566 gr_key
.ckey
.red
= (vo_colorkey
& 0x00FF0000) >> 16;
567 gr_key
.ckey
.green
= (vo_colorkey
& 0x0000FF00) >> 8;
568 gr_key
.ckey
.blue
= vo_colorkey
& 0x000000FF;
570 gr_key
.ckey
.op
= CKEY_FALSE
;
571 vidix_grkey_set(&gr_key
);
576 vga_setdisplaystart(0);
580 static int draw_slice(uint8_t *image
[],int stride
[],
581 int w
, int h
, int x
, int y
) {
583 UNUSED(image
);UNUSED(stride
);
587 return VO_ERROR
;//this is yv12 only -> vf_scale should do all transforms
590 static int draw_frame(uint8_t *src
[]) {
593 return VO_ERROR
;//this one should not be called
596 static void draw_osd(void)
598 if( mp_msg_test(MSGT_VO
,MSGL_DBG4
) )
599 mp_msg(MSGT_VO
,MSGL_DBG4
, "vo_svga: draw_osd()\n");
600 //only modes with bytesperpixel>0 can draw OSD
601 if(modeinfo
->bytesperpixel
==0) return;
602 if(!(mode_capabilities
&CAP_LINEAR
)) return;//force_native will remove OSD
608 svga_clear_box(0,0 + PageStore
[cpage
].yoffset
,
609 modeinfo
->width
, y_pos
);
610 svga_clear_box(0, image_height
+ y_pos
+ PageStore
[cpage
].yoffset
,
611 modeinfo
->width
, modeinfo
->height
-(image_height
+ y_pos
));
612 svga_clear_box(0, y_pos
+ PageStore
[cpage
].yoffset
,
613 x_pos
, image_height
);
614 svga_clear_box(image_width
+ x_pos
, y_pos
+ PageStore
[cpage
].yoffset
,
615 modeinfo
->width
-(x_pos
+image_width
), image_height
);
616 // vo_remove_text(modeinfo->width, modeinfo->height, clear_alpha);
617 vo_draw_text(modeinfo
->width
, modeinfo
->height
, draw_alpha
);
619 vo_draw_text(image_width
, image_height
, draw_alpha
);
623 static void flip_page(void) {
624 PageStore
[old_page
].locks
=PAGE_EMPTY
;
625 PageStore
[cpage
].locks
=PAGE_BUSY
;
627 if( mp_msg_test(MSGT_VO
,MSGL_DBG3
) )
628 mp_msg(MSGT_VO
,MSGL_DBG3
, "vo_svga: viewing page %d\n",cpage
);
629 if(sync_flip
&& old_page
!=cpage
){
630 if( mp_msg_test(MSGT_VO
,MSGL_DBG3
) ) mp_msg(MSGT_VO
,MSGL_DBG3
, "vo_svga:vga_waitretrace\n");
633 vga_setdisplaystart(PageStore
[cpage
].doffset
);
635 old_page
=cpage
;//cpage will be overwriten on next draw_image
638 static void check_events(void) {
641 static void uninit(void) {
644 if(vidix_name
[0])vidix_term();
649 /* --------------------------------------------------------------------- */
650 static int query_format(uint32_t format
) {
651 int32_t req_bpp
,flags
;
653 vga_modeinfo
* vminfo
;
655 if ( mp_msg_test(MSGT_VO
,MSGL_DBG4
) )
656 mp_msg(MSGT_VO
,MSGL_DBG4
, "vo_svga: query_format=%X \n",format
);
657 //only RGB modes supported
658 if( (!IMGFMT_IS_RGB(format
)) && (!IMGFMT_IS_BGR(format
)) ) return 0;
660 // Reject different endian
661 #ifdef WORDS_BIGENDIAN
662 if (IMGFMT_IS_BGR(format
)) return 0;
664 if (IMGFMT_IS_RGB(format
)) return 0;
667 //svgalib supports only BG4B! if we want BGR4 we have to emulate it (sw)
668 if( format
==IMGFMT_BGR4
|| format
==IMGFMT_RGB4
) return 0;
669 req_bpp
= IMGFMT_RGB_DEPTH(format
);
670 if( vo_dbpp
>0 && vo_dbpp
!=req_bpp
) return 0; //support -bpp options
672 lastmode
= vga_lastmodenumber();
673 for(i
=1;i
<=lastmode
;i
++){
674 vminfo
= vga_getmodeinfo(i
);
675 if( vminfo
== NULL
) continue;
676 if( vga_hasmode(i
) == 0 ) continue;
677 if( req_bpp
!= bpp_from_vminfo(vminfo
) ) continue;
678 if( (force_vm
> 0) && (force_vm
!= i
) ) continue;//quick hack
679 flags
= VFCAP_CSP_SUPPORTED
|
680 VFCAP_CSP_SUPPORTED_BY_HW
|
683 if(req_bpp
>8) flags
|=VFCAP_OSD
;
689 static void draw_alpha(int x0
, int y0
, int w
, int h
, unsigned char *src
,
690 unsigned char *srca
, int stride
) {
693 if( mp_msg_test(MSGT_VO
,MSGL_DBG3
) )
694 mp_msg(MSGT_VO
,MSGL_DBG3
, "vo_svga: draw_alpha(x0=%d,y0=%d,w=%d,h=%d,src=%p,srca=%p,stride=%d\n",
695 x0
,y0
,w
,h
,src
,srca
,stride
);
697 //drawing in the image, so place the stuff there
702 if( mp_msg_test(MSGT_VO
,MSGL_DBG4
) )
703 mp_msg(MSGT_VO
,MSGL_DBG4
, "vo_svga: OSD draw in page %d\n",cpage
);
704 base
=PageStore
[cpage
].vbase
+ y0
*mode_stride
+ x0
*modeinfo
->bytesperpixel
;
707 vo_draw_alpha_rgb32(w
, h
, src
, srca
, stride
, base
, mode_stride
);
710 vo_draw_alpha_rgb24(w
, h
, src
, srca
, stride
, base
, mode_stride
);
713 vo_draw_alpha_rgb16(w
, h
, src
, srca
, stride
, base
, mode_stride
);
716 vo_draw_alpha_rgb15(w
, h
, src
, srca
, stride
, base
, mode_stride
);
721 static uint32_t get_image(mp_image_t
*mpi
){
724 if(!IMGFMT_IS_BGR(mpi
->imgfmt
) && !IMGFMT_IS_RGB(mpi
->imgfmt
) ){
725 assert(0);//should never happen
730 ( (mpi
->type
!= MP_IMGTYPE_STATIC
) && (mpi
->type
!= MP_IMGTYPE_TEMP
)) ||
731 (mpi
->flags
& MP_IMGFLAG_PLANAR
) ||
732 (mpi
->flags
& MP_IMGFLAG_YUV
)
736 //reading from video memory is horribly slow
737 if( !(mpi
->flags
& MP_IMGFLAG_READABLE
) && vo_directrendering
&&
738 (mode_capabilities
& CAP_LINEAR
) ){
740 //find free page and reserve it
741 page
=page_find_free();
743 PageStore
[page
].locks
=PAGE_BUSY
;
745 mpi
->flags
|= MP_IMGFLAG_DIRECT
;
746 mpi
->stride
[0] = mode_stride
;
747 mpi
->planes
[0] = PageStore
[page
].vbase
+
748 y_pos
*mode_stride
+ (x_pos
*mpi
->bpp
)/8;
749 mpi
->priv
=(void *)page
;
750 if( mp_msg_test(MSGT_VO
,MSGL_DBG3
) )
751 mp_msg(MSGT_VO
,MSGL_DBG3
, "vo_svga: direct render allocated! page=%d\n",page
);