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:
parent
1d00d99470
commit
3611c8210c
1 changed files with 66 additions and 49 deletions
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue