26
|
1 #include <iostream>
|
|
2 #include <SDL.h>
|
|
3 #include "polygon.h"
|
|
4 #include "viewer.h"
|
|
5 #include "sys.h"
|
109
|
6 #include "SpuSpan.h"
|
105
|
7 #include "Func.h"
|
109
|
8 #include "error.h"
|
|
9 #include "fb.h"
|
26
|
10 using namespace std;
|
|
11
|
109
|
12 int Viewer::width;
|
|
13 int Viewer::height;
|
|
14 int Viewer::bpp;
|
|
15 int Viewer::spe_num;
|
|
16
|
28
|
17 #define redMask 0x00ff0000
|
|
18 #define greenMask 0x0000ff00
|
|
19 #define blueMask 0x000000ff
|
|
20 #define alphaMask 0
|
|
21
|
48
|
22 extern int create_sgp(Polygon *sg, SceneGraphPack *sgp);
|
26
|
23
|
109
|
24 #if 0
|
|
25 #define MEMORY_ALLOCATION(dest, align, size) \
|
|
26 posix_memalign((void**)(dest), (align), (size))
|
|
27 //void posix_memalign(void** dest, size_t align, size_t size){
|
|
28 //*dest = malloc(size);
|
|
29 //}
|
|
30 #else
|
|
31 #define MEMORY_ALLOCATION(dest, align, size) \
|
|
32 *((void**)dest) = malloc((size))
|
|
33 #endif
|
|
34
|
|
35
|
|
36
|
|
37
|
26
|
38 Viewer::Viewer(int b, int w, int h)
|
|
39 {
|
28
|
40 bpp = b;
|
|
41 width = w;
|
|
42 height = h;
|
109
|
43 spe_num = 1;
|
26
|
44 }
|
|
45
|
109
|
46 Viewer::Viewer(int b, int w, int h, int _num)
|
|
47 {
|
|
48 bpp = b;
|
|
49 width = w;
|
|
50 height = h;
|
|
51 spe_num = _num;
|
|
52 }
|
|
53
|
102
|
54 unsigned int fbdev_addr;
|
26
|
55
|
|
56 void Viewer::sdl_init()
|
|
57 {
|
67
|
58 if (SDL_Init( SDL_INIT_VIDEO ) < 0) {
|
28
|
59 fprintf(stderr,"Couldn't initialize SDL: %s\n",SDL_GetError());
|
|
60 exit( 1 );
|
26
|
61 }
|
89
|
62
|
109
|
63 #ifndef _DEBUG
|
67
|
64 screen = SDL_SetVideoMode( width, height, bpp, SDL_HWSURFACE);
|
|
65 if (screen == NULL) {
|
|
66 fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
|
|
67 SDL_Quit();
|
|
68 exit(1);
|
|
69 }
|
109
|
70 fbdev_addr = (uint32)screen->pixels;
|
70
|
71 #else
|
102
|
72 fbdev_addr = get_fbdev_addr();
|
109
|
73 if (fbdev_addr == 0) {
|
|
74 fbdev_addr = (unsigned int)(new Uint32[width*height*32/8]);
|
|
75 }
|
102
|
76 screen = SDL_CreateRGBSurfaceFrom((void*)fbdev_addr, width, height, 32,
|
|
77 width*4, redMask, greenMask,
|
|
78 blueMask, alphaMask);
|
70
|
79 #endif
|
26
|
80 }
|
|
81
|
|
82
|
|
83 int Viewer::get_ticks()
|
|
84 {
|
28
|
85 int time;
|
|
86 time = SDL_GetTicks();
|
|
87 return time;
|
26
|
88 }
|
|
89
|
|
90 bool Viewer::quit_check()
|
|
91 {
|
28
|
92 bool quit = false;
|
|
93 SDL_Event event;
|
|
94 while(SDL_PollEvent(&event))
|
26
|
95 {
|
28
|
96 if(event.type==SDL_QUIT)
|
26
|
97 {
|
28
|
98 quit = true;
|
|
99 return quit;
|
26
|
100 }
|
|
101 }
|
28
|
102 return quit;
|
26
|
103 }
|
|
104
|
|
105 void Viewer::quit()
|
|
106 {
|
28
|
107 SDL_Quit();
|
26
|
108 }
|
|
109
|
|
110
|
|
111 void Viewer::swap_buffers()
|
|
112 {
|
28
|
113 SDL_GL_SwapBuffers();
|
26
|
114 }
|
|
115
|
|
116
|
51
|
117 void
|
|
118 Viewer::write_pixel(int x, int y,float z, Uint32 rgb)
|
|
119 {
|
28
|
120 x += width/2;
|
|
121 y += height/2;
|
26
|
122
|
51
|
123 if (z < zRow[x][y]) {
|
109
|
124 if (x < width && x > 0 && y > 0 && y < height) {
|
|
125 zRow[x][y] = z;
|
|
126 y = height - y;
|
|
127 pixels[width*y + x] = rgb;
|
|
128 }
|
26
|
129 }
|
|
130 }
|
|
131
|
51
|
132 void
|
|
133 Viewer::write_line(float x1, float y1, float x2, float y2, Uint32 rgb)
|
26
|
134 {
|
51
|
135 if (x1 > x2) {
|
28
|
136 float x=0;
|
|
137 float y=0;
|
|
138 x=x1;
|
|
139 y=y1;
|
|
140 x1 = x2;
|
|
141 y1 = y2;
|
|
142 x2 = x;
|
|
143 y2 = y;
|
26
|
144 }
|
51
|
145
|
28
|
146 float s = y1;
|
26
|
147
|
51
|
148 if ((int)x1 == (int)x2) {
|
|
149 if (y1 > y2) {
|
28
|
150 float y=0;
|
|
151 y = y1;
|
|
152 y1 = y2;
|
|
153 y2 = y;
|
26
|
154 }
|
51
|
155
|
|
156 for (float i=y1; i<y2; i++) {
|
28
|
157 //write_pixel((int)x1,(int)i);
|
|
158 write_pixel((int)x1,(int)i,0,rgb);
|
26
|
159 }
|
51
|
160 } else {
|
28
|
161 float t = (y2 - y1)/(x2 - x1);
|
51
|
162 if (t < -1) {
|
28
|
163 float f = 0;
|
51
|
164 for (float i=x1; i<x2; i++) {
|
|
165 for (float a=(int)t; a<0; a++) {
|
28
|
166 write_pixel((int)i,(int)s,0,rgb);
|
|
167 s--;
|
26
|
168 }
|
51
|
169
|
28
|
170 f += t-(int)t;
|
51
|
171
|
|
172 if (f <= -1) {
|
28
|
173 write_pixel((int)i,(int)s,0,rgb);
|
|
174 f = 0;
|
|
175 s--;
|
26
|
176 }
|
|
177 }
|
51
|
178 } else if (t <= 1) {
|
|
179 for(float i=x1; i<x2; i++) {
|
28
|
180 //write_pixel((int)i,(int)s);
|
|
181 write_pixel((int)i,(int)s,0,rgb);
|
|
182 s += t;
|
26
|
183 }
|
51
|
184 } else {
|
28
|
185 float f = 0;
|
51
|
186 for (float i=x1; i<x2; i++) {
|
|
187 for (float a=0; a<(int)t; a++) {
|
28
|
188 write_pixel((int)i,(int)s,0,rgb);
|
|
189 s++;
|
26
|
190 }
|
51
|
191
|
28
|
192 f += t-(int)t;
|
51
|
193
|
|
194 if (f >= 1) {
|
28
|
195 write_pixel((int)i,(int)s,0,rgb);
|
|
196 f = 0;
|
|
197 s++;
|
26
|
198 }
|
|
199 }
|
|
200 }
|
|
201 }
|
|
202 }
|
|
203
|
|
204 void Viewer::write_triangle(float x1, float y1, float x2, float y2, float x3, float y3, Uint32 rgb)
|
|
205 {
|
28
|
206 write_line(x1,y1,x2,y2,rgb);
|
|
207 write_line(x2,y2,x3,y3,rgb);
|
|
208 write_line(x3,y3,x1,y1,rgb);
|
26
|
209 }
|
|
210
|
|
211 void Viewer::clean_pixels()
|
|
212 {
|
109
|
213 #if 0
|
28
|
214 for(int i=0; i<width*height; i++)
|
26
|
215 {
|
28
|
216 pixels[i] = 0x00;
|
26
|
217 }
|
109
|
218 #else
|
|
219 bzero(pixels, sizeof(int)*width*height);
|
|
220 #endif
|
26
|
221 }
|
|
222
|
|
223 void Viewer::graph_line()
|
|
224 {
|
28
|
225 int xl = width*height/2;
|
|
226 int yl = width/2;
|
|
227 for(int i=0; i<width; i++)
|
26
|
228 {
|
28
|
229 for(int t=0; t<height; t+=20)
|
26
|
230 {
|
28
|
231 pixels[width*t+i] = 0x5a;
|
26
|
232 }
|
28
|
233 pixels[xl +i] = 0xff;
|
26
|
234 }
|
28
|
235 for(int i=0; i<height; i++)
|
26
|
236 {
|
28
|
237 for(int t=0; t<width; t+=20)
|
26
|
238 {
|
28
|
239 pixels[i*width+t] = 0x5a;
|
26
|
240 }
|
28
|
241 pixels[i*width+yl] = 0xff;
|
26
|
242 }
|
|
243 }
|
|
244
|
54
|
245 int start_time;
|
|
246 int this_time;
|
|
247 int frames;
|
|
248 SDL_Surface *bitmap;
|
|
249 SDL_PixelFormat *pixelFormat;
|
|
250 Uint32 background;
|
|
251 Polygon *polygon;
|
88
|
252 SceneGraphPack *sgp;
|
|
253 PolygonPack *pp;
|
109
|
254 SpuSpan *ssl;
|
81
|
255
|
109
|
256 //SpanPack send_pack[6][10] __attribute__((aligned(16)));
|
|
257 SpanPack send_pack[SPE_NUM_MAX][MAX_SIZE_SPAN_PACK] __attribute__((aligned(16)));
|
94
|
258
|
99
|
259 void *__texture;
|
|
260
|
42
|
261 void
|
109
|
262 Viewer::run_init(char *xml)
|
42
|
263 {
|
|
264 HTaskPtr task;
|
54
|
265
|
|
266 start_time = get_ticks();
|
|
267 this_time = 0;
|
|
268 frames = 0;
|
|
269
|
|
270 pixelFormat = screen->format;
|
|
271 background = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
|
109
|
272 //polygon = new Polygon;
|
|
273 //polygon->set_data(xml);
|
|
274 polygon = Polygon::createFromXMLfile(xml);
|
54
|
275 polygon->viewer = this;
|
|
276
|
109
|
277 // TaskManager 側で
|
|
278 // allocate API を作っておいた方がいい。
|
|
279 // もしくは configure ?微妙か
|
|
280 //posix_memalign((void**)&sgp, 16, sizeof(SceneGraphPack));
|
|
281 //posix_memalign((void**)&pp, 16, sizeof(PolygonPack));
|
|
282 //posix_memalign((void**)&ssl, 16, sizeof(SpuSpan));
|
94
|
283 //sgp = new SceneGraphPack;
|
|
284 //pp = new PolygonPack;
|
109
|
285 //ssl = new SpuSpan;
|
|
286 MEMORY_ALLOCATION( &sgp, 16, sizeof(SceneGraphPack));
|
|
287 MEMORY_ALLOCATION( &pp, 16, sizeof(PolygonPack));
|
|
288 MEMORY_ALLOCATION( &ssl, 16, sizeof(SpuSpan));
|
88
|
289 create_sgp(polygon, sgp);
|
89
|
290 sgp->ssl = ssl;
|
42
|
291
|
109
|
292 //pixels = new Uint32[width*height];
|
|
293 pixels = (Uint32*)fbdev_addr;
|
|
294 //fbdev_addr = (Uint32)pixels;
|
99
|
295 //graph_line();
|
42
|
296
|
54
|
297 bitmap = SDL_CreateRGBSurfaceFrom((void *)pixels, width, height, 32,
|
42
|
298 width*4, redMask, greenMask,
|
|
299 blueMask, alphaMask);
|
|
300
|
105
|
301 task = manager->create_task(VIEWER_RUN_LOOP, 0, 0, 0, NULL);
|
63
|
302 task->spawn();
|
99
|
303
|
109
|
304 //posix_memalign((void**)&__texture, 16, 128*128*3);
|
|
305 //__texture = malloc(128*128*3);
|
|
306 MEMORY_ALLOCATION( &__texture, 16, 128*128*3);
|
102
|
307 memcpy(__texture, polygon->texture_image->pixels, 128*128*3);
|
109
|
308 HTaskPtr task_init_tex;
|
|
309
|
|
310 for (int i = 0; i < spe_num; i++) {
|
|
311 task_init_tex
|
|
312 = manager->create_task(TASK_INIT_TEXTURE, 0,
|
|
313 (uint32)__texture, 0, NULL);
|
|
314 //task_init_tex->set_cpu(CPU_SPE);
|
|
315 task_init_tex->set_cpu((CPU_TYPE)(i + SPE_0));
|
|
316 task_init_tex->spawn();
|
|
317 }
|
42
|
318 }
|
|
319
|
|
320 void
|
48
|
321 Viewer::run_loop(void)
|
42
|
322 {
|
|
323 HTaskPtr task_update_sgp = NULL;
|
81
|
324 HTaskPtr task_create_pp = NULL;
|
|
325 HTaskPtr task_create_sp = NULL;
|
|
326 HTaskPtr task_finish = NULL;
|
42
|
327
|
48
|
328 HTaskPtr task;
|
76
|
329 bool quit_flg;
|
|
330
|
|
331 quit_flg = quit_check();
|
|
332
|
109
|
333 SDL_BlitSurface(bitmap, NULL, screen, NULL);
|
|
334 SDL_UpdateRect(screen, 0, 0, 0, 0);
|
|
335
|
76
|
336 if (quit_flg == true) {
|
54
|
337 this_time = get_ticks();
|
105
|
338 task_finish = manager->create_task(VIEWER_RUN_FINISH, 0, 0, 0, NULL);
|
63
|
339 task_finish->spawn();
|
42
|
340 return;
|
|
341 }
|
|
342
|
109
|
343 // clean_pixels や zRow_init は、
|
|
344 // spe で fb に draw する時は必要ない。
|
|
345 // ppe 側で draw する時にだけ呼ぶべき。
|
102
|
346 //clean_pixels();
|
|
347 //zRow_init();
|
42
|
348
|
109
|
349 // これ自身、一つのタスクとして回す方がよいか
|
102
|
350 //graph_line();
|
106
|
351
|
81
|
352 task_update_sgp
|
109
|
353 = manager->create_task(TASK_UPDATE_SGP, sizeof(SceneGraphPack),
|
88
|
354 (uint32)sgp, (uint32)sgp, NULL);
|
|
355 task_create_pp
|
105
|
356 = manager->create_task(TASK_CREATE_PP, sizeof(SceneGraphPack),
|
88
|
357 (uint32)sgp, (uint32)pp, NULL);
|
89
|
358 task_create_sp
|
105
|
359 = manager->create_task(TASK_CREATE_SPAN, sizeof(PolygonPack),
|
92
|
360 (uint32)pp, 0, NULL);
|
88
|
361
|
105
|
362 task = manager->create_task(VIEWER_RUN_DRAW, 0, 0, 0, NULL);
|
48
|
363
|
109
|
364 task->wait_for(task_update_sgp);
|
|
365 task->wait_for(task_create_pp);
|
|
366 task->wait_for(task_create_sp);
|
|
367 task_create_sp->wait_for(task_create_pp);
|
85
|
368
|
74
|
369 //task_update_sgp->set_cpu(CPU_SPE);
|
89
|
370 //task_create_pp->set_cpu(CPU_SPE);
|
70
|
371
|
63
|
372 task_update_sgp->spawn();
|
|
373 task_create_pp->spawn();
|
89
|
374 task_create_sp->spawn();
|
63
|
375 task->spawn();
|
48
|
376 }
|
42
|
377
|
89
|
378 /**
|
109
|
379 * 本当はタスクとして TestDraw を選ぶ
|
89
|
380 */
|
101
|
381 //#define DRAW_POLYGON
|
|
382 #define DRAW_SPANPACK
|
94
|
383 //#define DRAW_SPUSPAN
|
48
|
384 void
|
|
385 Viewer::run_draw(void)
|
|
386 {
|
109
|
387 HTaskPtr task_loop;
|
|
388 HTaskPtr task_draw;
|
48
|
389
|
109
|
390 task_loop = manager->create_task(VIEWER_RUN_LOOP, 0, 0, 0, NULL);
|
94
|
391
|
102
|
392 #if 1
|
109
|
393 for (int j = 0; j < SPE_NUM_MAX; j++) {
|
|
394 for (int i = 0; i < MAX_SIZE_SPAN_PACK; i++) {
|
|
395 if (ssl->list[j].packs[i].info.size == 0) continue;
|
|
396 // memcpy はもちろんだめ。だけど。。。
|
|
397 // SPUSPAN->ss は配列で、各要素がアライメントとれてないと駄目。
|
|
398 #if 1
|
|
399 memcpy(&send_pack[j][i], &ssl->list[j].packs[i], sizeof(SpanPack));
|
|
400 task_draw
|
|
401 = manager->create_task(TASK_DRAW, sizeof(SpanPack),
|
|
402 (uint32)&send_pack[j][i], fbdev_addr, NULL);
|
|
403 #else
|
|
404 task_draw
|
|
405 = manager->create_task(TASK_DRAW, sizeof(SpanPack),
|
|
406 (uint32)&ssl->list[j].packs[i],
|
|
407 fbdev_addr, NULL);
|
|
408 #endif
|
|
409 //task_draw->set_cpu(CPU_SPE);
|
|
410 // もう少し良い選び方があってもいいはずだ
|
|
411 // てか ANY にすればいいんじゃね
|
|
412 task_draw->set_cpu((CPU_TYPE)(((i+j)%spe_num) + SPE_0));
|
|
413 //task_draw->set_cpu(CPU_PPE);
|
|
414 task_loop->wait_for(task_draw);
|
|
415 task_draw->spawn();
|
|
416 }
|
94
|
417 }
|
99
|
418 #endif
|
109
|
419 task_loop->spawn();
|
102
|
420 frames++;
|
109
|
421
|
102
|
422 return;
|
109
|
423
|
89
|
424 #ifdef DRAW_POLYGON
|
101
|
425 //polygon->draw(pp); // test draw of PolygonPack
|
|
426 polygon->draw(sgp); // test draw of PolygonPack
|
89
|
427 #else
|
|
428 # ifdef DRAW_SPANPACK // test draw of SpanPack
|
109
|
429 for (int j = 0; j < SPE_NUM_MAX; j++) {
|
|
430 for (int i = 0; i < MAX_SIZE_SPAN_PACK; i++) {
|
|
431 if (ssl->list[j].packs[i].info.size < 1) continue;
|
|
432 polygon->draw(&ssl->list[j].packs[i]);
|
|
433 }
|
89
|
434 }
|
|
435 # else
|
|
436 polygon->draw(&ssl->ss[0]);
|
|
437 polygon->draw(&ssl->ss[1]);
|
|
438 polygon->draw(&ssl->ss[2]);
|
|
439 polygon->draw(&ssl->ss[3]);
|
|
440 polygon->draw(&ssl->ss[4]);
|
|
441 polygon->draw(&ssl->ss[5]);
|
|
442 # endif
|
|
443 #endif
|
99
|
444
|
101
|
445 SDL_BlitSurface(bitmap, NULL, screen, NULL);
|
|
446 SDL_UpdateRect(screen, 0, 0, 0, 0);
|
42
|
447 }
|
|
448
|
|
449 void
|
48
|
450 Viewer::run_finish(void)
|
42
|
451 {
|
54
|
452 if (this_time != start_time) {
|
|
453 cout<< (((float)frames)/(this_time-start_time))*1000.0 << " FPS\n";
|
42
|
454 }
|
|
455
|
54
|
456 SDL_FreeSurface(bitmap);
|
106
|
457 //delete [] pixels;
|
54
|
458 polygon->delete_data();
|
|
459 delete polygon;
|
99
|
460
|
|
461 free(__texture);
|
42
|
462 quit();
|
|
463 }
|
|
464
|
28
|
465 void
|
|
466 Viewer::zRow_init()
|
|
467 {
|
|
468 for (int i = 0; i < width; i++) {
|
|
469 for (int j = 0; j < height; j++) {
|
|
470 zRow[i][j] = 65535;
|
26
|
471 }
|
28
|
472 }
|
26
|
473 }
|