diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/evas/src/modules/engines/psl1ght/evas_engine.c | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2 SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz |
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/evas/src/modules/engines/psl1ght/evas_engine.c')
-rw-r--r-- | libraries/evas/src/modules/engines/psl1ght/evas_engine.c | 511 |
1 files changed, 511 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/psl1ght/evas_engine.c b/libraries/evas/src/modules/engines/psl1ght/evas_engine.c new file mode 100644 index 0000000..750c098 --- /dev/null +++ b/libraries/evas/src/modules/engines/psl1ght/evas_engine.c | |||
@@ -0,0 +1,511 @@ | |||
1 | #include "evas_common.h" | ||
2 | #include "evas_private.h" | ||
3 | #include "evas_engine.h" | ||
4 | #include "rsxutil.h" | ||
5 | #include "Evas_Engine_PSL1GHT.h" | ||
6 | |||
7 | #include <malloc.h> | ||
8 | |||
9 | int _evas_engine_psl1ght_log_dom = -1; | ||
10 | |||
11 | /* function tables - filled in later (func and parent func) */ | ||
12 | static Evas_Func func, pfunc; | ||
13 | |||
14 | /* engine struct data */ | ||
15 | typedef struct _Render_Engine Render_Engine; | ||
16 | |||
17 | #define MAX_BUFFERS 2 | ||
18 | |||
19 | struct _Render_Engine | ||
20 | { | ||
21 | Tilebuf *tb; | ||
22 | Tilebuf_Rect *rects; | ||
23 | Eina_Inlist *cur_rect; | ||
24 | |||
25 | /* RSX device context */ | ||
26 | gcmContextData *context; | ||
27 | void *host_addr; | ||
28 | |||
29 | /* The buffers we will be drawing into. */ | ||
30 | rsxBuffer buffers[MAX_BUFFERS]; | ||
31 | int currentBuffer; | ||
32 | int width; | ||
33 | int height; | ||
34 | RGBA_Image *rgba_image; | ||
35 | uint32_t rgba_image_offset; | ||
36 | |||
37 | int end : 1; | ||
38 | }; | ||
39 | |||
40 | /* prototypes we will use here */ | ||
41 | static void *_output_setup(int w, int h); | ||
42 | |||
43 | static void *eng_info(Evas *e); | ||
44 | static void | ||
45 | eng_info_free(Evas *e, void *info); | ||
46 | static int | ||
47 | eng_setup(Evas *e, void *info); | ||
48 | static void | ||
49 | eng_output_free(void *data); | ||
50 | static void | ||
51 | eng_output_resize(void *data, int w, int h); | ||
52 | static void | ||
53 | eng_output_tile_size_set(void *data, int w, int h); | ||
54 | static void | ||
55 | eng_output_redraws_rect_add(void *data, int x, int y, int w, int h); | ||
56 | static void | ||
57 | eng_output_redraws_rect_del(void *data, int x, int y, int w, int h); | ||
58 | static void | ||
59 | eng_output_redraws_clear(void *data); | ||
60 | static void *eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch); | ||
61 | static void | ||
62 | eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h); | ||
63 | static void | ||
64 | eng_output_flush(void *data); | ||
65 | static void | ||
66 | eng_output_idle_flush(void *data); | ||
67 | |||
68 | /* internal engine routines */ | ||
69 | static void * | ||
70 | _output_setup(int w, int h) | ||
71 | { | ||
72 | Render_Engine *re; | ||
73 | int i; | ||
74 | u16 width, height; | ||
75 | DATA32 *image_data = NULL; | ||
76 | int image_size; | ||
77 | |||
78 | printf ("_output_setup called : %dx%d\n", w, h); | ||
79 | re = calloc(1, sizeof(Render_Engine)); | ||
80 | if (!re) | ||
81 | return NULL; | ||
82 | |||
83 | /* Allocate a 1Mb buffer, alligned to a 1Mb boundary | ||
84 | * to be our shared IO memory with the RSX. */ | ||
85 | re->host_addr = memalign (1024 * 1024, HOST_SIZE); | ||
86 | if (re->host_addr == NULL) | ||
87 | { | ||
88 | free (re); | ||
89 | return NULL; | ||
90 | } | ||
91 | re->context = initScreen (re->host_addr, HOST_SIZE); | ||
92 | if (re->context == NULL) | ||
93 | { | ||
94 | free (re->host_addr); | ||
95 | free (re); | ||
96 | return NULL; | ||
97 | } | ||
98 | width = w; | ||
99 | height = h; | ||
100 | setResolution (re->context, &width, &height); | ||
101 | re->currentBuffer = 0; | ||
102 | re->width = width; | ||
103 | re->height = height; | ||
104 | |||
105 | for (i = 0; i < MAX_BUFFERS; i++) | ||
106 | makeBuffer (&re->buffers[i], width, height, i); | ||
107 | |||
108 | flipBuffer(re->context, MAX_BUFFERS - 1); | ||
109 | |||
110 | /* if we haven't initialized - init (automatic abort if already done) */ | ||
111 | evas_common_cpu_init(); | ||
112 | evas_common_blend_init(); | ||
113 | evas_common_image_init(); | ||
114 | evas_common_convert_init(); | ||
115 | evas_common_scale_init(); | ||
116 | evas_common_rectangle_init(); | ||
117 | evas_common_polygon_init(); | ||
118 | evas_common_line_init(); | ||
119 | evas_common_font_init(); | ||
120 | evas_common_draw_init(); | ||
121 | evas_common_tilebuf_init(); | ||
122 | |||
123 | re->tb = evas_common_tilebuf_new(w, h); | ||
124 | |||
125 | /* in preliminary tests 16x16 gave highest framerates */ | ||
126 | evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); | ||
127 | |||
128 | /* Allocate our memaligned backbuffer */ | ||
129 | image_size = ((w * h * sizeof(u32)) + 0xfffff) & - 0x100000; | ||
130 | image_data = memalign (1024 * 1024, image_size); | ||
131 | re->rgba_image = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), | ||
132 | w, h, image_data, 1, EVAS_COLORSPACE_ARGB8888); | ||
133 | gcmMapMainMemory(image_data, image_size, &re->rgba_image_offset); | ||
134 | |||
135 | return re; | ||
136 | } | ||
137 | |||
138 | /* engine api this module provides */ | ||
139 | static void * | ||
140 | eng_info(Evas *e) | ||
141 | { | ||
142 | Evas_Engine_Info_PSL1GHT *info; | ||
143 | |||
144 | printf ("eng_info called\n"); | ||
145 | info = calloc(1, sizeof(Evas_Engine_Info_PSL1GHT)); | ||
146 | if (!info) | ||
147 | return NULL; | ||
148 | |||
149 | info->magic.magic = rand(); | ||
150 | info->render_mode = EVAS_RENDER_MODE_BLOCKING; | ||
151 | |||
152 | return info; | ||
153 | } | ||
154 | |||
155 | static void | ||
156 | eng_info_free(Evas *e __UNUSED__, void *info) | ||
157 | { | ||
158 | Evas_Engine_Info_PSL1GHT *in; | ||
159 | |||
160 | printf ("eng_info_free called\n"); | ||
161 | in = (Evas_Engine_Info_PSL1GHT *)info; | ||
162 | free(in); | ||
163 | } | ||
164 | |||
165 | static int | ||
166 | eng_setup(Evas *e, void *in) | ||
167 | { | ||
168 | Evas_Engine_Info_PSL1GHT *info; | ||
169 | |||
170 | printf ("eng_setup called\n"); | ||
171 | info = (Evas_Engine_Info_PSL1GHT *)in; | ||
172 | |||
173 | e->engine.data.output = _output_setup(e->output.w, e->output.h); | ||
174 | if (!e->engine.data.output) | ||
175 | return 0; | ||
176 | |||
177 | e->engine.func = &func; | ||
178 | e->engine.data.context = e->engine.func->context_new(e->engine.data.output); | ||
179 | |||
180 | return 1; | ||
181 | } | ||
182 | |||
183 | static void | ||
184 | eng_output_free(void *data) | ||
185 | { | ||
186 | Render_Engine *re; | ||
187 | int i; | ||
188 | |||
189 | printf ("eng_output_free called\n"); | ||
190 | re = (Render_Engine *)data; | ||
191 | |||
192 | gcmSetWaitFlip(re->context); | ||
193 | for (i = 0; i < MAX_BUFFERS; i++) | ||
194 | rsxFree (re->buffers[i].ptr); | ||
195 | |||
196 | if (re->rgba_image) | ||
197 | { | ||
198 | DATA32 *image_data; | ||
199 | |||
200 | image_data = re->rgba_image->image.data; | ||
201 | evas_cache_image_drop(&re->rgba_image->cache_entry); | ||
202 | free (image_data); | ||
203 | } | ||
204 | |||
205 | freeScreen (re->context); | ||
206 | free (re->host_addr); | ||
207 | |||
208 | evas_common_tilebuf_free(re->tb); | ||
209 | if (re->rects) | ||
210 | evas_common_tilebuf_free_render_rects(re->rects); | ||
211 | |||
212 | free(re); | ||
213 | |||
214 | evas_common_font_shutdown(); | ||
215 | evas_common_image_shutdown(); | ||
216 | } | ||
217 | |||
218 | static void | ||
219 | eng_output_resize(void *data, int w, int h) | ||
220 | { | ||
221 | Render_Engine *re; | ||
222 | int i; | ||
223 | u16 width, height; | ||
224 | DATA32 *image_data; | ||
225 | int image_size; | ||
226 | |||
227 | printf ("eng_output_resize called : %dx%d\n", w, h); | ||
228 | re = (Render_Engine *)data; | ||
229 | |||
230 | width = w; | ||
231 | height = h; | ||
232 | if (setResolution (re->context, &width, &height)) | ||
233 | { | ||
234 | re->width = width; | ||
235 | re->height = height; | ||
236 | |||
237 | gcmSetWaitFlip(re->context); | ||
238 | for (i = 0; i < MAX_BUFFERS; i++) { | ||
239 | rsxFree (re->buffers[i].ptr); | ||
240 | makeBuffer (&re->buffers[i], width, height, i); | ||
241 | } | ||
242 | |||
243 | flipBuffer(re->context, MAX_BUFFERS - 1); | ||
244 | |||
245 | evas_common_tilebuf_free(re->tb); | ||
246 | re->tb = evas_common_tilebuf_new(w, h); | ||
247 | evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); | ||
248 | |||
249 | /* Realloc our backbuf image */ | ||
250 | if (re->rgba_image) | ||
251 | { | ||
252 | image_data = re->rgba_image->image.data; | ||
253 | evas_cache_image_drop(&re->rgba_image->cache_entry); | ||
254 | free (image_data); | ||
255 | } | ||
256 | image_size = ((w * h * sizeof(u32)) + 0xfffff) & - 0x100000; | ||
257 | image_data = memalign (1024 * 1024, image_size); | ||
258 | re->rgba_image = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), | ||
259 | w, h, image_data, 1, EVAS_COLORSPACE_ARGB8888); | ||
260 | gcmMapMainMemory(image_data, image_size, &re->rgba_image_offset); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | static void | ||
265 | eng_output_tile_size_set(void *data, int w, int h) | ||
266 | { | ||
267 | Render_Engine *re; | ||
268 | |||
269 | printf ("eng_output_tile_size_set called : %dx%d\n", w, h); | ||
270 | re = (Render_Engine *)data; | ||
271 | evas_common_tilebuf_set_tile_size(re->tb, w, h); | ||
272 | } | ||
273 | |||
274 | static void | ||
275 | eng_output_redraws_rect_add(void *data, int x, int y, int w, int h) | ||
276 | { | ||
277 | Render_Engine *re; | ||
278 | |||
279 | //printf ("eng_output_redraws_rect_add called : %d,%d %dx%d\n", x, y, w, h); | ||
280 | re = (Render_Engine *)data; | ||
281 | evas_common_tilebuf_add_redraw(re->tb, x, y, w, h); | ||
282 | } | ||
283 | |||
284 | static void | ||
285 | eng_output_redraws_rect_del(void *data, int x, int y, int w, int h) | ||
286 | { | ||
287 | Render_Engine *re; | ||
288 | |||
289 | //printf ("eng_output_redraws_rect_del called : %d,%d %dx%d\n", x, y, w, h); | ||
290 | re = (Render_Engine *)data; | ||
291 | evas_common_tilebuf_del_redraw(re->tb, x, y, w, h); | ||
292 | } | ||
293 | |||
294 | static void | ||
295 | eng_output_redraws_clear(void *data) | ||
296 | { | ||
297 | Render_Engine *re; | ||
298 | |||
299 | //printf ("eng_output_redraws_clear called\n"); | ||
300 | re = (Render_Engine *)data; | ||
301 | evas_common_tilebuf_clear(re->tb); | ||
302 | } | ||
303 | |||
304 | static void * | ||
305 | eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch) | ||
306 | { | ||
307 | Render_Engine *re; | ||
308 | Tilebuf_Rect *rect; | ||
309 | int ux, uy, uw, uh; | ||
310 | |||
311 | re = (Render_Engine *)data; | ||
312 | /*printf ("eng_output_redraws_next_update_get called : %d,%d %dx%d -- %d,%d %dx%d\n", | ||
313 | *x, *y, *w, *h, *cx, *cy, *cw, *ch);*/ | ||
314 | if (re->end) | ||
315 | { | ||
316 | re->end = 0; | ||
317 | return NULL; | ||
318 | } | ||
319 | if (!re->rects) | ||
320 | { | ||
321 | re->rects = evas_common_tilebuf_get_render_rects(re->tb); | ||
322 | re->cur_rect = EINA_INLIST_GET(re->rects); | ||
323 | } | ||
324 | if (!re->cur_rect) | ||
325 | return NULL; | ||
326 | |||
327 | rect = (Tilebuf_Rect *)re->cur_rect; | ||
328 | ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h; | ||
329 | re->cur_rect = re->cur_rect->next; | ||
330 | if (!re->cur_rect) | ||
331 | { | ||
332 | evas_common_tilebuf_free_render_rects(re->rects); | ||
333 | re->rects = NULL; | ||
334 | re->end = 1; | ||
335 | } | ||
336 | |||
337 | *x = *cx = ux; | ||
338 | *y = *cy = uy; | ||
339 | *w = *cw = uw; | ||
340 | *h = *ch = uh; | ||
341 | /*printf ("eng_output_redraws_next_update_get returning : %d,%d %dx%d -- %d,%d %dx%d\n", | ||
342 | *x, *y, *w, *h, *cx, *cy, *cw, *ch);*/ | ||
343 | |||
344 | return re->rgba_image; | ||
345 | } | ||
346 | |||
347 | static void | ||
348 | eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h) | ||
349 | { | ||
350 | /* Don't do anything, we'll just coy the whole buffer when it's time to flush */ | ||
351 | } | ||
352 | |||
353 | static void | ||
354 | eng_output_flush(void *data) | ||
355 | { | ||
356 | Render_Engine *re; | ||
357 | rsxBuffer *buffer; | ||
358 | int width; | ||
359 | int height; | ||
360 | |||
361 | //printf ("eng_output_flush called\n"); | ||
362 | re = (Render_Engine *)data; | ||
363 | buffer = &re->buffers[re->currentBuffer]; | ||
364 | width = re->rgba_image->cache_entry.w; | ||
365 | height = re->rgba_image->cache_entry.h; | ||
366 | |||
367 | /* Wait for the flip before copying the buffer */ | ||
368 | waitFlip (); | ||
369 | |||
370 | if (re->width == width && | ||
371 | re->height == height) | ||
372 | { | ||
373 | /* DMA the back buffer into the rsx buffer */ | ||
374 | rsxSetTransferImage (re->context, | ||
375 | GCM_TRANSFER_MAIN_TO_LOCAL, | ||
376 | buffer->offset, buffer->width * sizeof(u32), | ||
377 | 0, 0, | ||
378 | re->rgba_image_offset, re->width * sizeof(u32), | ||
379 | 0, 0, re->width, re->height, sizeof(u32)); | ||
380 | } | ||
381 | else | ||
382 | { | ||
383 | gcmTransferScale gcm_scale; | ||
384 | gcmTransferSurface gcm_surface; | ||
385 | |||
386 | gcm_surface.format = GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8; | ||
387 | gcm_surface.pitch = buffer->width * sizeof(u32); | ||
388 | gcm_surface._pad0[0] = gcm_surface._pad0[1] = 0; | ||
389 | gcm_surface.offset = buffer->offset; | ||
390 | |||
391 | gcm_scale.interp = GCM_TRANSFER_INTERPOLATOR_LINEAR; | ||
392 | gcm_scale.conversion = GCM_TRANSFER_CONVERSION_TRUNCATE; | ||
393 | gcm_scale.format = GCM_TRANSFER_SCALE_FORMAT_A8R8G8B8; | ||
394 | gcm_scale.origin = GCM_TRANSFER_ORIGIN_CORNER; | ||
395 | gcm_scale.operation = GCM_TRANSFER_OPERATION_SRCCOPY; | ||
396 | gcm_scale.offset = re->rgba_image_offset; | ||
397 | gcm_scale.clipX = 0; | ||
398 | gcm_scale.clipY = 0; | ||
399 | gcm_scale.clipW = re->width; | ||
400 | gcm_scale.clipH = re->height; | ||
401 | gcm_scale.outX = 0; | ||
402 | gcm_scale.outY = 0; | ||
403 | gcm_scale.outW = re->width; | ||
404 | gcm_scale.outH = re->height; | ||
405 | gcm_scale.ratioX = rsxGetFixedSint32 ((float)width / (float)re->width); | ||
406 | gcm_scale.ratioY = rsxGetFixedSint32 ((float)height / (float)re->height); | ||
407 | gcm_scale.inX = 0; | ||
408 | gcm_scale.inY = 0; | ||
409 | gcm_scale.inW = (width & ~1); // Width must be a multiple of 2 | ||
410 | gcm_scale.inH = height; | ||
411 | if (gcm_scale.inW < 2) // Minimum inW value is 2 | ||
412 | gcm_scale.inW = 2; | ||
413 | if (gcm_scale.inW > 2046) // Maximum inW value is 2046 | ||
414 | gcm_scale.inW = 2046; | ||
415 | if (gcm_scale.inH < 1) // Minimum inH value is 1 | ||
416 | gcm_scale.inH = 1; | ||
417 | if (gcm_scale.inH > 2047) // Maximum inW value is 2047 | ||
418 | gcm_scale.inH = 2047; | ||
419 | gcm_scale.pitch = sizeof(u32) * width; | ||
420 | |||
421 | rsxSetTransferScaleMode (re->context, GCM_TRANSFER_MAIN_TO_LOCAL, GCM_TRANSFER_SURFACE); | ||
422 | rsxSetTransferScaleSurface (re->context, &gcm_scale, &gcm_surface); | ||
423 | } | ||
424 | /* Wait for the DMA to finish */ | ||
425 | flushRSX (re->context); | ||
426 | |||
427 | /* Flip buffer onto screen */ | ||
428 | flipBuffer (re->context, re->currentBuffer); | ||
429 | re->currentBuffer = (re->currentBuffer + 1) % MAX_BUFFERS; | ||
430 | } | ||
431 | |||
432 | static void | ||
433 | eng_output_idle_flush(void *data) | ||
434 | { | ||
435 | Render_Engine *re; | ||
436 | |||
437 | printf ("eng_output_idle_flush called\n"); | ||
438 | re = (Render_Engine *)data; | ||
439 | } | ||
440 | |||
441 | static Eina_Bool | ||
442 | eng_canvas_alpha_get(void *data, void *context __UNUSED__) | ||
443 | { | ||
444 | Render_Engine *re; | ||
445 | |||
446 | // printf ("eng_output_alpha_get called\n"); | ||
447 | re = (Render_Engine *)data; | ||
448 | return EINA_TRUE; | ||
449 | } | ||
450 | |||
451 | /* module advertising code */ | ||
452 | static int | ||
453 | module_open(Evas_Module *em) | ||
454 | { | ||
455 | if (!em) return 0; | ||
456 | /* get whatever engine module we inherit from */ | ||
457 | if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0; | ||
458 | _evas_engine_psl1ght_log_dom = eina_log_domain_register | ||
459 | ("evas-psl1ght", EVAS_DEFAULT_LOG_COLOR); | ||
460 | if (_evas_engine_psl1ght_log_dom < 0) | ||
461 | { | ||
462 | EINA_LOG_ERR("Can not create a module log domain."); | ||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | /* store it for later use */ | ||
467 | func = pfunc; | ||
468 | /* now to override methods */ | ||
469 | #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_) | ||
470 | ORD(info); | ||
471 | ORD(info_free); | ||
472 | ORD(setup); | ||
473 | ORD(canvas_alpha_get); | ||
474 | ORD(output_free); | ||
475 | ORD(output_resize); | ||
476 | ORD(output_tile_size_set); | ||
477 | ORD(output_redraws_rect_add); | ||
478 | ORD(output_redraws_rect_del); | ||
479 | ORD(output_redraws_clear); | ||
480 | ORD(output_redraws_next_update_get); | ||
481 | ORD(output_redraws_next_update_push); | ||
482 | ORD(output_flush); | ||
483 | ORD(output_idle_flush); | ||
484 | |||
485 | /* now advertise out own api */ | ||
486 | em->functions = (void *)(&func); | ||
487 | return 1; | ||
488 | } | ||
489 | |||
490 | static void | ||
491 | module_close(Evas_Module *em __UNUSED__) | ||
492 | { | ||
493 | eina_log_domain_unregister(_evas_engine_psl1ght_log_dom); | ||
494 | } | ||
495 | |||
496 | static Evas_Module_Api evas_modapi = | ||
497 | { | ||
498 | EVAS_MODULE_API_VERSION, | ||
499 | "psl1ght", | ||
500 | "none", | ||
501 | { | ||
502 | module_open, | ||
503 | module_close | ||
504 | } | ||
505 | }; | ||
506 | |||
507 | EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, psl1ght); | ||
508 | |||
509 | #ifndef EVAS_STATIC_BUILD_PSL1GHT | ||
510 | EVAS_EINA_MODULE_DEFINE(engine, psl1ght); | ||
511 | #endif | ||