forked from enlightenment/efl
evas render2 work - begin to make rectangles deal with render 2 basic
infra
This commit is contained in:
parent
0a2362fa69
commit
25983dcedd
|
@ -892,6 +892,22 @@ class Evas.Canvas (Eo.Base, Evas.Common_Interface)
|
|||
|
||||
return: bool;
|
||||
}
|
||||
render2_updates {
|
||||
/*@
|
||||
Render the given Evas canvas using the new rendering infra.
|
||||
|
||||
This is experimental and will change over time until noted here.
|
||||
|
||||
@return A newly allocated list of updated rectangles of thecanvas
|
||||
(@c Eina.Rectangle structs). Free this list with
|
||||
evas_render_updates_free().
|
||||
|
||||
@ingroup Evas_Canvas
|
||||
@since 1.15 */
|
||||
|
||||
return: free(own(list<Eina.Rectangle *> *), evas_render_updates_free)
|
||||
@warn_unused;
|
||||
}
|
||||
focus_out {
|
||||
/*@
|
||||
Inform to the evas that it lost the focus.
|
||||
|
|
|
@ -41,6 +41,13 @@ static int evas_object_rectangle_was_opaque(Evas_Object *eo_obj,
|
|||
Evas_Object_Protected_Data *obj,
|
||||
void *type_private_data);
|
||||
|
||||
static void evas_object_rectangle_render2_walk(Evas_Object *eo_obj,
|
||||
Evas_Object_Protected_Data *obj,
|
||||
void *type_private_data,
|
||||
void *updates,
|
||||
int offx,
|
||||
int offy);
|
||||
|
||||
#if 0 /* usless calls for a rect object. much more useful for images etc. */
|
||||
static void evas_object_rectangle_store(Evas_Object *eo_obj);
|
||||
static void evas_object_rectangle_unstore(Evas_Object *eo_obj);
|
||||
|
@ -73,7 +80,8 @@ static const Evas_Object_Func object_func =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
evas_object_rectangle_render2_walk
|
||||
};
|
||||
|
||||
/* the actual api call to add a rect */
|
||||
|
@ -116,6 +124,75 @@ evas_object_rectangle_init(Evas_Object *eo_obj)
|
|||
obj->type = o_type;
|
||||
}
|
||||
|
||||
static void
|
||||
evas_object_rectangle_render2_walk(Evas_Object *eo_obj,
|
||||
Evas_Object_Protected_Data *obj,
|
||||
void *type_private_data EINA_UNUSED,
|
||||
void *updates, int offx, int offy)
|
||||
{
|
||||
Eina_Bool visible_is, visible_was;
|
||||
unsigned int col_prev, col_cur;
|
||||
|
||||
if (obj->clip.clipees) return;
|
||||
visible_is = evas_object_is_visible(eo_obj, obj);
|
||||
if (!obj->changed) goto nochange;
|
||||
|
||||
if ((obj->cur->clipper) && (obj->cur->cache.clip.dirty))
|
||||
evas_object_clip_recalc(obj->cur->clipper);
|
||||
visible_was = evas_object_was_visible(eo_obj,obj);
|
||||
// just became visible or invisible
|
||||
if (visible_is != visible_was)
|
||||
{
|
||||
printf(" UP1 %p - %i %i %ix%i\n", eo_obj,
|
||||
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
||||
obj->cur->cache.clip.w, obj->cur->cache.clip.h);
|
||||
evas_common_tilebuf_add_redraw
|
||||
(updates,
|
||||
obj->cur->cache.clip.x - offx, obj->cur->cache.clip.y - offy,
|
||||
obj->cur->cache.clip.w, obj->cur->cache.clip.h);
|
||||
return;
|
||||
}
|
||||
// general change (prev and cur clip geom change)
|
||||
col_prev = (obj->prev->color.a << 24) | (obj->prev->color.r << 16) |
|
||||
(obj->prev->color.g << 8) | (obj->prev->color.b );
|
||||
col_cur = (obj->cur->color.a << 24) | (obj->cur->color.r << 16) |
|
||||
(obj->cur->color.g << 8) | (obj->cur->color.b );
|
||||
if ((col_prev != col_cur) ||
|
||||
((obj->cur->cache.clip.x != obj->prev->cache.clip.x) ||
|
||||
(obj->cur->cache.clip.y != obj->prev->cache.clip.y) ||
|
||||
(obj->cur->cache.clip.w != obj->prev->cache.clip.w) ||
|
||||
(obj->cur->cache.clip.h != obj->prev->cache.clip.h)) ||
|
||||
(obj->cur->render_op != obj->prev->render_op) ||
|
||||
(obj->restack)
|
||||
)
|
||||
{
|
||||
printf(" UP2 %p - %i %i %ix%i\n", eo_obj,
|
||||
obj->prev->cache.clip.x, obj->prev->cache.clip.y,
|
||||
obj->prev->cache.clip.w, obj->prev->cache.clip.h);
|
||||
evas_common_tilebuf_add_redraw
|
||||
(updates,
|
||||
obj->prev->cache.clip.x - offx, obj->prev->cache.clip.y - offy,
|
||||
obj->prev->cache.clip.w, obj->prev->cache.clip.h);
|
||||
evas_common_tilebuf_add_redraw
|
||||
(updates,
|
||||
obj->cur->cache.clip.x - offx, obj->cur->cache.clip.y - offy,
|
||||
obj->cur->cache.clip.w, obj->cur->cache.clip.h);
|
||||
return;
|
||||
}
|
||||
nochange:
|
||||
// object hasn't really changed
|
||||
if ((visible_is) && (evas_object_is_opaque(eo_obj, obj)))
|
||||
{
|
||||
printf(" NO- %p - %i %i %ix%i\n", eo_obj,
|
||||
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
||||
obj->cur->cache.clip.w, obj->cur->cache.clip.h);
|
||||
evas_common_tilebuf_del_redraw
|
||||
(updates,
|
||||
obj->cur->cache.clip.x - offx, obj->cur->cache.clip.y - offy,
|
||||
obj->cur->cache.clip.w, obj->cur->cache.clip.h);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
evas_object_rectangle_render(Evas_Object *eo_obj EINA_UNUSED,
|
||||
Evas_Object_Protected_Data *obj,
|
||||
|
|
|
@ -434,7 +434,6 @@ _evas_object_smart_members_get(Eo *eo_obj, Evas_Smart_Data *o)
|
|||
Eina_List *members = NULL;
|
||||
Eina_Inlist *member;
|
||||
|
||||
evas_object_async_block(obj);
|
||||
for (member = o->contained; member; member = member->next)
|
||||
members = eina_list_append(members, ((Evas_Object_Protected_Data *)member)->object);
|
||||
|
||||
|
@ -448,7 +447,6 @@ evas_object_smart_members_get_direct(const Evas_Object *eo_obj)
|
|||
MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);
|
||||
return NULL;
|
||||
MAGIC_CHECK_END();
|
||||
evas_object_async_block(obj);
|
||||
if (!eo_isa(eo_obj, MY_CLASS)) return NULL;
|
||||
Evas_Smart_Data *o = eo_data_scope_get(eo_obj, MY_CLASS);
|
||||
return o->contained;
|
||||
|
|
|
@ -2818,6 +2818,17 @@ _evas_canvas_render2(Eo *eo_e, Evas_Public_Data *e)
|
|||
return ret;
|
||||
}
|
||||
|
||||
EOLIAN Eina_List *
|
||||
_evas_canvas_render2_updates(Eo *eo_e, Evas_Public_Data *e)
|
||||
{
|
||||
Eina_List *updates = NULL;
|
||||
|
||||
eina_evlog("+render2_updates", eo_e, 0.0, NULL);
|
||||
updates = _evas_render2_updates(eo_e, e);
|
||||
eina_evlog("-render2_updates", eo_e, 0.0, NULL);
|
||||
return updates;
|
||||
}
|
||||
|
||||
EOLIAN Eina_Bool
|
||||
_evas_canvas_render_async(Eo *eo_e, Evas_Public_Data *e)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "evas_render2.h"
|
||||
|
||||
#ifdef EVAS_RENDER_DEBUG_TIMING
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
@ -23,12 +22,8 @@ static inline void
|
|||
out_time(double t)
|
||||
{
|
||||
double b = (t * 100.0) / (1.0 / 60.0);
|
||||
printf("%1.8fs (%1.2f%% 60fps budget)\n", t, b);
|
||||
printf("%1.2f%% / 60fps\n", b);
|
||||
}
|
||||
#endif
|
||||
|
||||
// a list of canvases currently rendering
|
||||
static Eina_List *_rendering = NULL;
|
||||
|
||||
static void
|
||||
_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)
|
|||
for (i = 0; i < freeze_num; i++) eo_do(eo_e, eo_event_freeze());
|
||||
}
|
||||
|
||||
// a list of canvases currently rendering
|
||||
static Eina_List *_rendering = NULL;
|
||||
|
||||
// just put the thread code inlined here for now as opposed to separate files
|
||||
#include "evas_render2_th_main.c"
|
||||
|
||||
// init all relevant render threads if needed
|
||||
static void
|
||||
_evas_render2_th_init(void)
|
||||
{
|
||||
static Eina_Bool initted = EINA_FALSE;
|
||||
|
||||
if (initted) return;
|
||||
initted = EINA_TRUE;
|
||||
_th_main_queue = eina_thread_queue_new();
|
||||
if (!eina_thread_create(&_th_main, EINA_THREAD_URGENT, 0,
|
||||
_evas_render2_th_main, NULL))
|
||||
ERR("Cannot create render2 thread");
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_evas_render2(Eo *eo_e, Evas_Public_Data *e)
|
||||
{
|
||||
double t;
|
||||
|
||||
// if nothing changed at all since last render - skip this frame
|
||||
if (!e->changed) return EINA_FALSE;
|
||||
// we are still rendering while being asked to render - skip this
|
||||
|
@ -55,60 +71,60 @@ _evas_render2(Eo *eo_e, Evas_Public_Data *e)
|
|||
if ((e->output.w != e->viewport.w) || (e->output.h != e->viewport.h))
|
||||
ERR("viewport size != output size!");
|
||||
|
||||
// if render threads not initted - init them - maybe move this later?
|
||||
_evas_render2_th_init();
|
||||
|
||||
printf("------------------------------------------------ %p %p\n", eo_e, e);
|
||||
// wait for any previous render pass to do its thing
|
||||
t = get_time();
|
||||
evas_canvas_async_block(e);
|
||||
t = get_time() - t;
|
||||
printf("T: block wait: "); out_time(t);
|
||||
// we have to calculate smare objects before render so do that here
|
||||
t = get_time();
|
||||
evas_call_smarts_calculate(eo_e);
|
||||
t = get_time() - t;
|
||||
printf("T: smart calc: "); out_time(t);
|
||||
// call canvas callbacks saying we are in the pre-render state
|
||||
_always_call(eo_e, EVAS_CALLBACK_RENDER_PRE, NULL);
|
||||
// bock any susbequent rneders from doing this walk
|
||||
eina_lock_take(&(e->lock_objects));
|
||||
// XXX: gain a reference
|
||||
// gain a reference
|
||||
eo_ref(eo_e);
|
||||
// XXX: put into the "i'm rendering" pool
|
||||
// put into the "i'm rendering" pool
|
||||
e->rendering = EINA_TRUE;
|
||||
_rendering = eina_list_append(_rendering, eo_e);
|
||||
// XXX; should wake up thread here to begin doing it's work
|
||||
|
||||
|
||||
|
||||
// XXX: call this from object walk thread
|
||||
eina_lock_release(&(e->lock_objects));
|
||||
// XXX: remove from the "i'm rendering" pool - do back in mainloop
|
||||
e->rendering = EINA_FALSE;
|
||||
_rendering = eina_list_remove(_rendering, eo_e);
|
||||
|
||||
|
||||
|
||||
// XXX: like below - call from thread messages - figure out if they just
|
||||
// should be dumbly called before render post anyway
|
||||
// call our flush pre at this point before rendering begins...
|
||||
_always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_PRE, NULL);
|
||||
_always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_POST, NULL);
|
||||
// XXX: call render post - should be a result from thread message called
|
||||
// from mainloop - also fill in post struct
|
||||
Evas_Event_Render_Post post;
|
||||
_always_call(eo_e, EVAS_CALLBACK_RENDER_POST, &post);
|
||||
|
||||
// XXX: release our reference
|
||||
eo_unref(eo_e);
|
||||
// tell main render thread to wake up and begin processing this canvas
|
||||
_evas_render2_th_main_msg_render(eo_e, e);
|
||||
|
||||
printf("%p %p\n", eo_e, e);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_evas_norender2(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
|
||||
Eina_List *
|
||||
_evas_render2_updates(Eo *eo_e, Evas_Public_Data *e)
|
||||
{
|
||||
evas_canvas_async_block(e);
|
||||
if (!_evas_render2(eo_e, e)) return NULL;
|
||||
return _evas_render2_updates_wait(eo_e, e);
|
||||
}
|
||||
|
||||
Eina_List *
|
||||
_evas_render2_updates_wait(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
|
||||
{
|
||||
evas_canvas_async_block(e);
|
||||
while (e->rendering) evas_async_events_process_blocking();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_evas_norender2(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
|
||||
{
|
||||
evas_canvas_async_block(e);
|
||||
}
|
||||
|
||||
void
|
||||
_evas_render2_idle_flush(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
|
||||
{
|
||||
|
|
|
@ -9,8 +9,9 @@
|
|||
#endif
|
||||
|
||||
Eina_Bool _evas_render2(Eo *eo_e, Evas_Public_Data *e);
|
||||
void _evas_norender2(Eo *eo_e, Evas_Public_Data *e);
|
||||
Eina_List *_evas_render2_updates(Eo *eo_e, Evas_Public_Data *e);
|
||||
Eina_List *_evas_render2_updates_wait(Eo *eo_e, Evas_Public_Data *e);
|
||||
void _evas_norender2(Eo *eo_e, Evas_Public_Data *e);
|
||||
void _evas_render2_idle_flush(Eo *eo_e, Evas_Public_Data *e);
|
||||
void _evas_render2_sync(Eo *eo_e, Evas_Public_Data *e);
|
||||
void _evas_render2_dump(Eo *eo_e, Evas_Public_Data *e);
|
||||
|
|
|
@ -0,0 +1,265 @@
|
|||
//#define DBG_OBJTREE 1
|
||||
|
||||
#define OBJ_ARRAY_PUSH(array, obj) \
|
||||
do \
|
||||
{ \
|
||||
eina_array_push(array, obj); \
|
||||
eo_data_ref(obj->object, NULL); \
|
||||
} while (0)
|
||||
|
||||
#define OBJS_ARRAY_CLEAN(array) \
|
||||
do \
|
||||
{ \
|
||||
Evas_Object_Protected_Data *item; \
|
||||
Eina_Array_Iterator iterator; \
|
||||
unsigned int idx; \
|
||||
EINA_ARRAY_ITER_NEXT(array, idx, item, iterator) \
|
||||
eo_data_unref(item->object, item); \
|
||||
eina_array_clean(array); \
|
||||
} while (0)
|
||||
|
||||
typedef struct _Msg_Main_Render Msg_Main_Render;
|
||||
typedef struct _Render2_Finish_Data Render2_Finish_Data;
|
||||
|
||||
struct _Msg_Main_Render
|
||||
{
|
||||
Eina_Thread_Queue_Msg head;
|
||||
Eo *eo_e;
|
||||
Evas_Public_Data *e;
|
||||
};
|
||||
|
||||
struct _Render2_Finish_Data
|
||||
{
|
||||
Eo *eo_e;
|
||||
Evas_Public_Data *e;
|
||||
Eina_List *updates;
|
||||
};
|
||||
|
||||
static Eina_Thread_Queue *_th_main_queue = NULL;
|
||||
static Eina_Thread _th_main;
|
||||
|
||||
#ifdef DBG_OBJTREE
|
||||
static void
|
||||
indent(int l)
|
||||
{
|
||||
int i; for (i = 0; i < l; i++) printf(" ");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
_evas_render2_th_main_delete_objects_clean(Evas_Public_Data *e)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj;
|
||||
unsigned int i;
|
||||
double t;
|
||||
|
||||
// cleanup deferred object deletion
|
||||
t = get_time();
|
||||
for (i = 0; i < e->delete_objects.count; ++i)
|
||||
{
|
||||
obj = eina_array_data_get(&e->delete_objects, i);
|
||||
evas_object_free(obj->object, 1);
|
||||
}
|
||||
// OBJS_ARRAY_CLEAN(&e->delete_objects);
|
||||
eina_array_clean(&e->delete_objects);
|
||||
t = get_time() - t;
|
||||
printf("T: object deletion: "); out_time(t);
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_render2_th_main_mainloop_done(void *data, Evas_Callback_Type type EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Render2_Finish_Data *render_finish_data = data;
|
||||
Evas_Event_Render_Post post;
|
||||
Eo *eo_e;
|
||||
Evas_Public_Data *e;
|
||||
Eina_Rectangle *rect;
|
||||
|
||||
e = render_finish_data->e;
|
||||
eo_e = render_finish_data->eo_e;
|
||||
// call the flush post callbacks
|
||||
_always_call(render_finish_data->eo_e, EVAS_CALLBACK_RENDER_FLUSH_POST, NULL);
|
||||
|
||||
// and now call the actual render post callbacks with updates list
|
||||
post.updated_area = render_finish_data->updates;
|
||||
_always_call(eo_e, EVAS_CALLBACK_RENDER_POST, &post);
|
||||
|
||||
EINA_LIST_FREE(render_finish_data->updates, rect) free(rect);
|
||||
free(render_finish_data);
|
||||
_evas_render2_th_main_delete_objects_clean(e);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_evas_render2_th_main_obj_del_handle(Evas_Public_Data *e,
|
||||
Evas_Object_Protected_Data *obj)
|
||||
{
|
||||
if (obj->delete_me == 2)
|
||||
{
|
||||
OBJ_ARRAY_PUSH(&e->delete_objects, obj);
|
||||
obj->delete_me++;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
else if (obj->delete_me != 0) obj->delete_me++;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_render2_th_main_obj_basic_process(Evas_Public_Data *e,
|
||||
Evas_Object_Protected_Data *obj,
|
||||
void *updates,
|
||||
int offx,
|
||||
int offy,
|
||||
int l EINA_UNUSED)
|
||||
{
|
||||
Evas_Object *eo_obj = obj->object;
|
||||
|
||||
if (!_evas_render2_th_main_obj_del_handle(e, obj)) return;
|
||||
evas_object_clip_recalc(obj);
|
||||
#ifdef DBG_OBJTREE
|
||||
indent(l); printf("BASIC %p %p [%10s]\n", e, eo_obj, obj->type);
|
||||
#endif
|
||||
if (obj->func->render2_walk)
|
||||
obj->func->render2_walk(eo_obj, obj, obj->private_data,
|
||||
updates, offx, offy);
|
||||
if (obj->changed)
|
||||
{
|
||||
evas_object_clip_changes_clean(eo_obj);
|
||||
evas_object_cur_prev(eo_obj);
|
||||
evas_object_change_reset(eo_obj);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_render2_th_main_obj_process(Evas_Public_Data *e,
|
||||
Evas_Object_Protected_Data *obj,
|
||||
void *updates,
|
||||
int offx,
|
||||
int offy,
|
||||
int l EINA_UNUSED)
|
||||
{
|
||||
// process object OR walk through child objects if smart and process those
|
||||
Evas_Object_Protected_Data *obj2;
|
||||
Evas_Object *eo_obj = obj->object;
|
||||
const Eina_Inlist *il;
|
||||
|
||||
if (!obj->changed) return;
|
||||
il = evas_object_smart_members_get_direct(eo_obj);
|
||||
if (il)
|
||||
{
|
||||
if (!_evas_render2_th_main_obj_del_handle(e, obj)) return;
|
||||
evas_object_clip_recalc(obj);
|
||||
#ifdef DBG_OBJTREE
|
||||
indent(l); printf("SMART %p %p [%10s] ch %i\n", e, eo_obj, obj->type, obj->changed);
|
||||
#endif
|
||||
if (obj->func->render2_walk)
|
||||
obj->func->render2_walk(eo_obj, obj, obj->private_data,
|
||||
updates, offx, offy);
|
||||
EINA_INLIST_FOREACH(il, obj2)
|
||||
_evas_render2_th_main_obj_process(e, obj2, updates,
|
||||
offx, offy, l + 1);
|
||||
if (obj->changed)
|
||||
{
|
||||
evas_object_clip_changes_clean(eo_obj);
|
||||
evas_object_cur_prev(eo_obj);
|
||||
evas_object_change_reset(eo_obj);
|
||||
}
|
||||
}
|
||||
else _evas_render2_th_main_obj_basic_process(e, obj, updates,
|
||||
offx, offy, l);
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_render2_th_main_do(Eo *eo_e, Evas_Public_Data *e)
|
||||
{
|
||||
Render2_Finish_Data *render_finish_data;
|
||||
Evas_Layer *lay;
|
||||
Evas_Object_Protected_Data *obj;
|
||||
double t;
|
||||
Tilebuf *updates = NULL;
|
||||
Tilebuf_Rect *rects, *r;
|
||||
Eina_List *updates_list = NULL;
|
||||
Eina_Rectangle *rect;
|
||||
|
||||
updates = evas_common_tilebuf_new(e->output.w, e->output.h);
|
||||
evas_common_tilebuf_set_tile_size(updates, TILESIZE, TILESIZE);
|
||||
// evas_common_tilebuf_tile_strict_set(updates, EINA_TRUE);
|
||||
static int num = 0;
|
||||
printf("........... updates # %i\n", num++);
|
||||
t = get_time();
|
||||
EINA_INLIST_FOREACH(e->layers, lay)
|
||||
{
|
||||
EINA_INLIST_FOREACH(lay->objects, obj)
|
||||
{
|
||||
_evas_render2_th_main_obj_process(e, obj,
|
||||
updates, 0, 0,
|
||||
0);
|
||||
}
|
||||
}
|
||||
t = get_time() - t;
|
||||
printf("T: update generation: "); out_time(t);
|
||||
|
||||
rects = evas_common_tilebuf_get_render_rects(updates);
|
||||
EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
|
||||
{
|
||||
rect = malloc(sizeof(Eina_Rectangle));
|
||||
if (rect)
|
||||
{
|
||||
printf(" %i %i %ix%i\n", r->x, r->y, r->w, r->h);
|
||||
rect->x = r->x; rect->y = r->y;
|
||||
rect->w = r->w; rect->h = r->h;
|
||||
updates_list = eina_list_append(updates_list, rect);
|
||||
}
|
||||
}
|
||||
evas_common_tilebuf_free_render_rects(rects);
|
||||
|
||||
evas_common_tilebuf_free(updates);
|
||||
|
||||
e->changed = EINA_FALSE;
|
||||
// remove from the "i'm rendering" pool - do back in mainloop
|
||||
e->rendering = EINA_FALSE;
|
||||
_rendering = eina_list_remove(_rendering, eo_e);
|
||||
// unblock mainlopp that may be waiting on the render thread
|
||||
eina_lock_release(&(e->lock_objects));
|
||||
|
||||
// send back
|
||||
render_finish_data = calloc(1, sizeof(Render2_Finish_Data));
|
||||
if (render_finish_data)
|
||||
{
|
||||
render_finish_data->eo_e = eo_e;
|
||||
render_finish_data->e = e;
|
||||
render_finish_data->updates = updates_list;
|
||||
evas_async_events_put(render_finish_data, 0, NULL,
|
||||
_evas_render2_th_main_mainloop_done);
|
||||
}
|
||||
else
|
||||
{
|
||||
EINA_LIST_FREE(updates_list, rect) free(rect);
|
||||
}
|
||||
eo_unref(eo_e);
|
||||
}
|
||||
|
||||
static void *
|
||||
_evas_render2_th_main(void *data EINA_UNUSED, Eina_Thread thread EINA_UNUSED)
|
||||
{
|
||||
void *ref = NULL;
|
||||
Msg_Main_Render *msg;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
msg = eina_thread_queue_wait(_th_main_queue, &ref);
|
||||
_evas_render2_th_main_do(msg->eo_e, msg->e);
|
||||
eina_thread_queue_wait_done(_th_main_queue, ref);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_render2_th_main_msg_render(Eo *eo_e, Evas_Public_Data *e)
|
||||
{
|
||||
void *ref;
|
||||
Msg_Main_Render *msg =
|
||||
eina_thread_queue_send(_th_main_queue, sizeof(Msg_Main_Render), &ref);
|
||||
msg->eo_e = eo_e;
|
||||
msg->e = e;
|
||||
eina_thread_queue_send_done(_th_main_queue, ref);
|
||||
}
|
|
@ -1216,6 +1216,15 @@ struct _Evas_Object_Func
|
|||
Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
|
||||
|
||||
int (*can_map) (Evas_Object *obj);
|
||||
|
||||
// new render2 functions
|
||||
|
||||
void (*render2_walk) (Evas_Object *obj, Evas_Object_Protected_Data *pd,
|
||||
void *type_private_data, void *updates,
|
||||
int offx, int offy);
|
||||
// void (*render2) (Evas_Object *obj, Evas_Object_Protected_Data *pd,
|
||||
// void *type_private_data, void *output, void *context,
|
||||
// void *surface, int x, int y);
|
||||
};
|
||||
|
||||
struct _Evas_Func
|
||||
|
|
|
@ -759,6 +759,7 @@ _ecore_evas_x_render(Ecore_Evas *ee)
|
|||
Eina_List *ll;
|
||||
Ecore_Evas *ee2;
|
||||
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
|
||||
static int render2 = -1;
|
||||
|
||||
if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync) &&
|
||||
(edata->sync_counter) && (!edata->sync_began) &&
|
||||
|
@ -780,20 +781,42 @@ _ecore_evas_x_render(Ecore_Evas *ee)
|
|||
}
|
||||
|
||||
if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
|
||||
if (!ee->can_async_render)
|
||||
if (render2 == -1)
|
||||
{
|
||||
Eina_List *updates = evas_render_updates(ee->evas);
|
||||
rend = _render_updates_process(ee, updates);
|
||||
evas_render_updates_free(updates);
|
||||
if (getenv("RENDER2")) render2 = 1;
|
||||
else render2 = 0;
|
||||
}
|
||||
else if (evas_render_async(ee->evas))
|
||||
if (render2)
|
||||
{
|
||||
EDBG("ee=%p started asynchronous render.", ee);
|
||||
ee->in_async_render = EINA_TRUE;
|
||||
rend = 1;
|
||||
if (!ee->can_async_render)
|
||||
{
|
||||
Eina_List *updates = evas_render2_updates(ee->evas);
|
||||
rend = _render_updates_process(ee, updates);
|
||||
evas_render_updates_free(updates);
|
||||
}
|
||||
else
|
||||
{
|
||||
ee->in_async_render = EINA_TRUE;
|
||||
if (evas_render2(ee->evas)) rend = 1;
|
||||
else ee->in_async_render = EINA_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ee->can_async_render)
|
||||
{
|
||||
Eina_List *updates = evas_render_updates(ee->evas);
|
||||
rend = _render_updates_process(ee, updates);
|
||||
evas_render_updates_free(updates);
|
||||
}
|
||||
else if (evas_render_async(ee->evas))
|
||||
{
|
||||
EDBG("ee=%p started asynchronous render.", ee);
|
||||
ee->in_async_render = EINA_TRUE;
|
||||
rend = 1;
|
||||
}
|
||||
else if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
|
||||
}
|
||||
else if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
|
||||
|
||||
return rend;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue