use memcpy's to speed up vertical gradients too. split the fancy memcpy() code out into the repeat_pixel function.

This commit is contained in:
Dana Jansens 2008-02-10 17:06:18 -05:00 committed by Mikael Magnusson
parent 1d00d99470
commit 3611c8210c

View file

@ -197,6 +197,52 @@ static void create_bevel_colors(RrAppearance *l)
l->surface.bevel_dark = RrColorNew(l->inst, r, g, b); l->surface.bevel_dark = RrColorNew(l->inst, r, g, b);
} }
/*! Repeat the first pixel over the entire block of memory
@param start The block of memory. start[0] will be copied
to the rest of the block.
@param w The width of the block of memory (including the already-set first
element
*/
static inline void repeat_pixel(RrPixel32 *start, gint w)
{
gint x;
RrPixel32 *dest;
dest = start + 1;
/* for really small things, just copy ourselves */
if (w < 8) {
for (x = w-1; x > 0; --x)
*(dest++) = *start;
}
/* for >= 8, then use O(log n) memcpy's... */
else {
gint len = 4;
gint lenbytes = 4 * sizeof(RrPixel32);
/* copy the first 3 * 32 bits (3 words) ourselves - then we have
3 + the original 1 = 4 words to make copies of at a time
this is faster than doing memcpy for 1 or 2 words at a time
*/
for (x = 3; x > 0; --x)
*(dest++) = *start;
for (x = w - 4; x > 0;) {
memcpy(dest, start, lenbytes);
x -= len;
dest += len;
len <<= 1;
lenbytes <<= 1;
if (len > x) {
len = x;
lenbytes = x * sizeof(RrPixel32);
}
}
}
}
static void gradient_parentrelative(RrAppearance *a, gint w, gint h) static void gradient_parentrelative(RrAppearance *a, gint w, gint h)
{ {
RrPixel32 *source, *dest; RrPixel32 *source, *dest;
@ -423,9 +469,9 @@ static void gradient_solid(RrAppearance *l, gint w, gint h)
static void gradient_splitvertical(RrAppearance *a, gint w, gint h) static void gradient_splitvertical(RrAppearance *a, gint w, gint h)
{ {
gint x, y1, y2, y3; gint y1, y2, y3;
RrSurface *sf = &a->surface; RrSurface *sf = &a->surface;
RrPixel32 *data, *start; RrPixel32 *data;
gint y1sz, y2sz, y3sz; gint y1sz, y2sz, y3sz;
VARS(y1); VARS(y1);
@ -479,44 +525,10 @@ static void gradient_splitvertical(RrAppearance *a, gint w, gint h)
*data = COLOR(y3); *data = COLOR(y3);
/* copy the first pixels into the whole rows */ /* copy the first pixels into the whole rows */
data = sf->pixel_data;
start = sf->pixel_data;
data = start + 1;
for (y1 = h; y1 > 0; --y1) { for (y1 = h; y1 > 0; --y1) {
/* for really small things, just copy ourselves */ repeat_pixel(data, w);
if (w < 8) { data += w;
for (x = w-1; x > 0; --x)
*(data++) = *start;
}
/* for >= 8, then use O(log n) memcpy's... */
else {
gint len = 4;
gint lenbytes = 4 * sizeof(RrPixel32);
/* copy the first 3 * 32 bits (3 words) ourselves - then we have
3 + the original 1 = 4 words to make copies of at a time
this is faster than doing memcpy for 1 or 2 words at a time
*/
for (x = 3; x > 0; --x)
*(data++) = *start;
for (x = w - 4; x > 0;) {
memcpy(data, start, lenbytes);
x -= len;
data += len;
len <<= 1;
lenbytes <<= 1;
if (len > x) {
len = x;
lenbytes = x * sizeof(RrPixel32);
}
}
}
start += w;
++data;
} }
} }
@ -582,23 +594,28 @@ static void gradient_mirrorhorizontal(RrSurface *sf, gint w, gint h)
static void gradient_vertical(RrSurface *sf, gint w, gint h) static void gradient_vertical(RrSurface *sf, gint w, gint h)
{ {
gint x, y; gint y;
RrPixel32 *data = sf->pixel_data; RrPixel32 *data;
RrPixel32 current;
VARS(y); VARS(y);
SETUP(y, sf->primary, sf->secondary, h); SETUP(y, sf->primary, sf->secondary, h);
for (y = h - 1; y > 0; --y) { /* 0 -> h-1 */ /* find the color for the first pixel of each row first */
current = COLOR(y); data = sf->pixel_data;
for (x = w; x > 0; --x) /* 0 -> w */
*(data++) = current;
for (y = h - 1; y > 0; --y) { /* 0 -> h-1 */
*data = COLOR(y);
data += w;
NEXT(y); NEXT(y);
} }
current = COLOR(y); *data = COLOR(y);
for (x = w; x > 0; --x) /* 0 -> w */
*(data++) = current; /* copy the first pixels into the whole rows */
data = sf->pixel_data;
for (y = h; y > 0; --y) {
repeat_pixel(data, w);
data += w;
}
} }