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