109
|
1 #include "viewer.h"
|
|
2 #include "polygon.h"
|
|
3 #include "sys.h"
|
|
4 #include "Func.h"
|
|
5 #include "error.h"
|
|
6 #include "TaskManager.h"
|
|
7
|
|
8 extern void post2runLoop(void *);
|
|
9 extern void post2runDraw(void *);
|
|
10
|
|
11 /* measure for FPS (Frame Per Second) */
|
|
12 int start_time;
|
|
13 int this_time;
|
|
14 int frames;
|
|
15
|
|
16 Polygon *polygon;
|
|
17
|
|
18 /* Data Pack */
|
|
19 SceneGraphPack *sgpack;
|
|
20 PolygonPack *ppack;
|
|
21 SpanPackPtr spackList;
|
|
22 SpanPackPtr *spackList_ptr;
|
|
23 int spackList_length;
|
|
24 int spackList_length_align;
|
|
25
|
|
26 void *__texture;
|
|
27
|
|
28 Viewer::Viewer(int b, int w, int h, int _num)
|
|
29 {
|
|
30 bpp = b;
|
|
31 width = w;
|
|
32 height = h;
|
|
33 spe_num = _num;
|
|
34 }
|
|
35
|
|
36 int
|
|
37 Viewer::get_ticks()
|
|
38 {
|
|
39 int time;
|
|
40 time = SDL_GetTicks();
|
|
41 return time;
|
|
42 }
|
|
43
|
|
44 bool
|
|
45 Viewer::quit_check()
|
|
46 {
|
|
47 SDL_Event event;
|
|
48
|
|
49 while(SDL_PollEvent(&event)) {
|
|
50 if (event.type==SDL_QUIT) {
|
|
51 return true;
|
|
52 }
|
|
53 }
|
|
54
|
|
55 Uint8 *keys=SDL_GetKeyState(NULL);
|
|
56
|
|
57 if (keys[SDLK_q] == SDL_PRESSED) {
|
|
58 return true;
|
|
59 }
|
|
60
|
|
61 return false;
|
|
62 }
|
|
63
|
|
64 void
|
|
65 Viewer::quit()
|
|
66 {
|
|
67 SDL_Quit();
|
|
68 }
|
|
69
|
|
70 void
|
|
71 Viewer::swap_buffers()
|
|
72 {
|
|
73 SDL_GL_SwapBuffers();
|
|
74 }
|
|
75
|
|
76 void
|
|
77 Viewer::run_init(char *xml)
|
|
78 {
|
|
79 HTaskPtr task_next;
|
|
80 HTaskPtr task_sgp;
|
|
81 HTaskPtr task_init_tex;
|
|
82
|
|
83 start_time = get_ticks();
|
|
84 this_time = 0;
|
|
85 frames = 0;
|
|
86
|
|
87 polygon = Polygon::createFromXMLfile(xml);
|
|
88 polygon->viewer = this;
|
|
89
|
|
90 sgpack = (SceneGraphPack*)manager->malloc(sizeof(SceneGraphPack));
|
|
91 sgpack->init();
|
|
92 ppack = (PolygonPack*)manager->malloc(sizeof(PolygonPack));
|
|
93
|
|
94 spackList_length = (this->height + split_screen_h - 1) / split_screen_h;
|
|
95 spackList = (SpanPack*)manager->malloc(sizeof(SpanPack)*spackList_length);
|
|
96
|
|
97 // SPU に送る address list は 16 倍数でないといけない。
|
|
98 // spackList_length*sizeof(SpanPack*) が 16 倍数になるような
|
|
99 // length_align を求めている。
|
|
100 spackList_length_align = (spackList_length + 3)&(~3);
|
|
101
|
|
102 /* 各 SPU が持つ、SpanPack の address list */
|
|
103 spackList_ptr = (SpanPack**)manager->malloc(sizeof(SpanPack*)*spackList_length_align);
|
|
104
|
|
105 for (int i = 0; i < spackList_length; i++) {
|
|
106 spackList_ptr[i] = &spackList[i];
|
|
107 }
|
|
108
|
|
109 __texture = (void*)manager->malloc(128*128*3);
|
|
110 memcpy(__texture, polygon->texture_image->pixels, 128*128*3);
|
|
111
|
|
112 task_next = manager->create_task(TASK_DUMMY);
|
|
113 task_next->set_post(&post2runLoop, NULL);
|
|
114
|
|
115 task_sgp = manager->create_task(TASK_CREATE_SGP);
|
|
116 task_sgp->add_inData(polygon, sizeof(Polygon));
|
|
117 //task_sgp->add_outData(sgpack, sizeof(SceneGraphPack));
|
|
118 task_sgp->add_param((uint32)sgpack);
|
|
119 task_next->wait_for(task_sgp);
|
|
120 task_sgp->spawn();
|
|
121
|
|
122 for (int i = 0; i < spe_num; i++) {
|
|
123 //アドレスを送ってる、サイズが0なのは送った先で計算するので不要
|
|
124 task_init_tex = manager->create_task(TASK_INIT_TEXTURE);
|
|
125 task_init_tex->add_param((int)__texture);
|
|
126
|
|
127 task_init_tex->set_cpu(SPE_ANY);
|
|
128 task_next->wait_for(task_init_tex);
|
|
129 task_init_tex->spawn();
|
|
130 }
|
|
131
|
|
132 task_next->spawn();
|
|
133 }
|
|
134
|
|
135 void
|
|
136 Viewer::run_loop(void)
|
|
137 {
|
|
138 HTaskPtr task_update_sgp = NULL;
|
|
139 HTaskPtr task_create_pp = NULL;
|
|
140 HTaskPtr task_create_sp = NULL;
|
|
141 HTaskPtr task_next;
|
|
142 bool quit_flg;
|
|
143
|
|
144 quit_flg = quit_check();
|
|
145
|
|
146 if (quit_flg == true) {
|
|
147 this_time = get_ticks();
|
|
148 run_finish();
|
|
149 return;
|
|
150 }
|
|
151
|
|
152 clean_pixels();
|
|
153
|
|
154 for (int i = 1; i <= spackList_length; i++) {
|
|
155 spackList[i-1].init(i*split_screen_h);
|
|
156 }
|
|
157
|
|
158 task_next = manager->create_task(TASK_DUMMY);
|
|
159 task_next->set_post(post2runDraw, NULL);
|
|
160
|
|
161 task_update_sgp = manager->create_task(TASK_UPDATE_SGP);
|
|
162 task_update_sgp->add_inData(sgpack, sizeof(SceneGraphPack));
|
|
163 task_update_sgp->add_outData(sgpack, sizeof(SceneGraphPack));
|
|
164 task_update_sgp->add_param(width);
|
|
165 task_update_sgp->add_param(height);
|
|
166 task_next->wait_for(task_update_sgp);
|
|
167
|
|
168 task_create_pp = manager->create_task(TASK_CREATE_PP);
|
|
169 task_create_pp->add_inData(sgpack, sizeof(SceneGraphPack));
|
|
170 task_create_pp->add_param((uint32)ppack);
|
|
171 //task_create_pp->set_cpu(SPE_ANY);
|
|
172 task_next->wait_for(task_create_pp);
|
|
173
|
|
174 int range_base = spe_num;
|
|
175 // 切り上げのつもり
|
|
176 int range = (spackList_length + range_base - 1) / range_base;
|
|
177
|
|
178 for (int i = 0; i < range_base; i++) {
|
|
179 int index_start = range*i;
|
|
180 int index_end = (index_start + range >= spackList_length)
|
|
181 ? spackList_length : index_start + range;
|
|
182
|
|
183 task_create_sp = manager->create_task(TASK_CREATE_SPAN);
|
|
184 task_create_sp->add_inData(ppack, sizeof(PolygonPack));
|
|
185 task_create_sp->add_inData(spackList_ptr,
|
|
186 sizeof(SpanPack*)*spackList_length_align);
|
|
187 task_create_sp->add_inData(&spackList[index_start], sizeof(SpanPack));
|
|
188
|
|
189 task_create_sp->add_param(index_start);
|
|
190
|
|
191 /**
|
|
192 * ex. screen_height が 480, spenum が 6 の場合、
|
|
193 * [ 1.. 80] [ 81..160] [161..240]
|
|
194 * [241..320] [321..400] [401..480]
|
|
195 *
|
|
196 * ex. screen_height が 1080, spenum が 5 の場合、
|
|
197 * [ 1..216] [217..432] [433..648]
|
|
198 * [649..864] [865..1080]
|
|
199 */
|
|
200 task_create_sp->add_param(index_start*split_screen_h + 1);
|
|
201 task_create_sp->add_param(index_end*split_screen_h);
|
|
202
|
|
203 task_next->wait_for(task_create_sp);
|
|
204 task_create_sp->wait_for(task_create_pp);
|
|
205
|
|
206 task_create_sp->set_cpu(SPE_ANY);
|
|
207 task_create_sp->spawn();
|
|
208 }
|
|
209
|
|
210 task_update_sgp->spawn();
|
|
211 task_create_pp->spawn();
|
|
212 task_next->spawn();
|
|
213 }
|
|
214
|
|
215 static int st_rgb = 0xffffff;
|
|
216 static int st_diff = 0x111111;
|
|
217
|
|
218 void
|
|
219 Viewer::run_draw(void)
|
|
220 {
|
|
221 HTaskPtr task_next;
|
|
222 HTaskPtr task_draw;
|
|
223
|
|
224 task_next = manager->create_task(TASK_DUMMY);
|
|
225 task_next->set_post(post2runLoop, NULL);
|
|
226
|
|
227 ppack->clear();
|
|
228
|
|
229 if (frames % 20 == 0) {
|
|
230 st_rgb += st_diff;
|
|
231 }
|
|
232 if (st_rgb >= 0xeeeeee || st_rgb <= 0) {
|
|
233 st_diff = -st_diff;
|
|
234 }
|
|
235
|
|
236 unsigned int diff = 0;
|
|
237 for (int i = 0; i < spackList_length; i++) {
|
|
238 SpanPack *spack = &spackList[i];
|
|
239 int startx = 1;
|
|
240 int endx = split_screen_w;
|
|
241
|
|
242 int start_y = spack->info.y_top - split_screen_h + 1;
|
|
243 int end_y = spack->info.y_top;
|
|
244 int rangey = (start_y + split_screen_h - 1 > this->height)
|
|
245 ? this->height - start_y + 1 : split_screen_h;
|
|
246
|
|
247 while (startx < this->width) {
|
|
248 if (spack->info.size > 0) {
|
|
249 // Draw SpanPack
|
|
250 task_draw = manager->create_task(TASK_DRAW_SPAN);
|
|
251 task_draw->add_inData(spack, sizeof(SpanPack));
|
|
252 } else {
|
|
253 // Draw Background (現在は塗りつぶし)
|
|
254 //break;
|
|
255 task_draw = manager->create_task(TASK_DRAW_BACK);
|
|
256 task_draw->add_param(0x00ffcc55);
|
|
257 //task_draw->add_param(st_rgb);
|
|
258 }
|
|
259
|
|
260 for (int k = 0; k < rangey; k++) {
|
|
261 int hoge = (k > rangey-3) ? 0 : 0;
|
|
262 task_draw->add_outData(
|
|
263 &pixels[(startx-1)+this->width*(k+start_y-1)+hoge],
|
|
264 (endx - startx + 1)*sizeof(int));
|
|
265 }
|
|
266
|
|
267 task_draw->add_param(startx);
|
|
268 task_draw->add_param(endx);
|
|
269 task_draw->add_param(rangey);
|
|
270 task_draw->set_cpu(SPE_ANY);
|
|
271 task_next->wait_for(task_draw);
|
|
272 task_draw->spawn();
|
|
273
|
|
274 startx += split_screen_w;
|
|
275 endx += split_screen_w;
|
|
276
|
|
277 if (endx > this->width) {
|
|
278 endx = this->width;
|
|
279 }
|
|
280 }
|
|
281 }
|
|
282
|
|
283 task_next->spawn();
|
|
284
|
|
285 frames++;
|
|
286 }
|
|
287
|
|
288 void
|
|
289 Viewer::run_finish(void)
|
|
290 {
|
|
291 if (this_time != start_time) {
|
|
292 printf("%f FPS\n", (((float)frames)/(this_time-start_time))*1000.0);
|
|
293 }
|
|
294
|
|
295 polygon->delete_data();
|
|
296 delete polygon;
|
|
297
|
|
298 free(__texture);
|
|
299 quit();
|
|
300 }
|