xref: /plan9-contrib/sys/src/9k/port/drawalloc.c (revision 45e6af3b6d7025ef7184352bb3f6852edd8de07e)
1*45e6af3bSDavid du Colombier #include <u.h>
2*45e6af3bSDavid du Colombier #include <libc.h>
3*45e6af3bSDavid du Colombier #include <draw.h>
4*45e6af3bSDavid du Colombier #include <memdraw.h>
5*45e6af3bSDavid du Colombier 
6*45e6af3bSDavid du Colombier void
memdrawallocinit(void)7*45e6af3bSDavid du Colombier memdrawallocinit(void)
8*45e6af3bSDavid du Colombier {
9*45e6af3bSDavid du Colombier }
10*45e6af3bSDavid du Colombier 
11*45e6af3bSDavid du Colombier void
memimagemove(void * from,void * to)12*45e6af3bSDavid du Colombier memimagemove(void *from, void *to)
13*45e6af3bSDavid du Colombier {
14*45e6af3bSDavid du Colombier 	Memdata *md;
15*45e6af3bSDavid du Colombier 
16*45e6af3bSDavid du Colombier 	md = *(Memdata**)to;
17*45e6af3bSDavid du Colombier 	if(md->base != from){
18*45e6af3bSDavid du Colombier 		print("compacted data not right: #%p\n", md->base);
19*45e6af3bSDavid du Colombier 		abort();
20*45e6af3bSDavid du Colombier 	}
21*45e6af3bSDavid du Colombier 	md->base = to;
22*45e6af3bSDavid du Colombier 
23*45e6af3bSDavid du Colombier 	/* if allocmemimage changes this must change too */
24*45e6af3bSDavid du Colombier 	md->bdata = (uchar*)md->base+sizeof(Memdata*)+sizeof(uintptr);
25*45e6af3bSDavid du Colombier }
26*45e6af3bSDavid du Colombier 
27*45e6af3bSDavid du Colombier Memimage*
allocmemimaged(Rectangle r,ulong chan,Memdata * md)28*45e6af3bSDavid du Colombier allocmemimaged(Rectangle r, ulong chan, Memdata *md)
29*45e6af3bSDavid du Colombier {
30*45e6af3bSDavid du Colombier 	int d;
31*45e6af3bSDavid du Colombier 	ulong l;
32*45e6af3bSDavid du Colombier 	Memimage *i;
33*45e6af3bSDavid du Colombier 
34*45e6af3bSDavid du Colombier 	if(Dx(r) <= 0 || Dy(r) <= 0){
35*45e6af3bSDavid du Colombier 		werrstr("bad rectangle %R", r);
36*45e6af3bSDavid du Colombier 		return nil;
37*45e6af3bSDavid du Colombier 	}
38*45e6af3bSDavid du Colombier 	if((d = chantodepth(chan)) == 0) {
39*45e6af3bSDavid du Colombier 		werrstr("bad channel descriptor %.8lux", chan);
40*45e6af3bSDavid du Colombier 		return nil;
41*45e6af3bSDavid du Colombier 	}
42*45e6af3bSDavid du Colombier 
43*45e6af3bSDavid du Colombier 	l = wordsperline(r, d);
44*45e6af3bSDavid du Colombier 
45*45e6af3bSDavid du Colombier 	i = mallocz(sizeof(Memimage), 1);
46*45e6af3bSDavid du Colombier 	if(i == nil)
47*45e6af3bSDavid du Colombier 		return nil;
48*45e6af3bSDavid du Colombier 
49*45e6af3bSDavid du Colombier 	i->data = md;
50*45e6af3bSDavid du Colombier 	i->zero = sizeof(ulong)*l*r.min.y;
51*45e6af3bSDavid du Colombier 
52*45e6af3bSDavid du Colombier 	if(r.min.x >= 0)
53*45e6af3bSDavid du Colombier 		i->zero += (r.min.x*d)/8;
54*45e6af3bSDavid du Colombier 	else
55*45e6af3bSDavid du Colombier 		i->zero -= (-r.min.x*d+7)/8;
56*45e6af3bSDavid du Colombier 	i->zero = -i->zero;
57*45e6af3bSDavid du Colombier 	i->width = l;
58*45e6af3bSDavid du Colombier 	i->r = r;
59*45e6af3bSDavid du Colombier 	i->clipr = r;
60*45e6af3bSDavid du Colombier 	i->flags = 0;
61*45e6af3bSDavid du Colombier 	i->layer = nil;
62*45e6af3bSDavid du Colombier 	i->cmap = memdefcmap;
63*45e6af3bSDavid du Colombier 	if(memsetchan(i, chan) < 0){
64*45e6af3bSDavid du Colombier 		free(i);
65*45e6af3bSDavid du Colombier 		return nil;
66*45e6af3bSDavid du Colombier 	}
67*45e6af3bSDavid du Colombier 	return i;
68*45e6af3bSDavid du Colombier }
69*45e6af3bSDavid du Colombier 
70*45e6af3bSDavid du Colombier Memimage*
allocmemimage(Rectangle r,ulong chan)71*45e6af3bSDavid du Colombier allocmemimage(Rectangle r, ulong chan)
72*45e6af3bSDavid du Colombier {
73*45e6af3bSDavid du Colombier 	int d;
74*45e6af3bSDavid du Colombier 	uchar *p;
75*45e6af3bSDavid du Colombier 	ulong l, nw;
76*45e6af3bSDavid du Colombier 	Memdata *md;
77*45e6af3bSDavid du Colombier 	Memimage *i;
78*45e6af3bSDavid du Colombier 
79*45e6af3bSDavid du Colombier 	if((d = chantodepth(chan)) == 0) {
80*45e6af3bSDavid du Colombier 		werrstr("bad channel descriptor %.8lux", chan);
81*45e6af3bSDavid du Colombier 		return nil;
82*45e6af3bSDavid du Colombier 	}
83*45e6af3bSDavid du Colombier 
84*45e6af3bSDavid du Colombier 	l = wordsperline(r, d);
85*45e6af3bSDavid du Colombier 	nw = l*Dy(r);
86*45e6af3bSDavid du Colombier 	md = malloc(sizeof(Memdata));
87*45e6af3bSDavid du Colombier 	if(md == nil)
88*45e6af3bSDavid du Colombier 		return nil;
89*45e6af3bSDavid du Colombier 
90*45e6af3bSDavid du Colombier 	md->ref = 1;
91*45e6af3bSDavid du Colombier 	md->base = malloc(sizeof(Memdata*)+sizeof(uintptr)+nw*sizeof(ulong));
92*45e6af3bSDavid du Colombier 	if(md->base == nil){
93*45e6af3bSDavid du Colombier 		free(md);
94*45e6af3bSDavid du Colombier 		return nil;
95*45e6af3bSDavid du Colombier 	}
96*45e6af3bSDavid du Colombier 
97*45e6af3bSDavid du Colombier 	p = (uchar*)md->base;
98*45e6af3bSDavid du Colombier 	*(Memdata**)p = md;
99*45e6af3bSDavid du Colombier 	p += sizeof(Memdata*);
100*45e6af3bSDavid du Colombier 
101*45e6af3bSDavid du Colombier 	*(uintptr*)p = getcallerpc(&r);
102*45e6af3bSDavid du Colombier 	p += sizeof(uintptr);
103*45e6af3bSDavid du Colombier 
104*45e6af3bSDavid du Colombier 	/* if this changes, memimagemove must change too */
105*45e6af3bSDavid du Colombier 	md->bdata = p;
106*45e6af3bSDavid du Colombier 	md->allocd = 1;
107*45e6af3bSDavid du Colombier 
108*45e6af3bSDavid du Colombier 	i = allocmemimaged(r, chan, md);
109*45e6af3bSDavid du Colombier 	if(i == nil){
110*45e6af3bSDavid du Colombier 		free(md->base);
111*45e6af3bSDavid du Colombier 		free(md);
112*45e6af3bSDavid du Colombier 		return nil;
113*45e6af3bSDavid du Colombier 	}
114*45e6af3bSDavid du Colombier 	md->imref = i;
115*45e6af3bSDavid du Colombier 	return i;
116*45e6af3bSDavid du Colombier }
117*45e6af3bSDavid du Colombier 
118*45e6af3bSDavid du Colombier void
freememimage(Memimage * i)119*45e6af3bSDavid du Colombier freememimage(Memimage *i)
120*45e6af3bSDavid du Colombier {
121*45e6af3bSDavid du Colombier 	if(i == nil)
122*45e6af3bSDavid du Colombier 		return;
123*45e6af3bSDavid du Colombier 	if(i->data->ref-- == 1 && i->data->allocd){
124*45e6af3bSDavid du Colombier 		if(i->data->base)
125*45e6af3bSDavid du Colombier 			free(i->data->base);
126*45e6af3bSDavid du Colombier 		free(i->data);
127*45e6af3bSDavid du Colombier 	}
128*45e6af3bSDavid du Colombier 	free(i);
129*45e6af3bSDavid du Colombier }
130