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