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 //---------------------------------------------------------