Mercurial > sdl-ios-xcode
comparison src/video/fbcon/SDL_fbvideo.c @ 106:63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Fixed matrox blit bug where src Y less than dst Y
Fixed hardware surface init when no resolution change
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Fri, 13 Jul 2001 10:19:51 +0000 |
parents | e85e03f195b4 |
children | 5d4bafca35cd |
comparison
equal
deleted
inserted
replaced
105:2136ea8953f9 | 106:63ec24e0575f |
---|---|
131 #endif | 131 #endif |
132 static int FB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); | 132 static int FB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); |
133 static void FB_VideoQuit(_THIS); | 133 static void FB_VideoQuit(_THIS); |
134 | 134 |
135 /* Hardware surface functions */ | 135 /* Hardware surface functions */ |
136 static int FB_InitHWSurfaces(_THIS, char *base, int size); | 136 static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size); |
137 static void FB_FreeHWSurfaces(_THIS); | 137 static void FB_FreeHWSurfaces(_THIS); |
138 static int FB_AllocHWSurface(_THIS, SDL_Surface *surface); | 138 static int FB_AllocHWSurface(_THIS, SDL_Surface *surface); |
139 static int FB_LockHWSurface(_THIS, SDL_Surface *surface); | 139 static int FB_LockHWSurface(_THIS, SDL_Surface *surface); |
140 static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface); | 140 static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface); |
141 static void FB_FreeHWSurface(_THIS, SDL_Surface *surface); | 141 static void FB_FreeHWSurface(_THIS, SDL_Surface *surface); |
142 static void FB_WaitVBL(_THIS); | 142 static void FB_WaitVBL(_THIS); |
143 static void FB_WaitIdle(_THIS); | |
143 static int FB_FlipHWSurface(_THIS, SDL_Surface *surface); | 144 static int FB_FlipHWSurface(_THIS, SDL_Surface *surface); |
144 | 145 |
145 /* Internal palette functions */ | 146 /* Internal palette functions */ |
146 static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo, | 147 static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo, |
147 struct fb_var_screeninfo *vinfo); | 148 struct fb_var_screeninfo *vinfo); |
189 } | 190 } |
190 return(0); | 191 return(0); |
191 } | 192 } |
192 memset(this->hidden, 0, (sizeof *this->hidden)); | 193 memset(this->hidden, 0, (sizeof *this->hidden)); |
193 wait_vbl = FB_WaitVBL; | 194 wait_vbl = FB_WaitVBL; |
195 wait_idle = FB_WaitIdle; | |
194 mouse_fd = -1; | 196 mouse_fd = -1; |
195 keyboard_fd = -1; | 197 keyboard_fd = -1; |
196 | 198 |
197 /* Set the function pointers */ | 199 /* Set the function pointers */ |
198 this->VideoInit = FB_VideoInit; | 200 this->VideoInit = FB_VideoInit; |
663 print_vinfo(&vinfo); | 665 print_vinfo(&vinfo); |
664 #endif | 666 #endif |
665 if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) { | 667 if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) { |
666 return(NULL); | 668 return(NULL); |
667 } | 669 } |
668 current->format->palette->ncolors = 16; | 670 current->format->palette->ncolors = 16; |
669 | 671 |
670 /* Get the fixed information about the console hardware. | 672 /* Get the fixed information about the console hardware. |
671 This is necessary since finfo.line_length changes. | 673 This is necessary since finfo.line_length changes. |
672 */ | 674 */ |
673 if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { | 675 if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { |
757 if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) { | 759 if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) { |
758 SDL_SetError("Couldn't set console screen info"); | 760 SDL_SetError("Couldn't set console screen info"); |
759 return(NULL); | 761 return(NULL); |
760 } | 762 } |
761 } | 763 } |
764 } else { | |
765 int maxheight; | |
766 | |
767 /* Figure out how much video memory is available */ | |
768 if ( flags & SDL_DOUBLEBUF ) { | |
769 maxheight = height*2; | |
770 } else { | |
771 maxheight = height; | |
772 } | |
773 if ( vinfo.yres_virtual > maxheight ) { | |
774 vinfo.yres_virtual = maxheight; | |
775 } | |
762 } | 776 } |
763 cache_vinfo = vinfo; | 777 cache_vinfo = vinfo; |
764 #ifdef FBCON_DEBUG | 778 #ifdef FBCON_DEBUG |
765 fprintf(stderr, "Printing actual vinfo:\n"); | 779 fprintf(stderr, "Printing actual vinfo:\n"); |
766 print_vinfo(&vinfo); | 780 print_vinfo(&vinfo); |
800 current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE); | 814 current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE); |
801 current->w = vinfo.xres; | 815 current->w = vinfo.xres; |
802 current->h = vinfo.yres; | 816 current->h = vinfo.yres; |
803 current->pitch = finfo.line_length; | 817 current->pitch = finfo.line_length; |
804 current->pixels = mapped_mem+mapped_offset; | 818 current->pixels = mapped_mem+mapped_offset; |
819 | |
820 /* Set up the information for hardware surfaces */ | |
821 surfaces_mem = (char *)current->pixels + | |
822 vinfo.yres_virtual*current->pitch; | |
823 surfaces_len = (mapped_memlen-(surfaces_mem-mapped_mem)); | |
824 FB_FreeHWSurfaces(this); | |
825 FB_InitHWSurfaces(this, current, surfaces_mem, surfaces_len); | |
805 | 826 |
806 /* Let the application know we have a hardware palette */ | 827 /* Let the application know we have a hardware palette */ |
807 switch (finfo.visual) { | 828 switch (finfo.visual) { |
808 case FB_VISUAL_PSEUDOCOLOR: | 829 case FB_VISUAL_PSEUDOCOLOR: |
809 current->flags |= SDL_HWPALETTE; | 830 current->flags |= SDL_HWPALETTE; |
818 current->flags |= SDL_DOUBLEBUF; | 839 current->flags |= SDL_DOUBLEBUF; |
819 flip_page = 0; | 840 flip_page = 0; |
820 flip_address[0] = (char *)current->pixels; | 841 flip_address[0] = (char *)current->pixels; |
821 flip_address[1] = (char *)current->pixels+ | 842 flip_address[1] = (char *)current->pixels+ |
822 current->h*current->pitch; | 843 current->h*current->pitch; |
844 this->screen = current; | |
823 FB_FlipHWSurface(this, current); | 845 FB_FlipHWSurface(this, current); |
824 } | 846 this->screen = NULL; |
825 } | 847 } |
826 | 848 } |
827 /* Set up the information for hardware surfaces */ | |
828 surfaces_mem = (char *)current->pixels + | |
829 vinfo.yres_virtual*current->pitch; | |
830 surfaces_len = (mapped_memlen-(surfaces_mem-mapped_mem)); | |
831 FB_FreeHWSurfaces(this); | |
832 FB_InitHWSurfaces(this, surfaces_mem, surfaces_len); | |
833 | 849 |
834 /* Set the update rectangle function */ | 850 /* Set the update rectangle function */ |
835 this->UpdateRects = FB_DirectUpdate; | 851 this->UpdateRects = FB_DirectUpdate; |
836 | 852 |
837 /* We're done */ | 853 /* We're done */ |
865 } | 881 } |
866 printf("\n"); | 882 printf("\n"); |
867 } | 883 } |
868 #endif | 884 #endif |
869 | 885 |
870 static int FB_InitHWSurfaces(_THIS, char *base, int size) | 886 static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size) |
871 { | 887 { |
872 surfaces.prev = NULL; | 888 vidmem_bucket *bucket; |
873 surfaces.used = 0; | 889 |
874 surfaces.base = base; | |
875 surfaces.size = size; | |
876 surfaces.next = NULL; | |
877 surfaces_memtotal = size; | 890 surfaces_memtotal = size; |
878 surfaces_memleft = size; | 891 surfaces_memleft = size; |
892 | |
893 if ( surfaces_memleft > 0 ) { | |
894 bucket = (vidmem_bucket *)malloc(sizeof(*bucket)); | |
895 if ( bucket == NULL ) { | |
896 SDL_OutOfMemory(); | |
897 return(-1); | |
898 } | |
899 bucket->prev = &surfaces; | |
900 bucket->used = 0; | |
901 bucket->dirty = 0; | |
902 bucket->base = base; | |
903 bucket->size = size; | |
904 bucket->next = NULL; | |
905 } else { | |
906 bucket = NULL; | |
907 } | |
908 | |
909 surfaces.prev = NULL; | |
910 surfaces.used = 1; | |
911 surfaces.dirty = 0; | |
912 surfaces.base = screen->pixels; | |
913 surfaces.size = (unsigned int)((long)base - (long)surfaces.base); | |
914 surfaces.next = bucket; | |
915 screen->hwdata = (struct private_hwdata *)&surfaces; | |
879 return(0); | 916 return(0); |
880 } | 917 } |
881 static void FB_FreeHWSurfaces(_THIS) | 918 static void FB_FreeHWSurfaces(_THIS) |
882 { | 919 { |
883 vidmem_bucket *bucket, *freeable; | 920 vidmem_bucket *bucket, *freeable; |
954 } | 991 } |
955 | 992 |
956 /* Set the current bucket values and return it! */ | 993 /* Set the current bucket values and return it! */ |
957 bucket->used = 1; | 994 bucket->used = 1; |
958 bucket->size = size; | 995 bucket->size = size; |
996 bucket->dirty = 0; | |
959 #ifdef FBCON_DEBUG | 997 #ifdef FBCON_DEBUG |
960 fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base); | 998 fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base); |
961 #endif | 999 #endif |
962 surfaces_memleft -= size; | 1000 surfaces_memleft -= size; |
963 surface->flags |= SDL_HWSURFACE; | 1001 surface->flags |= SDL_HWSURFACE; |
964 surface->pixels = bucket->base; | 1002 surface->pixels = bucket->base; |
1003 surface->hwdata = (struct private_hwdata *)bucket; | |
965 return(0); | 1004 return(0); |
966 } | 1005 } |
967 static void FB_FreeHWSurface(_THIS, SDL_Surface *surface) | 1006 static void FB_FreeHWSurface(_THIS, SDL_Surface *surface) |
968 { | 1007 { |
969 vidmem_bucket *bucket, *freeable; | 1008 vidmem_bucket *bucket, *freeable; |
970 | 1009 |
971 /* Look for the bucket in the current list */ | 1010 /* Look for the bucket in the current list */ |
972 for ( bucket=&surfaces; bucket; bucket=bucket->next ) { | 1011 for ( bucket=&surfaces; bucket; bucket=bucket->next ) { |
973 if ( bucket->base == (char *)surface->pixels ) { | 1012 if ( bucket == (vidmem_bucket *)surface->hwdata ) { |
974 break; | 1013 break; |
975 } | 1014 } |
976 } | 1015 } |
977 if ( (bucket == NULL) || ! bucket->used ) { | 1016 if ( bucket && bucket->used ) { |
978 return; | 1017 /* Add the memory back to the total */ |
979 } | 1018 #ifdef DGA_DEBUG |
980 | |
981 /* Add the memory back to the total */ | |
982 #ifdef FBCON_DEBUG | |
983 printf("Freeing bucket of %d bytes\n", bucket->size); | 1019 printf("Freeing bucket of %d bytes\n", bucket->size); |
984 #endif | 1020 #endif |
985 surfaces_memleft += bucket->size; | 1021 surfaces_memleft += bucket->size; |
986 | 1022 |
987 /* Can we merge the space with surrounding buckets? */ | 1023 /* Can we merge the space with surrounding buckets? */ |
988 bucket->used = 0; | 1024 bucket->used = 0; |
989 if ( bucket->next && ! bucket->next->used ) { | 1025 if ( bucket->next && ! bucket->next->used ) { |
990 #ifdef FBCON_DEBUG | 1026 #ifdef DGA_DEBUG |
991 printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size); | 1027 printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size); |
992 #endif | 1028 #endif |
993 freeable = bucket->next; | 1029 freeable = bucket->next; |
994 bucket->size += bucket->next->size; | 1030 bucket->size += bucket->next->size; |
995 bucket->next = bucket->next->next; | 1031 bucket->next = bucket->next->next; |
996 if ( bucket->next ) { | 1032 if ( bucket->next ) { |
997 bucket->next->prev = bucket; | 1033 bucket->next->prev = bucket; |
998 } | 1034 } |
999 free(freeable); | 1035 free(freeable); |
1000 } | 1036 } |
1001 if ( bucket->prev && ! bucket->prev->used ) { | 1037 if ( bucket->prev && ! bucket->prev->used ) { |
1002 #ifdef FBCON_DEBUG | 1038 #ifdef DGA_DEBUG |
1003 printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size); | 1039 printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size); |
1004 #endif | 1040 #endif |
1005 freeable = bucket; | 1041 freeable = bucket; |
1006 bucket->prev->size += bucket->size; | 1042 bucket->prev->size += bucket->size; |
1007 bucket->prev->next = bucket->next; | 1043 bucket->prev->next = bucket->next; |
1008 if ( bucket->next ) { | 1044 if ( bucket->next ) { |
1009 bucket->next->prev = bucket->prev; | 1045 bucket->next->prev = bucket->prev; |
1010 } | 1046 } |
1011 free(freeable); | 1047 free(freeable); |
1048 } | |
1012 } | 1049 } |
1013 surface->pixels = NULL; | 1050 surface->pixels = NULL; |
1051 surface->hwdata = NULL; | |
1014 } | 1052 } |
1015 static int FB_LockHWSurface(_THIS, SDL_Surface *surface) | 1053 static int FB_LockHWSurface(_THIS, SDL_Surface *surface) |
1016 { | 1054 { |
1017 if ( surface == SDL_VideoSurface ) { | 1055 if ( surface == this->screen ) { |
1018 SDL_mutexP(hw_lock); | 1056 SDL_mutexP(hw_lock); |
1057 if ( FB_IsSurfaceBusy(surface) ) { | |
1058 FB_WaitBusySurfaces(this); | |
1059 } | |
1060 } else { | |
1061 if ( FB_IsSurfaceBusy(surface) ) { | |
1062 FB_WaitBusySurfaces(this); | |
1063 } | |
1019 } | 1064 } |
1020 return(0); | 1065 return(0); |
1021 } | 1066 } |
1022 static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface) | 1067 static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface) |
1023 { | 1068 { |
1024 if ( surface == SDL_VideoSurface ) { | 1069 if ( surface == this->screen ) { |
1025 SDL_mutexV(hw_lock); | 1070 SDL_mutexV(hw_lock); |
1026 } | 1071 } |
1027 } | 1072 } |
1028 | 1073 |
1029 static void FB_WaitVBL(_THIS) | 1074 static void FB_WaitVBL(_THIS) |
1032 ioctl(console_fd, FBIOWAITRETRACE, 0); | 1077 ioctl(console_fd, FBIOWAITRETRACE, 0); |
1033 #endif | 1078 #endif |
1034 return; | 1079 return; |
1035 } | 1080 } |
1036 | 1081 |
1082 static void FB_WaitIdle(_THIS) | |
1083 { | |
1084 return; | |
1085 } | |
1086 | |
1037 static int FB_FlipHWSurface(_THIS, SDL_Surface *surface) | 1087 static int FB_FlipHWSurface(_THIS, SDL_Surface *surface) |
1038 { | 1088 { |
1039 /* Wait for vertical retrace and then flip display */ | 1089 /* Wait for vertical retrace and then flip display */ |
1040 cache_vinfo.yoffset = flip_page*surface->h; | 1090 cache_vinfo.yoffset = flip_page*surface->h; |
1091 if ( FB_IsSurfaceBusy(this->screen) ) { | |
1092 FB_WaitBusySurfaces(this); | |
1093 } | |
1041 wait_vbl(this); | 1094 wait_vbl(this); |
1042 if ( ioctl(console_fd, FBIOPAN_DISPLAY, &cache_vinfo) < 0 ) { | 1095 if ( ioctl(console_fd, FBIOPAN_DISPLAY, &cache_vinfo) < 0 ) { |
1043 SDL_SetError("ioctl(FBIOPAN_DISPLAY) failed"); | 1096 SDL_SetError("ioctl(FBIOPAN_DISPLAY) failed"); |
1044 return(-1); | 1097 return(-1); |
1045 } | 1098 } |