diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/evas/src/lib/canvas/evas_render.c | 1914 |
1 files changed, 0 insertions, 1914 deletions
diff --git a/libraries/evas/src/lib/canvas/evas_render.c b/libraries/evas/src/lib/canvas/evas_render.c deleted file mode 100644 index 32ce988..0000000 --- a/libraries/evas/src/lib/canvas/evas_render.c +++ /dev/null | |||
@@ -1,1914 +0,0 @@ | |||
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 | obj->changed_map = 0; | ||
616 | obj->changed_pchange = 0; | ||
617 | } | ||
618 | return obj->changed ? EINA_TRUE : EINA_FALSE; | ||
619 | } | ||
620 | /* | ||
621 | static void | ||
622 | unchange(Evas_Object *obj) | ||
623 | { | ||
624 | Evas_Object *obj2; | ||
625 | |||
626 | if (!obj->changed) return; | ||
627 | obj->changed = 0; | ||
628 | obj->changed_move_only = 0; | ||
629 | obj->changed_nomove = 0; | ||
630 | obj->changed_move = 0; | ||
631 | EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2) | ||
632 | { | ||
633 | unchange(obj2); | ||
634 | } | ||
635 | } | ||
636 | |||
637 | static int | ||
638 | chlist(Evas_Object *obj, int i) | ||
639 | { | ||
640 | Evas_Object *obj2; | ||
641 | int j; | ||
642 | int ret = 0; | ||
643 | |||
644 | if (!obj->changed) return 0; | ||
645 | for (j = 0; j < i; j++) printf(" "); | ||
646 | printf("ch2 %p %s %i [%i %i %ix%i] v %i/%i [r%i] %p\n", obj, | ||
647 | obj->type, | ||
648 | obj->changed_move_only, | ||
649 | obj->cur.geometry.x, | ||
650 | obj->cur.geometry.y, | ||
651 | obj->cur.geometry.w, | ||
652 | obj->cur.geometry.h, | ||
653 | obj->cur.visible, | ||
654 | obj->prev.visible, | ||
655 | obj->restack, | ||
656 | obj->clip.clipees); | ||
657 | EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2) | ||
658 | { | ||
659 | if (obj2->changed) | ||
660 | ret |= chlist(obj2, i + 1); | ||
661 | } | ||
662 | } | ||
663 | */ | ||
664 | static Eina_Bool | ||
665 | _evas_render_can_use_overlay(Evas *e, Evas_Object *obj) | ||
666 | { | ||
667 | Eina_Rectangle *r; | ||
668 | Evas_Object *tmp; | ||
669 | Eina_List *alphas = NULL; | ||
670 | Eina_List *opaques = NULL; | ||
671 | Evas_Object *video_parent = NULL; | ||
672 | Eina_Rectangle zone; | ||
673 | Evas_Coord xc1, yc1, xc2, yc2; | ||
674 | unsigned int i; | ||
675 | Eina_Bool nooverlay; | ||
676 | |||
677 | video_parent = _evas_object_image_video_parent_get(obj); | ||
678 | |||
679 | /* Check if any one is the stack make this object mapped */ | ||
680 | tmp = obj; | ||
681 | while (tmp && !_evas_render_has_map(tmp)) | ||
682 | tmp = tmp->smart.parent; | ||
683 | |||
684 | if (tmp && _evas_render_has_map(tmp)) return EINA_FALSE; /* we are mapped, we can't be an overlay */ | ||
685 | |||
686 | if (!evas_object_is_visible(obj)) return EINA_FALSE; /* no need to update the overlay if it's not visible */ | ||
687 | |||
688 | /* If any recoloring of the surface is needed, n overlay to */ | ||
689 | if ((obj->cur.cache.clip.r != 255) || | ||
690 | (obj->cur.cache.clip.g != 255) || | ||
691 | (obj->cur.cache.clip.b != 255) || | ||
692 | (obj->cur.cache.clip.a != 255)) | ||
693 | return EINA_FALSE; | ||
694 | |||
695 | /* Check presence of transparent object on top of the video object */ | ||
696 | EINA_RECTANGLE_SET(&zone, | ||
697 | obj->cur.cache.clip.x, | ||
698 | obj->cur.cache.clip.y, | ||
699 | obj->cur.cache.clip.w, | ||
700 | obj->cur.cache.clip.h); | ||
701 | |||
702 | for (i = e->active_objects.count - 1; i > 0; i--) | ||
703 | { | ||
704 | Eina_Rectangle self; | ||
705 | Eina_Rectangle *match; | ||
706 | Evas_Object *current; | ||
707 | Eina_List *l; | ||
708 | int xm1, ym1, xm2, ym2; | ||
709 | |||
710 | current = eina_array_data_get(&e->active_objects, i); | ||
711 | |||
712 | /* Did we find the video object in the stack ? */ | ||
713 | if (current == video_parent || current == obj) | ||
714 | break; | ||
715 | |||
716 | EINA_RECTANGLE_SET(&self, | ||
717 | current->cur.cache.clip.x, | ||
718 | current->cur.cache.clip.y, | ||
719 | current->cur.cache.clip.w, | ||
720 | current->cur.cache.clip.h); | ||
721 | |||
722 | /* This doesn't cover the area of the video object, so don't bother with that object */ | ||
723 | if (!eina_rectangles_intersect(&zone, &self)) | ||
724 | continue ; | ||
725 | |||
726 | xc1 = current->cur.cache.clip.x; | ||
727 | yc1 = current->cur.cache.clip.y; | ||
728 | xc2 = current->cur.cache.clip.x + current->cur.cache.clip.w; | ||
729 | yc2 = current->cur.cache.clip.y + current->cur.cache.clip.h; | ||
730 | |||
731 | if (evas_object_is_visible(current) && | ||
732 | (!current->clip.clipees) && | ||
733 | (current->cur.visible) && | ||
734 | (!current->delete_me) && | ||
735 | (current->cur.cache.clip.visible) && | ||
736 | (!current->smart.smart)) | ||
737 | { | ||
738 | Eina_Bool included = EINA_FALSE; | ||
739 | |||
740 | if (evas_object_is_opaque(current) || | ||
741 | ((current->func->has_opaque_rect) && | ||
742 | (current->func->has_opaque_rect(current)))) | ||
743 | { | ||
744 | /* The object is opaque */ | ||
745 | |||
746 | /* Check if the opaque object is inside another opaque object */ | ||
747 | EINA_LIST_FOREACH(opaques, l, match) | ||
748 | { | ||
749 | xm1 = match->x; | ||
750 | ym1 = match->y; | ||
751 | xm2 = match->x + match->w; | ||
752 | ym2 = match->y + match->h; | ||
753 | |||
754 | /* Both object are included */ | ||
755 | if (xc1 >= xm1 && yc1 >= ym1 && xc2 <= xm2 && yc2 <= ym2) | ||
756 | { | ||
757 | included = EINA_TRUE; | ||
758 | break; | ||
759 | } | ||
760 | } | ||
761 | |||
762 | /* Not included yet */ | ||
763 | if (!included) | ||
764 | { | ||
765 | Eina_List *ln; | ||
766 | Evas_Coord xn2, yn2; | ||
767 | |||
768 | r = eina_rectangle_new(current->cur.cache.clip.x, current->cur.cache.clip.y, | ||
769 | current->cur.cache.clip.w, current->cur.cache.clip.h); | ||
770 | |||
771 | opaques = eina_list_append(opaques, r); | ||
772 | |||
773 | xn2 = r->x + r->w; | ||
774 | yn2 = r->y + r->h; | ||
775 | |||
776 | /* Remove all the transparent object that are covered by the new opaque object */ | ||
777 | EINA_LIST_FOREACH_SAFE(alphas, l, ln, match) | ||
778 | { | ||
779 | xm1 = match->x; | ||
780 | ym1 = match->y; | ||
781 | xm2 = match->x + match->w; | ||
782 | ym2 = match->y + match->h; | ||
783 | |||
784 | if (xm1 >= r->x && ym1 >= r->y && xm2 <= xn2 && ym2 <= yn2) | ||
785 | { | ||
786 | /* The new rectangle is over some transparent object, | ||
787 | so remove the transparent object */ | ||
788 | alphas = eina_list_remove_list(alphas, l); | ||
789 | } | ||
790 | } | ||
791 | } | ||
792 | } | ||
793 | else | ||
794 | { | ||
795 | /* The object has some transparency */ | ||
796 | |||
797 | /* Check if the transparent object is inside any other transparent object */ | ||
798 | EINA_LIST_FOREACH(alphas, l, match) | ||
799 | { | ||
800 | xm1 = match->x; | ||
801 | ym1 = match->y; | ||
802 | xm2 = match->x + match->w; | ||
803 | ym2 = match->y + match->h; | ||
804 | |||
805 | /* Both object are included */ | ||
806 | if (xc1 >= xm1 && yc1 >= ym1 && xc2 <= xm2 && yc2 <= ym2) | ||
807 | { | ||
808 | included = EINA_TRUE; | ||
809 | break; | ||
810 | } | ||
811 | } | ||
812 | |||
813 | /* If not check if it is inside any opaque one */ | ||
814 | if (!included) | ||
815 | { | ||
816 | EINA_LIST_FOREACH(opaques, l, match) | ||
817 | { | ||
818 | xm1 = match->x; | ||
819 | ym1 = match->y; | ||
820 | xm2 = match->x + match->w; | ||
821 | ym2 = match->y + match->h; | ||
822 | |||
823 | /* Both object are included */ | ||
824 | if (xc1 >= xm1 && yc1 >= ym1 && xc2 <= xm2 && yc2 <= ym2) | ||
825 | { | ||
826 | included = EINA_TRUE; | ||
827 | break; | ||
828 | } | ||
829 | } | ||
830 | } | ||
831 | |||
832 | /* No inclusion at all, so add it */ | ||
833 | if (!included) | ||
834 | { | ||
835 | r = eina_rectangle_new(current->cur.cache.clip.x, current->cur.cache.clip.y, | ||
836 | current->cur.cache.clip.w, current->cur.cache.clip.h); | ||
837 | |||
838 | alphas = eina_list_append(alphas, r); | ||
839 | } | ||
840 | } | ||
841 | } | ||
842 | } | ||
843 | |||
844 | /* If there is any pending transparent object, then no overlay */ | ||
845 | nooverlay = !!eina_list_count(alphas); | ||
846 | |||
847 | EINA_LIST_FREE(alphas, r) | ||
848 | eina_rectangle_free(r); | ||
849 | EINA_LIST_FREE(opaques, r) | ||
850 | eina_rectangle_free(r); | ||
851 | |||
852 | if (nooverlay) | ||
853 | return EINA_FALSE; | ||
854 | |||
855 | return EINA_TRUE; | ||
856 | } | ||
857 | |||
858 | Eina_Bool | ||
859 | evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, | ||
860 | int off_x, int off_y, int mapped, | ||
861 | int ecx, int ecy, int ecw, int ech | ||
862 | #ifdef REND_DGB | ||
863 | , int level | ||
864 | #endif | ||
865 | ) | ||
866 | { | ||
867 | void *ctx; | ||
868 | Evas_Object *obj2; | ||
869 | Eina_Bool clean_them = EINA_FALSE; | ||
870 | |||
871 | evas_object_clip_recalc(obj); | ||
872 | RDI(level); | ||
873 | RD(" { evas_render_mapped(%p, %p, %p, %p, %i, %i, %i, %i)\n", e, obj, context, surface, off_x, off_y, mapped, level); | ||
874 | if (mapped) | ||
875 | { | ||
876 | if ((!evas_object_is_visible(obj)) || (obj->clip.clipees) || | ||
877 | (obj->cur.have_clipees)) | ||
878 | { | ||
879 | RDI(level); | ||
880 | RD(" }\n"); | ||
881 | return clean_them; | ||
882 | } | ||
883 | } | ||
884 | else if (!(((evas_object_is_active(obj) && (!obj->clip.clipees) && | ||
885 | (_evas_render_can_render(obj)))) | ||
886 | )) | ||
887 | { | ||
888 | RDI(level); | ||
889 | RD(" }\n"); | ||
890 | return clean_them; | ||
891 | } | ||
892 | |||
893 | // set render_pre - for child objs that may not have gotten it. | ||
894 | obj->pre_render_done = 1; | ||
895 | RD(" Hasmap: %p (%d) %p %d -> %d\n",obj->func->can_map, | ||
896 | obj->func->can_map ? obj->func->can_map(obj): -1, | ||
897 | obj->cur.map, obj->cur.usemap, | ||
898 | _evas_render_has_map(obj)); | ||
899 | if (_evas_render_has_map(obj)) | ||
900 | { | ||
901 | const Evas_Map_Point *p, *p_end; | ||
902 | RGBA_Map_Point pts[4], *pt; | ||
903 | int sw, sh; | ||
904 | int changed = 0, rendered = 0; | ||
905 | |||
906 | clean_them = EINA_TRUE; | ||
907 | |||
908 | sw = obj->cur.geometry.w; | ||
909 | sh = obj->cur.geometry.h; | ||
910 | RDI(level); | ||
911 | RD(" mapped obj: %ix%i\n", sw, sh); | ||
912 | if ((sw <= 0) || (sh <= 0)) | ||
913 | { | ||
914 | RDI(level); | ||
915 | RD(" }\n"); | ||
916 | return clean_them; | ||
917 | } | ||
918 | |||
919 | pts[0].px = obj->cur.map->persp.px << FP; | ||
920 | pts[0].py = obj->cur.map->persp.py << FP; | ||
921 | pts[0].foc = obj->cur.map->persp.foc << FP; | ||
922 | pts[0].z0 = obj->cur.map->persp.z0 << FP; | ||
923 | |||
924 | p = obj->cur.map->points; | ||
925 | p_end = p + obj->cur.map->count; | ||
926 | pt = pts; | ||
927 | for (; p < p_end; p++, pt++) | ||
928 | { | ||
929 | pt->x = (lround(p->x) + off_x) * FP1; | ||
930 | pt->y = (lround(p->y) + off_y) * FP1; | ||
931 | pt->z = (lround(p->z) ) * FP1; | ||
932 | pt->fx = p->px; | ||
933 | pt->fy = p->py; | ||
934 | pt->fz = p->z; | ||
935 | pt->u = lround(p->u) * FP1; | ||
936 | pt->v = lround(p->v) * FP1; | ||
937 | if (pt->u < 0) pt->u = 0; | ||
938 | else if (pt->u > (sw * FP1)) pt->u = (sw * FP1); | ||
939 | if (pt->v < 0) pt->v = 0; | ||
940 | else if (pt->v > (sh * FP1)) pt->v = (sh * FP1); | ||
941 | pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b); | ||
942 | } | ||
943 | /* Copy last for software engine */ | ||
944 | if (obj->cur.map->count & 0x1) | ||
945 | { | ||
946 | pts[obj->cur.map->count] = pts[obj->cur.map->count - 1]; | ||
947 | } | ||
948 | |||
949 | |||
950 | if (obj->cur.map->surface) | ||
951 | { | ||
952 | if ((obj->cur.map->surface_w != sw) || | ||
953 | (obj->cur.map->surface_h != sh)) | ||
954 | { | ||
955 | RDI(level); | ||
956 | RD(" new surf: %ix%i\n", sw, sh); | ||
957 | obj->layer->evas->engine.func->image_map_surface_free | ||
958 | (e->engine.data.output, obj->cur.map->surface); | ||
959 | obj->cur.map->surface = NULL; | ||
960 | } | ||
961 | } | ||
962 | if (!obj->cur.map->surface) | ||
963 | { | ||
964 | obj->cur.map->surface_w = sw; | ||
965 | obj->cur.map->surface_h = sh; | ||
966 | |||
967 | obj->cur.map->surface = | ||
968 | obj->layer->evas->engine.func->image_map_surface_new | ||
969 | (e->engine.data.output, obj->cur.map->surface_w, | ||
970 | obj->cur.map->surface_h, | ||
971 | obj->cur.map->alpha); | ||
972 | RDI(level); | ||
973 | RD(" fisrt surf: %ix%i\n", sw, sh); | ||
974 | changed = 1; | ||
975 | } | ||
976 | if (obj->smart.smart) | ||
977 | { | ||
978 | Evas_Object *o2; | ||
979 | |||
980 | EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), o2) | ||
981 | { | ||
982 | if (!evas_object_is_visible(o2) && | ||
983 | !evas_object_was_visible(o2)) | ||
984 | { | ||
985 | o2->changed = 0; | ||
986 | o2->changed_move_only = 0; | ||
987 | o2->changed_nomove = 0; | ||
988 | o2->changed_move = 0; | ||
989 | o2->changed_map = 0; | ||
990 | o2->changed_pchange = 0; | ||
991 | continue; | ||
992 | } | ||
993 | if (o2->changed) | ||
994 | { | ||
995 | // chlist(o2, 0); | ||
996 | changed = 1; | ||
997 | o2->changed = 0; | ||
998 | o2->changed_move_only = 0; | ||
999 | o2->changed_nomove = 0; | ||
1000 | o2->changed_move = 0; | ||
1001 | o2->changed_map = 0; | ||
1002 | o2->changed_pchange = 0; | ||
1003 | break; | ||
1004 | } | ||
1005 | } | ||
1006 | // unchange(obj); | ||
1007 | obj->changed = 0; | ||
1008 | obj->changed_move_only = 0; | ||
1009 | obj->changed_nomove = 0; | ||
1010 | obj->changed_move = 0; | ||
1011 | obj->changed_map = 0; | ||
1012 | obj->changed_pchange = 0; | ||
1013 | } | ||
1014 | else | ||
1015 | { | ||
1016 | if (obj->changed) | ||
1017 | { | ||
1018 | if ((obj->changed_pchange) && (obj->changed_map)) | ||
1019 | changed = 1; | ||
1020 | obj->changed = 0; | ||
1021 | obj->changed_move_only = 0; | ||
1022 | obj->changed_nomove = 0; | ||
1023 | obj->changed_move = 0; | ||
1024 | obj->changed_map = 0; | ||
1025 | obj->changed_pchange = 0; | ||
1026 | } | ||
1027 | } | ||
1028 | |||
1029 | // clear surface before re-render | ||
1030 | if ((changed) && (obj->cur.map->surface)) | ||
1031 | { | ||
1032 | int off_x2, off_y2; | ||
1033 | |||
1034 | RDI(level); | ||
1035 | RD(" children redraw\n"); | ||
1036 | // FIXME: calculate "changes" within map surface and only clear | ||
1037 | // and re-render those | ||
1038 | if (obj->cur.map->alpha) | ||
1039 | { | ||
1040 | ctx = e->engine.func->context_new(e->engine.data.output); | ||
1041 | e->engine.func->context_color_set | ||
1042 | (e->engine.data.output, ctx, 0, 0, 0, 0); | ||
1043 | e->engine.func->context_render_op_set | ||
1044 | (e->engine.data.output, ctx, EVAS_RENDER_COPY); | ||
1045 | e->engine.func->rectangle_draw(e->engine.data.output, | ||
1046 | ctx, | ||
1047 | obj->cur.map->surface, | ||
1048 | 0, 0, | ||
1049 | obj->cur.map->surface_w, | ||
1050 | obj->cur.map->surface_h); | ||
1051 | e->engine.func->context_free(e->engine.data.output, ctx); | ||
1052 | } | ||
1053 | ctx = e->engine.func->context_new(e->engine.data.output); | ||
1054 | off_x2 = -obj->cur.geometry.x; | ||
1055 | off_y2 = -obj->cur.geometry.y; | ||
1056 | if (obj->smart.smart) | ||
1057 | { | ||
1058 | EINA_INLIST_FOREACH | ||
1059 | (evas_object_smart_members_get_direct(obj), obj2) | ||
1060 | { | ||
1061 | clean_them |= evas_render_mapped(e, obj2, ctx, | ||
1062 | obj->cur.map->surface, | ||
1063 | off_x2, off_y2, 1, | ||
1064 | ecx, ecy, ecw, ech | ||
1065 | #ifdef REND_DGB | ||
1066 | , level + 1 | ||
1067 | #endif | ||
1068 | ); | ||
1069 | } | ||
1070 | } | ||
1071 | else | ||
1072 | { | ||
1073 | int x = 0, y = 0, w = 0, h = 0; | ||
1074 | |||
1075 | w = obj->cur.map->surface_w; | ||
1076 | h = obj->cur.map->surface_h; | ||
1077 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
1078 | obj->cur.geometry.x + off_x2, | ||
1079 | obj->cur.geometry.y + off_y2, | ||
1080 | obj->cur.geometry.w, | ||
1081 | obj->cur.geometry.h); | ||
1082 | |||
1083 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1084 | ctx, x, y, w, h); | ||
1085 | obj->func->render(obj, e->engine.data.output, ctx, | ||
1086 | obj->cur.map->surface, off_x2, off_y2); | ||
1087 | } | ||
1088 | e->engine.func->context_free(e->engine.data.output, ctx); | ||
1089 | rendered = 1; | ||
1090 | } | ||
1091 | |||
1092 | RDI(level); | ||
1093 | RD(" draw map\n"); | ||
1094 | |||
1095 | if (rendered) | ||
1096 | { | ||
1097 | obj->cur.map->surface = e->engine.func->image_dirty_region | ||
1098 | (e->engine.data.output, obj->cur.map->surface, | ||
1099 | 0, 0, obj->cur.map->surface_w, obj->cur.map->surface_h); | ||
1100 | } | ||
1101 | e->engine.func->context_clip_unset(e->engine.data.output, | ||
1102 | e->engine.data.context); | ||
1103 | if (obj->cur.map->surface) | ||
1104 | { | ||
1105 | if (obj->smart.smart) | ||
1106 | { | ||
1107 | if (obj->cur.clipper) | ||
1108 | { | ||
1109 | int x, y, w, h; | ||
1110 | Evas_Object *tobj; | ||
1111 | |||
1112 | obj->cur.cache.clip.dirty = 1; | ||
1113 | tobj = obj->cur.map_parent; | ||
1114 | obj->cur.map_parent = obj->cur.clipper->cur.map_parent; | ||
1115 | evas_object_clip_recalc(obj); | ||
1116 | obj->cur.map_parent = tobj; | ||
1117 | x = obj->cur.cache.clip.x; | ||
1118 | y = obj->cur.cache.clip.y; | ||
1119 | w = obj->cur.cache.clip.w; | ||
1120 | h = obj->cur.cache.clip.h; | ||
1121 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
1122 | obj->cur.clipper->cur.cache.clip.x, | ||
1123 | obj->cur.clipper->cur.cache.clip.y, | ||
1124 | obj->cur.clipper->cur.cache.clip.w, | ||
1125 | obj->cur.clipper->cur.cache.clip.h); | ||
1126 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1127 | e->engine.data.context, | ||
1128 | x + off_x, y + off_y, w, h); | ||
1129 | } | ||
1130 | } | ||
1131 | else | ||
1132 | { | ||
1133 | if (obj->cur.clipper) | ||
1134 | { | ||
1135 | int x, y, w, h; | ||
1136 | |||
1137 | evas_object_clip_recalc(obj); | ||
1138 | x = obj->cur.cache.clip.x; | ||
1139 | y = obj->cur.cache.clip.y; | ||
1140 | w = obj->cur.cache.clip.w; | ||
1141 | h = obj->cur.cache.clip.h; | ||
1142 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
1143 | obj->cur.clipper->cur.cache.clip.x, | ||
1144 | obj->cur.clipper->cur.cache.clip.y, | ||
1145 | obj->cur.clipper->cur.cache.clip.w, | ||
1146 | obj->cur.clipper->cur.cache.clip.h); | ||
1147 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1148 | e->engine.data.context, | ||
1149 | x + off_x, y + off_y, w, h); | ||
1150 | } | ||
1151 | } | ||
1152 | } | ||
1153 | // if (surface == e->engine.data.output) | ||
1154 | e->engine.func->context_clip_clip(e->engine.data.output, | ||
1155 | e->engine.data.context, | ||
1156 | ecx, ecy, ecw, ech); | ||
1157 | if (obj->cur.cache.clip.visible) | ||
1158 | { | ||
1159 | obj->layer->evas->engine.func->image_map_draw | ||
1160 | (e->engine.data.output, e->engine.data.context, surface, | ||
1161 | obj->cur.map->surface, obj->cur.map->count, pts, | ||
1162 | obj->cur.map->smooth, 0); | ||
1163 | } | ||
1164 | // FIXME: needs to cache these maps and | ||
1165 | // keep them only rendering updates | ||
1166 | // obj->layer->evas->engine.func->image_map_surface_free | ||
1167 | // (e->engine.data.output, obj->cur.map->surface); | ||
1168 | // obj->cur.map->surface = NULL; | ||
1169 | } | ||
1170 | else | ||
1171 | { | ||
1172 | if (mapped) | ||
1173 | { | ||
1174 | RDI(level); | ||
1175 | RD(" draw child of mapped obj\n"); | ||
1176 | ctx = e->engine.func->context_new(e->engine.data.output); | ||
1177 | if (obj->smart.smart) | ||
1178 | { | ||
1179 | EINA_INLIST_FOREACH | ||
1180 | (evas_object_smart_members_get_direct(obj), obj2) | ||
1181 | { | ||
1182 | clean_them |= evas_render_mapped(e, obj2, ctx, | ||
1183 | surface, | ||
1184 | off_x, off_y, 1, | ||
1185 | ecx, ecy, ecw, ech | ||
1186 | #ifdef REND_DGB | ||
1187 | , level + 1 | ||
1188 | #endif | ||
1189 | ); | ||
1190 | } | ||
1191 | } | ||
1192 | else | ||
1193 | { | ||
1194 | if (!obj->cur.map) | ||
1195 | { | ||
1196 | int x, y, w, h; | ||
1197 | |||
1198 | RDI(level); | ||
1199 | |||
1200 | x = obj->cur.cache.clip.x + off_x; | ||
1201 | y = obj->cur.cache.clip.y + off_y; | ||
1202 | w = obj->cur.cache.clip.w; | ||
1203 | h = obj->cur.cache.clip.h; | ||
1204 | |||
1205 | if (obj->cur.clipper) | ||
1206 | { | ||
1207 | if (_evas_render_has_map(obj)) | ||
1208 | evas_object_clip_recalc(obj); | ||
1209 | |||
1210 | RD(" clipper: %i %i %ix%i\n", | ||
1211 | obj->cur.clipper->cur.cache.clip.x + off_x, | ||
1212 | obj->cur.clipper->cur.cache.clip.y + off_y, | ||
1213 | obj->cur.clipper->cur.cache.clip.w, | ||
1214 | obj->cur.clipper->cur.cache.clip.h); | ||
1215 | |||
1216 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
1217 | obj->cur.clipper->cur.cache.clip.x + off_x, | ||
1218 | obj->cur.clipper->cur.cache.clip.y + off_y, | ||
1219 | obj->cur.clipper->cur.cache.clip.w, | ||
1220 | obj->cur.clipper->cur.cache.clip.h); | ||
1221 | } | ||
1222 | |||
1223 | RD(" clip: %i %i %ix%i [%i %i %ix%i]\n", | ||
1224 | obj->cur.cache.clip.x + off_x, | ||
1225 | obj->cur.cache.clip.y + off_y, | ||
1226 | obj->cur.cache.clip.w, | ||
1227 | obj->cur.cache.clip.h, | ||
1228 | obj->cur.geometry.x + off_x, | ||
1229 | obj->cur.geometry.y + off_y, | ||
1230 | obj->cur.geometry.w, | ||
1231 | obj->cur.geometry.h); | ||
1232 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1233 | ctx, x, y, w, h); | ||
1234 | } | ||
1235 | else | ||
1236 | { | ||
1237 | RDI(level); | ||
1238 | RD(" noclip\n"); | ||
1239 | } | ||
1240 | obj->func->render(obj, e->engine.data.output, ctx, | ||
1241 | surface, off_x, off_y); | ||
1242 | /* | ||
1243 | obj->layer->evas->engine.func->context_color_set(e->engine.data.output, | ||
1244 | ctx, | ||
1245 | 0, 30, 0, 30); | ||
1246 | obj->layer->evas->engine.func->rectangle_draw(e->engine.data.output, | ||
1247 | ctx, | ||
1248 | surface, | ||
1249 | 0, 0, 9999, 9999); | ||
1250 | */ | ||
1251 | } | ||
1252 | e->engine.func->context_free(e->engine.data.output, ctx); | ||
1253 | } | ||
1254 | else | ||
1255 | { | ||
1256 | if (obj->cur.clipper) | ||
1257 | { | ||
1258 | int x, y, w, h; | ||
1259 | |||
1260 | if (_evas_render_has_map(obj)) | ||
1261 | evas_object_clip_recalc(obj); | ||
1262 | x = obj->cur.cache.clip.x; | ||
1263 | y = obj->cur.cache.clip.y; | ||
1264 | w = obj->cur.cache.clip.w; | ||
1265 | h = obj->cur.cache.clip.h; | ||
1266 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
1267 | obj->cur.clipper->cur.cache.clip.x, | ||
1268 | obj->cur.clipper->cur.cache.clip.y, | ||
1269 | obj->cur.clipper->cur.cache.clip.w, | ||
1270 | obj->cur.clipper->cur.cache.clip.h); | ||
1271 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1272 | e->engine.data.context, | ||
1273 | x + off_x, y + off_y, w, h); | ||
1274 | e->engine.func->context_clip_clip(e->engine.data.output, | ||
1275 | e->engine.data.context, | ||
1276 | ecx, ecy, ecw, ech); | ||
1277 | } | ||
1278 | |||
1279 | RDI(level); | ||
1280 | RD(" draw normal obj\n"); | ||
1281 | obj->func->render(obj, e->engine.data.output, context, surface, | ||
1282 | off_x, off_y); | ||
1283 | } | ||
1284 | } | ||
1285 | RDI(level); | ||
1286 | RD(" }\n"); | ||
1287 | |||
1288 | return clean_them; | ||
1289 | } | ||
1290 | |||
1291 | static void | ||
1292 | _evas_render_cutout_add(Evas *e, Evas_Object *obj, int off_x, int off_y) | ||
1293 | { | ||
1294 | if (evas_object_is_opaque(obj)) | ||
1295 | { | ||
1296 | Evas_Coord cox, coy, cow, coh; | ||
1297 | |||
1298 | cox = obj->cur.cache.clip.x; | ||
1299 | coy = obj->cur.cache.clip.y; | ||
1300 | cow = obj->cur.cache.clip.w; | ||
1301 | coh = obj->cur.cache.clip.h; | ||
1302 | if ((obj->cur.map) && (obj->cur.usemap)) | ||
1303 | { | ||
1304 | Evas_Object *oo; | ||
1305 | |||
1306 | oo = obj; | ||
1307 | while (oo->cur.clipper) | ||
1308 | { | ||
1309 | if ((oo->cur.clipper->cur.map_parent | ||
1310 | != oo->cur.map_parent) && | ||
1311 | (!((oo->cur.map) && (oo->cur.usemap)))) | ||
1312 | break; | ||
1313 | RECTS_CLIP_TO_RECT(cox, coy, cow, coh, | ||
1314 | oo->cur.geometry.x, | ||
1315 | oo->cur.geometry.y, | ||
1316 | oo->cur.geometry.w, | ||
1317 | oo->cur.geometry.h); | ||
1318 | oo = oo->cur.clipper; | ||
1319 | } | ||
1320 | } | ||
1321 | e->engine.func->context_cutout_add | ||
1322 | (e->engine.data.output, e->engine.data.context, | ||
1323 | cox + off_x, coy + off_y, cow, coh); | ||
1324 | } | ||
1325 | else | ||
1326 | { | ||
1327 | if (obj->func->get_opaque_rect) | ||
1328 | { | ||
1329 | Evas_Coord obx, oby, obw, obh; | ||
1330 | |||
1331 | obj->func->get_opaque_rect(obj, &obx, &oby, &obw, &obh); | ||
1332 | if ((obw > 0) && (obh > 0)) | ||
1333 | { | ||
1334 | obx += off_x; | ||
1335 | oby += off_y; | ||
1336 | RECTS_CLIP_TO_RECT(obx, oby, obw, obh, | ||
1337 | obj->cur.cache.clip.x + off_x, | ||
1338 | obj->cur.cache.clip.y + off_y, | ||
1339 | obj->cur.cache.clip.w, | ||
1340 | obj->cur.cache.clip.h); | ||
1341 | e->engine.func->context_cutout_add | ||
1342 | (e->engine.data.output, e->engine.data.context, | ||
1343 | obx, oby, obw, obh); | ||
1344 | } | ||
1345 | } | ||
1346 | } | ||
1347 | } | ||
1348 | |||
1349 | static Eina_List * | ||
1350 | evas_render_updates_internal(Evas *e, | ||
1351 | unsigned char make_updates, | ||
1352 | unsigned char do_draw) | ||
1353 | { | ||
1354 | Evas_Object *obj; | ||
1355 | Eina_List *updates = NULL; | ||
1356 | Eina_List *ll; | ||
1357 | void *surface; | ||
1358 | Eina_Bool clean_them = EINA_FALSE; | ||
1359 | Eina_Bool alpha; | ||
1360 | Eina_Rectangle *r; | ||
1361 | int ux, uy, uw, uh; | ||
1362 | int cx, cy, cw, ch; | ||
1363 | unsigned int i, j; | ||
1364 | int haveup = 0; | ||
1365 | int redraw_all = 0; | ||
1366 | |||
1367 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1368 | return NULL; | ||
1369 | MAGIC_CHECK_END(); | ||
1370 | if (!e->changed) return NULL; | ||
1371 | |||
1372 | evas_call_smarts_calculate(e); | ||
1373 | |||
1374 | RD("[--- RENDER EVAS (size: %ix%i)\n", e->viewport.w, e->viewport.h); | ||
1375 | |||
1376 | evas_event_callback_call(e, EVAS_CALLBACK_RENDER_PRE, NULL); | ||
1377 | |||
1378 | /* Check if the modified object mean recalculating every thing */ | ||
1379 | if (!e->invalidate) | ||
1380 | _evas_render_check_pending_objects(&e->pending_objects, e); | ||
1381 | |||
1382 | /* phase 1. add extra updates for changed objects */ | ||
1383 | if (e->invalidate || e->render_objects.count <= 0) | ||
1384 | clean_them = _evas_render_phase1_process(e, | ||
1385 | &e->active_objects, | ||
1386 | &e->restack_objects, | ||
1387 | &e->delete_objects, | ||
1388 | &e->render_objects, | ||
1389 | &redraw_all); | ||
1390 | |||
1391 | /* phase 1.5. check if the video should be inlined or stay in their overlay */ | ||
1392 | alpha = e->engine.func->canvas_alpha_get(e->engine.data.output, | ||
1393 | e->engine.data.context); | ||
1394 | |||
1395 | EINA_LIST_FOREACH(e->video_objects, ll, obj) | ||
1396 | { | ||
1397 | /* we need the surface to be transparent to display the underlying overlay */ | ||
1398 | if (alpha && _evas_render_can_use_overlay(e, obj)) | ||
1399 | _evas_object_image_video_overlay_show(obj); | ||
1400 | else | ||
1401 | _evas_object_image_video_overlay_hide(obj); | ||
1402 | } | ||
1403 | |||
1404 | |||
1405 | /* phase 1.8. pre render for proxy */ | ||
1406 | _evas_render_phase1_direct(e, &e->active_objects, &e->restack_objects, | ||
1407 | &e->delete_objects, &e->render_objects); | ||
1408 | |||
1409 | /* phase 2. force updates for restacks */ | ||
1410 | for (i = 0; i < e->restack_objects.count; ++i) | ||
1411 | { | ||
1412 | obj = eina_array_data_get(&e->restack_objects, i); | ||
1413 | obj->func->render_pre(obj); | ||
1414 | _evas_render_prev_cur_clip_cache_add(e, obj); | ||
1415 | } | ||
1416 | eina_array_clean(&e->restack_objects); | ||
1417 | |||
1418 | /* phase 3. add exposes */ | ||
1419 | EINA_LIST_FREE(e->damages, r) | ||
1420 | { | ||
1421 | e->engine.func->output_redraws_rect_add(e->engine.data.output, | ||
1422 | r->x, r->y, r->w, r->h); | ||
1423 | eina_rectangle_free(r); | ||
1424 | } | ||
1425 | |||
1426 | /* phase 4. framespace, output & viewport changes */ | ||
1427 | if (e->framespace.changed) | ||
1428 | { | ||
1429 | int fx, fy, fw, fh; | ||
1430 | |||
1431 | fx = e->viewport.x - e->framespace.x; | ||
1432 | fy = e->viewport.y - e->framespace.y; | ||
1433 | fw = e->viewport.w + e->framespace.w; | ||
1434 | fh = e->viewport.h + e->framespace.h; | ||
1435 | e->engine.func->output_redraws_rect_add(e->engine.data.output, | ||
1436 | fx, fy, fw, fh); | ||
1437 | } | ||
1438 | |||
1439 | if (e->viewport.changed) | ||
1440 | { | ||
1441 | e->engine.func->output_redraws_rect_add(e->engine.data.output, | ||
1442 | 0, 0, | ||
1443 | e->output.w, e->output.h); | ||
1444 | } | ||
1445 | if (e->output.changed) | ||
1446 | { | ||
1447 | e->engine.func->output_resize(e->engine.data.output, | ||
1448 | e->output.w, e->output.h); | ||
1449 | e->engine.func->output_redraws_rect_add(e->engine.data.output, | ||
1450 | 0, 0, | ||
1451 | e->output.w, e->output.h); | ||
1452 | } | ||
1453 | if ((e->output.w != e->viewport.w) || (e->output.h != e->viewport.h)) | ||
1454 | { | ||
1455 | ERR("viewport size != output size!"); | ||
1456 | } | ||
1457 | if (redraw_all) | ||
1458 | { | ||
1459 | e->engine.func->output_redraws_rect_add(e->engine.data.output, | ||
1460 | 0, 0, | ||
1461 | e->output.w, e->output.h); | ||
1462 | } | ||
1463 | |||
1464 | /* phase 5. add obscures */ | ||
1465 | EINA_LIST_FOREACH(e->obscures, ll, r) | ||
1466 | { | ||
1467 | e->engine.func->output_redraws_rect_del(e->engine.data.output, | ||
1468 | r->x, r->y, r->w, r->h); | ||
1469 | } | ||
1470 | /* build obscure objects list of active objects that obscure */ | ||
1471 | for (i = 0; i < e->active_objects.count; ++i) | ||
1472 | { | ||
1473 | obj = eina_array_data_get(&e->active_objects, i); | ||
1474 | if (UNLIKELY((evas_object_is_opaque(obj) || | ||
1475 | ((obj->func->has_opaque_rect) && | ||
1476 | (obj->func->has_opaque_rect(obj)))) && | ||
1477 | evas_object_is_visible(obj) && | ||
1478 | (!obj->clip.clipees) && | ||
1479 | (obj->cur.visible) && | ||
1480 | (!obj->delete_me) && | ||
1481 | (obj->cur.cache.clip.visible) && | ||
1482 | (!obj->smart.smart))) | ||
1483 | /* obscuring_objects = eina_list_append(obscuring_objects, obj); */ | ||
1484 | eina_array_push(&e->obscuring_objects, obj); | ||
1485 | } | ||
1486 | |||
1487 | /* save this list */ | ||
1488 | /* obscuring_objects_orig = obscuring_objects; */ | ||
1489 | /* obscuring_objects = NULL; */ | ||
1490 | /* phase 6. go thru each update rect and render objects in it*/ | ||
1491 | if (do_draw) | ||
1492 | { | ||
1493 | unsigned int offset = 0; | ||
1494 | |||
1495 | while ((surface = | ||
1496 | e->engine.func->output_redraws_next_update_get | ||
1497 | (e->engine.data.output, | ||
1498 | &ux, &uy, &uw, &uh, | ||
1499 | &cx, &cy, &cw, &ch))) | ||
1500 | { | ||
1501 | int off_x, off_y; | ||
1502 | |||
1503 | RD(" [--- UPDATE %i %i %ix%i\n", ux, uy, uw, uh); | ||
1504 | if (make_updates) | ||
1505 | { | ||
1506 | Eina_Rectangle *rect; | ||
1507 | |||
1508 | NEW_RECT(rect, ux, uy, uw, uh); | ||
1509 | if (rect) | ||
1510 | updates = eina_list_append(updates, rect); | ||
1511 | } | ||
1512 | haveup = 1; | ||
1513 | off_x = cx - ux; | ||
1514 | off_y = cy - uy; | ||
1515 | /* build obscuring objects list (in order from bottom to top) */ | ||
1516 | if (alpha) | ||
1517 | { | ||
1518 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1519 | e->engine.data.context, | ||
1520 | ux + off_x, uy + off_y, uw, uh); | ||
1521 | } | ||
1522 | for (i = 0; i < e->obscuring_objects.count; ++i) | ||
1523 | { | ||
1524 | obj = (Evas_Object *)eina_array_data_get | ||
1525 | (&e->obscuring_objects, i); | ||
1526 | if (evas_object_is_in_output_rect(obj, ux, uy, uw, uh)) | ||
1527 | { | ||
1528 | eina_array_push(&e->temporary_objects, obj); | ||
1529 | |||
1530 | /* reset the background of the area if needed (using cutout and engine alpha flag to help) */ | ||
1531 | if (alpha) | ||
1532 | _evas_render_cutout_add(e, obj, off_x, off_y); | ||
1533 | } | ||
1534 | } | ||
1535 | if (alpha) | ||
1536 | { | ||
1537 | e->engine.func->context_color_set(e->engine.data.output, | ||
1538 | e->engine.data.context, | ||
1539 | 0, 0, 0, 0); | ||
1540 | e->engine.func->context_multiplier_unset | ||
1541 | (e->engine.data.output, e->engine.data.context); | ||
1542 | e->engine.func->context_render_op_set(e->engine.data.output, | ||
1543 | e->engine.data.context, | ||
1544 | EVAS_RENDER_COPY); | ||
1545 | e->engine.func->rectangle_draw(e->engine.data.output, | ||
1546 | e->engine.data.context, | ||
1547 | surface, | ||
1548 | cx, cy, cw, ch); | ||
1549 | e->engine.func->context_cutout_clear(e->engine.data.output, | ||
1550 | e->engine.data.context); | ||
1551 | e->engine.func->context_clip_unset(e->engine.data.output, | ||
1552 | e->engine.data.context); | ||
1553 | } | ||
1554 | /* render all object that intersect with rect */ | ||
1555 | for (i = 0; i < e->active_objects.count; ++i) | ||
1556 | { | ||
1557 | obj = eina_array_data_get(&e->active_objects, i); | ||
1558 | |||
1559 | /* if it's in our outpout rect and it doesn't clip anything */ | ||
1560 | 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); | ||
1561 | if ((evas_object_is_in_output_rect(obj, ux, uy, uw, uh) || | ||
1562 | (obj->smart.smart)) && | ||
1563 | (!obj->clip.clipees) && | ||
1564 | (obj->cur.visible) && | ||
1565 | (!obj->delete_me) && | ||
1566 | (obj->cur.cache.clip.visible) && | ||
1567 | // (!obj->smart.smart) && | ||
1568 | ((obj->cur.color.a > 0 || obj->cur.render_op != EVAS_RENDER_BLEND))) | ||
1569 | { | ||
1570 | int x, y, w, h; | ||
1571 | |||
1572 | RD(" DRAW (vis: %i, a: %i, clipees: %p\n", obj->cur.visible, obj->cur.color.a, obj->clip.clipees); | ||
1573 | if ((e->temporary_objects.count > offset) && | ||
1574 | (eina_array_data_get(&e->temporary_objects, offset) == obj)) | ||
1575 | offset++; | ||
1576 | x = cx; y = cy; w = cw; h = ch; | ||
1577 | if (((w > 0) && (h > 0)) || (obj->smart.smart)) | ||
1578 | { | ||
1579 | if (!obj->smart.smart) | ||
1580 | { | ||
1581 | RECTS_CLIP_TO_RECT(x, y, w, h, | ||
1582 | obj->cur.cache.clip.x + off_x, | ||
1583 | obj->cur.cache.clip.y + off_y, | ||
1584 | obj->cur.cache.clip.w, | ||
1585 | obj->cur.cache.clip.h); | ||
1586 | } | ||
1587 | if (obj->cur.mask) | ||
1588 | e->engine.func->context_mask_set(e->engine.data.output, | ||
1589 | e->engine.data.context, | ||
1590 | obj->cur.mask->func->engine_data_get(obj->cur.mask), | ||
1591 | obj->cur.mask->cur.geometry.x + off_x, | ||
1592 | obj->cur.mask->cur.geometry.y + off_y, | ||
1593 | obj->cur.mask->cur.geometry.w, | ||
1594 | obj->cur.mask->cur.geometry.h); | ||
1595 | else | ||
1596 | e->engine.func->context_mask_unset(e->engine.data.output, | ||
1597 | e->engine.data.context); | ||
1598 | e->engine.func->context_clip_set(e->engine.data.output, | ||
1599 | e->engine.data.context, | ||
1600 | x, y, w, h); | ||
1601 | #if 1 /* FIXME: this can slow things down... figure out optimum... coverage */ | ||
1602 | for (j = offset; j < e->temporary_objects.count; ++j) | ||
1603 | { | ||
1604 | Evas_Object *obj2; | ||
1605 | |||
1606 | obj2 = (Evas_Object *)eina_array_data_get | ||
1607 | (&e->temporary_objects, j); | ||
1608 | _evas_render_cutout_add(e, obj2, off_x, off_y); | ||
1609 | } | ||
1610 | #endif | ||
1611 | clean_them |= evas_render_mapped(e, obj, e->engine.data.context, | ||
1612 | surface, off_x, off_y, 0, | ||
1613 | cx, cy, cw, ch | ||
1614 | #ifdef REND_DGB | ||
1615 | , 1 | ||
1616 | #endif | ||
1617 | ); | ||
1618 | e->engine.func->context_cutout_clear(e->engine.data.output, | ||
1619 | e->engine.data.context); | ||
1620 | } | ||
1621 | } | ||
1622 | } | ||
1623 | /* punch rect out */ | ||
1624 | e->engine.func->output_redraws_next_update_push(e->engine.data.output, | ||
1625 | surface, | ||
1626 | ux, uy, uw, uh); | ||
1627 | /* free obscuring objects list */ | ||
1628 | eina_array_clean(&e->temporary_objects); | ||
1629 | RD(" ---]\n"); | ||
1630 | } | ||
1631 | /* flush redraws */ | ||
1632 | if (haveup) | ||
1633 | { | ||
1634 | evas_event_callback_call(e, EVAS_CALLBACK_RENDER_FLUSH_PRE, NULL); | ||
1635 | e->engine.func->output_flush(e->engine.data.output); | ||
1636 | evas_event_callback_call(e, EVAS_CALLBACK_RENDER_FLUSH_POST, NULL); | ||
1637 | } | ||
1638 | } | ||
1639 | /* clear redraws */ | ||
1640 | e->engine.func->output_redraws_clear(e->engine.data.output); | ||
1641 | /* and do a post render pass */ | ||
1642 | for (i = 0; i < e->active_objects.count; ++i) | ||
1643 | { | ||
1644 | obj = eina_array_data_get(&e->active_objects, i); | ||
1645 | obj->pre_render_done = 0; | ||
1646 | RD(" OBJ [%p] post... %i %i\n", obj, obj->changed, do_draw); | ||
1647 | if ((obj->changed) && (do_draw)) | ||
1648 | { | ||
1649 | RD(" OBJ [%p] post... func1\n", obj); | ||
1650 | obj->func->render_post(obj); | ||
1651 | obj->restack = 0; | ||
1652 | obj->changed = 0; | ||
1653 | obj->changed_move_only = 0; | ||
1654 | obj->changed_nomove = 0; | ||
1655 | obj->changed_move = 0; | ||
1656 | obj->changed_map = 0; | ||
1657 | obj->changed_pchange = 0; | ||
1658 | } | ||
1659 | else if ((obj->cur.map != obj->prev.map) || | ||
1660 | (obj->cur.usemap != obj->prev.usemap)) | ||
1661 | { | ||
1662 | RD(" OBJ [%p] post... func2\n", obj); | ||
1663 | obj->func->render_post(obj); | ||
1664 | obj->restack = 0; | ||
1665 | obj->changed = 0; | ||
1666 | obj->changed_move_only = 0; | ||
1667 | obj->changed_nomove = 0; | ||
1668 | obj->changed_move = 0; | ||
1669 | obj->changed_map = 0; | ||
1670 | obj->changed_pchange = 0; | ||
1671 | } | ||
1672 | /* moved to other pre-process phase 1 | ||
1673 | if (obj->delete_me == 2) | ||
1674 | { | ||
1675 | delete_objects = eina_list_append(delete_objects, obj); | ||
1676 | } | ||
1677 | else if (obj->delete_me != 0) obj->delete_me++; | ||
1678 | */ | ||
1679 | } | ||
1680 | /* free our obscuring object list */ | ||
1681 | eina_array_clean(&e->obscuring_objects); | ||
1682 | |||
1683 | /* If some object are still marked as changed, do not remove | ||
1684 | them from the pending list. */ | ||
1685 | eina_array_remove(&e->pending_objects, pending_change, NULL); | ||
1686 | |||
1687 | for (i = 0; i < e->render_objects.count; ++i) | ||
1688 | { | ||
1689 | obj = eina_array_data_get(&e->render_objects, i); | ||
1690 | obj->pre_render_done = 0; | ||
1691 | } | ||
1692 | |||
1693 | /* delete all objects flagged for deletion now */ | ||
1694 | for (i = 0; i < e->delete_objects.count; ++i) | ||
1695 | { | ||
1696 | obj = eina_array_data_get(&e->delete_objects, i); | ||
1697 | evas_object_free(obj, 1); | ||
1698 | } | ||
1699 | eina_array_clean(&e->delete_objects); | ||
1700 | |||
1701 | e->changed = 0; | ||
1702 | e->viewport.changed = 0; | ||
1703 | e->output.changed = 0; | ||
1704 | e->framespace.changed = 0; | ||
1705 | e->invalidate = 0; | ||
1706 | |||
1707 | // always clean... lots of mem waste! | ||
1708 | /* If their are some object to restack or some object to delete, | ||
1709 | * it's useless to keep the render object list around. */ | ||
1710 | if (clean_them) | ||
1711 | { | ||
1712 | eina_array_clean(&e->active_objects); | ||
1713 | eina_array_clean(&e->render_objects); | ||
1714 | eina_array_clean(&e->restack_objects); | ||
1715 | eina_array_clean(&e->delete_objects); | ||
1716 | eina_array_clean(&e->obscuring_objects); | ||
1717 | eina_array_clean(&e->temporary_objects); | ||
1718 | eina_array_clean(&e->clip_changes); | ||
1719 | /* we should flush here and have a mempool system for this | ||
1720 | eina_array_flush(&e->active_objects); | ||
1721 | eina_array_flush(&e->render_objects); | ||
1722 | eina_array_flush(&e->restack_objects); | ||
1723 | eina_array_flush(&e->delete_objects); | ||
1724 | eina_array_flush(&e->obscuring_objects); | ||
1725 | eina_array_flush(&e->temporary_objects); | ||
1726 | eina_array_flush(&e->clip_changes); | ||
1727 | */ | ||
1728 | e->invalidate = 1; | ||
1729 | } | ||
1730 | |||
1731 | evas_module_clean(); | ||
1732 | |||
1733 | evas_event_callback_call(e, EVAS_CALLBACK_RENDER_POST, NULL); | ||
1734 | |||
1735 | RD("---]\n"); | ||
1736 | |||
1737 | return updates; | ||
1738 | } | ||
1739 | |||
1740 | EAPI void | ||
1741 | evas_render_updates_free(Eina_List *updates) | ||
1742 | { | ||
1743 | Eina_Rectangle *r; | ||
1744 | |||
1745 | EINA_LIST_FREE(updates, r) | ||
1746 | eina_rectangle_free(r); | ||
1747 | } | ||
1748 | |||
1749 | EAPI Eina_List * | ||
1750 | evas_render_updates(Evas *e) | ||
1751 | { | ||
1752 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1753 | return NULL; | ||
1754 | MAGIC_CHECK_END(); | ||
1755 | |||
1756 | #ifdef EVAS_FRAME_QUEUING | ||
1757 | evas_common_frameq_flush_ready (); | ||
1758 | #endif | ||
1759 | |||
1760 | if (!e->changed) return NULL; | ||
1761 | return evas_render_updates_internal(e, 1, 1); | ||
1762 | } | ||
1763 | |||
1764 | EAPI void | ||
1765 | evas_render(Evas *e) | ||
1766 | { | ||
1767 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1768 | return; | ||
1769 | MAGIC_CHECK_END(); | ||
1770 | |||
1771 | #ifdef EVAS_FRAME_QUEUING | ||
1772 | evas_common_frameq_flush_ready (); | ||
1773 | #endif | ||
1774 | |||
1775 | if (!e->changed) return; | ||
1776 | evas_render_updates_internal(e, 0, 1); | ||
1777 | } | ||
1778 | |||
1779 | EAPI void | ||
1780 | evas_norender(Evas *e) | ||
1781 | { | ||
1782 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1783 | return; | ||
1784 | MAGIC_CHECK_END(); | ||
1785 | |||
1786 | // if (!e->changed) return; | ||
1787 | evas_render_updates_internal(e, 0, 0); | ||
1788 | } | ||
1789 | |||
1790 | EAPI void | ||
1791 | evas_render_idle_flush(Evas *e) | ||
1792 | { | ||
1793 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1794 | return; | ||
1795 | MAGIC_CHECK_END(); | ||
1796 | |||
1797 | evas_fonts_zero_presure(e); | ||
1798 | |||
1799 | if ((e->engine.func) && (e->engine.func->output_idle_flush) && | ||
1800 | (e->engine.data.output)) | ||
1801 | e->engine.func->output_idle_flush(e->engine.data.output); | ||
1802 | |||
1803 | eina_array_flush(&e->active_objects); | ||
1804 | eina_array_flush(&e->render_objects); | ||
1805 | eina_array_flush(&e->restack_objects); | ||
1806 | eina_array_flush(&e->delete_objects); | ||
1807 | eina_array_flush(&e->obscuring_objects); | ||
1808 | eina_array_flush(&e->temporary_objects); | ||
1809 | eina_array_flush(&e->clip_changes); | ||
1810 | eina_array_flush(&e->temporary_objects); | ||
1811 | |||
1812 | e->invalidate = 1; | ||
1813 | } | ||
1814 | |||
1815 | EAPI void | ||
1816 | evas_sync(Evas *e) | ||
1817 | { | ||
1818 | #ifdef EVAS_FRAME_QUEUING | ||
1819 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1820 | return; | ||
1821 | MAGIC_CHECK_END(); | ||
1822 | |||
1823 | evas_common_frameq_flush(); | ||
1824 | #else | ||
1825 | (void) e; | ||
1826 | #endif | ||
1827 | } | ||
1828 | |||
1829 | static void | ||
1830 | _evas_render_dump_map_surfaces(Evas_Object *obj) | ||
1831 | { | ||
1832 | if ((obj->cur.map) && obj->cur.map->surface) | ||
1833 | { | ||
1834 | obj->layer->evas->engine.func->image_map_surface_free | ||
1835 | (obj->layer->evas->engine.data.output, obj->cur.map->surface); | ||
1836 | obj->cur.map->surface = NULL; | ||
1837 | } | ||
1838 | |||
1839 | if (obj->smart.smart) | ||
1840 | { | ||
1841 | Evas_Object *obj2; | ||
1842 | |||
1843 | EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2) | ||
1844 | _evas_render_dump_map_surfaces(obj2); | ||
1845 | } | ||
1846 | } | ||
1847 | |||
1848 | EAPI void | ||
1849 | evas_render_dump(Evas *e) | ||
1850 | { | ||
1851 | Evas_Layer *lay; | ||
1852 | |||
1853 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1854 | return; | ||
1855 | MAGIC_CHECK_END(); | ||
1856 | |||
1857 | EINA_INLIST_FOREACH(e->layers, lay) | ||
1858 | { | ||
1859 | Evas_Object *obj; | ||
1860 | |||
1861 | EINA_INLIST_FOREACH(lay->objects, obj) | ||
1862 | { | ||
1863 | if ((obj->type) && (!strcmp(obj->type, "image"))) | ||
1864 | evas_object_inform_call_image_unloaded(obj); | ||
1865 | _evas_render_dump_map_surfaces(obj); | ||
1866 | } | ||
1867 | } | ||
1868 | if ((e->engine.func) && (e->engine.func->output_dump) && | ||
1869 | (e->engine.data.output)) | ||
1870 | e->engine.func->output_dump(e->engine.data.output); | ||
1871 | } | ||
1872 | |||
1873 | void | ||
1874 | evas_render_invalidate(Evas *e) | ||
1875 | { | ||
1876 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1877 | return; | ||
1878 | MAGIC_CHECK_END(); | ||
1879 | |||
1880 | eina_array_clean(&e->active_objects); | ||
1881 | eina_array_clean(&e->render_objects); | ||
1882 | |||
1883 | eina_array_flush(&e->restack_objects); | ||
1884 | eina_array_flush(&e->delete_objects); | ||
1885 | |||
1886 | e->invalidate = 1; | ||
1887 | } | ||
1888 | |||
1889 | void | ||
1890 | evas_render_object_recalc(Evas_Object *obj) | ||
1891 | { | ||
1892 | MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); | ||
1893 | return; | ||
1894 | MAGIC_CHECK_END(); | ||
1895 | |||
1896 | #ifndef EVAS_FRAME_QUEUING | ||
1897 | if ((!obj->changed) && (obj->delete_me < 2)) | ||
1898 | #else | ||
1899 | if ((!obj->changed)) | ||
1900 | #endif | ||
1901 | { | ||
1902 | Evas *e; | ||
1903 | |||
1904 | e = obj->layer->evas; | ||
1905 | if ((!e) || (e->cleanup)) return; | ||
1906 | #ifdef EVAS_FRAME_QUEUING | ||
1907 | if (obj->delete_me >= evas_common_frameq_get_frameq_sz() + 2) return; | ||
1908 | #endif | ||
1909 | eina_array_push(&e->pending_objects, obj); | ||
1910 | obj->changed = 1; | ||
1911 | } | ||
1912 | } | ||
1913 | |||
1914 | /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/ | ||