mirror of
https://github.com/mpv-player/mpv
synced 2025-01-20 21:07:29 +01:00
- 32/16 bit mode swtiching with DGA2.0
- now use only DGA2.0 API when DGA2.0 is available git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@262 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
80147bb9fb
commit
59ea3d5640
397
libvo/vo_dga.c
397
libvo/vo_dga.c
@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
//#include "linux/keycodes.h"
|
||||
#include "config.h"
|
||||
#include "video_out.h"
|
||||
#include "video_out_internal.h"
|
||||
#include "yuv2rgb.h"
|
||||
|
||||
|
||||
LIBVO_EXTERN( dga )
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
@ -61,6 +73,7 @@ static int vo_dga_src_skip; // bytes to skip after copying one line
|
||||
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 const vo_info_t* get_info( void )
|
||||
|
||||
static uint32_t query_format( uint32_t format )
|
||||
{
|
||||
printf("vo_dga: query_format\n");
|
||||
|
||||
if( !vo_init() ) return 0; // Can't open X11
|
||||
printf("Format: %lx\n", format);
|
||||
#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){
|
||||
|
||||
#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<modelines[i].bitsPerPixel-1; k++)dummy <<=1;
|
||||
dga_depths |= dummy;
|
||||
}
|
||||
|
||||
}
|
||||
XCloseDisplay(qdisp);
|
||||
|
||||
#else
|
||||
|
||||
for(k=0, dummy=1; k<vo_depthonscreen-1; k++)dummy <<=1;
|
||||
dga_depths |= dummy;
|
||||
// hope this shift is ok; heard that on some systems only up to 8 digits
|
||||
// may be shifted at a time. SIGH! It IS so.
|
||||
// test for RGB masks !!!! (if depthonscreen != 24 or 32 !!!)
|
||||
if( !(vo_depthonscreen == 24 || vo_depthonscreen == 32 ) ){
|
||||
printf("vo_dga: You're running 15/16 bit X Server; your hardware might use unsuitable RGB-mask!\n");
|
||||
}
|
||||
#endif
|
||||
dga_depths_init = 1;
|
||||
|
||||
if( dga_depths == 0){
|
||||
printf("vo_dga: Sorry, there seems to be no suitable depth available!\n");
|
||||
printf(" Try running X in 24 or 32 bit mode!!!\n");
|
||||
return 0;
|
||||
}else{
|
||||
for(i=0, dummy=1; i< 32; i++){
|
||||
if(dummy& dga_depths){
|
||||
printf("vo_dga: may use %2d bits per pixel\n", i+1);
|
||||
}
|
||||
dummy <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( format==IMGFMT_YV12 ) return 1;
|
||||
for(k=0, dummy=1; k<(format&0xFF)-1; k++)dummy<<=1;
|
||||
|
||||
if( ( format&IMGFMT_BGR_MASK )==IMGFMT_BGR &&
|
||||
( format&0xFF )==vo_depthonscreen ) return 1;
|
||||
( dummy & dga_depths )) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -175,71 +256,28 @@ static void
|
||||
uninit(void)
|
||||
{
|
||||
|
||||
#ifdef HAVE_DGA2
|
||||
XDGADevice *dgadevice;
|
||||
#endif
|
||||
|
||||
vo_dga_is_running = 0;
|
||||
printf("vo_dga: in uninit\n");
|
||||
XUngrabPointer (vo_dga_dpy, CurrentTime);
|
||||
XUngrabKeyboard (vo_dga_dpy, CurrentTime);
|
||||
#ifdef HAVE_DGA2
|
||||
dgadevice = XDGASetMode(vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0);
|
||||
if(dgadevice != NULL){
|
||||
XFree(dgadevice);
|
||||
}
|
||||
XDGACloseFramebuffer(vo_dga_dpy, XDefaultScreen(vo_dga_dpy));
|
||||
#else
|
||||
XF86DGADirectVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0);
|
||||
#endif
|
||||
XCloseDisplay(vo_dga_dpy);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
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 bank, ram;
|
||||
int x_off, y_off;
|
||||
|
||||
#ifdef HAVE_DGA2
|
||||
// needed to change DGA video mode
|
||||
int modecount,mX, mY, mVBI, i,j;
|
||||
int X,Y;
|
||||
XDGAMode *modelines=NULL;
|
||||
XDGADevice *dgadevice;
|
||||
#endif
|
||||
|
||||
if( vo_dga_is_running )return -1;
|
||||
|
||||
if( !vo_init() ){
|
||||
printf("vo_dga: vo_init() failed!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((vo_dga_dpy = XOpenDisplay(0))==NULL)
|
||||
{
|
||||
printf ("vo_dga: Can't open display\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#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;
|
||||
X=d_width; Y=d_height;
|
||||
|
||||
printf("vo_dga: Using DGA 2.0 mode changing support\n");
|
||||
j=0;
|
||||
// offbyone-error !!! i<=modecount is WRONG !!!
|
||||
for (i=1; i<modecount; i++)
|
||||
{
|
||||
if( modelines[i].bitsPerPixel == vo_depthonscreen &&
|
||||
modelines[i].maxViewportX)
|
||||
{
|
||||
printf("vo_dga: (%3d) Trying %4d x %4d @ %3d Hz @ %2d bpp ..",
|
||||
i,
|
||||
modelines[i].viewportWidth,
|
||||
modelines[i].viewportHeight,
|
||||
(unsigned int) modelines[i].verticalRefresh,
|
||||
modelines[i].bitsPerPixel );
|
||||
|
||||
#if 0
|
||||
if (
|
||||
(modelines[i].viewportWidth >= X) &&
|
||||
(modelines[i].viewportHeight >= Y) &&
|
||||
@ -290,23 +328,209 @@ static uint32_t init( uint32_t width, uint32_t height,
|
||||
}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;
|
||||
}
|
||||
|
||||
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<modecount; i++)
|
||||
{
|
||||
if( modelines[i].bitsPerPixel == vo_dga_planes)
|
||||
{
|
||||
printf("vo_dga: (%3d) Trying %4d x %4d @ %3d Hz @ %2d bpp ..",
|
||||
i,
|
||||
modelines[i].viewportWidth,
|
||||
modelines[i].viewportHeight,
|
||||
(unsigned int) modelines[i].verticalRefresh,
|
||||
modelines[i].bitsPerPixel );
|
||||
|
||||
if ( check_mode(d_width, d_height,
|
||||
modelines[i].viewportWidth,
|
||||
modelines[i].viewportHeight,
|
||||
(unsigned) modelines[i].verticalRefresh,
|
||||
&mX, &mY, &mVBI ))
|
||||
{
|
||||
j = i;
|
||||
printf(".ok!!\n");
|
||||
}else{
|
||||
printf(".no\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
X=(modelines[j].imageWidth-mX)/2;
|
||||
Y=(modelines[j].imageHeight-mY)/2;
|
||||
printf("vo_dga: Selected video mode %4d x %4d @ %3d Hz for image size %3d x %3d.\n",
|
||||
mX, mY, mVBI, width, height);
|
||||
|
||||
XF86DGASetViewPort (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), X,Y);
|
||||
dgadevice=XDGASetMode(vo_dga_dpy, XDefaultScreen(vo_dga_dpy), modelines[j].num);
|
||||
vo_dga_vp_width =mX;
|
||||
vo_dga_vp_height = mY;
|
||||
vo_dga_width = modelines[j].bytesPerScanline / vo_dga_bpp;
|
||||
dga_modenum = modelines[j].num;
|
||||
|
||||
XFree(modelines);
|
||||
modelines = NULL;
|
||||
|
||||
#else
|
||||
|
||||
printf("vo_dga: DGA 1.0 compatibility code: mode switching not supported (yet)!\n");
|
||||
|
||||
// assume these values are already known at this stage some day
|
||||
// so that the following check for video <-> 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 @@ static uint32_t init( uint32_t width, uint32_t height,
|
||||
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;
|
||||
if( format==IMGFMT_YV12 )
|
||||
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 @@ static uint32_t init( uint32_t width, uint32_t height,
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user