comparison src/video/directfb/SDL_DirectFB_video.c @ 728:5446a009107a

MGA CRTC2 support for DirectFB target contributed by Thomas Jarosch.
author Ryan C. Gordon <icculus@icculus.org>
date Fri, 03 Oct 2003 18:26:39 +0000
parents 0009aadb3d01
children d18e2b224d0e
comparison
equal deleted inserted replaced
727:cb1208fcd946 728:5446a009107a
16 License along with this library; if not, write to the Free 16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18
19 Sam Lantinga 19 Sam Lantinga
20 slouken@libsdl.org 20 slouken@libsdl.org
21
22 MGA CRTC2 support by Thomas Jarosch - tomj@simonv.com
23 CRTC2 support is inspired by mplayer's dfbmga driver
24 written by Ville Syrj��<syrjala@sci.fi>
21 */ 25 */
22 26
23 #ifdef SAVE_RCSID 27 #ifdef SAVE_RCSID
24 static char rcsid = 28 static char rcsid =
25 "@(#) $Id$"; 29 "@(#) $Id$";
370 struct DirectFBEnumRect *rect; 374 struct DirectFBEnumRect *rect;
371 IDirectFB *dfb = NULL; 375 IDirectFB *dfb = NULL;
372 IDirectFBDisplayLayer *layer = NULL; 376 IDirectFBDisplayLayer *layer = NULL;
373 IDirectFBEventBuffer *events = NULL; 377 IDirectFBEventBuffer *events = NULL;
374 378
379 HIDDEN->c2layer = NULL, HIDDEN->c2frame = NULL;
380 HIDDEN->enable_mga_crtc2 = 0;
381 HIDDEN->mga_crtc2_stretch_overscan = 1;
375 382
376 ret = DirectFBInit (NULL, NULL); 383 ret = DirectFBInit (NULL, NULL);
377 if (ret) 384 if (ret)
378 { 385 {
379 SetDirectFBerror ("DirectFBInit", ret); 386 SetDirectFBerror ("DirectFBInit", ret);
447 HIDDEN->initialized = 1; 454 HIDDEN->initialized = 1;
448 HIDDEN->dfb = dfb; 455 HIDDEN->dfb = dfb;
449 HIDDEN->layer = layer; 456 HIDDEN->layer = layer;
450 HIDDEN->eventbuffer = events; 457 HIDDEN->eventbuffer = events;
451 458
459 if (getenv("SDL_DIRECTFB_MGA_CRTC2") != NULL)
460 HIDDEN->enable_mga_crtc2 = 1;
461
462 if (HIDDEN->enable_mga_crtc2)
463 {
464 ret = dfb->GetDisplayLayer (dfb, 2, &HIDDEN->c2layer);
465 if (ret)
466 {
467 SetDirectFBerror ("dfb->GetDisplayLayer(CRTC2)", ret);
468 goto error;
469 }
470
471 ret = HIDDEN->layer->SetCooperativeLevel(HIDDEN->layer, DLSCL_EXCLUSIVE);
472 if (ret)
473 {
474 SetDirectFBerror ("layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret);
475 goto error;
476 }
477
478 ret = HIDDEN->c2layer->SetCooperativeLevel(HIDDEN->c2layer, DLSCL_EXCLUSIVE);
479 if (ret)
480 {
481 SetDirectFBerror ("c2layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret);
482 goto error;
483 }
484
485 HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0x0);
486
487 /* Init the surface here as it got a fixed size */
488 DFBDisplayLayerConfig dlc;
489 DFBDisplayLayerConfigFlags failed;
490
491 dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS;
492 dlc.buffermode = DLBM_BACKVIDEO;
493 dlc.options = DLOP_FLICKER_FILTERING;
494 dlc.pixelformat = DSPF_RGB32;
495
496 ret = HIDDEN->c2layer->TestConfiguration( HIDDEN->c2layer, &dlc, &failed );
497 if (ret)
498 {
499 SetDirectFBerror ("c2layer->TestConfiguration", ret);
500 goto error;
501 }
502
503 ret = HIDDEN->c2layer->SetConfiguration( HIDDEN->c2layer, &dlc );
504 if (ret)
505 {
506 SetDirectFBerror ("c2layer->SetConfiguration", ret);
507 goto error;
508 }
509
510 ret = HIDDEN->c2layer->GetSurface( HIDDEN->c2layer, &HIDDEN->c2frame );
511 if (ret)
512 {
513 SetDirectFBerror ("c2layer->GetSurface", ret);
514 goto error;
515 }
516
517 HIDDEN->c2framesize.x = 0;
518 HIDDEN->c2framesize.y = 0;
519 HIDDEN->c2frame->GetSize( HIDDEN->c2frame, &HIDDEN->c2framesize.w, &HIDDEN->c2framesize.h);
520
521 HIDDEN->c2frame->SetBlittingFlags( HIDDEN->c2frame, DSBLIT_NOFX );
522 HIDDEN->c2frame->SetColor( HIDDEN->c2frame, 0, 0, 0, 0xff );
523
524 /* Clear CRTC2 */
525 HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff );
526 HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0 );
527 HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff );
528 HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0 );
529 HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff );
530
531 HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0xFF );
532 }
533
452 return 0; 534 return 0;
453 535
454 error: 536 error:
455 if (events) 537 if (events)
456 events->Release (events); 538 events->Release (events);
457 539
540 if (HIDDEN->c2frame)
541 HIDDEN->c2frame->Release (HIDDEN->c2frame);
542
543 if (HIDDEN->c2layer)
544 HIDDEN->c2layer->Release (HIDDEN->c2layer);
545
458 if (layer) 546 if (layer)
459 layer->Release (layer); 547 layer->Release (layer);
460 548
461 if (dfb) 549 if (dfb)
462 dfb->Release (dfb); 550 dfb->Release (dfb);
513 601
514 /* Set cooperative level depending on flag SDL_FULLSCREEN */ 602 /* Set cooperative level depending on flag SDL_FULLSCREEN */
515 if (flags & SDL_FULLSCREEN) 603 if (flags & SDL_FULLSCREEN)
516 { 604 {
517 ret = HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_FULLSCREEN); 605 ret = HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_FULLSCREEN);
518 if (ret) 606 if (ret && !HIDDEN->enable_mga_crtc2)
519 { 607 {
520 DirectFBError ("dfb->SetCooperativeLevel", ret); 608 DirectFBError ("dfb->SetCooperativeLevel", ret);
521 flags &= ~SDL_FULLSCREEN; 609 flags &= ~SDL_FULLSCREEN;
522 } 610 }
523 } 611 }
586 674
587 current->flags |= SDL_HWPALETTE; 675 current->flags |= SDL_HWPALETTE;
588 } 676 }
589 677
590 current->hwdata->surface = surface; 678 current->hwdata->surface = surface;
679
680 /* MGA CRTC2 stuff */
681 if (HIDDEN->enable_mga_crtc2)
682 {
683 /* no stretching if c2ssize == c2framesize */
684 HIDDEN->c2ssize.x = 0, HIDDEN->c2ssize.y = 0;
685 HIDDEN->c2ssize.w = width;
686 HIDDEN->c2ssize.h = height;
687
688 HIDDEN->c2dsize.x = 0, HIDDEN->c2dsize.y = 0;
689 HIDDEN->c2dsize.w = width;
690 HIDDEN->c2dsize.h = height;
691
692 HIDDEN->mga_crtc2_stretch = 0;
693
694 if (getenv("SDL_DIRECTFB_MGA_STRETCH") != NULL)
695 {
696 /* don't stretch slightly smaller/larger images */
697 if (width < HIDDEN->c2framesize.w*0.95 && height < HIDDEN->c2framesize.w*0.95)
698 {
699 while (HIDDEN->c2dsize.w < HIDDEN->c2framesize.w*HIDDEN->mga_crtc2_stretch_overscan && HIDDEN->c2dsize.h < HIDDEN->c2framesize.h*HIDDEN->mga_crtc2_stretch_overscan)
700 {
701 HIDDEN->c2dsize.w+=4;
702 HIDDEN->c2dsize.h+=3;
703 }
704
705 /* one step down */
706 HIDDEN->c2dsize.w-=4;
707 HIDDEN->c2dsize.h-=3;
708
709 #ifdef DIRECTFB_CRTC2_DEBUG
710 printf("Stretched resolution: X: %d, Y: %d\n", HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
711 #endif
712
713 HIDDEN->mga_crtc2_stretch = 1;
714 }
715 else if (width > HIDDEN->c2framesize.w*0.95 && height > HIDDEN->c2framesize.w*0.95)
716 {
717 while (HIDDEN->c2dsize.w > HIDDEN->c2framesize.w*HIDDEN->mga_crtc2_stretch_overscan || HIDDEN->c2dsize.h > HIDDEN->c2framesize.h*HIDDEN->mga_crtc2_stretch_overscan)
718 {
719 HIDDEN->c2dsize.w-=4;
720 HIDDEN->c2dsize.h-=3;
721 }
722
723 #ifdef DIRECTFB_CRTC2_DEBUG
724 printf("Down-Stretched resolution: X: %d, Y: %d\n", HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
725 #endif
726
727 HIDDEN->mga_crtc2_stretch = 1;
728 }
729 }
730
731 /* Panning */
732 if (HIDDEN->c2framesize.w > HIDDEN->c2dsize.w)
733 HIDDEN->c2dsize.x = (HIDDEN->c2framesize.w - HIDDEN->c2dsize.w) / 2;
734 else
735 HIDDEN->c2dsize.x = (HIDDEN->c2dsize.w - HIDDEN->c2framesize.w) / 2;
736
737 if (HIDDEN->c2framesize.h > HIDDEN->c2dsize.h)
738 HIDDEN->c2dsize.y = (HIDDEN->c2framesize.h - HIDDEN->c2dsize.h) / 2;
739 else
740 HIDDEN->c2dsize.y = (HIDDEN->c2dsize.h - HIDDEN->c2framesize.h) / 2;
741
742 #ifdef DIRECTFB_CRTC2_DEBUG
743 printf("CTRC2 position X: %d, Y: %d\n", HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
744 #endif
745 }
591 746
592 return current; 747 return current;
593 } 748 }
594 749
595 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface) 750 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface)
730 return 0; 885 return 0;
731 } 886 }
732 887
733 static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface) 888 static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface)
734 { 889 {
735 return surface->hwdata->surface->Flip (surface->hwdata->surface, NULL, DSFLIP_WAITFORSYNC); 890 if (HIDDEN->enable_mga_crtc2)
891 {
892 int rtn = surface->hwdata->surface->Flip (surface->hwdata->surface, NULL, 0);
893 if (HIDDEN->mga_crtc2_stretch)
894 HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, surface->hwdata->surface, &HIDDEN->c2ssize, &HIDDEN->c2dsize);
895 else
896 HIDDEN->c2frame->Blit(HIDDEN->c2frame, surface->hwdata->surface, NULL, HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
897
898 HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
899 return rtn;
900 }
901 else
902 return surface->hwdata->surface->Flip (surface->hwdata->surface, NULL, DSFLIP_WAITFORSYNC);
736 } 903 }
737 904
738 static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface) 905 static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface)
739 { 906 {
740 DFBResult ret; 907 DFBResult ret;
761 surface->pixels = NULL; 928 surface->pixels = NULL;
762 } 929 }
763 930
764 static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) 931 static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
765 { 932 {
933 if (HIDDEN->enable_mga_crtc2)
934 {
935 if (HIDDEN->mga_crtc2_stretch)
936 HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, this->screen->hwdata->surface, &HIDDEN->c2ssize, &HIDDEN->c2dsize);
937 else
938 HIDDEN->c2frame->Blit(HIDDEN->c2frame, this->screen->hwdata->surface, NULL, HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
939
940 HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
941 }
766 } 942 }
767 943
768 static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects) 944 static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects)
769 { 945 {
770 DFBRegion region; 946 DFBRegion region;
806 region_valid = 1; 982 region_valid = 1;
807 } 983 }
808 } 984 }
809 985
810 if (region_valid) 986 if (region_valid)
811 surface->Flip (surface, &region, DSFLIP_WAITFORSYNC); 987 {
988 if (HIDDEN->enable_mga_crtc2)
989 {
990 if (HIDDEN->mga_crtc2_stretch)
991 HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, surface, &HIDDEN->c2ssize, &HIDDEN->c2dsize);
992 else
993 HIDDEN->c2frame->Blit(HIDDEN->c2frame, surface, NULL, HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
994
995 HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
996 }
997 else
998 surface->Flip (surface, &region, DSFLIP_WAITFORSYNC);
999 }
812 } 1000 }
813 1001
814 int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 1002 int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
815 { 1003 {
816 IDirectFBPalette *palette = this->screen->hwdata->palette; 1004 IDirectFBPalette *palette = this->screen->hwdata->palette;
853 palette->Release (palette); 1041 palette->Release (palette);
854 1042
855 if (surface) 1043 if (surface)
856 surface->Release (surface); 1044 surface->Release (surface);
857 1045
1046 if (HIDDEN->c2frame)
1047 {
1048 HIDDEN->c2frame->Release (HIDDEN->c2frame);
1049 HIDDEN->c2frame = NULL;
1050 }
1051
858 this->screen->hwdata->surface = NULL; 1052 this->screen->hwdata->surface = NULL;
859 this->screen->hwdata->palette = NULL; 1053 this->screen->hwdata->palette = NULL;
860 1054
861 if (HIDDEN->eventbuffer) 1055 if (HIDDEN->eventbuffer)
862 { 1056 {
863 HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer); 1057 HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer);
864 HIDDEN->eventbuffer = NULL; 1058 HIDDEN->eventbuffer = NULL;
1059 }
1060
1061 if (HIDDEN->c2layer)
1062 {
1063 HIDDEN->c2layer->Release (HIDDEN->c2layer);
1064 HIDDEN->c2layer = NULL;
865 } 1065 }
866 1066
867 if (HIDDEN->layer) 1067 if (HIDDEN->layer)
868 { 1068 {
869 HIDDEN->layer->Release (HIDDEN->layer); 1069 HIDDEN->layer->Release (HIDDEN->layer);