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