zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_fillrect.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
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_config.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) \
60 static void \
61 SDL_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 
98 static void
99 SDL_FillRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
100 {
101  int i, n;
102  Uint8 *p = NULL;
103 
104  SSE_BEGIN;
105  while (h--) {
106  n = w;
107  p = pixels;
108 
109  if (n > 63) {
110  int adjust = 16 - ((uintptr_t)p & 15);
111  if (adjust) {
112  n -= adjust;
113  SDL_memset(p, color, adjust);
114  p += adjust;
115  }
116  SSE_WORK;
117  }
118  if (n & 63) {
119  int remainder = (n & 63);
120  SDL_memset(p, color, remainder);
121  p += remainder;
122  }
123  pixels += pitch;
124  }
125 
126  SSE_END;
127 }
128 /* DEFINE_SSE_FILLRECT(1, Uint8) */
129 DEFINE_SSE_FILLRECT(2, Uint16)
130 DEFINE_SSE_FILLRECT(4, Uint32)
131 
132 /* *INDENT-ON* */
133 #endif /* __SSE__ */
134 
135 #ifdef __MMX__
136 /* *INDENT-OFF* */
137 
138 #define MMX_BEGIN \
139  __m64 c64 = _mm_set_pi32(color, color)
140 
141 #define MMX_WORK \
142  for (i = n / 64; i--;) { \
143  _mm_stream_pi((__m64 *)(p+0), c64); \
144  _mm_stream_pi((__m64 *)(p+8), c64); \
145  _mm_stream_pi((__m64 *)(p+16), c64); \
146  _mm_stream_pi((__m64 *)(p+24), c64); \
147  _mm_stream_pi((__m64 *)(p+32), c64); \
148  _mm_stream_pi((__m64 *)(p+40), c64); \
149  _mm_stream_pi((__m64 *)(p+48), c64); \
150  _mm_stream_pi((__m64 *)(p+56), c64); \
151  p += 64; \
152  }
153 
154 #define MMX_END \
155  _mm_empty()
156 
157 #define DEFINE_MMX_FILLRECT(bpp, type) \
158 static void \
159 SDL_FillRect##bpp##MMX(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
160 { \
161  int i, n; \
162  Uint8 *p = NULL; \
163  \
164  MMX_BEGIN; \
165  \
166  while (h--) { \
167  n = w * bpp; \
168  p = pixels; \
169  \
170  if (n > 63) { \
171  int adjust = 8 - ((uintptr_t)p & 7); \
172  if (adjust < 8) { \
173  n -= adjust; \
174  adjust /= bpp; \
175  while (adjust--) { \
176  *((type *)p) = (type)color; \
177  p += bpp; \
178  } \
179  } \
180  MMX_WORK; \
181  } \
182  if (n & 63) { \
183  int remainder = (n & 63); \
184  remainder /= bpp; \
185  while (remainder--) { \
186  *((type *)p) = (type)color; \
187  p += bpp; \
188  } \
189  } \
190  pixels += pitch; \
191  } \
192  \
193  MMX_END; \
194 }
195 
196 static void
197 SDL_FillRect1MMX(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
198 {
199  int i, n;
200  Uint8 *p = NULL;
201 
202  MMX_BEGIN;
203 
204  while (h--) {
205  n = w;
206  p = pixels;
207 
208  if (n > 63) {
209  int adjust = 8 - ((uintptr_t)p & 7);
210  if (adjust) {
211  n -= adjust;
212  SDL_memset(p, color, adjust);
213  p += adjust;
214  }
215  MMX_WORK;
216  }
217  if (n & 63) {
218  int remainder = (n & 63);
219  SDL_memset(p, color, remainder);
220  p += remainder;
221  }
222  pixels += pitch;
223  }
224 
225  MMX_END;
226 }
227 /* DEFINE_MMX_FILLRECT(1, Uint8) */
228 DEFINE_MMX_FILLRECT(2, Uint16)
229 DEFINE_MMX_FILLRECT(4, Uint32)
230 
231 /* *INDENT-ON* */
232 #endif /* __MMX__ */
233 
234 static void
235 SDL_FillRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
236 {
237  int n;
238  Uint8 *p = NULL;
239 
240  while (h--) {
241  n = w;
242  p = pixels;
243 
244  if (n > 3) {
245  switch ((uintptr_t) p & 3) {
246  case 1:
247  *p++ = (Uint8) color;
248  --n;
249  case 2:
250  *p++ = (Uint8) color;
251  --n;
252  case 3:
253  *p++ = (Uint8) color;
254  --n;
255  }
256  SDL_memset4(p, color, (n >> 2));
257  }
258  if (n & 3) {
259  p += (n & ~3);
260  switch (n & 3) {
261  case 3:
262  *p++ = (Uint8) color;
263  case 2:
264  *p++ = (Uint8) color;
265  case 1:
266  *p++ = (Uint8) color;
267  }
268  }
269  pixels += pitch;
270  }
271 }
272 
273 static void
274 SDL_FillRect2(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
275 {
276  int n;
277  Uint16 *p = NULL;
278 
279  while (h--) {
280  n = w;
281  p = (Uint16 *) pixels;
282 
283  if (n > 1) {
284  if ((uintptr_t) p & 2) {
285  *p++ = (Uint16) color;
286  --n;
287  }
288  SDL_memset4(p, color, (n >> 1));
289  }
290  if (n & 1) {
291  p[n - 1] = (Uint16) color;
292  }
293  pixels += pitch;
294  }
295 }
296 
297 static void
298 SDL_FillRect3(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
299 {
300  Uint8 r = (Uint8) ((color >> 16) & 0xFF);
301  Uint8 g = (Uint8) ((color >> 8) & 0xFF);
302  Uint8 b = (Uint8) (color & 0xFF);
303  int n;
304  Uint8 *p = NULL;
305 
306  while (h--) {
307  n = w;
308  p = pixels;
309 
310  while (n--) {
311  *p++ = r;
312  *p++ = g;
313  *p++ = b;
314  }
315  pixels += pitch;
316  }
317 }
318 
319 static void
320 SDL_FillRect4(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
321 {
322  while (h--) {
323  SDL_memset4(pixels, color, w);
324  pixels += pitch;
325  }
326 }
327 
328 /*
329  * This function performs a fast fill of the given rectangle with 'color'
330  */
331 int
332 SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
333 {
334  SDL_Rect clipped;
335  Uint8 *pixels;
336 
337  if (!dst) {
338  return SDL_SetError("Passed NULL destination surface");
339  }
340 
341  /* This function doesn't work on surfaces < 8 bpp */
342  if (dst->format->BitsPerPixel < 8) {
343  return SDL_SetError("SDL_FillRect(): Unsupported surface format");
344  }
345 
346  /* If 'rect' == NULL, then fill the whole surface */
347  if (rect) {
348  /* Perform clipping */
349  if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
350  return 0;
351  }
352  rect = &clipped;
353  } else {
354  rect = &dst->clip_rect;
355  }
356 
357  /* Perform software fill */
358  if (!dst->pixels) {
359  return SDL_SetError("SDL_FillRect(): You must lock the surface");
360  }
361 
362  pixels = (Uint8 *) dst->pixels + rect->y * dst->pitch +
363  rect->x * dst->format->BytesPerPixel;
364 
365  switch (dst->format->BytesPerPixel) {
366  case 1:
367  {
368  color |= (color << 8);
369  color |= (color << 16);
370 #ifdef __SSE__
371  if (SDL_HasSSE()) {
372  SDL_FillRect1SSE(pixels, dst->pitch, color, rect->w, rect->h);
373  break;
374  }
375 #endif
376 #ifdef __MMX__
377  if (SDL_HasMMX()) {
378  SDL_FillRect1MMX(pixels, dst->pitch, color, rect->w, rect->h);
379  break;
380  }
381 #endif
382  SDL_FillRect1(pixels, dst->pitch, color, rect->w, rect->h);
383  break;
384  }
385 
386  case 2:
387  {
388  color |= (color << 16);
389 #ifdef __SSE__
390  if (SDL_HasSSE()) {
391  SDL_FillRect2SSE(pixels, dst->pitch, color, rect->w, rect->h);
392  break;
393  }
394 #endif
395 #ifdef __MMX__
396  if (SDL_HasMMX()) {
397  SDL_FillRect2MMX(pixels, dst->pitch, color, rect->w, rect->h);
398  break;
399  }
400 #endif
401  SDL_FillRect2(pixels, dst->pitch, color, rect->w, rect->h);
402  break;
403  }
404 
405  case 3:
406  /* 24-bit RGB is a slow path, at least for now. */
407  {
408  SDL_FillRect3(pixels, dst->pitch, color, rect->w, rect->h);
409  break;
410  }
411 
412  case 4:
413  {
414 #ifdef __SSE__
415  if (SDL_HasSSE()) {
416  SDL_FillRect4SSE(pixels, dst->pitch, color, rect->w, rect->h);
417  break;
418  }
419 #endif
420 #ifdef __MMX__
421  if (SDL_HasMMX()) {
422  SDL_FillRect4MMX(pixels, dst->pitch, color, rect->w, rect->h);
423  break;
424  }
425 #endif
426  SDL_FillRect4(pixels, dst->pitch, color, rect->w, rect->h);
427  break;
428  }
429  }
430 
431  /* We're done! */
432  return 0;
433 }
434 
435 int
437  Uint32 color)
438 {
439  int i;
440  int status = 0;
441 
442  if (!rects) {
443  return SDL_SetError("SDL_FillRects() passed NULL rects");
444  }
445 
446  for (i = 0; i < count; ++i) {
447  status += SDL_FillRect(dst, &rects[i], color);
448  }
449  return status;
450 }
451 
452 /* vi: set ts=4 sw=4 expandtab: */
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:7294
GLuint color
Definition: glew.h:7185
GLboolean GLboolean g
Definition: glew.h:8736
#define NULL
Definition: ftobjs.h:61
Uint8 BytesPerPixel
Definition: SDL_pixels.h:277
GLclampd n
Definition: glew.h:7287
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
DECLSPEC SDL_bool SDLCALL SDL_HasMMX(void)
Definition: SDL_cpuinfo.c:548
DECLSPEC SDL_bool SDLCALL SDL_HasSSE(void)
Definition: SDL_cpuinfo.c:566
switch(yytype)
DECLSPEC int SDLCALL SDL_FillRect(SDL_Surface *dst, const SDL_Rect *rect, Uint32 color)
Definition: SDL_fillrect.c:332
static void SDL_FillRect3(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
Definition: SDL_fillrect.c:298
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
GLenum GLenum dst
Definition: glew.h:2396
DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result)
Calculate the intersection of two rectangles.
Definition: SDL_rect.c:75
void * pixels
Definition: SDL_surface.h:75
Uint8 BitsPerPixel
Definition: SDL_pixels.h:276
GLint GLsizei count
Definition: gl2ext.h:1011
GLfloat GLfloat p
Definition: glew.h:14938
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
Definition: SDL_string.c:261
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
unsigned int uintptr_t
int x
Definition: SDL_rect.h:65
int w
Definition: SDL_rect.h:66
SDL_Rect clip_rect
Definition: SDL_surface.h:85
SDL_PixelFormat * format
Definition: SDL_surface.h:72
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl2ext.h:845
static void SDL_FillRect2(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
Definition: SDL_fillrect.c:274
int h
Definition: SDL_rect.h:66
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
GLdouble GLdouble GLdouble r
Definition: glew.h:1392
GLdouble GLdouble GLdouble b
Definition: glew.h:8383
SDL_FORCE_INLINE void SDL_memset4(void *dst, int val, size_t dwords)
Definition: SDL_stdinc.h:258
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:137
static void SDL_FillRect4(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
Definition: SDL_fillrect.c:320
static void SDL_FillRect1(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
Definition: SDL_fillrect.c:235
int i
Definition: pngrutil.c:1377
DECLSPEC int SDLCALL SDL_FillRects(SDL_Surface *dst, const SDL_Rect *rects, int count, Uint32 color)
Definition: SDL_fillrect.c:436
int y
Definition: SDL_rect.h:65
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
INT64 INT64 INT64 remainder
Definition: wglew.h:1155