diff options
author | Vito Caputo <vcaputo@gnugeneration.com> | 2016-12-13 08:20:24 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-13 08:20:24 -0800 |
commit | 2e292bd40f67e6e2612ad93fd77cdcd3449e4892 (patch) | |
tree | 4600607eb8c12af034b2bf29eec4f8207f9413c4 /rototiller32.c | |
parent | 3ea61db55a9c21f7621f8a64d91153cb1955b2ff (diff) | |
parent | 173cac2fe990496fca2403aa3a4bfcbd6007e7e6 (diff) |
Merge pull request #2 from vcaputo/moar
More candy
Diffstat (limited to 'rototiller32.c')
-rw-r--r-- | rototiller32.c | 214 |
1 files changed, 0 insertions, 214 deletions
diff --git a/rototiller32.c b/rototiller32.c deleted file mode 100644 index 13b762f..0000000 --- a/rototiller32.c +++ /dev/null @@ -1,214 +0,0 @@ -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <xf86drm.h> -#include <xf86drmMode.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <math.h> - -/* Copyright (C) 2016 Vito Caputo <vcaputo@pengaru.com> */ - -#define exit_if(_cond, _fmt, ...) \ - if (_cond) { \ - fprintf(stderr, "Fatal error: " _fmt "\n", ##__VA_ARGS__); \ - exit(EXIT_FAILURE); \ - } - -#define pexit_if(_cond, _fmt, ...) \ - exit_if(_cond, _fmt ": %s", ##__VA_ARGS__, strerror(errno)) - -/* Some defines for the fixed-point stuff in render(). */ -#define FIXED_TRIG_LUT_SIZE 4096 /* size of the cos/sin look-up tables */ -#define FIXED_BITS 12 /* fractional bits */ -#define FIXED_EXP 4096 /* 2^FIXED_BITS */ -#define FIXED_COS(_rad) costab[_rad % FIXED_TRIG_LUT_SIZE] -#define FIXED_SIN(_rad) sintab[_rad % FIXED_TRIG_LUT_SIZE] -#define FIXED_MULT(_a, _b) ((_a * _b) >> FIXED_BITS) -#define FIXED_NEW(_i) (_i << FIXED_BITS) -#define FIXED_TO_INT(_f) ((_f) >> FIXED_BITS) - -/* Draw a rotating checkered 256x256 texture into next_page. */ -static void render(uint32_t *current_page, uint32_t *next_page, int width, int height, int pitch) { - static int32_t costab[FIXED_TRIG_LUT_SIZE], sintab[FIXED_TRIG_LUT_SIZE]; - static uint8_t texture[256][256]; - static int initialized; - static uint32_t colors[2]; - static unsigned r, rr; - - int y_cos_r, y_sin_r, x_cos_r, x_sin_r, x_cos_r_init, x_sin_r_init, cos_r, sin_r; - int x, y, stride; - uint8_t tx, ty; /* 256x256 texture; 8 bit texture indices to modulo via overflow. */ - - if (!initialized) { - int i; - - initialized = 1; - - /* Generate simple checker pattern texture, nothing clever, feel free to play! */ - /* If you modify texture on every frame instead of only @ initialization you can - * produce some neat output. These values are indexed into colors[] below. */ - for (y = 0; y < 128; y++) { - for (x = 0; x < 128; x++) - texture[y][x] = 1; - for (; x < 256; x++) - texture[y][x] = 0; - } - for (; y < 256; y++) { - for (x = 0; x < 128; x++) - texture[y][x] = 0; - for (; x < 256; x++) - texture[y][x] = 1; - } - - /* Generate fixed-point cos & sin LUTs. */ - for (i = 0; i < FIXED_TRIG_LUT_SIZE; i++) { - costab[i] = ((cos((double)2*M_PI*i/FIXED_TRIG_LUT_SIZE))*FIXED_EXP); - sintab[i] = ((sin((double)2*M_PI*i/FIXED_TRIG_LUT_SIZE))*FIXED_EXP); - } - } - - pitch /= 4; /* pitch is number of bytes in a row, scale it to uint32_t units. */ - stride = (pitch - width); /* stride is number of words from row end to start of next row */ - - /* This is all done using fixed-point in the hopes of being faster, and yes assumptions - * are being made WRT the overflow of tx/ty as well, only tested on x86_64. */ - cos_r = FIXED_COS(r); - sin_r = FIXED_SIN(r); - - /* Vary the colors, this is just a mashup of sinusoidal rgb values. */ - colors[0] = ((FIXED_TO_INT(FIXED_MULT(FIXED_COS(rr), FIXED_NEW(127))) + 128) << 16) | - ((FIXED_TO_INT(FIXED_MULT(FIXED_SIN(rr / 2), FIXED_NEW(127))) + 128) << 8) | - ((FIXED_TO_INT(FIXED_MULT(FIXED_COS(rr / 3), FIXED_NEW(127))) + 128)); - - colors[1] = ((FIXED_TO_INT(FIXED_MULT(FIXED_SIN(rr / 2), FIXED_NEW(127))) + 128) << 16) | - ((FIXED_TO_INT(FIXED_MULT(FIXED_COS(rr / 2), FIXED_NEW(127))) + 128)) << 8 | - ((FIXED_TO_INT(FIXED_MULT(FIXED_SIN(rr), FIXED_NEW(127))) + 128) ); - - /* The dimensions are cut in half and negated to center the rotation. */ - /* The [xy]_{sin,cos}_r variables are accumulators to replace multiplication with addition. */ - x_cos_r_init = FIXED_MULT(-FIXED_NEW((width / 2)), cos_r); - x_sin_r_init = FIXED_MULT(-FIXED_NEW((width / 2)), sin_r); - - y_cos_r = FIXED_MULT(-FIXED_NEW((height / 2)), cos_r); - y_sin_r = FIXED_MULT(-FIXED_NEW((height / 2)), sin_r); - - for (y = 0; y < height; y++) { - - x_cos_r = x_cos_r_init; - x_sin_r = x_sin_r_init; - - for (x = 0; x < width; x++, next_page++) { - - tx = FIXED_TO_INT(x_sin_r - y_cos_r); - ty = FIXED_TO_INT(y_sin_r + x_cos_r); - - *next_page = colors[texture[ty][tx]]; - - x_cos_r += cos_r; - x_sin_r += sin_r; - } - - next_page += stride; - y_cos_r += cos_r; - y_sin_r += sin_r; - } - - // This governs the rotation and color cycle. - r += FIXED_TO_INT(FIXED_MULT(FIXED_SIN(rr), FIXED_NEW(16))); - rr += 2; -} - - - -int main(int argc, const char *argv[]) { - int drm_fd; - drmModeResPtr drm_res; - drmModeConnectorPtr drm_con; - uint32_t *fb_maps[2], drm_fbs[2]; - unsigned page = 0, next_page; - - pexit_if(!drmAvailable(), - "drm unavailable"); - - /* FIXME: use drmOpen(), requires digging to see what you're supposed to supply it for name. */ - pexit_if((drm_fd = open("/dev/dri/card0", O_RDWR)) < 0, - "unable to open drm device"); - - /* this requires root, but doesn't seem necessary for what's being done here, which is a bit surprising. */ -// pexit_if(drmSetMaster(drm_fd) < 0, -// "unable to set master"); - - exit_if(!(drm_res = drmModeGetResources(drm_fd)), - "unable to get drm resources"); - - exit_if(drm_res->count_connectors < 1 || - !(drm_con = drmModeGetConnector(drm_fd, drm_res->connectors[0])), - "unable to get first connector"); - - /* create double-buffers */ - struct drm_mode_create_dumb create_dumb = { - .width = drm_con->modes[0].hdisplay, - .height = drm_con->modes[0].vdisplay, - .bpp = 32, - .flags = 0, // unused, - }; - pexit_if(ioctl(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb) < 0, - "unable to create dumb buffer A"); - - struct drm_mode_map_dumb map_dumb = { - .handle = create_dumb.handle, - .pad = 0, // unused - }; - pexit_if(ioctl(drm_fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb) < 0, - "unable to prepare dumb buffer A for mmap"); - pexit_if(!(fb_maps[0] = mmap(NULL, create_dumb.size, PROT_READ|PROT_WRITE, MAP_SHARED, drm_fd, map_dumb.offset)), - "unable to mmap dumb buffer A"); - - pexit_if(drmModeAddFB(drm_fd, create_dumb.width, create_dumb.height, 24, create_dumb.bpp, create_dumb.pitch, create_dumb.handle, &drm_fbs[0]) < 0, - "unable to add dumb buffer A as fb"); - - /* second one... */ - pexit_if(ioctl(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb) < 0, - "unable to create dumb buffer B"); - pexit_if(drmModeAddFB(drm_fd, create_dumb.width, create_dumb.height, 24, create_dumb.bpp, create_dumb.pitch, create_dumb.handle, &drm_fbs[1]) < 0, - "unable to add dumb buffer B as fb"); - - map_dumb.handle = create_dumb.handle; - - pexit_if(ioctl(drm_fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb) < 0, - "unable to prepare dumb buffer B for mmap"); - pexit_if(!(fb_maps[1] = mmap(NULL, create_dumb.size, PROT_READ|PROT_WRITE, MAP_SHARED, drm_fd, map_dumb.offset)), - "unable to mmap dumb buffer B"); - - /* make the current page the visible one */ - pexit_if(drmModeSetCrtc(drm_fd, drm_res->crtcs[0], drm_fbs[page], 0, 0, drm_res->connectors, 1, drm_con->modes) < 0, - "unable to configure crtc"); - - drmEventContext drm_ev_ctx = { - .version = DRM_EVENT_CONTEXT_VERSION, - .vblank_handler = NULL, - .page_flip_handler = NULL - }; - - // now the rendering & page-flipping loop */ - for (;;page = next_page) { - next_page = (page + 1) % 2; - - /* render next page */ - render(fb_maps[page], fb_maps[next_page], create_dumb.width, create_dumb.height, create_dumb.pitch); - - /* flip synchronously */ - pexit_if(drmModePageFlip(drm_fd, drm_res->crtcs[0], drm_fbs[next_page], DRM_MODE_PAGE_FLIP_EVENT, NULL) < 0, - "unable to flip page %u to %u", page, next_page); - drmHandleEvent(drm_fd, &drm_ev_ctx); - } - - return EXIT_SUCCESS; -} |