Atlas - SDL_blit.c
Home / ext / SDL / src / video Lines: 1 | Size: 9012 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "SDL_internal.h" 22 23#include "SDL_sysvideo.h" 24#include "SDL_surface_c.h" 25#include "SDL_blit_auto.h" 26#include "SDL_blit_copy.h" 27#include "SDL_blit_slow.h" 28#include "SDL_RLEaccel_c.h" 29#include "SDL_pixels_c.h" 30 31// The general purpose software blit routine 32static bool SDLCALL SDL_SoftBlit(SDL_Surface *src, const SDL_Rect *srcrect, 33 SDL_Surface *dst, const SDL_Rect *dstrect) 34{ 35 bool okay; 36 int src_locked; 37 int dst_locked; 38 39 // Everything is okay at the beginning... 40 okay = true; 41 42 // Lock the destination if it's in hardware 43 dst_locked = 0; 44 if (SDL_MUSTLOCK(dst)) { 45 if (!SDL_LockSurface(dst)) { 46 okay = false; 47 } else { 48 dst_locked = 1; 49 } 50 } 51 // Lock the source if it's in hardware 52 src_locked = 0; 53 if (SDL_MUSTLOCK(src)) { 54 if (!SDL_LockSurface(src)) { 55 okay = false; 56 } else { 57 src_locked = 1; 58 } 59 } 60 61 // Set up source and destination buffer pointers, and BLIT! 62 if (okay) { 63 SDL_BlitFunc RunBlit; 64 SDL_BlitInfo *info = &src->map.info; 65 66 // Set up the blit information 67 if (info->src_fmt->bits_per_pixel >= 8) { 68 info->src = (Uint8 *)src->pixels + 69 srcrect->y * src->pitch + 70 srcrect->x * info->src_fmt->bytes_per_pixel; 71 } else { 72 info->src = (Uint8 *)src->pixels + 73 srcrect->y * src->pitch + 74 (srcrect->x * info->src_fmt->bits_per_pixel) / 8; 75 info->leading_skip = 76 ((srcrect->x * info->src_fmt->bits_per_pixel) % 8) / 77 info->src_fmt->bits_per_pixel; 78 } 79 info->src_w = srcrect->w; 80 info->src_h = srcrect->h; 81 info->src_pitch = src->pitch; 82 info->src_skip = 83 info->src_pitch - info->src_w * info->src_fmt->bytes_per_pixel; 84 info->dst = (Uint8 *)dst->pixels + 85 dstrect->y * dst->pitch + 86 dstrect->x * info->dst_fmt->bytes_per_pixel; 87 info->dst_w = dstrect->w; 88 info->dst_h = dstrect->h; 89 info->dst_pitch = dst->pitch; 90 info->dst_skip = 91 info->dst_pitch - info->dst_w * info->dst_fmt->bytes_per_pixel; 92 RunBlit = (SDL_BlitFunc)src->map.data; 93 94 // Run the actual software blit 95 RunBlit(info); 96 } 97 98 // We need to unlock the surfaces if they're locked 99 if (dst_locked) { 100 SDL_UnlockSurface(dst); 101 } 102 if (src_locked) { 103 SDL_UnlockSurface(src); 104 } 105 // Blit is done! 106 return okay; 107} 108 109#ifdef SDL_HAVE_BLIT_AUTO 110 111#ifdef SDL_PLATFORM_MACOS 112#include <sys/sysctl.h> 113 114static bool SDL_UseAltivecPrefetch(void) 115{ 116 const char key[] = "hw.l3cachesize"; 117 u_int64_t result = 0; 118 size_t typeSize = sizeof(result); 119 120 if (sysctlbyname(key, &result, &typeSize, NULL, 0) == 0 && result > 0) { 121 return true; 122 } else { 123 return false; 124 } 125} 126#else 127static bool SDL_UseAltivecPrefetch(void) 128{ 129 // Just guess G4 130 return true; 131} 132#endif // SDL_PLATFORM_MACOS 133 134static SDL_BlitFunc SDL_ChooseBlitFunc(SDL_PixelFormat src_format, SDL_PixelFormat dst_format, int flags, 135 SDL_BlitFuncEntry *entries) 136{ 137 int i, flagcheck = (flags & (SDL_COPY_MODULATE_MASK | SDL_COPY_BLEND_MASK | SDL_COPY_COLORKEY | SDL_COPY_NEAREST)); 138 static unsigned int features = 0x7fffffff; 139 140 // Get the available CPU features 141 if (features == 0x7fffffff) { 142 features = SDL_CPU_ANY; 143 if (SDL_HasMMX()) { 144 features |= SDL_CPU_MMX; 145 } 146 if (SDL_HasSSE()) { 147 features |= SDL_CPU_SSE; 148 } 149 if (SDL_HasSSE2()) { 150 features |= SDL_CPU_SSE2; 151 } 152 if (SDL_HasAltiVec()) { 153 if (SDL_UseAltivecPrefetch()) { 154 features |= SDL_CPU_ALTIVEC_PREFETCH; 155 } else { 156 features |= SDL_CPU_ALTIVEC_NOPREFETCH; 157 } 158 } 159 } 160 161 for (i = 0; entries[i].func; ++i) { 162 // Check for matching pixel formats 163 if (src_format != entries[i].src_format) { 164 continue; 165 } 166 if (dst_format != entries[i].dst_format) { 167 continue; 168 } 169 170 // Check flags 171 if ((flagcheck & entries[i].flags) != flagcheck) { 172 continue; 173 } 174 175 // Check CPU features 176 if ((entries[i].cpu & features) != entries[i].cpu) { 177 continue; 178 } 179 180 // We found the best one! 181 return entries[i].func; 182 } 183 return NULL; 184} 185#endif // SDL_HAVE_BLIT_AUTO 186 187// Figure out which of many blit routines to set up on a surface 188bool SDL_CalculateBlit(SDL_Surface *surface, SDL_Surface *dst) 189{ 190 SDL_BlitFunc blit = NULL; 191 SDL_BlitMap *map = &surface->map; 192 SDL_Colorspace src_colorspace = surface->colorspace; 193 SDL_Colorspace dst_colorspace = dst->colorspace; 194 195 // We don't currently support blitting to < 8 bpp surfaces 196 if (SDL_BITSPERPIXEL(dst->format) < 8) { 197 SDL_InvalidateMap(map); 198 return SDL_SetError("Blit combination not supported"); 199 } 200 201 // We should have cleared out RLE at this point 202 SDL_assert(!(surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL)); 203 204 map->blit = SDL_SoftBlit; 205 map->info.src_surface = surface; 206 map->info.src_fmt = surface->fmt; 207 map->info.src_pal = surface->palette; 208 map->info.dst_surface = dst; 209 map->info.dst_fmt = dst->fmt; 210 map->info.dst_pal = dst->palette; 211 212#ifdef SDL_HAVE_RLE 213 // See if we can do RLE acceleration 214 if (map->info.flags & SDL_COPY_RLE_DESIRED) { 215 if (SDL_RLESurface(surface)) { 216 return true; 217 } 218 } 219#endif 220 221 // Choose a standard blit function 222 if (!blit) { 223 if (src_colorspace != dst_colorspace || 224 SDL_BYTESPERPIXEL(surface->format) > 4 || 225 SDL_BYTESPERPIXEL(dst->format) > 4) { 226 blit = SDL_Blit_Slow_Float; 227 } 228 } 229 if (!blit) { 230 if (map->identity && !(map->info.flags & ~SDL_COPY_RLE_DESIRED)) { 231 blit = SDL_BlitCopy; 232 } else if (SDL_ISPIXELFORMAT_10BIT(surface->format) || 233 SDL_ISPIXELFORMAT_10BIT(dst->format)) { 234 blit = SDL_Blit_Slow; 235 } 236#ifdef SDL_HAVE_BLIT_0 237 else if (SDL_BITSPERPIXEL(surface->format) < 8 && 238 SDL_ISPIXELFORMAT_INDEXED(surface->format)) { 239 blit = SDL_CalculateBlit0(surface); 240 } 241#endif 242#ifdef SDL_HAVE_BLIT_1 243 else if (SDL_BYTESPERPIXEL(surface->format) == 1 && 244 SDL_ISPIXELFORMAT_INDEXED(surface->format)) { 245 blit = SDL_CalculateBlit1(surface); 246 } 247#endif 248#ifdef SDL_HAVE_BLIT_A 249 else if (map->info.flags & SDL_COPY_BLEND) { 250 blit = SDL_CalculateBlitA(surface); 251 } 252#endif 253#ifdef SDL_HAVE_BLIT_N 254 else { 255 blit = SDL_CalculateBlitN(surface); 256 } 257#endif 258 } 259#ifdef SDL_HAVE_BLIT_AUTO 260 if (!blit) { 261 SDL_PixelFormat src_format = surface->format; 262 SDL_PixelFormat dst_format = dst->format; 263 264 blit = 265 SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags, 266 SDL_GeneratedBlitFuncTable); 267 } 268#endif 269 270#ifndef TEST_SLOW_BLIT 271 if (!blit) 272#endif 273 { 274 SDL_PixelFormat src_format = surface->format; 275 SDL_PixelFormat dst_format = dst->format; 276 277 if ((!SDL_ISPIXELFORMAT_INDEXED(src_format) || 278 (src_format == SDL_PIXELFORMAT_INDEX8 && surface->palette)) && 279 !SDL_ISPIXELFORMAT_FOURCC(src_format) && 280 (!SDL_ISPIXELFORMAT_INDEXED(dst_format) || 281 (dst_format == SDL_PIXELFORMAT_INDEX8 && dst->palette)) && 282 !SDL_ISPIXELFORMAT_FOURCC(dst_format)) { 283 blit = SDL_Blit_Slow; 284 } 285 } 286 map->data = (void *)blit; 287 288 // Make sure we have a blit function 289 if (!blit) { 290 SDL_InvalidateMap(map); 291 return SDL_SetError("Blit combination not supported"); 292 } 293 294 return true; 295} 296[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.