comparison libvo/vo_dga.c @ 266:336b1559a447

- added detection of memsize of graphics card to check if double buffering is possible - fixed resolution switching a little and added more debug output - resolution switching is still according to d_width and d_height which is not always a good idea ...
author acki2
date Sun, 01 Apr 2001 08:07:14 +0000
parents 78e8925fd6b4
children 8ffe2f459851
comparison
equal deleted inserted replaced
265:1d02e6f7c63a 266:336b1559a447
1 #define DISP 1 #define DISP
2 2
3 /* 3 /*
4 * $Id$
5 *
4 * video_out_dga.c, X11 interface 6 * video_out_dga.c, X11 interface
5 * 7 *
6 * 8 *
7 * Copyright ( C ) 2001, Andreas Ackermann. All Rights Reserved. 9 * Copyright ( C ) 2001, Andreas Ackermann. All Rights Reserved.
8 * 10 *
13 * note well: 15 * note well:
14 * 16 *
15 * o this is alpha 17 * o this is alpha
16 * o covers only common video card formats 18 * o covers only common video card formats
17 * o works only on intel architectures 19 * o works only on intel architectures
20 *
21 * $Log$
22 * Revision 1.9 2001/04/01 08:07:14 acki2
23 * - added detection of memsize of graphics card to check if double buffering is possible
24 * - fixed resolution switching a little and added more debug output
25 * - resolution switching is still according to d_width and d_height which
26 * is not always a good idea ...
27 *
18 * 28 *
19 * 30/02/2001 29 * 30/02/2001
20 * 30 *
21 * o query_format(): with DGA 2.0 it returns all depths it supports 31 * o query_format(): with DGA 2.0 it returns all depths it supports
22 * (even 16 when running 32 and vice versa) 32 * (even 16 when running 32 and vice versa)
37 * o included VidMode switching support for DGA1.0, written by Michael Graffam 47 * o included VidMode switching support for DGA1.0, written by Michael Graffam
38 * mgraffam@idsi.net 48 * mgraffam@idsi.net
39 * 49 *
40 */ 50 */
41 51
42 52 //#define VO_DGA_FORCE_DEPTH 32
43 53
44 #include <stdio.h> 54 #include <stdio.h>
45 #include <stdlib.h> 55 #include <stdlib.h>
46 #include <string.h> 56 #include <string.h>
47 57
77 87
78 #ifdef HAVE_XF86VM 88 #ifdef HAVE_XF86VM
79 static XF86VidModeModeInfo **vo_dga_vidmodes=NULL; 89 static XF86VidModeModeInfo **vo_dga_vidmodes=NULL;
80 #endif 90 #endif
81 91
92
93 //extern int verbose; // shouldn't someone remove the static from
94 // its definition in mplayer.c ???
82 95
83 static int vo_dga_width; // bytes per line in framebuffer 96 static int vo_dga_width; // bytes per line in framebuffer
84 static int vo_dga_vp_width; // visible pixels per line in 97 static int vo_dga_vp_width; // visible pixels per line in
85 // framebuffer 98 // framebuffer
86 static int vo_dga_vp_height; // visible lines in framebuffer 99 static int vo_dga_vp_height; // visible lines in framebuffer
244 ( modelines[i].bitsPerPixel != 15 && 257 ( modelines[i].bitsPerPixel != 15 &&
245 modelines[i].bitsPerPixel != 16 258 modelines[i].bitsPerPixel != 16
246 ) 259 )
247 ) 260 )
248 { 261 {
262 // this only for debug reasons ...
263 if(modelines[i].bitsPerPixel == 15 || modelines[i].bitsPerPixel == 16){
264 printf("vo_dga: depth: %d, %08x, %08x, %08x\n",
265 modelines[i].bitsPerPixel,
266 modelines[i].redMask,
267 modelines[i].greenMask,
268 modelines[i].blueMask);
269 }
249 for(k=0, dummy=1; k<modelines[i].bitsPerPixel-1; k++)dummy <<=1; 270 for(k=0, dummy=1; k<modelines[i].bitsPerPixel-1; k++)dummy <<=1;
250 dga_depths |= dummy; 271 dga_depths |= dummy;
251 } 272 }
252 273
253 } 274 }
334 } 355 }
335 356
336 357
337 //---------------------------------------------------------- 358 //----------------------------------------------------------
338 359
339 int check_mode( int x, int y, 360 int check_mode( int num, int x, int y, int bpp,
340 int new_x, int new_y, int new_vbi, 361 int new_x, int new_y, int new_vbi,
341 int *old_x, int *old_y, int *old_vbi){ 362 int *old_x, int *old_y, int *old_vbi){
342 363
364 printf("vo_dga: (%3d) Trying %4d x %4d @ %3d Hz @ %2d bpp ..",
365 num, new_x, new_y, new_vbi, bpp );
366 printf("(old: %dx%d@%d).", *old_x, *old_y, *old_vbi);
343 if ( 367 if (
344 (new_x >= x) && 368 (new_x >= x) &&
345 (new_y >= y) && 369 (new_y >= y) &&
346 ( 370 (
347 // prefer a better resolution either in X or in Y 371 // prefer a better resolution either in X or in Y
357 ( 381 (
358 ((new_x < *old_x) && 382 ((new_x < *old_x) &&
359 !(new_y > *old_y)) || 383 !(new_y > *old_y)) ||
360 ((new_y < *old_y) && 384 ((new_y < *old_y) &&
361 !(new_x > *old_x)) 385 !(new_x > *old_x))
362 ) 386 )
363 // but if we get an identical resolution choose 387 // but if we get an identical resolution choose
364 // the one with the lower refreshrate (saves bandwidth !!!) 388 // the one with the lower refreshrate (saves bandwidth !!!)
365 // as long as it's above 50 Hz (acki2 on 30/3/2001) 389 // as long as it's above 50 Hz (acki2 on 30/3/2001)
366 || 390 ||
367 ( 391 (
368 (new_x == *old_x) && 392 (new_x == *old_x) &&
369 (new_y == *old_y) && 393 (new_y == *old_y) &&
370 ( 394 (
371 ( 395 (
372 new_vbi >= *old_vbi && *old_vbi < 50 396 new_vbi >= *old_vbi && *old_vbi < 50
373 ) 397 )
374 || 398 ||
375 ( 399 (
376 *old_vbi >= 50 && 400 *old_vbi >= 50 &&
377 new_vbi < *old_vbi && 401 new_vbi < *old_vbi &&
378 new_vbi >= 50 402 new_vbi >= 50
379 )
380 ) 403 )
381 ) 404 )
382 ) 405 )
383 ) 406 )
407 )
384 { 408 {
385 *old_x = new_x; 409 *old_x = new_x;
386 *old_y = new_y; 410 *old_y = new_y;
387 *old_vbi = new_vbi; 411 *old_vbi = new_vbi;
412 printf(".ok!!\n");
388 return 1; 413 return 1;
389 }else{ 414 }else{
415 printf(".no\n");
390 return 0; 416 return 0;
391 } 417 }
392 } 418 }
393 419
394 420
402 428
403 int x_off, y_off; 429 int x_off, y_off;
404 430
405 #ifdef HAVE_DGA2 431 #ifdef HAVE_DGA2
406 // needed to change DGA video mode 432 // needed to change DGA video mode
407 int modecount,mX, mY, mVBI, i,j; 433 int modecount, mX=100000, mY=100000 , mVBI=100000, i,j=0;
408 int dga_modenum; 434 int dga_modenum;
409 XDGAMode *modelines=NULL; 435 XDGAMode *modelines=NULL;
410 XDGADevice *dgadevice; 436 XDGADevice *dgadevice;
437 int max_vpy_pos;
411 #else 438 #else
412 #ifdef HAVE_XF86VM 439 #ifdef HAVE_XF86VM
413 unsigned int vm_event, vm_error; 440 unsigned int vm_event, vm_error;
414 unsigned int vm_ver, vm_rev; 441 unsigned int vm_ver, vm_rev;
415 int i,j,have_vm=0; 442 int i, j=0, have_vm=0;
416 int modecount,mX, mY, mVBI, dga_modenum; 443 int modecount, mX=100000, mY=100000, mVBI=100000, dga_modenum;
417 #endif 444 #endif
418 int bank, ram; 445 int bank, ram;
419 #endif 446 #endif
420 447
421 if( vo_dga_is_running )return -1; 448 if( vo_dga_is_running )return -1;
463 // Code to change the video mode added by Michael Graffam 490 // Code to change the video mode added by Michael Graffam
464 // mgraffam@idsi.net 491 // mgraffam@idsi.net
465 if (modelines==NULL) 492 if (modelines==NULL)
466 modelines=XDGAQueryModes(vo_dga_dpy, XDefaultScreen(vo_dga_dpy),&modecount); 493 modelines=XDGAQueryModes(vo_dga_dpy, XDefaultScreen(vo_dga_dpy),&modecount);
467 494
468 mX=modelines[0].imageWidth;
469 mY=modelines[0].imageHeight;
470 mVBI = modelines[0].verticalRefresh;
471
472
473 printf("vo_dga: Using DGA 2.0 mode changing support\n"); 495 printf("vo_dga: Using DGA 2.0 mode changing support\n");
474 j=0;
475 // offbyone-error !!! i<=modecount is WRONG !!! 496 // offbyone-error !!! i<=modecount is WRONG !!!
476 for (i=1; i<modecount; i++) 497 for (i=0; i<modecount; i++)
477 { 498 {
478 if( modelines[i].bitsPerPixel == vo_dga_planes) 499 if( modelines[i].bitsPerPixel == vo_dga_planes)
479 { 500 {
480 printf("vo_dga: (%3d) Trying %4d x %4d @ %3d Hz @ %2d bpp ..", 501 if ( check_mode(i, d_width, d_height, modelines[i].bitsPerPixel,
481 i,
482 modelines[i].viewportWidth,
483 modelines[i].viewportHeight,
484 (unsigned int) modelines[i].verticalRefresh,
485 modelines[i].bitsPerPixel );
486
487 if ( check_mode(d_width, d_height,
488 modelines[i].viewportWidth, 502 modelines[i].viewportWidth,
489 modelines[i].viewportHeight, 503 modelines[i].viewportHeight,
490 (unsigned) modelines[i].verticalRefresh, 504 (unsigned) modelines[i].verticalRefresh,
491 &mX, &mY, &mVBI )) 505 &mX, &mY, &mVBI )) j = i;
492 {
493 j = i;
494 printf(".ok!!\n");
495 }else{
496 printf(".no\n");
497 }
498 } 506 }
499 } 507 }
500 printf("vo_dga: Selected video mode %4d x %4d @ %3d Hz for image size %3d x %3d.\n", 508 printf("vo_dga: Selected video mode %4d x %4d @ %3d Hz for image size %3d x %3d.\n",
501 mX, mY, mVBI, width, height); 509 mX, mY, mVBI, width, height);
502 510
503 vo_dga_vp_width =mX; 511 vo_dga_vp_width =mX;
504 vo_dga_vp_height = mY; 512 vo_dga_vp_height = mY;
505 vo_dga_width = modelines[j].bytesPerScanline / vo_dga_bpp; 513 vo_dga_width = modelines[j].bytesPerScanline / vo_dga_bpp;
506 dga_modenum = modelines[j].num; 514 dga_modenum = modelines[j].num;
515 max_vpy_pos = modelines[j].maxViewportY;
507 516
508 XFree(modelines); 517 XFree(modelines);
509 modelines = NULL; 518 modelines = NULL;
510 519
511 #else 520 #else
512
513 521
514 #ifdef HAVE_XF86VM 522 #ifdef HAVE_XF86VM
515 523
516 printf("vo_dga: DGA 1.0 compatibility code: Using XF86VidMode for mode switching!\n"); 524 printf("vo_dga: DGA 1.0 compatibility code: Using XF86VidMode for mode switching!\n");
517 525
518 if (XF86VidModeQueryExtension(vo_dga_dpy, &vm_event, &vm_error)) { 526 if (XF86VidModeQueryExtension(vo_dga_dpy, &vm_event, &vm_error)) {
519 XF86VidModeQueryVersion(vo_dga_dpy, &vm_ver, &vm_rev); 527 XF86VidModeQueryVersion(vo_dga_dpy, &vm_ver, &vm_rev);
520 printf("vo_dga: XF86VidMode Extension v%i.%i\n", vm_ver, vm_rev); 528 printf("vo_dga: XF86VidMode Extension v%i.%i\n", vm_ver, vm_rev);
521 have_vm=1; 529 have_vm=1;
522 } else { 530 } else {
523 printf("vo_dga: XF86VidMode Extention not available.\n"); 531 printf("vo_dga: XF86VidMode Extension not available.\n");
524 } 532 }
525 533
526 #define GET_VREFRESH(dotclk, x, y)( (((dotclk)/(x))*1000)/(y) ) 534 #define GET_VREFRESH(dotclk, x, y)( (((dotclk)/(x))*1000)/(y) )
527 535
528 if (have_vm) { 536 if (have_vm) {
529 int screen; 537 int screen;
530 screen=XDefaultScreen(vo_dga_dpy); 538 screen=XDefaultScreen(vo_dga_dpy);
531 XF86VidModeGetAllModeLines(vo_dga_dpy,screen,&modecount,&vo_dga_vidmodes); 539 XF86VidModeGetAllModeLines(vo_dga_dpy,screen,&modecount,&vo_dga_vidmodes);
532 540
533 if(vo_dga_vidmodes != NULL ){ 541 if(vo_dga_vidmodes != NULL ){
534 542 for (i=0; i<modecount; i++){
535 mX=vo_dga_vidmodes[0]->hdisplay; 543 if ( check_mode(i, d_width, d_height, vo_dga_planes,
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, 544 vo_dga_vidmodes[i]->hdisplay,
556 vo_dga_vidmodes[i]->vdisplay, 545 vo_dga_vidmodes[i]->vdisplay,
557 GET_VREFRESH(vo_dga_vidmodes[i]->dotclock, 546 GET_VREFRESH(vo_dga_vidmodes[i]->dotclock,
558 vo_dga_vidmodes[i]->htotal, 547 vo_dga_vidmodes[i]->htotal,
559 vo_dga_vidmodes[i]->vtotal), 548 vo_dga_vidmodes[i]->vtotal),
560 &mX, &mY, &mVBI )){ 549 &mX, &mY, &mVBI )) j = i;
561 j = i;
562 printf(".ok!!\n");
563 }else{
564 printf(".no\n");
565 }
566 } 550 }
567 551
568 printf("vo_dga: Selected video mode %4d x %4d @ %3d Hz for image size %3d x %3d.\n", 552 printf("vo_dga: Selected video mode %4d x %4d @ %3d Hz for image size %3d x %3d.\n",
569 mX, mY, mVBI, width, height); 553 mX, mY, mVBI, width, height);
570 }else{ 554 }else{
578 562
579 #else 563 #else
580 printf("vo_dga: Only have DGA 1.0 extension and no XF86VidMode :-(\n"); 564 printf("vo_dga: Only have DGA 1.0 extension and no XF86VidMode :-(\n");
581 #endif 565 #endif
582 #endif 566 #endif
583
584 567
585 vo_dga_src_format = format; 568 vo_dga_src_format = format;
586 vo_dga_src_width = width; 569 vo_dga_src_width = width;
587 vo_dga_src_height = height; 570 vo_dga_src_height = height;
588 571
684 vo_dga_dbf_current = 0; 667 vo_dga_dbf_current = 0;
685 668
686 if(format ==IMGFMT_YV12 )vo_dga_dbf_mem_offset = 0; 669 if(format ==IMGFMT_YV12 )vo_dga_dbf_mem_offset = 0;
687 // disable doublebuffering for YV12 670 // disable doublebuffering for YV12
688 671
689 printf("vo_dga: Doublebuffering %s.\n", vo_dga_dbf_mem_offset ? "enabled" : "disabled"); 672 #ifdef HAVE_DGA2
673 if(vo_dga_vp_height>max_vpy_pos){
674 vo_dga_dbf_mem_offset = 0;
675 printf("vo_dga: Not enough memory for double buffering!\n");
676 }
677 #endif
690 678
691 // now clear screen 679 // now clear screen
692 { 680 {
693 int size = vo_dga_width * 681 int size = vo_dga_width *
694 (vo_dga_vp_height + (vo_dga_dbf_mem_offset != 0 ? 682 (vo_dga_vp_height + (vo_dga_dbf_mem_offset != 0 ?
695 (vo_dga_src_height+y_off) : 0)) * 683 (vo_dga_src_height+y_off) : 0)) *
696 vo_dga_bpp; 684 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); 685 #ifndef HAVE_DGA2
698 memset(vo_dga_base, 0, size); 686 printf("%d, %d\n", size, ram);
699 } 687 if(size>ram*1024){
688 vo_dga_dbf_mem_offset = 0;
689 printf("vo_dga: Not enough memory for double buffering!\n");
690 size -= (vo_dga_src_height+y_off) * vo_dga_width * vo_dga_bpp;
691 }
692 #endif
693
694 printf("vo_dga: Clearing framebuffer (%d bytes). If mplayer exits", size);
695 printf(" here, you haven't enough memory on your card.\n");
696 fflush(stdout);
697 memset(vo_dga_base, 0, size);
698 }
699 printf("vo_dga: Doublebuffering %s.\n", vo_dga_dbf_mem_offset ? "enabled" : "disabled");
700 vo_dga_is_running = 1; 700 vo_dga_is_running = 1;
701 return 0; 701 return 0;
702 } 702 }
703 703
704 //--------------------------------------------------------- 704 //---------------------------------------------------------