# HG changeset patch # User acki2 # Date 985990178 0 # Node ID 3b7e4bf7c7ed9befb1ca2c41e2a46225cfb6e205 # Parent 1742ea658d0ba5f32d050935bdc3e2fc1744856e - 32/16 bit mode swtiching with DGA2.0 - now use only DGA2.0 API when DGA2.0 is available diff -r 1742ea658d0b -r 3b7e4bf7c7ed libvo/vo_dga.c --- a/libvo/vo_dga.c Fri Mar 30 17:16:56 2001 +0000 +++ b/libvo/vo_dga.c Fri Mar 30 22:09:38 2001 +0000 @@ -15,7 +15,20 @@ * o this is alpha * o covers only common video card formats * o works only on intel architectures + * + * 30/02/2001 * + * o query_format(): with DGA 2.0 it returns all depths it supports + * (even 16 when running 32 and vice versa) + * Checks for (hopefully!) compatible RGBmasks in 15/16 bit modes + * o added some more criterions for resolution switching + * o cleanup + * o with DGA2.0 present, ONLY DGA2.0 functions are used + * o for 15/16 modes ONLY RGB 555 is supported, since the divx-codec + * happens to map the data this way. If your graphics card supports + * this, you're well off and may use these modes; for mpeg + * movies things could be different, but I was too lazy to implement + * it ... */ @@ -24,13 +37,12 @@ #include #include - -//#include "linux/keycodes.h" #include "config.h" #include "video_out.h" #include "video_out_internal.h" #include "yuv2rgb.h" + LIBVO_EXTERN( dga ) #include @@ -61,6 +73,7 @@ static int vo_dga_vp_skip; // dto. for dest static int vo_dga_lines; // num of lines to copy static int vo_dga_src_format; +static int vo_dga_planes; // bits per pixel on screen static unsigned char *vo_dga_base; static Display *vo_dga_dpy; @@ -158,14 +171,82 @@ static uint32_t query_format( uint32_t format ) { - printf("vo_dga: query_format\n"); + +#ifdef HAVE_DGA2 + XDGAMode *modelines; + int modecount; + Display *qdisp; +#endif + + int i,k,dummy; + static int dga_depths_init = 0; + static int dga_depths = 0; // each bit that is set represents + // a depth the X-Server is capable + // of displaying + + + if( !vo_init() ) return 0; // Can't open X11 + + if(dga_depths_init == 0){ - if( !vo_init() ) return 0; // Can't open X11 - printf("Format: %lx\n", format); +#ifdef HAVE_DGA2 + + if((qdisp = XOpenDisplay(0))==NULL){ + printf("vo_dga: Can't open display!\n"); + return 0; + } + modelines=XDGAQueryModes(qdisp, XDefaultScreen(qdisp),&modecount); + for(i=0; i< modecount; i++){ + if( ( (modelines[i].bitsPerPixel == 15 || + modelines[i].bitsPerPixel == 16) && + modelines[i].redMask == 0x7c00 && + modelines[i].greenMask == 0x03e0 && + modelines[i].blueMask == 0x001f + ) || + ( modelines[i].bitsPerPixel != 15 && + modelines[i].bitsPerPixel != 16 + ) + ) + { + for(k=0, dummy=1; k= X) && (modelines[i].viewportHeight >= Y) && @@ -290,23 +328,209 @@ }else{ printf(".no\n"); } +#endif + + +//---------------------------------------------------------- + +int check_mode( int x, int y, + int new_x, int new_y, int new_vbi, + int *old_x, int *old_y, int *old_vbi){ + + if ( + (new_x >= x) && + (new_y >= y) && + ( + // prefer a better resolution either in X or in Y + // as long as the other dimension is at least the same + // + // hmm ... MAYBE it would be more clever to focus on the + // x-resolution; I had 712x400 and 640x480 and the movie + // was 640x360; 640x480 would be the 'right thing' here + // but since 712x400 was queried first I got this one. + // I think there should be a cmd-line switch to let the + // user choose the mode he likes ... (acki2) + + ( + ((new_x < *old_x) && + !(new_y > *old_y)) || + ((new_y < *old_y) && + !(new_x > *old_x)) + ) + // but if we get an identical resolution choose + // the one with the lower refreshrate (saves bandwidth !!!) + // as long as it's above 50 Hz (acki2 on 30/3/2001) + || + ( + (new_x == *old_x) && + (new_y == *old_y) && + ( + ( + new_vbi >= *old_vbi && *old_vbi < 50 + ) + || + ( + *old_vbi >= 50 && + new_vbi < *old_vbi && + new_vbi >= 50 + ) + ) + ) + ) + ) + { + *old_x = new_x; + *old_y = new_y; + *old_vbi = new_vbi; + return 1; + }else{ + return 0; } +} + + + +//--------------------------------------------------------- + +static uint32_t init( uint32_t width, uint32_t height, + uint32_t d_width,uint32_t d_height, + uint32_t fullscreen,char *title,uint32_t format ) +{ + + int x_off, y_off; + +#ifdef HAVE_DGA2 + // needed to change DGA video mode + int modecount,mX, mY, mVBI, i,j; + int dga_modenum; + XDGAMode *modelines=NULL; + XDGADevice *dgadevice; +#else + int bank, ram; +#endif + + if( vo_dga_is_running )return -1; + + + if( !vo_init() ){ + printf("vo_dga: vo_init() failed!\n"); + return 0; } - X=(modelines[j].imageWidth-mX)/2; - Y=(modelines[j].imageHeight-mY)/2; + + if (format == IMGFMT_YV12 ){ + vo_dga_planes = vo_depthonscreen; + vo_dga_planes = vo_dga_planes == 15 ? 16 : vo_dga_planes; + }else{ + vo_dga_planes = (format & 0xff); + + // hack!!! here we should only get what we told in query_format() + // but mplayer is somewhat generous about 15/16bit depth ... + + vo_dga_planes = vo_dga_planes == 15 ? 16 : vo_dga_planes; + } + + if((vo_dga_dpy = XOpenDisplay(0))==NULL) + { + printf ("vo_dga: Can't open display\n"); + return 1; + } + + vo_dga_bpp = (vo_dga_planes+7) >> 3; + +// choose a suitable mode ... + +#ifdef HAVE_DGA2 +// Code to change the video mode added by Michael Graffam +// mgraffam@idsi.net + if (modelines==NULL) + modelines=XDGAQueryModes(vo_dga_dpy, XDefaultScreen(vo_dga_dpy),&modecount); + + mX=modelines[0].imageWidth; + mY=modelines[0].imageHeight; + mVBI = modelines[0].verticalRefresh; + + + printf("vo_dga: Using DGA 2.0 mode changing support\n"); + j=0; + // offbyone-error !!! i<=modecount is WRONG !!! + for (i=1; i screen size can be done ... + + vo_dga_vp_width = 1280; + vo_dga_vp_height = 1024; + +#endif + + + vo_dga_src_format = format; + vo_dga_src_width = width; + vo_dga_src_height = height; + + if(vo_dga_src_width > vo_dga_vp_width || + vo_dga_src_height > vo_dga_vp_height) + { + printf("vo_dga: Sorry, video larger than viewport is not yet supported!\n"); + // ugly, do something nicer in the future ... + return 1; + } + +// now lets start the DGA thing + +#ifdef HAVE_DGA2 + + if (!XDGAOpenFramebuffer(vo_dga_dpy, XDefaultScreen(vo_dga_dpy))){ + printf("vo_dga: Framebuffer mapping failed!!!\n"); + XCloseDisplay(vo_dga_dpy); + return 1; + } + dgadevice=XDGASetMode(vo_dga_dpy, XDefaultScreen(vo_dga_dpy), dga_modenum); XDGASync(vo_dga_dpy, XDefaultScreen(vo_dga_dpy)); - XFree(modelines); + vo_dga_base = dgadevice->data; XFree(dgadevice); - // end mode change code + + XDGASetViewport (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0, 0, XDGAFlipRetrace); + #else - printf("vo_dga: DGA 1.0 compatibility code\n"); -#endif XF86DGAGetViewPortSize(vo_dga_dpy,XDefaultScreen(vo_dga_dpy), &vo_dga_vp_width, @@ -315,38 +539,29 @@ XF86DGAGetVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), (char **)&vo_dga_base, &vo_dga_width, &bank, &ram); -#ifndef HAVE_DGA2 + XF86DGADirectVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), + XF86DGADirectGraphics | XF86DGADirectMouse | + XF86DGADirectKeyb); + XF86DGASetViewPort (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0, 0); + #endif // do some more checkings here ... + if( format==IMGFMT_YV12 ) - yuv2rgb_init( vo_depthonscreen, MODE_RGB ); - - vo_dga_src_format = format; - vo_dga_src_width = width; - vo_dga_src_height = height; - vo_dga_bpp = (vo_depthonscreen+7) >> 3; + yuv2rgb_init( vo_dga_planes == 16 ? 15 : vo_dga_planes , MODE_RGB ); printf("vo_dga: bytes/line: %d, screen res: %dx%d, depth: %d, base: %08x, bpp: %d\n", vo_dga_width, vo_dga_vp_width, - vo_dga_vp_height, vo_depthonscreen, vo_dga_base, + vo_dga_vp_height, vo_dga_planes, vo_dga_base, vo_dga_bpp); - printf("vo_dga: video res: %dx%d\n", vo_dga_src_width, vo_dga_src_height); - - if(vo_dga_src_width > vo_dga_vp_width || - vo_dga_src_height > vo_dga_vp_height){ - printf("vo_dga: Sorry, video larger than viewport is not yet supported!\n"); - // ugly, do something nicer in the future ... - return 1; - } x_off = (vo_dga_vp_width - vo_dga_src_width)>>1; y_off = (vo_dga_vp_height - vo_dga_src_height)>>1; - vo_dga_bytes_per_line = vo_dga_src_width * vo_dga_bpp; // todo - vo_dga_lines = vo_dga_src_height; // todo - + vo_dga_bytes_per_line = vo_dga_src_width * vo_dga_bpp; + vo_dga_lines = vo_dga_src_height; vo_dga_src_offset = 0; vo_dga_vp_offset = (y_off * vo_dga_width + x_off ) * vo_dga_bpp; @@ -356,10 +571,6 @@ printf("vo_dga: vp_off=%d, vp_skip=%d, bpl=%d\n", vo_dga_vp_offset, vo_dga_vp_skip, vo_dga_bytes_per_line); - - XF86DGADirectVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), - XF86DGADirectGraphics | XF86DGADirectMouse | - XF86DGADirectKeyb); XGrabKeyboard (vo_dga_dpy, DefaultRootWindow(vo_dga_dpy), True, GrabModeAsync,GrabModeAsync, CurrentTime);