* Last modified: Fri Feb 21 02:14:29 2014, <dmo2118@gmail.com>
* Added support for SMP rendering.
* Tweaked math a bit re: performance.
+ * Last modified: Tue Dec 30 16:43:33 2014, <dmo2118@gmail.com>
+ * Killed the black margin on the right and bottom.
+ * Reduced the default grid size to 2.
*/
#include <math.h>
#include "thread_util.h"
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
#else
typedef unsigned int uint32_t;
".background: black",
".foreground: white",
"*count: 3", /* number of waves */
- "*gridsize: 4", /* pixel size, smaller values for better resolution */
- "*ncolors: 128", /* number of colours used */
+ "*gridsize: 2", /* pixel size, smaller values for better resolution */
+ "*ncolors: 192", /* number of colours used */
"*hue: 0", /* hue to use for base color (0-360) */
"*speed: 30", /* speed of wave origins moving around */
"*delay: 30000", /* or something */
#ifdef HAVE_XSHM_EXTENSION
"*useSHM: True", /* use shared memory extension */
#endif /* HAVE_XSHM_EXTENSION */
-#ifdef USE_IPHONE
+#ifdef HAVE_MOBILE
"*ignoreRotation: True",
#endif
THREAD_DEFAULTS
*/
int w;
int h;
+ unsigned w_div_g, h_div_g;
Colormap cmap;
Screen *screen;
unsigned bits_per_pixel;
self->context = c;
self->thread_id = id;
- self->result_row = malloc((c->w / c->grid_size) * sizeof(unsigned));
+ self->result_row = malloc(c->w_div_g * sizeof(unsigned));
if(!self->result_row)
return ENOMEM;
#ifdef USE_XIMAGE
- self->row = malloc((c->w / c->grid_size) * sizeof(uint32_t));
+ self->row = malloc(c->w_div_g * sizeof(uint32_t));
if(!self->row) {
free(self->result_row);
return ENOMEM;
unsigned result;
int dist1;
int g = c->grid_size;
- unsigned w_div_g = c->w/g;
int dx, dy, g2 = 2 * g * g;
int px, py, px2g;
void *scanline = c->ximage->data + c->ximage->bytes_per_line * g * self->thread_id;
#endif
- for(j = self->thread_id; j < c->h/g; j += c->threadpool.count) {
+ for(j = self->thread_id; j < c->h_div_g; j += c->threadpool.count) {
px = g/2;
py = j*g + px;
- memset(self->result_row, 0, w_div_g * sizeof(unsigned));
+ memset(self->result_row, 0, c->w_div_g * sizeof(unsigned));
for(k = 0; k < c->count; k++) {
/* px2g = g*(px*2 + g); */
px2g = g2;
- for(i = 0; i < w_div_g; i++) {
+ for(i = 0; i < c->w_div_g; i++) {
/*
* Discarded possibilities for improving performance here:
* 1. Using octagon-based distance estimation
}
}
- for(i = 0; i < w_div_g; i++) {
+ for(i = 0; i < c->w_div_g; i++) {
result = self->result_row[i];
if(c->ximage->bits_per_pixel == 32)
{
uint32_t *ptr = (uint32_t *)scanline;
- for(i = 0; i < w_div_g; i++) {
+ for(i = 0; i < c->w_div_g; i++) {
for(k = 0; k < g; k++)
ptr[g*i+k] = self->row[i];
}
else if(c->ximage->bits_per_pixel == 24)
{
uint8_t *ptr = (uint8_t *)scanline;
- for(i = 0; i < w_div_g; i++) {
+ for(i = 0; i < c->w_div_g; i++) {
for(k = 0; k < g; k++) {
uint32_t pixel = self->row[i];
/* Might not work on big-endian. */
else if(c->ximage->bits_per_pixel == 16)
{
uint16_t *ptr = (uint16_t *)scanline;
- for(i = 0; i < w_div_g; i++) {
+ for(i = 0; i < c->w_div_g; i++) {
for(k = 0; k < g; k++)
ptr[g*i+k] = self->row[i];
}
else if(c->ximage->bits_per_pixel == 8)
{
uint8_t *ptr = (uint8_t *)scanline;
- for(i = 0; i < w_div_g; i++) {
+ for(i = 0; i < c->w_div_g; i++) {
for(k = 0; k < g; k++)
ptr[g*i+k] = self->row[i];
}
}
else
{
- for(i = 0; i < w_div_g; i++) {
+ for(i = 0; i < c->w_div_g; i++) {
for(k = 0; k < g; k++)
/* XPutPixel is thread safe as long as the XImage didn't have its
* bits_per_pixel changed. */
/* Set the width so that each thread can work on a different line. */
unsigned align = thread_memory_alignment(dpy) * 8 - 1;
+ unsigned wbits, w, h;
+
+ c->w = xgwa->width;
+ c->h = xgwa->height;
+ c->w_div_g = (c->w + c->grid_size - 1) / c->grid_size;
+ c->h_div_g = (c->h + c->grid_size - 1) / c->grid_size;
+ w = c->w_div_g * c->grid_size;
+ h = c->h_div_g * c->grid_size;
+
/* The width of a scan line, in *bits*. */
- unsigned width = (xgwa->width * c->bits_per_pixel + align) & ~align;
+ wbits = (w * c->bits_per_pixel + align) & ~align;
# ifdef HAVE_XSHM_EXTENSION
/*
{
c->ximage = create_xshm_image(dpy, xgwa->visual, xgwa->depth,
ZPixmap, 0, &c->shm_info,
- width / c->bits_per_pixel, xgwa->height);
+ wbits / c->bits_per_pixel, h);
if (!c->ximage)
c->use_shm = False;
/* If create_xshm_image fails, it will not be attempted again. */
c->ximage =
XCreateImage(dpy, xgwa->visual,
xgwa->depth, ZPixmap, 0, 0, /* depth, fmt, offset, data */
- xgwa->width, /* width */
+ w, /* width */
# ifdef USE_BIG_XIMAGE
- xgwa->height, /* height */
+ h, /* height */
# else
c->grid_size, /* height */
# endif
- 8, width / 8); /* pad, bpl */
+ 8, wbits / 8); /* pad, bpl */
if(c->ximage)
{
unsigned long valmask = 0;
#endif
-# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
+# ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */
dbuf = False;
# endif
c->delay = get_integer_resource(dpy, "delay", "Integer");
XGetWindowAttributes(c->dpy, c->win, &xgwa);
- c->w = xgwa.width;
- c->h = xgwa.height;
c->cmap = xgwa.colormap;
c->screen = xgwa.screen;
c->bits_per_pixel = get_bits_per_pixel(c->dpy, xgwa.depth);
c->radius = radius;
#endif
+ if (c->radius < 1) c->radius = 1;
c->wave_height = calloc(c->radius, sizeof(unsigned));
check_no_mem(dpy, c, c->wave_height);
* or eight pixels at a time.
*/
-#ifdef TEST_PATTERN
-static uint32_t
-_alloc_color(struct inter_context *c, uint16_t r, uint16_t g, uint16_t b)
-{
- XColor color;
- color.red = r;
- color.green = g;
- color.blue = b;
- XAllocColor(c->dpy, c->cmap, &color);
- return color.pixel;
-}
-
-static void _copy_test(Display *dpy, Drawable src, Drawable dst, GC gc, int x, int y, uint32_t cells)
-{
- XCopyArea(dpy, src, dst, gc, 0, 0, 3, 2, x, y);
-
- {
- XImage *image = XGetImage(dpy, src, 0, 0, 3, 2, cells, ZPixmap);
- XPutImage(dpy, dst, gc, image, 0, 0, x, y + 2, 3, 2);
- XDestroyImage(image);
- }
-}
-
-static void _test_pattern(Display *dpy, Drawable d, GC gc, const uint32_t *rgb)
-{
- unsigned x;
- for(x = 0; x != 3; ++x)
- {
- XSetForeground(dpy, gc, rgb[x]);
- XDrawPoint(dpy, d, gc, x, 0);
- XSetForeground(dpy, gc, rgb[2 - x]);
- XFillRectangle(dpy, d, gc, x, 1, 1, 1);
- }
-
- _copy_test(dpy, d, d, gc, 0, 2, rgb[0] | rgb[1] | rgb[2]);
-}
-#endif /* TEST_PATTERN */
-
static unsigned long do_inter(struct inter_context* c)
{
int i;
}
#endif
-#ifdef TEST_PATTERN
- {
-/* XWindowAttributes xgwa;
- XGetWindowAttributes(c->dpy, c->win, &xgwa); */
-
- /* if(xgwa.width >= 9 && xgwa.height >= 10) */
- {
- Screen *screen = ScreenOfDisplay(c->dpy, DefaultScreen(c->dpy));
- Visual *visual = DefaultVisualOfScreen(screen);
- Pixmap pixmap = XCreatePixmap(c->dpy, TARGET(c), 3, 10, visual_depth(screen, visual));
-
- {
- XSetForeground(c->dpy, c->copy_gc, _alloc_color(c, 0xffff, 0x7fff, 0x7fff));
- XDrawPoint(c->dpy, TARGET(c), c->copy_gc, 0, c->h - 1);
- }
-
- uint32_t rgb[3], cells;
- rgb[0] = _alloc_color(c, 0xffff, 0, 0);
- rgb[1] = _alloc_color(c, 0, 0xffff, 0);
- rgb[2] = _alloc_color(c, 0, 0, 0xffff);
- cells = rgb[0] | rgb[1] | rgb[2];
-
- _test_pattern(c->dpy, TARGET(c), c->copy_gc, rgb);
- _test_pattern(c->dpy, pixmap, c->copy_gc, rgb);
- /* Here's a good spot to verify that the pixmap contains the right colors
- * at the top. */
- _copy_test(c->dpy, TARGET(c), pixmap, c->copy_gc, 0, 6, cells);
-
- XCopyArea(c->dpy, pixmap, TARGET(c), c->copy_gc, 0, 0, 3, 10, 3, 0);
- {
- XImage *image = XGetImage(c->dpy, pixmap, 0, 0, 3, 10, cells, ZPixmap);
- XPutImage(c->dpy, TARGET(c), c->copy_gc, image, 0, 0, 6, 0, 3, 10);
- XDestroyImage(image);
- }
-
- XFreePixmap(c->dpy, pixmap);
- XSync(c->dpy, False);
- }
- }
-#endif /* TEST_PATTERN */
-
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
if (c->back_buf)
{
{
struct inter_context *c = (struct inter_context *) closure;
XWindowAttributes xgwa;
- Bool dbuf = (c->pix_buf
+ Bool dbuf = (!!c->pix_buf
# ifdef HAVE_DOUBLE_BUFFER_EXTENSION
|| c->back_buf
# endif
);
- c->w = w;
- c->h = h;
-
#ifdef USE_XIMAGE
destroy_image(dpy, c);
c->ximage = 0;