#include #include #include #include #include #include #include #include #include #include #include #include struct dial_asset { char *feature; int width; int height; int pos_x; int pos_y; char *filename; char *data; }; struct dial_param { sem_t control_sem; struct biqueue *bq; }; #include #include #define NUM_DIAL_FEATURES (sizeof(dassets) / sizeof(struct dial_asset)) static int load_dial_asset(struct dial_asset *d) { int r; int fd; int sz; fd = open(d->filename, O_RDONLY); if(fd < 0) { printf("could not open %s, %d\n", d->filename, errno); goto err1; } sz = d->width * d->height * 4; d->data = calloc(sz, 1); if(!d->data) { printf("could not allocate data for %s\n", d->feature); goto err2; } r = read(fd, d->data, sz); if(r != sz) { printf("could not read data for %s\n", d->feature); goto err3; } close(fd); return 0; err3: free(d->data); err2: close(fd); err1: return -1; } static void dial_wait_for_next_slot(struct dial_param *prm) { int r; retry: r = sem_wait(&prm->control_sem); if(r) goto retry; } static void add_to_layer(struct sw_blend_layer *layers, int index, char *name, struct dial_asset *d) { layers[index].buf.width = d->width; layers[index].buf.height = d->height; layers[index].buf.format = DRM_FORMAT_ARGB8888; layers[index].buf.stride = d->width * 4; layers[index].buf.vaddr = d->data; layers[index].buf.stride2 = 0; layers[index].buf.vaddr2 = NULL; layers[index].x = d->pos_x; layers[index].y = d->pos_y; layers[index].blend = true; layers[index].blendfuncs = SRC_GL_SRC_ALPHA | DST_GL_ONE_MINUS_SRC_ALPHA; layers[index].name = name; } static void *dial_run(void *arg) { int i; struct dial_param *prm = arg; struct rect damage = { .top = 0, .left = 0, .width = CONFIG_WIDTH, .height = CONFIG_HEIGHT, }; struct sw_blend_buffer dst; struct sw_blend_layer layers[NUM_DIAL_FEATURES]; while(true) { struct buffer *buf; dial_wait_for_next_slot(prm); buf = list_entry(bq_next_empty(prm->bq), struct buffer, link); dst.width = buf->width; dst.height = buf->height; dst.format = buf->format; dst.stride = buf->stride; dst.vaddr = buf->vaddr; dst.stride2 = 0; dst.vaddr2 = NULL; for(i = 0; i < NUM_DIAL_FEATURES; i++) { add_to_layer(layers, i, dassets[i].feature, &dassets[i]); } sw_blend(&dst, layers, NUM_DIAL_FEATURES, true, 0xff000000, NULL, 0, &damage, 1); bq_queue_full(prm->bq, &buf->link); } } void dial_start(struct biqueue *bq) { int i; pthread_t tid; for(i = 0; i < NUM_DIAL_FEATURES; i++) { load_dial_asset(&dassets[i]); } struct dial_param *prm = calloc(sizeof(*prm), 1); sem_init(&prm->control_sem, 0, 1); prm->bq = bq; pthread_create(&tid, NULL, dial_run, prm); }