diff options
author | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2015-06-02 20:39:57 +0900 |
---|---|---|
committer | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2015-06-09 17:34:39 +0900 |
commit | 25983dceddeda7d07220e97e227cd4c814707039 (patch) | |
tree | 078a335cd73978399d8ca6cb631a9932d4a23231 /src | |
parent | 0a2362fa69ebde8557f128e5b96a16f8b66a6fb9 (diff) |
evas render2 work - begin to make rectangles deal with render 2 basic
infra
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/evas/canvas/evas_canvas.eo | 16 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_object_rectangle.c | 79 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_object_smart.c | 2 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_render.c | 11 | ||||
-rw-r--r-- | src/lib/evas/canvas/render2/evas_render2.c | 80 | ||||
-rw-r--r-- | src/lib/evas/canvas/render2/evas_render2.h | 3 | ||||
-rw-r--r-- | src/lib/evas/canvas/render2/evas_render2_th_main.c | 265 | ||||
-rw-r--r-- | src/lib/evas/include/evas_private.h | 9 | ||||
-rw-r--r-- | src/modules/ecore_evas/engines/x/ecore_evas_x.c | 43 |
9 files changed, 462 insertions, 46 deletions
diff --git a/src/lib/evas/canvas/evas_canvas.eo b/src/lib/evas/canvas/evas_canvas.eo index d6dc1056f4..79462c71de 100644 --- a/src/lib/evas/canvas/evas_canvas.eo +++ b/src/lib/evas/canvas/evas_canvas.eo | |||
@@ -892,6 +892,22 @@ class Evas.Canvas (Eo.Base, Evas.Common_Interface) | |||
892 | 892 | ||
893 | return: bool; | 893 | return: bool; |
894 | } | 894 | } |
895 | render2_updates { | ||
896 | /*@ | ||
897 | Render the given Evas canvas using the new rendering infra. | ||
898 | |||
899 | This is experimental and will change over time until noted here. | ||
900 | |||
901 | @return A newly allocated list of updated rectangles of thecanvas | ||
902 | (@c Eina.Rectangle structs). Free this list with | ||
903 | evas_render_updates_free(). | ||
904 | |||
905 | @ingroup Evas_Canvas | ||
906 | @since 1.15 */ | ||
907 | |||
908 | return: free(own(list<Eina.Rectangle *> *), evas_render_updates_free) | ||
909 | @warn_unused; | ||
910 | } | ||
895 | focus_out { | 911 | focus_out { |
896 | /*@ | 912 | /*@ |
897 | Inform to the evas that it lost the focus. | 913 | Inform to the evas that it lost the focus. |
diff --git a/src/lib/evas/canvas/evas_object_rectangle.c b/src/lib/evas/canvas/evas_object_rectangle.c index cdee4ad1eb..8f603e6daa 100644 --- a/src/lib/evas/canvas/evas_object_rectangle.c +++ b/src/lib/evas/canvas/evas_object_rectangle.c | |||
@@ -41,6 +41,13 @@ static int evas_object_rectangle_was_opaque(Evas_Object *eo_obj, | |||
41 | Evas_Object_Protected_Data *obj, | 41 | Evas_Object_Protected_Data *obj, |
42 | void *type_private_data); | 42 | void *type_private_data); |
43 | 43 | ||
44 | static void evas_object_rectangle_render2_walk(Evas_Object *eo_obj, | ||
45 | Evas_Object_Protected_Data *obj, | ||
46 | void *type_private_data, | ||
47 | void *updates, | ||
48 | int offx, | ||
49 | int offy); | ||
50 | |||
44 | #if 0 /* usless calls for a rect object. much more useful for images etc. */ | 51 | #if 0 /* usless calls for a rect object. much more useful for images etc. */ |
45 | static void evas_object_rectangle_store(Evas_Object *eo_obj); | 52 | static void evas_object_rectangle_store(Evas_Object *eo_obj); |
46 | static void evas_object_rectangle_unstore(Evas_Object *eo_obj); | 53 | static void evas_object_rectangle_unstore(Evas_Object *eo_obj); |
@@ -73,7 +80,8 @@ static const Evas_Object_Func object_func = | |||
73 | NULL, | 80 | NULL, |
74 | NULL, | 81 | NULL, |
75 | NULL, | 82 | NULL, |
76 | NULL | 83 | NULL, |
84 | evas_object_rectangle_render2_walk | ||
77 | }; | 85 | }; |
78 | 86 | ||
79 | /* the actual api call to add a rect */ | 87 | /* the actual api call to add a rect */ |
@@ -117,6 +125,75 @@ evas_object_rectangle_init(Evas_Object *eo_obj) | |||
117 | } | 125 | } |
118 | 126 | ||
119 | static void | 127 | static void |
128 | evas_object_rectangle_render2_walk(Evas_Object *eo_obj, | ||
129 | Evas_Object_Protected_Data *obj, | ||
130 | void *type_private_data EINA_UNUSED, | ||
131 | void *updates, int offx, int offy) | ||
132 | { | ||
133 | Eina_Bool visible_is, visible_was; | ||
134 | unsigned int col_prev, col_cur; | ||
135 | |||
136 | if (obj->clip.clipees) return; | ||
137 | visible_is = evas_object_is_visible(eo_obj, obj); | ||
138 | if (!obj->changed) goto nochange; | ||
139 | |||
140 | if ((obj->cur->clipper) && (obj->cur->cache.clip.dirty)) | ||
141 | evas_object_clip_recalc(obj->cur->clipper); | ||
142 | visible_was = evas_object_was_visible(eo_obj,obj); | ||
143 | // just became visible or invisible | ||
144 | if (visible_is != visible_was) | ||
145 | { | ||
146 | printf(" UP1 %p - %i %i %ix%i\n", eo_obj, | ||
147 | obj->cur->cache.clip.x, obj->cur->cache.clip.y, | ||
148 | obj->cur->cache.clip.w, obj->cur->cache.clip.h); | ||
149 | evas_common_tilebuf_add_redraw | ||
150 | (updates, | ||
151 | obj->cur->cache.clip.x - offx, obj->cur->cache.clip.y - offy, | ||
152 | obj->cur->cache.clip.w, obj->cur->cache.clip.h); | ||
153 | return; | ||
154 | } | ||
155 | // general change (prev and cur clip geom change) | ||
156 | col_prev = (obj->prev->color.a << 24) | (obj->prev->color.r << 16) | | ||
157 | (obj->prev->color.g << 8) | (obj->prev->color.b ); | ||
158 | col_cur = (obj->cur->color.a << 24) | (obj->cur->color.r << 16) | | ||
159 | (obj->cur->color.g << 8) | (obj->cur->color.b ); | ||
160 | if ((col_prev != col_cur) || | ||
161 | ((obj->cur->cache.clip.x != obj->prev->cache.clip.x) || | ||
162 | (obj->cur->cache.clip.y != obj->prev->cache.clip.y) || | ||
163 | (obj->cur->cache.clip.w != obj->prev->cache.clip.w) || | ||
164 | (obj->cur->cache.clip.h != obj->prev->cache.clip.h)) || | ||
165 | (obj->cur->render_op != obj->prev->render_op) || | ||
166 | (obj->restack) | ||
167 | ) | ||
168 | { | ||
169 | printf(" UP2 %p - %i %i %ix%i\n", eo_obj, | ||
170 | obj->prev->cache.clip.x, obj->prev->cache.clip.y, | ||
171 | obj->prev->cache.clip.w, obj->prev->cache.clip.h); | ||
172 | evas_common_tilebuf_add_redraw | ||
173 | (updates, | ||
174 | obj->prev->cache.clip.x - offx, obj->prev->cache.clip.y - offy, | ||
175 | obj->prev->cache.clip.w, obj->prev->cache.clip.h); | ||
176 | evas_common_tilebuf_add_redraw | ||
177 | (updates, | ||
178 | obj->cur->cache.clip.x - offx, obj->cur->cache.clip.y - offy, | ||
179 | obj->cur->cache.clip.w, obj->cur->cache.clip.h); | ||
180 | return; | ||
181 | } | ||
182 | nochange: | ||
183 | // object hasn't really changed | ||
184 | if ((visible_is) && (evas_object_is_opaque(eo_obj, obj))) | ||
185 | { | ||
186 | printf(" NO- %p - %i %i %ix%i\n", eo_obj, | ||
187 | obj->cur->cache.clip.x, obj->cur->cache.clip.y, | ||
188 | obj->cur->cache.clip.w, obj->cur->cache.clip.h); | ||
189 | evas_common_tilebuf_del_redraw | ||
190 | (updates, | ||
191 | obj->cur->cache.clip.x - offx, obj->cur->cache.clip.y - offy, | ||
192 | obj->cur->cache.clip.w, obj->cur->cache.clip.h); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | static void | ||
120 | evas_object_rectangle_render(Evas_Object *eo_obj EINA_UNUSED, | 197 | evas_object_rectangle_render(Evas_Object *eo_obj EINA_UNUSED, |
121 | Evas_Object_Protected_Data *obj, | 198 | Evas_Object_Protected_Data *obj, |
122 | void *type_private_data EINA_UNUSED, | 199 | void *type_private_data EINA_UNUSED, |
diff --git a/src/lib/evas/canvas/evas_object_smart.c b/src/lib/evas/canvas/evas_object_smart.c index 3aeb9376dd..b5ced9eb1e 100644 --- a/src/lib/evas/canvas/evas_object_smart.c +++ b/src/lib/evas/canvas/evas_object_smart.c | |||
@@ -434,7 +434,6 @@ _evas_object_smart_members_get(Eo *eo_obj, Evas_Smart_Data *o) | |||
434 | Eina_List *members = NULL; | 434 | Eina_List *members = NULL; |
435 | Eina_Inlist *member; | 435 | Eina_Inlist *member; |
436 | 436 | ||
437 | evas_object_async_block(obj); | ||
438 | for (member = o->contained; member; member = member->next) | 437 | for (member = o->contained; member; member = member->next) |
439 | members = eina_list_append(members, ((Evas_Object_Protected_Data *)member)->object); | 438 | members = eina_list_append(members, ((Evas_Object_Protected_Data *)member)->object); |
440 | 439 | ||
@@ -448,7 +447,6 @@ evas_object_smart_members_get_direct(const Evas_Object *eo_obj) | |||
448 | MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ); | 447 | MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ); |
449 | return NULL; | 448 | return NULL; |
450 | MAGIC_CHECK_END(); | 449 | MAGIC_CHECK_END(); |
451 | evas_object_async_block(obj); | ||
452 | if (!eo_isa(eo_obj, MY_CLASS)) return NULL; | 450 | if (!eo_isa(eo_obj, MY_CLASS)) return NULL; |
453 | Evas_Smart_Data *o = eo_data_scope_get(eo_obj, MY_CLASS); | 451 | Evas_Smart_Data *o = eo_data_scope_get(eo_obj, MY_CLASS); |
454 | return o->contained; | 452 | return o->contained; |
diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index 0625f3520d..b97552cd11 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c | |||
@@ -2818,6 +2818,17 @@ _evas_canvas_render2(Eo *eo_e, Evas_Public_Data *e) | |||
2818 | return ret; | 2818 | return ret; |
2819 | } | 2819 | } |
2820 | 2820 | ||
2821 | EOLIAN Eina_List * | ||
2822 | _evas_canvas_render2_updates(Eo *eo_e, Evas_Public_Data *e) | ||
2823 | { | ||
2824 | Eina_List *updates = NULL; | ||
2825 | |||
2826 | eina_evlog("+render2_updates", eo_e, 0.0, NULL); | ||
2827 | updates = _evas_render2_updates(eo_e, e); | ||
2828 | eina_evlog("-render2_updates", eo_e, 0.0, NULL); | ||
2829 | return updates; | ||
2830 | } | ||
2831 | |||
2821 | EOLIAN Eina_Bool | 2832 | EOLIAN Eina_Bool |
2822 | _evas_canvas_render_async(Eo *eo_e, Evas_Public_Data *e) | 2833 | _evas_canvas_render_async(Eo *eo_e, Evas_Public_Data *e) |
2823 | { | 2834 | { |
diff --git a/src/lib/evas/canvas/render2/evas_render2.c b/src/lib/evas/canvas/render2/evas_render2.c index b4080e411a..803101b1ee 100644 --- a/src/lib/evas/canvas/render2/evas_render2.c +++ b/src/lib/evas/canvas/render2/evas_render2.c | |||
@@ -1,6 +1,5 @@ | |||
1 | #include "evas_render2.h" | 1 | #include "evas_render2.h" |
2 | 2 | ||
3 | #ifdef EVAS_RENDER_DEBUG_TIMING | ||
4 | #include <sys/time.h> | 3 | #include <sys/time.h> |
5 | 4 | ||
6 | #ifndef _WIN32 | 5 | #ifndef _WIN32 |
@@ -23,12 +22,8 @@ static inline void | |||
23 | out_time(double t) | 22 | out_time(double t) |
24 | { | 23 | { |
25 | double b = (t * 100.0) / (1.0 / 60.0); | 24 | double b = (t * 100.0) / (1.0 / 60.0); |
26 | printf("%1.8fs (%1.2f%% 60fps budget)\n", t, b); | 25 | printf("%1.2f%% / 60fps\n", b); |
27 | } | 26 | } |
28 | #endif | ||
29 | |||
30 | // a list of canvases currently rendering | ||
31 | static Eina_List *_rendering = NULL; | ||
32 | 27 | ||
33 | static void | 28 | static void |
34 | _always_call(Eo *eo_e, Evas_Callback_Type type, void *event_info) | 29 | _always_call(Eo *eo_e, Evas_Callback_Type type, void *event_info) |
@@ -41,10 +36,31 @@ _always_call(Eo *eo_e, Evas_Callback_Type type, void *event_info) | |||
41 | for (i = 0; i < freeze_num; i++) eo_do(eo_e, eo_event_freeze()); | 36 | for (i = 0; i < freeze_num; i++) eo_do(eo_e, eo_event_freeze()); |
42 | } | 37 | } |
43 | 38 | ||
39 | // a list of canvases currently rendering | ||
40 | static Eina_List *_rendering = NULL; | ||
41 | |||
42 | // just put the thread code inlined here for now as opposed to separate files | ||
43 | #include "evas_render2_th_main.c" | ||
44 | |||
45 | // init all relevant render threads if needed | ||
46 | static void | ||
47 | _evas_render2_th_init(void) | ||
48 | { | ||
49 | static Eina_Bool initted = EINA_FALSE; | ||
50 | |||
51 | if (initted) return; | ||
52 | initted = EINA_TRUE; | ||
53 | _th_main_queue = eina_thread_queue_new(); | ||
54 | if (!eina_thread_create(&_th_main, EINA_THREAD_URGENT, 0, | ||
55 | _evas_render2_th_main, NULL)) | ||
56 | ERR("Cannot create render2 thread"); | ||
57 | } | ||
44 | 58 | ||
45 | Eina_Bool | 59 | Eina_Bool |
46 | _evas_render2(Eo *eo_e, Evas_Public_Data *e) | 60 | _evas_render2(Eo *eo_e, Evas_Public_Data *e) |
47 | { | 61 | { |
62 | double t; | ||
63 | |||
48 | // if nothing changed at all since last render - skip this frame | 64 | // if nothing changed at all since last render - skip this frame |
49 | if (!e->changed) return EINA_FALSE; | 65 | if (!e->changed) return EINA_FALSE; |
50 | // we are still rendering while being asked to render - skip this | 66 | // we are still rendering while being asked to render - skip this |
@@ -55,61 +71,61 @@ _evas_render2(Eo *eo_e, Evas_Public_Data *e) | |||
55 | if ((e->output.w != e->viewport.w) || (e->output.h != e->viewport.h)) | 71 | if ((e->output.w != e->viewport.w) || (e->output.h != e->viewport.h)) |
56 | ERR("viewport size != output size!"); | 72 | ERR("viewport size != output size!"); |
57 | 73 | ||
74 | // if render threads not initted - init them - maybe move this later? | ||
75 | _evas_render2_th_init(); | ||
76 | |||
77 | printf("------------------------------------------------ %p %p\n", eo_e, e); | ||
58 | // wait for any previous render pass to do its thing | 78 | // wait for any previous render pass to do its thing |
79 | t = get_time(); | ||
59 | evas_canvas_async_block(e); | 80 | evas_canvas_async_block(e); |
81 | t = get_time() - t; | ||
82 | printf("T: block wait: "); out_time(t); | ||
60 | // we have to calculate smare objects before render so do that here | 83 | // we have to calculate smare objects before render so do that here |
84 | t = get_time(); | ||
61 | evas_call_smarts_calculate(eo_e); | 85 | evas_call_smarts_calculate(eo_e); |
86 | t = get_time() - t; | ||
87 | printf("T: smart calc: "); out_time(t); | ||
62 | // call canvas callbacks saying we are in the pre-render state | 88 | // call canvas callbacks saying we are in the pre-render state |
63 | _always_call(eo_e, EVAS_CALLBACK_RENDER_PRE, NULL); | 89 | _always_call(eo_e, EVAS_CALLBACK_RENDER_PRE, NULL); |
64 | // bock any susbequent rneders from doing this walk | 90 | // bock any susbequent rneders from doing this walk |
65 | eina_lock_take(&(e->lock_objects)); | 91 | eina_lock_take(&(e->lock_objects)); |
66 | // XXX: gain a reference | 92 | // gain a reference |
67 | eo_ref(eo_e); | 93 | eo_ref(eo_e); |
68 | // XXX: put into the "i'm rendering" pool | 94 | // put into the "i'm rendering" pool |
69 | e->rendering = EINA_TRUE; | 95 | e->rendering = EINA_TRUE; |
70 | _rendering = eina_list_append(_rendering, eo_e); | 96 | _rendering = eina_list_append(_rendering, eo_e); |
71 | // XXX; should wake up thread here to begin doing it's work | ||
72 | |||
73 | 97 | ||
74 | 98 | // call our flush pre at this point before rendering begins... | |
75 | // XXX: call this from object walk thread | ||
76 | eina_lock_release(&(e->lock_objects)); | ||
77 | // XXX: remove from the "i'm rendering" pool - do back in mainloop | ||
78 | e->rendering = EINA_FALSE; | ||
79 | _rendering = eina_list_remove(_rendering, eo_e); | ||
80 | |||
81 | |||
82 | |||
83 | // XXX: like below - call from thread messages - figure out if they just | ||
84 | // should be dumbly called before render post anyway | ||
85 | _always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_PRE, NULL); | 99 | _always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_PRE, NULL); |
86 | _always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_POST, NULL); | ||
87 | // XXX: call render post - should be a result from thread message called | ||
88 | // from mainloop - also fill in post struct | ||
89 | Evas_Event_Render_Post post; | ||
90 | _always_call(eo_e, EVAS_CALLBACK_RENDER_POST, &post); | ||
91 | 100 | ||
92 | // XXX: release our reference | 101 | // tell main render thread to wake up and begin processing this canvas |
93 | eo_unref(eo_e); | 102 | _evas_render2_th_main_msg_render(eo_e, e); |
94 | 103 | ||
95 | printf("%p %p\n", eo_e, e); | ||
96 | return EINA_FALSE; | 104 | return EINA_FALSE; |
97 | } | 105 | } |
98 | 106 | ||
99 | void | 107 | Eina_List * |
100 | _evas_norender2(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) | 108 | _evas_render2_updates(Eo *eo_e, Evas_Public_Data *e) |
101 | { | 109 | { |
102 | evas_canvas_async_block(e); | 110 | if (!_evas_render2(eo_e, e)) return NULL; |
111 | return _evas_render2_updates_wait(eo_e, e); | ||
103 | } | 112 | } |
104 | 113 | ||
105 | Eina_List * | 114 | Eina_List * |
106 | _evas_render2_updates_wait(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) | 115 | _evas_render2_updates_wait(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) |
107 | { | 116 | { |
108 | evas_canvas_async_block(e); | 117 | evas_canvas_async_block(e); |
118 | while (e->rendering) evas_async_events_process_blocking(); | ||
109 | return NULL; | 119 | return NULL; |
110 | } | 120 | } |
111 | 121 | ||
112 | void | 122 | void |
123 | _evas_norender2(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) | ||
124 | { | ||
125 | evas_canvas_async_block(e); | ||
126 | } | ||
127 | |||
128 | void | ||
113 | _evas_render2_idle_flush(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) | 129 | _evas_render2_idle_flush(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e) |
114 | { | 130 | { |
115 | evas_canvas_async_block(e); | 131 | evas_canvas_async_block(e); |
diff --git a/src/lib/evas/canvas/render2/evas_render2.h b/src/lib/evas/canvas/render2/evas_render2.h index 95982dcef6..bdad7096f2 100644 --- a/src/lib/evas/canvas/render2/evas_render2.h +++ b/src/lib/evas/canvas/render2/evas_render2.h | |||
@@ -9,8 +9,9 @@ | |||
9 | #endif | 9 | #endif |
10 | 10 | ||
11 | Eina_Bool _evas_render2(Eo *eo_e, Evas_Public_Data *e); | 11 | Eina_Bool _evas_render2(Eo *eo_e, Evas_Public_Data *e); |
12 | void _evas_norender2(Eo *eo_e, Evas_Public_Data *e); | 12 | Eina_List *_evas_render2_updates(Eo *eo_e, Evas_Public_Data *e); |
13 | Eina_List *_evas_render2_updates_wait(Eo *eo_e, Evas_Public_Data *e); | 13 | Eina_List *_evas_render2_updates_wait(Eo *eo_e, Evas_Public_Data *e); |
14 | void _evas_norender2(Eo *eo_e, Evas_Public_Data *e); | ||
14 | void _evas_render2_idle_flush(Eo *eo_e, Evas_Public_Data *e); | 15 | void _evas_render2_idle_flush(Eo *eo_e, Evas_Public_Data *e); |
15 | void _evas_render2_sync(Eo *eo_e, Evas_Public_Data *e); | 16 | void _evas_render2_sync(Eo *eo_e, Evas_Public_Data *e); |
16 | void _evas_render2_dump(Eo *eo_e, Evas_Public_Data *e); | 17 | void _evas_render2_dump(Eo *eo_e, Evas_Public_Data *e); |
diff --git a/src/lib/evas/canvas/render2/evas_render2_th_main.c b/src/lib/evas/canvas/render2/evas_render2_th_main.c new file mode 100644 index 0000000000..c462d870f4 --- /dev/null +++ b/src/lib/evas/canvas/render2/evas_render2_th_main.c | |||
@@ -0,0 +1,265 @@ | |||
1 | //#define DBG_OBJTREE 1 | ||
2 | |||
3 | #define OBJ_ARRAY_PUSH(array, obj) \ | ||
4 | do \ | ||
5 | { \ | ||
6 | eina_array_push(array, obj); \ | ||
7 | eo_data_ref(obj->object, NULL); \ | ||
8 | } while (0) | ||
9 | |||
10 | #define OBJS_ARRAY_CLEAN(array) \ | ||
11 | do \ | ||
12 | { \ | ||
13 | Evas_Object_Protected_Data *item; \ | ||
14 | Eina_Array_Iterator iterator; \ | ||
15 | unsigned int idx; \ | ||
16 | EINA_ARRAY_ITER_NEXT(array, idx, item, iterator) \ | ||
17 | eo_data_unref(item->object, item); \ | ||
18 | eina_array_clean(array); \ | ||
19 | } while (0) | ||
20 | |||
21 | typedef struct _Msg_Main_Render Msg_Main_Render; | ||
22 | typedef struct _Render2_Finish_Data Render2_Finish_Data; | ||
23 | |||
24 | struct _Msg_Main_Render | ||
25 | { | ||
26 | Eina_Thread_Queue_Msg head; | ||
27 | Eo *eo_e; | ||
28 | Evas_Public_Data *e; | ||
29 | }; | ||
30 | |||
31 | struct _Render2_Finish_Data | ||
32 | { | ||
33 | Eo *eo_e; | ||
34 | Evas_Public_Data *e; | ||
35 | Eina_List *updates; | ||
36 | }; | ||
37 | |||
38 | static Eina_Thread_Queue *_th_main_queue = NULL; | ||
39 | static Eina_Thread _th_main; | ||
40 | |||
41 | #ifdef DBG_OBJTREE | ||
42 | static void | ||
43 | indent(int l) | ||
44 | { | ||
45 | int i; for (i = 0; i < l; i++) printf(" "); | ||
46 | } | ||
47 | #endif | ||
48 | |||
49 | static void | ||
50 | _evas_render2_th_main_delete_objects_clean(Evas_Public_Data *e) | ||
51 | { | ||
52 | Evas_Object_Protected_Data *obj; | ||
53 | unsigned int i; | ||
54 | double t; | ||
55 | |||
56 | // cleanup deferred object deletion | ||
57 | t = get_time(); | ||
58 | for (i = 0; i < e->delete_objects.count; ++i) | ||
59 | { | ||
60 | obj = eina_array_data_get(&e->delete_objects, i); | ||
61 | evas_object_free(obj->object, 1); | ||
62 | } | ||
63 | // OBJS_ARRAY_CLEAN(&e->delete_objects); | ||
64 | eina_array_clean(&e->delete_objects); | ||
65 | t = get_time() - t; | ||
66 | printf("T: object deletion: "); out_time(t); | ||
67 | } | ||
68 | |||
69 | static void | ||
70 | _evas_render2_th_main_mainloop_done(void *data, Evas_Callback_Type type EINA_UNUSED, void *event_info EINA_UNUSED) | ||
71 | { | ||
72 | Render2_Finish_Data *render_finish_data = data; | ||
73 | Evas_Event_Render_Post post; | ||
74 | Eo *eo_e; | ||
75 | Evas_Public_Data *e; | ||
76 | Eina_Rectangle *rect; | ||
77 | |||
78 | e = render_finish_data->e; | ||
79 | eo_e = render_finish_data->eo_e; | ||
80 | // call the flush post callbacks | ||
81 | _always_call(render_finish_data->eo_e, EVAS_CALLBACK_RENDER_FLUSH_POST, NULL); | ||
82 | |||
83 | // and now call the actual render post callbacks with updates list | ||
84 | post.updated_area = render_finish_data->updates; | ||
85 | _always_call(eo_e, EVAS_CALLBACK_RENDER_POST, &post); | ||
86 | |||
87 | EINA_LIST_FREE(render_finish_data->updates, rect) free(rect); | ||
88 | free(render_finish_data); | ||
89 | _evas_render2_th_main_delete_objects_clean(e); | ||
90 | } | ||
91 | |||
92 | static Eina_Bool | ||
93 | _evas_render2_th_main_obj_del_handle(Evas_Public_Data *e, | ||
94 | Evas_Object_Protected_Data *obj) | ||
95 | { | ||
96 | if (obj->delete_me == 2) | ||
97 | { | ||
98 | OBJ_ARRAY_PUSH(&e->delete_objects, obj); | ||
99 | obj->delete_me++; | ||
100 | return EINA_FALSE; | ||
101 | } | ||
102 | else if (obj->delete_me != 0) obj->delete_me++; | ||
103 | return EINA_TRUE; | ||
104 | } | ||
105 | |||
106 | static void | ||
107 | _evas_render2_th_main_obj_basic_process(Evas_Public_Data *e, | ||
108 | Evas_Object_Protected_Data *obj, | ||
109 | void *updates, | ||
110 | int offx, | ||
111 | int offy, | ||
112 | int l EINA_UNUSED) | ||
113 | { | ||
114 | Evas_Object *eo_obj = obj->object; | ||
115 | |||
116 | if (!_evas_render2_th_main_obj_del_handle(e, obj)) return; | ||
117 | evas_object_clip_recalc(obj); | ||
118 | #ifdef DBG_OBJTREE | ||
119 | indent(l); printf("BASIC %p %p [%10s]\n", e, eo_obj, obj->type); | ||
120 | #endif | ||
121 | if (obj->func->render2_walk) | ||
122 | obj->func->render2_walk(eo_obj, obj, obj->private_data, | ||
123 | updates, offx, offy); | ||
124 | if (obj->changed) | ||
125 | { | ||
126 | evas_object_clip_changes_clean(eo_obj); | ||
127 | evas_object_cur_prev(eo_obj); | ||
128 | evas_object_change_reset(eo_obj); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | static void | ||
133 | _evas_render2_th_main_obj_process(Evas_Public_Data *e, | ||
134 | Evas_Object_Protected_Data *obj, | ||
135 | void *updates, | ||
136 | int offx, | ||
137 | int offy, | ||
138 | int l EINA_UNUSED) | ||
139 | { | ||
140 | // process object OR walk through child objects if smart and process those | ||
141 | Evas_Object_Protected_Data *obj2; | ||
142 | Evas_Object *eo_obj = obj->object; | ||
143 | const Eina_Inlist *il; | ||
144 | |||
145 | if (!obj->changed) return; | ||
146 | il = evas_object_smart_members_get_direct(eo_obj); | ||
147 | if (il) | ||
148 | { | ||
149 | if (!_evas_render2_th_main_obj_del_handle(e, obj)) return; | ||
150 | evas_object_clip_recalc(obj); | ||
151 | #ifdef DBG_OBJTREE | ||
152 | indent(l); printf("SMART %p %p [%10s] ch %i\n", e, eo_obj, obj->type, obj->changed); | ||
153 | #endif | ||
154 | if (obj->func->render2_walk) | ||
155 | obj->func->render2_walk(eo_obj, obj, obj->private_data, | ||
156 | updates, offx, offy); | ||
157 | EINA_INLIST_FOREACH(il, obj2) | ||
158 | _evas_render2_th_main_obj_process(e, obj2, updates, | ||
159 | offx, offy, l + 1); | ||
160 | if (obj->changed) | ||
161 | { | ||
162 | evas_object_clip_changes_clean(eo_obj); | ||
163 | evas_object_cur_prev(eo_obj); | ||
164 | evas_object_change_reset(eo_obj); | ||
165 | } | ||
166 | } | ||
167 | else _evas_render2_th_main_obj_basic_process(e, obj, updates, | ||
168 | offx, offy, l); | ||
169 | } | ||
170 | |||
171 | static void | ||
172 | _evas_render2_th_main_do(Eo *eo_e, Evas_Public_Data *e) | ||
173 | { | ||
174 | Render2_Finish_Data *render_finish_data; | ||
175 | Evas_Layer *lay; | ||
176 | Evas_Object_Protected_Data *obj; | ||
177 | double t; | ||
178 | Tilebuf *updates = NULL; | ||
179 | Tilebuf_Rect *rects, *r; | ||
180 | Eina_List *updates_list = NULL; | ||
181 | Eina_Rectangle *rect; | ||
182 | |||
183 | updates = evas_common_tilebuf_new(e->output.w, e->output.h); | ||
184 | evas_common_tilebuf_set_tile_size(updates, TILESIZE, TILESIZE); | ||
185 | // evas_common_tilebuf_tile_strict_set(updates, EINA_TRUE); | ||
186 | static int num = 0; | ||
187 | printf("........... updates # %i\n", num++); | ||
188 | t = get_time(); | ||
189 | EINA_INLIST_FOREACH(e->layers, lay) | ||
190 | { | ||
191 | EINA_INLIST_FOREACH(lay->objects, obj) | ||
192 | { | ||
193 | _evas_render2_th_main_obj_process(e, obj, | ||
194 | updates, 0, 0, | ||
195 | 0); | ||
196 | } | ||
197 | } | ||
198 | t = get_time() - t; | ||
199 | printf("T: update generation: "); out_time(t); | ||
200 | |||
201 | rects = evas_common_tilebuf_get_render_rects(updates); | ||
202 | EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r) | ||
203 | { | ||
204 | rect = malloc(sizeof(Eina_Rectangle)); | ||
205 | if (rect) | ||
206 | { | ||
207 | printf(" %i %i %ix%i\n", r->x, r->y, r->w, r->h); | ||
208 | rect->x = r->x; rect->y = r->y; | ||
209 | rect->w = r->w; rect->h = r->h; | ||
210 | updates_list = eina_list_append(updates_list, rect); | ||
211 | } | ||
212 | } | ||
213 | evas_common_tilebuf_free_render_rects(rects); | ||
214 | |||
215 | evas_common_tilebuf_free(updates); | ||
216 | |||
217 | e->changed = EINA_FALSE; | ||
218 | // remove from the "i'm rendering" pool - do back in mainloop | ||
219 | e->rendering = EINA_FALSE; | ||
220 | _rendering = eina_list_remove(_rendering, eo_e); | ||
221 | // unblock mainlopp that may be waiting on the render thread | ||
222 | eina_lock_release(&(e->lock_objects)); | ||
223 | |||
224 | // send back | ||
225 | render_finish_data = calloc(1, sizeof(Render2_Finish_Data)); | ||
226 | if (render_finish_data) | ||
227 | { | ||
228 | render_finish_data->eo_e = eo_e; | ||
229 | render_finish_data->e = e; | ||
230 | render_finish_data->updates = updates_list; | ||
231 | evas_async_events_put(render_finish_data, 0, NULL, | ||
232 | _evas_render2_th_main_mainloop_done); | ||
233 | } | ||
234 | else | ||
235 | { | ||
236 | EINA_LIST_FREE(updates_list, rect) free(rect); | ||
237 | } | ||
238 | eo_unref(eo_e); | ||
239 | } | ||
240 | |||
241 | static void * | ||
242 | _evas_render2_th_main(void *data EINA_UNUSED, Eina_Thread thread EINA_UNUSED) | ||
243 | { | ||
244 | void *ref = NULL; | ||
245 | Msg_Main_Render *msg; | ||
246 | |||
247 | for (;;) | ||
248 | { | ||
249 | msg = eina_thread_queue_wait(_th_main_queue, &ref); | ||
250 | _evas_render2_th_main_do(msg->eo_e, msg->e); | ||
251 | eina_thread_queue_wait_done(_th_main_queue, ref); | ||
252 | } | ||
253 | return NULL; | ||
254 | } | ||
255 | |||
256 | static void | ||
257 | _evas_render2_th_main_msg_render(Eo *eo_e, Evas_Public_Data *e) | ||
258 | { | ||
259 | void *ref; | ||
260 | Msg_Main_Render *msg = | ||
261 | eina_thread_queue_send(_th_main_queue, sizeof(Msg_Main_Render), &ref); | ||
262 | msg->eo_e = eo_e; | ||
263 | msg->e = e; | ||
264 | eina_thread_queue_send_done(_th_main_queue, ref); | ||
265 | } | ||
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 52feb58367..b2678df042 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h | |||
@@ -1216,6 +1216,15 @@ struct _Evas_Object_Func | |||
1216 | Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); | 1216 | Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); |
1217 | 1217 | ||
1218 | int (*can_map) (Evas_Object *obj); | 1218 | int (*can_map) (Evas_Object *obj); |
1219 | |||
1220 | // new render2 functions | ||
1221 | |||
1222 | void (*render2_walk) (Evas_Object *obj, Evas_Object_Protected_Data *pd, | ||
1223 | void *type_private_data, void *updates, | ||
1224 | int offx, int offy); | ||
1225 | // void (*render2) (Evas_Object *obj, Evas_Object_Protected_Data *pd, | ||
1226 | // void *type_private_data, void *output, void *context, | ||
1227 | // void *surface, int x, int y); | ||
1219 | }; | 1228 | }; |
1220 | 1229 | ||
1221 | struct _Evas_Func | 1230 | struct _Evas_Func |
diff --git a/src/modules/ecore_evas/engines/x/ecore_evas_x.c b/src/modules/ecore_evas/engines/x/ecore_evas_x.c index 63ccfbce5d..a090da7cae 100644 --- a/src/modules/ecore_evas/engines/x/ecore_evas_x.c +++ b/src/modules/ecore_evas/engines/x/ecore_evas_x.c | |||
@@ -759,6 +759,7 @@ _ecore_evas_x_render(Ecore_Evas *ee) | |||
759 | Eina_List *ll; | 759 | Eina_List *ll; |
760 | Ecore_Evas *ee2; | 760 | Ecore_Evas *ee2; |
761 | Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data; | 761 | Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data; |
762 | static int render2 = -1; | ||
762 | 763 | ||
763 | if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync) && | 764 | if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync) && |
764 | (edata->sync_counter) && (!edata->sync_began) && | 765 | (edata->sync_counter) && (!edata->sync_began) && |
@@ -780,20 +781,42 @@ _ecore_evas_x_render(Ecore_Evas *ee) | |||
780 | } | 781 | } |
781 | 782 | ||
782 | if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); | 783 | if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); |
783 | if (!ee->can_async_render) | 784 | if (render2 == -1) |
784 | { | 785 | { |
785 | Eina_List *updates = evas_render_updates(ee->evas); | 786 | if (getenv("RENDER2")) render2 = 1; |
786 | rend = _render_updates_process(ee, updates); | 787 | else render2 = 0; |
787 | evas_render_updates_free(updates); | ||
788 | } | 788 | } |
789 | else if (evas_render_async(ee->evas)) | 789 | if (render2) |
790 | { | 790 | { |
791 | EDBG("ee=%p started asynchronous render.", ee); | 791 | if (!ee->can_async_render) |
792 | ee->in_async_render = EINA_TRUE; | 792 | { |
793 | rend = 1; | 793 | Eina_List *updates = evas_render2_updates(ee->evas); |
794 | rend = _render_updates_process(ee, updates); | ||
795 | evas_render_updates_free(updates); | ||
796 | } | ||
797 | else | ||
798 | { | ||
799 | ee->in_async_render = EINA_TRUE; | ||
800 | if (evas_render2(ee->evas)) rend = 1; | ||
801 | else ee->in_async_render = EINA_FALSE; | ||
802 | } | ||
803 | } | ||
804 | else | ||
805 | { | ||
806 | if (!ee->can_async_render) | ||
807 | { | ||
808 | Eina_List *updates = evas_render_updates(ee->evas); | ||
809 | rend = _render_updates_process(ee, updates); | ||
810 | evas_render_updates_free(updates); | ||
811 | } | ||
812 | else if (evas_render_async(ee->evas)) | ||
813 | { | ||
814 | EDBG("ee=%p started asynchronous render.", ee); | ||
815 | ee->in_async_render = EINA_TRUE; | ||
816 | rend = 1; | ||
817 | } | ||
818 | else if (ee->func.fn_post_render) ee->func.fn_post_render(ee); | ||
794 | } | 819 | } |
795 | else if (ee->func.fn_post_render) ee->func.fn_post_render(ee); | ||
796 | |||
797 | return rend; | 820 | return rend; |
798 | } | 821 | } |
799 | 822 | ||