video: speed up SDL_FillRect[s] slightly (thanks, Jakub!). "This patch does the following: * Instead of SDL_FillRects calling SDL_FillRect in a loop the opposite happens -- SDL_FillRect (a specific case) calls SDL_FillRects (a general case) with a count of 1 * The switch/case block is moved out of the loop -- it modifies the color once and stores the fill routine in a pointer which is then used throughout the loop" Fixes Bugzilla #4674.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
diff --git a/src/video/SDL_fillrect.c b/src/video/SDL_fillrect.c
index ecea66e..4b870f9 100644
--- a/src/video/SDL_fillrect.c
+++ b/src/video/SDL_fillrect.c
@@ -243,19 +243,8 @@ SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
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 {
+ if (!rect) {
rect = &dst->clip_rect;
/* Don't attempt to fill if the surface's clip_rect is empty */
if (SDL_RectEmpty(rect)) {
@@ -263,13 +252,36 @@ SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
}
}
+ return SDL_FillRects(dst, rect, 1, color);
+}
+
+int
+SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
+ Uint32 color)
+{
+ SDL_Rect clipped;
+ Uint8 *pixels;
+ const SDL_Rect* rect;
+ void (*fill_function)(Uint8 * pixels, int pitch, Uint32 color, int w, int h);
+ int i;
+
+ 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");
+ }
+
/* 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;
+ if (!rects) {
+ return SDL_SetError("SDL_FillRects() passed NULL rects");
+ }
switch (dst->format->BytesPerPixel) {
case 1:
@@ -278,11 +290,11 @@ SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
color |= (color << 16);
#ifdef __SSE__
if (SDL_HasSSE()) {
- SDL_FillRect1SSE(pixels, dst->pitch, color, rect->w, rect->h);
+ fill_function = SDL_FillRect1SSE;
break;
}
#endif
- SDL_FillRect1(pixels, dst->pitch, color, rect->w, rect->h);
+ fill_function = SDL_FillRect1;
break;
}
@@ -291,18 +303,18 @@ SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
color |= (color << 16);
#ifdef __SSE__
if (SDL_HasSSE()) {
- SDL_FillRect2SSE(pixels, dst->pitch, color, rect->w, rect->h);
+ fill_function = SDL_FillRect2SSE;
break;
}
#endif
- SDL_FillRect2(pixels, dst->pitch, color, rect->w, rect->h);
+ fill_function = SDL_FillRect2;
break;
}
case 3:
/* 24-bit RGB is a slow path, at least for now. */
{
- SDL_FillRect3(pixels, dst->pitch, color, rect->w, rect->h);
+ fill_function = SDL_FillRect3;
break;
}
@@ -310,34 +322,32 @@ SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
{
#ifdef __SSE__
if (SDL_HasSSE()) {
- SDL_FillRect4SSE(pixels, dst->pitch, color, rect->w, rect->h);
+ fill_function = SDL_FillRect4SSE;
break;
}
#endif
- SDL_FillRect4(pixels, dst->pitch, color, rect->w, rect->h);
+ fill_function = SDL_FillRect4;
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;
+ for (i = 0; i < count; ++i) {
+ rect = &rects[i];
+ /* Perform clipping */
+ if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
+ continue;
+ }
+ rect = &clipped;
- if (!rects) {
- return SDL_SetError("SDL_FillRects() passed NULL rects");
- }
+ pixels = (Uint8 *) dst->pixels + rect->y * dst->pitch +
+ rect->x * dst->format->BytesPerPixel;
- for (i = 0; i < count; ++i) {
- status += SDL_FillRect(dst, &rects[i], color);
+ fill_function(pixels, dst->pitch, color, rect->w, rect->h);
}
- return status;
+
+ /* We're done! */
+ return 0;
}
/* vi: set ts=4 sw=4 expandtab: */