[sixel] queue + engine #2537

pull/2610/head
nick black 2 years ago committed by nick black
parent b6d01be757
commit 403ae965fa

@ -1,9 +1,13 @@
#include <math.h>
#include <stdatomic.h>
#include "internal.h"
#include "fbuf.h"
#define RGBSIZE 3
// number of worker threads FIXME
#define POPULATION 3
// this palette entry is a sentinel for a transparent pixel (and thus caps
// the palette at 65535 other entries).
#define TRANS_PALETTE_ENTRY 65535
@ -181,6 +185,7 @@ qidx(const qnode* q){
}
typedef struct qstate {
atomic_int refcount; // initialized to worker count
// we always work in terms of quantized colors (quantization is the first
// step of rendering), using indexes into the derived palette. the actual
// palette need only be stored during the initial render, since the sixel
@ -199,6 +204,7 @@ typedef struct qstate {
// these are the leny and lenx passed to sixel_blit(), which are likely
// different from those reachable through bargs->len{y,x}!
int leny, lenx;
struct qstate* next; // next in the threading engine's queue
} qstate;
#define QNODECOUNT 1000
@ -230,6 +236,8 @@ alloc_qstate(unsigned colorregs, qstate* qs){
// when we pull a dynamic one that it needs its popcount initialized.
memset(qs->qnodes, 0, sizeof(qnode) * QNODECOUNT);
qs->table = NULL;
qs->refcount = 1 + POPULATION;
qs->next = NULL;
return 0;
}
@ -1435,7 +1443,7 @@ int sixel_draw(const tinfo* ti, const ncpile* p, sprixel* s, fbuf* f,
// we keep a few worker threads spun up to assist with quantization.
typedef struct sixel_engine {
// FIXME we'll want maybe one per core in our cpuset?
pthread_t tids[3];
pthread_t tids[POPULATION];
unsigned workers;
unsigned workers_wanted;
pthread_mutex_t lock;
@ -1461,18 +1469,27 @@ sixel_worker(void* v){
}else{
pthread_mutex_unlock(&globsengine.lock);
}
qstate* qs = NULL;
pthread_mutex_lock(&sengine->lock);
do{
pthread_mutex_lock(&sengine->lock);
while(sengine->qs == NULL && !sengine->done){
while((sengine->qs == NULL || sengine->qs == qs) && !sengine->done){
pthread_cond_wait(&sengine->cond, &sengine->lock);
}
if(sengine->done){
pthread_mutex_unlock(&sengine->lock);
return NULL;
}
// FIXME take workchunk
qs = sengine->qs;
pthread_mutex_unlock(&sengine->lock);
// FIXME handle workchunk
// FIXME handle qs
if(--qs->refcount == 0){
qstate* qnext = qs->next;
free_qstate(qs);
pthread_mutex_lock(&sengine->lock);
sengine->qs = qnext;
}else{
pthread_mutex_lock(&sengine->lock);
}
}while(1);
}

Loading…
Cancel
Save