Mercurial > sdl-ios-xcode
comparison src/video/SDL_surface.c @ 1672:8e754b82cecc SDL-1.3
Updated SDL_Surface code for software-only access, fixed some build errors
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 09 Jun 2006 07:06:12 +0000 |
parents | eef792d31de8 |
children | 90bf530ced8e |
comparison
equal
deleted
inserted
replaced
1671:89f7510fe17a | 1672:8e754b82cecc |
---|---|
20 slouken@libsdl.org | 20 slouken@libsdl.org |
21 */ | 21 */ |
22 #include "SDL_config.h" | 22 #include "SDL_config.h" |
23 | 23 |
24 #include "SDL_video.h" | 24 #include "SDL_video.h" |
25 #include "SDL_compat.h" | |
25 #include "SDL_sysvideo.h" | 26 #include "SDL_sysvideo.h" |
26 #include "SDL_cursor_c.h" | |
27 #include "SDL_blit.h" | 27 #include "SDL_blit.h" |
28 #include "SDL_RLEaccel_c.h" | 28 #include "SDL_RLEaccel_c.h" |
29 #include "SDL_pixels_c.h" | 29 #include "SDL_pixels_c.h" |
30 #include "SDL_leaks.h" | 30 #include "SDL_leaks.h" |
31 | 31 |
68 } | 68 } |
69 surface->w = width; | 69 surface->w = width; |
70 surface->h = height; | 70 surface->h = height; |
71 surface->pitch = SDL_CalculatePitch(surface); | 71 surface->pitch = SDL_CalculatePitch(surface); |
72 surface->pixels = NULL; | 72 surface->pixels = NULL; |
73 surface->hwdata = NULL; | |
74 surface->locked = 0; | 73 surface->locked = 0; |
75 surface->map = NULL; | 74 surface->map = NULL; |
76 SDL_SetClipRect(surface, NULL); | 75 SDL_SetClipRect(surface, NULL); |
77 SDL_FormatChanged(surface); | 76 SDL_FormatChanged(surface); |
78 | 77 |
112 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, | 111 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, |
113 Uint32 Amask) | 112 Uint32 Amask) |
114 { | 113 { |
115 SDL_Surface *surface; | 114 SDL_Surface *surface; |
116 | 115 |
117 surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, depth, | 116 surface = |
118 Rmask, Gmask, Bmask, Amask); | 117 SDL_CreateRGBSurface(0, 0, 0, depth, Rmask, Gmask, Bmask, Amask); |
119 if (surface != NULL) { | 118 if (surface != NULL) { |
120 surface->flags |= SDL_PREALLOC; | 119 surface->flags |= SDL_PREALLOC; |
121 surface->pixels = pixels; | 120 surface->pixels = pixels; |
122 surface->w = width; | 121 surface->w = width; |
123 surface->h = height; | 122 surface->h = height; |
144 (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { | 143 (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { |
145 SDL_SetError("Unknown texture format"); | 144 SDL_SetError("Unknown texture format"); |
146 return NULL; | 145 return NULL; |
147 } | 146 } |
148 | 147 |
149 surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, bpp, | 148 surface = SDL_CreateRGBSurface(0, 0, 0, bpp, Rmask, Gmask, Bmask, Amask); |
150 Rmask, Gmask, Bmask, Amask); | |
151 if (surface != NULL) { | 149 if (surface != NULL) { |
152 surface->flags |= (SDL_HWSURFACE | SDL_PREALLOC); | 150 surface->flags |= (SDL_HWSURFACE | SDL_PREALLOC); |
153 surface->w = width; | 151 surface->w = w; |
154 surface->h = height; | 152 surface->h = h; |
153 surface->lock_data = (void *) textureID; | |
155 SDL_SetClipRect(surface, NULL); | 154 SDL_SetClipRect(surface, NULL); |
156 } | 155 } |
157 return surface; | 156 return surface; |
158 } | 157 } |
159 | 158 |
219 if (surface->flags & SDL_RLEACCEL) { | 218 if (surface->flags & SDL_RLEACCEL) { |
220 SDL_UnRLESurface(surface, 1); | 219 SDL_UnRLESurface(surface, 1); |
221 } | 220 } |
222 | 221 |
223 if (flag) { | 222 if (flag) { |
224 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
225 | |
226 surface->flags |= SDL_SRCCOLORKEY; | 223 surface->flags |= SDL_SRCCOLORKEY; |
227 surface->format->colorkey = key; | 224 surface->format->colorkey = key; |
228 if ((surface->flags & SDL_HWACCEL) == SDL_HWACCEL) { | |
229 if ((_this->SetHWColorKey == NULL) || | |
230 (_this->SetHWColorKey(_this, surface, key) < 0)) { | |
231 surface->flags &= ~SDL_HWACCEL; | |
232 } | |
233 } | |
234 if (flag & SDL_RLEACCELOK) { | 225 if (flag & SDL_RLEACCELOK) { |
235 surface->flags |= SDL_RLEACCELOK; | 226 surface->flags |= SDL_RLEACCELOK; |
236 } else { | 227 } else { |
237 surface->flags &= ~SDL_RLEACCELOK; | 228 surface->flags &= ~SDL_RLEACCELOK; |
238 } | 229 } |
270 | 261 |
271 if (!(flag & SDL_RLEACCELOK) && (surface->flags & SDL_RLEACCEL)) | 262 if (!(flag & SDL_RLEACCELOK) && (surface->flags & SDL_RLEACCEL)) |
272 SDL_UnRLESurface(surface, 1); | 263 SDL_UnRLESurface(surface, 1); |
273 | 264 |
274 if (flag) { | 265 if (flag) { |
275 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
276 | |
277 surface->flags |= SDL_SRCALPHA; | 266 surface->flags |= SDL_SRCALPHA; |
278 surface->format->alpha = value; | 267 surface->format->alpha = value; |
279 if ((surface->flags & SDL_HWACCEL) == SDL_HWACCEL) { | |
280 if ((_this->SetHWAlpha == NULL) || | |
281 (_this->SetHWAlpha(_this, surface, value) < 0)) { | |
282 surface->flags &= ~SDL_HWACCEL; | |
283 } | |
284 } | |
285 if (flag & SDL_RLEACCELOK) { | 268 if (flag & SDL_RLEACCELOK) { |
286 surface->flags |= SDL_RLEACCELOK; | 269 surface->flags |= SDL_RLEACCELOK; |
287 } else { | 270 } else { |
288 surface->flags &= ~SDL_RLEACCELOK; | 271 surface->flags &= ~SDL_RLEACCELOK; |
289 } | 272 } |
295 * The representation for software surfaces is independent of | 278 * The representation for software surfaces is independent of |
296 * per-surface alpha, so no need to invalidate the blit mapping | 279 * per-surface alpha, so no need to invalidate the blit mapping |
297 * if just the alpha value was changed. (If either is 255, we still | 280 * if just the alpha value was changed. (If either is 255, we still |
298 * need to invalidate.) | 281 * need to invalidate.) |
299 */ | 282 */ |
300 if ((surface->flags & SDL_HWACCEL) == SDL_HWACCEL | 283 if (oldflags != surface->flags |
301 || oldflags != surface->flags | 284 || (((oldalpha + 1) ^ (value + 1)) & 0x100)) { |
302 || (((oldalpha + 1) ^ (value + 1)) & 0x100)) | |
303 SDL_InvalidateMap(surface->map); | 285 SDL_InvalidateMap(surface->map); |
286 } | |
304 return (0); | 287 return (0); |
305 } | 288 } |
306 | 289 |
307 int | 290 int |
308 SDL_SetAlphaChannel(SDL_Surface * surface, Uint8 value) | 291 SDL_SetAlphaChannel(SDL_Surface * surface, Uint8 value) |
436 */ | 419 */ |
437 int | 420 int |
438 SDL_LowerBlit(SDL_Surface * src, SDL_Rect * srcrect, | 421 SDL_LowerBlit(SDL_Surface * src, SDL_Rect * srcrect, |
439 SDL_Surface * dst, SDL_Rect * dstrect) | 422 SDL_Surface * dst, SDL_Rect * dstrect) |
440 { | 423 { |
441 SDL_blit do_blit; | |
442 | |
443 /* Check to make sure the blit mapping is valid */ | 424 /* Check to make sure the blit mapping is valid */ |
444 if ((src->map->dst != dst) || | 425 if ((src->map->dst != dst) || |
445 (src->map->dst->format_version != src->map->format_version)) { | 426 (src->map->dst->format_version != src->map->format_version)) { |
446 if (SDL_MapSurface(src, dst) < 0) { | 427 if (SDL_MapSurface(src, dst) < 0) { |
447 return (-1); | 428 return (-1); |
448 } | 429 } |
449 } | 430 } |
450 | 431 return (src->map->sw_blit(src, srcrect, dst, dstrect)); |
451 /* Figure out which blitter to use */ | |
452 if ((src->flags & SDL_HWACCEL) == SDL_HWACCEL) { | |
453 do_blit = src->map->hw_blit; | |
454 } else { | |
455 do_blit = src->map->sw_blit; | |
456 } | |
457 return (do_blit(src, srcrect, dst, dstrect)); | |
458 } | 432 } |
459 | 433 |
460 | 434 |
461 int | 435 int |
462 SDL_UpperBlit(SDL_Surface * src, SDL_Rect * srcrect, | 436 SDL_UpperBlit(SDL_Surface * src, SDL_Rect * srcrect, |
599 if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) { | 573 if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) { |
600 return (0); | 574 return (0); |
601 } | 575 } |
602 } else { | 576 } else { |
603 dstrect = &dst->clip_rect; | 577 dstrect = &dst->clip_rect; |
604 } | |
605 | |
606 /* Check for hardware acceleration */ | |
607 if (((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && | |
608 _this->info.blit_fill) { | |
609 return (_this->FillHWRect(_this, dst, dstrect, color)); | |
610 } | 578 } |
611 | 579 |
612 /* Perform software fill */ | 580 /* Perform software fill */ |
613 if (SDL_LockSurface(dst) != 0) { | 581 if (SDL_LockSurface(dst) != 0) { |
614 return (-1); | 582 return (-1); |
630 * SDL_memset() on PPC (both glibc and codewarrior) uses | 598 * SDL_memset() on PPC (both glibc and codewarrior) uses |
631 * the dcbz (Data Cache Block Zero) instruction, which | 599 * the dcbz (Data Cache Block Zero) instruction, which |
632 * causes an alignment exception if the destination is | 600 * causes an alignment exception if the destination is |
633 * uncachable, so only use it on software surfaces | 601 * uncachable, so only use it on software surfaces |
634 */ | 602 */ |
635 if ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) { | 603 if (dst->flags & SDL_HWSURFACE) { |
636 if (dstrect->w >= 8) { | 604 if (dstrect->w >= 8) { |
637 /* | 605 /* |
638 * 64-bit stores are probably most | 606 * 64-bit stores are probably most |
639 * efficient to uncached video memory | 607 * efficient to uncached video memory |
640 */ | 608 */ |
750 SDL_LockSurface(SDL_Surface * surface) | 718 SDL_LockSurface(SDL_Surface * surface) |
751 { | 719 { |
752 if (!surface->locked) { | 720 if (!surface->locked) { |
753 /* Perform the lock */ | 721 /* Perform the lock */ |
754 if (surface->flags & SDL_HWSURFACE) { | 722 if (surface->flags & SDL_HWSURFACE) { |
755 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | 723 if (SDL_LockTexture |
756 if (_this->LockHWSurface(_this, surface) < 0) { | 724 ((SDL_TextureID) surface->lock_data, NULL, 1, |
725 &surface->pixels, &surface->pitch) < 0) { | |
757 return (-1); | 726 return (-1); |
758 } | 727 } |
759 } | 728 } |
760 if (surface->flags & SDL_RLEACCEL) { | 729 if (surface->flags & SDL_RLEACCEL) { |
761 SDL_UnRLESurface(surface, 1); | 730 SDL_UnRLESurface(surface, 1); |
762 surface->flags |= SDL_RLEACCEL; /* save accel'd state */ | 731 surface->flags |= SDL_RLEACCEL; /* save accel'd state */ |
763 } | 732 } |
764 /* This needs to be done here in case pixels changes value */ | |
765 surface->pixels = (Uint8 *) surface->pixels + surface->offset; | |
766 } | 733 } |
767 | 734 |
768 /* Increment the surface lock count, for recursive locks */ | 735 /* Increment the surface lock count, for recursive locks */ |
769 ++surface->locked; | 736 ++surface->locked; |
770 | 737 |
781 /* Only perform an unlock if we are locked */ | 748 /* Only perform an unlock if we are locked */ |
782 if (!surface->locked || (--surface->locked > 0)) { | 749 if (!surface->locked || (--surface->locked > 0)) { |
783 return; | 750 return; |
784 } | 751 } |
785 | 752 |
786 /* Perform the unlock */ | |
787 surface->pixels = (Uint8 *) surface->pixels - surface->offset; | |
788 | |
789 /* Unlock hardware or accelerated surfaces */ | 753 /* Unlock hardware or accelerated surfaces */ |
790 if (surface->flags & SDL_HWSURFACE) { | 754 if (surface->flags & SDL_HWSURFACE) { |
791 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | 755 SDL_UnlockTexture((SDL_TextureID) surface->lock_data); |
792 _this->UnlockHWSurface(_this, surface); | |
793 } else { | 756 } else { |
794 /* Update RLE encoded surface with new data */ | 757 /* Update RLE encoded surface with new data */ |
795 if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) { | 758 if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) { |
796 surface->flags &= ~SDL_RLEACCEL; /* stop lying */ | 759 surface->flags &= ~SDL_RLEACCEL; /* stop lying */ |
797 SDL_RLESurface(surface); | 760 SDL_RLESurface(surface); |
823 } | 786 } |
824 if (i == format->palette->ncolors) { | 787 if (i == format->palette->ncolors) { |
825 SDL_SetError("Empty destination palette"); | 788 SDL_SetError("Empty destination palette"); |
826 return (NULL); | 789 return (NULL); |
827 } | 790 } |
828 } | |
829 | |
830 /* Only create hw surfaces with alpha channel if hw alpha blits | |
831 are supported */ | |
832 if (format->Amask != 0 && (flags & SDL_HWSURFACE)) { | |
833 const SDL_VideoInfo *vi = SDL_GetVideoInfo(); | |
834 if (!vi || !vi->blit_hw_A) | |
835 flags &= ~SDL_HWSURFACE; | |
836 } | 791 } |
837 | 792 |
838 /* Create a new surface with the desired format */ | 793 /* Create a new surface with the desired format */ |
839 convert = SDL_CreateRGBSurface(flags, | 794 convert = SDL_CreateRGBSurface(flags, |
840 surface->w, surface->h, | 795 surface->w, surface->h, |
925 return; | 880 return; |
926 } | 881 } |
927 while (surface->locked > 0) { | 882 while (surface->locked > 0) { |
928 SDL_UnlockSurface(surface); | 883 SDL_UnlockSurface(surface); |
929 } | 884 } |
930 if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) { | 885 if (surface->flags & SDL_RLEACCEL) { |
931 SDL_UnRLESurface(surface, 0); | 886 SDL_UnRLESurface(surface, 0); |
932 } | 887 } |
933 if (surface->format) { | 888 if (surface->format) { |
934 SDL_FreeFormat(surface->format); | 889 SDL_FreeFormat(surface->format); |
935 surface->format = NULL; | 890 surface->format = NULL; |
936 } | 891 } |
937 if (surface->map != NULL) { | 892 if (surface->map != NULL) { |
938 SDL_FreeBlitMap(surface->map); | 893 SDL_FreeBlitMap(surface->map); |
939 surface->map = NULL; | 894 surface->map = NULL; |
940 } | 895 } |
941 if (surface->hwdata) { | 896 /* Should we destroy the texture too? |
942 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | 897 if (surface->flags & SDL_HWSURFACE) { |
943 _this->FreeHWSurface(_this, surface); | 898 SDL_DestroyTexture((SDL_TextureID)surface->lock_data); |
944 } | 899 } |
900 */ | |
945 if (surface->pixels && ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC)) { | 901 if (surface->pixels && ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC)) { |
946 SDL_free(surface->pixels); | 902 SDL_free(surface->pixels); |
947 } | 903 } |
948 SDL_free(surface); | 904 SDL_free(surface); |
949 #ifdef CHECK_LEAKS | 905 #ifdef CHECK_LEAKS |