changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/games/mandel.c

changeset 4350: 1f9d7811d546
parent: a07a65338a49
author: cinap_lenrek@felloff.net
date: Mon, 16 Mar 2015 05:46:08 +0100
permissions: -rw-r--r--
description: kernel: get rid of auxpage() and preserve cache index bits in Page.va in mount cache

the mount cache uses Page.va to store cached range offset and
limit, but mips kernel uses cache index bits from Page.va to
maintain page coloring. Page.va was not initialized by auxpage().

this change removes auxpage() which was primarily used only
by the mount cache and use newpage() with cache file offset
page as va so we will get a page of the right color.

mount cache keeps the index bits intact by only using the top
and buttom PGSHIFT bits of Page.va for the range offset/limit.
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <thread.h>
5 #include <mouse.h>
6 #include <cursor.h>
7 
8 enum { ncolors = 600 };
9 
10 double xmin = -2, xmax = 1;
11 double ymin = -1, ymax = 1;
12 Mousectl *mctl;
13 Rendez rend;
14 int stopdraw;
15 uchar *imagedata;
16 Image *image;
17 extern Cursor reading;
18 uchar colors[3 * (ncolors + 1)];
19 
20 double
21 convx(Rectangle *r, int x)
22 {
23  return (xmax - xmin) * (x - r->min.x) / (r->max.x - r->min.x) + xmin;
24 }
25 
26 double
27 convy(Rectangle *r, int y)
28 {
29  return (ymax - ymin) * (r->max.y - y) / (r->max.y - r->min.y) + ymin;
30 }
31 
32 void
33 pixel(int x, int y)
34 {
35  draw(screen, Rect(x, y, x + 1, y + 1), display->black, nil, ZP);
36 }
37 
38 ulong
39 iterate(double x, double y)
40 {
41  int i;
42  double zx, zy, zx2, zy2, v;
43 
44  zx = zy = zx2 = zy2 = 0;
45  for(i = 0; i < 100; i++){
46  zy = 2 * zx * zy + y;
47  zx = zx2 - zy2 + x;
48  zx2 = zx * zx;
49  zy2 = zy * zy;
50  if(zx2 + zy2 >= 4){
51  v = 2 + i - log(log(sqrt(zx2 + zy2)) / log(i + 2)) / 0.69314718;
52  return (int)(v * 1000) % ncolors;
53  }
54  }
55  return 0;
56 }
57 
58 void
59 redrawproc(void *)
60 {
61  int x, y;
62  uchar *p, *q;
63 
64  qlock(rend.l);
65  for(;;){
66  setcursor(mctl, &reading);
67  p = imagedata;
68  for(y = screen->r.min.y; y < screen->r.max.y; y++)
69  for(x = screen->r.min.x; x < screen->r.max.x; x++){
70  if(stopdraw)
71  goto check;
72  q = colors + 3 * iterate(convx(&screen->r, x), convy(&screen->r, y));
73  *p++ = *q++;
74  *p++ = *q++;
75  *p++ = *q;
76  }
77  if(stopdraw)
78  goto check;
79  lockdisplay(display);
80  loadimage(image, image->r, imagedata, Dx(image->r) * Dy(image->r) * 3);
81  draw(screen, screen->r, image, nil, screen->r.min);
82  flushimage(display, 1);
83  unlockdisplay(display);
84  check:
85  stopdraw = 0;
86  setcursor(mctl, nil);
87  rsleep(&rend);
88  stopdraw = 0;
89  }
90 }
91 
92 void
93 zoom(void)
94 {
95  Rectangle r;
96  double xmin_, xmax_, ymin_, ymax_;
97 
98  r = getrect(3, mctl);
99  if(r.min.x == 0 && r.min.y == 0 && r.max.x == 0 && r.max.y == 0)
100  return;
101  xmin_ = convx(&screen->r, r.min.x);
102  xmax_ = convx(&screen->r, r.max.x);
103  ymin_ = convy(&screen->r, r.max.y);
104  ymax_ = convy(&screen->r, r.min.y);
105  stopdraw = 1;
106  qlock(rend.l);
107  xmin = xmin_;
108  xmax = xmax_;
109  ymin = ymin_;
110  ymax = ymax_;
111  rwakeup(&rend);
112  qunlock(rend.l);
113 }
114 
115 char *menus[] = {
116  "zoom in",
117  "reset",
118  "quit",
119  nil,
120 };
121 
122 Menu menu = {
123  .item = menus
124 };
125 
126 void
127 resizethread(void *)
128 {
129  ulong l;
130 
131  for(;;){
132  if(recv(mctl->resizec, &l) < 1)
133  continue;
134  stopdraw = 1;
135  qlock(rend.l);
136  if(getwindow(display, Refnone) < 0)
137  sysfatal("getwindow: %r");
138  freeimage(image);
139  free(imagedata);
140  image = allocimage(display, screen->r, RGB24, 0, DBlack);
141  imagedata = malloc(3 * Dx(screen->r) * Dy(screen->r));
142  rwakeup(&rend);
143  qunlock(rend.l);
144  }
145 }
146 
147 void
148 initcolors(void)
149 {
150  uchar *p;
151  int h, x;
152 
153  for(p = colors + 3, h = 0; p < colors + nelem(colors); h++){
154  x = 0xFF - abs(h % (ncolors / 3) - ncolors / 6) * 0xFF / (ncolors / 6);
155  if(h < ncolors/6){
156  *p++ = 0xFF;
157  *p++ = x;
158  *p++ = 0;
159  }else if(h < ncolors/3){
160  *p++ = x;
161  *p++ = 0xFF;
162  *p++ = 0;
163  }else if(h < ncolors/2){
164  *p++ = 0;
165  *p++ = 0xFF;
166  *p++ = x;
167  }else if(h < 2*ncolors/3){
168  *p++ = 0;
169  *p++ = x;
170  *p++ = 0xFF;
171  }else if(h < 5*ncolors/6){
172  *p++ = x;
173  *p++ = 0;
174  *p++ = 0xFF;
175  }else{
176  *p++ = 0xFF;
177  *p++ = 0;
178  *p++ = x;
179  }
180  }
181 }
182 
183 void
184 threadmain()
185 {
186  static QLock ql;
187  int rc;
188 
189  if(initdraw(nil, nil, "mandelbrot") < 0)
190  sysfatal("initdraw: %r");
191  display->locking = 1;
192  unlockdisplay(display);
193  if((mctl = initmouse(nil, screen)) == nil)
194  sysfatal("initmouse: %r");
195  rend.l = &ql;
196  image = allocimage(display, screen->r, RGB24, 0, DBlack);
197  imagedata = malloc(3 * Dx(screen->r) * Dy(screen->r));
198  initcolors();
199  proccreate(redrawproc, nil, mainstacksize);
200  threadcreate(resizethread, nil, mainstacksize);
201  for(;;){
202  readmouse(mctl);
203  if(mctl->buttons & 4){
204  lockdisplay(display);
205  rc = menuhit(3, mctl, &menu, nil);
206  unlockdisplay(display);
207  switch(rc){
208  case 0:
209  zoom();
210  break;
211  case 1:
212  stopdraw = 1;
213  qlock(rend.l);
214  xmin = -2;
215  xmax = 1;
216  ymin = -1;
217  ymax = 1;
218  rwakeup(&rend);
219  qunlock(rend.l);
220  break;
221  case 2:
222  threadexitsall(nil);
223  }
224  }
225  }
226 }
227 
228 Cursor reading = {
229  {-1, -1},
230  {0xff, 0x80, 0xff, 0x80, 0xff, 0x00, 0xfe, 0x00,
231  0xff, 0x00, 0xff, 0x80, 0xff, 0xc0, 0xef, 0xe0,
232  0xc7, 0xf0, 0x03, 0xf0, 0x01, 0xe0, 0x00, 0xc0,
233  0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, },
234  {0x00, 0x00, 0x7f, 0x00, 0x7e, 0x00, 0x7c, 0x00,
235  0x7e, 0x00, 0x7f, 0x00, 0x6f, 0x80, 0x47, 0xc0,
236  0x03, 0xe0, 0x01, 0xf0, 0x00, 0xe0, 0x00, 0x40,
237  0x00, 0x00, 0x01, 0xb6, 0x01, 0xb6, 0x00, 0x00, }
238 };