vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

alloc.c (3421B)


      1 #include "u.h"
      2 #include "lib.h"
      3 #include "draw.h"
      4 #include "memdraw.h"
      5 #define poolalloc(a,b) malloc(b)
      6 #define poolfree(a, b) free(b)
      7 
      8 void
      9 memimagemove(void *from, void *to)
     10 {
     11 	Memdata *md;
     12 
     13 	md = *(Memdata**)to;
     14 	if(md->base != from){
     15 		print("compacted data not right: #%p\n", md->base);
     16 		abort();
     17 	}
     18 	md->base = to;
     19 
     20 	/* if allocmemimage changes this must change too */
     21 	md->bdata = (uchar*)md->base+sizeof(Memdata*)+sizeof(uint32);
     22 }
     23 
     24 Memimage*
     25 allocmemimaged(Rectangle r, uint32 chan, Memdata *md, void *X)
     26 {
     27 	int d;
     28 	uint32 l;
     29 	Memimage *i;
     30 
     31 	if(Dx(r) <= 0 || Dy(r) <= 0){
     32 		werrstr("bad rectangle %R", r);
     33 		return nil;
     34 	}
     35 	if((d = chantodepth(chan)) == 0) {
     36 		werrstr("bad channel descriptor %.8lux", chan);
     37 		return nil;
     38 	}
     39 
     40 	l = wordsperline(r, d);
     41 
     42 	i = mallocz(sizeof(Memimage), 1);
     43 	if(i == nil)
     44 		return nil;
     45 
     46 	i->data = md;
     47 	i->x = X;
     48 	i->zero = sizeof(uint32)*l*r.min.y;
     49 	
     50 	if(r.min.x >= 0)
     51 		i->zero += (r.min.x*d)/8;
     52 	else
     53 		i->zero -= (-r.min.x*d+7)/8;
     54 	i->zero = -i->zero;
     55 	i->width = l;
     56 	i->r = r;
     57 	i->clipr = r;
     58 	i->flags = 0;
     59 	i->layer = nil;
     60 	i->cmap = memdefcmap;
     61 	if(memsetchan(i, chan) < 0){
     62 		free(i);
     63 		return nil;
     64 	}
     65 	return i;
     66 }
     67 
     68 Memimage*
     69 _allocmemimage(Rectangle r, uint32 chan)
     70 {
     71 	int d;
     72 	uchar *p;
     73 	uint32 l, nw;
     74 	Memdata *md;
     75 	Memimage *i;
     76 
     77 	if((d = chantodepth(chan)) == 0) {
     78 		werrstr("bad channel descriptor %.8lux", chan);
     79 		return nil;
     80 	}
     81 
     82 	l = wordsperline(r, d);
     83 	nw = l*Dy(r);
     84 	md = malloc(sizeof(Memdata));
     85 	if(md == nil)
     86 		return nil;
     87 
     88 	md->ref = 1;
     89 	md->base = poolalloc(imagmem, sizeof(Memdata*)+(1+nw)*sizeof(uint32));
     90 	if(md->base == nil){
     91 		free(md);
     92 		return nil;
     93 	}
     94 
     95 	p = (uchar*)md->base;
     96 	*(Memdata**)p = md;
     97 	p += sizeof(Memdata*);
     98 
     99 	*(uint32*)p = getcallerpc(&r);
    100 	p += sizeof(uint32);
    101 
    102 	/* if this changes, memimagemove must change too */
    103 	md->bdata = p;
    104 	md->allocd = 1;
    105 
    106 	i = allocmemimaged(r, chan, md, nil);
    107 	if(i == nil){
    108 		poolfree(imagmem, md->base);
    109 		free(md);
    110 		return nil;
    111 	}
    112 	md->imref = i;
    113 	return i;
    114 }
    115 
    116 void
    117 _freememimage(Memimage *i)
    118 {
    119 	if(i == nil)
    120 		return;
    121 	if(i->data->ref-- == 1 && i->data->allocd){
    122 		if(i->data->base)
    123 			poolfree(imagmem, i->data->base);
    124 		free(i->data);
    125 	}
    126 	free(i);
    127 }
    128 
    129 /*
    130  * Wordaddr is deprecated.
    131  */
    132 uint32*
    133 wordaddr(Memimage *i, Point p)
    134 {
    135 	return (uint32*) ((uintptr)byteaddr(i, p) & ~(sizeof(uint32)-1));
    136 }
    137 
    138 uchar*
    139 byteaddr(Memimage *i, Point p)
    140 {
    141 	uchar *a;
    142 
    143 	a = i->data->bdata+i->zero+sizeof(uint32)*p.y*i->width;
    144 
    145 	if(i->depth < 8){
    146 		/*
    147 		 * We need to always round down,
    148 		 * but C rounds toward zero.
    149 		 */
    150 		int np;
    151 		np = 8/i->depth;
    152 		if(p.x < 0)
    153 			return a+(p.x-np+1)/np;
    154 		else
    155 			return a+p.x/np;
    156 	}
    157 	else
    158 		return a+p.x*(i->depth/8);
    159 }
    160 
    161 int
    162 memsetchan(Memimage *i, uint32 chan)
    163 {
    164 	int d;
    165 	int t, j, k;
    166 	uint32 cc;
    167 	int bytes;
    168 
    169 	if((d = chantodepth(chan)) == 0) {
    170 		werrstr("bad channel descriptor");
    171 		return -1;
    172 	}
    173 
    174 	i->depth = d;
    175 	i->chan = chan;
    176 	i->flags &= ~(Fgrey|Falpha|Fcmap|Fbytes);
    177 	bytes = 1;
    178 	for(cc=chan, j=0, k=0; cc; j+=NBITS(cc), cc>>=8, k++){
    179 		t=TYPE(cc);
    180 		if(t < 0 || t >= NChan){
    181 			werrstr("bad channel string");
    182 			return -1;
    183 		}
    184 		if(t == CGrey)
    185 			i->flags |= Fgrey;
    186 		if(t == CAlpha)
    187 			i->flags |= Falpha;
    188 		if(t == CMap && i->cmap == nil){
    189 			i->cmap = memdefcmap;
    190 			i->flags |= Fcmap;
    191 		}
    192 
    193 		i->shift[t] = j;
    194 		i->mask[t] = (1<<NBITS(cc))-1;
    195 		i->nbits[t] = NBITS(cc);
    196 		if(NBITS(cc) != 8)
    197 			bytes = 0;
    198 	}
    199 	i->nchan = k;
    200 	if(bytes)
    201 		i->flags |= Fbytes;
    202 	return 0;
    203 }