Atlas - SDL_fillrect.c

Home / ext / SDL2 / src / video Lines: 1 | Size: 8499 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 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_video.h" 24#include "SDL_blit.h" 25 26 27#ifdef __SSE__ 28/* *INDENT-OFF* */ 29 30#ifdef _MSC_VER 31#define SSE_BEGIN \ 32 __m128 c128; \ 33 c128.m128_u32[0] = color; \ 34 c128.m128_u32[1] = color; \ 35 c128.m128_u32[2] = color; \ 36 c128.m128_u32[3] = color; 37#else 38#define SSE_BEGIN \ 39 __m128 c128; \ 40 DECLARE_ALIGNED(Uint32, cccc[4], 16); \ 41 cccc[0] = color; \ 42 cccc[1] = color; \ 43 cccc[2] = color; \ 44 cccc[3] = color; \ 45 c128 = *(__m128 *)cccc; 46#endif 47 48#define SSE_WORK \ 49 for (i = n / 64; i--;) { \ 50 _mm_stream_ps((float *)(p+0), c128); \ 51 _mm_stream_ps((float *)(p+16), c128); \ 52 _mm_stream_ps((float *)(p+32), c128); \ 53 _mm_stream_ps((float *)(p+48), c128); \ 54 p += 64; \ 55 } 56 57#define SSE_END 58 59#define DEFINE_SSE_FILLRECT(bpp, type) \ 60static void \ 61SDL_FillRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \ 62{ \ 63 int i, n; \ 64 Uint8 *p = NULL; \ 65 \ 66 SSE_BEGIN; \ 67 \ 68 while (h--) { \ 69 n = w * bpp; \ 70 p = pixels; \ 71 \ 72 if (n > 63) { \ 73 int adjust = 16 - ((uintptr_t)p & 15); \ 74 if (adjust < 16) { \ 75 n -= adjust; \ 76 adjust /= bpp; \ 77 while (adjust--) { \ 78 *((type *)p) = (type)color; \ 79 p += bpp; \ 80 } \ 81 } \ 82 SSE_WORK; \ 83 } \ 84 if (n & 63) { \ 85 int remainder = (n & 63); \ 86 remainder /= bpp; \ 87 while (remainder--) { \ 88 *((type *)p) = (type)color; \ 89 p += bpp; \ 90 } \ 91 } \ 92 pixels += pitch; \ 93 } \ 94 \ 95 SSE_END; \ 96} 97 98static void 99SDL_FillRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) 100{ 101 int i, n; 102 103 SSE_BEGIN; 104 while (h--) { 105 Uint8 *p = pixels; 106 n = w; 107 108 if (n > 63) { 109 int adjust = 16 - ((uintptr_t)p & 15); 110 if (adjust) { 111 n -= adjust; 112 SDL_memset(p, color, adjust); 113 p += adjust; 114 } 115 SSE_WORK; 116 } 117 if (n & 63) { 118 int remainder = (n & 63); 119 SDL_memset(p, color, remainder); 120 } 121 pixels += pitch; 122 } 123 124 SSE_END; 125} 126/* DEFINE_SSE_FILLRECT(1, Uint8) */ 127DEFINE_SSE_FILLRECT(2, Uint16) 128DEFINE_SSE_FILLRECT(4, Uint32) 129 130/* *INDENT-ON* */ 131#endif /* __SSE__ */ 132 133static void 134SDL_FillRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h) 135{ 136 int n; 137 Uint8 *p = NULL; 138 139 while (h--) { 140 n = w; 141 p = pixels; 142 143 if (n > 3) { 144 switch ((uintptr_t) p & 3) { 145 case 1: 146 *p++ = (Uint8) color; 147 --n; /* fallthrough */ 148 case 2: 149 *p++ = (Uint8) color; 150 --n; /* fallthrough */ 151 case 3: 152 *p++ = (Uint8) color; 153 --n; /* fallthrough */ 154 } 155 SDL_memset4(p, color, (n >> 2)); 156 } 157 if (n & 3) { 158 p += (n & ~3); 159 switch (n & 3) { 160 case 3: 161 *p++ = (Uint8) color; /* fallthrough */ 162 case 2: 163 *p++ = (Uint8) color; /* fallthrough */ 164 case 1: 165 *p++ = (Uint8) color; /* fallthrough */ 166 } 167 } 168 pixels += pitch; 169 } 170} 171 172static void 173SDL_FillRect2(Uint8 * pixels, int pitch, Uint32 color, int w, int h) 174{ 175 int n; 176 Uint16 *p = NULL; 177 178 while (h--) { 179 n = w; 180 p = (Uint16 *) pixels; 181 182 if (n > 1) { 183 if ((uintptr_t) p & 2) { 184 *p++ = (Uint16) color; 185 --n; 186 } 187 SDL_memset4(p, color, (n >> 1)); 188 } 189 if (n & 1) { 190 p[n - 1] = (Uint16) color; 191 } 192 pixels += pitch; 193 } 194} 195 196static void 197SDL_FillRect3(Uint8 * pixels, int pitch, Uint32 color, int w, int h) 198{ 199#if SDL_BYTEORDER == SDL_LIL_ENDIAN 200 Uint8 b1 = (Uint8) (color & 0xFF); 201 Uint8 b2 = (Uint8) ((color >> 8) & 0xFF); 202 Uint8 b3 = (Uint8) ((color >> 16) & 0xFF); 203#elif SDL_BYTEORDER == SDL_BIG_ENDIAN 204 Uint8 b1 = (Uint8) ((color >> 16) & 0xFF); 205 Uint8 b2 = (Uint8) ((color >> 8) & 0xFF); 206 Uint8 b3 = (Uint8) (color & 0xFF); 207#endif 208 int n; 209 Uint8 *p = NULL; 210 211 while (h--) { 212 n = w; 213 p = pixels; 214 215 while (n--) { 216 *p++ = b1; 217 *p++ = b2; 218 *p++ = b3; 219 } 220 pixels += pitch; 221 } 222} 223 224static void 225SDL_FillRect4(Uint8 * pixels, int pitch, Uint32 color, int w, int h) 226{ 227 while (h--) { 228 SDL_memset4(pixels, color, w); 229 pixels += pitch; 230 } 231} 232 233/* 234 * This function performs a fast fill of the given rectangle with 'color' 235 */ 236int 237SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color) 238{ 239 SDL_Rect clipped; 240 Uint8 *pixels; 241 242 if (!dst) { 243 return SDL_SetError("Passed NULL destination surface"); 244 } 245 246 /* This function doesn't work on surfaces < 8 bpp */ 247 if (dst->format->BitsPerPixel < 8) { 248 return SDL_SetError("SDL_FillRect(): Unsupported surface format"); 249 } 250 251 /* If 'rect' == NULL, then fill the whole surface */ 252 if (rect) { 253 /* Perform clipping */ 254 if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) { 255 return 0; 256 } 257 rect = &clipped; 258 } else { 259 rect = &dst->clip_rect; 260 /* Don't attempt to fill if the surface's clip_rect is empty */ 261 if (SDL_RectEmpty(rect)) { 262 return 0; 263 } 264 } 265 266 /* Perform software fill */ 267 if (!dst->pixels) { 268 return SDL_SetError("SDL_FillRect(): You must lock the surface"); 269 } 270 271 pixels = (Uint8 *) dst->pixels + rect->y * dst->pitch + 272 rect->x * dst->format->BytesPerPixel; 273 274 switch (dst->format->BytesPerPixel) { 275 case 1: 276 { 277 color |= (color << 8); 278 color |= (color << 16); 279#ifdef __SSE__ 280 if (SDL_HasSSE()) { 281 SDL_FillRect1SSE(pixels, dst->pitch, color, rect->w, rect->h); 282 break; 283 } 284#endif 285 SDL_FillRect1(pixels, dst->pitch, color, rect->w, rect->h); 286 break; 287 } 288 289 case 2: 290 { 291 color |= (color << 16); 292#ifdef __SSE__ 293 if (SDL_HasSSE()) { 294 SDL_FillRect2SSE(pixels, dst->pitch, color, rect->w, rect->h); 295 break; 296 } 297#endif 298 SDL_FillRect2(pixels, dst->pitch, color, rect->w, rect->h); 299 break; 300 } 301 302 case 3: 303 /* 24-bit RGB is a slow path, at least for now. */ 304 { 305 SDL_FillRect3(pixels, dst->pitch, color, rect->w, rect->h); 306 break; 307 } 308 309 case 4: 310 { 311#ifdef __SSE__ 312 if (SDL_HasSSE()) { 313 SDL_FillRect4SSE(pixels, dst->pitch, color, rect->w, rect->h); 314 break; 315 } 316#endif 317 SDL_FillRect4(pixels, dst->pitch, color, rect->w, rect->h); 318 break; 319 } 320 } 321 322 /* We're done! */ 323 return 0; 324} 325 326int 327SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, 328 Uint32 color) 329{ 330 int i; 331 int status = 0; 332 333 if (!rects) { 334 return SDL_SetError("SDL_FillRects() passed NULL rects"); 335 } 336 337 for (i = 0; i < count; ++i) { 338 status += SDL_FillRect(dst, &rects[i], color); 339 } 340 return status; 341} 342 343/* vi: set ts=4 sw=4 expandtab: */ 344
[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.