SDL_fillrect.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
#include "SDL_video.h"
#include "SDL_blit.h"
#ifdef __SSE__
/* *INDENT-OFF* */
#ifdef _MSC_VER
#define SSE_BEGIN \
__m128 c128; \
c128.m128_u32[0] = color; \
c128.m128_u32[1] = color; \
c128.m128_u32[2] = color; \
c128.m128_u32[3] = color;
#else
#define SSE_BEGIN \
__m128 c128; \
DECLARE_ALIGNED(Uint32, cccc[4], 16); \
cccc[0] = color; \
cccc[1] = color; \
cccc[2] = color; \
cccc[3] = color; \
c128 = *(__m128 *)cccc;
#endif
#define SSE_WORK \
for (i = n / 64; i--;) { \
_mm_stream_ps((float *)(p+0), c128); \
_mm_stream_ps((float *)(p+16), c128); \
_mm_stream_ps((float *)(p+32), c128); \
_mm_stream_ps((float *)(p+48), c128); \
p += 64; \
}
#define SSE_END
#define DEFINE_SSE_FILLRECT(bpp, type) \
static void \
SDL_FillRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
{ \
int i, n; \
Uint8 *p = NULL; \
\
SSE_BEGIN; \
\
while (h--) { \
n = w * bpp; \
p = pixels; \
\
if (n > 63) { \
int adjust = 16 - ((uintptr_t)p & 15); \
if (adjust < 16) { \
n -= adjust; \
adjust /= bpp; \
while (adjust--) { \
*((type *)p) = (type)color; \
p += bpp; \
} \
} \
SSE_WORK; \
} \
if (n & 63) { \
int remainder = (n & 63); \
remainder /= bpp; \
while (remainder--) { \
*((type *)p) = (type)color; \
p += bpp; \
} \
} \
pixels += pitch; \
} \
\
SSE_END; \
}
static void
SDL_FillRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
{
int i, n;
SSE_BEGIN;
while (h--) {
Uint8 *p = pixels;
n = w;
if (n > 63) {
int adjust = 16 - ((uintptr_t)p & 15);
if (adjust) {
n -= adjust;
SDL_memset(p, color, adjust);
p += adjust;
}
SSE_WORK;
}
if (n & 63) {
int remainder = (n & 63);
SDL_memset(p, color, remainder);
}
pixels += pitch;
}
SSE_END;
}
/* DEFINE_SSE_FILLRECT(1, Uint8) */
DEFINE_SSE_FILLRECT(2, Uint16)
DEFINE_SSE_FILLRECT(4, Uint32)
/* *INDENT-ON* */
#endif /* __SSE__ */
static void
SDL_FillRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
{
int n;
Uint8 *p = NULL;
while (h--) {
n = w;
p = pixels;
if (n > 3) {
switch ((uintptr_t) p & 3) {
case 1:
*p++ = (Uint8) color;
--n;
case 2:
*p++ = (Uint8) color;
--n;
case 3:
*p++ = (Uint8) color;
--n;
}
SDL_memset4(p, color, (n >> 2));
}
if (n & 3) {
p += (n & ~3);
switch (n & 3) {
case 3:
*p++ = (Uint8) color;
case 2:
*p++ = (Uint8) color;
case 1:
*p++ = (Uint8) color;
}
}
pixels += pitch;
}
}
static void
SDL_FillRect2(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
{
int n;
Uint16 *p = NULL;
while (h--) {
n = w;
p = (Uint16 *) pixels;
if (n > 1) {
if ((uintptr_t) p & 2) {
*p++ = (Uint16) color;
--n;
}
SDL_memset4(p, color, (n >> 1));
}
if (n & 1) {
p[n - 1] = (Uint16) color;
}
pixels += pitch;
}
}
static void
SDL_FillRect3(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
{
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
Uint8 b1 = (Uint8) (color & 0xFF);
Uint8 b2 = (Uint8) ((color >> 8) & 0xFF);
Uint8 b3 = (Uint8) ((color >> 16) & 0xFF);
#elif SDL_BYTEORDER == SDL_BIG_ENDIAN
Uint8 b1 = (Uint8) ((color >> 16) & 0xFF);
Uint8 b2 = (Uint8) ((color >> 8) & 0xFF);
Uint8 b3 = (Uint8) (color & 0xFF);
#endif
int n;
Uint8 *p = NULL;
while (h--) {
n = w;
p = pixels;
while (n--) {
*p++ = b1;
*p++ = b2;
*p++ = b3;
}
pixels += pitch;
}
}
static void
SDL_FillRect4(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
{
while (h--) {
SDL_memset4(pixels, color, w);
pixels += pitch;
}
}
/*
* This function performs a fast fill of the given rectangle with 'color'
*/
int
SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
{
SDL_Rect clipped;
Uint8 *pixels;
if (!dst) {
return SDL_SetError("Passed NULL destination surface");
}
/* This function doesn't work on surfaces < 8 bpp */
if (dst->format->BitsPerPixel < 8) {
return SDL_SetError("SDL_FillRect(): Unsupported surface format");
}
/* If 'rect' == NULL, then fill the whole surface */
if (rect) {
/* Perform clipping */
if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
return 0;
}
rect = &clipped;
} else {
rect = &dst->clip_rect;
/* Don't attempt to fill if the surface's clip_rect is empty */
if (SDL_RectEmpty(rect)) {
return 0;
}
}
/* Perform software fill */
if (!dst->pixels) {
return SDL_SetError("SDL_FillRect(): You must lock the surface");
}
pixels = (Uint8 *) dst->pixels + rect->y * dst->pitch +
rect->x * dst->format->BytesPerPixel;
switch (dst->format->BytesPerPixel) {
case 1:
{
color |= (color << 8);
color |= (color << 16);
#ifdef __SSE__
if (SDL_HasSSE()) {
SDL_FillRect1SSE(pixels, dst->pitch, color, rect->w, rect->h);
break;
}
#endif
SDL_FillRect1(pixels, dst->pitch, color, rect->w, rect->h);
break;
}
case 2:
{
color |= (color << 16);
#ifdef __SSE__
if (SDL_HasSSE()) {
SDL_FillRect2SSE(pixels, dst->pitch, color, rect->w, rect->h);
break;
}
#endif
SDL_FillRect2(pixels, dst->pitch, color, rect->w, rect->h);
break;
}
case 3:
/* 24-bit RGB is a slow path, at least for now. */
{
SDL_FillRect3(pixels, dst->pitch, color, rect->w, rect->h);
break;
}
case 4:
{
#ifdef __SSE__
if (SDL_HasSSE()) {
SDL_FillRect4SSE(pixels, dst->pitch, color, rect->w, rect->h);
break;
}
#endif
SDL_FillRect4(pixels, dst->pitch, color, rect->w, rect->h);
break;
}
}
/* We're done! */
return 0;
}
int
SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
Uint32 color)
{
int i;
int status = 0;
if (!rects) {
return SDL_SetError("SDL_FillRects() passed NULL rects");
}
for (i = 0; i < count; ++i) {
status += SDL_FillRect(dst, &rects[i], color);
}
return status;
}
/* vi: set ts=4 sw=4 expandtab: */
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1737
n
GLdouble n
Definition: SDL_opengl_glext.h:1952
Uint32
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:157
SDL_PixelFormat::BytesPerPixel
Uint8 BytesPerPixel
Definition: SDL_pixels.h:304
count
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1564
rect
SDL_Rect rect
Definition: testrelative.c:27
p
GLfloat GLfloat p
Definition: SDL_opengl_glext.h:11090
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
pixels
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1565
SDL_IntersectRect
#define SDL_IntersectRect
Definition: SDL_dynapi_overrides.h:300
SDL_RectEmpty
SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
Returns true if the rectangle has no area.
Definition: SDL_rect.h:82
SDL_FillRect3
static void SDL_FillRect3(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
Definition: SDL_fillrect.c:197
SDL_video.h
SDL_FillRects
int SDL_FillRects(SDL_Surface *dst, const SDL_Rect *rects, int count, Uint32 color)
Definition: SDL_fillrect.c:327
SDL_Surface::pixels
void * pixels
Definition: SDL_surface.h:75
SDL_memset4
SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords)
Definition: SDL_stdinc.h:361
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
SDL_PixelFormat::BitsPerPixel
Uint8 BitsPerPixel
Definition: SDL_pixels.h:303
uintptr_t
unsigned int uintptr_t
Definition: SDL_config_windows.h:69
SDL_Rect::x
int x
Definition: SDL_rect.h:66
SDL_Rect::w
int w
Definition: SDL_rect.h:67
SDL_Surface::clip_rect
SDL_Rect clip_rect
Definition: SDL_surface.h:85
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:42
NULL
#define NULL
Definition: begin_code.h:143
SDL_FillRect
int SDL_FillRect(SDL_Surface *dst, const SDL_Rect *rect, Uint32 color)
Definition: SDL_fillrect.c:237
SDL_Surface::format
SDL_PixelFormat * format
Definition: SDL_surface.h:72
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:36
SDL_FillRect2
static void SDL_FillRect2(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
Definition: SDL_fillrect.c:173
SDL_blit.h
SDL_Rect::h
int h
Definition: SDL_rect.h:67
rects
SDL_Rect rects[MAX_RECTS]
Definition: testintersections.c:129
color
GLuint color
Definition: SDL_opengl_glext.h:1148
SDL_Surface::pitch
int pitch
Definition: SDL_surface.h:74
Uint16
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:147
SDL_FillRect4
static void SDL_FillRect4(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
Definition: SDL_fillrect.c:225
SDL_FillRect1
static void SDL_FillRect1(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
Definition: SDL_fillrect.c:134
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731
SDL_HasSSE
#define SDL_HasSSE
Definition: SDL_dynapi_overrides.h:113
SDL_Rect::y
int y
Definition: SDL_rect.h:66
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1946
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:392
SDL_Rect
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64