Mercurial > mplayer.hg
comparison libvo/vo_dga.c @ 263:78e8925fd6b4
- added VidMode changing support for DGA1.0 (used code from Michael Graffam (mgraffam@idsi.net))
author | acki2 |
---|---|
date | Sat, 31 Mar 2001 09:16:08 +0000 |
parents | 2c7c77d793df |
children | 336b1559a447 |
comparison
equal
deleted
inserted
replaced
262:2c7c77d793df | 263:78e8925fd6b4 |
---|---|
32 * o you may define VO_DGA_FORCE_DEPTH to the depth you desire | 32 * o you may define VO_DGA_FORCE_DEPTH to the depth you desire |
33 * if you don't like the choice the driver makes | 33 * if you don't like the choice the driver makes |
34 * Beware: unless you can use DGA2.0 this has to be your X Servers | 34 * Beware: unless you can use DGA2.0 this has to be your X Servers |
35 * depth!!! | 35 * depth!!! |
36 * o Added double buffering :-)) | 36 * o Added double buffering :-)) |
37 * o included VidMode switching support for DGA1.0, written by Michael Graffam | |
38 * mgraffam@idsi.net | |
39 * | |
37 */ | 40 */ |
38 | 41 |
39 | 42 |
40 | 43 |
41 #include <stdio.h> | 44 #include <stdio.h> |
45 #include "config.h" | 48 #include "config.h" |
46 #include "video_out.h" | 49 #include "video_out.h" |
47 #include "video_out_internal.h" | 50 #include "video_out_internal.h" |
48 #include "yuv2rgb.h" | 51 #include "yuv2rgb.h" |
49 | 52 |
53 | |
50 //#undef HAVE_DGA2 | 54 //#undef HAVE_DGA2 |
55 //#undef HAVE_XF86VM | |
56 | |
51 | 57 |
52 LIBVO_EXTERN( dga ) | 58 LIBVO_EXTERN( dga ) |
53 | 59 |
54 #include <X11/Xlib.h> | 60 #include <X11/Xlib.h> |
55 #include <X11/extensions/xf86dga.h> | 61 #include <X11/extensions/xf86dga.h> |
62 | |
63 #ifdef HAVE_XF86VM | |
64 #include <X11/extensions/xf86vmode.h> | |
65 #endif | |
66 | |
56 | 67 |
57 #include "x11_common.h" | 68 #include "x11_common.h" |
58 | 69 |
59 static vo_info_t vo_info = | 70 static vo_info_t vo_info = |
60 { | 71 { |
62 "dga", | 73 "dga", |
63 "Andreas Ackermann <acki@acki-netz.de>", | 74 "Andreas Ackermann <acki@acki-netz.de>", |
64 "" | 75 "" |
65 }; | 76 }; |
66 | 77 |
78 #ifdef HAVE_XF86VM | |
79 static XF86VidModeModeInfo **vo_dga_vidmodes=NULL; | |
80 #endif | |
81 | |
82 | |
67 static int vo_dga_width; // bytes per line in framebuffer | 83 static int vo_dga_width; // bytes per line in framebuffer |
68 static int vo_dga_vp_width; // visible pixels per line in framebuffer | 84 static int vo_dga_vp_width; // visible pixels per line in |
85 // framebuffer | |
69 static int vo_dga_vp_height; // visible lines in framebuffer | 86 static int vo_dga_vp_height; // visible lines in framebuffer |
70 static int vo_dga_is_running = 0; | 87 static int vo_dga_is_running = 0; |
71 static int vo_dga_src_width; // width of video in pixels | 88 static int vo_dga_src_width; // width of video in pixels |
72 static int vo_dga_src_height; // height of video in pixels | 89 static int vo_dga_src_height; // height of video in pixels |
73 static int vo_dga_bpp; // bytes per pixel in framebuffer | 90 static int vo_dga_bpp; // bytes per pixel in framebuffer |
282 { | 299 { |
283 | 300 |
284 #ifdef HAVE_DGA2 | 301 #ifdef HAVE_DGA2 |
285 XDGADevice *dgadevice; | 302 XDGADevice *dgadevice; |
286 #endif | 303 #endif |
287 | 304 |
288 vo_dga_is_running = 0; | 305 if(vo_dga_is_running){ |
289 printf("vo_dga: in uninit\n"); | 306 vo_dga_is_running = 0; |
290 XUngrabPointer (vo_dga_dpy, CurrentTime); | 307 printf("vo_dga: in uninit\n"); |
291 XUngrabKeyboard (vo_dga_dpy, CurrentTime); | 308 XUngrabPointer (vo_dga_dpy, CurrentTime); |
309 XUngrabKeyboard (vo_dga_dpy, CurrentTime); | |
292 #ifdef HAVE_DGA2 | 310 #ifdef HAVE_DGA2 |
293 dgadevice = XDGASetMode(vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0); | 311 dgadevice = XDGASetMode(vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0); |
294 if(dgadevice != NULL){ | 312 if(dgadevice != NULL){ |
295 XFree(dgadevice); | 313 XFree(dgadevice); |
296 } | 314 } |
297 XDGACloseFramebuffer(vo_dga_dpy, XDefaultScreen(vo_dga_dpy)); | 315 XDGACloseFramebuffer(vo_dga_dpy, XDefaultScreen(vo_dga_dpy)); |
298 #else | 316 #else |
299 XF86DGADirectVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0); | 317 XF86DGADirectVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0); |
300 #endif | 318 // first disable DirectVideo and then switch mode back! |
301 XCloseDisplay(vo_dga_dpy); | 319 #ifdef HAVE_XF86VM |
320 if (vo_dga_vidmodes != NULL ){ | |
321 int screen; screen=XDefaultScreen( vo_dga_dpy ); | |
322 printf("vo_dga: VidModeExt: Switching back..\n"); | |
323 // seems some graphics adaptors need this more than once ... | |
324 XF86VidModeSwitchToMode(vo_dga_dpy,screen,vo_dga_vidmodes[0]); | |
325 XF86VidModeSwitchToMode(vo_dga_dpy,screen,vo_dga_vidmodes[0]); | |
326 XF86VidModeSwitchToMode(vo_dga_dpy,screen,vo_dga_vidmodes[0]); | |
327 XF86VidModeSwitchToMode(vo_dga_dpy,screen,vo_dga_vidmodes[0]); | |
328 XFree(vo_dga_vidmodes); | |
329 } | |
330 #endif | |
331 #endif | |
332 XCloseDisplay(vo_dga_dpy); | |
333 } | |
302 } | 334 } |
303 | 335 |
304 | 336 |
305 //---------------------------------------------------------- | 337 //---------------------------------------------------------- |
306 | 338 |
375 int modecount,mX, mY, mVBI, i,j; | 407 int modecount,mX, mY, mVBI, i,j; |
376 int dga_modenum; | 408 int dga_modenum; |
377 XDGAMode *modelines=NULL; | 409 XDGAMode *modelines=NULL; |
378 XDGADevice *dgadevice; | 410 XDGADevice *dgadevice; |
379 #else | 411 #else |
412 #ifdef HAVE_XF86VM | |
413 unsigned int vm_event, vm_error; | |
414 unsigned int vm_ver, vm_rev; | |
415 int i,j,have_vm=0; | |
416 int modecount,mX, mY, mVBI, dga_modenum; | |
417 #endif | |
380 int bank, ram; | 418 int bank, ram; |
381 #endif | 419 #endif |
382 | 420 |
383 if( vo_dga_is_running )return -1; | 421 if( vo_dga_is_running )return -1; |
384 | 422 |
392 vo_dga_planes = vo_depthonscreen; | 430 vo_dga_planes = vo_depthonscreen; |
393 vo_dga_planes = vo_dga_planes == 15 ? 16 : vo_dga_planes; | 431 vo_dga_planes = vo_dga_planes == 15 ? 16 : vo_dga_planes; |
394 }else{ | 432 }else{ |
395 vo_dga_planes = (format & 0xff); | 433 vo_dga_planes = (format & 0xff); |
396 | 434 |
397 // hack!!! here we should only get what we told in query_format() | 435 // hack!!! here we should only get what we told we can handle in |
398 // but mplayer is somewhat generous about 15/16bit depth ... | 436 // query_format() but mplayer is somewhat generous about |
437 // 15/16bit depth ... | |
399 | 438 |
400 vo_dga_planes = vo_dga_planes == 15 ? 16 : vo_dga_planes; | 439 vo_dga_planes = vo_dga_planes == 15 ? 16 : vo_dga_planes; |
401 } | 440 } |
402 | 441 |
403 if((vo_dga_dpy = XOpenDisplay(0))==NULL) | 442 if((vo_dga_dpy = XOpenDisplay(0))==NULL) |
405 printf ("vo_dga: Can't open display\n"); | 444 printf ("vo_dga: Can't open display\n"); |
406 return 1; | 445 return 1; |
407 } | 446 } |
408 | 447 |
409 vo_dga_bpp = (vo_dga_planes+7) >> 3; | 448 vo_dga_bpp = (vo_dga_planes+7) >> 3; |
449 | |
450 // TODO: find out screen resolution of X-Server here and | |
451 // provide them as default values (used only in case | |
452 // DGA1.0 and no VidMode Ext or VidModeExt doesn't return | |
453 // any screens to check if video is larger than current screen) | |
454 | |
455 vo_dga_vp_width = 1280; | |
456 vo_dga_vp_height = 1024; | |
457 | |
458 | |
410 | 459 |
411 // choose a suitable mode ... | 460 // choose a suitable mode ... |
412 | 461 |
413 #ifdef HAVE_DGA2 | 462 #ifdef HAVE_DGA2 |
414 // Code to change the video mode added by Michael Graffam | 463 // Code to change the video mode added by Michael Graffam |
459 XFree(modelines); | 508 XFree(modelines); |
460 modelines = NULL; | 509 modelines = NULL; |
461 | 510 |
462 #else | 511 #else |
463 | 512 |
464 printf("vo_dga: DGA 1.0 compatibility code: mode switching not supported (yet)!\n"); | 513 |
465 | 514 #ifdef HAVE_XF86VM |
466 // assume these values are already known at this stage some day | 515 |
467 // so that the following check for video <-> screen size can be done ... | 516 printf("vo_dga: DGA 1.0 compatibility code: Using XF86VidMode for mode switching!\n"); |
468 | 517 |
469 vo_dga_vp_width = 1280; | 518 if (XF86VidModeQueryExtension(vo_dga_dpy, &vm_event, &vm_error)) { |
470 vo_dga_vp_height = 1024; | 519 XF86VidModeQueryVersion(vo_dga_dpy, &vm_ver, &vm_rev); |
471 | 520 printf("vo_dga: XF86VidMode Extension v%i.%i\n", vm_ver, vm_rev); |
521 have_vm=1; | |
522 } else { | |
523 printf("vo_dga: XF86VidMode Extention not available.\n"); | |
524 } | |
525 | |
526 #define GET_VREFRESH(dotclk, x, y)( (((dotclk)/(x))*1000)/(y) ) | |
527 | |
528 if (have_vm) { | |
529 int screen; | |
530 screen=XDefaultScreen(vo_dga_dpy); | |
531 XF86VidModeGetAllModeLines(vo_dga_dpy,screen,&modecount,&vo_dga_vidmodes); | |
532 | |
533 if(vo_dga_vidmodes != NULL ){ | |
534 | |
535 mX=vo_dga_vidmodes[0]->hdisplay; | |
536 mY=vo_dga_vidmodes[0]->vdisplay; | |
537 | |
538 // TODO: calculate refreshrate from dotclock, hss, hstp, ... | |
539 mVBI = GET_VREFRESH(vo_dga_vidmodes[0]->dotclock, | |
540 vo_dga_vidmodes[0]->htotal, | |
541 vo_dga_vidmodes[0]->vtotal); | |
542 | |
543 j=0; | |
544 for (i=1; i<modecount; i++){ | |
545 printf("vo_dga: (%3d) Trying %4d x %4d @ %3d Hz @ %2d bpp ..", | |
546 i, | |
547 vo_dga_vidmodes[i]->hdisplay, | |
548 vo_dga_vidmodes[i]->vdisplay, | |
549 GET_VREFRESH(vo_dga_vidmodes[i]->dotclock, | |
550 vo_dga_vidmodes[i]->htotal, | |
551 vo_dga_vidmodes[i]->vtotal), | |
552 vo_dga_planes ); | |
553 | |
554 if ( check_mode(d_width, d_height, | |
555 vo_dga_vidmodes[i]->hdisplay, | |
556 vo_dga_vidmodes[i]->vdisplay, | |
557 GET_VREFRESH(vo_dga_vidmodes[i]->dotclock, | |
558 vo_dga_vidmodes[i]->htotal, | |
559 vo_dga_vidmodes[i]->vtotal), | |
560 &mX, &mY, &mVBI )){ | |
561 j = i; | |
562 printf(".ok!!\n"); | |
563 }else{ | |
564 printf(".no\n"); | |
565 } | |
566 } | |
567 | |
568 printf("vo_dga: Selected video mode %4d x %4d @ %3d Hz for image size %3d x %3d.\n", | |
569 mX, mY, mVBI, width, height); | |
570 }else{ | |
571 printf("vo_dga: XF86VidMode returned no screens - using current resolution.\n"); | |
572 } | |
573 dga_modenum = j; | |
574 vo_dga_vp_width = mX; | |
575 vo_dga_vp_height = mY; | |
576 } | |
577 | |
578 | |
579 #else | |
580 printf("vo_dga: Only have DGA 1.0 extension and no XF86VidMode :-(\n"); | |
581 #endif | |
472 #endif | 582 #endif |
473 | 583 |
474 | 584 |
475 vo_dga_src_format = format; | 585 vo_dga_src_format = format; |
476 vo_dga_src_width = width; | 586 vo_dga_src_width = width; |
479 if(vo_dga_src_width > vo_dga_vp_width || | 589 if(vo_dga_src_width > vo_dga_vp_width || |
480 vo_dga_src_height > vo_dga_vp_height) | 590 vo_dga_src_height > vo_dga_vp_height) |
481 { | 591 { |
482 printf("vo_dga: Sorry, video larger than viewport is not yet supported!\n"); | 592 printf("vo_dga: Sorry, video larger than viewport is not yet supported!\n"); |
483 // ugly, do something nicer in the future ... | 593 // ugly, do something nicer in the future ... |
594 #ifndef HAVE_DGA2 | |
595 #ifdef HAVE_XF86VM | |
596 if(vo_dga_vidmodes){ | |
597 XFree(vo_dga_vidmodes); | |
598 vo_dga_vidmodes = NULL; | |
599 } | |
600 #endif | |
601 #endif | |
484 return 1; | 602 return 1; |
485 } | 603 } |
486 | 604 |
487 // now lets start the DGA thing | 605 // now lets start the DGA thing |
488 | 606 |
500 XFree(dgadevice); | 618 XFree(dgadevice); |
501 | 619 |
502 XDGASetViewport (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0, 0, XDGAFlipRetrace); | 620 XDGASetViewport (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0, 0, XDGAFlipRetrace); |
503 | 621 |
504 #else | 622 #else |
505 | 623 |
624 #ifdef HAVE_XF86VM | |
625 XF86VidModeLockModeSwitch(vo_dga_dpy,XDefaultScreen(vo_dga_dpy),0); | |
626 // Two calls are needed to switch modes on my ATI Rage 128. Why? | |
627 // for riva128 one call is enough! | |
628 XF86VidModeSwitchToMode(vo_dga_dpy,XDefaultScreen(vo_dga_dpy),vo_dga_vidmodes[dga_modenum]); | |
629 XF86VidModeSwitchToMode(vo_dga_dpy,XDefaultScreen(vo_dga_dpy),vo_dga_vidmodes[dga_modenum]); | |
630 #endif | |
631 | |
506 XF86DGAGetViewPortSize(vo_dga_dpy,XDefaultScreen(vo_dga_dpy), | 632 XF86DGAGetViewPortSize(vo_dga_dpy,XDefaultScreen(vo_dga_dpy), |
507 &vo_dga_vp_width, | 633 &vo_dga_vp_width, |
508 &vo_dga_vp_height); | 634 &vo_dga_vp_height); |
509 | 635 |
510 XF86DGAGetVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), | 636 XF86DGAGetVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), |
546 XGrabKeyboard (vo_dga_dpy, DefaultRootWindow(vo_dga_dpy), True, | 672 XGrabKeyboard (vo_dga_dpy, DefaultRootWindow(vo_dga_dpy), True, |
547 GrabModeAsync,GrabModeAsync, CurrentTime); | 673 GrabModeAsync,GrabModeAsync, CurrentTime); |
548 XGrabPointer (vo_dga_dpy, DefaultRootWindow(vo_dga_dpy), True, | 674 XGrabPointer (vo_dga_dpy, DefaultRootWindow(vo_dga_dpy), True, |
549 ButtonPressMask,GrabModeAsync, GrabModeAsync, | 675 ButtonPressMask,GrabModeAsync, GrabModeAsync, |
550 None, None, CurrentTime); | 676 None, None, CurrentTime); |
551 | |
552 // TODO: chekc if mem of graphics adaptor is large enough for dbf | 677 // TODO: chekc if mem of graphics adaptor is large enough for dbf |
553 | 678 |
554 | |
555 // set up variables for double buffering ... | 679 // set up variables for double buffering ... |
680 // note: set vo_dga_dbf_mem_offset to NULL to disable doublebuffering | |
556 | 681 |
557 vo_dga_dbf_y_offset = y_off + vo_dga_src_height; | 682 vo_dga_dbf_y_offset = y_off + vo_dga_src_height; |
558 vo_dga_dbf_mem_offset = vo_dga_width * vo_dga_bpp * vo_dga_dbf_y_offset; | 683 vo_dga_dbf_mem_offset = vo_dga_width * vo_dga_bpp * vo_dga_dbf_y_offset; |
559 vo_dga_dbf_current = 0; | 684 vo_dga_dbf_current = 0; |
560 | 685 |
561 if(format ==IMGFMT_YV12 )vo_dga_dbf_mem_offset = 0; | 686 if(format ==IMGFMT_YV12 )vo_dga_dbf_mem_offset = 0; |
562 // disable doublebuffering for YV12 | 687 // disable doublebuffering for YV12 |
688 | |
689 printf("vo_dga: Doublebuffering %s.\n", vo_dga_dbf_mem_offset ? "enabled" : "disabled"); | |
563 | 690 |
564 // now clear screen | 691 // now clear screen |
565 | 692 { |
566 memset(vo_dga_base, 0, vo_dga_width * | 693 int size = vo_dga_width * |
567 (vo_dga_vp_height + (vo_dga_dbf_mem_offset != 0 ? (vo_dga_src_height+y_off) : 0)) * | 694 (vo_dga_vp_height + (vo_dga_dbf_mem_offset != 0 ? |
568 vo_dga_bpp); | 695 (vo_dga_src_height+y_off) : 0)) * |
569 | 696 vo_dga_bpp; |
697 fprintf(stderr, "vo_dga: Before memset: %d. If mplayer exits here, you haven't enough memory for doublebuffering. I'll fix this in the future to check for amount of mem available... For now, select a lower resolution ...\n", size); | |
698 memset(vo_dga_base, 0, size); | |
699 } | |
570 vo_dga_is_running = 1; | 700 vo_dga_is_running = 1; |
571 return 0; | 701 return 0; |
572 } | 702 } |
573 | 703 |
574 //--------------------------------------------------------- | 704 //--------------------------------------------------------- |