539
|
1 #include <SDL.h>
|
|
2 #include "viewer.h"
|
|
3 #include "viewer_types.h"
|
|
4 #include "SceneGraph.h"
|
|
5 #include "SceneGraphRoot.h"
|
|
6 #include "scene_graph_pack.h"
|
|
7 #include "sys.h"
|
|
8 #include "Func.h"
|
|
9 #include "error.h"
|
|
10 #include "TaskManager.h"
|
|
11 #include <wchar.h>
|
|
12 #include "Pad.h"
|
|
13
|
|
14 static void post2runLoop(void *viewer);
|
|
15 static void post2runDraw(void *viewer);
|
|
16 static void post2speRendering(void *viewer);
|
|
17 static void post2speDraw(void *viewer);
|
|
18 // static void post2speRunLoop(void *viewer);
|
|
19 //static void post2runMove(void *viewer);
|
|
20 //static void post2exchange_sgroot(void *viewer);
|
|
21 //static void post2speRunLoop(void *viewer);
|
|
22 static void post2runMoveDrawLoop(void *viewer);
|
|
23
|
|
24 /* measure for FPS (Frame Per Second) */
|
|
25 int start_time;
|
|
26 int this_time;
|
|
27 int frames;
|
|
28
|
|
29 SceneGraphRootPtr sgroot;
|
|
30 //SceneGraphRootPtr sgroot_2;
|
|
31
|
|
32 /* Data Pack sent to Other CPUs (ex. SPE) */
|
|
33 SceneGraphPack *sgpack;
|
|
34 PolygonPack *ppack;
|
|
35 SpanPackPtr spackList;
|
|
36 SpanPackPtr *spackList_ptr;
|
|
37
|
|
38 int spackList_length;
|
|
39 int spackList_length_align;
|
|
40
|
|
41 /**
|
|
42 *
|
|
43 */
|
|
44
|
|
45 Viewer::Viewer(int b, int w, int h, int _num)
|
|
46 {
|
|
47 bpp = b;
|
|
48 width = w;
|
|
49 height = h;
|
|
50 spe_num = _num;
|
|
51 }
|
|
52
|
|
53 int
|
|
54 Viewer::get_ticks(void)
|
|
55 {
|
|
56 int time;
|
|
57 time = SDL_GetTicks();
|
|
58 return time;
|
|
59 }
|
|
60
|
|
61 bool
|
|
62 Viewer::quit_check(void)
|
|
63 {
|
|
64 SDL_Event event;
|
|
65
|
|
66 while(SDL_PollEvent(&event)) {
|
|
67 if (event.type==SDL_QUIT) {
|
|
68 return true;
|
|
69 }
|
|
70 }
|
|
71
|
|
72 Uint8 *keys=SDL_GetKeyState(NULL);
|
|
73
|
|
74 if (keys[SDLK_q] == SDL_PRESSED) {
|
|
75 return true;
|
|
76 }
|
|
77
|
|
78 return false;
|
|
79 }
|
|
80
|
|
81 void
|
|
82 Viewer::quit(void)
|
|
83 {
|
|
84 SDL_Quit();
|
|
85 }
|
|
86
|
|
87 void
|
|
88 Viewer::swap_buffers(void)
|
|
89 {
|
|
90 SDL_GL_SwapBuffers();
|
|
91 }
|
|
92
|
|
93 extern void node_init(TaskManager *manager);
|
|
94 extern void create_cube_split(TaskManager *manager, int);
|
|
95 extern void panel_init(TaskManager *manager, int bg);
|
|
96 extern void universe_init(TaskManager *manager);
|
|
97 extern void ieshoot_init(TaskManager *manager);
|
|
98 extern void ball_bound_init(TaskManager *manager, int, int);
|
|
99 extern void lcube_init(TaskManager *manager, int, int);
|
|
100 extern void direction_init(TaskManager *manager);
|
|
101 extern void init_position(TaskManager *manager, int, int);
|
|
102 extern void vacuum_init(TaskManager *manager, int w, int h);
|
|
103 extern void untitled_init(TaskManager *manager);
|
|
104 extern void chain_init(TaskManager *manager, int w, int h);
|
|
105 extern void chain_old_init(TaskManager *manager, int w, int h);
|
|
106 extern void boss1_init(TaskManager *manager, int w, int h);
|
|
107 extern void init_gaplant(TaskManager *manager, int w, int h);
|
|
108 extern void vacuum_init2(TaskManager *manager, int w, int h);
|
|
109
|
|
110 void
|
|
111 Viewer::run_init(TaskManager *manager, const char *xml, int sg_number)
|
|
112 {
|
|
113 this->manager = manager;
|
|
114
|
|
115 start_time = get_ticks();
|
|
116 this_time = 0;
|
|
117 frames = 0;
|
|
118
|
|
119 sgroot = new SceneGraphRoot(this->width, this->height);
|
|
120 // sgroot_2 = new SceneGraphRoot(this->width, this->height);
|
|
121 //sgroot->createFromXMLFile(xml);
|
|
122 // ここの switch は application->init(this, manager, sg_no); になるべき
|
|
123 switch (sg_number) {
|
|
124 case 0:
|
|
125 case 1:
|
|
126 create_cube_split(manager, sg_number);
|
|
127 break;
|
|
128 case 2:
|
|
129 case 3:
|
|
130 case 4:
|
|
131 panel_init(manager, sg_number);
|
|
132 break;
|
|
133 case 5:
|
|
134 universe_init(manager);
|
|
135 break;
|
|
136 case 6:
|
|
137 ieshoot_init(manager);
|
|
138 break;
|
|
139 case 7:
|
|
140 ball_bound_init(manager, this->width, this->height);
|
|
141 break;
|
|
142 case 8:
|
|
143 lcube_init(manager, this->width, this->height);
|
|
144 break;
|
|
145 case 9:
|
|
146 direction_init(manager);
|
|
147 break;
|
|
148 case 10:
|
|
149 init_position(manager, this->width, this->height);
|
|
150 break;
|
|
151 case 11:
|
|
152 // vacuum_init(manager, this->width, this->height);
|
|
153 break;
|
|
154 case 12:
|
|
155 untitled_init(manager);
|
|
156 break;
|
|
157 case 13:
|
|
158 boss1_init(manager, this->width, this->height);
|
|
159 break;
|
|
160 case 14:
|
|
161 init_gaplant(manager, this->width, this->height);
|
|
162 break;
|
|
163 case 15:
|
|
164 vacuum_init2(manager, this->width, this->height);
|
|
165 break;
|
|
166 case 16:
|
|
167 app = new Chain();
|
|
168 app->init(manager, this->width, this->height);
|
|
169 speLoop();
|
|
170 return;
|
|
171 break;
|
|
172 case 17:
|
|
173 chain_old_init(manager, this->width, this->height);
|
|
174 break;
|
|
175 default:
|
|
176 node_init(manager);
|
|
177 break;
|
|
178 }
|
|
179
|
|
180 mainLoop();
|
|
181 }
|
|
182
|
|
183
|
|
184 HTaskPtr
|
|
185 Viewer::initLoop()
|
|
186 {
|
|
187 HTaskPtr task_next;
|
|
188 HTaskPtr task_tex;
|
|
189
|
|
190 sgpack = (SceneGraphPack*)manager->allocate(sizeof(SceneGraphPack));
|
|
191 sgpack->init();
|
|
192 ppack = (PolygonPack*)manager->allocate(sizeof(PolygonPack));
|
|
193
|
|
194 spackList_length = (this->height + split_screen_h - 1) / split_screen_h;
|
|
195 spackList = (SpanPack*)manager->allocate(sizeof(SpanPack)*spackList_length);
|
|
196
|
|
197 /**
|
|
198 * SPU に送る address list は 16 バイト倍数でないといけない。
|
|
199 * spackList_length*sizeof(SpanPack*) が 16 バイト倍数になるような
|
|
200 * length_align を求めている。はみ出した部分は使われない
|
|
201 * (ex) spackList_length が 13 の場合
|
|
202 * spackList_length_align = 16;
|
|
203 * 実際に送るデータは64バイトになるのでOK
|
|
204 * 14,15,16 の部分は何も入らない。
|
|
205 */
|
|
206 spackList_length_align = (spackList_length + 3)&(~3);
|
|
207
|
|
208 /* 各 SPU が持つ、SpanPack の address list */
|
|
209 spackList_ptr =
|
|
210 (SpanPack**)manager->allocate(sizeof(SpanPack*)*spackList_length_align);
|
|
211
|
|
212 for (int i = 0; i < spackList_length; i++) {
|
|
213 spackList_ptr[i] = &spackList[i];
|
|
214 }
|
|
215
|
|
216 for (int i = 1; i <= spackList_length; i++) {
|
|
217 spackList[i-1].init(i*split_screen_h);
|
|
218 }
|
|
219
|
|
220 task_next = manager->create_task(TASK_DUMMY);
|
|
221
|
|
222 for (int i = 0; i < spe_num; i++) {
|
|
223 task_tex = manager->create_task(TASK_INIT_TEXTURE);
|
|
224 /*
|
|
225 * ここはもう少しわかりやすい使い方がいいかもしれぬ。こんなもん?
|
|
226 */
|
|
227 task_tex->set_cpu((CPU_TYPE)((int)SPE_0 + i));
|
|
228 task_next->wait_for(task_tex);
|
|
229 task_tex->spawn();
|
|
230 }
|
|
231
|
|
232 return task_next;
|
|
233 }
|
|
234
|
|
235 /* Loop って言っても1回しか実行されない */
|
|
236 void
|
|
237 Viewer::speLoop()
|
|
238 {
|
|
239 HTaskPtr task_next = initLoop();
|
|
240 // key の情報を格納する領域を確保する (global_alloc(KEY_STATUS))
|
|
241 HTaskPtr init_key_task = manager->create_task(INIT_KEY_TASK);
|
|
242 init_key_task->set_cpu(SPE_0);
|
|
243 init_key_task->spawn();
|
|
244
|
|
245 // SPE に送信する KEY_STATUS の領域確保
|
|
246 key_stat *key = (key_stat*)manager->allocate(sizeof(key_stat));
|
|
247 this->keyPtr = key;
|
|
248
|
|
249 // post2runLoop は旧バージョン用なので post2speRunLoop の様なものを別につくるべき
|
|
250 //task_next->set_post(post2speRunLoop, (void*)this); // set_post(function(this->run_loop()), NULL)
|
|
251 //task_next->spawn();
|
|
252 // TASK_INIT_TEXTURE が全て終わったら DUMMY_TASK が Viewer::run_loop() を呼ぶ
|
|
253
|
|
254 /* test */
|
|
255
|
|
256 HTaskPtr task_switch = manager->create_task(TASK_SWITCH);
|
|
257 task_switch->wait_for(task_next);
|
|
258 task_switch->set_post(post2runMoveDrawLoop, (void*)this);
|
|
259 task_switch->spawn();
|
|
260 }
|
|
261
|
|
262 void
|
|
263 Viewer::getKey()
|
|
264 {
|
|
265 Pad *pad = sgroot->getController();
|
|
266 if (pad->right.isHold()) {
|
|
267 keyPtr->right = HOLD;
|
|
268 } else if (pad->right.isPush()) {
|
|
269 keyPtr->right = PUSH;
|
|
270 } else {
|
|
271 keyPtr->right = NONE;
|
|
272 }
|
|
273
|
|
274 if (pad->left.isHold()) {
|
|
275 keyPtr->left = HOLD;
|
|
276 } else if (pad->left.isPush()) {
|
|
277 keyPtr->left = PUSH;
|
|
278 } else {
|
|
279 keyPtr->left = NONE;
|
|
280 }
|
|
281
|
|
282 if (pad->up.isHold()) {
|
|
283 keyPtr->up = HOLD;
|
|
284 } else if (pad->up.isPush()) {
|
|
285 keyPtr->up = PUSH;
|
|
286 } else {
|
|
287 keyPtr->up = NONE;
|
|
288 }
|
|
289
|
|
290 if (pad->down.isHold()) {
|
|
291 keyPtr->down = HOLD;
|
|
292 } else if (pad->down.isPush()) {
|
|
293 keyPtr->down = PUSH;
|
|
294 } else {
|
|
295 keyPtr->down = NONE;
|
|
296 }
|
|
297
|
|
298 if (pad->circle.isHold()) {
|
|
299 keyPtr->circle = HOLD;
|
|
300 } else if (pad->circle.isPush()) {
|
|
301 keyPtr->circle = PUSH;
|
|
302 } else {
|
|
303 keyPtr->circle = NONE;
|
|
304 }
|
|
305 }
|
|
306
|
|
307 static void
|
|
308 post2runMoveDrawLoop(void *viewer_)
|
|
309 {
|
|
310 Viewer *viewer = (Viewer*)viewer_;
|
|
311
|
|
312 // 同じ PPE 上なので sgroot(ポインタ) を add_param で送る。
|
|
313 //HTaskPtr send_key_task = viewer->manager->create_task(SEND_KEY);
|
|
314 //send_key_task->add_param((int)sgroot);
|
|
315 // set input data -> viewer keyPtr
|
|
316 viewer->getKey();
|
|
317 HTaskPtr update_key = viewer->manager->create_task(UPDATE_KEY);
|
|
318 update_key->add_inData(viewer->keyPtr, sizeof(key_stat));
|
|
319 update_key->set_cpu(SPE_0);
|
|
320 update_key->spawn();
|
|
321
|
|
322 /* TASK_MOVE は外から引数で取ってくるべき */
|
|
323 //HTaskPtr move_task = viewer->manager->create_task(viewer->app->move_taskid);
|
|
324 HTaskPtr move_task = viewer->manager->create_task(TASK_MOVE);
|
|
325 //move_task->add_param(sgroot);
|
|
326
|
|
327 //HTaskPtr draw_task = viewer->manager->create_task(TASK_DRAW);
|
|
328
|
|
329 /* rendering task test */
|
|
330 HTaskPtr draw_task = viewer->manager->create_task(TASK_DUMMY);
|
|
331 HTaskPtr draw_dummy = viewer->manager->create_task(TASK_DUMMY);
|
|
332
|
|
333 HTaskPtr switch_task = viewer->manager->create_task(TASK_SWITCH);
|
|
334 viewer->draw_dummy = draw_dummy;
|
|
335 switch_task->wait_for(draw_dummy);
|
|
336 draw_task->set_post(post2speRendering, (void*)viewer);
|
|
337
|
|
338 switch_task->wait_for(move_task);
|
|
339 switch_task->wait_for(draw_task);
|
|
340 move_task->spawn();
|
|
341 draw_task->spawn();
|
|
342
|
|
343 switch_task->set_post(post2runMoveDrawLoop, (void*)viewer);
|
|
344 switch_task->spawn();
|
|
345
|
|
346 }
|
|
347
|
|
348 #if 0
|
|
349 static void
|
|
350 post2speRunLoop(void *viewer_)
|
|
351 {
|
|
352 Viewer *viewer = (Viewer *)viewer_;
|
|
353 HTaskPtr task_next = viewer->manager->create_task(TASK_DUMMY);
|
|
354 viewer->run_move(task_next);
|
|
355 }
|
|
356 #endif
|
|
357
|
|
358 void
|
|
359 Viewer::mainLoop()
|
|
360 {
|
|
361 HTaskPtr task_next = initLoop();
|
|
362
|
|
363 task_next->set_post(&post2runLoop, (void *)this); // set_post(function(this->run_loop()), NULL)
|
|
364 task_next->spawn();
|
|
365 }
|
|
366
|
|
367 #if 0
|
|
368 void
|
|
369 post2runMove(void *viewer_)
|
|
370 {
|
|
371 Viewer *viewer = (Viewer*)viewer_;
|
|
372 HTaskPtr task_next = viewer->manager->create_task(TASK_DUMMY);
|
|
373 viewer->run_move(task_next);
|
|
374 }
|
|
375 #endif
|
|
376
|
|
377
|
|
378 void
|
|
379 Viewer::run_move(HTaskPtr task_next)
|
|
380 {
|
|
381 sgroot->updateControllerState();
|
|
382 sgroot->allExecute(width, height);
|
|
383 }
|
|
384
|
|
385 void
|
|
386 Viewer::run_collision()
|
|
387 {
|
|
388 }
|
|
389
|
|
390 void
|
|
391 post2rendering(void *viewer_)
|
|
392 {
|
|
393 Viewer *viewer = (Viewer *)viewer_;
|
|
394 HTaskPtr task_next = viewer->manager->create_task(TASK_DUMMY);
|
|
395 viewer->rendering(task_next);
|
|
396 }
|
|
397
|
|
398 void
|
|
399 Viewer::rendering(HTaskPtr task_next)
|
|
400 {
|
|
401 #if 0
|
|
402 HTaskPtr task_create_pp = manager->create_task(TASK_CREATE_PP2);
|
|
403
|
|
404 // SceneGraph(木構造) -> PolygonPack
|
|
405
|
|
406 task_create_pp->add_param((uint32)sgroot->getDrawSceneGraph());
|
|
407 task_create_pp->add_param((uint32)ppack);
|
|
408
|
|
409 task_next->wait_for(task_create_pp);
|
|
410
|
|
411 int range_base = spe_num;
|
|
412 // 切り上げのつもり
|
|
413 int range = (spackList_length + range_base - 1) / range_base;
|
|
414
|
|
415 for (int i = 0; i < range_base; i++) {
|
|
416 int index_start = range*i;
|
|
417 int index_end = (index_start + range >= spackList_length)
|
|
418 ? spackList_length : index_start + range;
|
|
419
|
|
420 HTaskPtr task_create_sp = manager->create_task(TASK_CREATE_SPAN);
|
|
421 task_create_sp->add_inData(ppack, sizeof(PolygonPack));
|
|
422 task_create_sp->add_inData(spackList_ptr,
|
|
423 sizeof(SpanPack*)*spackList_length_align);
|
|
424 task_create_sp->add_inData(&spackList[index_start], sizeof(SpanPack));
|
|
425
|
|
426 task_create_sp->add_param(index_start);
|
|
427
|
|
428 /**
|
|
429 * ex. screen_height が 480, spenum が 6 の場合、各SPEのy担当範囲
|
|
430 * [ 1.. 80] [ 81..160] [161..240]
|
|
431 * [241..320] [321..400] [401..480]
|
|
432 *
|
|
433 * ex. screen_height が 1080, spenum が 5 の場合、
|
|
434 * [ 1..216] [217..432] [433..648]
|
|
435 * [649..864] [865..1080]
|
|
436 */
|
|
437 task_create_sp->add_param(index_start*split_screen_h + 1);
|
|
438 task_create_sp->add_param(index_end*split_screen_h);
|
|
439
|
|
440 task_next->wait_for(task_create_sp);
|
|
441 task_create_sp->wait_for(task_create_pp);
|
|
442
|
|
443 task_create_sp->set_cpu(SPE_ANY);
|
|
444 task_create_sp->spawn();
|
|
445 }
|
|
446
|
|
447 task_create_pp->spawn();
|
|
448 #else
|
|
449 common_rendering(task_next);
|
|
450 #endif
|
|
451
|
|
452 // Barrier 同期
|
|
453 // run_draw() を呼ぶ post2runDraw
|
|
454 task_next->set_post(post2runDraw, (void*)this); // set_post(function(this->run_draw()), NULL)
|
|
455 task_next->spawn();
|
|
456
|
|
457 // TASK_CREATE_SPAN が全て終わったら DUMMY_TASK が Viewer::run_draw() を呼ぶ
|
|
458 }
|
|
459
|
|
460 static void
|
|
461 post2runLoop(void *viewer_)
|
|
462 {
|
|
463 Viewer *viewer = (Viewer*)viewer_;
|
|
464 HTaskPtr task_next = viewer->manager->create_task(TASK_DUMMY);
|
|
465 viewer->run_loop(task_next);
|
|
466
|
|
467 }
|
|
468
|
|
469 void
|
|
470 Viewer::run_loop(HTaskPtr task_next)
|
|
471 {
|
|
472 bool quit_flg;
|
|
473 quit_flg = quit_check();
|
|
474 if (quit_flg == true) {
|
|
475 this_time = get_ticks();
|
|
476 run_finish();
|
|
477 return;
|
|
478 }
|
|
479
|
|
480 clean_pixels();
|
|
481
|
|
482 for (int i = 1; i <= spackList_length; i++) {
|
|
483 spackList[i-1].reinit(i*split_screen_h);
|
|
484 }
|
|
485
|
|
486 //run_move(task_next);
|
|
487 sgroot->updateControllerState();
|
|
488 sgroot->allExecute(width, height);
|
|
489 //sgroot->checkRemove();
|
|
490
|
|
491 // ここから下は Rendering という関数にする
|
|
492 rendering(task_next);
|
|
493 }
|
|
494
|
|
495 static void
|
|
496 post2runDraw(void *viewer_)
|
|
497 {
|
|
498 Viewer *viewer = (Viewer*)viewer_;
|
|
499 HTaskPtr task_next = viewer->manager->create_task(TASK_DUMMY);
|
|
500 viewer->run_draw(task_next);
|
|
501
|
|
502 }
|
|
503
|
|
504 void
|
|
505 Viewer::run_draw(HTaskPtr task_next) // 引数に post2runLoop を入れるようにする
|
|
506 {
|
|
507 #if 0
|
|
508 HTaskPtr task_draw;
|
|
509
|
|
510 //task_next = manager->create_task(TASK_DUMMY);
|
|
511 //task_next->set_post(post2runLoop, (void*)this);
|
|
512
|
|
513 ppack->clear();
|
|
514 for (int i = 0; i < spackList_length; i++) {
|
|
515 SpanPack *spack = &spackList[i];
|
|
516 int startx = 1;
|
|
517 int endx = split_screen_w;
|
|
518
|
|
519 int starty = spack->info.y_top - split_screen_h + 1;
|
|
520 //int endy = spack->info.y_top;
|
|
521 int rangey = (starty + split_screen_h - 1 > this->height)
|
|
522 ? this->height - starty + 1 : split_screen_h;
|
|
523
|
|
524 while (startx < this->width) {
|
|
525 if (spack->info.size > 0) {
|
|
526 // Draw SpanPack
|
|
527 task_draw = manager->create_task(TASK_DRAW_SPAN);
|
|
528 task_draw->add_inData(spack, sizeof(SpanPack));
|
|
529
|
|
530 task_draw->add_param(
|
|
531 (uint32)&pixels[(startx-1) + this->width*(starty-1)]);
|
|
532 task_draw->add_param(this->width);
|
|
533 } else {
|
|
534 // 7.7.3 SL1 Data Cache Range Set to Zero コマンド
|
|
535 // を使って、DMAでclearするべき... ということは、
|
|
536 // それもSPEでやる方が良い?
|
|
537 memset(&pixels[(startx-1)+this->width*(starty-1)],
|
|
538 0, (this->width)*sizeof(int)*rangey);
|
|
539 break;
|
|
540 }
|
|
541
|
|
542 task_draw->add_param(startx);
|
|
543 task_draw->add_param(endx);
|
|
544 task_draw->add_param(rangey);
|
|
545 task_draw->set_cpu(SPE_ANY);
|
|
546 task_next->wait_for(task_draw);
|
|
547 task_draw->spawn();
|
|
548
|
|
549 startx += split_screen_w;
|
|
550 endx += split_screen_w;
|
|
551
|
|
552 if (endx > this->width) {
|
|
553 endx = this->width;
|
|
554 }
|
|
555 }
|
|
556 }
|
|
557 #else
|
|
558 common_draw(task_next);
|
|
559 #endif
|
|
560
|
|
561 task_next->set_post(post2runLoop, (void*)this); // set_post(function(this->run_loop()), NULL)
|
|
562 task_next->spawn();
|
|
563 // TASK_DRAW_SPAN が全て終わったら DUMMY_TASK が Viewer::run_loop() を呼ぶ
|
|
564
|
|
565 frames++;
|
|
566 }
|
|
567
|
|
568 void
|
|
569 Viewer::run_finish(void)
|
|
570 {
|
|
571 if (this_time != start_time) {
|
|
572 printf("%f FPS\n", (((float)frames)/(this_time-start_time))*1000.0);
|
|
573 }
|
|
574
|
|
575 delete sgroot;
|
|
576 // delete sgroot_2;
|
|
577 quit();
|
|
578 }
|
|
579
|
|
580 static void
|
|
581 post2speRendering(void *viewer_)
|
|
582 {
|
|
583 Viewer *viewer = (Viewer*)viewer_;
|
|
584 HTaskPtr task_next = viewer->manager->create_task(TASK_DUMMY);
|
|
585 viewer->spe_rendering(task_next);
|
|
586 }
|
|
587
|
|
588 void
|
|
589 Viewer::spe_rendering(HTaskPtr task_next)
|
|
590 {
|
|
591 common_rendering(task_next);
|
|
592
|
|
593 this->draw_dummy->wait_for(task_next);
|
|
594 task_next->set_post(post2speDraw, (void*)this);
|
|
595 task_next->spawn();
|
|
596
|
|
597 }
|
|
598
|
|
599 static void
|
|
600 post2speDraw(void *viewer_)
|
|
601 {
|
|
602 Viewer *viewer = (Viewer*)viewer_;
|
|
603 HTaskPtr task_next = viewer->manager->create_task(TASK_DUMMY);
|
|
604 viewer->spe_draw(task_next);
|
|
605 }
|
|
606
|
|
607 void
|
|
608 Viewer::spe_draw(HTaskPtr task_next)
|
|
609 {
|
|
610 common_draw(task_next);
|
|
611
|
|
612 this->draw_dummy->wait_for(task_next);
|
|
613 task_next->spawn();
|
|
614 this->draw_dummy->spawn();
|
|
615
|
|
616 frames++;
|
|
617 }
|
|
618
|
|
619 void
|
|
620 Viewer::common_rendering(HTaskPtr task_next)
|
|
621 {
|
|
622 HTaskPtr task_create_pp = manager->create_task(TASK_CREATE_PP2);
|
|
623
|
|
624 // SceneGraph(木構造) -> PolygonPack
|
|
625
|
|
626 task_create_pp->add_param((uint32)sgroot->getDrawSceneGraph());
|
|
627 task_create_pp->add_param((uint32)ppack);
|
|
628
|
|
629 task_next->wait_for(task_create_pp);
|
|
630
|
|
631 int range_base = spe_num;
|
|
632 // 切り上げのつもり
|
|
633 int range = (spackList_length + range_base - 1) / range_base;
|
|
634
|
|
635 for (int i = 0; i < range_base; i++) {
|
|
636 int index_start = range*i;
|
|
637 int index_end = (index_start + range >= spackList_length)
|
|
638 ? spackList_length : index_start + range;
|
|
639
|
|
640 HTaskPtr task_create_sp = manager->create_task(TASK_CREATE_SPAN);
|
|
641 task_create_sp->add_inData(ppack, sizeof(PolygonPack));
|
|
642 task_create_sp->add_inData(spackList_ptr,
|
|
643 sizeof(SpanPack*)*spackList_length_align);
|
|
644 task_create_sp->add_inData(&spackList[index_start], sizeof(SpanPack));
|
|
645
|
|
646 task_create_sp->add_param(index_start);
|
|
647
|
|
648 /**
|
|
649 * ex. screen_height が 480, spenum が 6 の場合、各SPEのy担当範囲
|
|
650 * [ 1.. 80] [ 81..160] [161..240]
|
|
651 * [241..320] [321..400] [401..480]
|
|
652 *
|
|
653 * ex. screen_height が 1080, spenum が 5 の場合、
|
|
654 * [ 1..216] [217..432] [433..648]
|
|
655 * [649..864] [865..1080]
|
|
656 */
|
|
657 task_create_sp->add_param(index_start*split_screen_h + 1);
|
|
658 task_create_sp->add_param(index_end*split_screen_h);
|
|
659
|
|
660 task_next->wait_for(task_create_sp);
|
|
661 task_create_sp->wait_for(task_create_pp);
|
|
662
|
|
663 task_create_sp->set_cpu(SPE_ANY);
|
|
664 task_create_sp->spawn();
|
|
665 }
|
|
666
|
|
667 task_create_pp->spawn();
|
|
668 }
|
|
669
|
|
670 void
|
|
671 Viewer::common_draw(HTaskPtr task_next)
|
|
672 {
|
|
673 HTaskPtr task_draw;
|
|
674
|
|
675 //task_next = manager->create_task(TASK_DUMMY);
|
|
676 //task_next->set_post(post2runLoop, (void*)this);
|
|
677
|
|
678 ppack->clear();
|
|
679 for (int i = 0; i < spackList_length; i++) {
|
|
680 SpanPack *spack = &spackList[i];
|
|
681 int startx = 1;
|
|
682 int endx = split_screen_w;
|
|
683
|
|
684 int starty = spack->info.y_top - split_screen_h + 1;
|
|
685 //int endy = spack->info.y_top;
|
|
686 int rangey = (starty + split_screen_h - 1 > this->height)
|
|
687 ? this->height - starty + 1 : split_screen_h;
|
|
688
|
|
689 while (startx < this->width) {
|
|
690 if (spack->info.size > 0) {
|
|
691 // Draw SpanPack
|
|
692 task_draw = manager->create_task(TASK_DRAW_SPAN);
|
|
693 task_draw->add_inData(spack, sizeof(SpanPack));
|
|
694
|
|
695 task_draw->add_param(
|
|
696 (uint32)&pixels[(startx-1) + this->width*(starty-1)]);
|
|
697 task_draw->add_param(this->width);
|
|
698 } else {
|
|
699 // 7.7.3 SL1 Data Cache Range Set to Zero コマンド
|
|
700 // を使って、DMAでclearするべき... ということは、
|
|
701 // それもSPEでやる方が良い?
|
|
702 memset(&pixels[(startx-1)+this->width*(starty-1)],
|
|
703 0, (this->width)*sizeof(int)*rangey);
|
|
704 break;
|
|
705 }
|
|
706
|
|
707 task_draw->add_param(startx);
|
|
708 task_draw->add_param(endx);
|
|
709 task_draw->add_param(rangey);
|
|
710 task_draw->set_cpu(SPE_ANY);
|
|
711 task_next->wait_for(task_draw);
|
|
712 task_draw->spawn();
|
|
713
|
|
714 startx += split_screen_w;
|
|
715 endx += split_screen_w;
|
|
716
|
|
717 if (endx > this->width) {
|
|
718 endx = this->width;
|
|
719 }
|
|
720 }
|
|
721 }
|
|
722 }
|
|
723
|
|
724 /* end */
|