From: Dana Jansens Date: Sun, 10 Feb 2008 22:06:18 +0000 (-0500) Subject: use memcpy's to speed up vertical gradients too. split the fancy memcpy() code out... X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=3611c8210cc632c2a21c67ccbf40857342c10371;p=chaz%2Fopenbox use memcpy's to speed up vertical gradients too. split the fancy memcpy() code out into the repeat_pixel function. --- diff --git a/render/gradient.c b/render/gradient.c index bbd2a5c9..d1d90e41 100644 --- a/render/gradient.c +++ b/render/gradient.c @@ -197,6 +197,52 @@ static void create_bevel_colors(RrAppearance *l) 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) { 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) { - gint x, y1, y2, y3; + gint y1, y2, y3; RrSurface *sf = &a->surface; - RrPixel32 *data, *start; + RrPixel32 *data; gint y1sz, y2sz, y3sz; VARS(y1); @@ -479,44 +525,10 @@ static void gradient_splitvertical(RrAppearance *a, gint w, gint h) *data = COLOR(y3); /* copy the first pixels into the whole rows */ - - start = sf->pixel_data; - data = start + 1; - + data = sf->pixel_data; for (y1 = h; y1 > 0; --y1) { - /* for really small things, just copy ourselves */ - if (w < 8) { - 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; + repeat_pixel(data, w); + data += w; } } @@ -582,23 +594,28 @@ static void gradient_mirrorhorizontal(RrSurface *sf, gint w, gint h) static void gradient_vertical(RrSurface *sf, gint w, gint h) { - gint x, y; - RrPixel32 *data = sf->pixel_data; - RrPixel32 current; + gint y; + RrPixel32 *data; VARS(y); SETUP(y, sf->primary, sf->secondary, h); - for (y = h - 1; y > 0; --y) { /* 0 -> h-1 */ - current = COLOR(y); - for (x = w; x > 0; --x) /* 0 -> w */ - *(data++) = current; + /* find the color for the first pixel of each row first */ + data = sf->pixel_data; + for (y = h - 1; y > 0; --y) { /* 0 -> h-1 */ + *data = COLOR(y); + data += w; NEXT(y); } - current = COLOR(y); - for (x = w; x > 0; --x) /* 0 -> w */ - *(data++) = current; + *data = COLOR(y); + + /* copy the first pixels into the whole rows */ + data = sf->pixel_data; + for (y = h; y > 0; --y) { + repeat_pixel(data, w); + data += w; + } }