Added shadow precomputation for large-enough windows.

This commit is contained in:
dolio 2004-09-21 22:59:38 +00:00
parent b73a269bf2
commit 26fd15f06b
2 changed files with 68 additions and 6 deletions

View File

@ -1,3 +1,10 @@
2004-09-21 Dan Doel <dolio@case.edu>
* xcompmgr.c: (presum_gaussian), (make_shadow), (main):
Added precomputation of shadows to make them a little more
friendly to slower computers (and make ridiculously huge
shadows usable on faster computers).
2004-09-20 Adam Jackson <ajax@freedesktop.org> 2004-09-20 Adam Jackson <ajax@freedesktop.org>
* xcompmgr.c: * xcompmgr.c:

View File

@ -192,6 +192,11 @@ Bool fadeTrans = False;
Bool autoRedirect = False; Bool autoRedirect = False;
/* For shadow precomputation */
int Gsize = -1;
unsigned char *shadowCorner = NULL;
unsigned char *shadowTop = NULL;
int int
get_time_in_milliseconds () get_time_in_milliseconds ()
{ {
@ -472,6 +477,42 @@ sum_gaussian (conv *map, double opacity, int x, int y, int width, int height)
return ((unsigned char) (v * opacity * 255.0)); return ((unsigned char) (v * opacity * 255.0));
} }
/* precompute shadow corners and sides to save time for large windows */
static void
presum_gaussian (conv *map)
{
int center = map->size/2;
int opacity, x, y;
Gsize = map->size;
if (shadowCorner)
free ((void *)shadowCorner);
if (shadowTop)
free ((void *)shadowTop);
shadowCorner = (unsigned char *)(malloc ((Gsize + 1) * (Gsize + 1) * 26));
shadowTop = (unsigned char *)(malloc ((Gsize + 1) * 26));
for (x = 0; x <= Gsize; x++)
{
shadowTop[25 * (Gsize + 1) + x] = sum_gaussian (map, 1, x - center, center, Gsize * 2, Gsize * 2);
for(opacity = 0; opacity < 25; opacity++)
shadowTop[opacity * (Gsize + 1) + x] = shadowTop[25 * (Gsize + 1) + x] * opacity / 25;
for(y = 0; y <= x; y++)
{
shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x]
= sum_gaussian (map, 1, x - center, y - center, Gsize * 2, Gsize * 2);
shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + x * (Gsize + 1) + y]
= shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x];
for(opacity = 0; opacity < 25; opacity++)
shadowCorner[opacity * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x]
= shadowCorner[opacity * (Gsize + 1) * (Gsize + 1) + x * (Gsize + 1) + y]
= shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x] * opacity / 25;
}
}
}
static XImage * static XImage *
make_shadow (Display *dpy, double opacity, int width, int height) make_shadow (Display *dpy, double opacity, int width, int height)
{ {
@ -485,7 +526,7 @@ make_shadow (Display *dpy, double opacity, int width, int height)
int x, y; int x, y;
unsigned char d; unsigned char d;
int x_diff; int x_diff;
int opacity_int = (int)(opacity * 25);
data = malloc (swidth * sheight * sizeof (unsigned char)); data = malloc (swidth * sheight * sizeof (unsigned char));
if (!data) if (!data)
return 0; return 0;
@ -508,7 +549,9 @@ make_shadow (Display *dpy, double opacity, int width, int height)
/* /*
* center (fill the complete data array) * center (fill the complete data array)
*/ */
if (Gsize > 0)
d = shadowTop[opacity_int * (Gsize + 1) + Gsize];
else
d = sum_gaussian (gaussianMap, opacity, center, center, width, height); d = sum_gaussian (gaussianMap, opacity, center, center, width, height);
memset(data, d, sheight * swidth); memset(data, d, sheight * swidth);
@ -525,6 +568,9 @@ make_shadow (Display *dpy, double opacity, int width, int height)
for (y = 0; y < ylimit; y++) for (y = 0; y < ylimit; y++)
for (x = 0; x < xlimit; x++) for (x = 0; x < xlimit; x++)
{ {
if (xlimit == Gsize && ylimit == Gsize)
d = shadowCorner[opacity_int * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x];
else
d = sum_gaussian (gaussianMap, opacity, x - center, y - center, width, height); d = sum_gaussian (gaussianMap, opacity, x - center, y - center, width, height);
data[y * swidth + x] = d; data[y * swidth + x] = d;
data[(sheight - y - 1) * swidth + x] = d; data[(sheight - y - 1) * swidth + x] = d;
@ -540,6 +586,9 @@ make_shadow (Display *dpy, double opacity, int width, int height)
{ {
for (y = 0; y < ylimit; y++) for (y = 0; y < ylimit; y++)
{ {
if (ylimit == Gsize)
d = shadowTop[opacity_int * (Gsize + 1) + y];
else
d = sum_gaussian (gaussianMap, opacity, center, y - center, width, height); d = sum_gaussian (gaussianMap, opacity, center, y - center, width, height);
memset (&data[y * swidth + gsize], d, x_diff); memset (&data[y * swidth + gsize], d, x_diff);
memset (&data[(sheight - y - 1) * swidth + gsize], d, x_diff); memset (&data[(sheight - y - 1) * swidth + gsize], d, x_diff);
@ -552,6 +601,9 @@ make_shadow (Display *dpy, double opacity, int width, int height)
for (x = 0; x < xlimit; x++) for (x = 0; x < xlimit; x++)
{ {
if (xlimit == Gsize)
d = shadowTop[opacity_int * (Gsize + 1) + x];
else
d = sum_gaussian (gaussianMap, opacity, x - center, center, width, height); d = sum_gaussian (gaussianMap, opacity, x - center, center, width, height);
for (y = gsize; y < sheight - gsize; y++) for (y = gsize; y < sheight - gsize; y++)
{ {
@ -1901,7 +1953,10 @@ main (int argc, char **argv)
pa.subwindow_mode = IncludeInferiors; pa.subwindow_mode = IncludeInferiors;
if (compMode == CompClientShadows) if (compMode == CompClientShadows)
{
gaussianMap = make_gaussian_map(dpy, shadowRadius); gaussianMap = make_gaussian_map(dpy, shadowRadius);
presum_gaussian (gaussianMap);
}
root_width = DisplayWidth (dpy, scr); root_width = DisplayWidth (dpy, scr);
root_height = DisplayHeight (dpy, scr); root_height = DisplayHeight (dpy, scr);