Mercurial > mplayer.hg
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 //--------------------------------------------------------- |