diff src/video/SDL_drawrect.c @ 3594:c8bed77b0386

Added SDL_DrawRect(), SDL_DrawRects(), SDL_BlendRect() and SDL_BlendRects() Fixed line drawing so when blending a sequence of lines there are no overlapping pixels drawn.
author Sam Lantinga <slouken@libsdl.org>
date Fri, 18 Dec 2009 07:41:59 +0000
parents b931bcfd94a0
children f7b03b6838cb
line wrap: on
line diff
--- a/src/video/SDL_drawrect.c	Fri Dec 18 07:03:09 2009 +0000
+++ b/src/video/SDL_drawrect.c	Fri Dec 18 07:41:59 2009 +0000
@@ -22,398 +22,39 @@
 #include "SDL_config.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 \
-    DECLARE_ALIGNED(Uint32, cccc[4], 16); \
-    cccc[0] = color; \
-    cccc[1] = color; \
-    cccc[2] = color; \
-    cccc[3] = color; \
-    __m128 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_DrawRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
-{ \
-    SSE_BEGIN; \
- \
-    while (h--) { \
-        int i, n = w * bpp; \
-        Uint8 *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_DrawRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
-{
-    SSE_BEGIN;
-
-    while (h--) {
-        int i, n = w;
-        Uint8 *p = pixels;
-
-        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);
-            p += remainder;
-        }
-        pixels += pitch;
-    }
-
-    SSE_END;
-}
-/*DEFINE_SSE_FILLRECT(1, Uint8)*/
-DEFINE_SSE_FILLRECT(2, Uint16)
-DEFINE_SSE_FILLRECT(4, Uint32)
-
-/* *INDENT-ON* */
-#endif /* __SSE__ */
-
-#ifdef __MMX__
-/* *INDENT-OFF* */
-
-#define MMX_BEGIN \
-    __m64 c64 = _mm_set_pi32(color, color)
-
-#define MMX_WORK \
-    for (i = n / 64; i--;) { \
-        _mm_stream_pi((__m64 *)(p+0), c64); \
-        _mm_stream_pi((__m64 *)(p+8), c64); \
-        _mm_stream_pi((__m64 *)(p+16), c64); \
-        _mm_stream_pi((__m64 *)(p+24), c64); \
-        _mm_stream_pi((__m64 *)(p+32), c64); \
-        _mm_stream_pi((__m64 *)(p+40), c64); \
-        _mm_stream_pi((__m64 *)(p+48), c64); \
-        _mm_stream_pi((__m64 *)(p+56), c64); \
-        p += 64; \
-    }
-
-#define MMX_END \
-    _mm_empty()
-
-#define DEFINE_MMX_FILLRECT(bpp, type) \
-static void \
-SDL_DrawRect##bpp##MMX(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
-{ \
-    MMX_BEGIN; \
- \
-    while (h--) { \
-        int i, n = w * bpp; \
-        Uint8 *p = pixels; \
- \
-        if (n > 63) { \
-            int adjust = 8 - ((uintptr_t)p & 7); \
-            if (adjust < 8) { \
-                n -= adjust; \
-                adjust /= bpp; \
-                while (adjust--) { \
-                    *((type *)p) = (type)color; \
-                    p += bpp; \
-                } \
-            } \
-            MMX_WORK; \
-        } \
-        if (n & 63) { \
-            int remainder = (n & 63); \
-            remainder /= bpp; \
-            while (remainder--) { \
-                *((type *)p) = (type)color; \
-                p += bpp; \
-            } \
-        } \
-        pixels += pitch; \
-    } \
- \
-    MMX_END; \
-}
-
-static void
-SDL_DrawRect1MMX(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
-{
-    MMX_BEGIN;
-
-    while (h--) {
-        int i, n = w;
-        Uint8 *p = pixels;
-
-        if (n > 63) {
-            int adjust = 8 - ((uintptr_t)p & 7);
-            if (adjust) {
-                n -= adjust;
-                SDL_memset(p, color, adjust);
-                p += adjust;
-            }
-            MMX_WORK;
-        }
-        if (n & 63) {
-            int remainder = (n & 63);
-            SDL_memset(p, color, remainder);
-            p += remainder;
-        }
-        pixels += pitch;
-    }
-
-    MMX_END;
-}
-/*DEFINE_MMX_FILLRECT(1, Uint8)*/
-DEFINE_MMX_FILLRECT(2, Uint16)
-DEFINE_MMX_FILLRECT(4, Uint32)
-
-/* *INDENT-ON* */
-#endif /* __MMX__ */
-
-static void
-SDL_DrawRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
-{
-    while (h--) {
-        int n = w;
-        Uint8 *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_DrawRect2(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
-{
-    while (h--) {
-        int n = w;
-        Uint16 *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_DrawRect3(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
-{
-    Uint8 r = (Uint8) ((color >> 16) & 0xFF);
-    Uint8 g = (Uint8) ((color >> 8) & 0xFF);
-    Uint8 b = (Uint8) (color & 0xFF);
-
-    while (h--) {
-        int n = w;
-        Uint8 *p = pixels;
-
-        while (n--) {
-            *p++ = r;
-            *p++ = g;
-            *p++ = b;
-        }
-        pixels += pitch;
-    }
-}
-
-static void
-SDL_DrawRect4(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_DrawRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
 {
-    SDL_Rect clipped;
-    Uint8 *pixels;
+    SDL_Rect full_rect;
+    SDL_Point points[5];
 
     if (!dst) {
         SDL_SetError("Passed NULL destination surface");
         return -1;
     }
 
-    /* This function doesn't work on surfaces < 8 bpp */
-    if (dst->format->BitsPerPixel < 8) {
-        SDL_SetError("SDL_DrawRect(): Unsupported surface format");
-        return -1;
-    }
-
-    /* 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;
-    }
-
-    /* Perform software fill */
-    if (!dst->pixels) {
-        SDL_SetError("SDL_DrawRect(): You must lock the surface");
-        return (-1);
+    /* If 'rect' == NULL, then outline the whole surface */
+    if (!rect) {
+        full_rect.x = 0;
+        full_rect.y = 0;
+        full_rect.w = dst->w;
+        full_rect.h = dst->h;
+        rect = &full_rect;
     }
 
-    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_DrawRect1SSE(pixels, dst->pitch, color, rect->w, rect->h);
-                break;
-            }
-#endif
-#ifdef __MMX__
-            if (SDL_HasMMX()) {
-                SDL_DrawRect1MMX(pixels, dst->pitch, color, rect->w, rect->h);
-                break;
-            }
-#endif
-            SDL_DrawRect1(pixels, dst->pitch, color, rect->w, rect->h);
-            break;
-        }
-
-    case 2:
-        {
-            color |= (color << 16);
-#ifdef __SSE__
-            if (SDL_HasSSE()) {
-                SDL_DrawRect2SSE(pixels, dst->pitch, color, rect->w, rect->h);
-                break;
-            }
-#endif
-#ifdef __MMX__
-            if (SDL_HasMMX()) {
-                SDL_DrawRect2MMX(pixels, dst->pitch, color, rect->w, rect->h);
-                break;
-            }
-#endif
-            SDL_DrawRect2(pixels, dst->pitch, color, rect->w, rect->h);
-            break;
-        }
-
-    case 3:
-        /* 24-bit RGB is a slow path, at least for now. */
-        {
-            SDL_DrawRect3(pixels, dst->pitch, color, rect->w, rect->h);
-            break;
-        }
-
-    case 4:
-        {
-#ifdef __SSE__
-            if (SDL_HasSSE()) {
-                SDL_DrawRect4SSE(pixels, dst->pitch, color, rect->w, rect->h);
-                break;
-            }
-#endif
-#ifdef __MMX__
-            if (SDL_HasMMX()) {
-                SDL_DrawRect4MMX(pixels, dst->pitch, color, rect->w, rect->h);
-                break;
-            }
-#endif
-            SDL_DrawRect4(pixels, dst->pitch, color, rect->w, rect->h);
-            break;
-        }
-    }
-
-    /* We're done! */
-    return 0;
+    points[0].x = rect->x;
+    points[0].y = rect->y;
+    points[1].x = rect->x+rect->w-1;
+    points[1].y = rect->y;
+    points[2].x = rect->x+rect->w-1;
+    points[2].y = rect->y+rect->h-1;
+    points[3].x = rect->x;
+    points[3].y = rect->y+rect->h-1;
+    points[4].x = rect->x;
+    points[4].y = rect->y;
+    return SDL_DrawLines(dst, points, 5, color);
 }
 
 int
@@ -421,12 +62,13 @@
               Uint32 color)
 {
     int i;
-    int status = 0;
 
     for (i = 0; i < count; ++i) {
-        status = SDL_DrawRect(dst, rects[i], color);
+        if (SDL_DrawRect(dst, rects[i], color) < 0) {
+            return -1;
+        }
     }
-    return status;
+    return 0;
 }
 
 /* vi: set ts=4 sw=4 expandtab: */