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/lib/canvas/evas_render.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/lib/canvas/evas_render.c')
-rw-r--r-- | libraries/evas/src/lib/canvas/evas_render.c | 1866 |
1 files changed, 1866 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/canvas/evas_render.c b/libraries/evas/src/lib/canvas/evas_render.c new file mode 100644 index 0000000..0abee97 --- /dev/null +++ b/libraries/evas/src/lib/canvas/evas_render.c | |||
@@ -0,0 +1,1866 @@ | |||
1 | #include "evas_common.h" | ||
2 | #include "evas_private.h" | ||
3 | #include <math.h> | ||
4 | |||
5 | // debug rendering | ||
6 | /* #define REND_DGB 1 */ | ||
7 | /* #define STDOUT_DBG 1 */ | ||
8 | |||
9 | #ifdef REND_DGB | ||
10 | static FILE *dbf = NULL; | ||
11 | |||
12 | static void | ||
13 | rend_dbg(const char *txt) | ||
14 | { | ||
15 | if (!dbf) | ||
16 | { | ||
17 | #ifdef STDOUT_DBG | ||
18 | dbf = stdout; | ||
19 | #else | ||
20 | dbf = fopen("EVAS-RENDER-DEBUG.log", "w"); | ||
21 | #endif | ||
22 | if (!dbf) return; | ||
23 | } | ||
24 | fputs(txt, dbf); | ||
25 | fflush(dbf); | ||
26 | } | ||
27 | #define RD(args...) \ | ||
28 | { \ | ||
29 | char __tmpbuf[4096]; \ | ||
30 | \ | ||
31 | snprintf(__tmpbuf, sizeof(__tmpbuf), ##args); \ | ||
32 | rend_dbg(__tmpbuf); \ | ||
33 | } | ||
34 | #define RDI(xxxx) \ | ||
35 | { \ | ||
36 | char __tmpbuf[4096]; int __tmpi; \ | ||
37 | for (__tmpi = 0; __tmpi < xxxx; __tmpi++) \ | ||
38 | __tmpbuf[__tmpi] = ' '; \ | ||
39 | __tmpbuf[__tmpi] = 0; \ | ||
40 | rend_dbg(__tmpbuf); \ | ||
41 | } | ||
42 | #else | ||
43 | #define RD(args...) | ||
44 | #define RDI(x) | ||
45 | #endif | ||
46 | |||
47 | static Eina_List * | ||
48 | evas_render_updates_internal(Evas *e, unsigned char make_updates, unsigned char do_draw); | ||
49 | |||
50 | EAPI void | ||
51 | evas_damage_rectangle_add(Evas *e, int x, int y, int w, int h) | ||
52 | { | ||
53 | Eina_Rectangle *r; | ||
54 | |||
55 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
56 | return; | ||
57 | MAGIC_CHECK_END(); | ||
58 | NEW_RECT(r, x, y, w, h); | ||
59 | if (!r) return; | ||
60 | e->damages = eina_list_append(e->damages, r); | ||
61 | e->changed = 1; | ||
62 | } | ||
63 | |||
64 | EAPI void | ||
65 | evas_obscured_rectangle_add(Evas *e, int x, int y, int w, int h) | ||
66 | { | ||
67 | Eina_Rectangle *r; | ||
68 | |||
69 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
70 | return; | ||
71 | MAGIC_CHECK_END(); | ||
72 | NEW_RECT(r, x, y, w, h); | ||
73 | if (!r) return; | ||
74 | e->obscures = eina_list_append(e->obscures, r); | ||
75 | } | ||
76 | |||
77 | EAPI void | ||
78 | evas_obscured_clear(Evas *e) | ||
79 | { | ||
80 | Eina_Rectangle *r; | ||
81 | |||
82 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
83 | return; | ||
84 | MAGIC_CHECK_END(); | ||
85 | EINA_LIST_FREE(e->obscures, r) | ||
86 | { | ||
87 | eina_rectangle_free(r); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | static Eina_Bool | ||
92 | _evas_render_has_map(Evas_Object *obj) | ||
93 | { | ||
94 | return ((!((obj->func->can_map) && (obj->func->can_map(obj)))) && | ||
95 | ((obj->cur.map) && (obj->cur.usemap))); | ||
96 | // return ((obj->cur.map) && (obj->cur.usemap)); | ||
97 | } | ||
98 | |||
99 | static Eina_Bool | ||
100 | _evas_render_had_map(Evas_Object *obj) | ||
101 | { | ||
102 | return ((obj->prev.map) && (obj->prev.usemap)); | ||
103 | // return ((!obj->cur.map) && (obj->prev.usemap)); | ||
104 | } | ||
105 | |||
106 | static Eina_Bool | ||
107 | _evas_render_is_relevant(Evas_Object *obj) | ||
108 | { | ||
109 | return ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) || | ||
110 | (evas_object_was_visible(obj) && (!obj->prev.have_clipees))); | ||
111 | } | ||
112 | |||
113 | static Eina_Bool | ||
114 | _evas_render_can_render(Evas_Object *obj) | ||
115 | { | ||
116 | return (evas_object_is_visible(obj) && (!obj->cur.have_clipees)); | ||
117 | } | ||
118 | |||
119 | static void | ||
120 | _evas_render_prev_cur_clip_cache_add(Evas *e, Evas_Object *obj) | ||
121 | { | ||
122 | e->engine.func->output_redraws_rect_add(e->engine.data.output, | ||
123 | obj->prev.cache.clip.x, | ||
124 | obj->prev.cache.clip.y, | ||
125 | obj->prev.cache.clip.w, | ||
126 | obj->prev.cache.clip.h); | ||
127 | e->engine.func->output_redraws_rect_add(e->engine.data.output, | ||
128 | obj->cur.cache.clip.x, | ||
129 | obj->cur.cache.clip.y, | ||
130 | obj->cur.cache.clip.w, | ||
131 | obj->cur.cache.clip.h); | ||
132 | } | ||
133 | |||
134 | static void | ||
135 | _evas_render_cur_clip_cache_del(Evas *e, Evas_Object *obj) | ||
136 | { | ||
137 | Evas_Coord x, y, w, h; | ||
138 | |||
139 | x = obj->cur.cache.clip.x; | ||
140 | y = obj->cur.cache.clip.y; | ||
141 | w = obj->cur.cache.clip.w; | ||
142 | h = obj->cur.cache.clip.h; | ||
143 | if (obj->cur.clipper) | ||
144 | { | ||
145 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
146 | obj->cur.clipper->cur.cache.clip.x, | ||
147 | obj->cur.clipper->cur.cache.clip.y, | ||
148 | obj->cur.clipper->cur.cache.clip.w, | ||
149 | obj->cur.clipper->cur.cache.clip.h); | ||
150 | } | ||
151 | e->engine.func->output_redraws_rect_del(e->engine.data.output, | ||
152 | x, y, w, h); | ||
153 | } | ||
154 | |||
155 | static void | ||
156 | _evas_render_phase1_direct(Evas *e, | ||
157 | Eina_Array *active_objects, | ||
158 | Eina_Array *restack_objects __UNUSED__, | ||
159 | Eina_Array *delete_objects __UNUSED__, | ||
160 | Eina_Array *render_objects) | ||
161 | { | ||
162 | unsigned int i; | ||
163 | Eina_List *l; | ||
164 | Evas_Object *proxy; | ||
165 | |||
166 | RD(" [--- PHASE 1 DIRECT\n"); | ||
167 | for (i = 0; i < active_objects->count; i++) | ||
168 | { | ||
169 | Evas_Object *obj; | ||
170 | |||
171 | obj = eina_array_data_get(active_objects, i); | ||
172 | if (obj->changed) | ||
173 | { | ||
174 | /* Flag need redraw on proxy too */ | ||
175 | evas_object_clip_recalc(obj); | ||
176 | if (obj->proxy.proxies) | ||
177 | { | ||
178 | EINA_LIST_FOREACH(obj->proxy.proxies, l, proxy) | ||
179 | proxy->proxy.redraw = 1; | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | for (i = 0; i < render_objects->count; i++) | ||
184 | { | ||
185 | Evas_Object *obj; | ||
186 | |||
187 | obj = eina_array_data_get(render_objects, i); | ||
188 | RD(" OBJ [%p] changed %i\n", obj, obj->changed); | ||
189 | if (obj->changed) | ||
190 | { | ||
191 | /* Flag need redraw on proxy too */ | ||
192 | evas_object_clip_recalc(obj); | ||
193 | obj->func->render_pre(obj); | ||
194 | if (obj->proxy.proxies) | ||
195 | { | ||
196 | obj->proxy.redraw = 1; | ||
197 | EINA_LIST_FOREACH(obj->proxy.proxies, l, proxy) | ||
198 | { | ||
199 | proxy->func->render_pre(proxy); | ||
200 | _evas_render_prev_cur_clip_cache_add(e, proxy); | ||
201 | } | ||
202 | } | ||
203 | else if (obj->proxy.redraw) | ||
204 | { | ||
205 | _evas_render_prev_cur_clip_cache_add(e, obj); | ||
206 | } | ||
207 | if (obj->pre_render_done) | ||
208 | { | ||
209 | RD(" pre-render-done smart:%p|%p [%p, %i] | [%p, %i] has_map:%i had_map:%i\n", | ||
210 | obj->smart.smart, | ||
211 | evas_object_smart_members_get_direct(obj), | ||
212 | obj->cur.map, obj->cur.usemap, | ||
213 | obj->prev.map, obj->prev.usemap, | ||
214 | _evas_render_has_map(obj), | ||
215 | _evas_render_had_map(obj)); | ||
216 | if ((obj->smart.smart) && | ||
217 | (_evas_render_has_map(obj))) | ||
218 | { | ||
219 | RD(" has map + smart\n"); | ||
220 | _evas_render_prev_cur_clip_cache_add(e, obj); | ||
221 | } | ||
222 | } | ||
223 | else if (_evas_render_had_map(obj)) | ||
224 | { | ||
225 | RD(" no pre-render done\n"); | ||
226 | _evas_render_prev_cur_clip_cache_add(e, obj); | ||
227 | } | ||
228 | } | ||
229 | else | ||
230 | { | ||
231 | if (obj->smart.smart) | ||
232 | { | ||
233 | // obj->func->render_pre(obj); | ||
234 | } | ||
235 | else if ((obj->rect_del) || | ||
236 | (evas_object_is_opaque(obj) && evas_object_is_visible(obj))) | ||
237 | { | ||
238 | RD(" rect del\n"); | ||
239 | _evas_render_cur_clip_cache_del(e, obj); | ||
240 | } | ||
241 | } | ||
242 | } | ||
243 | RD(" ---]\n"); | ||
244 | } | ||
245 | |||
246 | static Eina_Bool | ||
247 | _evas_render_phase1_object_process(Evas *e, Evas_Object *obj, | ||
248 | Eina_Array *active_objects, | ||
249 | Eina_Array *restack_objects, | ||
250 | Eina_Array *delete_objects, | ||
251 | Eina_Array *render_objects, | ||
252 | int restack, int map, | ||
253 | int *redraw_all | ||
254 | #ifdef REND_DGB | ||
255 | , int level | ||
256 | #endif | ||
257 | ) | ||
258 | { | ||
259 | Eina_Bool clean_them = EINA_FALSE; | ||
260 | Evas_Object *obj2; | ||
261 | int is_active; | ||
262 | Eina_Bool hmap; | ||
263 | |||
264 | obj->rect_del = 0; | ||
265 | obj->render_pre = 0; | ||
266 | |||
267 | #ifndef EVAS_FRAME_QUEUING | ||
268 | /* because of clip objects - delete 2 cycles later */ | ||
269 | if (obj->delete_me == 2) | ||
270 | #else | ||
271 | if (obj->delete_me == evas_common_frameq_get_frameq_sz() + 2) | ||
272 | #endif | ||
273 | eina_array_push(delete_objects, obj); | ||
274 | else if (obj->delete_me != 0) obj->delete_me++; | ||
275 | /* If the object will be removed, we should not cache anything during this run. */ | ||
276 | if (obj->delete_me != 0) clean_them = EINA_TRUE; | ||
277 | |||
278 | /* build active object list */ | ||
279 | evas_object_clip_recalc(obj); | ||
280 | is_active = evas_object_is_active(obj); | ||
281 | obj->is_active = is_active; | ||
282 | |||
283 | RDI(level); | ||
284 | RD(" [--- PROCESS [%p] '%s' active = %i, del = %i | %i %i %ix%i\n", obj, obj->type, is_active, obj->delete_me, obj->cur.geometry.x, obj->cur.geometry.y, obj->cur.geometry.w, obj->cur.geometry.h); | ||
285 | if ((is_active) || (obj->delete_me != 0)) | ||
286 | eina_array_push(active_objects, obj); | ||
287 | |||
288 | #ifdef REND_DGB | ||
289 | if (!is_active) | ||
290 | { | ||
291 | RDI(level); | ||
292 | RD(" [%p] vis: %i, cache.clip.vis: %i cache.clip.a: %i [%p]\n", obj, obj->cur.visible, obj->cur.cache.clip.visible, obj->cur.cache.clip.a, obj->func->is_visible); | ||
293 | } | ||
294 | #endif | ||
295 | |||
296 | map = _evas_render_has_map(obj); | ||
297 | hmap = _evas_render_had_map(obj); | ||
298 | |||
299 | if ((restack) && (!map)) | ||
300 | { | ||
301 | if (!obj->changed) | ||
302 | { | ||
303 | eina_array_push(&e->pending_objects, obj); | ||
304 | obj->changed = 1; | ||
305 | } | ||
306 | obj->restack = 1; | ||
307 | clean_them = EINA_TRUE; | ||
308 | } | ||
309 | |||
310 | if (map) | ||
311 | { | ||
312 | RDI(level); | ||
313 | RD(" obj mapped\n"); | ||
314 | if (obj->changed) | ||
315 | { | ||
316 | if (map != hmap) | ||
317 | { | ||
318 | *redraw_all = 1; | ||
319 | } | ||
320 | evas_object_clip_recalc(obj); | ||
321 | if ((obj->restack) && | ||
322 | (is_active) && (!obj->clip.clipees) && | ||
323 | ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) || | ||
324 | (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) | ||
325 | { | ||
326 | eina_array_push(render_objects, obj); | ||
327 | _evas_render_prev_cur_clip_cache_add(e, obj); | ||
328 | obj->render_pre = 1; | ||
329 | } | ||
330 | else if ((is_active) && (!obj->clip.clipees) && | ||
331 | ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) || | ||
332 | (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) | ||
333 | { | ||
334 | eina_array_push(render_objects, obj); | ||
335 | _evas_render_prev_cur_clip_cache_add(e, obj); | ||
336 | obj->render_pre = 1; | ||
337 | } | ||
338 | } | ||
339 | return clean_them; | ||
340 | } | ||
341 | else if (_evas_render_had_map(obj)) | ||
342 | { | ||
343 | RDI(level); | ||
344 | RD(" had map - restack objs\n"); | ||
345 | // eina_array_push(restack_objects, obj); | ||
346 | _evas_render_prev_cur_clip_cache_add(e, obj); | ||
347 | if (obj->changed) | ||
348 | { | ||
349 | if (hmap) | ||
350 | { | ||
351 | if (!map) | ||
352 | { | ||
353 | if ((obj->cur.map) && (obj->cur.usemap)) map = 1; | ||
354 | } | ||
355 | } | ||
356 | if (map != hmap) | ||
357 | { | ||
358 | *redraw_all = 1; | ||
359 | } | ||
360 | } | ||
361 | } | ||
362 | |||
363 | /* handle normal rendering. this object knows how to handle maps */ | ||
364 | if (obj->changed) | ||
365 | { | ||
366 | if (obj->smart.smart) | ||
367 | { | ||
368 | RDI(level); | ||
369 | RD(" changed + smart - render ok\n"); | ||
370 | eina_array_push(render_objects, obj); | ||
371 | obj->render_pre = 1; | ||
372 | EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2) | ||
373 | { | ||
374 | _evas_render_phase1_object_process(e, obj2, | ||
375 | active_objects, | ||
376 | restack_objects, | ||
377 | delete_objects, | ||
378 | render_objects, | ||
379 | obj->restack, | ||
380 | map, | ||
381 | redraw_all | ||
382 | #ifdef REND_DGB | ||
383 | , level + 1 | ||
384 | #endif | ||
385 | ); | ||
386 | } | ||
387 | } | ||
388 | else | ||
389 | { | ||
390 | if ((is_active) && (!obj->clip.clipees) && | ||
391 | _evas_render_is_relevant(obj)) | ||
392 | { | ||
393 | RDI(level); | ||
394 | RD(" relevant + active\n"); | ||
395 | if (obj->restack) | ||
396 | eina_array_push(restack_objects, obj); | ||
397 | else | ||
398 | { | ||
399 | eina_array_push(render_objects, obj); | ||
400 | obj->render_pre = 1; | ||
401 | } | ||
402 | } | ||
403 | else | ||
404 | { | ||
405 | RDI(level); | ||
406 | RD(" skip - not smart, not active or clippees or not relevant\n"); | ||
407 | } | ||
408 | } | ||
409 | } | ||
410 | else | ||
411 | { | ||
412 | RD(" not changed... [%i] -> (%i %i %p %i) [%i]\n", | ||
413 | evas_object_is_visible(obj), | ||
414 | obj->cur.visible, obj->cur.cache.clip.visible, obj->smart.smart, obj->cur.cache.clip.a, | ||
415 | evas_object_was_visible(obj)); | ||
416 | if ((!obj->clip.clipees) && (obj->delete_me == 0) && | ||
417 | (_evas_render_can_render(obj) || | ||
418 | (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) | ||
419 | { | ||
420 | if (obj->smart.smart) | ||
421 | { | ||
422 | RDI(level); | ||
423 | RD(" smart + visible/was visible + not clip\n"); | ||
424 | eina_array_push(render_objects, obj); | ||
425 | obj->render_pre = 1; | ||
426 | EINA_INLIST_FOREACH | ||
427 | (evas_object_smart_members_get_direct(obj), obj2) | ||
428 | { | ||
429 | _evas_render_phase1_object_process(e, obj2, | ||
430 | active_objects, | ||
431 | restack_objects, | ||
432 | delete_objects, | ||
433 | render_objects, | ||
434 | restack, map, | ||
435 | redraw_all | ||
436 | #ifdef REND_DGB | ||
437 | , level + 1 | ||
438 | #endif | ||
439 | ); | ||
440 | } | ||
441 | } | ||
442 | else | ||
443 | { | ||
444 | if (evas_object_is_opaque(obj) && | ||
445 | evas_object_is_visible(obj)) | ||
446 | { | ||
447 | RDI(level); | ||
448 | RD(" opaque + visible\n"); | ||
449 | eina_array_push(render_objects, obj); | ||
450 | obj->rect_del = 1; | ||
451 | } | ||
452 | else if (evas_object_is_visible(obj)) | ||
453 | { | ||
454 | RDI(level); | ||
455 | RD(" visible\n"); | ||
456 | eina_array_push(render_objects, obj); | ||
457 | obj->render_pre = 1; | ||
458 | } | ||
459 | else | ||
460 | { | ||
461 | RDI(level); | ||
462 | RD(" skip\n"); | ||
463 | } | ||
464 | } | ||
465 | } | ||
466 | /* | ||
467 | else if (obj->smart.smart) | ||
468 | { | ||
469 | RDI(level); | ||
470 | RD(" smart + mot visible/was visible\n"); | ||
471 | eina_array_push(render_objects, obj); | ||
472 | obj->render_pre = 1; | ||
473 | EINA_INLIST_FOREACH | ||
474 | (evas_object_smart_members_get_direct(obj), obj2) | ||
475 | { | ||
476 | _evas_render_phase1_object_process(e, obj2, | ||
477 | active_objects, | ||
478 | restack_objects, | ||
479 | delete_objects, | ||
480 | render_objects, | ||
481 | restack, map, | ||
482 | redraw_all | ||
483 | #ifdef REND_DGB | ||
484 | , level + 1 | ||
485 | #endif | ||
486 | ); | ||
487 | } | ||
488 | } | ||
489 | */ | ||
490 | } | ||
491 | if (!is_active) obj->restack = 0; | ||
492 | RDI(level); | ||
493 | RD(" ---]\n"); | ||
494 | return clean_them; | ||
495 | } | ||
496 | |||
497 | static Eina_Bool | ||
498 | _evas_render_phase1_process(Evas *e, | ||
499 | Eina_Array *active_objects, | ||
500 | Eina_Array *restack_objects, | ||
501 | Eina_Array *delete_objects, | ||
502 | Eina_Array *render_objects, | ||
503 | int *redraw_all) | ||
504 | { | ||
505 | Evas_Layer *lay; | ||
506 | Eina_Bool clean_them = EINA_FALSE; | ||
507 | |||
508 | RD(" [--- PHASE 1\n"); | ||
509 | EINA_INLIST_FOREACH(e->layers, lay) | ||
510 | { | ||
511 | Evas_Object *obj; | ||
512 | |||
513 | EINA_INLIST_FOREACH(lay->objects, obj) | ||
514 | { | ||
515 | clean_them |= _evas_render_phase1_object_process | ||
516 | (e, obj, active_objects, restack_objects, delete_objects, | ||
517 | render_objects, 0, 0, redraw_all | ||
518 | #ifdef REND_DGB | ||
519 | , 1 | ||
520 | #endif | ||
521 | ); | ||
522 | } | ||
523 | } | ||
524 | RD(" ---]\n"); | ||
525 | return clean_them; | ||
526 | } | ||
527 | |||
528 | static void | ||
529 | _evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *e) | ||
530 | { | ||
531 | unsigned int i; | ||
532 | |||
533 | for (i = 0; i < pending_objects->count; ++i) | ||
534 | { | ||
535 | Evas_Object *obj; | ||
536 | int is_active, ok = 0; | ||
537 | |||
538 | obj = eina_array_data_get(pending_objects, i); | ||
539 | |||
540 | if (!obj->layer) goto clean_stuff; | ||
541 | |||
542 | evas_object_clip_recalc(obj); | ||
543 | is_active = evas_object_is_active(obj); | ||
544 | |||
545 | if ((!is_active) && (!obj->is_active) && (!obj->render_pre) && | ||
546 | (!obj->rect_del)) | ||
547 | { | ||
548 | ok = 1; | ||
549 | goto clean_stuff; | ||
550 | } | ||
551 | |||
552 | if (obj->is_active == is_active) | ||
553 | { | ||
554 | if (obj->changed) | ||
555 | { | ||
556 | if (obj->smart.smart) | ||
557 | { | ||
558 | if (obj->render_pre || obj->rect_del) ok = 1; | ||
559 | } | ||
560 | else | ||
561 | if ((is_active) && (obj->restack) && (!obj->clip.clipees) && | ||
562 | (_evas_render_can_render(obj) || | ||
563 | (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) | ||
564 | { | ||
565 | if (!(obj->render_pre || obj->rect_del)) ok = 1; | ||
566 | } | ||
567 | else | ||
568 | if (is_active && (!obj->clip.clipees) && | ||
569 | (_evas_render_can_render(obj) || | ||
570 | (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) | ||
571 | { | ||
572 | if (obj->render_pre || obj->rect_del) ok = 1; | ||
573 | } | ||
574 | } | ||
575 | else | ||
576 | { | ||
577 | if ((!obj->clip.clipees) && (obj->delete_me == 0) && | ||
578 | (!obj->cur.have_clipees || (evas_object_was_visible(obj) && (!obj->prev.have_clipees))) | ||
579 | && evas_object_is_opaque(obj) && evas_object_is_visible(obj)) | ||
580 | { | ||
581 | if (obj->rect_del || obj->smart.smart) ok = 1; | ||
582 | } | ||
583 | } | ||
584 | } | ||
585 | |||
586 | clean_stuff: | ||
587 | if (!ok) | ||
588 | { | ||
589 | eina_array_clean(&e->active_objects); | ||
590 | eina_array_clean(&e->render_objects); | ||
591 | eina_array_clean(&e->restack_objects); | ||
592 | eina_array_clean(&e->delete_objects); | ||
593 | e->invalidate = 1; | ||
594 | return ; | ||
595 | } | ||
596 | } | ||
597 | } | ||
598 | |||
599 | Eina_Bool | ||
600 | pending_change(void *data, void *gdata __UNUSED__) | ||
601 | { | ||
602 | Evas_Object *obj; | ||
603 | |||
604 | obj = data; | ||
605 | if (obj->delete_me) return EINA_FALSE; | ||
606 | if (obj->pre_render_done) | ||
607 | { | ||
608 | RD(" OBJ [%p] pending change %i -> 0, pre %i\n", obj, obj->changed, obj->pre_render_done); | ||
609 | obj->pre_render_done = 0; | ||
610 | //// FIXME: this wipes out changes | ||
611 | obj->changed = 0; | ||
612 | obj->changed_move_only = 0; | ||
613 | obj->changed_nomove = 0; | ||
614 | obj->changed_move = 0; | ||
615 | } | ||
616 | return obj->changed ? EINA_TRUE : EINA_FALSE; | ||
617 | } | ||
618 | /* | ||
619 | static void | ||
620 | unchange(Evas_Object *obj) | ||
621 | { | ||
622 | Evas_Object *obj2; | ||
623 | |||
624 | if (!obj->changed) return; | ||
625 | obj->changed = 0; | ||
626 | obj->changed_move_only = 0; | ||
627 | obj->changed_nomove = 0; | ||
628 | obj->changed_move = 0; | ||
629 | EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2) | ||
630 | { | ||
631 | unchange(obj2); | ||
632 | } | ||
633 | } | ||
634 | |||
635 | static int | ||
636 | chlist(Evas_Object *obj, int i) | ||
637 | { | ||
638 | Evas_Object *obj2; | ||
639 | int j; | ||
640 | int ret = 0; | ||
641 | |||
642 | if (!obj->changed) return 0; | ||
643 | for (j = 0; j < i; j++) printf(" "); | ||
644 | printf("ch2 %p %s %i [%i %i %ix%i] v %i/%i [r%i] %p\n", obj, | ||
645 | obj->type, | ||
646 | obj->changed_move_only, | ||
647 | obj->cur.geometry.x, | ||
648 | obj->cur.geometry.y, | ||
649 | obj->cur.geometry.w, | ||
650 | obj->cur.geometry.h, | ||
651 | obj->cur.visible, | ||
652 | obj->prev.visible, | ||
653 | obj->restack, | ||
654 | obj->clip.clipees); | ||
655 | EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2) | ||
656 | { | ||
657 | if (obj2->changed) | ||
658 | ret |= chlist(obj2, i + 1); | ||
659 | } | ||
660 | } | ||
661 | */ | ||
662 | static Eina_Bool | ||
663 | _evas_render_can_use_overlay(Evas *e, Evas_Object *obj) | ||
664 | { | ||
665 | Eina_Rectangle *r; | ||
666 | Evas_Object *tmp; | ||
667 | Eina_List *alphas = NULL; | ||
668 | Eina_List *opaques = NULL; | ||
669 | Evas_Object *video_parent = NULL; | ||
670 | Eina_Rectangle zone; | ||
671 | Evas_Coord xc1, yc1, xc2, yc2; | ||
672 | unsigned int i; | ||
673 | Eina_Bool nooverlay; | ||
674 | |||
675 | video_parent = _evas_object_image_video_parent_get(obj); | ||
676 | |||
677 | /* Check if any one is the stack make this object mapped */ | ||
678 | tmp = obj; | ||
679 | while (tmp && !_evas_render_has_map(tmp)) | ||
680 | tmp = tmp->smart.parent; | ||
681 | |||
682 | if (tmp && _evas_render_has_map(tmp)) return EINA_FALSE; /* we are mapped, we can't be an overlay */ | ||
683 | |||
684 | if (!evas_object_is_visible(obj)) return EINA_FALSE; /* no need to update the overlay if it's not visible */ | ||
685 | |||
686 | /* If any recoloring of the surface is needed, n overlay to */ | ||
687 | if ((obj->cur.cache.clip.r != 255) || | ||
688 | (obj->cur.cache.clip.g != 255) || | ||
689 | (obj->cur.cache.clip.b != 255) || | ||
690 | (obj->cur.cache.clip.a != 255)) | ||
691 | return EINA_FALSE; | ||
692 | |||
693 | /* Check presence of transparent object on top of the video object */ | ||
694 | EINA_RECTANGLE_SET(&zone, | ||
695 | obj->cur.cache.clip.x, | ||
696 | obj->cur.cache.clip.y, | ||
697 | obj->cur.cache.clip.w, | ||
698 | obj->cur.cache.clip.h); | ||
699 | |||
700 | for (i = e->active_objects.count - 1; i > 0; i--) | ||
701 | { | ||
702 | Eina_Rectangle self; | ||
703 | Eina_Rectangle *match; | ||
704 | Evas_Object *current; | ||
705 | Eina_List *l; | ||
706 | int xm1, ym1, xm2, ym2; | ||
707 | |||
708 | current = eina_array_data_get(&e->active_objects, i); | ||
709 | |||
710 | /* Did we find the video object in the stack ? */ | ||
711 | if (current == video_parent || current == obj) | ||
712 | break; | ||
713 | |||
714 | EINA_RECTANGLE_SET(&self, | ||
715 | current->cur.cache.clip.x, | ||
716 | current->cur.cache.clip.y, | ||
717 | current->cur.cache.clip.w, | ||
718 | current->cur.cache.clip.h); | ||
719 | |||
720 | /* This doesn't cover the area of the video object, so don't bother with that object */ | ||
721 | if (!eina_rectangles_intersect(&zone, &self)) | ||
722 | continue ; | ||
723 | |||
724 | xc1 = current->cur.cache.clip.x; | ||
725 | yc1 = current->cur.cache.clip.y; | ||
726 | xc2 = current->cur.cache.clip.x + current->cur.cache.clip.w; | ||
727 | yc2 = current->cur.cache.clip.y + current->cur.cache.clip.h; | ||
728 | |||
729 | if (evas_object_is_visible(current) && | ||
730 | (!current->clip.clipees) && | ||
731 | (current->cur.visible) && | ||
732 | (!current->delete_me) && | ||
733 | (current->cur.cache.clip.visible) && | ||
734 | (!current->smart.smart)) | ||
735 | { | ||
736 | Eina_Bool included = EINA_FALSE; | ||
737 | |||
738 | if (evas_object_is_opaque(current) || | ||
739 | ((current->func->has_opaque_rect) && | ||
740 | (current->func->has_opaque_rect(current)))) | ||
741 | { | ||
742 | /* The object is opaque */ | ||
743 | |||
744 | /* Check if the opaque object is inside another opaque object */ | ||
745 | EINA_LIST_FOREACH(opaques, l, match) | ||
746 | { | ||
747 | xm1 = match->x; | ||
748 | ym1 = match->y; | ||
749 | xm2 = match->x + match->w; | ||
750 | ym2 = match->y + match->h; | ||
751 | |||
752 | /* Both object are included */ | ||
753 | if (xc1 >= xm1 && yc1 >= ym1 && xc2 <= xm2 && yc2 <= ym2) | ||
754 | { | ||
755 | included = EINA_TRUE; | ||
756 | break; | ||
757 | } | ||
758 | } | ||
759 | |||
760 | /* Not included yet */ | ||
761 | if (!included) | ||
762 | { | ||
763 | Eina_List *ln; | ||
764 | Evas_Coord xn2, yn2; | ||
765 | |||
766 | r = eina_rectangle_new(current->cur.cache.clip.x, current->cur.cache.clip.y, | ||
767 | current->cur.cache.clip.w, current->cur.cache.clip.h); | ||
768 | |||
769 | opaques = eina_list_append(opaques, r); | ||
770 | |||
771 | xn2 = r->x + r->w; | ||
772 | yn2 = r->y + r->h; | ||
773 | |||
774 | /* Remove all the transparent object that are covered by the new opaque object */ | ||
775 | EINA_LIST_FOREACH_SAFE(alphas, l, ln, match) | ||
776 | { | ||
777 | xm1 = match->x; | ||
778 | ym1 = match->y; | ||
779 | xm2 = match->x + match->w; | ||
780 | ym2 = match->y + match->h; | ||
781 | |||
782 | if (xm1 >= r->x && ym1 >= r->y && xm2 <= xn2 && ym2 <= yn2) | ||
783 | { | ||
784 | /* The new rectangle is over some transparent object, | ||
785 | so remove the transparent object */ | ||
786 | alphas = eina_list_remove_list(alphas, l); | ||
787 | } | ||
788 | } | ||
789 | } | ||
790 | } | ||
791 | else | ||
792 | { | ||
793 | /* The object has some transparency */ | ||
794 | |||
795 | /* Check if the transparent object is inside any other transparent object */ | ||
796 | EINA_LIST_FOREACH(alphas, l, match) | ||
797 | { | ||
798 | xm1 = match->x; | ||
799 | ym1 = match->y; | ||
800 | xm2 = match->x + match->w; | ||
801 | ym2 = match->y + match->h; | ||
802 | |||
803 | /* Both object are included */ | ||
804 | if (xc1 >= xm1 && yc1 >= ym1 && xc2 <= xm2 && yc2 <= ym2) | ||
805 | { | ||
806 | included = EINA_TRUE; | ||
807 | break; | ||
808 | } | ||
809 | } | ||
810 | |||
811 | /* If not check if it is inside any opaque one */ | ||
812 | if (!included) | ||
813 | { | ||
814 | EINA_LIST_FOREACH(opaques, l, match) | ||
815 | { | ||
816 | xm1 = match->x; | ||
817 | ym1 = match->y; | ||
818 | xm2 = match->x + match->w; | ||
819 | ym2 = match->y + match->h; | ||
820 | |||
821 | /* Both object are included */ | ||
822 | if (xc1 >= xm1 && yc1 >= ym1 && xc2 <= xm2 && yc2 <= ym2) | ||
823 | { | ||
824 | included = EINA_TRUE; | ||
825 | break; | ||
826 | } | ||
827 | } | ||
828 | } | ||
829 | |||
830 | /* No inclusion at all, so add it */ | ||
831 | if (!included) | ||
832 | { | ||
833 | r = eina_rectangle_new(current->cur.cache.clip.x, current->cur.cache.clip.y, | ||
834 | current->cur.cache.clip.w, current->cur.cache.clip.h); | ||
835 | |||
836 | alphas = eina_list_append(alphas, r); | ||
837 | } | ||
838 | } | ||
839 | } | ||
840 | } | ||
841 | |||
842 | /* If there is any pending transparent object, then no overlay */ | ||
843 | nooverlay = !!eina_list_count(alphas); | ||
844 | |||
845 | EINA_LIST_FREE(alphas, r) | ||
846 | eina_rectangle_free(r); | ||
847 | EINA_LIST_FREE(opaques, r) | ||
848 | eina_rectangle_free(r); | ||
849 | |||
850 | if (nooverlay) | ||
851 | return EINA_FALSE; | ||
852 | |||
853 | return EINA_TRUE; | ||
854 | } | ||
855 | |||
856 | Eina_Bool | ||
857 | evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, | ||
858 | int off_x, int off_y, int mapped, | ||
859 | int ecx, int ecy, int ecw, int ech | ||
860 | #ifdef REND_DGB | ||
861 | , int level | ||
862 | #endif | ||
863 | ) | ||
864 | { | ||
865 | void *ctx; | ||
866 | Evas_Object *obj2; | ||
867 | Eina_Bool clean_them = EINA_FALSE; | ||
868 | |||
869 | evas_object_clip_recalc(obj); | ||
870 | RDI(level); | ||
871 | RD(" { evas_render_mapped(%p, %p, %p, %p, %i, %i, %i, %i)\n", e, obj, context, surface, off_x, off_y, mapped, level); | ||
872 | if (mapped) | ||
873 | { | ||
874 | if ((!evas_object_is_visible(obj)) || (obj->clip.clipees) || | ||
875 | (obj->cur.have_clipees)) | ||
876 | { | ||
877 | RDI(level); | ||
878 | RD(" }\n"); | ||
879 | return clean_them; | ||
880 | } | ||
881 | } | ||
882 | else if (!(((evas_object_is_active(obj) && (!obj->clip.clipees) && | ||
883 | (_evas_render_can_render(obj)))) | ||
884 | )) | ||
885 | { | ||
886 | RDI(level); | ||
887 | RD(" }\n"); | ||
888 | return clean_them; | ||
889 | } | ||
890 | |||
891 | // set render_pre - for child objs that may not have gotten it. | ||
892 | obj->pre_render_done = 1; | ||
893 | RD(" Hasmap: %p (%d) %p %d -> %d\n",obj->func->can_map, | ||
894 | obj->func->can_map ? obj->func->can_map(obj): -1, | ||
895 | obj->cur.map, obj->cur.usemap, | ||
896 | _evas_render_has_map(obj)); | ||
897 | if (_evas_render_has_map(obj)) | ||
898 | { | ||
899 | const Evas_Map_Point *p, *p_end; | ||
900 | RGBA_Map_Point pts[4], *pt; | ||
901 | int sw, sh; | ||
902 | int changed = 0, rendered = 0; | ||
903 | |||
904 | clean_them = EINA_TRUE; | ||
905 | |||
906 | sw = obj->cur.geometry.w; | ||
907 | sh = obj->cur.geometry.h; | ||
908 | RDI(level); | ||
909 | RD(" mapped obj: %ix%i\n", sw, sh); | ||
910 | if ((sw <= 0) || (sh <= 0)) | ||
911 | { | ||
912 | RDI(level); | ||
913 | RD(" }\n"); | ||
914 | return clean_them; | ||
915 | } | ||
916 | |||
917 | pts[0].px = obj->cur.map->persp.px << FP; | ||
918 | pts[0].py = obj->cur.map->persp.py << FP; | ||
919 | pts[0].foc = obj->cur.map->persp.foc << FP; | ||
920 | pts[0].z0 = obj->cur.map->persp.z0 << FP; | ||
921 | |||
922 | p = obj->cur.map->points; | ||
923 | p_end = p + obj->cur.map->count; | ||
924 | pt = pts; | ||
925 | for (; p < p_end; p++, pt++) | ||
926 | { | ||
927 | pt->x = (lround(p->x) + off_x) * FP1; | ||
928 | pt->y = (lround(p->y) + off_y) * FP1; | ||
929 | pt->z = (lround(p->z) ) * FP1; | ||
930 | pt->fx = p->px; | ||
931 | pt->fy = p->py; | ||
932 | pt->fz = p->z; | ||
933 | pt->u = lround(p->u) * FP1; | ||
934 | pt->v = lround(p->v) * FP1; | ||
935 | if (pt->u < 0) pt->u = 0; | ||
936 | else if (pt->u > (sw * FP1)) pt->u = (sw * FP1); | ||
937 | if (pt->v < 0) pt->v = 0; | ||
938 | else if (pt->v > (sh * FP1)) pt->v = (sh * FP1); | ||
939 | pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b); | ||
940 | } | ||
941 | /* Copy last for software engine */ | ||
942 | if (obj->cur.map->count & 0x1) | ||
943 | { | ||
944 | pts[obj->cur.map->count] = pts[obj->cur.map->count - 1]; | ||
945 | } | ||
946 | |||
947 | |||
948 | if (obj->cur.map->surface) | ||
949 | { | ||
950 | if ((obj->cur.map->surface_w != sw) || | ||
951 | (obj->cur.map->surface_h != sh)) | ||
952 | { | ||
953 | RDI(level); | ||
954 | RD(" new surf: %ix%i\n", sw, sh); | ||
955 | obj->layer->evas->engine.func->image_map_surface_free | ||
956 | (e->engine.data.output, obj->cur.map->surface); | ||
957 | obj->cur.map->surface = NULL; | ||
958 | } | ||
959 | } | ||
960 | if (!obj->cur.map->surface) | ||
961 | { | ||
962 | obj->cur.map->surface_w = sw; | ||
963 | obj->cur.map->surface_h = sh; | ||
964 | |||
965 | obj->cur.map->surface = | ||
966 | obj->layer->evas->engine.func->image_map_surface_new | ||
967 | (e->engine.data.output, obj->cur.map->surface_w, | ||
968 | obj->cur.map->surface_h, | ||
969 | obj->cur.map->alpha); | ||
970 | RDI(level); | ||
971 | RD(" fisrt surf: %ix%i\n", sw, sh); | ||
972 | changed = 1; | ||
973 | } | ||
974 | if (obj->smart.smart) | ||
975 | { | ||
976 | Evas_Object *o2; | ||
977 | |||
978 | EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), o2) | ||
979 | { | ||
980 | if (!evas_object_is_visible(o2) && | ||
981 | !evas_object_was_visible(o2)) | ||
982 | { | ||
983 | o2->changed = 0; | ||
984 | o2->changed_move_only = 0; | ||
985 | o2->changed_nomove = 0; | ||
986 | o2->changed_move = 0; | ||
987 | continue; | ||
988 | } | ||
989 | if (o2->changed) | ||
990 | { | ||
991 | // chlist(o2, 0); | ||
992 | changed = 1; | ||
993 | o2->changed = 0; | ||
994 | o2->changed_move_only = 0; | ||
995 | o2->changed_nomove = 0; | ||
996 | o2->changed_move = 0; | ||
997 | break; | ||
998 | } | ||
999 | } | ||
1000 | // unchange(obj); | ||
1001 | obj->changed = 0; | ||
1002 | obj->changed_move_only = 0; | ||
1003 | obj->changed_nomove = 0; | ||
1004 | obj->changed_move = 0; | ||
1005 | } | ||
1006 | else | ||
1007 | { | ||
1008 | if (obj->changed) | ||
1009 | { | ||
1010 | changed = 1; | ||
1011 | obj->changed = 0; | ||
1012 | obj->changed_move_only = 0; | ||
1013 | obj->changed_nomove = 0; | ||
1014 | obj->changed_move = 0; | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | // clear surface before re-render | ||
1019 | if ((changed) && (obj->cur.map->surface)) | ||
1020 | { | ||
1021 | int off_x2, off_y2; | ||
1022 | |||
1023 | RDI(level); | ||
1024 | RD(" children redraw\n"); | ||
1025 | // FIXME: calculate "changes" within map surface and only clear | ||
1026 | // and re-render those | ||
1027 | if (obj->cur.map->alpha) | ||
1028 | { | ||
1029 | ctx = e->engine.func->context_new(e->engine.data.output); | ||
1030 | e->engine.func->context_color_set | ||
1031 | (e->engine.data.output, ctx, 0, 0, 0, 0); | ||
1032 | e->engine.func->context_render_op_set | ||
1033 | (e->engine.data.output, ctx, EVAS_RENDER_COPY); | ||
1034 | e->engine.func->rectangle_draw(e->engine.data.output, | ||
1035 | ctx, | ||
1036 | obj->cur.map->surface, | ||
1037 | 0, 0, | ||
1038 | obj->cur.map->surface_w, | ||
1039 | obj->cur.map->surface_h); | ||
1040 | e->engine.func->context_free(e->engine.data.output, ctx); | ||
1041 | } | ||
1042 | ctx = e->engine.func->context_new(e->engine.data.output); | ||
1043 | off_x2 = -obj->cur.geometry.x; | ||
1044 | off_y2 = -obj->cur.geometry.y; | ||
1045 | if (obj->smart.smart) | ||
1046 | { | ||
1047 | EINA_INLIST_FOREACH | ||
1048 | (evas_object_smart_members_get_direct(obj), obj2) | ||
1049 | { | ||
1050 | clean_them |= evas_render_mapped(e, obj2, ctx, | ||
1051 | obj->cur.map->surface, | ||
1052 | off_x2, off_y2, 1, | ||
1053 | ecx, ecy, ecw, ech | ||
1054 | #ifdef REND_DGB | ||
1055 | , level + 1 | ||
1056 | #endif | ||
1057 | ); | ||
1058 | } | ||
1059 | } | ||
1060 | else | ||
1061 | { | ||
1062 | int x = 0, y = 0, w = 0, h = 0; | ||
1063 | |||
1064 | w = obj->cur.map->surface_w; | ||
1065 | h = obj->cur.map->surface_h; | ||
1066 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
1067 | obj->cur.geometry.x + off_x2, | ||
1068 | obj->cur.geometry.y + off_y2, | ||
1069 | obj->cur.geometry.w, | ||
1070 | obj->cur.geometry.h); | ||
1071 | |||
1072 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1073 | ctx, x, y, w, h); | ||
1074 | obj->func->render(obj, e->engine.data.output, ctx, | ||
1075 | obj->cur.map->surface, off_x2, off_y2); | ||
1076 | } | ||
1077 | e->engine.func->context_free(e->engine.data.output, ctx); | ||
1078 | rendered = 1; | ||
1079 | } | ||
1080 | |||
1081 | RDI(level); | ||
1082 | RD(" draw map\n"); | ||
1083 | |||
1084 | if (rendered) | ||
1085 | { | ||
1086 | obj->cur.map->surface = e->engine.func->image_dirty_region | ||
1087 | (e->engine.data.output, obj->cur.map->surface, | ||
1088 | 0, 0, obj->cur.map->surface_w, obj->cur.map->surface_h); | ||
1089 | } | ||
1090 | e->engine.func->context_clip_unset(e->engine.data.output, | ||
1091 | e->engine.data.context); | ||
1092 | if (obj->cur.map->surface) | ||
1093 | { | ||
1094 | if (obj->smart.smart) | ||
1095 | { | ||
1096 | if (obj->cur.clipper) | ||
1097 | { | ||
1098 | int x, y, w, h; | ||
1099 | Evas_Object *tobj; | ||
1100 | |||
1101 | obj->cur.cache.clip.dirty = 1; | ||
1102 | tobj = obj->cur.map_parent; | ||
1103 | obj->cur.map_parent = obj->cur.clipper->cur.map_parent; | ||
1104 | evas_object_clip_recalc(obj); | ||
1105 | obj->cur.map_parent = tobj; | ||
1106 | x = obj->cur.cache.clip.x; | ||
1107 | y = obj->cur.cache.clip.y; | ||
1108 | w = obj->cur.cache.clip.w; | ||
1109 | h = obj->cur.cache.clip.h; | ||
1110 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
1111 | obj->cur.clipper->cur.cache.clip.x, | ||
1112 | obj->cur.clipper->cur.cache.clip.y, | ||
1113 | obj->cur.clipper->cur.cache.clip.w, | ||
1114 | obj->cur.clipper->cur.cache.clip.h); | ||
1115 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1116 | e->engine.data.context, | ||
1117 | x + off_x, y + off_y, w, h); | ||
1118 | } | ||
1119 | } | ||
1120 | else | ||
1121 | { | ||
1122 | if (obj->cur.clipper) | ||
1123 | { | ||
1124 | int x, y, w, h; | ||
1125 | |||
1126 | evas_object_clip_recalc(obj); | ||
1127 | x = obj->cur.cache.clip.x; | ||
1128 | y = obj->cur.cache.clip.y; | ||
1129 | w = obj->cur.cache.clip.w; | ||
1130 | h = obj->cur.cache.clip.h; | ||
1131 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
1132 | obj->cur.clipper->cur.cache.clip.x, | ||
1133 | obj->cur.clipper->cur.cache.clip.y, | ||
1134 | obj->cur.clipper->cur.cache.clip.w, | ||
1135 | obj->cur.clipper->cur.cache.clip.h); | ||
1136 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1137 | e->engine.data.context, | ||
1138 | x + off_x, y + off_y, w, h); | ||
1139 | } | ||
1140 | } | ||
1141 | } | ||
1142 | if (surface == e->engine.data.output) | ||
1143 | e->engine.func->context_clip_clip(e->engine.data.output, | ||
1144 | e->engine.data.context, | ||
1145 | ecx, ecy, ecw, ech); | ||
1146 | if (obj->cur.cache.clip.visible) | ||
1147 | obj->layer->evas->engine.func->image_map_draw | ||
1148 | (e->engine.data.output, e->engine.data.context, surface, | ||
1149 | obj->cur.map->surface, obj->cur.map->count, pts, | ||
1150 | obj->cur.map->smooth, 0); | ||
1151 | // FIXME: needs to cache these maps and | ||
1152 | // keep them only rendering updates | ||
1153 | // obj->layer->evas->engine.func->image_map_surface_free | ||
1154 | // (e->engine.data.output, obj->cur.map->surface); | ||
1155 | // obj->cur.map->surface = NULL; | ||
1156 | } | ||
1157 | else | ||
1158 | { | ||
1159 | if (mapped) | ||
1160 | { | ||
1161 | RDI(level); | ||
1162 | RD(" draw child of mapped obj\n"); | ||
1163 | ctx = e->engine.func->context_new(e->engine.data.output); | ||
1164 | if (obj->smart.smart) | ||
1165 | { | ||
1166 | EINA_INLIST_FOREACH | ||
1167 | (evas_object_smart_members_get_direct(obj), obj2) | ||
1168 | { | ||
1169 | clean_them |= evas_render_mapped(e, obj2, ctx, | ||
1170 | surface, | ||
1171 | off_x, off_y, 1, | ||
1172 | ecx, ecy, ecw, ech | ||
1173 | #ifdef REND_DGB | ||
1174 | , level + 1 | ||
1175 | #endif | ||
1176 | ); | ||
1177 | } | ||
1178 | } | ||
1179 | else | ||
1180 | { | ||
1181 | if (!obj->cur.map) | ||
1182 | { | ||
1183 | int x, y, w, h; | ||
1184 | |||
1185 | RDI(level); | ||
1186 | |||
1187 | x = obj->cur.cache.clip.x + off_x; | ||
1188 | y = obj->cur.cache.clip.y + off_y; | ||
1189 | w = obj->cur.cache.clip.w; | ||
1190 | h = obj->cur.cache.clip.h; | ||
1191 | |||
1192 | if (obj->cur.clipper) | ||
1193 | { | ||
1194 | if (_evas_render_has_map(obj)) | ||
1195 | evas_object_clip_recalc(obj); | ||
1196 | |||
1197 | RD(" clipper: %i %i %ix%i\n", | ||
1198 | obj->cur.clipper->cur.cache.clip.x + off_x, | ||
1199 | obj->cur.clipper->cur.cache.clip.y + off_y, | ||
1200 | obj->cur.clipper->cur.cache.clip.w, | ||
1201 | obj->cur.clipper->cur.cache.clip.h); | ||
1202 | |||
1203 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
1204 | obj->cur.clipper->cur.cache.clip.x + off_x, | ||
1205 | obj->cur.clipper->cur.cache.clip.y + off_y, | ||
1206 | obj->cur.clipper->cur.cache.clip.w, | ||
1207 | obj->cur.clipper->cur.cache.clip.h); | ||
1208 | } | ||
1209 | |||
1210 | RD(" clip: %i %i %ix%i [%i %i %ix%i]\n", | ||
1211 | obj->cur.cache.clip.x + off_x, | ||
1212 | obj->cur.cache.clip.y + off_y, | ||
1213 | obj->cur.cache.clip.w, | ||
1214 | obj->cur.cache.clip.h, | ||
1215 | obj->cur.geometry.x + off_x, | ||
1216 | obj->cur.geometry.y + off_y, | ||
1217 | obj->cur.geometry.w, | ||
1218 | obj->cur.geometry.h); | ||
1219 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1220 | ctx, x, y, w, h); | ||
1221 | } | ||
1222 | else | ||
1223 | { | ||
1224 | RDI(level); | ||
1225 | RD(" noclip\n"); | ||
1226 | } | ||
1227 | obj->func->render(obj, e->engine.data.output, ctx, | ||
1228 | surface, off_x, off_y); | ||
1229 | /* | ||
1230 | obj->layer->evas->engine.func->context_color_set(e->engine.data.output, | ||
1231 | ctx, | ||
1232 | 0, 30, 0, 30); | ||
1233 | obj->layer->evas->engine.func->rectangle_draw(e->engine.data.output, | ||
1234 | ctx, | ||
1235 | surface, | ||
1236 | 0, 0, 9999, 9999); | ||
1237 | */ | ||
1238 | } | ||
1239 | e->engine.func->context_free(e->engine.data.output, ctx); | ||
1240 | } | ||
1241 | else | ||
1242 | { | ||
1243 | if (obj->cur.clipper) | ||
1244 | { | ||
1245 | int x, y, w, h; | ||
1246 | |||
1247 | if (_evas_render_has_map(obj)) | ||
1248 | evas_object_clip_recalc(obj); | ||
1249 | x = obj->cur.cache.clip.x; | ||
1250 | y = obj->cur.cache.clip.y; | ||
1251 | w = obj->cur.cache.clip.w; | ||
1252 | h = obj->cur.cache.clip.h; | ||
1253 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
1254 | obj->cur.clipper->cur.cache.clip.x, | ||
1255 | obj->cur.clipper->cur.cache.clip.y, | ||
1256 | obj->cur.clipper->cur.cache.clip.w, | ||
1257 | obj->cur.clipper->cur.cache.clip.h); | ||
1258 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1259 | e->engine.data.context, | ||
1260 | x + off_x, y + off_y, w, h); | ||
1261 | e->engine.func->context_clip_clip(e->engine.data.output, | ||
1262 | e->engine.data.context, | ||
1263 | ecx, ecy, ecw, ech); | ||
1264 | } | ||
1265 | |||
1266 | RDI(level); | ||
1267 | RD(" draw normal obj\n"); | ||
1268 | obj->func->render(obj, e->engine.data.output, context, surface, | ||
1269 | off_x, off_y); | ||
1270 | } | ||
1271 | } | ||
1272 | RDI(level); | ||
1273 | RD(" }\n"); | ||
1274 | |||
1275 | return clean_them; | ||
1276 | } | ||
1277 | |||
1278 | static void | ||
1279 | _evas_render_cutout_add(Evas *e, Evas_Object *obj, int off_x, int off_y) | ||
1280 | { | ||
1281 | if (evas_object_is_opaque(obj)) | ||
1282 | { | ||
1283 | Evas_Coord cox, coy, cow, coh; | ||
1284 | |||
1285 | cox = obj->cur.cache.clip.x; | ||
1286 | coy = obj->cur.cache.clip.y; | ||
1287 | cow = obj->cur.cache.clip.w; | ||
1288 | coh = obj->cur.cache.clip.h; | ||
1289 | if ((obj->cur.map) && (obj->cur.usemap)) | ||
1290 | { | ||
1291 | Evas_Object *oo; | ||
1292 | |||
1293 | oo = obj; | ||
1294 | while (oo->cur.clipper) | ||
1295 | { | ||
1296 | if ((oo->cur.clipper->cur.map_parent | ||
1297 | != oo->cur.map_parent) && | ||
1298 | (!((oo->cur.map) && (oo->cur.usemap)))) | ||
1299 | break; | ||
1300 | RECTS_CLIP_TO_RECT(cox, coy, cow, coh, | ||
1301 | oo->cur.geometry.x, | ||
1302 | oo->cur.geometry.y, | ||
1303 | oo->cur.geometry.w, | ||
1304 | oo->cur.geometry.h); | ||
1305 | oo = oo->cur.clipper; | ||
1306 | } | ||
1307 | } | ||
1308 | e->engine.func->context_cutout_add | ||
1309 | (e->engine.data.output, e->engine.data.context, | ||
1310 | cox + off_x, coy + off_y, cow, coh); | ||
1311 | } | ||
1312 | else | ||
1313 | { | ||
1314 | if (obj->func->get_opaque_rect) | ||
1315 | { | ||
1316 | Evas_Coord obx, oby, obw, obh; | ||
1317 | |||
1318 | obj->func->get_opaque_rect(obj, &obx, &oby, &obw, &obh); | ||
1319 | if ((obw > 0) && (obh > 0)) | ||
1320 | { | ||
1321 | obx += off_x; | ||
1322 | oby += off_y; | ||
1323 | RECTS_CLIP_TO_RECT(obx, oby, obw, obh, | ||
1324 | obj->cur.cache.clip.x + off_x, | ||
1325 | obj->cur.cache.clip.y + off_y, | ||
1326 | obj->cur.cache.clip.w, | ||
1327 | obj->cur.cache.clip.h); | ||
1328 | e->engine.func->context_cutout_add | ||
1329 | (e->engine.data.output, e->engine.data.context, | ||
1330 | obx, oby, obw, obh); | ||
1331 | } | ||
1332 | } | ||
1333 | } | ||
1334 | } | ||
1335 | |||
1336 | static Eina_List * | ||
1337 | evas_render_updates_internal(Evas *e, | ||
1338 | unsigned char make_updates, | ||
1339 | unsigned char do_draw) | ||
1340 | { | ||
1341 | Evas_Object *obj; | ||
1342 | Eina_List *updates = NULL; | ||
1343 | Eina_List *ll; | ||
1344 | void *surface; | ||
1345 | Eina_Bool clean_them = EINA_FALSE; | ||
1346 | Eina_Bool alpha; | ||
1347 | Eina_Rectangle *r; | ||
1348 | int ux, uy, uw, uh; | ||
1349 | int cx, cy, cw, ch; | ||
1350 | unsigned int i, j; | ||
1351 | int haveup = 0; | ||
1352 | int redraw_all = 0; | ||
1353 | |||
1354 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1355 | return NULL; | ||
1356 | MAGIC_CHECK_END(); | ||
1357 | if (!e->changed) return NULL; | ||
1358 | |||
1359 | evas_call_smarts_calculate(e); | ||
1360 | |||
1361 | RD("[--- RENDER EVAS (size: %ix%i)\n", e->viewport.w, e->viewport.h); | ||
1362 | |||
1363 | /* Check if the modified object mean recalculating every thing */ | ||
1364 | if (!e->invalidate) | ||
1365 | _evas_render_check_pending_objects(&e->pending_objects, e); | ||
1366 | |||
1367 | /* phase 1. add extra updates for changed objects */ | ||
1368 | if (e->invalidate || e->render_objects.count <= 0) | ||
1369 | clean_them = _evas_render_phase1_process(e, | ||
1370 | &e->active_objects, | ||
1371 | &e->restack_objects, | ||
1372 | &e->delete_objects, | ||
1373 | &e->render_objects, | ||
1374 | &redraw_all); | ||
1375 | |||
1376 | /* phase 1.5. check if the video should be inlined or stay in their overlay */ | ||
1377 | alpha = e->engine.func->canvas_alpha_get(e->engine.data.output, | ||
1378 | e->engine.data.context); | ||
1379 | |||
1380 | EINA_LIST_FOREACH(e->video_objects, ll, obj) | ||
1381 | { | ||
1382 | /* we need the surface to be transparent to display the underlying overlay */ | ||
1383 | if (alpha && _evas_render_can_use_overlay(e, obj)) | ||
1384 | _evas_object_image_video_overlay_show(obj); | ||
1385 | else | ||
1386 | _evas_object_image_video_overlay_hide(obj); | ||
1387 | } | ||
1388 | |||
1389 | |||
1390 | /* phase 1.8. pre render for proxy */ | ||
1391 | _evas_render_phase1_direct(e, &e->active_objects, &e->restack_objects, | ||
1392 | &e->delete_objects, &e->render_objects); | ||
1393 | |||
1394 | /* phase 2. force updates for restacks */ | ||
1395 | for (i = 0; i < e->restack_objects.count; ++i) | ||
1396 | { | ||
1397 | obj = eina_array_data_get(&e->restack_objects, i); | ||
1398 | obj->func->render_pre(obj); | ||
1399 | _evas_render_prev_cur_clip_cache_add(e, obj); | ||
1400 | } | ||
1401 | eina_array_clean(&e->restack_objects); | ||
1402 | /* phase 3. add exposes */ | ||
1403 | EINA_LIST_FREE(e->damages, r) | ||
1404 | { | ||
1405 | e->engine.func->output_redraws_rect_add(e->engine.data.output, | ||
1406 | r->x, r->y, r->w, r->h); | ||
1407 | eina_rectangle_free(r); | ||
1408 | } | ||
1409 | /* phase 4. output & viewport changes */ | ||
1410 | if (e->viewport.changed) | ||
1411 | { | ||
1412 | e->engine.func->output_redraws_rect_add(e->engine.data.output, | ||
1413 | 0, 0, | ||
1414 | e->output.w, e->output.h); | ||
1415 | } | ||
1416 | if (e->output.changed) | ||
1417 | { | ||
1418 | e->engine.func->output_resize(e->engine.data.output, | ||
1419 | e->output.w, e->output.h); | ||
1420 | e->engine.func->output_redraws_rect_add(e->engine.data.output, | ||
1421 | 0, 0, | ||
1422 | e->output.w, e->output.h); | ||
1423 | } | ||
1424 | if ((e->output.w != e->viewport.w) || (e->output.h != e->viewport.h)) | ||
1425 | { | ||
1426 | ERR("viewport size != output size!"); | ||
1427 | } | ||
1428 | if (redraw_all) | ||
1429 | { | ||
1430 | e->engine.func->output_redraws_rect_add(e->engine.data.output, | ||
1431 | 0, 0, | ||
1432 | e->output.w, e->output.h); | ||
1433 | } | ||
1434 | /* phase 5. add obscures */ | ||
1435 | EINA_LIST_FOREACH(e->obscures, ll, r) | ||
1436 | { | ||
1437 | e->engine.func->output_redraws_rect_del(e->engine.data.output, | ||
1438 | r->x, r->y, r->w, r->h); | ||
1439 | } | ||
1440 | /* build obscure objects list of active objects that obscure */ | ||
1441 | for (i = 0; i < e->active_objects.count; ++i) | ||
1442 | { | ||
1443 | obj = eina_array_data_get(&e->active_objects, i); | ||
1444 | if (UNLIKELY((evas_object_is_opaque(obj) || | ||
1445 | ((obj->func->has_opaque_rect) && | ||
1446 | (obj->func->has_opaque_rect(obj)))) && | ||
1447 | evas_object_is_visible(obj) && | ||
1448 | (!obj->clip.clipees) && | ||
1449 | (obj->cur.visible) && | ||
1450 | (!obj->delete_me) && | ||
1451 | (obj->cur.cache.clip.visible) && | ||
1452 | (!obj->smart.smart))) | ||
1453 | /* obscuring_objects = eina_list_append(obscuring_objects, obj); */ | ||
1454 | eina_array_push(&e->obscuring_objects, obj); | ||
1455 | } | ||
1456 | |||
1457 | /* save this list */ | ||
1458 | /* obscuring_objects_orig = obscuring_objects; */ | ||
1459 | /* obscuring_objects = NULL; */ | ||
1460 | /* phase 6. go thru each update rect and render objects in it*/ | ||
1461 | if (do_draw) | ||
1462 | { | ||
1463 | unsigned int offset = 0; | ||
1464 | |||
1465 | while ((surface = | ||
1466 | e->engine.func->output_redraws_next_update_get | ||
1467 | (e->engine.data.output, | ||
1468 | &ux, &uy, &uw, &uh, | ||
1469 | &cx, &cy, &cw, &ch))) | ||
1470 | { | ||
1471 | int off_x, off_y; | ||
1472 | |||
1473 | RD(" [--- UPDATE %i %i %ix%i\n", ux, uy, uw, uh); | ||
1474 | if (make_updates) | ||
1475 | { | ||
1476 | Eina_Rectangle *rect; | ||
1477 | |||
1478 | NEW_RECT(rect, ux, uy, uw, uh); | ||
1479 | if (rect) | ||
1480 | updates = eina_list_append(updates, rect); | ||
1481 | } | ||
1482 | haveup = 1; | ||
1483 | off_x = cx - ux; | ||
1484 | off_y = cy - uy; | ||
1485 | /* build obscuring objects list (in order from bottom to top) */ | ||
1486 | for (i = 0; i < e->obscuring_objects.count; ++i) | ||
1487 | { | ||
1488 | obj = (Evas_Object *)eina_array_data_get | ||
1489 | (&e->obscuring_objects, i); | ||
1490 | if (evas_object_is_in_output_rect(obj, ux, uy, uw, uh)) | ||
1491 | { | ||
1492 | eina_array_push(&e->temporary_objects, obj); | ||
1493 | |||
1494 | /* reset the background of the area if needed (using cutout and engine alpha flag to help) */ | ||
1495 | if (alpha) | ||
1496 | _evas_render_cutout_add(e, obj, off_x, off_y); | ||
1497 | } | ||
1498 | } | ||
1499 | if (alpha) | ||
1500 | { | ||
1501 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1502 | e->engine.data.context, | ||
1503 | ux + off_x, uy + off_y, uw, uh); | ||
1504 | e->engine.func->context_color_set(e->engine.data.output, | ||
1505 | e->engine.data.context, | ||
1506 | 0, 0, 0, 0); | ||
1507 | e->engine.func->context_multiplier_unset | ||
1508 | (e->engine.data.output, e->engine.data.context); | ||
1509 | e->engine.func->context_render_op_set(e->engine.data.output, | ||
1510 | e->engine.data.context, | ||
1511 | EVAS_RENDER_COPY); | ||
1512 | e->engine.func->rectangle_draw(e->engine.data.output, | ||
1513 | e->engine.data.context, | ||
1514 | surface, | ||
1515 | cx, cy, cw, ch); | ||
1516 | e->engine.func->context_cutout_clear(e->engine.data.output, | ||
1517 | e->engine.data.context); | ||
1518 | e->engine.func->context_clip_unset(e->engine.data.output, | ||
1519 | e->engine.data.context); | ||
1520 | } | ||
1521 | /* render all object that intersect with rect */ | ||
1522 | for (i = 0; i < e->active_objects.count; ++i) | ||
1523 | { | ||
1524 | obj = eina_array_data_get(&e->active_objects, i); | ||
1525 | |||
1526 | /* if it's in our outpout rect and it doesn't clip anything */ | ||
1527 | RD(" OBJ: [%p] '%s' %i %i %ix%i\n", obj, obj->type, obj->cur.geometry.x, obj->cur.geometry.y, obj->cur.geometry.w, obj->cur.geometry.h); | ||
1528 | if ((evas_object_is_in_output_rect(obj, ux, uy, uw, uh) || | ||
1529 | (obj->smart.smart)) && | ||
1530 | (!obj->clip.clipees) && | ||
1531 | (obj->cur.visible) && | ||
1532 | (!obj->delete_me) && | ||
1533 | (obj->cur.cache.clip.visible) && | ||
1534 | // (!obj->smart.smart) && | ||
1535 | ((obj->cur.color.a > 0 || obj->cur.render_op != EVAS_RENDER_BLEND))) | ||
1536 | { | ||
1537 | int x, y, w, h; | ||
1538 | |||
1539 | RD(" DRAW (vis: %i, a: %i, clipees: %p\n", obj->cur.visible, obj->cur.color.a, obj->clip.clipees); | ||
1540 | if ((e->temporary_objects.count > offset) && | ||
1541 | (eina_array_data_get(&e->temporary_objects, offset) == obj)) | ||
1542 | offset++; | ||
1543 | x = cx; y = cy; w = cw; h = ch; | ||
1544 | if (((w > 0) && (h > 0)) || (obj->smart.smart)) | ||
1545 | { | ||
1546 | if (!obj->smart.smart) | ||
1547 | { | ||
1548 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
1549 | obj->cur.cache.clip.x + off_x, | ||
1550 | obj->cur.cache.clip.y + off_y, | ||
1551 | obj->cur.cache.clip.w, | ||
1552 | obj->cur.cache.clip.h); | ||
1553 | } | ||
1554 | if (obj->cur.mask) | ||
1555 | e->engine.func->context_mask_set(e->engine.data.output, | ||
1556 | e->engine.data.context, | ||
1557 | obj->cur.mask->func->engine_data_get(obj->cur.mask), | ||
1558 | obj->cur.mask->cur.geometry.x + off_x, | ||
1559 | obj->cur.mask->cur.geometry.y + off_y, | ||
1560 | obj->cur.mask->cur.geometry.w, | ||
1561 | obj->cur.mask->cur.geometry.h); | ||
1562 | else | ||
1563 | e->engine.func->context_mask_unset(e->engine.data.output, | ||
1564 | e->engine.data.context); | ||
1565 | if (obj->cur.clipper) | ||
1566 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1567 | e->engine.data.context, | ||
1568 | x, y, w, h); | ||
1569 | else | ||
1570 | e->engine.func->context_clip_unset(e->engine.data.output, | ||
1571 | e->engine.data.context); | ||
1572 | #if 1 /* FIXME: this can slow things down... figure out optimum... coverage */ | ||
1573 | for (j = offset; j < e->temporary_objects.count; ++j) | ||
1574 | { | ||
1575 | Evas_Object *obj2; | ||
1576 | |||
1577 | obj2 = (Evas_Object *)eina_array_data_get | ||
1578 | (&e->temporary_objects, j); | ||
1579 | _evas_render_cutout_add(e, obj2, off_x, off_y); | ||
1580 | } | ||
1581 | #endif | ||
1582 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1583 | e->engine.data.context, | ||
1584 | x, y, w, h); | ||
1585 | clean_them |= evas_render_mapped(e, obj, e->engine.data.context, | ||
1586 | surface, off_x, off_y, 0, | ||
1587 | cx, cy, cw, ch | ||
1588 | #ifdef REND_DGB | ||
1589 | , 1 | ||
1590 | #endif | ||
1591 | ); | ||
1592 | e->engine.func->context_cutout_clear(e->engine.data.output, | ||
1593 | e->engine.data.context); | ||
1594 | } | ||
1595 | } | ||
1596 | } | ||
1597 | /* punch rect out */ | ||
1598 | e->engine.func->output_redraws_next_update_push(e->engine.data.output, | ||
1599 | surface, | ||
1600 | ux, uy, uw, uh); | ||
1601 | /* free obscuring objects list */ | ||
1602 | eina_array_clean(&e->temporary_objects); | ||
1603 | RD(" ---]\n"); | ||
1604 | } | ||
1605 | /* flush redraws */ | ||
1606 | if (haveup) | ||
1607 | { | ||
1608 | evas_event_callback_call(e, EVAS_CALLBACK_RENDER_FLUSH_PRE, NULL); | ||
1609 | e->engine.func->output_flush(e->engine.data.output); | ||
1610 | evas_event_callback_call(e, EVAS_CALLBACK_RENDER_FLUSH_POST, NULL); | ||
1611 | } | ||
1612 | } | ||
1613 | /* clear redraws */ | ||
1614 | e->engine.func->output_redraws_clear(e->engine.data.output); | ||
1615 | /* and do a post render pass */ | ||
1616 | for (i = 0; i < e->active_objects.count; ++i) | ||
1617 | { | ||
1618 | obj = eina_array_data_get(&e->active_objects, i); | ||
1619 | obj->pre_render_done = 0; | ||
1620 | RD(" OBJ [%p] post... %i %i\n", obj, obj->changed, do_draw); | ||
1621 | if ((obj->changed) && (do_draw)) | ||
1622 | { | ||
1623 | RD(" OBJ [%p] post... func1\n", obj); | ||
1624 | obj->func->render_post(obj); | ||
1625 | obj->restack = 0; | ||
1626 | obj->changed = 0; | ||
1627 | obj->changed_move_only = 0; | ||
1628 | obj->changed_nomove = 0; | ||
1629 | obj->changed_move = 0; | ||
1630 | } | ||
1631 | else if ((obj->cur.map != obj->prev.map) || | ||
1632 | (obj->cur.usemap != obj->prev.usemap)) | ||
1633 | { | ||
1634 | RD(" OBJ [%p] post... func2\n", obj); | ||
1635 | obj->func->render_post(obj); | ||
1636 | obj->restack = 0; | ||
1637 | obj->changed = 0; | ||
1638 | obj->changed_move_only = 0; | ||
1639 | obj->changed_nomove = 0; | ||
1640 | obj->changed_move = 0; | ||
1641 | } | ||
1642 | /* moved to other pre-process phase 1 | ||
1643 | if (obj->delete_me == 2) | ||
1644 | { | ||
1645 | delete_objects = eina_list_append(delete_objects, obj); | ||
1646 | } | ||
1647 | else if (obj->delete_me != 0) obj->delete_me++; | ||
1648 | */ | ||
1649 | } | ||
1650 | /* free our obscuring object list */ | ||
1651 | eina_array_clean(&e->obscuring_objects); | ||
1652 | |||
1653 | /* If some object are still marked as changed, do not remove | ||
1654 | them from the pending list. */ | ||
1655 | eina_array_remove(&e->pending_objects, pending_change, NULL); | ||
1656 | |||
1657 | for (i = 0; i < e->render_objects.count; ++i) | ||
1658 | { | ||
1659 | obj = eina_array_data_get(&e->render_objects, i); | ||
1660 | obj->pre_render_done = 0; | ||
1661 | } | ||
1662 | |||
1663 | /* delete all objects flagged for deletion now */ | ||
1664 | for (i = 0; i < e->delete_objects.count; ++i) | ||
1665 | { | ||
1666 | obj = eina_array_data_get(&e->delete_objects, i); | ||
1667 | evas_object_free(obj, 1); | ||
1668 | } | ||
1669 | eina_array_clean(&e->delete_objects); | ||
1670 | |||
1671 | e->changed = 0; | ||
1672 | e->viewport.changed = 0; | ||
1673 | e->output.changed = 0; | ||
1674 | e->invalidate = 0; | ||
1675 | |||
1676 | /* If their are some object to restack or some object to delete, | ||
1677 | * it's useless to keep the render object list around. */ | ||
1678 | if (clean_them) | ||
1679 | { | ||
1680 | eina_array_clean(&e->active_objects); | ||
1681 | eina_array_clean(&e->render_objects); | ||
1682 | eina_array_clean(&e->restack_objects); | ||
1683 | eina_array_clean(&e->delete_objects); | ||
1684 | eina_array_clean(&e->obscuring_objects); | ||
1685 | e->invalidate = 1; | ||
1686 | } | ||
1687 | |||
1688 | evas_module_clean(); | ||
1689 | |||
1690 | RD("---]\n"); | ||
1691 | |||
1692 | return updates; | ||
1693 | } | ||
1694 | |||
1695 | EAPI void | ||
1696 | evas_render_updates_free(Eina_List *updates) | ||
1697 | { | ||
1698 | Eina_Rectangle *r; | ||
1699 | |||
1700 | EINA_LIST_FREE(updates, r) | ||
1701 | eina_rectangle_free(r); | ||
1702 | } | ||
1703 | |||
1704 | EAPI Eina_List * | ||
1705 | evas_render_updates(Evas *e) | ||
1706 | { | ||
1707 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1708 | return NULL; | ||
1709 | MAGIC_CHECK_END(); | ||
1710 | |||
1711 | #ifdef EVAS_FRAME_QUEUING | ||
1712 | evas_common_frameq_flush_ready (); | ||
1713 | #endif | ||
1714 | |||
1715 | if (!e->changed) return NULL; | ||
1716 | return evas_render_updates_internal(e, 1, 1); | ||
1717 | } | ||
1718 | |||
1719 | EAPI void | ||
1720 | evas_render(Evas *e) | ||
1721 | { | ||
1722 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1723 | return; | ||
1724 | MAGIC_CHECK_END(); | ||
1725 | |||
1726 | #ifdef EVAS_FRAME_QUEUING | ||
1727 | evas_common_frameq_flush_ready (); | ||
1728 | #endif | ||
1729 | |||
1730 | if (!e->changed) return; | ||
1731 | evas_render_updates_internal(e, 0, 1); | ||
1732 | } | ||
1733 | |||
1734 | EAPI void | ||
1735 | evas_norender(Evas *e) | ||
1736 | { | ||
1737 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1738 | return; | ||
1739 | MAGIC_CHECK_END(); | ||
1740 | |||
1741 | // if (!e->changed) return; | ||
1742 | evas_render_updates_internal(e, 0, 0); | ||
1743 | } | ||
1744 | |||
1745 | EAPI void | ||
1746 | evas_render_idle_flush(Evas *e) | ||
1747 | { | ||
1748 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1749 | return; | ||
1750 | MAGIC_CHECK_END(); | ||
1751 | |||
1752 | evas_fonts_zero_presure(e); | ||
1753 | |||
1754 | if ((e->engine.func) && (e->engine.func->output_idle_flush) && | ||
1755 | (e->engine.data.output)) | ||
1756 | e->engine.func->output_idle_flush(e->engine.data.output); | ||
1757 | |||
1758 | eina_array_flush(&e->delete_objects); | ||
1759 | eina_array_flush(&e->active_objects); | ||
1760 | eina_array_flush(&e->restack_objects); | ||
1761 | eina_array_flush(&e->render_objects); | ||
1762 | eina_array_flush(&e->clip_changes); | ||
1763 | |||
1764 | e->invalidate = 1; | ||
1765 | } | ||
1766 | |||
1767 | EAPI void | ||
1768 | evas_sync(Evas *e) | ||
1769 | { | ||
1770 | #ifdef EVAS_FRAME_QUEUING | ||
1771 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1772 | return; | ||
1773 | MAGIC_CHECK_END(); | ||
1774 | |||
1775 | evas_common_frameq_flush(); | ||
1776 | #else | ||
1777 | (void) e; | ||
1778 | #endif | ||
1779 | } | ||
1780 | |||
1781 | static void | ||
1782 | _evas_render_dump_map_surfaces(Evas_Object *obj) | ||
1783 | { | ||
1784 | if ((obj->cur.map) && obj->cur.map->surface) | ||
1785 | { | ||
1786 | obj->layer->evas->engine.func->image_map_surface_free | ||
1787 | (obj->layer->evas->engine.data.output, obj->cur.map->surface); | ||
1788 | obj->cur.map->surface = NULL; | ||
1789 | } | ||
1790 | |||
1791 | if (obj->smart.smart) | ||
1792 | { | ||
1793 | Evas_Object *obj2; | ||
1794 | |||
1795 | EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2) | ||
1796 | _evas_render_dump_map_surfaces(obj2); | ||
1797 | } | ||
1798 | } | ||
1799 | |||
1800 | EAPI void | ||
1801 | evas_render_dump(Evas *e) | ||
1802 | { | ||
1803 | Evas_Layer *lay; | ||
1804 | |||
1805 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1806 | return; | ||
1807 | MAGIC_CHECK_END(); | ||
1808 | |||
1809 | EINA_INLIST_FOREACH(e->layers, lay) | ||
1810 | { | ||
1811 | Evas_Object *obj; | ||
1812 | |||
1813 | EINA_INLIST_FOREACH(lay->objects, obj) | ||
1814 | { | ||
1815 | if ((obj->type) && (!strcmp(obj->type, "image"))) | ||
1816 | evas_object_inform_call_image_unloaded(obj); | ||
1817 | _evas_render_dump_map_surfaces(obj); | ||
1818 | } | ||
1819 | } | ||
1820 | if ((e->engine.func) && (e->engine.func->output_dump) && | ||
1821 | (e->engine.data.output)) | ||
1822 | e->engine.func->output_dump(e->engine.data.output); | ||
1823 | } | ||
1824 | |||
1825 | void | ||
1826 | evas_render_invalidate(Evas *e) | ||
1827 | { | ||
1828 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1829 | return; | ||
1830 | MAGIC_CHECK_END(); | ||
1831 | |||
1832 | eina_array_clean(&e->active_objects); | ||
1833 | eina_array_clean(&e->render_objects); | ||
1834 | |||
1835 | eina_array_flush(&e->restack_objects); | ||
1836 | eina_array_flush(&e->delete_objects); | ||
1837 | |||
1838 | e->invalidate = 1; | ||
1839 | } | ||
1840 | |||
1841 | void | ||
1842 | evas_render_object_recalc(Evas_Object *obj) | ||
1843 | { | ||
1844 | MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); | ||
1845 | return; | ||
1846 | MAGIC_CHECK_END(); | ||
1847 | |||
1848 | #ifndef EVAS_FRAME_QUEUING | ||
1849 | if ((!obj->changed) && (obj->delete_me < 2)) | ||
1850 | #else | ||
1851 | if ((!obj->changed)) | ||
1852 | #endif | ||
1853 | { | ||
1854 | Evas *e; | ||
1855 | |||
1856 | e = obj->layer->evas; | ||
1857 | if ((!e) || (e->cleanup)) return; | ||
1858 | #ifdef EVAS_FRAME_QUEUING | ||
1859 | if (obj->delete_me >= evas_common_frameq_get_frameq_sz() + 2) return; | ||
1860 | #endif | ||
1861 | eina_array_push(&e->pending_objects, obj); | ||
1862 | obj->changed = 1; | ||
1863 | } | ||
1864 | } | ||
1865 | |||
1866 | /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/ | ||