2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h"
|
2002-11-08 00:02:15 -08:00
|
|
|
#include "evas_private.h"
|
2011-10-10 23:06:11 -07:00
|
|
|
#include <math.h>
|
2013-09-02 21:48:08 -07:00
|
|
|
#include <assert.h>
|
2012-05-07 10:22:06 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
#include "evas_cs2_private.h"
|
|
|
|
#endif
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2013-01-17 06:31:34 -08:00
|
|
|
#ifdef EVAS_RENDER_DEBUG_TIMING
|
|
|
|
#include <sys/time.h>
|
|
|
|
#endif
|
|
|
|
|
2015-03-19 22:18:17 -07:00
|
|
|
#include "evas_render2.h"
|
2013-12-19 05:49:16 -08:00
|
|
|
|
2015-09-03 23:13:35 -07:00
|
|
|
/* Enable this for extra verbose rendering debug logs */
|
2015-10-07 18:56:35 -07:00
|
|
|
//#define REND_DBG 1
|
2015-09-03 23:13:35 -07:00
|
|
|
#define STDOUT_DBG
|
2009-11-15 05:46:20 -08:00
|
|
|
|
2012-09-12 12:00:23 -07:00
|
|
|
#ifdef REND_DBG
|
2009-11-15 05:46:20 -08:00
|
|
|
static FILE *dbf = NULL;
|
2015-09-01 04:47:40 -07:00
|
|
|
static int __RD_level = 0;
|
2015-10-07 18:56:35 -07:00
|
|
|
static int __RD_enable = REND_DBG;
|
2009-11-15 05:46:20 -08:00
|
|
|
|
|
|
|
static void
|
|
|
|
rend_dbg(const char *txt)
|
|
|
|
{
|
|
|
|
if (!dbf)
|
|
|
|
{
|
2010-09-03 01:23:38 -07:00
|
|
|
#ifdef STDOUT_DBG
|
|
|
|
dbf = stdout;
|
2011-05-20 23:23:33 -07:00
|
|
|
#else
|
2015-12-03 00:32:39 -08:00
|
|
|
dbf = fopen("EVAS-RENDER-DEBUG.log", "wb");
|
2011-05-20 23:23:33 -07:00
|
|
|
#endif
|
2009-11-15 05:46:20 -08:00
|
|
|
if (!dbf) return;
|
|
|
|
}
|
|
|
|
fputs(txt, dbf);
|
|
|
|
fflush(dbf);
|
|
|
|
}
|
2015-01-26 00:35:42 -08:00
|
|
|
#define RD(xxxx, args...) \
|
2015-10-07 18:56:35 -07:00
|
|
|
do { if (__RD_enable) { \
|
2009-11-15 05:46:20 -08:00
|
|
|
char __tmpbuf[4096]; int __tmpi; \
|
2015-09-01 04:47:40 -07:00
|
|
|
__RD_level = xxxx; \
|
2015-01-26 00:35:42 -08:00
|
|
|
if (xxxx) { \
|
|
|
|
for (__tmpi = 0; __tmpi < xxxx * 2; __tmpi++) \
|
|
|
|
__tmpbuf[__tmpi] = ' '; \
|
|
|
|
__tmpbuf[__tmpi] = 0; \
|
|
|
|
rend_dbg(__tmpbuf); \
|
|
|
|
} \
|
|
|
|
snprintf(__tmpbuf, sizeof(__tmpbuf), ##args); \
|
2009-11-15 05:46:20 -08:00
|
|
|
rend_dbg(__tmpbuf); \
|
2015-10-07 18:56:35 -07:00
|
|
|
} } while (0)
|
2015-07-21 01:48:47 -07:00
|
|
|
#define IFRD(ifcase, xxxx, args...) \
|
2015-10-07 18:56:35 -07:00
|
|
|
if (__RD_enable && (ifcase)) { \
|
2015-07-21 01:48:47 -07:00
|
|
|
char __tmpbuf[4096]; int __tmpi; \
|
2015-09-01 04:47:40 -07:00
|
|
|
__RD_level = xxxx; \
|
2015-07-21 01:48:47 -07:00
|
|
|
if (xxxx) { \
|
|
|
|
for (__tmpi = 0; __tmpi < xxxx * 2; __tmpi++) \
|
|
|
|
__tmpbuf[__tmpi] = ' '; \
|
|
|
|
__tmpbuf[__tmpi] = 0; \
|
|
|
|
rend_dbg(__tmpbuf); \
|
|
|
|
} \
|
|
|
|
snprintf(__tmpbuf, sizeof(__tmpbuf), ##args); \
|
|
|
|
rend_dbg(__tmpbuf); \
|
|
|
|
}
|
2009-11-15 05:46:20 -08:00
|
|
|
#else
|
2015-07-21 01:48:47 -07:00
|
|
|
#define RD(xxx, args...)
|
|
|
|
#define IFRD(ifcase, xxx, args...)
|
2009-11-15 05:46:20 -08:00
|
|
|
#endif
|
|
|
|
|
2016-11-25 21:25:41 -08:00
|
|
|
#define OBJ_ARRAY_PUSH(array, obj) eina_array_push(array, obj)
|
|
|
|
#define OBJS_ARRAY_CLEAN(array) eina_array_clean(array)
|
|
|
|
#define OBJS_ARRAY_FLUSH(array) eina_array_flush(array)
|
2013-05-02 00:47:16 -07:00
|
|
|
|
2014-11-12 02:25:21 -08:00
|
|
|
/* save typing */
|
|
|
|
#define ENFN evas->engine.func
|
|
|
|
#define ENDT evas->engine.data.output
|
|
|
|
|
2012-12-18 08:28:55 -08:00
|
|
|
typedef struct _Render_Updates Render_Updates;
|
|
|
|
struct _Render_Updates
|
|
|
|
{
|
|
|
|
void *surface;
|
|
|
|
Eina_Rectangle *area;
|
|
|
|
};
|
|
|
|
|
|
|
|
static Eina_Bool
|
2013-03-25 19:48:23 -07:00
|
|
|
evas_render_updates_internal(Evas *eo_e, unsigned char make_updates, unsigned char do_draw, Evas_Render_Done_Cb done_func, void *done_data, Eina_Bool do_async);
|
2005-12-03 01:27:53 -08:00
|
|
|
|
2013-09-02 21:48:08 -07:00
|
|
|
static Eina_List *_rendering_evases = NULL;
|
|
|
|
|
2013-01-17 06:31:34 -08:00
|
|
|
#ifdef EVAS_RENDER_DEBUG_TIMING
|
|
|
|
static double
|
|
|
|
_time_get()
|
|
|
|
{
|
|
|
|
struct timeval tv;
|
|
|
|
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
|
|
|
|
return (tv.tv_sec + tv.tv_usec / 1000000.0) * 1000.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct accumulator {
|
2015-04-03 07:34:15 -07:00
|
|
|
double total, min, max, draw_start_time;
|
2013-01-17 06:31:34 -08:00
|
|
|
int samples;
|
|
|
|
const char *what;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct accumulator async_accumulator = {
|
|
|
|
.total = 0,
|
|
|
|
.min = 1000000,
|
|
|
|
.max = 0,
|
|
|
|
.samples = 0,
|
|
|
|
.what = "async render"
|
|
|
|
};
|
|
|
|
static struct accumulator sync_accumulator = {
|
|
|
|
.total = 0,
|
|
|
|
.min = 1000000,
|
|
|
|
.max = 0,
|
|
|
|
.samples = 0,
|
|
|
|
.what = "sync render"
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
2015-04-03 07:34:15 -07:00
|
|
|
_accumulate_time(double before, Eina_Bool async)
|
2013-01-17 06:31:34 -08:00
|
|
|
{
|
2015-04-03 07:34:15 -07:00
|
|
|
static Eina_Bool async_start = EINA_TRUE;
|
|
|
|
static double cache_before;
|
|
|
|
struct accumulator *acc = &sync_accumulator;
|
|
|
|
if (async)
|
|
|
|
{
|
|
|
|
acc = &async_accumulator;
|
|
|
|
if (async_start)
|
|
|
|
{
|
|
|
|
async_start = EINA_FALSE;
|
|
|
|
cache_before = before;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
async_start = EINA_TRUE;
|
|
|
|
before = cache_before;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-17 06:31:34 -08:00
|
|
|
double diff = _time_get() - before;
|
|
|
|
|
|
|
|
acc->total += diff;
|
|
|
|
if (diff > acc->max) acc->max = diff;
|
|
|
|
if (diff < acc->min) acc->min = diff;
|
|
|
|
|
|
|
|
acc->samples++;
|
|
|
|
if (acc->samples % 100 == 0)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "*** %s: avg %fms min %fms max %fms\n",
|
|
|
|
acc->what, acc->total / 100.0, acc->min, acc->max);
|
|
|
|
acc->total = 0.0;
|
|
|
|
acc->max = 0.0;
|
|
|
|
acc->min = 1000000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-07-07 05:29:31 -07:00
|
|
|
static int _render_busy = 0;
|
|
|
|
|
2016-09-07 18:26:30 -07:00
|
|
|
static inline Eina_Bool
|
2016-11-07 03:36:59 -08:00
|
|
|
_is_obj_in_framespace(Evas_Object_Protected_Data *obj, Evas_Public_Data *evas EINA_UNUSED)
|
2016-09-07 18:26:30 -07:00
|
|
|
{
|
2016-11-07 03:36:59 -08:00
|
|
|
return obj->is_frame;
|
2016-09-07 18:26:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2016-11-07 03:36:59 -08:00
|
|
|
_evas_render_framespace_context_clip_clip(Evas_Public_Data *evas, void *ctx,
|
|
|
|
int ox, int oy)
|
2016-09-07 18:26:30 -07:00
|
|
|
{
|
|
|
|
int fx, fy, fw, fh;
|
|
|
|
|
|
|
|
fx = evas->framespace.x;
|
|
|
|
fy = evas->framespace.y;
|
|
|
|
fw = evas->viewport.w - evas->framespace.w;
|
|
|
|
fh = evas->viewport.h - evas->framespace.h;
|
|
|
|
|
2016-11-07 03:36:59 -08:00
|
|
|
ENFN->context_clip_clip(ENDT, ctx, fx + ox, fy + oy, fw, fh);
|
2016-09-07 18:26:30 -07:00
|
|
|
}
|
|
|
|
|
2015-07-07 05:29:31 -07:00
|
|
|
static void
|
|
|
|
_evas_render_cleanup(void)
|
|
|
|
{
|
|
|
|
if (_render_busy != 0) return;
|
|
|
|
evas_common_rgba_pending_unloads_cleanup();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_render_busy_begin(void)
|
|
|
|
{
|
|
|
|
_render_busy++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_render_busy_end(void)
|
|
|
|
{
|
|
|
|
_render_busy--;
|
|
|
|
_evas_render_cleanup();
|
|
|
|
}
|
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN void
|
2014-06-26 14:29:46 -07:00
|
|
|
_evas_canvas_damage_rectangle_add(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, int x, int y, int w, int h)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
Eina_Rectangle *r;
|
|
|
|
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_canvas_async_block(e);
|
2009-04-14 02:27:27 -07:00
|
|
|
NEW_RECT(r, x, y, w, h);
|
2002-11-08 00:02:15 -08:00
|
|
|
if (!r) return;
|
2008-10-21 09:31:05 -07:00
|
|
|
e->damages = eina_list_append(e->damages, r);
|
2012-05-16 06:21:37 -07:00
|
|
|
e->changed = EINA_TRUE;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN void
|
2014-06-26 14:29:46 -07:00
|
|
|
_evas_canvas_obscured_rectangle_add(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, int x, int y, int w, int h)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
|
|
|
Eina_Rectangle *r;
|
|
|
|
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_canvas_async_block(e);
|
2009-04-14 02:27:27 -07:00
|
|
|
NEW_RECT(r, x, y, w, h);
|
2002-11-08 00:02:15 -08:00
|
|
|
if (!r) return;
|
2008-10-21 09:31:05 -07:00
|
|
|
e->obscures = eina_list_append(e->obscures, r);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN void
|
2014-06-26 14:29:46 -07:00
|
|
|
_evas_canvas_obscured_clear(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
|
|
|
Eina_Rectangle *r;
|
|
|
|
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_canvas_async_block(e);
|
2009-04-14 02:27:27 -07:00
|
|
|
EINA_LIST_FREE(e->obscures, r)
|
2009-10-30 03:11:15 -07:00
|
|
|
{
|
|
|
|
eina_rectangle_free(r);
|
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2012-11-20 03:52:16 -08:00
|
|
|
static Eina_Bool
|
|
|
|
_evas_clip_changes_free(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
|
|
|
|
{
|
|
|
|
eina_rectangle_free(data);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2009-11-10 00:50:11 -08:00
|
|
|
static Eina_Bool
|
2012-10-10 00:23:00 -07:00
|
|
|
_evas_render_had_map(Evas_Object_Protected_Data *obj)
|
2009-11-10 00:50:11 -08:00
|
|
|
{
|
2013-01-21 19:56:00 -08:00
|
|
|
return ((obj->map->prev.map) && (obj->map->prev.usemap));
|
2013-03-12 05:58:19 -07:00
|
|
|
// return ((!obj->map->cur.map) && (obj->prev->usemap));
|
2009-11-10 00:50:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2016-11-25 17:52:15 -08:00
|
|
|
_evas_render_is_relevant(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
|
2009-11-10 00:50:11 -08:00
|
|
|
{
|
2013-03-12 05:58:19 -07:00
|
|
|
return ((evas_object_is_visible(eo_obj, obj) && (!obj->cur->have_clipees)) ||
|
|
|
|
(evas_object_was_visible(eo_obj, obj) && (!obj->prev->have_clipees)));
|
2009-11-10 00:50:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2012-10-10 00:23:00 -07:00
|
|
|
_evas_render_can_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
|
2009-11-10 00:50:11 -08:00
|
|
|
{
|
2015-05-12 01:37:01 -07:00
|
|
|
return (evas_object_is_visible(eo_obj, obj) && (!obj->cur->have_clipees) &&
|
|
|
|
!obj->no_render);
|
2009-11-10 00:50:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-10-10 00:23:00 -07:00
|
|
|
_evas_render_prev_cur_clip_cache_add(Evas_Public_Data *e, Evas_Object_Protected_Data *obj)
|
2009-11-10 00:50:11 -08:00
|
|
|
{
|
|
|
|
e->engine.func->output_redraws_rect_add(e->engine.data.output,
|
2013-04-26 11:01:44 -07:00
|
|
|
obj->prev->cache.clip.x + e->framespace.x,
|
|
|
|
obj->prev->cache.clip.y + e->framespace.y,
|
2013-03-12 05:58:19 -07:00
|
|
|
obj->prev->cache.clip.w,
|
|
|
|
obj->prev->cache.clip.h);
|
2009-11-10 00:50:11 -08:00
|
|
|
e->engine.func->output_redraws_rect_add(e->engine.data.output,
|
2013-04-26 11:01:44 -07:00
|
|
|
obj->cur->cache.clip.x + e->framespace.x,
|
|
|
|
obj->cur->cache.clip.y + e->framespace.y,
|
2013-03-12 05:58:19 -07:00
|
|
|
obj->cur->cache.clip.w,
|
|
|
|
obj->cur->cache.clip.h);
|
2009-11-10 00:50:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-10-10 00:23:00 -07:00
|
|
|
_evas_render_cur_clip_cache_del(Evas_Public_Data *e, Evas_Object_Protected_Data *obj)
|
2009-11-10 00:50:11 -08:00
|
|
|
{
|
2011-11-10 21:56:40 -08:00
|
|
|
Evas_Coord x, y, w, h;
|
2012-05-16 06:21:37 -07:00
|
|
|
|
2013-03-12 05:58:19 -07:00
|
|
|
x = obj->cur->cache.clip.x;
|
|
|
|
y = obj->cur->cache.clip.y;
|
|
|
|
w = obj->cur->cache.clip.w;
|
|
|
|
h = obj->cur->cache.clip.h;
|
|
|
|
if (obj->cur->clipper)
|
2011-11-10 21:56:40 -08:00
|
|
|
{
|
|
|
|
RECTS_CLIP_TO_RECT(x, y, w, h,
|
2013-03-12 05:58:19 -07:00
|
|
|
obj->cur->clipper->cur->cache.clip.x,
|
|
|
|
obj->cur->clipper->cur->cache.clip.y,
|
|
|
|
obj->cur->clipper->cur->cache.clip.w,
|
|
|
|
obj->cur->clipper->cur->cache.clip.h);
|
2011-11-10 21:56:40 -08:00
|
|
|
}
|
2016-11-25 17:47:34 -08:00
|
|
|
evas_render_update_del(e, x + e->framespace.x, y + e->framespace.y, w, h);
|
2009-11-10 00:50:11 -08:00
|
|
|
}
|
|
|
|
|
2014-11-12 17:47:29 -08:00
|
|
|
/* sets the redraw flag for all the proxies depending on this obj as a source */
|
2013-11-24 17:09:34 -08:00
|
|
|
static void
|
|
|
|
_evas_proxy_redraw_set(Evas_Public_Data *e, Evas_Object_Protected_Data *obj,
|
|
|
|
Eina_Bool render)
|
|
|
|
{
|
|
|
|
Evas_Object *eo_proxy;
|
|
|
|
Evas_Object_Protected_Data *proxy;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(obj->proxy->proxies, l, eo_proxy)
|
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
proxy = efl_data_scope_get(eo_proxy, EFL_CANVAS_OBJECT_CLASS);
|
2013-11-24 17:09:34 -08:00
|
|
|
|
|
|
|
/* Flag need redraw on proxy too */
|
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, proxy->proxy,
|
|
|
|
Evas_Object_Proxy_Data, proxy_write)
|
|
|
|
proxy_write->redraw = EINA_TRUE;
|
|
|
|
EINA_COW_WRITE_END(evas_object_proxy_cow, proxy->proxy, proxy_write);
|
|
|
|
|
|
|
|
if (render)
|
|
|
|
{
|
|
|
|
proxy->func->render_pre(eo_proxy, proxy, proxy->private_data);
|
|
|
|
_evas_render_prev_cur_clip_cache_add(e, proxy);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Update the proxies recursively.
|
|
|
|
_evas_proxy_redraw_set(e, proxy, render);
|
|
|
|
}
|
2014-01-07 00:39:23 -08:00
|
|
|
|
|
|
|
if (obj->proxy->proxy_textures)
|
|
|
|
{
|
|
|
|
/* Flag need redraw on proxy texture source */
|
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy,
|
|
|
|
Evas_Object_Proxy_Data, source)
|
|
|
|
source->redraw = EINA_TRUE;
|
|
|
|
EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, source);
|
|
|
|
}
|
2013-11-24 17:09:34 -08:00
|
|
|
}
|
|
|
|
|
2014-11-12 17:47:29 -08:00
|
|
|
/* sets the mask redraw flag for all the objects clipped by this mask */
|
|
|
|
static void
|
|
|
|
_evas_mask_redraw_set(Evas_Public_Data *e EINA_UNUSED,
|
|
|
|
Evas_Object_Protected_Data *obj)
|
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *clippee;
|
|
|
|
Eina_List *l;
|
|
|
|
|
2015-01-26 22:02:27 -08:00
|
|
|
if (!(obj->mask->redraw))
|
2014-11-12 17:47:29 -08:00
|
|
|
{
|
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_mask_cow, obj->mask,
|
|
|
|
Evas_Object_Mask_Data, mask)
|
|
|
|
mask->redraw = EINA_TRUE;
|
|
|
|
EINA_COW_WRITE_END(evas_object_mask_cow, obj->mask, mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!obj->cur->cache.clip.dirty)
|
|
|
|
{
|
|
|
|
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
|
|
|
|
state_write->cache.clip.dirty = EINA_TRUE;
|
|
|
|
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(obj->clip.clipees, l, clippee)
|
|
|
|
{
|
|
|
|
evas_object_clip_recalc(clippee);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline Eina_Bool
|
|
|
|
_evas_render_object_changed_get(Evas_Object_Protected_Data *obj)
|
|
|
|
{
|
|
|
|
if (obj->smart.smart)
|
|
|
|
return evas_object_smart_changed_get(obj->object);
|
|
|
|
else
|
|
|
|
return obj->changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline Eina_Bool
|
|
|
|
_evas_render_object_is_mask(Evas_Object_Protected_Data *obj)
|
|
|
|
{
|
|
|
|
if (!obj) return EINA_FALSE;
|
2015-01-26 00:35:42 -08:00
|
|
|
if (obj->mask->is_mask && obj->clip.clipees)
|
|
|
|
return EINA_TRUE;
|
|
|
|
return EINA_FALSE;
|
2014-11-12 17:47:29 -08:00
|
|
|
}
|
|
|
|
|
2009-11-06 21:01:43 -08:00
|
|
|
static void
|
2012-10-10 00:23:00 -07:00
|
|
|
_evas_render_phase1_direct(Evas_Public_Data *e,
|
2016-11-25 21:25:41 -08:00
|
|
|
Eina_Inarray *active_objects,
|
2012-10-08 18:58:41 -07:00
|
|
|
Eina_Array *restack_objects EINA_UNUSED,
|
|
|
|
Eina_Array *delete_objects EINA_UNUSED,
|
2009-11-10 00:50:11 -08:00
|
|
|
Eina_Array *render_objects)
|
2009-11-06 21:01:43 -08:00
|
|
|
{
|
|
|
|
unsigned int i;
|
2013-11-24 17:09:34 -08:00
|
|
|
Evas_Object *eo_obj;
|
2009-11-06 21:01:43 -08:00
|
|
|
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, " [--- PHASE 1 DIRECT\n");
|
2016-11-25 21:25:41 -08:00
|
|
|
for (i = 0; i < active_objects->len; i++)
|
2011-05-19 06:01:44 -07:00
|
|
|
{
|
2016-11-30 00:36:42 -08:00
|
|
|
Evas_Active_Entry *ent = eina_inarray_nth(active_objects, i);
|
|
|
|
Evas_Object_Protected_Data *obj = ent->obj;
|
2013-04-06 22:00:10 -07:00
|
|
|
|
2016-11-30 00:36:42 -08:00
|
|
|
EINA_PREFETCH(&(obj->cur->clipper));
|
2013-10-31 01:01:41 -07:00
|
|
|
if (obj->changed) evas_object_clip_recalc(obj);
|
|
|
|
|
2014-11-12 17:47:29 -08:00
|
|
|
if (obj->proxy->proxies || obj->proxy->proxy_textures)
|
|
|
|
{
|
|
|
|
/* is proxy source */
|
|
|
|
if (_evas_render_object_changed_get(obj))
|
|
|
|
_evas_proxy_redraw_set(e, obj, EINA_FALSE);
|
|
|
|
}
|
|
|
|
if (_evas_render_object_is_mask(obj))
|
|
|
|
{
|
|
|
|
/* is image clipper */
|
|
|
|
if (_evas_render_object_changed_get(obj))
|
2015-02-25 22:36:09 -08:00
|
|
|
_evas_mask_redraw_set(e, obj);
|
2014-11-12 17:47:29 -08:00
|
|
|
}
|
2011-05-19 06:01:44 -07:00
|
|
|
}
|
2009-11-09 07:18:37 -08:00
|
|
|
for (i = 0; i < render_objects->count; i++)
|
2009-11-06 21:01:43 -08:00
|
|
|
{
|
2013-11-24 17:09:34 -08:00
|
|
|
Evas_Object_Protected_Data *obj =
|
2016-11-26 19:02:12 -08:00
|
|
|
eina_array_data_get(render_objects, i);
|
2012-10-08 18:58:41 -07:00
|
|
|
eo_obj = obj->object;
|
2013-11-24 17:09:34 -08:00
|
|
|
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, " OBJ [%p", obj);
|
2015-07-21 01:48:47 -07:00
|
|
|
IFRD(obj->name, 0, " '%s'", obj->name);
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, "] changed %i\n", obj->changed);
|
2013-11-24 17:09:34 -08:00
|
|
|
|
2011-05-20 23:23:33 -07:00
|
|
|
if (obj->changed)
|
2009-11-06 21:01:43 -08:00
|
|
|
{
|
2013-04-06 22:00:10 -07:00
|
|
|
evas_object_clip_recalc(obj);
|
2013-12-07 10:14:14 -08:00
|
|
|
obj->func->render_pre(eo_obj, obj, obj->private_data);
|
2014-11-12 17:47:29 -08:00
|
|
|
|
|
|
|
if (obj->proxy->redraw || obj->mask->redraw)
|
2013-12-07 10:14:14 -08:00
|
|
|
_evas_render_prev_cur_clip_cache_add(e, obj);
|
2014-11-12 17:47:29 -08:00
|
|
|
|
|
|
|
if (!obj->smart.smart || evas_object_smart_changed_get(eo_obj))
|
2011-02-06 15:51:48 -08:00
|
|
|
{
|
2014-11-12 17:47:29 -08:00
|
|
|
/* proxy sources */
|
|
|
|
if (obj->proxy->proxies || obj->proxy->proxy_textures)
|
2011-05-19 06:01:44 -07:00
|
|
|
{
|
2013-11-17 23:10:55 -08:00
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy,
|
|
|
|
Evas_Object_Proxy_Data, proxy_write)
|
|
|
|
proxy_write->redraw = EINA_TRUE;
|
|
|
|
EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy,
|
|
|
|
proxy_write);
|
2013-11-24 17:09:34 -08:00
|
|
|
_evas_proxy_redraw_set(e, obj, EINA_TRUE);
|
2011-05-19 06:01:44 -07:00
|
|
|
}
|
2014-11-12 17:47:29 -08:00
|
|
|
|
|
|
|
/* clipper objects (image masks) */
|
|
|
|
if (_evas_render_object_is_mask(obj))
|
|
|
|
_evas_mask_redraw_set(e, obj);
|
2011-05-19 06:01:44 -07:00
|
|
|
}
|
2012-05-30 00:32:27 -07:00
|
|
|
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, " pre-render-done smart:%p|%p [%p, %i] | [%p, %i] has_map:%i had_map:%i\n",
|
2012-05-30 00:32:27 -07:00
|
|
|
obj->smart.smart,
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_smart_members_get_direct(eo_obj),
|
2013-01-21 19:56:00 -08:00
|
|
|
obj->map->cur.map, obj->map->cur.usemap,
|
2013-08-05 23:45:07 -07:00
|
|
|
obj->map->prev.map, obj->map->prev.usemap,
|
2016-01-06 04:52:46 -08:00
|
|
|
_evas_render_has_map(obj),
|
2012-10-10 00:23:00 -07:00
|
|
|
_evas_render_had_map(obj));
|
2012-10-08 18:58:41 -07:00
|
|
|
if ((obj->is_smart) &&
|
2016-01-06 04:52:46 -08:00
|
|
|
(((_evas_render_has_map(obj) && !_evas_render_can_map(obj)) ||
|
2012-10-25 08:24:27 -07:00
|
|
|
(obj->changed_src_visible))))
|
2011-05-19 06:01:44 -07:00
|
|
|
{
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, " has map + smart\n");
|
2012-10-10 00:23:00 -07:00
|
|
|
_evas_render_prev_cur_clip_cache_add(e, obj);
|
2009-11-15 05:46:20 -08:00
|
|
|
}
|
2009-11-06 21:01:43 -08:00
|
|
|
}
|
2011-05-20 23:23:33 -07:00
|
|
|
else
|
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
if (obj->is_smart)
|
2009-11-06 21:01:43 -08:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
// obj->func->render_pre(eo_obj);
|
2009-11-06 21:01:43 -08:00
|
|
|
}
|
2013-09-24 03:32:24 -07:00
|
|
|
else if (evas_object_is_visible(eo_obj, obj) &&
|
|
|
|
((obj->rect_del) ||
|
2014-02-12 22:40:29 -08:00
|
|
|
(evas_object_is_opaque(eo_obj, obj))) &&
|
|
|
|
(!evas_object_is_source_invisible(eo_obj, obj)))
|
2009-11-15 05:46:20 -08:00
|
|
|
{
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, " rect del\n");
|
2012-10-10 00:23:00 -07:00
|
|
|
_evas_render_cur_clip_cache_del(e, obj);
|
2009-11-15 05:46:20 -08:00
|
|
|
}
|
2011-05-20 23:23:33 -07:00
|
|
|
}
|
2009-11-06 21:01:43 -08:00
|
|
|
}
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, " ---]\n");
|
2009-10-30 03:11:15 -07:00
|
|
|
}
|
|
|
|
|
2016-11-18 01:56:59 -08:00
|
|
|
static void
|
|
|
|
_evas_render_object_map_change_update(Evas_Public_Data *e, Evas_Object *eo_obj EINA_UNUSED,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
Eina_Bool map, Eina_Bool hmap,
|
|
|
|
int *redraw_all)
|
|
|
|
{
|
|
|
|
if (map == hmap) return;
|
|
|
|
|
|
|
|
if (obj->map)
|
|
|
|
{
|
|
|
|
Evas_Coord x = 0, y = 0, w = 0, h = 0;
|
|
|
|
|
|
|
|
if (map)
|
|
|
|
{
|
|
|
|
x = obj->prev->cache.clip.x;
|
|
|
|
y = obj->prev->cache.clip.y;
|
|
|
|
w = obj->prev->cache.clip.w;
|
|
|
|
h = obj->prev->cache.clip.h;
|
|
|
|
if (obj->prev->clipper)
|
|
|
|
{
|
|
|
|
RECTS_CLIP_TO_RECT(x, y, w, h,
|
|
|
|
obj->prev->clipper->prev->cache.clip.x,
|
|
|
|
obj->prev->clipper->prev->cache.clip.y,
|
|
|
|
obj->prev->clipper->prev->cache.clip.w,
|
|
|
|
obj->prev->clipper->prev->cache.clip.h);
|
|
|
|
}
|
|
|
|
e->engine.func->output_redraws_rect_add(e->engine.data.output,
|
|
|
|
x + e->framespace.x,
|
|
|
|
y + e->framespace.y,
|
|
|
|
w, h);
|
|
|
|
x = obj->map->cur.map->normal_geometry.x;
|
|
|
|
y = obj->map->cur.map->normal_geometry.y;
|
|
|
|
w = obj->map->cur.map->normal_geometry.w;
|
|
|
|
h = obj->map->cur.map->normal_geometry.h;
|
|
|
|
if (obj->cur->clipper)
|
|
|
|
{
|
|
|
|
RECTS_CLIP_TO_RECT(x, y, w, h,
|
|
|
|
obj->cur->clipper->cur->cache.clip.x,
|
|
|
|
obj->cur->clipper->cur->cache.clip.y,
|
|
|
|
obj->cur->clipper->cur->cache.clip.w,
|
|
|
|
obj->cur->clipper->cur->cache.clip.h);
|
|
|
|
}
|
|
|
|
e->engine.func->output_redraws_rect_add(e->engine.data.output,
|
|
|
|
x + e->framespace.x,
|
|
|
|
y + e->framespace.y,
|
|
|
|
w, h);
|
|
|
|
}
|
|
|
|
else if (hmap)
|
|
|
|
{
|
|
|
|
x = obj->map->prev.map->normal_geometry.x;
|
|
|
|
y = obj->map->prev.map->normal_geometry.y;
|
|
|
|
w = obj->map->prev.map->normal_geometry.w;
|
|
|
|
h = obj->map->prev.map->normal_geometry.h;
|
|
|
|
if (obj->prev->clipper)
|
|
|
|
{
|
|
|
|
RECTS_CLIP_TO_RECT(x, y, w, h,
|
|
|
|
obj->prev->clipper->prev->cache.clip.x,
|
|
|
|
obj->prev->clipper->prev->cache.clip.y,
|
|
|
|
obj->prev->clipper->prev->cache.clip.w,
|
|
|
|
obj->prev->clipper->prev->cache.clip.h);
|
|
|
|
}
|
|
|
|
e->engine.func->output_redraws_rect_add(e->engine.data.output,
|
|
|
|
x + e->framespace.x,
|
|
|
|
y + e->framespace.y,
|
|
|
|
w, h);
|
|
|
|
x = obj->cur->cache.clip.x;
|
|
|
|
y = obj->cur->cache.clip.y;
|
|
|
|
w = obj->cur->cache.clip.w;
|
|
|
|
h = obj->cur->cache.clip.h;
|
|
|
|
if (obj->cur->clipper)
|
|
|
|
{
|
|
|
|
RECTS_CLIP_TO_RECT(x, y, w, h,
|
|
|
|
obj->cur->clipper->cur->cache.clip.x,
|
|
|
|
obj->cur->clipper->cur->cache.clip.y,
|
|
|
|
obj->cur->clipper->cur->cache.clip.w,
|
|
|
|
obj->cur->clipper->cur->cache.clip.h);
|
|
|
|
}
|
|
|
|
e->engine.func->output_redraws_rect_add(e->engine.data.output,
|
|
|
|
x + e->framespace.x,
|
|
|
|
y + e->framespace.y,
|
|
|
|
w, h);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
*redraw_all = 1;
|
|
|
|
}
|
|
|
|
|
2016-11-25 17:47:34 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// object render update phase 1 code -> figure out updates and built object
|
|
|
|
// render/active/delete etc. lists/arrays.
|
|
|
|
//
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2016-11-25 21:25:41 -08:00
|
|
|
Eina_Inarray *active_objects;
|
|
|
|
Eina_Array *render_objects;
|
|
|
|
Eina_Array *snapshot_objects;
|
2016-11-25 17:47:34 -08:00
|
|
|
|
|
|
|
Eina_Inarray *update_del;
|
|
|
|
} Render_Cache;
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_render_update_del(Evas_Public_Data *e, int x, int y, int w, int h)
|
|
|
|
{
|
|
|
|
if (EINA_LIKELY((e->update_del_redirect_array == NULL)))
|
|
|
|
{
|
|
|
|
e->engine.func->output_redraws_rect_del(e->engine.data.output,
|
|
|
|
x, y, w, h);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Eina_Rectangle r;
|
|
|
|
|
|
|
|
r.x = x; r.y = y; r.w = w; r.h = h;
|
|
|
|
eina_inarray_push(e->update_del_redirect_array, &r);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_render_object_render_cache_free(Evas_Object *eo_obj EINA_UNUSED,
|
|
|
|
void *data)
|
|
|
|
{
|
|
|
|
Render_Cache *rc;
|
|
|
|
|
|
|
|
if (!data) return;
|
|
|
|
rc = data;
|
2016-11-25 21:25:41 -08:00
|
|
|
eina_inarray_free(rc->active_objects);
|
2016-11-25 17:47:34 -08:00
|
|
|
eina_array_free(rc->render_objects);
|
|
|
|
eina_array_free(rc->snapshot_objects);
|
2016-12-02 19:44:57 -08:00
|
|
|
eina_inarray_free(rc->update_del);
|
2016-11-25 17:47:34 -08:00
|
|
|
free(rc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Render_Cache *
|
|
|
|
_evas_render_phase1_object_render_cache_new(void)
|
|
|
|
{
|
|
|
|
Render_Cache *rc;
|
|
|
|
|
|
|
|
rc = malloc(sizeof(Render_Cache));
|
2016-11-25 21:25:41 -08:00
|
|
|
rc->active_objects = eina_inarray_new(sizeof(Evas_Active_Entry), 32);
|
2016-11-25 17:47:34 -08:00
|
|
|
rc->render_objects = eina_array_new(32);
|
|
|
|
rc->snapshot_objects = eina_array_new(32);
|
|
|
|
rc->update_del = eina_inarray_new(sizeof(Eina_Rectangle), 16);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2016-11-21 18:09:18 -08:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
Evas_Public_Data *e;
|
2016-11-25 21:25:41 -08:00
|
|
|
Eina_Inarray *active_objects;
|
2016-11-21 18:09:18 -08:00
|
|
|
Eina_Array *render_objects;
|
|
|
|
Eina_Array *snapshot_objects;
|
2016-11-25 17:47:34 -08:00
|
|
|
Eina_Array *restack_objects;
|
|
|
|
Eina_Array *delete_objects;
|
2016-11-21 18:09:18 -08:00
|
|
|
int redraw_all;
|
|
|
|
} Phase1_Context;
|
|
|
|
|
2016-11-25 17:47:34 -08:00
|
|
|
static void
|
|
|
|
_evas_render_phase1_object_ctx_render_cache_fill(Phase1_Context *ctx,
|
|
|
|
Render_Cache *rc)
|
|
|
|
{
|
|
|
|
ctx->active_objects = rc->active_objects;
|
|
|
|
ctx->render_objects = rc->render_objects;
|
|
|
|
ctx->snapshot_objects = rc->snapshot_objects;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_render_phase1_object_ctx_render_cache_append(Phase1_Context *ctx,
|
|
|
|
Render_Cache *rc)
|
|
|
|
{
|
|
|
|
void *obj;
|
|
|
|
unsigned int i, c;
|
|
|
|
Eina_Rectangle *r;
|
2016-11-25 21:25:41 -08:00
|
|
|
Evas_Active_Entry *ent;
|
2016-11-25 17:47:34 -08:00
|
|
|
|
|
|
|
#define ARR_APPEND(x) \
|
|
|
|
if (rc->x != ctx->x) { \
|
|
|
|
do { \
|
|
|
|
c = eina_array_count_get(rc->x); \
|
|
|
|
for (i = 0; i < c; i++) { \
|
|
|
|
obj = eina_array_data_get(rc->x, i); \
|
|
|
|
eina_array_push(ctx->x, obj); \
|
|
|
|
} \
|
|
|
|
} while (0); \
|
|
|
|
}
|
|
|
|
ARR_APPEND(render_objects);
|
|
|
|
ARR_APPEND(snapshot_objects);
|
|
|
|
|
2016-11-25 21:25:41 -08:00
|
|
|
c = eina_inarray_count(rc->active_objects);
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
{
|
|
|
|
ent = eina_inarray_nth(rc->active_objects, i);
|
|
|
|
eina_inarray_push(ctx->active_objects, ent);
|
|
|
|
}
|
|
|
|
|
2016-11-25 17:47:34 -08:00
|
|
|
c = eina_inarray_count(rc->update_del);
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
{
|
|
|
|
r = eina_inarray_nth(rc->update_del, i);
|
|
|
|
evas_render_update_del(ctx->e, r->x, r->y, r->w, r->h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-17 03:01:52 -07:00
|
|
|
static Eina_Bool
|
2016-11-21 18:09:18 -08:00
|
|
|
_evas_render_phase1_object_process(Phase1_Context *p1ctx,
|
2016-11-25 18:10:18 -08:00
|
|
|
Evas_Object_Protected_Data *obj,
|
2016-11-22 04:07:29 -08:00
|
|
|
Eina_Bool restack,
|
|
|
|
Eina_Bool mapped_parent,
|
|
|
|
Eina_Bool src_changed,
|
|
|
|
int level);
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_render_phase1_object_restack_handle(Phase1_Context *p1ctx,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
Eina_Bool obj_changed)
|
|
|
|
{
|
|
|
|
if (!obj_changed)
|
|
|
|
{
|
|
|
|
OBJ_ARRAY_PUSH(&(p1ctx->e->pending_objects), obj);
|
|
|
|
obj->changed = EINA_TRUE;
|
|
|
|
}
|
|
|
|
obj->restack = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_render_phase1_object_map_clipper_fix(Evas_Object *eo_obj,
|
|
|
|
Evas_Object_Protected_Data *obj)
|
|
|
|
{
|
|
|
|
evas_object_change(obj->cur->clipper->object, obj->cur->clipper);
|
|
|
|
evas_object_clip_dirty(obj->cur->clipper->object, obj->cur->clipper);
|
|
|
|
evas_object_clip_recalc(obj->cur->clipper);
|
|
|
|
evas_object_update_bounding_box(eo_obj, obj, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_render_phase1_object_mapped(Phase1_Context *p1ctx,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
Eina_Bool src_changed,
|
|
|
|
Eina_Bool hmap,
|
|
|
|
Eina_Bool is_active,
|
|
|
|
Eina_Bool obj_changed,
|
|
|
|
int level)
|
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *obj2;
|
2016-11-25 18:10:18 -08:00
|
|
|
Evas_Object *eo_obj = obj->object;
|
2016-11-22 04:07:29 -08:00
|
|
|
|
|
|
|
RD(level, " obj mapped\n");
|
|
|
|
if (!hmap && obj->cur->clipper)
|
|
|
|
// Fix some bad clipping issues before an evas map animation starts
|
|
|
|
_evas_render_phase1_object_map_clipper_fix(eo_obj, obj);
|
|
|
|
if (!obj_changed) return;
|
|
|
|
|
|
|
|
_evas_render_object_map_change_update(p1ctx->e, eo_obj, obj,
|
|
|
|
EINA_TRUE, hmap,
|
|
|
|
&(p1ctx->redraw_all));
|
|
|
|
if (!((is_active) &&
|
|
|
|
(!obj->clip.clipees) &&
|
|
|
|
((evas_object_is_visible(eo_obj, obj) &&
|
|
|
|
(!obj->cur->have_clipees)) ||
|
|
|
|
(evas_object_was_visible(eo_obj, obj) &&
|
|
|
|
(!obj->prev->have_clipees)))))
|
|
|
|
return;
|
|
|
|
OBJ_ARRAY_PUSH(p1ctx->render_objects, obj);
|
|
|
|
_evas_render_prev_cur_clip_cache_add(p1ctx->e, obj);
|
|
|
|
obj->render_pre = EINA_TRUE;
|
|
|
|
if (!obj->is_smart) return;
|
2016-11-25 17:47:34 -08:00
|
|
|
if (obj_changed) evas_object_smart_render_cache_clear(eo_obj);
|
2016-11-22 04:07:29 -08:00
|
|
|
EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(eo_obj), obj2)
|
|
|
|
{
|
2016-11-25 18:10:18 -08:00
|
|
|
_evas_render_phase1_object_process(p1ctx, obj2, obj->restack,
|
2016-11-22 04:07:29 -08:00
|
|
|
EINA_TRUE, src_changed, level + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_render_phase1_object_mapped_had_restack(Phase1_Context *p1ctx,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
Eina_Bool map,
|
|
|
|
Eina_Bool obj_changed)
|
|
|
|
{
|
2016-11-25 18:10:18 -08:00
|
|
|
Evas_Object *eo_obj = obj->object;
|
|
|
|
|
2016-11-22 04:07:29 -08:00
|
|
|
RD(level, " had map - restack objs\n");
|
|
|
|
_evas_render_prev_cur_clip_cache_add(p1ctx->e, obj);
|
|
|
|
if (obj_changed)
|
|
|
|
{
|
|
|
|
if (!map)
|
|
|
|
{
|
|
|
|
if ((obj->map->cur.map) && (obj->map->cur.usemap))
|
|
|
|
map = EINA_TRUE;
|
|
|
|
}
|
|
|
|
_evas_render_object_map_change_update(p1ctx->e, eo_obj, obj,
|
|
|
|
map, EINA_TRUE,
|
|
|
|
&(p1ctx->redraw_all));
|
|
|
|
}
|
|
|
|
if (!(!map && obj->cur->clipper)) return;
|
|
|
|
// Fix some bad clipping issues after an evas_map animation finishes
|
|
|
|
evas_object_change(obj->cur->clipper->object, obj->cur->clipper);
|
|
|
|
evas_object_clip_dirty(obj->cur->clipper->object, obj->cur->clipper);
|
|
|
|
evas_object_clip_recalc(obj->cur->clipper);
|
|
|
|
evas_object_update_bounding_box(eo_obj, obj, NULL);
|
|
|
|
}
|
|
|
|
|
2016-11-25 17:47:34 -08:00
|
|
|
#define RENDCACHE 1
|
|
|
|
|
2016-11-22 04:07:29 -08:00
|
|
|
static Eina_Bool
|
|
|
|
_evas_render_phase1_object_changed_smart(Phase1_Context *p1ctx,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
Eina_Bool mapped_parent,
|
2016-11-25 17:47:34 -08:00
|
|
|
Eina_Bool obj_changed,
|
2016-11-22 04:07:29 -08:00
|
|
|
Eina_Bool src_changed,
|
|
|
|
Eina_Bool is_active,
|
|
|
|
int level)
|
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *obj2;
|
2016-11-25 17:47:34 -08:00
|
|
|
Render_Cache *rc = NULL;
|
|
|
|
void *p_del_redir;
|
2016-11-25 18:10:18 -08:00
|
|
|
Evas_Object *eo_obj = obj->object;
|
2016-11-22 04:07:29 -08:00
|
|
|
|
|
|
|
RD(level, " changed + smart - render ok\n");
|
|
|
|
OBJ_ARRAY_PUSH(p1ctx->render_objects, obj);
|
|
|
|
|
|
|
|
if (!is_active && obj->proxy->proxies) src_changed = EINA_TRUE;
|
|
|
|
|
|
|
|
obj->render_pre = EINA_TRUE;
|
2016-11-25 17:47:34 -08:00
|
|
|
if (obj_changed)
|
2016-11-22 04:07:29 -08:00
|
|
|
{
|
2016-11-25 17:47:34 -08:00
|
|
|
evas_object_smart_render_cache_clear(eo_obj);
|
|
|
|
EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(eo_obj), obj2)
|
|
|
|
{
|
2016-11-25 18:10:18 -08:00
|
|
|
_evas_render_phase1_object_process(p1ctx, obj2, obj->restack,
|
2016-11-25 17:47:34 -08:00
|
|
|
mapped_parent, src_changed,
|
|
|
|
level + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Phase1_Context *ctx = p1ctx;
|
|
|
|
Phase1_Context tmpctx;
|
|
|
|
|
|
|
|
#ifdef RENDCACHE
|
|
|
|
if (obj->no_change_render > 3)
|
|
|
|
{
|
|
|
|
rc = evas_object_smart_render_cache_get(eo_obj);
|
|
|
|
if (!rc)
|
|
|
|
{
|
|
|
|
rc = _evas_render_phase1_object_render_cache_new();
|
|
|
|
evas_object_smart_render_cache_set(eo_obj, rc);
|
|
|
|
ctx = &tmpctx;
|
|
|
|
*ctx = *p1ctx;
|
|
|
|
p_del_redir = p1ctx->e->update_del_redirect_array;
|
|
|
|
p1ctx->e->update_del_redirect_array = rc->update_del;
|
|
|
|
_evas_render_phase1_object_ctx_render_cache_fill(ctx, rc);
|
|
|
|
EINA_INLIST_FOREACH
|
|
|
|
(evas_object_smart_members_get_direct(eo_obj), obj2)
|
|
|
|
{
|
2016-11-25 18:10:18 -08:00
|
|
|
_evas_render_phase1_object_process(ctx, obj2,
|
2016-11-25 17:47:34 -08:00
|
|
|
obj->restack,
|
|
|
|
mapped_parent,
|
|
|
|
src_changed,
|
|
|
|
level + 1);
|
|
|
|
}
|
|
|
|
p1ctx->redraw_all = ctx->redraw_all;
|
|
|
|
p1ctx->e->update_del_redirect_array = p_del_redir;
|
|
|
|
}
|
|
|
|
_evas_render_phase1_object_ctx_render_cache_append(p1ctx, rc);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
EINA_INLIST_FOREACH
|
|
|
|
(evas_object_smart_members_get_direct(eo_obj), obj2)
|
|
|
|
{
|
2016-11-25 18:10:18 -08:00
|
|
|
_evas_render_phase1_object_process(ctx, obj2, obj->restack,
|
2016-11-25 17:47:34 -08:00
|
|
|
mapped_parent,
|
2016-11-25 18:10:18 -08:00
|
|
|
src_changed, level + 1);
|
2016-11-25 17:47:34 -08:00
|
|
|
}
|
|
|
|
}
|
2016-11-22 04:07:29 -08:00
|
|
|
}
|
|
|
|
return src_changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_render_phase1_object_changed_normal(Phase1_Context *p1ctx,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
Eina_Bool is_active,
|
|
|
|
int level
|
|
|
|
#ifndef REND_DBG
|
|
|
|
EINA_UNUSED
|
|
|
|
#endif
|
|
|
|
)
|
|
|
|
{
|
2016-11-25 18:10:18 -08:00
|
|
|
Evas_Object *eo_obj = obj->object;
|
|
|
|
|
2016-11-25 17:52:15 -08:00
|
|
|
if ((!obj->clip.clipees) && _evas_render_is_relevant(eo_obj, obj))
|
2016-11-22 04:07:29 -08:00
|
|
|
{
|
|
|
|
if (EINA_LIKELY(is_active))
|
|
|
|
{
|
|
|
|
RD(level, " relevant + active\n");
|
|
|
|
if (EINA_UNLIKELY(obj->restack))
|
|
|
|
OBJ_ARRAY_PUSH(p1ctx->restack_objects, obj);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
OBJ_ARRAY_PUSH(p1ctx->render_objects, obj);
|
|
|
|
obj->render_pre = EINA_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* It goes to be hidden. Prev caching should be replaced
|
|
|
|
by the current (hidden) state. */
|
|
|
|
if (evas_object_is_visible(eo_obj, obj) !=
|
|
|
|
evas_object_was_visible(eo_obj, obj))
|
|
|
|
evas_object_cur_prev(eo_obj);
|
|
|
|
RD(level, " skip - not smart, not active or clippees or not relevant\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (is_active &&
|
|
|
|
_evas_render_object_is_mask(obj) &&
|
|
|
|
(evas_object_is_visible(eo_obj, obj) ||
|
|
|
|
evas_object_was_visible(eo_obj, obj)))
|
|
|
|
{
|
|
|
|
if (EINA_UNLIKELY(obj->restack))
|
|
|
|
OBJ_ARRAY_PUSH(p1ctx->restack_objects, obj);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
OBJ_ARRAY_PUSH(p1ctx->render_objects, obj);
|
|
|
|
obj->render_pre = EINA_TRUE;
|
|
|
|
}
|
|
|
|
RD(level, " relevant + active: clipper image\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RD(level, " skip - not smart, not active or clippees or not relevant\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_render_phase1_object_no_changed_smart(Phase1_Context *p1ctx,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
Eina_Bool restack,
|
|
|
|
Eina_Bool mapped_parent,
|
|
|
|
Eina_Bool src_changed,
|
|
|
|
int level)
|
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *obj2;
|
2016-11-25 17:47:34 -08:00
|
|
|
Phase1_Context *ctx = p1ctx;
|
|
|
|
Phase1_Context tmpctx;
|
|
|
|
Render_Cache *rc = NULL;
|
|
|
|
void *p_del_redir;
|
2016-11-25 18:10:18 -08:00
|
|
|
Evas_Object *eo_obj = obj->object;
|
2016-11-22 04:07:29 -08:00
|
|
|
|
|
|
|
RD(level, " smart + visible/was visible + not clip\n");
|
|
|
|
OBJ_ARRAY_PUSH(p1ctx->render_objects, obj);
|
|
|
|
obj->render_pre = EINA_TRUE;
|
2016-11-25 17:47:34 -08:00
|
|
|
#ifdef RENDCACHE
|
|
|
|
if (obj->no_change_render > 3)
|
2016-11-22 04:07:29 -08:00
|
|
|
{
|
2016-11-25 17:47:34 -08:00
|
|
|
rc = evas_object_smart_render_cache_get(eo_obj);
|
|
|
|
if (!rc)
|
|
|
|
{
|
|
|
|
rc = _evas_render_phase1_object_render_cache_new();
|
|
|
|
evas_object_smart_render_cache_set(eo_obj, rc);
|
|
|
|
ctx = &tmpctx;
|
|
|
|
*ctx = *p1ctx;
|
|
|
|
p_del_redir = p1ctx->e->update_del_redirect_array;
|
|
|
|
p1ctx->e->update_del_redirect_array = rc->update_del;
|
|
|
|
_evas_render_phase1_object_ctx_render_cache_fill(ctx, rc);
|
|
|
|
EINA_INLIST_FOREACH
|
|
|
|
(evas_object_smart_members_get_direct(eo_obj), obj2)
|
|
|
|
{
|
2016-11-25 18:10:18 -08:00
|
|
|
_evas_render_phase1_object_process(ctx, obj2, restack,
|
2016-11-25 17:47:34 -08:00
|
|
|
mapped_parent,
|
2016-11-25 18:10:18 -08:00
|
|
|
src_changed, level + 1);
|
2016-11-25 17:47:34 -08:00
|
|
|
}
|
|
|
|
p1ctx->redraw_all = ctx->redraw_all;
|
|
|
|
p1ctx->e->update_del_redirect_array = p_del_redir;
|
|
|
|
}
|
|
|
|
_evas_render_phase1_object_ctx_render_cache_append(p1ctx, rc);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
EINA_INLIST_FOREACH
|
|
|
|
(evas_object_smart_members_get_direct(eo_obj), obj2)
|
|
|
|
{
|
2016-11-25 18:10:18 -08:00
|
|
|
_evas_render_phase1_object_process(ctx, obj2, restack,
|
2016-11-25 17:47:34 -08:00
|
|
|
mapped_parent,
|
2016-11-25 18:10:18 -08:00
|
|
|
src_changed, level + 1);
|
2016-11-25 17:47:34 -08:00
|
|
|
}
|
2016-11-22 04:07:29 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_render_phase1_object_no_changed_normal(Phase1_Context *p1ctx,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
int level
|
|
|
|
#ifndef REND_DBG
|
|
|
|
EINA_UNUSED
|
|
|
|
#endif
|
|
|
|
)
|
|
|
|
{
|
2016-11-25 18:10:18 -08:00
|
|
|
Evas_Object *eo_obj = obj->object;
|
|
|
|
|
2016-11-22 04:07:29 -08:00
|
|
|
if (evas_object_is_opaque(eo_obj, obj) &&
|
|
|
|
evas_object_is_visible(eo_obj, obj))
|
|
|
|
{
|
|
|
|
RD(level, " opaque + visible\n");
|
|
|
|
OBJ_ARRAY_PUSH(p1ctx->render_objects, obj);
|
|
|
|
obj->rect_del = EINA_TRUE;
|
|
|
|
}
|
|
|
|
else if (evas_object_is_visible(eo_obj, obj))
|
|
|
|
{
|
|
|
|
RD(level, " visible\n");
|
|
|
|
OBJ_ARRAY_PUSH(p1ctx->render_objects, obj);
|
|
|
|
obj->render_pre = EINA_TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RD(level, " skip\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_evas_render_phase1_object_process(Phase1_Context *p1ctx,
|
2016-11-25 18:10:18 -08:00
|
|
|
Evas_Object_Protected_Data *obj,
|
2016-11-22 04:07:29 -08:00
|
|
|
Eina_Bool restack,
|
2014-03-26 23:47:00 -07:00
|
|
|
Eina_Bool mapped_parent,
|
2016-11-21 18:09:18 -08:00
|
|
|
Eina_Bool src_changed,
|
|
|
|
int level)
|
2008-05-26 06:24:24 -07:00
|
|
|
{
|
2009-06-17 03:01:52 -07:00
|
|
|
Eina_Bool clean_them = EINA_FALSE;
|
2016-11-22 04:07:29 -08:00
|
|
|
Eina_Bool map, hmap, can_map, map_not_can_map, obj_changed, is_active;
|
2016-11-25 18:10:18 -08:00
|
|
|
Evas_Object *eo_obj = obj->object;
|
2012-07-16 04:33:12 -07:00
|
|
|
|
2016-11-30 00:36:42 -08:00
|
|
|
EINA_PREFETCH(&(obj->cur->clipper));
|
|
|
|
|
2012-05-15 04:43:23 -07:00
|
|
|
obj->rect_del = EINA_FALSE;
|
|
|
|
obj->render_pre = EINA_FALSE;
|
2008-05-26 06:24:24 -07:00
|
|
|
|
2016-11-22 20:57:27 -08:00
|
|
|
if (obj->delete_me == 2) OBJ_ARRAY_PUSH(p1ctx->delete_objects, obj);
|
2012-04-26 02:53:03 -07:00
|
|
|
else if (obj->delete_me != 0) obj->delete_me++;
|
2016-11-25 17:47:34 -08:00
|
|
|
|
2008-05-26 06:24:24 -07:00
|
|
|
/* If the object will be removed, we should not cache anything during this run. */
|
2009-11-10 00:50:11 -08:00
|
|
|
if (obj->delete_me != 0) clean_them = EINA_TRUE;
|
2008-05-26 06:24:24 -07:00
|
|
|
|
2016-11-25 17:47:34 -08:00
|
|
|
obj_changed = obj->changed;
|
|
|
|
|
|
|
|
if (obj->is_static_clip) goto done;
|
2016-11-22 20:57:27 -08:00
|
|
|
|
|
|
|
//Need pre render for the children of mapped object.
|
|
|
|
//But only when they have changed.
|
2016-11-25 17:47:34 -08:00
|
|
|
if (mapped_parent && (!obj->changed)) goto done;
|
2016-11-22 20:57:27 -08:00
|
|
|
|
2005-10-26 19:44:36 -07:00
|
|
|
/* build active object list */
|
2013-04-06 22:00:10 -07:00
|
|
|
evas_object_clip_recalc(obj);
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2014-03-26 23:47:00 -07:00
|
|
|
if (src_changed) is_active = EINA_TRUE;
|
2014-03-27 00:16:49 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
is_active = evas_object_is_active(eo_obj, obj);
|
2014-09-01 03:45:19 -07:00
|
|
|
if (is_active && obj->proxy->proxies) src_changed = is_active;
|
2014-03-27 00:16:49 -07:00
|
|
|
}
|
|
|
|
obj->is_active = is_active;
|
|
|
|
|
2015-01-26 00:35:42 -08:00
|
|
|
#ifdef REND_DBG
|
2016-03-28 01:47:02 -07:00
|
|
|
RD(level, "[--- PROCESS [%p", obj->object);
|
2015-07-21 01:48:47 -07:00
|
|
|
IFRD(obj->name, 0, " '%s'", obj->name);
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, "] '%s' active = %i, del = %i | %i %i %ix%i\n", obj->type, is_active, obj->delete_me, obj->cur->geometry.x, obj->cur->geometry.y, obj->cur->geometry.w, obj->cur->geometry.h);
|
|
|
|
#endif
|
2012-07-15 20:12:39 -07:00
|
|
|
|
2016-11-22 04:07:29 -08:00
|
|
|
if ((!mapped_parent) &&
|
|
|
|
((is_active) || (obj->delete_me != 0)) &&
|
|
|
|
(!obj->no_render))
|
2016-11-25 21:25:41 -08:00
|
|
|
{
|
|
|
|
Evas_Active_Entry ent;
|
|
|
|
|
|
|
|
#ifdef INLINE_ACTIVE_GEOM
|
|
|
|
if (obj->is_smart)
|
|
|
|
evas_object_smart_bounding_box_get(eo_obj, &(ent.rect), NULL);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ent.rect.x = obj->cur->cache.clip.x;
|
|
|
|
ent.rect.y = obj->cur->cache.clip.y;
|
|
|
|
ent.rect.w = obj->cur->cache.clip.w;
|
|
|
|
ent.rect.h = obj->cur->cache.clip.h;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
ent.obj = obj;
|
|
|
|
eina_inarray_push(p1ctx->active_objects, &ent);
|
|
|
|
}
|
2015-10-07 18:57:54 -07:00
|
|
|
if (is_active && obj->cur->snapshot && !obj->delete_me &&
|
|
|
|
evas_object_is_visible(eo_obj, obj))
|
2016-11-21 18:09:18 -08:00
|
|
|
OBJ_ARRAY_PUSH(p1ctx->snapshot_objects, obj);
|
2009-11-19 00:37:22 -08:00
|
|
|
|
2012-09-12 12:00:23 -07:00
|
|
|
#ifdef REND_DBG
|
2009-11-19 00:37:22 -08:00
|
|
|
if (!is_active)
|
|
|
|
{
|
2016-10-31 19:48:30 -07:00
|
|
|
RD(level, "[%p", obj->object);
|
2015-07-21 01:48:47 -07:00
|
|
|
IFRD(obj->name, 0, " '%s'", obj->name);
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, "] vis: %i, cache.clip.vis: %i cache.clip.a: %i [%p]\n", obj->cur->visible, obj->cur->cache.clip.visible, obj->cur->cache.clip.a, obj->func->is_visible);
|
2009-11-19 00:37:22 -08:00
|
|
|
}
|
2010-04-27 06:43:10 -07:00
|
|
|
#endif
|
|
|
|
|
2016-01-06 04:52:46 -08:00
|
|
|
map = _evas_render_has_map(obj);
|
2012-10-10 00:23:00 -07:00
|
|
|
hmap = _evas_render_had_map(obj);
|
2016-01-06 04:52:46 -08:00
|
|
|
can_map = _evas_render_can_map(obj);
|
2016-11-22 04:07:29 -08:00
|
|
|
map_not_can_map = map & !can_map;
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2016-11-22 04:07:29 -08:00
|
|
|
if (EINA_UNLIKELY((restack && !map_not_can_map)))
|
2005-10-26 23:40:28 -07:00
|
|
|
{
|
2016-11-22 04:07:29 -08:00
|
|
|
_evas_render_phase1_object_restack_handle(p1ctx, obj, obj_changed);
|
|
|
|
obj_changed = EINA_TRUE;
|
2011-05-20 23:23:33 -07:00
|
|
|
clean_them = EINA_TRUE;
|
2005-10-26 23:40:28 -07:00
|
|
|
}
|
2009-11-06 21:01:43 -08:00
|
|
|
|
2016-11-22 04:07:29 -08:00
|
|
|
if (EINA_UNLIKELY(map_not_can_map))
|
2009-10-28 01:59:01 -07:00
|
|
|
{
|
2016-11-25 18:10:18 -08:00
|
|
|
_evas_render_phase1_object_mapped(p1ctx, obj, src_changed, hmap,
|
|
|
|
is_active, obj_changed, level);
|
2016-11-25 17:47:34 -08:00
|
|
|
goto done;
|
2009-10-28 01:59:01 -07:00
|
|
|
}
|
2016-11-22 04:07:29 -08:00
|
|
|
else if (EINA_UNLIKELY(hmap && !can_map))
|
2016-11-25 18:10:18 -08:00
|
|
|
_evas_render_phase1_object_mapped_had_restack(p1ctx, obj, map,
|
|
|
|
obj_changed);
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2009-10-28 01:59:01 -07:00
|
|
|
/* handle normal rendering. this object knows how to handle maps */
|
2016-11-22 04:07:29 -08:00
|
|
|
if (obj_changed)
|
2005-10-26 19:44:36 -07:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
if (obj->is_smart)
|
2016-11-22 04:07:29 -08:00
|
|
|
src_changed =
|
2016-11-25 18:10:18 -08:00
|
|
|
_evas_render_phase1_object_changed_smart(p1ctx, obj, mapped_parent,
|
|
|
|
obj_changed, src_changed,
|
|
|
|
is_active, level);
|
2016-11-22 04:07:29 -08:00
|
|
|
else /* non smart object */
|
2016-11-25 18:10:18 -08:00
|
|
|
_evas_render_phase1_object_changed_normal(p1ctx, obj, is_active,
|
|
|
|
level);
|
2005-10-26 19:44:36 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-11-12 17:47:29 -08:00
|
|
|
/* not changed */
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, " not changed... [%i] -> (%i %i %p %i) [%i]\n",
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_is_visible(eo_obj, obj),
|
2013-03-12 05:58:19 -07:00
|
|
|
obj->cur->visible, obj->cur->cache.clip.visible, obj->smart.smart,
|
|
|
|
obj->cur->cache.clip.a, evas_object_was_visible(eo_obj, obj));
|
2016-11-22 04:07:29 -08:00
|
|
|
if ((!obj->clip.clipees) &&
|
|
|
|
(EINA_LIKELY(obj->delete_me == 0)) &&
|
2012-10-10 00:23:00 -07:00
|
|
|
(_evas_render_can_render(eo_obj, obj) ||
|
2016-11-22 04:07:29 -08:00
|
|
|
(evas_object_was_visible(eo_obj, obj) &&
|
|
|
|
(!obj->prev->have_clipees))))
|
2011-05-20 23:23:33 -07:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
if (obj->is_smart)
|
2016-11-25 18:10:18 -08:00
|
|
|
_evas_render_phase1_object_no_changed_smart(p1ctx, obj, restack,
|
2016-11-22 04:07:29 -08:00
|
|
|
mapped_parent,
|
2016-11-25 18:10:18 -08:00
|
|
|
src_changed, level);
|
2016-11-22 04:07:29 -08:00
|
|
|
else /* not smart */
|
2016-11-25 18:10:18 -08:00
|
|
|
_evas_render_phase1_object_no_changed_normal(p1ctx, obj, level);
|
2009-11-15 05:46:20 -08:00
|
|
|
}
|
2016-11-22 04:07:29 -08:00
|
|
|
else if (EINA_UNLIKELY(is_active &&
|
|
|
|
_evas_render_object_is_mask(obj) &&
|
|
|
|
evas_object_is_visible(eo_obj, obj)))
|
2014-11-12 17:47:29 -08:00
|
|
|
{
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, " visible clipper image\n");
|
2016-11-21 18:09:18 -08:00
|
|
|
OBJ_ARRAY_PUSH(p1ctx->render_objects, obj);
|
2014-11-12 17:47:29 -08:00
|
|
|
obj->render_pre = EINA_TRUE;
|
|
|
|
}
|
2012-07-15 20:12:39 -07:00
|
|
|
}
|
|
|
|
if (!is_active) obj->restack = EINA_FALSE;
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, "---]\n");
|
2016-11-25 17:47:34 -08:00
|
|
|
done:
|
|
|
|
if (obj_changed) obj->no_change_render = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (obj->no_change_render < 255) obj->no_change_render++;
|
|
|
|
}
|
2012-07-15 20:12:39 -07:00
|
|
|
return clean_them;
|
2005-10-26 19:44:36 -07:00
|
|
|
}
|
|
|
|
|
2016-11-25 17:47:34 -08:00
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-06-17 03:01:52 -07:00
|
|
|
static Eina_Bool
|
2016-11-21 18:09:18 -08:00
|
|
|
_evas_render_phase1_process(Phase1_Context *p1ctx)
|
2005-10-26 19:44:36 -07:00
|
|
|
{
|
2008-10-17 04:23:18 -07:00
|
|
|
Evas_Layer *lay;
|
2009-06-17 03:01:52 -07:00
|
|
|
Eina_Bool clean_them = EINA_FALSE;
|
2005-10-26 19:44:36 -07:00
|
|
|
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, " [--- PHASE 1\n");
|
2016-11-21 18:09:18 -08:00
|
|
|
EINA_INLIST_FOREACH(p1ctx->e->layers, lay)
|
2005-10-26 19:44:36 -07:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj;
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2011-05-20 23:23:33 -07:00
|
|
|
EINA_INLIST_FOREACH(lay->objects, obj)
|
|
|
|
{
|
|
|
|
clean_them |= _evas_render_phase1_object_process
|
2016-11-25 18:10:18 -08:00
|
|
|
(p1ctx, obj, EINA_FALSE, EINA_FALSE, EINA_FALSE, 2);
|
2011-05-20 23:23:33 -07:00
|
|
|
}
|
2008-05-26 06:24:24 -07:00
|
|
|
}
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, " ---]\n");
|
2008-05-26 06:24:24 -07:00
|
|
|
return clean_them;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *eo_e EINA_UNUSED, Evas_Public_Data *e)
|
2008-05-26 06:24:24 -07:00
|
|
|
{
|
2010-05-05 04:36:21 -07:00
|
|
|
unsigned int i;
|
2008-05-26 06:24:24 -07:00
|
|
|
|
|
|
|
for (i = 0; i < pending_objects->count; ++i)
|
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_obj;
|
2012-05-16 06:21:37 -07:00
|
|
|
int is_active;
|
|
|
|
Eina_Bool ok = EINA_FALSE;
|
2012-10-08 18:58:41 -07:00
|
|
|
|
2016-11-30 00:36:42 -08:00
|
|
|
Evas_Object_Protected_Data *obj = eina_array_data_get(pending_objects, i);
|
2012-10-08 18:58:41 -07:00
|
|
|
eo_obj = obj->object;
|
|
|
|
|
2011-05-20 23:23:33 -07:00
|
|
|
if (!obj->layer) goto clean_stuff;
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2016-11-30 00:36:42 -08:00
|
|
|
EINA_PREFETCH(&(obj->cur->clipper));
|
|
|
|
EINA_PREFETCH(&(obj->cur->cache.clip));
|
2016-11-26 19:02:12 -08:00
|
|
|
//If the children are in active objects, They should be cleaned up.
|
|
|
|
if (EINA_UNLIKELY((obj->changed_map) &&
|
|
|
|
(_evas_render_has_map(obj)) &&
|
|
|
|
(!_evas_render_can_map(obj))))
|
|
|
|
goto clean_stuff;
|
2012-05-29 17:51:11 -07:00
|
|
|
|
2013-04-06 22:00:10 -07:00
|
|
|
evas_object_clip_recalc(obj);
|
2012-10-08 18:58:41 -07:00
|
|
|
is_active = evas_object_is_active(eo_obj, obj);
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2011-05-20 23:23:33 -07:00
|
|
|
if ((!is_active) && (!obj->is_active) && (!obj->render_pre) &&
|
2009-10-30 03:11:15 -07:00
|
|
|
(!obj->rect_del))
|
2011-05-20 23:23:33 -07:00
|
|
|
{
|
2012-05-16 06:21:37 -07:00
|
|
|
ok = EINA_TRUE;
|
2011-05-20 23:23:33 -07:00
|
|
|
goto clean_stuff;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (obj->is_active == is_active)
|
|
|
|
{
|
|
|
|
if (obj->changed)
|
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
if (obj->is_smart)
|
2011-05-20 23:23:33 -07:00
|
|
|
{
|
2012-05-16 06:21:37 -07:00
|
|
|
if (obj->render_pre || obj->rect_del) ok = EINA_TRUE;
|
2011-05-20 23:23:33 -07:00
|
|
|
}
|
2009-10-28 01:59:01 -07:00
|
|
|
else
|
2011-05-20 23:23:33 -07:00
|
|
|
if ((is_active) && (obj->restack) && (!obj->clip.clipees) &&
|
2012-10-10 00:23:00 -07:00
|
|
|
(_evas_render_can_render(eo_obj, obj) ||
|
2013-03-12 05:58:19 -07:00
|
|
|
(evas_object_was_visible(eo_obj, obj) && (!obj->prev->have_clipees))))
|
2009-10-28 01:59:01 -07:00
|
|
|
{
|
2012-05-16 06:21:37 -07:00
|
|
|
if (!(obj->render_pre || obj->rect_del))
|
|
|
|
ok = EINA_TRUE;
|
2009-10-28 01:59:01 -07:00
|
|
|
}
|
2011-05-20 23:23:33 -07:00
|
|
|
else
|
|
|
|
if (is_active && (!obj->clip.clipees) &&
|
2012-10-10 00:23:00 -07:00
|
|
|
(_evas_render_can_render(eo_obj, obj) ||
|
2013-03-12 05:58:19 -07:00
|
|
|
(evas_object_was_visible(eo_obj, obj) && (!obj->prev->have_clipees))))
|
2011-05-20 23:23:33 -07:00
|
|
|
{
|
2012-05-16 06:21:37 -07:00
|
|
|
if (obj->render_pre || obj->rect_del) ok = EINA_TRUE;
|
2011-05-20 23:23:33 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((!obj->clip.clipees) && (obj->delete_me == 0) &&
|
2013-03-12 05:58:19 -07:00
|
|
|
(!obj->cur->have_clipees || (evas_object_was_visible(eo_obj, obj) && (!obj->prev->have_clipees)))
|
2012-10-08 18:58:41 -07:00
|
|
|
&& evas_object_is_opaque(eo_obj, obj) && evas_object_is_visible(eo_obj, obj))
|
2009-10-30 03:11:15 -07:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
if (obj->rect_del || obj->is_smart) ok = EINA_TRUE;
|
2009-10-30 03:11:15 -07:00
|
|
|
}
|
2011-05-20 23:23:33 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
clean_stuff:
|
|
|
|
if (!ok)
|
|
|
|
{
|
2016-11-25 21:25:41 -08:00
|
|
|
eina_inarray_flush(&e->active_objects);
|
2013-05-02 00:47:16 -07:00
|
|
|
OBJS_ARRAY_CLEAN(&e->render_objects);
|
|
|
|
OBJS_ARRAY_CLEAN(&e->restack_objects);
|
|
|
|
OBJS_ARRAY_CLEAN(&e->delete_objects);
|
2015-05-09 11:02:13 -07:00
|
|
|
OBJS_ARRAY_CLEAN(&e->snapshot_objects);
|
2012-05-16 06:21:37 -07:00
|
|
|
e->invalidate = EINA_TRUE;
|
2013-06-20 04:28:18 -07:00
|
|
|
return;
|
2011-05-20 23:23:33 -07:00
|
|
|
}
|
2005-10-26 19:44:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-03 22:13:19 -07:00
|
|
|
Eina_Bool
|
2012-10-08 18:58:41 -07:00
|
|
|
pending_change(void *data, void *gdata EINA_UNUSED)
|
2008-06-04 09:42:39 -07:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_obj;
|
2008-06-04 09:42:39 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = data;
|
|
|
|
eo_obj = obj->object;
|
2008-10-16 05:27:07 -07:00
|
|
|
if (obj->delete_me) return EINA_FALSE;
|
2009-11-23 02:07:07 -08:00
|
|
|
if (obj->pre_render_done)
|
|
|
|
{
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, " OBJ [%p", obj);
|
2015-07-21 01:48:47 -07:00
|
|
|
IFRD(obj->name, 0, " '%s'", obj->name);
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, "] pending change %i -> 0, pre %i\n", obj->changed, obj->pre_render_done);
|
2013-07-08 17:46:15 -07:00
|
|
|
obj->func->render_post(eo_obj, obj, obj->private_data);
|
2012-05-16 06:21:37 -07:00
|
|
|
obj->pre_render_done = EINA_FALSE;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change_reset(eo_obj);
|
2009-11-23 02:07:07 -08:00
|
|
|
}
|
2013-12-19 00:34:05 -08:00
|
|
|
else if (!_evas_render_can_render(eo_obj, obj) &&
|
|
|
|
(!obj->is_active) && (!obj->render_pre) &&
|
|
|
|
(!obj->rect_del))
|
|
|
|
{
|
|
|
|
evas_object_change_reset(eo_obj);
|
|
|
|
}
|
2016-08-15 06:44:41 -07:00
|
|
|
if (!obj->changed) efl_data_unref(eo_obj, obj);
|
2008-10-16 05:27:07 -07:00
|
|
|
return obj->changed ? EINA_TRUE : EINA_FALSE;
|
2008-06-04 09:42:39 -07:00
|
|
|
}
|
2011-01-19 03:59:53 -08:00
|
|
|
|
2011-10-02 20:28:52 -07:00
|
|
|
static Eina_Bool
|
2012-10-10 00:23:00 -07:00
|
|
|
_evas_render_can_use_overlay(Evas_Public_Data *e, Evas_Object *eo_obj)
|
2011-10-02 20:28:52 -07:00
|
|
|
{
|
|
|
|
Eina_Rectangle *r;
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_tmp;
|
2011-10-02 20:28:52 -07:00
|
|
|
Eina_List *alphas = NULL;
|
|
|
|
Eina_List *opaques = NULL;
|
|
|
|
Evas_Object *video_parent = NULL;
|
|
|
|
Eina_Rectangle zone;
|
|
|
|
Evas_Coord xc1, yc1, xc2, yc2;
|
2015-05-09 11:02:13 -07:00
|
|
|
int i;
|
2011-10-02 20:28:52 -07:00
|
|
|
Eina_Bool nooverlay;
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-10 00:23:00 -07:00
|
|
|
Evas_Object_Protected_Data *tmp = NULL;
|
evas/image: Add video surface caps.
Wayland subsurfaces can be used as video surfaces too, similarly to
Ecore_X windows. However, they support a different set of features. Some
of them, like subsurface clipping and scaling, might be added in the
future, but so far we must work with what we have.
This commit allows to set an enum bitfield to the Video_Surface, with
the default value being one that will keep the same behavior as before,
for Ecore_X window. Thus, backward compatibility should not be broken.
It's possible to inform Evas that the surface in question is not able to
resize or scale, or that it's above or below the original canvas
surface. This allows Evas to show the surface itself, or use a buffer of
pixels instead, when the capabilities are not available.
2013-09-26 09:49:18 -07:00
|
|
|
Evas_Coord imgw, imgh;
|
|
|
|
unsigned int caps;
|
|
|
|
Eina_Bool surface_below, stacking_check, object_above = EINA_FALSE;
|
|
|
|
Eina_Bool ignore_window;
|
2011-10-02 20:28:52 -07:00
|
|
|
|
2016-08-10 07:23:04 -07:00
|
|
|
video_parent = _evas_object_image_videfl_parent_get(eo_obj);
|
2011-10-02 20:28:52 -07:00
|
|
|
|
|
|
|
/* Check if any one is the stack make this object mapped */
|
2012-10-08 18:58:41 -07:00
|
|
|
eo_tmp = eo_obj;
|
2016-08-15 06:44:41 -07:00
|
|
|
tmp = efl_data_scope_get(eo_tmp, EFL_CANVAS_OBJECT_CLASS);
|
2016-01-06 04:52:46 -08:00
|
|
|
while (tmp && !(_evas_render_has_map(tmp) && !_evas_render_can_map(tmp)))
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
|
|
|
eo_tmp = tmp->smart.parent;
|
2016-08-15 06:44:41 -07:00
|
|
|
tmp = efl_data_scope_get(eo_tmp, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2011-10-02 20:28:52 -07:00
|
|
|
|
2016-01-06 04:52:46 -08:00
|
|
|
if (tmp && _evas_render_has_map(tmp) && !_evas_render_can_map(tmp))
|
|
|
|
return EINA_FALSE; /* we are mapped, we can't be an overlay */
|
2011-10-02 20:28:52 -07:00
|
|
|
|
2016-01-06 04:52:46 -08:00
|
|
|
if (!evas_object_is_visible(eo_obj, obj))
|
|
|
|
return EINA_FALSE; /* no need to update the overlay if it's not visible */
|
2011-10-02 20:28:52 -07:00
|
|
|
|
|
|
|
/* If any recoloring of the surface is needed, n overlay to */
|
2013-03-12 05:58:19 -07:00
|
|
|
if ((obj->cur->cache.clip.r != 255) ||
|
|
|
|
(obj->cur->cache.clip.g != 255) ||
|
|
|
|
(obj->cur->cache.clip.b != 255) ||
|
|
|
|
(obj->cur->cache.clip.a != 255))
|
2011-10-02 20:28:52 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
|
evas/image: Add video surface caps.
Wayland subsurfaces can be used as video surfaces too, similarly to
Ecore_X windows. However, they support a different set of features. Some
of them, like subsurface clipping and scaling, might be added in the
future, but so far we must work with what we have.
This commit allows to set an enum bitfield to the Video_Surface, with
the default value being one that will keep the same behavior as before,
for Ecore_X window. Thus, backward compatibility should not be broken.
It's possible to inform Evas that the surface in question is not able to
resize or scale, or that it's above or below the original canvas
surface. This allows Evas to show the surface itself, or use a buffer of
pixels instead, when the capabilities are not available.
2013-09-26 09:49:18 -07:00
|
|
|
caps = evas_object_image_video_surface_caps_get(eo_obj);
|
|
|
|
|
|
|
|
/* check if surface is above the canvas */
|
|
|
|
surface_below = !!(caps & EVAS_VIDEO_SURFACE_BELOW);
|
|
|
|
if (!surface_below)
|
|
|
|
{
|
|
|
|
/* above canvas, must support resize and clipping */
|
|
|
|
|
|
|
|
/* check if video surface supports resize */
|
|
|
|
evas_object_image_size_get(eo_obj, &imgw, &imgh);
|
|
|
|
if ((obj->cur->geometry.w != imgw) ||
|
|
|
|
(obj->cur->geometry.h != imgh))
|
|
|
|
{
|
|
|
|
if (!(caps & EVAS_VIDEO_SURFACE_RESIZE))
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
/* check if video surface supports clipping */
|
|
|
|
evas_object_image_size_get(eo_obj, &imgw, &imgh);
|
|
|
|
if ((obj->cur->cache.clip.x != obj->cur->geometry.x) ||
|
|
|
|
(obj->cur->cache.clip.y != obj->cur->geometry.y) ||
|
|
|
|
(obj->cur->cache.clip.w != obj->cur->geometry.w) ||
|
|
|
|
(obj->cur->cache.clip.h != obj->cur->geometry.h))
|
|
|
|
{
|
|
|
|
if (!(caps & EVAS_VIDEO_SURFACE_CLIP))
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check for window/surface/canvas limits */
|
|
|
|
ignore_window = !!(caps & EVAS_VIDEO_SURFACE_IGNORE_WINDOW);
|
|
|
|
if (!ignore_window)
|
|
|
|
{
|
|
|
|
Evas_Coord x1, x2, y1, y2;
|
|
|
|
Evas_Coord fx, fy, fw, fh;
|
|
|
|
|
|
|
|
fx = e->framespace.x;
|
|
|
|
fy = e->framespace.y;
|
|
|
|
fw = e->framespace.w;
|
|
|
|
fh = e->framespace.h;
|
|
|
|
|
|
|
|
x1 = obj->cur->geometry.x + fx;
|
|
|
|
y1 = obj->cur->geometry.y + fy;
|
|
|
|
x2 = obj->cur->geometry.x + obj->cur->geometry.w + fx;
|
|
|
|
y2 = obj->cur->geometry.y + obj->cur->geometry.h + fy;
|
|
|
|
|
|
|
|
if ((x1 < fx) || (y1 < fy) ||
|
|
|
|
(x2 > e->output.w - (fw - fx)) ||
|
|
|
|
(y2 > e->output.h - (fh - fy)))
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check if there are other objects above the video object? */
|
|
|
|
stacking_check = !!(caps & EVAS_VIDEO_SURFACE_STACKING_CHECK);
|
|
|
|
if (!stacking_check)
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
2011-10-02 20:28:52 -07:00
|
|
|
/* Check presence of transparent object on top of the video object */
|
|
|
|
EINA_RECTANGLE_SET(&zone,
|
2013-03-12 05:58:19 -07:00
|
|
|
obj->cur->cache.clip.x,
|
|
|
|
obj->cur->cache.clip.y,
|
|
|
|
obj->cur->cache.clip.w,
|
|
|
|
obj->cur->cache.clip.h);
|
2011-10-02 20:28:52 -07:00
|
|
|
|
2016-11-25 21:25:41 -08:00
|
|
|
for (i = e->active_objects.len - 1; i > 0; i--)
|
2011-10-02 20:28:52 -07:00
|
|
|
{
|
|
|
|
Eina_Rectangle self;
|
|
|
|
Eina_Rectangle *match;
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_current;
|
2011-10-02 20:28:52 -07:00
|
|
|
Eina_List *l;
|
|
|
|
int xm1, ym1, xm2, ym2;
|
2016-11-25 21:25:41 -08:00
|
|
|
Evas_Active_Entry *ent = eina_inarray_nth(&e->active_objects, i);
|
|
|
|
Evas_Object_Protected_Data *current = ent->obj;
|
2011-10-02 20:28:52 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
eo_current = current->object;
|
2011-10-02 20:28:52 -07:00
|
|
|
/* Did we find the video object in the stack ? */
|
2012-10-08 18:58:41 -07:00
|
|
|
if (eo_current == video_parent || eo_current == eo_obj)
|
2011-10-02 20:28:52 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
EINA_RECTANGLE_SET(&self,
|
2013-03-12 05:58:19 -07:00
|
|
|
current->cur->cache.clip.x,
|
|
|
|
current->cur->cache.clip.y,
|
|
|
|
current->cur->cache.clip.w,
|
|
|
|
current->cur->cache.clip.h);
|
2011-10-02 20:28:52 -07:00
|
|
|
|
|
|
|
/* This doesn't cover the area of the video object, so don't bother with that object */
|
|
|
|
if (!eina_rectangles_intersect(&zone, &self))
|
2012-05-25 05:55:45 -07:00
|
|
|
continue;
|
2011-10-02 20:28:52 -07:00
|
|
|
|
2013-03-12 05:58:19 -07:00
|
|
|
xc1 = current->cur->cache.clip.x;
|
|
|
|
yc1 = current->cur->cache.clip.y;
|
|
|
|
xc2 = current->cur->cache.clip.x + current->cur->cache.clip.w;
|
|
|
|
yc2 = current->cur->cache.clip.y + current->cur->cache.clip.h;
|
2011-10-02 20:28:52 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
if (evas_object_is_visible(eo_current, current) &&
|
2011-10-02 20:28:52 -07:00
|
|
|
(!current->clip.clipees) &&
|
2013-03-12 05:58:19 -07:00
|
|
|
(current->cur->visible) &&
|
2011-10-02 20:28:52 -07:00
|
|
|
(!current->delete_me) &&
|
2013-03-12 05:58:19 -07:00
|
|
|
(current->cur->cache.clip.visible) &&
|
2016-08-15 06:44:41 -07:00
|
|
|
(!efl_isa(eo_current, EFL_CANVAS_GROUP_CLASS)))
|
2011-10-02 20:28:52 -07:00
|
|
|
{
|
|
|
|
Eina_Bool included = EINA_FALSE;
|
|
|
|
|
evas/image: Add video surface caps.
Wayland subsurfaces can be used as video surfaces too, similarly to
Ecore_X windows. However, they support a different set of features. Some
of them, like subsurface clipping and scaling, might be added in the
future, but so far we must work with what we have.
This commit allows to set an enum bitfield to the Video_Surface, with
the default value being one that will keep the same behavior as before,
for Ecore_X window. Thus, backward compatibility should not be broken.
It's possible to inform Evas that the surface in question is not able to
resize or scale, or that it's above or below the original canvas
surface. This allows Evas to show the surface itself, or use a buffer of
pixels instead, when the capabilities are not available.
2013-09-26 09:49:18 -07:00
|
|
|
if (!surface_below)
|
|
|
|
{
|
|
|
|
object_above = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
if (evas_object_is_opaque(eo_current, current) ||
|
2011-10-02 20:28:52 -07:00
|
|
|
((current->func->has_opaque_rect) &&
|
2013-07-08 17:46:15 -07:00
|
|
|
(current->func->has_opaque_rect(eo_current, current, current->private_data))))
|
2011-10-02 20:28:52 -07:00
|
|
|
{
|
|
|
|
/* The object is opaque */
|
|
|
|
|
|
|
|
/* Check if the opaque object is inside another opaque object */
|
|
|
|
EINA_LIST_FOREACH(opaques, l, match)
|
|
|
|
{
|
|
|
|
xm1 = match->x;
|
|
|
|
ym1 = match->y;
|
|
|
|
xm2 = match->x + match->w;
|
|
|
|
ym2 = match->y + match->h;
|
|
|
|
|
|
|
|
/* Both object are included */
|
|
|
|
if (xc1 >= xm1 && yc1 >= ym1 && xc2 <= xm2 && yc2 <= ym2)
|
|
|
|
{
|
|
|
|
included = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Not included yet */
|
|
|
|
if (!included)
|
|
|
|
{
|
|
|
|
Eina_List *ln;
|
|
|
|
Evas_Coord xn2, yn2;
|
|
|
|
|
2013-03-12 05:58:19 -07:00
|
|
|
r = eina_rectangle_new(current->cur->cache.clip.x, current->cur->cache.clip.y,
|
|
|
|
current->cur->cache.clip.w, current->cur->cache.clip.h);
|
2011-10-02 20:28:52 -07:00
|
|
|
|
|
|
|
opaques = eina_list_append(opaques, r);
|
|
|
|
|
|
|
|
xn2 = r->x + r->w;
|
|
|
|
yn2 = r->y + r->h;
|
|
|
|
|
|
|
|
/* Remove all the transparent object that are covered by the new opaque object */
|
|
|
|
EINA_LIST_FOREACH_SAFE(alphas, l, ln, match)
|
|
|
|
{
|
|
|
|
xm1 = match->x;
|
|
|
|
ym1 = match->y;
|
|
|
|
xm2 = match->x + match->w;
|
|
|
|
ym2 = match->y + match->h;
|
|
|
|
|
|
|
|
if (xm1 >= r->x && ym1 >= r->y && xm2 <= xn2 && ym2 <= yn2)
|
|
|
|
{
|
|
|
|
/* The new rectangle is over some transparent object,
|
|
|
|
so remove the transparent object */
|
|
|
|
alphas = eina_list_remove_list(alphas, l);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* The object has some transparency */
|
|
|
|
|
|
|
|
/* Check if the transparent object is inside any other transparent object */
|
|
|
|
EINA_LIST_FOREACH(alphas, l, match)
|
|
|
|
{
|
|
|
|
xm1 = match->x;
|
|
|
|
ym1 = match->y;
|
|
|
|
xm2 = match->x + match->w;
|
|
|
|
ym2 = match->y + match->h;
|
|
|
|
|
|
|
|
/* Both object are included */
|
|
|
|
if (xc1 >= xm1 && yc1 >= ym1 && xc2 <= xm2 && yc2 <= ym2)
|
|
|
|
{
|
|
|
|
included = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If not check if it is inside any opaque one */
|
|
|
|
if (!included)
|
|
|
|
{
|
|
|
|
EINA_LIST_FOREACH(opaques, l, match)
|
|
|
|
{
|
|
|
|
xm1 = match->x;
|
|
|
|
ym1 = match->y;
|
|
|
|
xm2 = match->x + match->w;
|
|
|
|
ym2 = match->y + match->h;
|
|
|
|
|
|
|
|
/* Both object are included */
|
|
|
|
if (xc1 >= xm1 && yc1 >= ym1 && xc2 <= xm2 && yc2 <= ym2)
|
|
|
|
{
|
|
|
|
included = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No inclusion at all, so add it */
|
|
|
|
if (!included)
|
|
|
|
{
|
2013-03-12 05:58:19 -07:00
|
|
|
r = eina_rectangle_new(current->cur->cache.clip.x, current->cur->cache.clip.y,
|
|
|
|
current->cur->cache.clip.w, current->cur->cache.clip.h);
|
2011-10-02 20:28:52 -07:00
|
|
|
|
|
|
|
alphas = eina_list_append(alphas, r);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If there is any pending transparent object, then no overlay */
|
|
|
|
nooverlay = !!eina_list_count(alphas);
|
|
|
|
|
|
|
|
EINA_LIST_FREE(alphas, r)
|
|
|
|
eina_rectangle_free(r);
|
|
|
|
EINA_LIST_FREE(opaques, r)
|
|
|
|
eina_rectangle_free(r);
|
|
|
|
|
evas/image: Add video surface caps.
Wayland subsurfaces can be used as video surfaces too, similarly to
Ecore_X windows. However, they support a different set of features. Some
of them, like subsurface clipping and scaling, might be added in the
future, but so far we must work with what we have.
This commit allows to set an enum bitfield to the Video_Surface, with
the default value being one that will keep the same behavior as before,
for Ecore_X window. Thus, backward compatibility should not be broken.
It's possible to inform Evas that the surface in question is not able to
resize or scale, or that it's above or below the original canvas
surface. This allows Evas to show the surface itself, or use a buffer of
pixels instead, when the capabilities are not available.
2013-09-26 09:49:18 -07:00
|
|
|
if (nooverlay || object_above)
|
2011-10-02 20:28:52 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
2008-06-04 09:42:39 -07:00
|
|
|
|
2015-09-03 01:38:48 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_proxy_context_clip(Evas_Public_Data *evas, void *ctx, Evas_Proxy_Render_Data *proxy_render_data, Evas_Object_Protected_Data *obj, int off_x, int off_y)
|
|
|
|
{
|
|
|
|
const Evas_Coord_Rectangle *clip;
|
|
|
|
Evas_Object_Protected_Data *clipper;
|
2015-10-13 04:33:57 -07:00
|
|
|
int cw, ch;
|
2015-09-03 01:38:48 -07:00
|
|
|
|
|
|
|
/* cache.clip can not be relied on, since the evas is frozen, but we need
|
|
|
|
* to set the clip. so we recurse from clipper to clipper until we reach
|
|
|
|
* the source object's clipper */
|
|
|
|
|
2015-10-13 04:33:57 -07:00
|
|
|
if (!proxy_render_data) return EINA_TRUE;
|
|
|
|
if (proxy_render_data->source_clip)
|
|
|
|
{
|
|
|
|
/* trust cache.clip since we clip like the source */
|
|
|
|
ENFN->context_clip_clip(ENDT, ctx,
|
|
|
|
obj->cur->cache.clip.x + off_x,
|
|
|
|
obj->cur->cache.clip.y + off_y,
|
|
|
|
obj->cur->cache.clip.w, obj->cur->cache.clip.h);
|
|
|
|
ENFN->context_clip_get(ENDT, ctx, NULL, NULL, &cw, &ch);
|
2016-06-23 08:26:02 -07:00
|
|
|
return ((cw > 0) && (ch > 0));
|
2015-10-13 04:33:57 -07:00
|
|
|
}
|
|
|
|
|
2015-09-03 01:38:48 -07:00
|
|
|
if (!obj || !obj->cur->clipper) return EINA_TRUE;
|
|
|
|
|
|
|
|
clipper = obj->cur->clipper;
|
|
|
|
if (!clipper->cur->visible) return EINA_FALSE;
|
|
|
|
clip = &clipper->cur->geometry;
|
|
|
|
ENFN->context_clip_clip(ENDT, ctx, clip->x + off_x, clip->y + off_y, clip->w, clip->h);
|
2015-10-13 04:33:57 -07:00
|
|
|
ENFN->context_clip_get(ENDT, ctx, NULL, NULL, &cw, &ch);
|
2016-06-23 08:26:02 -07:00
|
|
|
if ((cw <= 0) || (ch <= 0)) return EINA_FALSE;
|
2015-09-03 01:38:48 -07:00
|
|
|
|
|
|
|
/* stop if we found the source object's clipper */
|
2015-10-13 04:33:57 -07:00
|
|
|
if (clipper == proxy_render_data->src_obj->cur->clipper) return EINA_TRUE;
|
2015-09-03 01:38:48 -07:00
|
|
|
|
2016-06-23 08:48:34 -07:00
|
|
|
/* recurse to the clipper itself.
|
|
|
|
* origin of clipper's clipper won't be transformed to derivative space. */
|
|
|
|
return _proxy_context_clip(evas, ctx, proxy_render_data, clipper,
|
2016-06-23 19:33:04 -07:00
|
|
|
-proxy_render_data->src_obj->cur->geometry.x,
|
|
|
|
-proxy_render_data->src_obj->cur->geometry.y);
|
2015-09-03 01:38:48 -07:00
|
|
|
}
|
|
|
|
|
2013-07-04 19:09:03 -07:00
|
|
|
static void
|
2015-09-03 00:36:32 -07:00
|
|
|
_evas_render_mapped_context_clip_set(Evas_Public_Data *evas, Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *ctx, Evas_Proxy_Render_Data *proxy_render_data, int off_x, int off_y)
|
2013-07-04 19:09:03 -07:00
|
|
|
{
|
|
|
|
int x, y, w, h;
|
|
|
|
Eina_Bool proxy_src_clip = EINA_TRUE;
|
|
|
|
|
|
|
|
if (proxy_render_data) proxy_src_clip = proxy_render_data->source_clip;
|
|
|
|
|
2015-10-13 04:33:57 -07:00
|
|
|
if (proxy_src_clip)
|
2013-07-04 19:09:03 -07:00
|
|
|
{
|
|
|
|
x = obj->cur->cache.clip.x;
|
|
|
|
y = obj->cur->cache.clip.y;
|
|
|
|
w = obj->cur->cache.clip.w;
|
|
|
|
h = obj->cur->cache.clip.h;
|
|
|
|
|
|
|
|
RECTS_CLIP_TO_RECT(x, y, w, h,
|
|
|
|
obj->cur->clipper->cur->cache.clip.x,
|
|
|
|
obj->cur->clipper->cur->cache.clip.y,
|
|
|
|
obj->cur->clipper->cur->cache.clip.w,
|
|
|
|
obj->cur->clipper->cur->cache.clip.h);
|
|
|
|
|
2015-09-03 00:36:32 -07:00
|
|
|
ENFN->context_clip_set(ENDT, ctx, x + off_x, y + off_y, w, h);
|
2013-07-04 19:09:03 -07:00
|
|
|
}
|
2015-10-06 01:36:29 -07:00
|
|
|
else if (evas->is_frozen)
|
|
|
|
{
|
|
|
|
/* can't trust cache.clip here - clip should be in ctx already */
|
|
|
|
}
|
2013-07-04 19:09:03 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
//FIXME: Consider to clip by the proxy clipper.
|
|
|
|
if (proxy_render_data->eo_src != eo_obj)
|
|
|
|
{
|
|
|
|
x = obj->cur->clipper->cur->geometry.x + off_x;
|
|
|
|
y = obj->cur->clipper->cur->geometry.y + off_y;
|
|
|
|
w = obj->cur->clipper->cur->geometry.w;
|
|
|
|
h = obj->cur->clipper->cur->geometry.h;
|
2015-09-03 00:36:32 -07:00
|
|
|
ENFN->context_clip_clip(ENDT, ctx, x, y, w, h);
|
2013-07-04 19:09:03 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-20 07:40:28 -07:00
|
|
|
Eina_Bool
|
2015-09-02 20:11:52 -07:00
|
|
|
evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
|
2012-10-18 04:30:04 -07:00
|
|
|
Evas_Object_Protected_Data *obj, void *context,
|
|
|
|
void *surface, int off_x, int off_y, int mapped, int ecx,
|
2013-05-31 04:28:12 -07:00
|
|
|
int ecy, int ecw, int ech,
|
2014-11-04 21:54:35 -08:00
|
|
|
Evas_Proxy_Render_Data *proxy_render_data, int level,
|
2014-11-12 02:18:09 -08:00
|
|
|
Eina_Bool use_mapped_ctx, Eina_Bool do_async)
|
2009-10-30 03:11:15 -07:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj2;
|
2010-05-05 04:36:21 -07:00
|
|
|
Eina_Bool clean_them = EINA_FALSE;
|
2013-05-06 06:18:08 -07:00
|
|
|
Eina_Bool proxy_src_clip = EINA_TRUE;
|
2015-09-02 22:06:36 -07:00
|
|
|
void *ctx;
|
2009-11-15 05:46:20 -08:00
|
|
|
|
2013-05-31 04:28:12 -07:00
|
|
|
if (!proxy_render_data)
|
2013-04-29 05:05:33 -07:00
|
|
|
{
|
2015-09-03 01:38:48 -07:00
|
|
|
/* don't render if the source is invisible */
|
2013-04-29 05:05:33 -07:00
|
|
|
if ((evas_object_is_source_invisible(eo_obj, obj)))
|
|
|
|
return clean_them;
|
|
|
|
}
|
|
|
|
else
|
2013-05-31 04:28:12 -07:00
|
|
|
proxy_src_clip = proxy_render_data->source_clip;
|
2013-04-28 23:30:37 -07:00
|
|
|
|
2016-11-30 00:36:42 -08:00
|
|
|
evas_object_clip_recalc(obj);
|
|
|
|
|
2015-09-03 01:38:48 -07:00
|
|
|
/* leave early if clipper is not visible */
|
2016-11-26 19:02:12 -08:00
|
|
|
if ((obj->cur->clipper) && (!obj->cur->clipper->cur->visible))
|
2015-09-03 01:38:48 -07:00
|
|
|
return clean_them;
|
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+render_object", eo_obj, 0.0, NULL);
|
2015-01-26 00:35:42 -08:00
|
|
|
#ifdef REND_DBG
|
|
|
|
RD(level, "{\n");
|
2016-10-31 19:48:30 -07:00
|
|
|
RD(level, " evas_render_mapped(evas:%p, obj:%p", evas->evas, obj->object);
|
2015-07-21 01:48:47 -07:00
|
|
|
IFRD(obj->name, 0, " '%s'", obj->name);
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, ", ctx:%p, sfc:%p, offset:%i,%i, %s, use_mapped_ctx:%d, %s)\n", context, surface, off_x, off_y,
|
|
|
|
mapped ? "mapped" : "normal", use_mapped_ctx, do_async ? "async" : "sync");
|
|
|
|
RD(level, " obj: '%s' %s", obj->type, obj->is_smart ? "(smart) " : "");
|
2016-11-16 01:09:37 -08:00
|
|
|
if (obj->is_frame) RD(0, "(frame) ");
|
2015-09-01 04:47:40 -07:00
|
|
|
if (obj->name) RD(0, "'%s'\n", obj->name);
|
2015-01-26 00:35:42 -08:00
|
|
|
else RD(0, "\n");
|
|
|
|
if (obj->cur->clipper)
|
2013-08-19 00:35:34 -07:00
|
|
|
{
|
2016-10-13 01:42:38 -07:00
|
|
|
RD(level, " clipper: '%s'%s%s %p (mask: %p) %d,%d %dx%d ; color: {%d,%d,%d,%d} ; cached: {%d,%d,%d,%d}\n",
|
2015-01-26 00:35:42 -08:00
|
|
|
obj->cur->clipper->type,
|
|
|
|
obj->cur->clipper->name ? ":" : "",
|
|
|
|
obj->cur->clipper->name ? obj->cur->clipper->name : "",
|
2016-10-31 19:48:30 -07:00
|
|
|
obj->cur->clipper->object, obj->clip.mask ? obj->clip.mask->object : NULL,
|
2015-01-26 00:35:42 -08:00
|
|
|
obj->cur->clipper->cur->geometry.x, obj->cur->clipper->cur->geometry.y,
|
2016-10-13 01:42:38 -07:00
|
|
|
obj->cur->clipper->cur->geometry.w, obj->cur->clipper->cur->geometry.h,
|
|
|
|
obj->cur->clipper->cur->color.r, obj->cur->clipper->cur->color.g,
|
|
|
|
obj->cur->clipper->cur->color.b, obj->cur->clipper->cur->color.a,
|
|
|
|
obj->cur->clipper->cur->cache.clip.r, obj->cur->clipper->cur->cache.clip.g,
|
|
|
|
obj->cur->clipper->cur->cache.clip.b, obj->cur->clipper->cur->cache.clip.a);
|
2013-08-19 00:35:34 -07:00
|
|
|
}
|
2015-09-01 04:47:40 -07:00
|
|
|
|
2016-10-13 01:42:38 -07:00
|
|
|
RD(level, " geom: %d,%d %dx%d, cache.clip: (vis: %d) %d,%d %dx%d ; color: {%d,%d,%d,%d} ; cached: {%d,%d,%d,%d}\n",
|
|
|
|
obj->cur->geometry.x, obj->cur->geometry.y, obj->cur->geometry.w, obj->cur->geometry.h, obj->cur->cache.clip.visible,
|
|
|
|
obj->cur->cache.clip.x, obj->cur->cache.clip.y, obj->cur->cache.clip.w, obj->cur->cache.clip.h,
|
|
|
|
obj->cur->color.r, obj->cur->color.g, obj->cur->color.b, obj->cur->color.a,
|
|
|
|
obj->cur->cache.clip.r, obj->cur->cache.clip.g, obj->cur->cache.clip.b, obj->cur->cache.clip.a);
|
2015-09-03 00:36:32 -07:00
|
|
|
{
|
2016-10-13 01:42:38 -07:00
|
|
|
int _cu, _cc, _cm, _cx, _cy, _cw, _ch, _cr, _cg, _cb, _ca, _cmr, _cmg, _cmb, _cma;
|
|
|
|
_cu = ENFN->context_clip_get(ENDT, context, &_cx, &_cy, &_cw, &_ch);
|
2016-10-31 19:48:30 -07:00
|
|
|
_cc = ENFN->context_color_get(ENDT, context, &_cr, &_cg, &_cb, &_ca);
|
|
|
|
_cm = ENFN->context_multiplier_get(ENDT, context, &_cmr, &_cmg, &_cmb, &_cma);
|
2016-10-13 01:42:38 -07:00
|
|
|
RD(level, " context clip: [%d] %d,%d %dx%d ; color: [%d] {%d,%d,%d,%d} ; mult: [%d] {%d,%d,%d,%d}\n",
|
|
|
|
_cu, _cx, _cy, _cw, _ch, _cc, _cr, _cg, _cb, _ca, _cm, _cmr, _cmg, _cmb, _cma);
|
2015-09-03 00:36:32 -07:00
|
|
|
}
|
2015-01-26 00:35:42 -08:00
|
|
|
#endif
|
2013-04-26 04:05:46 -07:00
|
|
|
|
2009-11-09 07:18:37 -08:00
|
|
|
if (mapped)
|
|
|
|
{
|
2015-02-02 22:38:50 -08:00
|
|
|
if (_evas_render_object_is_mask(obj))
|
2014-11-12 17:47:29 -08:00
|
|
|
{
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, " is mask: redraw:%d sfc:%p\n", obj->mask->redraw, obj->mask->surface);
|
2015-02-02 22:38:50 -08:00
|
|
|
if (!use_mapped_ctx || (surface != obj->mask->surface))
|
|
|
|
{
|
2015-09-01 04:47:40 -07:00
|
|
|
RD(level, " not rendering mask surface\n");
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, "}\n");
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_object", eo_obj, 0.0, NULL);
|
2015-02-02 22:38:50 -08:00
|
|
|
return clean_them;
|
|
|
|
}
|
|
|
|
// else don't return: draw mask in its surface
|
2014-11-12 17:47:29 -08:00
|
|
|
}
|
|
|
|
else if (proxy_src_clip)
|
2009-11-15 05:46:20 -08:00
|
|
|
{
|
2015-10-06 01:36:29 -07:00
|
|
|
if (!evas->is_frozen) /* same as "if (proxy_render_data)" */
|
2013-04-25 22:45:41 -07:00
|
|
|
{
|
2015-10-06 01:36:29 -07:00
|
|
|
if ((!evas_object_is_visible(eo_obj, obj)) || (obj->clip.clipees)
|
|
|
|
|| (obj->cur->have_clipees) || (obj->no_render))
|
|
|
|
{
|
|
|
|
IFRD(obj->no_render, level, " no_render\n");
|
|
|
|
IFRD(obj->clip.clipees || obj->cur->have_clipees, level, " has clippees\n");
|
|
|
|
IFRD(!evas_object_is_visible(eo_obj, obj), level, " not visible\n");
|
|
|
|
RD(level, "}\n");
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_object", eo_obj, 0.0, NULL);
|
2015-10-06 01:36:29 -07:00
|
|
|
return clean_them;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* can not trust cache.clip - evas is frozen */
|
2015-11-01 19:23:00 -08:00
|
|
|
if (!obj->cur->visible || obj->clip.clipees || (obj->no_render && !proxy_render_data) ||
|
2015-10-06 01:36:29 -07:00
|
|
|
(!obj->cur->color.a && (obj->cur->render_op == EVAS_RENDER_BLEND)))
|
|
|
|
{
|
|
|
|
IFRD(obj->no_render, level, " proxy_src_clip + no_render\n");
|
|
|
|
IFRD(obj->clip.clipees || obj->cur->have_clipees, level, " proxy_src_clip + has clippees\n");
|
|
|
|
IFRD(!obj->cur->visible, level, " proxy_src_clip + not visible\n");
|
|
|
|
IFRD(!obj->cur->color.a && (obj->cur->render_op == EVAS_RENDER_BLEND), level, " proxy_src_clip + 0 alpha\n");
|
|
|
|
RD(level, "}\n");
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_object", eo_obj, 0.0, NULL);
|
2015-10-06 01:36:29 -07:00
|
|
|
return clean_them;
|
|
|
|
}
|
2016-07-04 00:06:04 -07:00
|
|
|
else if (proxy_render_data && (surface != obj->proxy->surface) &&
|
|
|
|
obj->proxy->src_invisible)
|
|
|
|
{
|
|
|
|
RD(level, " src_invisible + not proxy surface (recursive proxies)\n");
|
|
|
|
RD(level, "}\n");
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_object", eo_obj, 0.0, NULL);
|
2016-07-04 00:06:04 -07:00
|
|
|
return clean_them;
|
|
|
|
}
|
2013-04-25 22:45:41 -07:00
|
|
|
}
|
2013-04-26 04:05:46 -07:00
|
|
|
}
|
2015-05-12 01:37:01 -07:00
|
|
|
else if (!evas_object_is_proxy_visible(eo_obj, obj) ||
|
2013-07-28 04:24:46 -07:00
|
|
|
(obj->clip.clipees) || (obj->cur->have_clipees))
|
2015-05-12 01:37:01 -07:00
|
|
|
{
|
2015-09-01 04:47:40 -07:00
|
|
|
IFRD(!evas_object_is_proxy_visible(eo_obj, obj), level, " proxy not visible\n");
|
|
|
|
IFRD(obj->clip.clipees || obj->cur->have_clipees, level, " has clippees\n");
|
2015-05-12 01:37:01 -07:00
|
|
|
RD(level, "}\n");
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_object", eo_obj, 0.0, NULL);
|
2015-05-12 01:37:01 -07:00
|
|
|
return clean_them;
|
|
|
|
}
|
2015-06-16 03:20:57 -07:00
|
|
|
else if (obj->no_render && (!use_mapped_ctx || (surface != obj->proxy->surface)))
|
2015-05-12 01:37:01 -07:00
|
|
|
{
|
2015-09-01 04:47:40 -07:00
|
|
|
RD(level, " no_render\n");
|
|
|
|
RD(level, "}\n");
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_object", eo_obj, 0.0, NULL);
|
2015-05-12 01:37:01 -07:00
|
|
|
return clean_them;
|
2009-11-15 05:46:20 -08:00
|
|
|
}
|
2009-11-09 07:18:37 -08:00
|
|
|
}
|
2013-04-26 04:05:46 -07:00
|
|
|
else if (!(((evas_object_is_active(eo_obj, obj) && (!obj->clip.clipees) &&
|
|
|
|
(_evas_render_can_render(eo_obj, obj))))
|
|
|
|
))
|
2009-11-15 05:46:20 -08:00
|
|
|
{
|
2015-09-01 04:47:40 -07:00
|
|
|
IFRD(!evas_object_is_active(eo_obj, obj), level, " not active\n");
|
|
|
|
IFRD(!_evas_render_can_render(eo_obj, obj), level, " can't render\n");
|
|
|
|
IFRD(obj->clip.clipees, level, " has clippees\n");
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, "}\n");
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_object", eo_obj, 0.0, NULL);
|
2010-05-05 04:36:21 -07:00
|
|
|
return clean_them;
|
2009-11-15 05:46:20 -08:00
|
|
|
}
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2009-11-23 02:07:07 -08:00
|
|
|
// set render_pre - for child objs that may not have gotten it.
|
2013-09-02 20:39:49 -07:00
|
|
|
obj->pre_render_done = EINA_TRUE;
|
2016-01-06 04:52:46 -08:00
|
|
|
RD(level, " hasmap: %s [can_map: %d] cur.map:%p cur.usemap:%d\n",
|
|
|
|
_evas_render_has_map(obj) ? "yes" : "no",
|
2012-10-08 18:58:41 -07:00
|
|
|
obj->func->can_map ? obj->func->can_map(eo_obj): -1,
|
2015-01-26 00:35:42 -08:00
|
|
|
obj->map->cur.map, obj->map->cur.usemap);
|
2016-01-06 04:52:46 -08:00
|
|
|
if (_evas_render_has_map(obj) && !_evas_render_can_map(obj))
|
2009-10-30 03:11:15 -07:00
|
|
|
{
|
2009-10-31 02:08:01 -07:00
|
|
|
int sw, sh;
|
2012-05-16 06:21:37 -07:00
|
|
|
Eina_Bool changed = EINA_FALSE, rendered = EINA_FALSE;
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2011-05-20 23:23:33 -07:00
|
|
|
clean_them = EINA_TRUE;
|
2010-05-05 04:36:21 -07:00
|
|
|
|
2013-03-12 05:58:19 -07:00
|
|
|
sw = obj->cur->geometry.w;
|
|
|
|
sh = obj->cur->geometry.h;
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, " surf size: %ix%i\n", sw, sh);
|
2009-11-15 05:46:20 -08:00
|
|
|
if ((sw <= 0) || (sh <= 0))
|
|
|
|
{
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, "}\n");
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_object", eo_obj, 0.0, NULL);
|
2010-05-05 04:36:21 -07:00
|
|
|
return clean_them;
|
2009-11-15 05:46:20 -08:00
|
|
|
}
|
2014-01-05 20:54:58 -08:00
|
|
|
|
|
|
|
changed = evas_object_map_update(eo_obj, off_x, off_y, sw, sh, sw, sh);
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2013-01-21 19:56:00 -08:00
|
|
|
if (obj->map->surface)
|
2009-10-31 02:08:01 -07:00
|
|
|
{
|
2013-01-21 19:56:00 -08:00
|
|
|
if ((obj->map->surface_w != sw) ||
|
|
|
|
(obj->map->surface_h != sh))
|
2009-10-31 02:08:01 -07:00
|
|
|
{
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, " new surf: %ix%i\n", sw, sh);
|
2016-12-06 01:56:07 -08:00
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
|
|
|
|
{
|
|
|
|
ENFN->image_free(ENDT, map_write->surface);
|
|
|
|
map_write->surface = NULL;
|
|
|
|
}
|
|
|
|
EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
|
2009-10-31 02:08:01 -07:00
|
|
|
}
|
|
|
|
}
|
2013-01-21 19:56:00 -08:00
|
|
|
if (!obj->map->surface)
|
2009-10-31 02:08:01 -07:00
|
|
|
{
|
2013-01-21 19:56:00 -08:00
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
|
|
|
|
{
|
|
|
|
map_write->surface_w = sw;
|
|
|
|
map_write->surface_h = sh;
|
|
|
|
|
2015-09-02 20:11:52 -07:00
|
|
|
map_write->surface = ENFN->image_map_surface_new
|
|
|
|
(ENDT, map_write->surface_w,
|
|
|
|
map_write->surface_h,
|
|
|
|
map_write->cur.map->alpha);
|
2013-01-21 19:56:00 -08:00
|
|
|
}
|
|
|
|
EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
|
|
|
|
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, " first surf: %ix%i\n", sw, sh);
|
2012-05-16 06:21:37 -07:00
|
|
|
changed = EINA_TRUE;
|
2009-10-31 02:08:01 -07:00
|
|
|
}
|
2013-05-05 19:03:11 -07:00
|
|
|
|
2013-11-24 23:05:12 -08:00
|
|
|
if (!changed) changed = evas_object_smart_changed_get(eo_obj);
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2012-08-23 12:58:02 -07:00
|
|
|
/* mark the old map as invalid, so later we don't reuse it as a
|
|
|
|
* cache. */
|
2013-01-21 19:56:00 -08:00
|
|
|
if (changed && obj->map->prev.map)
|
|
|
|
{
|
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
|
|
|
|
map_write->prev.valid_map = EINA_FALSE;
|
|
|
|
EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
|
|
|
|
}
|
2012-08-23 12:58:02 -07:00
|
|
|
|
2009-10-31 02:08:01 -07:00
|
|
|
// clear surface before re-render
|
2013-01-21 19:56:00 -08:00
|
|
|
if ((changed) && (obj->map->surface))
|
2009-10-30 03:11:15 -07:00
|
|
|
{
|
2010-09-01 15:45:30 -07:00
|
|
|
int off_x2, off_y2;
|
2011-05-20 23:23:33 -07:00
|
|
|
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, " children redraw\n");
|
2009-11-09 07:18:37 -08:00
|
|
|
// FIXME: calculate "changes" within map surface and only clear
|
|
|
|
// and re-render those
|
2013-01-21 19:56:00 -08:00
|
|
|
if (obj->map->cur.map->alpha)
|
2009-10-31 18:32:23 -07:00
|
|
|
{
|
2015-09-02 20:11:52 -07:00
|
|
|
ctx = ENFN->context_new(ENDT);
|
|
|
|
ENFN->context_color_set(ENDT, ctx, 0, 0, 0, 0);
|
|
|
|
ENFN->context_render_op_set(ENDT, ctx, EVAS_RENDER_COPY);
|
|
|
|
ENFN->rectangle_draw(ENDT, ctx, obj->map->surface,
|
|
|
|
0, 0, obj->map->surface_w, obj->map->surface_h,
|
|
|
|
EINA_FALSE);
|
|
|
|
ENFN->context_free(ENDT, ctx);
|
2009-10-31 18:32:23 -07:00
|
|
|
}
|
2015-09-02 20:11:52 -07:00
|
|
|
ctx = ENFN->context_new(ENDT);
|
2013-03-12 05:58:19 -07:00
|
|
|
off_x2 = -obj->cur->geometry.x;
|
|
|
|
off_y2 = -obj->cur->geometry.y;
|
2012-10-08 18:58:41 -07:00
|
|
|
if (obj->is_smart)
|
2009-10-31 02:08:01 -07:00
|
|
|
{
|
|
|
|
EINA_INLIST_FOREACH
|
2012-10-08 18:58:41 -07:00
|
|
|
(evas_object_smart_members_get_direct(eo_obj), obj2)
|
2011-05-20 23:23:33 -07:00
|
|
|
{
|
2015-09-02 20:11:52 -07:00
|
|
|
clean_them |= evas_render_mapped(evas, obj2->object,
|
2012-10-18 04:30:04 -07:00
|
|
|
obj2, ctx,
|
2013-01-21 19:56:00 -08:00
|
|
|
obj->map->surface,
|
2011-05-20 23:23:33 -07:00
|
|
|
off_x2, off_y2, 1,
|
2012-10-18 04:30:04 -07:00
|
|
|
ecx, ecy, ecw, ech,
|
2014-11-04 21:54:35 -08:00
|
|
|
proxy_render_data,
|
|
|
|
level + 1,
|
2014-11-12 02:18:09 -08:00
|
|
|
EINA_FALSE,
|
2014-11-04 21:54:35 -08:00
|
|
|
do_async);
|
2014-03-31 22:08:14 -07:00
|
|
|
/* We aren't sure this object will be rendered by
|
|
|
|
normal(not proxy) drawing after, we reset this
|
|
|
|
only in case of normal drawing. For optmizing,
|
2016-11-21 21:33:48 -08:00
|
|
|
push this object in an array then reset them
|
2014-03-31 22:08:14 -07:00
|
|
|
in the end of the rendering.*/
|
|
|
|
if (!proxy_render_data)
|
|
|
|
evas_object_change_reset(obj2->object);
|
2011-05-20 23:23:33 -07:00
|
|
|
}
|
2009-10-31 02:08:01 -07:00
|
|
|
}
|
|
|
|
else
|
2010-04-28 07:38:46 -07:00
|
|
|
{
|
|
|
|
int x = 0, y = 0, w = 0, h = 0;
|
2010-05-01 06:27:05 -07:00
|
|
|
|
2013-01-21 19:56:00 -08:00
|
|
|
w = obj->map->surface_w;
|
|
|
|
h = obj->map->surface_h;
|
2010-04-28 07:38:46 -07:00
|
|
|
RECTS_CLIP_TO_RECT(x, y, w, h,
|
2013-03-12 05:58:19 -07:00
|
|
|
obj->cur->geometry.x + off_x2,
|
|
|
|
obj->cur->geometry.y + off_y2,
|
|
|
|
obj->cur->geometry.w,
|
|
|
|
obj->cur->geometry.h);
|
2011-03-15 09:20:57 -07:00
|
|
|
|
2015-09-02 20:11:52 -07:00
|
|
|
ENFN->context_clip_set(ENDT, ctx, x, y, w, h);
|
2015-09-03 00:36:32 -07:00
|
|
|
#ifdef REND_DBG
|
|
|
|
int _c, _cx, _cy, _cw, _ch;
|
|
|
|
_c = ENFN->context_clip_get(ENDT, ctx, &_cx, &_cy, &_cw, &_ch);
|
|
|
|
RD(level, " draw mapped obj: render(clip: [%d] %d,%d %dx%d)\n", _c, _cx, _cy, _cw, _ch);
|
|
|
|
#endif
|
2016-01-06 04:52:46 -08:00
|
|
|
// FIXME: Should this really be sync render?
|
2013-07-08 17:46:15 -07:00
|
|
|
obj->func->render(eo_obj, obj, obj->private_data,
|
2015-09-02 20:11:52 -07:00
|
|
|
ENDT, ctx,
|
2013-01-21 19:56:00 -08:00
|
|
|
obj->map->surface, off_x2, off_y2,
|
2012-12-18 08:28:55 -08:00
|
|
|
EINA_FALSE);
|
2010-04-28 07:38:46 -07:00
|
|
|
}
|
2015-09-02 20:11:52 -07:00
|
|
|
ENFN->context_free(ENDT, ctx);
|
2012-05-16 06:21:37 -07:00
|
|
|
rendered = EINA_TRUE;
|
2009-10-31 02:08:01 -07:00
|
|
|
}
|
|
|
|
|
2010-04-30 01:24:55 -07:00
|
|
|
if (rendered)
|
|
|
|
{
|
2013-01-21 19:56:00 -08:00
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
|
|
|
|
{
|
2015-09-02 20:11:52 -07:00
|
|
|
map_write->surface = ENFN->image_dirty_region
|
|
|
|
(ENDT, map_write->surface,
|
2013-01-21 19:56:00 -08:00
|
|
|
0, 0, map_write->surface_w, map_write->surface_h);
|
|
|
|
|
|
|
|
map_write->cur.valid_map = EINA_TRUE;
|
|
|
|
}
|
|
|
|
EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
|
2010-04-30 01:24:55 -07:00
|
|
|
}
|
2015-09-02 22:06:36 -07:00
|
|
|
|
|
|
|
/* duplicate context and reset clip */
|
|
|
|
ctx = ENFN->context_dup(ENDT, context);
|
|
|
|
ENFN->context_clip_unset(ENDT, ctx);
|
2015-09-03 01:38:48 -07:00
|
|
|
//ENFN->context_multiplier_unset(ENDT, ctx); // this probably should be here, too
|
2015-09-02 22:06:36 -07:00
|
|
|
|
2013-01-21 19:56:00 -08:00
|
|
|
if (obj->map->surface)
|
2010-09-01 15:45:30 -07:00
|
|
|
{
|
2016-11-07 23:22:22 -08:00
|
|
|
Evas_Object_Protected_Data *mask = obj->clip.mask;
|
|
|
|
|
2013-03-12 05:58:19 -07:00
|
|
|
if (obj->cur->clipper)
|
2010-09-01 15:45:30 -07:00
|
|
|
{
|
2016-11-30 00:36:42 -08:00
|
|
|
evas_object_clip_recalc(obj);
|
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
if (obj->is_smart)
|
2010-10-11 02:53:52 -07:00
|
|
|
{
|
2013-07-04 19:14:47 -07:00
|
|
|
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
|
|
|
|
{
|
|
|
|
state_write->cache.clip.dirty = EINA_TRUE;
|
|
|
|
}
|
|
|
|
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
|
2010-10-11 02:53:52 -07:00
|
|
|
}
|
2015-09-02 22:06:36 -07:00
|
|
|
_evas_render_mapped_context_clip_set(evas, eo_obj, obj, ctx,
|
2013-07-04 19:14:47 -07:00
|
|
|
proxy_render_data, off_x,
|
|
|
|
off_y);
|
2015-02-04 23:11:45 -08:00
|
|
|
|
|
|
|
/* Clipper masks */
|
2016-11-07 23:22:22 -08:00
|
|
|
if (mask)
|
2015-02-04 23:11:45 -08:00
|
|
|
{
|
|
|
|
// This path can be hit when we're multiplying masks on top of each other...
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, " has mask: [%p%s%s] redraw:%d sfc:%p\n",
|
|
|
|
mask, mask->name?":":"", mask->name?mask->name:"",
|
|
|
|
mask->mask->redraw, mask->mask->surface);
|
2015-02-04 23:11:45 -08:00
|
|
|
if (mask->mask->redraw || !mask->mask->surface)
|
2015-09-02 20:11:52 -07:00
|
|
|
evas_render_mask_subrender(evas, mask, obj->clip.prev_mask, level + 1);
|
2015-02-04 23:11:45 -08:00
|
|
|
|
|
|
|
if (mask->mask->surface)
|
|
|
|
{
|
2015-09-02 22:06:36 -07:00
|
|
|
ENFN->context_clip_image_set(ENDT, ctx, mask->mask->surface,
|
|
|
|
mask->cur->geometry.x + off_x,
|
|
|
|
mask->cur->geometry.y + off_y,
|
|
|
|
evas, do_async);
|
2015-02-04 23:11:45 -08:00
|
|
|
}
|
|
|
|
}
|
2010-09-01 15:45:30 -07:00
|
|
|
}
|
2016-09-07 18:26:30 -07:00
|
|
|
|
2016-12-06 01:56:07 -08:00
|
|
|
if (obj->cur->cache.clip.visible || !proxy_src_clip)
|
|
|
|
{
|
|
|
|
ENFN->context_clip_clip(ENDT, ctx, ecx, ecy, ecw, ech);
|
|
|
|
ENFN->context_multiplier_unset(ENDT, ctx);
|
|
|
|
ENFN->context_render_op_set(ENDT, ctx, obj->cur->render_op);
|
2015-09-03 00:36:32 -07:00
|
|
|
#ifdef REND_DBG
|
2016-12-06 01:56:07 -08:00
|
|
|
int _c, _cx, _cy, _cw, _ch;
|
|
|
|
_c = ENFN->context_clip_get(ENDT, ctx, &_cx, &_cy, &_cw, &_ch);
|
|
|
|
RD(level, " draw image map(clip: [%d] %d,%d %dx%d)\n", _c, _cx, _cy, _cw, _ch);
|
2015-09-03 00:36:32 -07:00
|
|
|
#endif
|
2016-12-06 01:56:07 -08:00
|
|
|
evas_draw_image_map_async_check
|
|
|
|
(obj, ENDT, ctx, surface,
|
|
|
|
obj->map->surface, obj->map->spans,
|
|
|
|
obj->map->cur.map->smooth, 0, do_async);
|
|
|
|
}
|
2012-03-20 21:04:03 -07:00
|
|
|
}
|
2015-02-04 23:11:45 -08:00
|
|
|
|
2015-09-02 22:06:36 -07:00
|
|
|
ENFN->context_free(ENDT, ctx);
|
2015-02-04 23:11:45 -08:00
|
|
|
|
2009-10-30 03:11:15 -07:00
|
|
|
// FIXME: needs to cache these maps and
|
|
|
|
// keep them only rendering updates
|
2015-09-02 20:11:52 -07:00
|
|
|
// ENFN->image_free
|
|
|
|
// (ENDT, obj->map->surface);
|
2013-01-21 19:56:00 -08:00
|
|
|
// obj->map->surface = NULL;
|
2009-10-30 03:11:15 -07:00
|
|
|
}
|
2015-01-26 00:35:42 -08:00
|
|
|
else // not "has map"
|
2009-11-06 21:01:43 -08:00
|
|
|
{
|
|
|
|
if (mapped)
|
|
|
|
{
|
2015-09-03 00:36:32 -07:00
|
|
|
RD(level, " child of mapped obj\n");
|
2015-01-26 00:35:42 -08:00
|
|
|
|
2014-11-12 02:18:09 -08:00
|
|
|
if (use_mapped_ctx)
|
2015-09-02 22:06:36 -07:00
|
|
|
ctx = ENFN->context_dup(ENDT, context);
|
2014-11-12 02:18:09 -08:00
|
|
|
else
|
2015-09-02 20:11:52 -07:00
|
|
|
ctx = ENFN->context_new(ENDT);
|
2015-01-26 00:35:42 -08:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
if (obj->is_smart)
|
2009-11-06 21:01:43 -08:00
|
|
|
{
|
2015-01-26 00:52:38 -08:00
|
|
|
/* Clipper masks */
|
2015-04-14 00:20:00 -07:00
|
|
|
if (obj->cur->clipper && (mapped > 1) &&
|
2015-01-26 00:52:38 -08:00
|
|
|
_evas_render_object_is_mask(obj->cur->clipper))
|
|
|
|
{
|
|
|
|
// This path can be hit when we're multiplying masks on top of each other...
|
|
|
|
Evas_Object_Protected_Data *mask = obj->cur->clipper;
|
|
|
|
|
2016-11-30 00:36:42 -08:00
|
|
|
evas_object_clip_recalc(obj);
|
|
|
|
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, " has mask: [%p%s%s] redraw:%d sfc:%p\n",
|
|
|
|
mask, mask->name?":":"", mask->name?mask->name:"",
|
|
|
|
mask->mask->redraw, mask->mask->surface);
|
2015-01-26 00:52:38 -08:00
|
|
|
if (mask->mask->redraw || !mask->mask->surface)
|
2015-09-02 20:11:52 -07:00
|
|
|
evas_render_mask_subrender(evas, mask, obj->clip.prev_mask, level + 1);
|
2015-01-26 00:52:38 -08:00
|
|
|
|
|
|
|
if (mask->mask->surface)
|
|
|
|
{
|
2015-09-02 22:06:36 -07:00
|
|
|
use_mapped_ctx = EINA_TRUE;
|
|
|
|
ENFN->context_clip_image_set(ENDT, ctx,
|
|
|
|
mask->mask->surface,
|
|
|
|
mask->cur->geometry.x + off_x,
|
|
|
|
mask->cur->geometry.y + off_y,
|
|
|
|
evas, do_async);
|
2015-01-26 00:52:38 -08:00
|
|
|
}
|
|
|
|
}
|
2015-09-03 01:38:48 -07:00
|
|
|
else if (!proxy_src_clip)
|
|
|
|
{
|
|
|
|
if (!_proxy_context_clip(evas, ctx, proxy_render_data, obj, off_x, off_y))
|
2016-11-06 18:26:22 -08:00
|
|
|
{
|
|
|
|
eina_evlog("-render_object", eo_obj, 0.0, NULL);
|
|
|
|
return clean_them;
|
|
|
|
}
|
2015-09-03 01:38:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef REND_DBG
|
|
|
|
int _c, _cx, _cy, _cw, _ch;
|
|
|
|
_c = ENFN->context_clip_get(ENDT, ctx, &_cx, &_cy, &_cw, &_ch);
|
|
|
|
RD(level, " draw smart children(clip: [%d] %d,%d %dx%d)\n",
|
|
|
|
_c, _cx, _cy, _cw, _ch);
|
|
|
|
#endif
|
2015-01-26 00:52:38 -08:00
|
|
|
|
2009-11-06 21:01:43 -08:00
|
|
|
EINA_INLIST_FOREACH
|
2012-10-08 18:58:41 -07:00
|
|
|
(evas_object_smart_members_get_direct(eo_obj), obj2)
|
2011-05-20 23:23:33 -07:00
|
|
|
{
|
2015-09-02 20:11:52 -07:00
|
|
|
clean_them |= evas_render_mapped(evas, obj2->object,
|
2012-10-18 04:30:04 -07:00
|
|
|
obj2, ctx, surface,
|
2015-04-14 00:20:00 -07:00
|
|
|
off_x, off_y, mapped + 1,
|
2012-10-18 04:30:04 -07:00
|
|
|
ecx, ecy, ecw, ech,
|
2014-11-04 21:54:35 -08:00
|
|
|
proxy_render_data,
|
|
|
|
level + 1,
|
2015-09-02 22:06:36 -07:00
|
|
|
use_mapped_ctx,
|
2014-11-04 21:54:35 -08:00
|
|
|
do_async);
|
2014-03-31 22:08:14 -07:00
|
|
|
/* We aren't sure this object will be rendered by
|
|
|
|
normal(not proxy) drawing after, we reset this
|
|
|
|
only in case of normal drawing. For optmizing,
|
2015-01-26 00:35:42 -08:00
|
|
|
push this object in an array then reset them
|
2014-03-31 22:08:14 -07:00
|
|
|
in the end of the rendering.*/
|
|
|
|
if (!proxy_render_data)
|
|
|
|
evas_object_change_reset(obj2->object);
|
2011-05-20 23:23:33 -07:00
|
|
|
}
|
2009-11-06 21:01:43 -08:00
|
|
|
}
|
|
|
|
else
|
2010-08-24 01:14:46 -07:00
|
|
|
{
|
2015-09-03 01:38:48 -07:00
|
|
|
const Evas_Coord_Rectangle *clip = &obj->cur->geometry;
|
|
|
|
ENFN->context_clip_clip(ENDT, ctx, clip->x + off_x, clip->y + off_y, clip->w, clip->h);
|
|
|
|
|
2015-04-14 00:20:00 -07:00
|
|
|
if (obj->cur->clipper && (mapped > 1))
|
2012-08-16 23:02:49 -07:00
|
|
|
{
|
2016-11-07 23:22:22 -08:00
|
|
|
Evas_Object_Protected_Data *mask = obj->clip.mask;
|
|
|
|
|
|
|
|
if (obj->mask->surface != surface)
|
2015-09-03 01:38:48 -07:00
|
|
|
{
|
2016-11-07 23:22:22 -08:00
|
|
|
if (proxy_src_clip)
|
|
|
|
{
|
2016-11-30 00:36:42 -08:00
|
|
|
if ((_evas_render_has_map(obj) && !_evas_render_can_map(obj)) ||
|
|
|
|
_evas_render_object_is_mask(obj->cur->clipper))
|
|
|
|
evas_object_clip_recalc(obj);
|
2016-11-07 23:22:22 -08:00
|
|
|
_evas_render_mapped_context_clip_set(evas, eo_obj, obj, ctx,
|
|
|
|
proxy_render_data,
|
|
|
|
off_x, off_y);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!_proxy_context_clip(evas, ctx, proxy_render_data, obj, off_x, off_y))
|
|
|
|
{
|
|
|
|
eina_evlog("-render_object", eo_obj, 0.0, NULL);
|
|
|
|
return clean_them;
|
|
|
|
}
|
|
|
|
}
|
2015-09-03 01:38:48 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-11-07 23:22:22 -08:00
|
|
|
// rendering a mask in its own surface:
|
|
|
|
// we want to render it fully and clip only at
|
|
|
|
// clippee (maskee) render time
|
|
|
|
RD(level, " draw mask\n");
|
2015-09-03 01:38:48 -07:00
|
|
|
}
|
2014-11-12 17:47:29 -08:00
|
|
|
|
|
|
|
/* Clipper masks */
|
2016-11-07 23:22:22 -08:00
|
|
|
if (mask)
|
2014-11-12 17:47:29 -08:00
|
|
|
{
|
|
|
|
// This path can be hit when we're multiplying masks on top of each other...
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, " has mask: [%p%s%s] redraw:%d sfc:%p\n",
|
|
|
|
mask, mask->name?":":"", mask->name?mask->name:"",
|
|
|
|
mask->mask->redraw, mask->mask->surface);
|
2014-11-12 17:47:29 -08:00
|
|
|
if (mask->mask->redraw || !mask->mask->surface)
|
2015-09-02 20:11:52 -07:00
|
|
|
evas_render_mask_subrender(evas, mask, obj->clip.prev_mask, level + 1);
|
2014-11-12 17:47:29 -08:00
|
|
|
|
|
|
|
if (mask->mask->surface)
|
|
|
|
{
|
2015-09-02 22:06:36 -07:00
|
|
|
ENFN->context_clip_image_set(ENDT, ctx,
|
|
|
|
mask->mask->surface,
|
|
|
|
mask->cur->geometry.x + off_x,
|
|
|
|
mask->cur->geometry.y + off_y,
|
|
|
|
evas, do_async);
|
2014-11-12 17:47:29 -08:00
|
|
|
}
|
|
|
|
}
|
2010-09-25 07:30:02 -07:00
|
|
|
}
|
2015-09-03 01:38:48 -07:00
|
|
|
|
2015-09-03 00:36:32 -07:00
|
|
|
#ifdef REND_DBG
|
|
|
|
int _c, _cx, _cy, _cw, _ch;
|
|
|
|
_c = ENFN->context_clip_get(ENDT, ctx, &_cx, &_cy, &_cw, &_ch);
|
|
|
|
RD(level, " render(clip: [%d] %d,%d %dx%d)\n", _c, _cx, _cy, _cw, _ch);
|
|
|
|
#endif
|
2015-09-03 01:38:48 -07:00
|
|
|
|
2013-07-08 17:46:15 -07:00
|
|
|
obj->func->render(eo_obj, obj, obj->private_data,
|
2015-09-02 20:11:52 -07:00
|
|
|
ENDT, ctx, surface, off_x, off_y, EINA_FALSE);
|
2015-02-03 00:32:59 -08:00
|
|
|
}
|
2015-09-02 22:06:36 -07:00
|
|
|
|
|
|
|
ENFN->context_free(ENDT, ctx);
|
2009-11-06 21:01:43 -08:00
|
|
|
}
|
2016-10-31 20:06:22 -07:00
|
|
|
else if (!obj->is_smart)
|
2009-11-09 07:18:37 -08:00
|
|
|
{
|
2015-09-03 01:38:48 -07:00
|
|
|
ctx = ENFN->context_dup(ENDT, context);
|
2013-05-07 09:16:49 -07:00
|
|
|
if (obj->cur->clipper)
|
2011-03-15 09:20:57 -07:00
|
|
|
{
|
2014-11-12 17:47:29 -08:00
|
|
|
Evas_Object_Protected_Data *clipper = obj->cur->clipper;
|
2011-03-15 09:20:57 -07:00
|
|
|
int x, y, w, h;
|
|
|
|
|
2015-09-03 01:38:48 -07:00
|
|
|
if (proxy_src_clip)
|
|
|
|
{
|
2016-11-30 00:36:42 -08:00
|
|
|
if ((_evas_render_has_map(obj) && !_evas_render_can_map(obj)) ||
|
|
|
|
_evas_render_object_is_mask(obj->cur->clipper))
|
|
|
|
evas_object_clip_recalc(obj);
|
2015-09-03 01:38:48 -07:00
|
|
|
x = obj->cur->cache.clip.x;
|
|
|
|
y = obj->cur->cache.clip.y;
|
|
|
|
w = obj->cur->cache.clip.w;
|
|
|
|
h = obj->cur->cache.clip.h;
|
|
|
|
RECTS_CLIP_TO_RECT(x, y, w, h,
|
|
|
|
clipper->cur->cache.clip.x,
|
|
|
|
clipper->cur->cache.clip.y,
|
|
|
|
clipper->cur->cache.clip.w,
|
|
|
|
clipper->cur->cache.clip.h);
|
|
|
|
ENFN->context_clip_set(ENDT, ctx, x + off_x, y + off_y, w, h);
|
2016-10-21 12:17:43 -07:00
|
|
|
if (!_is_obj_in_framespace(obj, evas))
|
2016-11-07 03:36:59 -08:00
|
|
|
{
|
|
|
|
_evas_render_framespace_context_clip_clip
|
|
|
|
(evas, ctx, off_x - evas->framespace.x, off_y - evas->framespace.y);
|
|
|
|
}
|
2016-09-07 18:26:30 -07:00
|
|
|
|
2016-11-16 01:09:37 -08:00
|
|
|
ENFN->context_clip_clip(ENDT, ctx, ecx, ecy, ecw, ech);
|
2015-09-03 01:38:48 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!_proxy_context_clip(evas, ctx, proxy_render_data, obj, off_x, off_y))
|
2016-11-06 18:26:22 -08:00
|
|
|
{
|
|
|
|
eina_evlog("-render_object", eo_obj, 0.0, NULL);
|
|
|
|
return clean_them;
|
|
|
|
}
|
2015-09-03 01:38:48 -07:00
|
|
|
}
|
2011-03-15 09:20:57 -07:00
|
|
|
}
|
2016-11-07 03:36:59 -08:00
|
|
|
else if (!_is_obj_in_framespace(obj, evas))
|
|
|
|
{
|
|
|
|
_evas_render_framespace_context_clip_clip
|
|
|
|
(evas, ctx, off_x - evas->framespace.x, off_y - evas->framespace.y);
|
|
|
|
}
|
2011-03-15 09:20:57 -07:00
|
|
|
|
2015-09-03 00:36:32 -07:00
|
|
|
#ifdef REND_DBG
|
|
|
|
int _c, _cx, _cy, _cw, _ch;
|
|
|
|
_c = ENFN->context_clip_get(ENDT, context, &_cx, &_cy, &_cw, &_ch);
|
|
|
|
RD(level, " draw normal obj: render(clip: [%d] %d,%d %dx%d)\n", _c, _cx, _cy, _cw, _ch);
|
|
|
|
#endif
|
2015-09-03 01:38:48 -07:00
|
|
|
|
2013-07-08 17:46:15 -07:00
|
|
|
obj->func->render(eo_obj, obj, obj->private_data,
|
2015-09-03 01:38:48 -07:00
|
|
|
ENDT, ctx, surface,
|
2012-12-18 08:28:55 -08:00
|
|
|
off_x, off_y, do_async);
|
2015-09-03 01:38:48 -07:00
|
|
|
ENFN->context_free(ENDT, ctx);
|
2009-11-09 07:18:37 -08:00
|
|
|
}
|
2012-05-28 22:13:03 -07:00
|
|
|
if (obj->changed_map) clean_them = EINA_TRUE;
|
2009-11-06 21:01:43 -08:00
|
|
|
}
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, "}\n");
|
2010-05-05 04:36:21 -07:00
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_object", eo_obj, 0.0, NULL);
|
2010-05-05 04:36:21 -07:00
|
|
|
return clean_them;
|
2009-10-30 03:11:15 -07:00
|
|
|
}
|
|
|
|
|
2014-10-22 23:27:40 -07:00
|
|
|
/*
|
|
|
|
* Render the source object when a proxy is set.
|
|
|
|
* Used to force a draw if necessary, else just makes sure it's available.
|
|
|
|
* Called from: image objects and text with filters.
|
|
|
|
* TODO: 3d objects subrender should probably be merged here as well.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
evas_render_proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Evas_Object *eo_proxy,
|
2016-12-13 00:41:49 -08:00
|
|
|
Evas_Object_Protected_Data *proxy_obj, Eina_Rectangle region,
|
|
|
|
Eina_Bool do_async)
|
2014-10-22 23:27:40 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *evas = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2014-10-22 23:27:40 -07:00
|
|
|
Evas_Object_Protected_Data *source;
|
|
|
|
Eina_Bool source_clip = EINA_FALSE;
|
2015-09-01 04:47:40 -07:00
|
|
|
int level = 1;
|
2014-10-22 23:27:40 -07:00
|
|
|
void *ctx;
|
2016-12-13 00:41:49 -08:00
|
|
|
int x, y, w, h, W, H;
|
2014-10-22 23:27:40 -07:00
|
|
|
|
2015-09-01 04:47:40 -07:00
|
|
|
#ifdef REND_DBG
|
|
|
|
level = __RD_level;
|
|
|
|
#endif
|
|
|
|
|
2014-10-22 23:27:40 -07:00
|
|
|
if (!eo_source) return;
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+proxy_subrender", eo_proxy, 0.0, NULL);
|
2016-08-15 06:44:41 -07:00
|
|
|
source = efl_data_scope_get(eo_source, EFL_CANVAS_OBJECT_CLASS);
|
2014-10-22 23:27:40 -07:00
|
|
|
|
2016-12-13 00:41:49 -08:00
|
|
|
W = source->cur->geometry.w;
|
|
|
|
H = source->cur->geometry.h;
|
|
|
|
x = region.x;
|
|
|
|
y = region.y;
|
|
|
|
if(x >= W) x = W - 1;
|
|
|
|
if(x >= H) x = H - 1;
|
|
|
|
if(x < 0) x = 0;
|
|
|
|
if(y < 0) y = 0;
|
|
|
|
w = (region.w > 0) ? region.w : W;
|
|
|
|
h = (region.h > 0) ? region.h : H;
|
|
|
|
if((x + w) > W) w = W - x;
|
|
|
|
if((y + h) > H) h = H - y;
|
|
|
|
if(w < 0) w = 0;
|
|
|
|
if(h < 0) h = 0;
|
|
|
|
|
|
|
|
RD(level, " proxy_subrender(source: %p, proxy: %p, region: %d,%d %dx%d)\n", eo_source, eo_proxy, x, y, w, h);
|
2015-09-01 04:47:40 -07:00
|
|
|
|
2014-10-22 23:27:40 -07:00
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy,
|
|
|
|
Evas_Object_Proxy_Data, proxy_write)
|
|
|
|
{
|
|
|
|
proxy_write->redraw = EINA_FALSE;
|
|
|
|
|
|
|
|
/* We need to redraw surface then */
|
|
|
|
if ((proxy_write->surface) &&
|
|
|
|
((proxy_write->w != w) || (proxy_write->h != h)))
|
|
|
|
{
|
2015-09-01 04:47:40 -07:00
|
|
|
RD(level, " free surface: %p\n", proxy_write->surface);
|
2015-07-01 20:04:02 -07:00
|
|
|
ENFN->image_free(ENDT, proxy_write->surface);
|
2014-10-22 23:27:40 -07:00
|
|
|
proxy_write->surface = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: Hardcoded alpha 'on' */
|
|
|
|
/* FIXME (cont): Should see if the object has alpha */
|
|
|
|
if (!proxy_write->surface)
|
|
|
|
{
|
2016-07-18 22:36:41 -07:00
|
|
|
if ((w < 1) || (h < 1)) goto end;
|
2014-11-12 02:25:21 -08:00
|
|
|
proxy_write->surface = ENFN->image_map_surface_new(ENDT, w, h, 1);
|
2015-09-01 04:47:40 -07:00
|
|
|
RD(level, " created surface: %p %dx%d\n", proxy_write->surface, w, h);
|
2014-10-22 23:27:40 -07:00
|
|
|
if (!proxy_write->surface) goto end;
|
|
|
|
proxy_write->w = w;
|
|
|
|
proxy_write->h = h;
|
|
|
|
}
|
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+proxy_fill", eo_proxy, 0.0, NULL);
|
2014-11-12 02:25:21 -08:00
|
|
|
ctx = ENFN->context_new(ENDT);
|
|
|
|
ENFN->context_color_set(ENDT, ctx, 0, 0,0, 0);
|
2015-09-01 04:47:40 -07:00
|
|
|
ENFN->context_render_op_set(ENDT, ctx, EVAS_RENDER_COPY);
|
2014-11-12 02:25:21 -08:00
|
|
|
ENFN->rectangle_draw(ENDT, ctx, proxy_write->surface, 0, 0, w, h, do_async);
|
|
|
|
ENFN->context_free(ENDT, ctx);
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-proxy_fill", eo_proxy, 0.0, NULL);
|
2014-10-22 23:27:40 -07:00
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
if (efl_isa(eo_proxy, EFL_CANVAS_IMAGE_INTERNAL_CLASS))
|
2016-03-09 22:13:20 -08:00
|
|
|
source_clip = _evas_image_proxy_source_clip_get(eo_proxy);
|
2014-10-22 23:27:40 -07:00
|
|
|
|
|
|
|
Evas_Proxy_Render_Data proxy_render_data = {
|
|
|
|
.eo_proxy = eo_proxy,
|
|
|
|
.proxy_obj = proxy_obj,
|
|
|
|
.eo_src = eo_source,
|
2015-09-03 01:38:48 -07:00
|
|
|
.src_obj = source,
|
2016-12-13 00:41:49 -08:00
|
|
|
.region = (Eina_Rectangle) { x, y, w, h },
|
2014-10-22 23:27:40 -07:00
|
|
|
.source_clip = source_clip
|
|
|
|
};
|
2015-09-03 00:36:32 -07:00
|
|
|
|
2015-09-03 01:38:48 -07:00
|
|
|
/* protect changes to the objects' cache.clip */
|
|
|
|
evas_event_freeze(evas->evas);
|
|
|
|
|
2015-09-03 00:36:32 -07:00
|
|
|
ctx = ENFN->context_new(ENDT);
|
2014-11-12 02:25:21 -08:00
|
|
|
evas_render_mapped(evas, eo_source, source, ctx, proxy_write->surface,
|
2016-12-13 00:41:49 -08:00
|
|
|
x - source->cur->geometry.x,
|
|
|
|
y - source->cur->geometry.y,
|
2015-09-01 04:47:40 -07:00
|
|
|
level + 1, 0, 0, evas->output.w, evas->output.h,
|
|
|
|
&proxy_render_data, level + 1, EINA_TRUE, do_async);
|
2014-11-12 02:25:21 -08:00
|
|
|
ENFN->context_free(ENDT, ctx);
|
2015-09-03 00:36:32 -07:00
|
|
|
|
2014-11-12 02:25:21 -08:00
|
|
|
proxy_write->surface = ENFN->image_dirty_region(ENDT, proxy_write->surface, 0, 0, w, h);
|
2015-09-03 01:38:48 -07:00
|
|
|
|
|
|
|
/* restore previous state */
|
|
|
|
evas_event_thaw(evas->evas);
|
2014-10-22 23:27:40 -07:00
|
|
|
}
|
|
|
|
end:
|
|
|
|
EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, proxy_write);
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-proxy_subrender", eo_proxy, 0.0, NULL);
|
2014-10-22 23:27:40 -07:00
|
|
|
}
|
|
|
|
|
2014-11-12 17:47:29 -08:00
|
|
|
/* @internal
|
|
|
|
* Synchronously render a mask image (or smart object) into a surface.
|
|
|
|
* In SW the target surface will be ALPHA only (GRY8), after conversion.
|
|
|
|
* In GL the target surface will be RGBA for now. TODO: Find out how to
|
|
|
|
* render GL to alpha, if that's possible.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
evas_render_mask_subrender(Evas_Public_Data *evas,
|
|
|
|
Evas_Object_Protected_Data *mask,
|
2015-01-26 00:35:42 -08:00
|
|
|
Evas_Object_Protected_Data *prev_mask,
|
|
|
|
int level)
|
2014-11-12 17:47:29 -08:00
|
|
|
{
|
|
|
|
int x, y, w, h, r, g, b, a;
|
2015-02-25 02:05:12 -08:00
|
|
|
Eina_Bool is_image, done = EINA_FALSE;
|
2014-11-12 17:47:29 -08:00
|
|
|
void *ctx;
|
|
|
|
|
|
|
|
if (!mask) return;
|
|
|
|
if (!mask->mask->redraw && mask->mask->surface)
|
|
|
|
{
|
|
|
|
DBG("Requested mask redraw but the redraw flag is off.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+mask_subrender", mask->object, 0.0, NULL);
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(level, "evas_render_mask_subrender(%p, prev: %p)\n", mask, prev_mask);
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
is_image = efl_isa(mask->object, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
|
2015-02-25 02:05:12 -08:00
|
|
|
|
2014-11-12 17:47:29 -08:00
|
|
|
x = mask->cur->geometry.x;
|
|
|
|
y = mask->cur->geometry.y;
|
|
|
|
w = mask->cur->geometry.w;
|
|
|
|
h = mask->cur->geometry.h;
|
|
|
|
|
|
|
|
r = mask->cur->color.r;
|
|
|
|
g = mask->cur->color.g;
|
|
|
|
b = mask->cur->color.b;
|
|
|
|
a = mask->cur->color.a;
|
|
|
|
if ((r != 255) || (g != 255) || (b != 255) || (a != 255))
|
|
|
|
{
|
|
|
|
EINA_COW_STATE_WRITE_BEGIN(mask, state_write, cur)
|
|
|
|
{
|
|
|
|
state_write->color.r = 255;
|
|
|
|
state_write->color.g = 255;
|
|
|
|
state_write->color.b = 255;
|
|
|
|
state_write->color.a = 255;
|
|
|
|
}
|
|
|
|
EINA_COW_STATE_WRITE_END(mask, state_write, cur);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prev_mask == mask)
|
|
|
|
prev_mask = NULL;
|
|
|
|
|
|
|
|
if (prev_mask)
|
|
|
|
{
|
|
|
|
if (!prev_mask->mask->is_mask)
|
|
|
|
{
|
|
|
|
ERR("Passed invalid mask that is not a mask");
|
|
|
|
prev_mask = NULL;
|
|
|
|
}
|
|
|
|
else if (!prev_mask->mask->surface)
|
|
|
|
{
|
2015-02-02 22:51:01 -08:00
|
|
|
// Note: This is preventive code. Never seen it happen.
|
2014-11-12 17:47:29 -08:00
|
|
|
WRN("Mask render order may be invalid");
|
2015-01-26 00:35:42 -08:00
|
|
|
evas_render_mask_subrender(evas, prev_mask, prev_mask->clip.prev_mask, level + 1);
|
2014-11-12 17:47:29 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_mask_cow, mask->mask, Evas_Object_Mask_Data, mdata)
|
|
|
|
mdata->redraw = EINA_FALSE;
|
|
|
|
|
2015-04-16 17:24:46 -07:00
|
|
|
if (is_image && ENFN->image_scaled_update)
|
2014-11-12 17:47:29 -08:00
|
|
|
{
|
2015-04-16 17:24:46 -07:00
|
|
|
Eina_Bool filled = EINA_FALSE, border = EINA_FALSE;
|
|
|
|
int bl = 0, br = 0, bt = 0, bb = 0;
|
2015-02-26 22:57:36 -08:00
|
|
|
|
|
|
|
if (evas_object_image_filled_get(mask->object))
|
|
|
|
filled = EINA_TRUE;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int fx, fy, fw, fh;
|
|
|
|
evas_object_image_fill_get(mask->object, &fx, &fy, &fw, &fh);
|
|
|
|
if ((fx == 0) && (fy == 0) && (fw == w) && (fh == h))
|
|
|
|
filled = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2015-04-16 17:24:46 -07:00
|
|
|
evas_object_image_border_get(mask->object, &bl, &br, &bt, &bb);
|
|
|
|
if (bl || br || bt || bb)
|
|
|
|
border = EINA_TRUE;
|
|
|
|
|
2016-01-12 18:10:25 -08:00
|
|
|
if (!border && filled && !prev_mask && mask->func->engine_data_get)
|
2015-02-25 02:05:12 -08:00
|
|
|
{
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+mask_scaled_update", mask->object, 0.0, NULL);
|
2015-02-26 22:57:36 -08:00
|
|
|
/* Fast path (for GL) that avoids creating a map surface, render the
|
|
|
|
* scaled image in it, when the shaders can just scale on the fly. */
|
|
|
|
Eina_Bool smooth = evas_object_image_smooth_scale_get(mask->object);
|
|
|
|
void *original = mask->func->engine_data_get(mask->object);
|
|
|
|
void *scaled = ENFN->image_scaled_update
|
|
|
|
(ENDT, mdata->surface, original, w, h, smooth, EINA_TRUE, EVAS_COLORSPACE_GRY8);
|
|
|
|
if (scaled)
|
|
|
|
{
|
|
|
|
done = EINA_TRUE;
|
|
|
|
mdata->surface = scaled;
|
|
|
|
mdata->w = w;
|
|
|
|
mdata->h = h;
|
|
|
|
mdata->is_alpha = (ENFN->image_colorspace_get(ENDT, scaled) == EVAS_COLORSPACE_GRY8);
|
2015-03-11 19:28:02 -07:00
|
|
|
mdata->is_scaled = EINA_TRUE;
|
2015-02-26 22:57:36 -08:00
|
|
|
}
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-mask_scaled_update", mask->object, 0.0, NULL);
|
2015-02-25 02:05:12 -08:00
|
|
|
}
|
2014-11-12 17:47:29 -08:00
|
|
|
}
|
|
|
|
|
2015-02-25 02:05:12 -08:00
|
|
|
if (!done)
|
2014-11-12 17:47:29 -08:00
|
|
|
{
|
2015-02-25 02:05:12 -08:00
|
|
|
/* delete render surface if changed or if already alpha
|
|
|
|
* (we don't know how to render objects to alpha) */
|
2015-03-11 19:28:02 -07:00
|
|
|
if (mdata->surface && ((w != mdata->w) || (h != mdata->h) || mdata->is_alpha || mdata->is_scaled))
|
2015-02-25 02:05:12 -08:00
|
|
|
{
|
2015-07-01 20:04:02 -07:00
|
|
|
ENFN->image_free(ENDT, mdata->surface);
|
2015-02-25 02:05:12 -08:00
|
|
|
mdata->surface = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create new RGBA render surface if needed */
|
|
|
|
if (!mdata->surface)
|
|
|
|
{
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+mask_surface_new", mask->object, 0.0, NULL);
|
2015-02-25 02:05:12 -08:00
|
|
|
mdata->surface = ENFN->image_map_surface_new(ENDT, w, h, EINA_TRUE);
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-mask_surface_new", mask->object, 0.0, NULL);
|
2015-02-25 02:05:12 -08:00
|
|
|
if (!mdata->surface) goto end;
|
|
|
|
mdata->is_alpha = EINA_FALSE;
|
2015-03-11 19:28:02 -07:00
|
|
|
mdata->is_scaled = EINA_FALSE;
|
2015-02-25 02:05:12 -08:00
|
|
|
mdata->w = w;
|
|
|
|
mdata->h = h;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear surface with transparency */
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+mask_rect_clear", mask->object, 0.0, NULL);
|
2015-02-25 02:05:12 -08:00
|
|
|
ctx = ENFN->context_new(ENDT);
|
|
|
|
ENFN->context_color_set(ENDT, ctx, 0, 0, 0, 0);
|
|
|
|
ENFN->context_render_op_set(ENDT, ctx, EVAS_RENDER_COPY);
|
|
|
|
ENFN->rectangle_draw(ENDT, ctx, mdata->surface, 0, 0, w, h, EINA_FALSE);
|
|
|
|
ENFN->context_free(ENDT, ctx);
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-mask_rect_clear", mask->object, 0.0, NULL);
|
2015-02-25 02:05:12 -08:00
|
|
|
|
|
|
|
/* Render mask to RGBA surface */
|
|
|
|
ctx = ENFN->context_new(ENDT);
|
|
|
|
if (prev_mask)
|
|
|
|
{
|
|
|
|
ENFN->context_clip_image_set(ENDT, ctx,
|
|
|
|
prev_mask->mask->surface,
|
|
|
|
prev_mask->cur->geometry.x - x,
|
2015-07-26 22:10:29 -07:00
|
|
|
prev_mask->cur->geometry.y - y,
|
|
|
|
evas, EINA_FALSE);
|
2015-02-25 02:05:12 -08:00
|
|
|
}
|
|
|
|
evas_render_mapped(evas, mask->object, mask, ctx, mdata->surface,
|
2015-04-14 00:20:00 -07:00
|
|
|
-x, -y, 2, 0, 0, evas->output.w, evas->output.h,
|
2015-02-25 02:05:12 -08:00
|
|
|
NULL, level, EINA_TRUE, EINA_FALSE);
|
|
|
|
ENFN->context_free(ENDT, ctx);
|
|
|
|
|
|
|
|
/* BEGIN HACK */
|
|
|
|
|
|
|
|
/* Now we want to convert this RGBA surface to Alpha.
|
|
|
|
* NOTE: So, this is not going to work with the GL engine but only with
|
|
|
|
* the SW engine. Here's the detection hack:
|
|
|
|
* FIXME: If you know of a way to support rendering to GL_ALPHA in GL,
|
|
|
|
* then we should render directly to an ALPHA surface. A priori,
|
|
|
|
* GLES FBO does not support this.
|
|
|
|
*/
|
|
|
|
if (!ENFN->gl_surface_read_pixels)
|
|
|
|
{
|
|
|
|
RGBA_Image *alpha_surface;
|
|
|
|
DATA32 *rgba;
|
|
|
|
DATA8* alpha;
|
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+mask_new_cpy_data", mask->object, 0.0, NULL);
|
2015-02-25 02:05:12 -08:00
|
|
|
alpha_surface = ENFN->image_new_from_copied_data
|
|
|
|
(ENDT, w, h, NULL, EINA_TRUE, EVAS_COLORSPACE_GRY8);
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-mask_new_cpy_data", mask->object, 0.0, NULL);
|
2015-02-25 02:05:12 -08:00
|
|
|
if (!alpha_surface) goto end;
|
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+mask_cpy_data", mask->object, 0.0, NULL);
|
2015-02-25 02:05:12 -08:00
|
|
|
/* Copy alpha channel */
|
|
|
|
rgba = ((RGBA_Image *) mdata->surface)->image.data;
|
|
|
|
alpha = alpha_surface->image.data8;
|
|
|
|
for (y = h; y; --y)
|
|
|
|
for (x = w; x; --x, alpha++, rgba++)
|
|
|
|
*alpha = (DATA8) A_VAL(rgba);
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-mask_cpy_data", mask->object, 0.0, NULL);
|
2015-02-25 02:05:12 -08:00
|
|
|
|
|
|
|
/* Now we can drop the original surface */
|
2015-07-01 20:04:02 -07:00
|
|
|
ENFN->image_free(ENDT, mdata->surface);
|
2015-02-25 02:05:12 -08:00
|
|
|
mdata->surface = alpha_surface;
|
|
|
|
mdata->is_alpha = EINA_TRUE;
|
|
|
|
}
|
|
|
|
/* END OF HACK */
|
2014-11-12 17:47:29 -08:00
|
|
|
}
|
|
|
|
|
2015-01-21 00:30:18 -08:00
|
|
|
mdata->surface = ENFN->image_dirty_region(ENDT, mdata->surface, 0, 0, w, h);
|
|
|
|
|
2014-11-12 17:47:29 -08:00
|
|
|
end:
|
|
|
|
EINA_COW_WRITE_END(evas_object_mask_cow, mask->mask, mdata);
|
|
|
|
|
|
|
|
if ((r != 255) || (g != 255) || (b != 255) || (a != 255))
|
|
|
|
{
|
|
|
|
EINA_COW_STATE_WRITE_BEGIN(mask, state_write, cur)
|
|
|
|
{
|
|
|
|
state_write->color.r = r;
|
|
|
|
state_write->color.g = g;
|
|
|
|
state_write->color.b = b;
|
|
|
|
state_write->color.a = a;
|
|
|
|
}
|
|
|
|
EINA_COW_STATE_WRITE_END(mask, state_write, cur);
|
|
|
|
}
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-mask_subrender", mask->object, 0.0, NULL);
|
2014-11-12 17:47:29 -08:00
|
|
|
}
|
|
|
|
|
2011-10-27 02:39:18 -07:00
|
|
|
static void
|
2015-07-31 16:32:24 -07:00
|
|
|
_evas_render_cutout_add(Evas_Public_Data *e, void *context, Evas_Object_Protected_Data *obj, int off_x, int off_y)
|
2011-10-27 02:39:18 -07:00
|
|
|
{
|
2013-04-11 00:25:36 -07:00
|
|
|
if (evas_object_is_source_invisible(obj->object, obj)) return;
|
|
|
|
if (evas_object_is_opaque(obj->object, obj))
|
2011-10-27 02:39:18 -07:00
|
|
|
{
|
|
|
|
Evas_Coord cox, coy, cow, coh;
|
2013-04-11 00:25:36 -07:00
|
|
|
|
2013-03-12 05:58:19 -07:00
|
|
|
cox = obj->cur->cache.clip.x;
|
|
|
|
coy = obj->cur->cache.clip.y;
|
|
|
|
cow = obj->cur->cache.clip.w;
|
|
|
|
coh = obj->cur->cache.clip.h;
|
2013-01-21 19:56:00 -08:00
|
|
|
if ((obj->map->cur.map) && (obj->map->cur.usemap))
|
2011-10-27 02:39:18 -07:00
|
|
|
{
|
2012-10-16 05:41:48 -07:00
|
|
|
Evas_Object_Protected_Data *oo;
|
2012-05-16 06:21:37 -07:00
|
|
|
|
2016-11-25 18:21:34 -08:00
|
|
|
oo = obj;
|
2013-03-12 05:58:19 -07:00
|
|
|
while (oo->cur->clipper)
|
2011-10-27 02:39:18 -07:00
|
|
|
{
|
2013-03-12 05:58:19 -07:00
|
|
|
if ((oo->cur->clipper->map->cur.map_parent
|
2013-01-21 19:56:00 -08:00
|
|
|
!= oo->map->cur.map_parent) &&
|
|
|
|
(!((oo->map->cur.map) && (oo->map->cur.usemap))))
|
2011-10-27 02:39:18 -07:00
|
|
|
break;
|
|
|
|
RECTS_CLIP_TO_RECT(cox, coy, cow, coh,
|
2013-03-12 05:58:19 -07:00
|
|
|
oo->cur->geometry.x,
|
|
|
|
oo->cur->geometry.y,
|
|
|
|
oo->cur->geometry.w,
|
|
|
|
oo->cur->geometry.h);
|
|
|
|
oo = oo->cur->clipper;
|
2011-10-27 02:39:18 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
e->engine.func->context_cutout_add
|
2015-07-31 16:32:24 -07:00
|
|
|
(e->engine.data.output, context,
|
2011-10-27 02:39:18 -07:00
|
|
|
cox + off_x, coy + off_y, cow, coh);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (obj->func->get_opaque_rect)
|
|
|
|
{
|
|
|
|
Evas_Coord obx, oby, obw, obh;
|
2012-05-16 06:21:37 -07:00
|
|
|
|
2013-07-08 17:46:15 -07:00
|
|
|
obj->func->get_opaque_rect(obj->object, obj, obj->private_data, &obx, &oby, &obw, &obh);
|
2011-10-27 02:39:18 -07:00
|
|
|
if ((obw > 0) && (obh > 0))
|
|
|
|
{
|
|
|
|
obx += off_x;
|
|
|
|
oby += off_y;
|
|
|
|
RECTS_CLIP_TO_RECT(obx, oby, obw, obh,
|
2013-03-12 05:58:19 -07:00
|
|
|
obj->cur->cache.clip.x + off_x,
|
|
|
|
obj->cur->cache.clip.y + off_y,
|
|
|
|
obj->cur->cache.clip.w,
|
|
|
|
obj->cur->cache.clip.h);
|
2011-10-27 02:39:18 -07:00
|
|
|
e->engine.func->context_cutout_add
|
2015-07-31 16:32:24 -07:00
|
|
|
(e->engine.data.output, context,
|
2011-10-27 02:39:18 -07:00
|
|
|
obx, oby, obw, obh);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-18 08:26:44 -08:00
|
|
|
void
|
|
|
|
evas_render_rendering_wait(Evas_Public_Data *evas)
|
|
|
|
{
|
|
|
|
while (evas->rendering) evas_async_events_process_blocking();
|
|
|
|
}
|
|
|
|
|
2013-09-02 21:48:08 -07:00
|
|
|
/*
|
|
|
|
* Syncs ALL async rendering canvases. Must be called in the main thread.
|
|
|
|
*/
|
2013-09-02 15:38:52 -07:00
|
|
|
void
|
2013-10-17 12:13:24 -07:00
|
|
|
evas_all_sync(void)
|
2013-09-02 15:38:52 -07:00
|
|
|
{
|
2013-09-02 21:48:08 -07:00
|
|
|
Evas_Public_Data *evas;
|
2013-09-02 15:38:52 -07:00
|
|
|
|
2013-09-02 21:48:08 -07:00
|
|
|
if (!_rendering_evases) return;
|
|
|
|
|
|
|
|
evas = eina_list_data_get(eina_list_last(_rendering_evases));
|
|
|
|
evas_render_rendering_wait(evas);
|
|
|
|
|
|
|
|
assert(_rendering_evases == NULL);
|
2013-09-02 15:38:52 -07:00
|
|
|
}
|
|
|
|
|
2013-01-11 11:54:12 -08:00
|
|
|
static Eina_Bool
|
2013-01-17 14:14:05 -08:00
|
|
|
_drop_scie_ref(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
|
2013-01-11 11:54:12 -08:00
|
|
|
{
|
2013-01-17 14:14:05 -08:00
|
|
|
evas_common_rgba_image_scalecache_item_unref(data);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
2013-01-16 14:32:39 -08:00
|
|
|
|
2013-01-17 14:14:05 -08:00
|
|
|
static Eina_Bool
|
|
|
|
_drop_image_cache_ref(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
|
|
|
|
{
|
2013-01-11 11:54:12 -08:00
|
|
|
#ifdef EVAS_CSERVE2
|
2013-09-02 02:53:18 -07:00
|
|
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(data))
|
2013-01-11 11:54:12 -08:00
|
|
|
evas_cache2_image_close((Image_Entry *)data);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_drop((Image_Entry *)data);
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2013-11-30 20:26:04 -08:00
|
|
|
static void
|
|
|
|
_cb_always_call(Evas *eo_e, Evas_Callback_Type type, void *event_info)
|
|
|
|
{
|
|
|
|
int freeze_num = 0, i;
|
|
|
|
|
2016-08-10 07:23:04 -07:00
|
|
|
freeze_num = efl_event_freeze_count_get(eo_e);
|
|
|
|
for (i = 0; i < freeze_num; i++) efl_event_thaw(eo_e);
|
2013-11-30 20:26:04 -08:00
|
|
|
evas_event_callback_call(eo_e, type, event_info);
|
2016-08-10 07:23:04 -07:00
|
|
|
for (i = 0; i < freeze_num; i++) efl_event_freeze(eo_e);
|
2013-11-30 20:26:04 -08:00
|
|
|
}
|
|
|
|
|
2016-11-25 21:25:41 -08:00
|
|
|
#ifndef INLINE_ACTIVE_GEOM
|
2016-05-24 19:45:16 -07:00
|
|
|
static inline Eina_Bool
|
|
|
|
_is_obj_in_rect(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
|
|
|
|
int x, int y, int w, int h)
|
|
|
|
{
|
|
|
|
if (obj->is_smart)
|
|
|
|
{
|
|
|
|
Evas_Coord_Rectangle rect;
|
|
|
|
|
|
|
|
evas_object_smart_bounding_box_get(eo_obj, &rect, NULL);
|
|
|
|
if (RECTS_INTERSECT(x, y, w, h, rect.x, rect.y, rect.w, rect.h))
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (evas_object_is_in_output_rect(eo_obj, obj, x, y, w, h))
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2016-11-25 21:25:41 -08:00
|
|
|
#endif
|
2016-05-24 19:45:16 -07:00
|
|
|
|
2015-04-15 03:05:59 -07:00
|
|
|
static Eina_Bool
|
|
|
|
evas_render_updates_internal_loop(Evas *eo_e, Evas_Public_Data *e,
|
2015-07-31 16:32:24 -07:00
|
|
|
void *surface, void *context,
|
2015-05-09 11:02:13 -07:00
|
|
|
Evas_Object_Protected_Data *top,
|
2015-04-15 03:05:59 -07:00
|
|
|
int ux, int uy, int uw, int uh,
|
|
|
|
int cx, int cy, int cw, int ch,
|
|
|
|
int fx, int fy,
|
|
|
|
Eina_Bool alpha,
|
|
|
|
Eina_Bool do_async,
|
2015-10-07 18:56:35 -07:00
|
|
|
unsigned int *offset, int level)
|
2015-04-15 03:05:59 -07:00
|
|
|
{
|
|
|
|
Evas_Object *eo_obj;
|
|
|
|
Evas_Object_Protected_Data *obj;
|
|
|
|
int off_x, off_y;
|
|
|
|
unsigned int i, j;
|
|
|
|
Eina_Bool clean_them = EINA_FALSE;
|
|
|
|
|
|
|
|
eina_evlog("+render_setup", eo_e, 0.0, NULL);
|
2015-10-07 18:56:35 -07:00
|
|
|
RD(level, " [--- UPDATE %i %i %ix%i\n", ux, uy, uw, uh);
|
2015-04-15 03:05:59 -07:00
|
|
|
|
|
|
|
off_x = cx - ux;
|
|
|
|
off_y = cy - uy;
|
|
|
|
/* build obscuring objects list (in order from bottom to top) */
|
|
|
|
if (alpha)
|
|
|
|
{
|
|
|
|
e->engine.func->context_clip_set(e->engine.data.output,
|
2015-07-31 16:32:24 -07:00
|
|
|
context,
|
2015-04-15 03:05:59 -07:00
|
|
|
ux + off_x, uy + off_y, uw, uh);
|
|
|
|
}
|
|
|
|
for (i = 0; i < e->obscuring_objects.count; ++i)
|
|
|
|
{
|
|
|
|
obj = (Evas_Object_Protected_Data *)eina_array_data_get
|
|
|
|
(&e->obscuring_objects, i);
|
|
|
|
if (evas_object_is_in_output_rect(obj->object, obj, ux - fx, uy - fy, uw, uh))
|
|
|
|
{
|
|
|
|
OBJ_ARRAY_PUSH(&e->temporary_objects, obj);
|
|
|
|
|
2015-07-31 16:32:24 -07:00
|
|
|
if (obj == top) break;
|
|
|
|
|
2015-04-15 03:05:59 -07:00
|
|
|
/* reset the background of the area if needed (using cutout and engine alpha flag to help) */
|
|
|
|
if (alpha)
|
2015-07-31 16:32:24 -07:00
|
|
|
_evas_render_cutout_add(e, context, obj, off_x + fx, off_y + fy);
|
2015-04-15 03:05:59 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (alpha)
|
|
|
|
{
|
|
|
|
e->engine.func->context_color_set(e->engine.data.output,
|
2015-07-31 16:32:24 -07:00
|
|
|
context,
|
2015-04-15 03:05:59 -07:00
|
|
|
0, 0, 0, 0);
|
|
|
|
e->engine.func->context_multiplier_unset
|
|
|
|
(e->engine.data.output, e->engine.data.context);
|
|
|
|
e->engine.func->context_render_op_set(e->engine.data.output,
|
2015-07-31 16:32:24 -07:00
|
|
|
context,
|
2015-04-15 03:05:59 -07:00
|
|
|
EVAS_RENDER_COPY);
|
|
|
|
e->engine.func->rectangle_draw(e->engine.data.output,
|
2015-07-31 16:32:24 -07:00
|
|
|
context, surface,
|
2015-04-15 03:05:59 -07:00
|
|
|
cx, cy, cw, ch, do_async);
|
2015-07-31 16:32:24 -07:00
|
|
|
e->engine.func->context_cutout_clear(e->engine.data.output, context);
|
|
|
|
e->engine.func->context_clip_unset(e->engine.data.output, context);
|
2015-04-15 03:05:59 -07:00
|
|
|
}
|
|
|
|
eina_evlog("-render_setup", eo_e, 0.0, NULL);
|
|
|
|
|
|
|
|
eina_evlog("+render_objects", eo_e, 0.0, NULL);
|
|
|
|
/* render all object that intersect with rect */
|
2016-11-25 21:25:41 -08:00
|
|
|
for (i = 0; i < e->active_objects.len; i++)
|
2015-04-15 03:05:59 -07:00
|
|
|
{
|
2016-11-30 00:36:42 -08:00
|
|
|
Evas_Active_Entry *ent = eina_inarray_nth(&e->active_objects, i);
|
2016-11-25 21:25:41 -08:00
|
|
|
|
|
|
|
obj = ent->obj;
|
2015-04-15 03:05:59 -07:00
|
|
|
eo_obj = obj->object;
|
|
|
|
|
2015-05-09 11:02:13 -07:00
|
|
|
if (obj == top) break;
|
|
|
|
|
2015-04-15 03:05:59 -07:00
|
|
|
/* if it's in our outpout rect and it doesn't clip anything */
|
2016-03-28 01:47:02 -07:00
|
|
|
RD(level, " OBJ: [%p", eo_obj);
|
2015-09-01 04:47:40 -07:00
|
|
|
IFRD(obj->name, 0, " '%s'", obj->name);
|
2015-10-07 18:56:35 -07:00
|
|
|
RD(level, "] '%s' %i %i %ix%i\n", obj->type, obj->cur->geometry.x, obj->cur->geometry.y, obj->cur->geometry.w, obj->cur->geometry.h);
|
2016-11-25 21:25:41 -08:00
|
|
|
if (
|
2015-04-15 03:05:59 -07:00
|
|
|
(!obj->clip.clipees) &&
|
|
|
|
(obj->cur->visible) &&
|
|
|
|
(obj->cur->cache.clip.visible) &&
|
2016-11-25 21:25:41 -08:00
|
|
|
#ifdef INLINE_ACTIVE_GEOM
|
|
|
|
RECTS_INTERSECT(ux - fx, uy - fy, uw, uh,
|
|
|
|
ent->rect.x, ent->rect.y,
|
|
|
|
ent->rect.w, ent->rect.h) &&
|
|
|
|
#else
|
|
|
|
(_is_obj_in_rect(eo_obj, obj, ux - fx, uy - fy, uw, uh)) &&
|
|
|
|
#endif
|
|
|
|
(!obj->delete_me) &&
|
2015-04-15 03:05:59 -07:00
|
|
|
((obj->cur->color.a > 0 || obj->cur->render_op != EVAS_RENDER_BLEND)))
|
|
|
|
{
|
|
|
|
int x, y, w, h;
|
|
|
|
|
2015-10-07 18:56:35 -07:00
|
|
|
RD(level, " DRAW (vis: %i, a: %i, clipees: %p)\n", obj->cur->visible, obj->cur->color.a, obj->clip.clipees);
|
2015-04-15 03:05:59 -07:00
|
|
|
if ((e->temporary_objects.count > *offset) &&
|
|
|
|
(eina_array_data_get(&e->temporary_objects, *offset) == obj))
|
|
|
|
(*offset)++;
|
|
|
|
x = cx; y = cy; w = cw; h = ch;
|
|
|
|
if (((w > 0) && (h > 0)) || (obj->is_smart))
|
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *prev_mask = NULL;
|
|
|
|
Evas_Object_Protected_Data *mask = NULL;
|
|
|
|
|
|
|
|
if (!obj->is_smart)
|
|
|
|
{
|
2016-11-16 01:09:37 -08:00
|
|
|
int cfx, cfy;
|
|
|
|
if (!obj->is_frame)
|
|
|
|
{
|
|
|
|
cfx = obj->cur->cache.clip.x + off_x + fx;
|
|
|
|
cfy = obj->cur->cache.clip.y + off_y + fy;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cfx = obj->cur->cache.clip.x + off_x;
|
|
|
|
cfy = obj->cur->cache.clip.y + off_y;
|
|
|
|
}
|
|
|
|
RECTS_CLIP_TO_RECT(x, y, w, h, cfx, cfy,
|
2015-04-15 03:05:59 -07:00
|
|
|
obj->cur->cache.clip.w,
|
|
|
|
obj->cur->cache.clip.h);
|
|
|
|
}
|
|
|
|
|
|
|
|
e->engine.func->context_clip_set(e->engine.data.output,
|
2015-07-31 16:32:24 -07:00
|
|
|
context,
|
2015-04-15 03:05:59 -07:00
|
|
|
x, y, w, h);
|
2016-11-21 21:33:48 -08:00
|
|
|
|
2015-04-15 03:05:59 -07:00
|
|
|
/* Clipper masks */
|
|
|
|
if (_evas_render_object_is_mask(obj->cur->clipper))
|
|
|
|
mask = obj->cur->clipper; // main object clipped by this mask
|
|
|
|
else if (obj->clip.mask)
|
|
|
|
mask = obj->clip.mask; // propagated clip
|
|
|
|
prev_mask = obj->clip.prev_mask;
|
|
|
|
|
|
|
|
if (mask)
|
|
|
|
{
|
|
|
|
if (mask->mask->redraw || !mask->mask->surface)
|
|
|
|
evas_render_mask_subrender(obj->layer->evas, mask, prev_mask, 4);
|
|
|
|
|
|
|
|
if (mask->mask->surface)
|
|
|
|
{
|
|
|
|
e->engine.func->context_clip_image_set
|
|
|
|
(e->engine.data.output,
|
2015-07-31 16:32:24 -07:00
|
|
|
context,
|
2015-04-15 03:05:59 -07:00
|
|
|
mask->mask->surface,
|
|
|
|
mask->cur->geometry.x + off_x,
|
|
|
|
mask->cur->geometry.y + off_y,
|
|
|
|
e, do_async);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+cutouts_add", obj->object, 0.0, NULL);
|
2015-04-15 03:05:59 -07:00
|
|
|
#if 1 /* FIXME: this can slow things down... figure out optimum... coverage */
|
|
|
|
for (j = *offset; j < e->temporary_objects.count; ++j)
|
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *obj2;
|
|
|
|
|
|
|
|
obj2 = (Evas_Object_Protected_Data *)eina_array_data_get
|
|
|
|
(&e->temporary_objects, j);
|
2015-05-09 11:02:13 -07:00
|
|
|
if (obj2 == top) break;
|
2015-10-04 23:51:02 -07:00
|
|
|
#if 1
|
|
|
|
if (
|
|
|
|
RECTS_INTERSECT
|
|
|
|
(obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
|
|
|
obj->cur->cache.clip.w, obj->cur->cache.clip.h,
|
|
|
|
obj2->cur->cache.clip.x, obj2->cur->cache.clip.y,
|
|
|
|
obj2->cur->cache.clip.w, obj2->cur->cache.clip.h) &&
|
|
|
|
RECTS_INTERSECT
|
|
|
|
(obj2->cur->cache.clip.x, obj2->cur->cache.clip.y,
|
|
|
|
obj2->cur->cache.clip.w, obj2->cur->cache.clip.h,
|
|
|
|
ux, uy, uw, uh)
|
|
|
|
)
|
|
|
|
#endif
|
|
|
|
_evas_render_cutout_add(e, context, obj2, off_x + fx, off_y + fy);
|
2015-04-15 03:05:59 -07:00
|
|
|
}
|
|
|
|
#endif
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-cutouts_add", obj->object, 0.0, NULL);
|
2015-07-31 16:32:24 -07:00
|
|
|
clean_them |= evas_render_mapped(e, eo_obj, obj, context,
|
2015-04-15 03:05:59 -07:00
|
|
|
surface, off_x + fx,
|
|
|
|
off_y + fy, 0,
|
|
|
|
cx, cy, cw, ch,
|
2015-10-07 18:56:35 -07:00
|
|
|
NULL, level + 3,
|
2015-04-15 03:05:59 -07:00
|
|
|
EINA_FALSE,
|
|
|
|
do_async);
|
|
|
|
e->engine.func->context_cutout_clear(e->engine.data.output,
|
2015-07-31 16:32:24 -07:00
|
|
|
context);
|
2015-04-15 03:05:59 -07:00
|
|
|
|
|
|
|
if (mask)
|
|
|
|
{
|
|
|
|
e->engine.func->context_clip_image_unset
|
2015-07-31 16:32:24 -07:00
|
|
|
(e->engine.data.output, context);
|
2015-04-15 03:05:59 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
eina_evlog("-render_objects", eo_e, 0.0, NULL);
|
|
|
|
/* free obscuring objects list */
|
|
|
|
OBJS_ARRAY_CLEAN(&e->temporary_objects);
|
2015-10-11 20:03:52 -07:00
|
|
|
|
|
|
|
#ifdef REND_DBG
|
2015-10-07 18:56:35 -07:00
|
|
|
if (top) RD(level, " ---] SNAPSHOT [obj:%p sfc:%p]\n", top, surface);
|
|
|
|
else RD(level, " ---]\n");
|
2015-10-11 20:03:52 -07:00
|
|
|
#endif
|
2015-04-15 03:05:59 -07:00
|
|
|
|
|
|
|
return clean_them;
|
|
|
|
}
|
|
|
|
|
2012-12-18 08:26:44 -08:00
|
|
|
static Eina_Bool
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_render_updates_internal(Evas *eo_e,
|
2009-10-28 01:59:01 -07:00
|
|
|
unsigned char make_updates,
|
2012-12-18 08:26:44 -08:00
|
|
|
unsigned char do_draw,
|
|
|
|
Evas_Render_Done_Cb done_func,
|
|
|
|
void *done_data,
|
|
|
|
Eina_Bool do_async)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_obj;
|
|
|
|
Evas_Object_Protected_Data *obj;
|
2012-10-10 00:23:00 -07:00
|
|
|
Evas_Public_Data *e;
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *ll;
|
2009-06-17 03:01:52 -07:00
|
|
|
Eina_Bool clean_them = EINA_FALSE;
|
2016-11-15 15:54:29 -08:00
|
|
|
Eina_Bool rendering = EINA_FALSE;
|
2009-06-26 06:26:52 -07:00
|
|
|
Eina_Bool alpha;
|
2009-06-23 06:57:27 -07:00
|
|
|
Eina_Rectangle *r;
|
2015-04-15 03:05:59 -07:00
|
|
|
unsigned int i;
|
2016-11-21 18:09:18 -08:00
|
|
|
Phase1_Context p1ctx;
|
2010-08-23 23:58:07 -07:00
|
|
|
int redraw_all = 0;
|
2015-04-15 03:05:59 -07:00
|
|
|
Evas_Render_Mode render_mode = !do_async ?
|
|
|
|
EVAS_RENDER_MODE_SYNC :
|
|
|
|
EVAS_RENDER_MODE_ASYNC_INIT;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
MAGIC_CHECK(eo_e, Evas, MAGIC_EVAS);
|
2012-12-18 08:26:44 -08:00
|
|
|
return EINA_FALSE;
|
2002-11-08 00:02:15 -08:00
|
|
|
MAGIC_CHECK_END();
|
2012-10-10 00:23:00 -07:00
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2012-12-18 08:26:44 -08:00
|
|
|
if (!e->changed) return EINA_FALSE;
|
|
|
|
|
2013-01-11 10:20:11 -08:00
|
|
|
if (e->rendering)
|
|
|
|
{
|
2013-01-14 12:02:43 -08:00
|
|
|
if (do_async)
|
|
|
|
return EINA_FALSE;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WRN("Mixing render sync as already doing async "
|
|
|
|
"render! Syncing! e=%p [%s]", e,
|
|
|
|
e->engine.module->definition->name);
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_wait", eo_e, 0.0, NULL);
|
|
|
|
evas_render_rendering_wait(e);
|
|
|
|
eina_evlog("-render_wait", eo_e, 0.0, NULL);
|
2013-01-14 12:02:43 -08:00
|
|
|
}
|
2013-01-11 10:20:11 -08:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2015-04-03 07:34:15 -07:00
|
|
|
#ifdef EVAS_RENDER_DEBUG_TIMING
|
|
|
|
double start_time = _time_get();
|
|
|
|
#endif
|
|
|
|
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get())
|
|
|
|
evas_cserve2_dispatch();
|
|
|
|
#endif
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_calc", eo_e, 0.0, NULL);
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_call_smarts_calculate(eo_e);
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_calc", eo_e, 0.0, NULL);
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2015-04-16 01:36:32 -07:00
|
|
|
RD(0, "[--- RENDER EVAS (size: %ix%i): %p (eo %p)\n", e->viewport.w, e->viewport.h, e, eo_e);
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2013-11-30 20:26:04 -08:00
|
|
|
_cb_always_call(eo_e, EVAS_CALLBACK_RENDER_PRE, NULL);
|
2012-05-16 06:21:37 -07:00
|
|
|
|
2008-05-26 06:24:24 -07:00
|
|
|
/* Check if the modified object mean recalculating every thing */
|
2008-06-04 09:42:39 -07:00
|
|
|
if (!e->invalidate)
|
2015-05-14 01:35:22 -07:00
|
|
|
{
|
|
|
|
eina_evlog("+render_pending", eo_e, 0.0, NULL);
|
|
|
|
_evas_render_check_pending_objects(&e->pending_objects, eo_e, e);
|
|
|
|
eina_evlog("-render_pending", eo_e, 0.0, NULL);
|
|
|
|
}
|
2008-05-26 06:24:24 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
/* phase 1. add extra updates for changed objects */
|
2011-10-21 03:25:35 -07:00
|
|
|
if (e->invalidate || e->render_objects.count <= 0)
|
2015-05-14 01:35:22 -07:00
|
|
|
{
|
|
|
|
eina_evlog("+render_phase1", eo_e, 0.0, NULL);
|
2016-11-21 18:09:18 -08:00
|
|
|
|
|
|
|
p1ctx.e = e;
|
|
|
|
p1ctx.active_objects = &e->active_objects;
|
|
|
|
p1ctx.restack_objects = &e->restack_objects;
|
|
|
|
p1ctx.delete_objects = &e->delete_objects;
|
|
|
|
p1ctx.render_objects = &e->render_objects;
|
|
|
|
p1ctx.snapshot_objects = &e->snapshot_objects;
|
|
|
|
p1ctx.redraw_all = redraw_all;
|
|
|
|
clean_them = _evas_render_phase1_process(&p1ctx);
|
|
|
|
redraw_all = p1ctx.redraw_all;
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_phase1", eo_e, 0.0, NULL);
|
|
|
|
}
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2011-10-02 20:28:52 -07:00
|
|
|
/* phase 1.5. check if the video should be inlined or stay in their overlay */
|
|
|
|
alpha = e->engine.func->canvas_alpha_get(e->engine.data.output,
|
2012-10-16 05:41:48 -07:00
|
|
|
e->engine.data.context);
|
2011-10-02 20:28:52 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(e->video_objects, ll, eo_obj)
|
2011-10-02 20:28:52 -07:00
|
|
|
{
|
|
|
|
/* we need the surface to be transparent to display the underlying overlay */
|
2012-10-10 00:23:00 -07:00
|
|
|
if (alpha && _evas_render_can_use_overlay(e, eo_obj))
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_object_image_video_overlay_show(eo_obj);
|
2011-10-02 20:28:52 -07:00
|
|
|
else
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_object_image_video_overlay_hide(eo_obj);
|
2011-10-02 20:28:52 -07:00
|
|
|
}
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_phase1_direct", eo_e, 0.0, NULL);
|
2011-10-13 02:23:42 -07:00
|
|
|
/* phase 1.8. pre render for proxy */
|
2012-10-10 00:23:00 -07:00
|
|
|
_evas_render_phase1_direct(e, &e->active_objects, &e->restack_objects,
|
2011-10-13 02:23:42 -07:00
|
|
|
&e->delete_objects, &e->render_objects);
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_phase1_direct", eo_e, 0.0, NULL);
|
2011-10-13 02:23:42 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
/* phase 2. force updates for restacks */
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_phase2", eo_e, 0.0, NULL);
|
2008-05-26 06:24:24 -07:00
|
|
|
for (i = 0; i < e->restack_objects.count; ++i)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2011-05-20 23:23:33 -07:00
|
|
|
obj = eina_array_data_get(&e->restack_objects, i);
|
2015-02-03 21:43:14 -08:00
|
|
|
if (_evas_render_object_is_mask(obj))
|
|
|
|
_evas_mask_redraw_set(e, obj);
|
2014-01-27 08:54:25 -08:00
|
|
|
obj->func->render_pre(obj->object, obj, obj->private_data);
|
2012-10-10 00:23:00 -07:00
|
|
|
_evas_render_prev_cur_clip_cache_add(e, obj);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2013-05-02 00:47:16 -07:00
|
|
|
OBJS_ARRAY_CLEAN(&e->restack_objects);
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_phase2", eo_e, 0.0, NULL);
|
2011-12-26 15:10:27 -08:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
/* phase 3. add exposes */
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_phase3", eo_e, 0.0, NULL);
|
2009-04-14 02:27:27 -07:00
|
|
|
EINA_LIST_FREE(e->damages, r)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2010-09-24 23:19:30 -07:00
|
|
|
e->engine.func->output_redraws_rect_add(e->engine.data.output,
|
|
|
|
r->x, r->y, r->w, r->h);
|
|
|
|
eina_rectangle_free(r);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_phase3", eo_e, 0.0, NULL);
|
2011-12-26 15:10:27 -08:00
|
|
|
|
2011-12-17 10:45:09 -08:00
|
|
|
/* phase 4. framespace, output & viewport changes */
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_phase4", eo_e, 0.0, NULL);
|
2003-04-17 05:05:00 -07:00
|
|
|
if (e->viewport.changed)
|
|
|
|
{
|
2010-09-24 23:19:30 -07:00
|
|
|
e->engine.func->output_redraws_rect_add(e->engine.data.output,
|
|
|
|
0, 0,
|
|
|
|
e->output.w, e->output.h);
|
2003-04-17 05:05:00 -07:00
|
|
|
}
|
|
|
|
if (e->output.changed)
|
|
|
|
{
|
2010-09-24 23:19:30 -07:00
|
|
|
e->engine.func->output_resize(e->engine.data.output,
|
|
|
|
e->output.w, e->output.h);
|
|
|
|
e->engine.func->output_redraws_rect_add(e->engine.data.output,
|
|
|
|
0, 0,
|
|
|
|
e->output.w, e->output.h);
|
2003-04-17 05:05:00 -07:00
|
|
|
}
|
2006-11-15 19:20:24 -08:00
|
|
|
if ((e->output.w != e->viewport.w) || (e->output.h != e->viewport.h))
|
|
|
|
{
|
2011-05-20 23:23:33 -07:00
|
|
|
ERR("viewport size != output size!");
|
2006-11-15 19:20:24 -08:00
|
|
|
}
|
2012-05-25 05:55:45 -07:00
|
|
|
|
|
|
|
if (e->framespace.changed)
|
2010-08-23 23:58:07 -07:00
|
|
|
{
|
2013-08-23 00:34:22 -07:00
|
|
|
/* NB: If the framespace changes, we need to add a redraw rectangle
|
2016-11-21 21:33:48 -08:00
|
|
|
* which covers the Whole viewport. This is because 'framespace' is
|
|
|
|
* defined as "the space IN the viewport which is Occupied by the
|
2013-08-23 00:34:22 -07:00
|
|
|
* window frame" */
|
2010-08-23 23:58:07 -07:00
|
|
|
e->engine.func->output_redraws_rect_add(e->engine.data.output,
|
2013-08-23 00:34:22 -07:00
|
|
|
e->viewport.x, e->viewport.y,
|
|
|
|
e->viewport.w, e->viewport.h);
|
2012-05-25 05:55:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (redraw_all)
|
|
|
|
{
|
|
|
|
e->engine.func->output_redraws_rect_add(e->engine.data.output, 0, 0,
|
2010-08-23 23:58:07 -07:00
|
|
|
e->output.w, e->output.h);
|
|
|
|
}
|
2015-07-31 17:38:31 -07:00
|
|
|
|
|
|
|
// Add redraw for all snapshot object due to potential use of pixels outside
|
|
|
|
// of the update area by filters.
|
|
|
|
// The side effect is that it also fix rendering of partial update of filter...
|
|
|
|
// As they are never partially updated anymore !
|
|
|
|
|
|
|
|
// FIXME: don't add redraw rect for snapshot with no filter applied on
|
|
|
|
// Also damage the filter object that use a snapshot.
|
2016-11-26 23:58:56 -08:00
|
|
|
if (!redraw_all)
|
2015-07-31 17:38:31 -07:00
|
|
|
{
|
2016-11-26 23:58:56 -08:00
|
|
|
for (i = 0; i < e->snapshot_objects.count; i++)
|
|
|
|
{
|
|
|
|
obj = (Evas_Object_Protected_Data *)eina_array_data_get(&e->snapshot_objects, i);
|
|
|
|
|
|
|
|
if (evas_object_is_visible(obj->object, obj))
|
|
|
|
e->engine.func->output_redraws_rect_add(e->engine.data.output,
|
|
|
|
obj->cur->geometry.x,
|
|
|
|
obj->cur->geometry.y,
|
|
|
|
obj->cur->geometry.w,
|
|
|
|
obj->cur->geometry.h);
|
|
|
|
}
|
2015-07-31 17:38:31 -07:00
|
|
|
}
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_phase4", eo_e, 0.0, NULL);
|
2011-12-26 15:10:27 -08:00
|
|
|
|
2003-04-17 05:05:00 -07:00
|
|
|
/* phase 5. add obscures */
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_phase5", eo_e, 0.0, NULL);
|
2008-10-21 09:31:05 -07:00
|
|
|
EINA_LIST_FOREACH(e->obscures, ll, r)
|
2016-11-25 17:47:34 -08:00
|
|
|
evas_render_update_del(e, r->x, r->y, r->w, r->h);
|
2016-11-14 18:22:14 -08:00
|
|
|
|
|
|
|
static int prepare = -1;
|
|
|
|
if (prepare == -1)
|
|
|
|
{
|
|
|
|
if (getenv("EVAS_PREPARE")) prepare = !!atoi(getenv("EVAS_PREPARE"));
|
|
|
|
else prepare = 1;
|
|
|
|
}
|
|
|
|
/* build obscure objects list of active objects that obscure as well
|
|
|
|
* as objects that may need data (image data loads, texture updates,
|
|
|
|
* pre-render buffers/fbo's etc.) that are not up to date yet */
|
2016-11-25 21:25:41 -08:00
|
|
|
for (i = 0; i < e->active_objects.len; i++)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2016-11-30 00:36:42 -08:00
|
|
|
Evas_Active_Entry *ent = eina_inarray_nth(&e->active_objects, i);
|
2016-11-25 21:25:41 -08:00
|
|
|
|
|
|
|
obj = ent->obj;
|
2012-10-08 18:58:41 -07:00
|
|
|
eo_obj = obj->object;
|
2016-11-26 23:58:56 -08:00
|
|
|
if (UNLIKELY(
|
|
|
|
(!obj->is_smart) &&
|
|
|
|
(!obj->clip.clipees) &&
|
|
|
|
(evas_object_is_opaque(eo_obj, obj) ||
|
2009-02-16 20:53:03 -08:00
|
|
|
((obj->func->has_opaque_rect) &&
|
2013-07-08 17:46:15 -07:00
|
|
|
(obj->func->has_opaque_rect(eo_obj, obj, obj->private_data)))) &&
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_is_visible(eo_obj, obj) &&
|
2016-11-26 23:58:56 -08:00
|
|
|
(!obj->mask->is_mask) && (!obj->clip.mask) &&
|
|
|
|
(!obj->delete_me)))
|
2013-05-02 00:47:16 -07:00
|
|
|
OBJ_ARRAY_PUSH(&e->obscuring_objects, obj);
|
2016-11-14 18:22:14 -08:00
|
|
|
if (prepare)
|
|
|
|
{
|
|
|
|
if (obj->func->render_prepare)
|
2016-11-16 19:28:52 -08:00
|
|
|
obj->func->render_prepare(eo_obj, obj, do_async);
|
2016-11-14 18:22:14 -08:00
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_phase5", eo_e, 0.0, NULL);
|
2011-10-02 20:28:52 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
/* save this list */
|
2011-05-20 23:23:33 -07:00
|
|
|
/* obscuring_objects_orig = obscuring_objects; */
|
|
|
|
/* obscuring_objects = NULL; */
|
2004-02-16 11:22:48 -08:00
|
|
|
/* phase 6. go thru each update rect and render objects in it*/
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_phase6", eo_e, 0.0, NULL);
|
2007-01-22 04:44:57 -08:00
|
|
|
if (do_draw)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2015-07-31 16:47:46 -07:00
|
|
|
Render_Updates *ru;
|
2015-04-15 03:05:59 -07:00
|
|
|
void *surface;
|
|
|
|
int ux, uy, uw, uh;
|
|
|
|
int cx, cy, cw, ch;
|
2011-05-20 23:23:33 -07:00
|
|
|
unsigned int offset = 0;
|
2013-04-26 11:01:44 -07:00
|
|
|
int fx = e->framespace.x;
|
|
|
|
int fy = e->framespace.y;
|
2015-05-09 11:02:13 -07:00
|
|
|
int j;
|
2015-04-15 03:05:59 -07:00
|
|
|
Eina_Bool haveup = EINA_FALSE;
|
2008-06-04 09:42:39 -07:00
|
|
|
|
2015-07-07 05:29:31 -07:00
|
|
|
if (do_async) _evas_render_busy_begin();
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_surface", eo_e, 0.0, NULL);
|
2011-05-20 23:23:33 -07:00
|
|
|
while ((surface =
|
|
|
|
e->engine.func->output_redraws_next_update_get
|
2010-09-24 23:19:30 -07:00
|
|
|
(e->engine.data.output,
|
2011-05-20 23:23:33 -07:00
|
|
|
&ux, &uy, &uw, &uh,
|
|
|
|
&cx, &cy, &cw, &ch)))
|
|
|
|
{
|
2012-05-16 06:21:37 -07:00
|
|
|
haveup = EINA_TRUE;
|
2014-11-12 17:47:29 -08:00
|
|
|
|
2015-05-09 11:02:13 -07:00
|
|
|
/* phase 6.1 render every snapshot that needs to be updated
|
|
|
|
for this part of the screen */
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+render_snapshots", eo_e, 0.0, NULL);
|
2015-05-09 11:02:13 -07:00
|
|
|
for (j = e->snapshot_objects.count - 1; j >= 0; j--)
|
|
|
|
{
|
|
|
|
Eina_Rectangle output, cr, ur;
|
|
|
|
|
|
|
|
obj = (Evas_Object_Protected_Data *)eina_array_data_get(&e->snapshot_objects, j);
|
|
|
|
|
|
|
|
EINA_RECTANGLE_SET(&output,
|
|
|
|
obj->cur->geometry.x,
|
|
|
|
obj->cur->geometry.y,
|
|
|
|
obj->cur->geometry.w,
|
|
|
|
obj->cur->geometry.h);
|
|
|
|
EINA_RECTANGLE_SET(&ur, ux, uy, uw, uh);
|
|
|
|
|
|
|
|
if (eina_rectangle_intersection(&ur, &output))
|
|
|
|
{
|
2015-07-31 16:32:24 -07:00
|
|
|
void *ctx;
|
2015-05-09 11:02:13 -07:00
|
|
|
void *pseudo_canvas;
|
|
|
|
unsigned int restore_offset = offset;
|
|
|
|
|
|
|
|
EINA_RECTANGLE_SET(&cr,
|
|
|
|
ur.x - output.x, ur.y - output.y,
|
|
|
|
ur.w, ur.h);
|
|
|
|
|
|
|
|
pseudo_canvas = _evas_object_image_surface_get(obj->object, obj);
|
|
|
|
|
2015-10-07 18:56:35 -07:00
|
|
|
RD(0, " SNAPSHOT [obj:%p sfc:%p ur:%d,%d %dx%d]\n", obj, pseudo_canvas, ur.x, ur.y, ur.w, ur.h);
|
2015-07-31 16:32:24 -07:00
|
|
|
ctx = e->engine.func->context_new(e->engine.data.output);
|
|
|
|
clean_them |= evas_render_updates_internal_loop(eo_e, e, pseudo_canvas, ctx,
|
2015-05-09 11:02:13 -07:00
|
|
|
obj,
|
|
|
|
ur.x, ur.y, ur.w, ur.h,
|
|
|
|
cr.x, cr.y, cr.w, cr.h,
|
|
|
|
fx, fy, alpha,
|
2015-07-31 16:47:46 -07:00
|
|
|
do_async,
|
2015-10-07 18:56:35 -07:00
|
|
|
&offset, 1);
|
2015-07-31 16:32:24 -07:00
|
|
|
e->engine.func->context_free(e->engine.data.output, ctx);
|
2015-05-09 11:02:13 -07:00
|
|
|
|
2015-06-30 01:14:23 -07:00
|
|
|
// Force the object has changed for filter to take it into
|
|
|
|
// account. It won't be in the pending object array.
|
|
|
|
obj->changed = EINA_TRUE;
|
|
|
|
|
2015-05-09 11:02:13 -07:00
|
|
|
offset = restore_offset;
|
|
|
|
}
|
|
|
|
}
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_snapshots", eo_e, 0.0, NULL);
|
2015-05-09 11:02:13 -07:00
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+render_update", eo_e, 0.0, NULL);
|
2015-05-09 11:02:13 -07:00
|
|
|
/* phase 6.2 render all the object on the target surface */
|
2016-03-31 16:52:38 -07:00
|
|
|
if ((do_async) || (make_updates))
|
2015-07-31 16:47:46 -07:00
|
|
|
{
|
|
|
|
ru = malloc(sizeof(*ru));
|
|
|
|
ru->surface = surface;
|
2016-07-02 23:43:04 -07:00
|
|
|
//XXX: need a way of reffing output surfaces
|
2015-07-31 16:47:46 -07:00
|
|
|
NEW_RECT(ru->area, ux, uy, uw, uh);
|
2015-09-27 10:56:28 -07:00
|
|
|
eina_spinlock_take(&(e->render.lock));
|
2015-07-31 16:47:46 -07:00
|
|
|
e->render.updates = eina_list_append(e->render.updates, ru);
|
2015-09-27 10:56:28 -07:00
|
|
|
eina_spinlock_release(&(e->render.lock));
|
2015-07-31 16:47:46 -07:00
|
|
|
}
|
|
|
|
|
2015-07-31 16:32:24 -07:00
|
|
|
clean_them |= evas_render_updates_internal_loop(eo_e, e, surface, e->engine.data.context,
|
2015-05-09 11:02:13 -07:00
|
|
|
NULL,
|
2012-12-19 08:15:58 -08:00
|
|
|
ux, uy, uw, uh,
|
2015-04-15 03:05:59 -07:00
|
|
|
cx, cy, cw, ch,
|
|
|
|
fx, fy, alpha,
|
2015-07-31 16:47:46 -07:00
|
|
|
do_async,
|
2015-10-07 18:56:35 -07:00
|
|
|
&offset, 0);
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_update", eo_e, 0.0, NULL);
|
2015-09-15 02:26:35 -07:00
|
|
|
if (!do_async)
|
|
|
|
{
|
|
|
|
eina_evlog("+render_push", eo_e, 0.0, NULL);
|
|
|
|
e->engine.func->output_redraws_next_update_push(e->engine.data.output,
|
|
|
|
surface,
|
|
|
|
ux, uy, uw, uh,
|
|
|
|
render_mode);
|
|
|
|
eina_evlog("-render_push", eo_e, 0.0, NULL);
|
|
|
|
}
|
2011-05-20 23:23:33 -07:00
|
|
|
}
|
2012-12-18 08:26:44 -08:00
|
|
|
|
2016-11-16 11:30:16 -08:00
|
|
|
if (haveup)
|
2010-03-16 05:30:55 -07:00
|
|
|
{
|
2016-11-16 11:30:16 -08:00
|
|
|
if (do_async)
|
|
|
|
{
|
|
|
|
eina_evlog("+render_output_async_flush", eo_e, 0.0, NULL);
|
|
|
|
efl_ref(eo_e);
|
|
|
|
e->rendering = EINA_TRUE;
|
|
|
|
_rendering_evases = eina_list_append(_rendering_evases, e);
|
|
|
|
_cb_always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_PRE, NULL);
|
|
|
|
evas_thread_queue_flush((Evas_Thread_Command_Cb)done_func, done_data);
|
|
|
|
eina_evlog("-render_output_async_flush", eo_e, 0.0, NULL);
|
|
|
|
}
|
|
|
|
else
|
2013-10-01 11:35:09 -07:00
|
|
|
{
|
2016-11-16 11:30:16 -08:00
|
|
|
eina_evlog("+render_output_flush", eo_e, 0.0, NULL);
|
|
|
|
EINA_LIST_FOREACH(e->video_objects, ll, eo_obj)
|
|
|
|
{
|
|
|
|
_evas_object_image_video_overlay_do(eo_obj);
|
|
|
|
}
|
|
|
|
_cb_always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_PRE, NULL);
|
|
|
|
e->engine.func->output_flush(e->engine.data.output,
|
|
|
|
EVAS_RENDER_MODE_SYNC);
|
|
|
|
_cb_always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_POST, NULL);
|
|
|
|
eina_evlog("-render_output_flush", eo_e, 0.0, NULL);
|
2013-10-01 11:35:09 -07:00
|
|
|
}
|
2010-03-16 05:30:55 -07:00
|
|
|
}
|
2016-11-16 11:30:16 -08:00
|
|
|
rendering = haveup;
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_surface", eo_e, 0.0, NULL);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_phase6", eo_e, 0.0, NULL);
|
2012-12-18 08:26:44 -08:00
|
|
|
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_clear", eo_e, 0.0, NULL);
|
2016-11-16 11:30:16 -08:00
|
|
|
if (!do_async && rendering)
|
2012-12-18 08:26:44 -08:00
|
|
|
{
|
|
|
|
/* clear redraws */
|
|
|
|
e->engine.func->output_redraws_clear(e->engine.data.output);
|
|
|
|
}
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_clear", eo_e, 0.0, NULL);
|
2012-12-18 08:26:44 -08:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
/* and do a post render pass */
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_post", eo_e, 0.0, NULL);
|
2016-11-25 21:25:41 -08:00
|
|
|
IFRD(e->active_objects.len, 0, " [--- POST RENDER\n");
|
|
|
|
for (i = 0; i < e->active_objects.len; i++)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2016-11-25 21:25:41 -08:00
|
|
|
Evas_Active_Entry *ent = eina_inarray_nth(&e->active_objects, i);
|
|
|
|
|
|
|
|
obj = ent->obj;
|
2012-10-08 18:58:41 -07:00
|
|
|
eo_obj = obj->object;
|
2012-05-16 06:21:37 -07:00
|
|
|
obj->pre_render_done = EINA_FALSE;
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, " OBJ [%p", obj);
|
2015-07-21 01:48:47 -07:00
|
|
|
IFRD(obj->name, 0, " '%s'", obj->name);
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, "] changed:%i do_draw:%i (%s)\n", obj->changed, do_draw, obj->type);
|
2012-10-19 05:00:57 -07:00
|
|
|
if ((clean_them) || (obj->changed && do_draw))
|
2009-11-06 00:44:49 -08:00
|
|
|
{
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, " OBJ [%p", obj);
|
2015-07-21 01:48:47 -07:00
|
|
|
IFRD(obj->name, 0, " '%s'", obj->name);
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, "] render_post()\n");
|
2013-07-08 17:46:15 -07:00
|
|
|
obj->func->render_post(eo_obj, obj, obj->private_data);
|
2012-05-16 06:21:37 -07:00
|
|
|
obj->restack = EINA_FALSE;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change_reset(eo_obj);
|
2009-11-06 00:44:49 -08:00
|
|
|
}
|
2011-05-20 23:23:33 -07:00
|
|
|
/* moved to other pre-process phase 1
|
|
|
|
if (obj->delete_me == 2)
|
|
|
|
{
|
|
|
|
delete_objects = eina_list_append(delete_objects, obj);
|
|
|
|
}
|
|
|
|
else if (obj->delete_me != 0) obj->delete_me++;
|
|
|
|
*/
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_post", eo_e, 0.0, NULL);
|
2016-11-25 21:25:41 -08:00
|
|
|
IFRD(e->active_objects.len, 0, " ---]\n");
|
2015-01-26 00:35:42 -08:00
|
|
|
|
2005-10-26 21:25:30 -07:00
|
|
|
/* free our obscuring object list */
|
2013-05-02 00:47:16 -07:00
|
|
|
OBJS_ARRAY_CLEAN(&e->obscuring_objects);
|
2008-06-04 09:42:39 -07:00
|
|
|
|
|
|
|
/* If some object are still marked as changed, do not remove
|
|
|
|
them from the pending list. */
|
2008-10-16 05:27:07 -07:00
|
|
|
eina_array_remove(&e->pending_objects, pending_change, NULL);
|
2008-06-04 09:42:39 -07:00
|
|
|
|
2013-12-02 23:23:05 -08:00
|
|
|
/* Reinsert parent of changed object in the pending changed state */
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+render_post_change", eo_e, 0.0, NULL);
|
2013-12-02 23:23:05 -08:00
|
|
|
for (i = 0; i < e->pending_objects.count; ++i)
|
|
|
|
{
|
|
|
|
obj = eina_array_data_get(&e->pending_objects, i);
|
|
|
|
if (obj->smart.parent)
|
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *smart_parent;
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
smart_parent = efl_data_scope_get(obj->smart.parent,
|
2016-06-20 21:26:15 -07:00
|
|
|
EFL_CANVAS_OBJECT_CLASS);
|
2013-12-02 23:23:05 -08:00
|
|
|
evas_object_change(obj->smart.parent, smart_parent);
|
|
|
|
}
|
|
|
|
}
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_post_change", eo_e, 0.0, NULL);
|
2013-12-02 23:23:05 -08:00
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+render_post_reset", eo_e, 0.0, NULL);
|
2011-06-13 00:34:44 -07:00
|
|
|
for (i = 0; i < e->render_objects.count; ++i)
|
|
|
|
{
|
|
|
|
obj = eina_array_data_get(&e->render_objects, i);
|
2012-10-08 18:58:41 -07:00
|
|
|
eo_obj = obj->object;
|
2012-05-16 06:21:37 -07:00
|
|
|
obj->pre_render_done = EINA_FALSE;
|
2012-09-12 11:36:08 -07:00
|
|
|
if ((obj->changed) && (do_draw))
|
|
|
|
{
|
2013-12-02 23:23:05 -08:00
|
|
|
obj->func->render_post(eo_obj, obj, obj->private_data);
|
2012-09-12 11:36:08 -07:00
|
|
|
obj->restack = EINA_FALSE;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change_reset(eo_obj);
|
2012-09-12 11:36:08 -07:00
|
|
|
}
|
2011-06-13 00:34:44 -07:00
|
|
|
}
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_post_reset", eo_e, 0.0, NULL);
|
2011-06-13 00:34:44 -07:00
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+render_end", eo_e, 0.0, NULL);
|
2012-05-16 06:21:37 -07:00
|
|
|
e->changed = EINA_FALSE;
|
|
|
|
e->viewport.changed = EINA_FALSE;
|
|
|
|
e->output.changed = EINA_FALSE;
|
|
|
|
e->framespace.changed = EINA_FALSE;
|
|
|
|
e->invalidate = EINA_FALSE;
|
2008-06-04 09:42:39 -07:00
|
|
|
|
2012-03-20 01:08:42 -07:00
|
|
|
// always clean... lots of mem waste!
|
2010-04-27 06:43:10 -07:00
|
|
|
/* If their are some object to restack or some object to delete,
|
2009-11-09 07:18:37 -08:00
|
|
|
* it's useless to keep the render object list around. */
|
2010-05-05 04:36:21 -07:00
|
|
|
if (clean_them)
|
2008-06-04 09:42:39 -07:00
|
|
|
{
|
2016-11-25 21:25:41 -08:00
|
|
|
eina_inarray_flush(&e->active_objects);
|
2013-05-02 00:47:16 -07:00
|
|
|
OBJS_ARRAY_CLEAN(&e->render_objects);
|
|
|
|
OBJS_ARRAY_CLEAN(&e->restack_objects);
|
|
|
|
OBJS_ARRAY_CLEAN(&e->temporary_objects);
|
2015-05-09 11:02:13 -07:00
|
|
|
OBJS_ARRAY_CLEAN(&e->snapshot_objects);
|
2012-11-20 03:52:16 -08:00
|
|
|
eina_array_foreach(&e->clip_changes, _evas_clip_changes_free, NULL);
|
2012-03-20 01:08:42 -07:00
|
|
|
eina_array_clean(&e->clip_changes);
|
2016-11-21 21:33:48 -08:00
|
|
|
/* we should flush here and have a mempool system for this
|
2016-11-25 21:25:41 -08:00
|
|
|
eina_inarray_flush(&e->active_objects);
|
2012-03-20 01:08:42 -07:00
|
|
|
eina_array_flush(&e->render_objects);
|
|
|
|
eina_array_flush(&e->restack_objects);
|
|
|
|
eina_array_flush(&e->delete_objects);
|
|
|
|
eina_array_flush(&e->obscuring_objects);
|
|
|
|
eina_array_flush(&e->temporary_objects);
|
|
|
|
eina_array_flush(&e->clip_changes);
|
|
|
|
*/
|
2012-05-16 06:21:37 -07:00
|
|
|
e->invalidate = EINA_TRUE;
|
2008-06-04 09:42:39 -07:00
|
|
|
}
|
2008-04-14 02:31:31 -07:00
|
|
|
|
2013-05-02 00:48:43 -07:00
|
|
|
/* delete all objects flagged for deletion now */
|
|
|
|
for (i = 0; i < e->delete_objects.count; ++i)
|
|
|
|
{
|
|
|
|
obj = eina_array_data_get(&e->delete_objects, i);
|
2014-01-27 08:54:25 -08:00
|
|
|
evas_object_free(obj->object, 1);
|
2013-05-02 00:48:43 -07:00
|
|
|
}
|
|
|
|
eina_array_clean(&e->delete_objects);
|
|
|
|
/* if we deleted no objects this frame or we deleted a lot (> 1024) then
|
|
|
|
* try and reset the deleted objects array to empty (no mem used) for
|
|
|
|
* efficiency */
|
|
|
|
if ((e->delete_objects.count == 0) || (e->delete_objects.count > 1024))
|
|
|
|
eina_array_flush(&e->delete_objects);
|
2016-11-21 21:33:48 -08:00
|
|
|
|
2006-09-18 02:40:29 -07:00
|
|
|
evas_module_clean();
|
2012-05-16 06:21:37 -07:00
|
|
|
|
2012-12-18 08:26:44 -08:00
|
|
|
if (!do_async)
|
2013-03-20 02:53:26 -07:00
|
|
|
{
|
|
|
|
Evas_Event_Render_Post post;
|
2016-03-31 16:52:38 -07:00
|
|
|
Eina_List *l;
|
|
|
|
Render_Updates *ru;
|
2013-03-20 02:53:26 -07:00
|
|
|
|
2016-03-31 16:52:38 -07:00
|
|
|
post.updated_area = NULL;
|
|
|
|
EINA_LIST_FOREACH(e->render.updates, l, ru)
|
|
|
|
{
|
|
|
|
post.updated_area = eina_list_append(post.updated_area, ru->area);
|
2016-07-02 23:43:04 -07:00
|
|
|
//XXX: need a way of unreffing output surfaces
|
2016-06-03 03:08:40 -07:00
|
|
|
ru->surface = NULL;
|
2016-03-31 16:52:38 -07:00
|
|
|
}
|
2015-09-27 10:56:28 -07:00
|
|
|
eina_spinlock_take(&(e->render.lock));
|
2016-03-31 16:52:38 -07:00
|
|
|
_cb_always_call(eo_e, EVAS_CALLBACK_RENDER_POST, post.updated_area ? &post : NULL);
|
2015-09-27 10:56:28 -07:00
|
|
|
eina_spinlock_release(&(e->render.lock));
|
2016-03-31 16:52:38 -07:00
|
|
|
if (post.updated_area) eina_list_free(post.updated_area);
|
2013-03-20 02:53:26 -07:00
|
|
|
}
|
2008-04-14 02:31:31 -07:00
|
|
|
|
2015-01-26 00:35:42 -08:00
|
|
|
RD(0, "---]\n");
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2013-01-17 06:31:34 -08:00
|
|
|
#ifdef EVAS_RENDER_DEBUG_TIMING
|
2015-04-03 07:34:15 -07:00
|
|
|
_accumulate_time(start_time, do_async);
|
2013-01-17 06:31:34 -08:00
|
|
|
#endif
|
|
|
|
|
2015-07-07 05:29:31 -07:00
|
|
|
if (!do_async) _evas_render_cleanup();
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_end", eo_e, 0.0, NULL);
|
2016-11-15 15:54:29 -08:00
|
|
|
return rendering;
|
2012-12-18 08:26:44 -08:00
|
|
|
}
|
|
|
|
|
2013-01-11 11:55:40 -08:00
|
|
|
static Eina_Bool
|
|
|
|
_drop_glyph_ref(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
|
|
|
|
{
|
|
|
|
evas_common_font_glyphs_unref(data);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2013-01-15 09:35:11 -08:00
|
|
|
static Eina_Bool
|
|
|
|
_drop_texts_ref(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
|
|
|
|
{
|
|
|
|
evas_common_font_fonts_unref(data);
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2012-12-18 08:26:44 -08:00
|
|
|
static void
|
|
|
|
evas_render_wakeup(Evas *eo_e)
|
|
|
|
{
|
2013-03-20 02:53:26 -07:00
|
|
|
Evas_Event_Render_Post post;
|
2012-12-18 08:26:44 -08:00
|
|
|
Render_Updates *ru;
|
|
|
|
Eina_Bool haveup = EINA_FALSE;
|
|
|
|
Eina_List *ret_updates = NULL;
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2012-12-18 08:26:44 -08:00
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+render_wakeup", eo_e, 0.0, NULL);
|
2015-09-27 10:56:28 -07:00
|
|
|
eina_spinlock_take(&(e->render.lock));
|
2012-12-18 08:26:44 -08:00
|
|
|
EINA_LIST_FREE(e->render.updates, ru)
|
|
|
|
{
|
2013-03-20 02:53:26 -07:00
|
|
|
ret_updates = eina_list_append(ret_updates, ru->area);
|
2012-12-18 08:26:44 -08:00
|
|
|
free(ru);
|
|
|
|
haveup = EINA_TRUE;
|
|
|
|
}
|
2015-09-27 10:56:28 -07:00
|
|
|
eina_spinlock_release(&(e->render.lock));
|
2012-12-18 08:26:44 -08:00
|
|
|
|
|
|
|
/* flush redraws */
|
|
|
|
if (haveup)
|
|
|
|
{
|
2013-10-01 11:35:09 -07:00
|
|
|
Eina_List *ll;
|
|
|
|
Evas_Object *eo_obj;
|
|
|
|
EINA_LIST_FOREACH(e->video_objects, ll, eo_obj)
|
|
|
|
{
|
|
|
|
_evas_object_image_video_overlay_do(eo_obj);
|
|
|
|
}
|
2013-11-30 20:26:04 -08:00
|
|
|
_cb_always_call(eo_e, EVAS_CALLBACK_RENDER_FLUSH_POST, NULL);
|
2012-12-18 08:26:44 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* clear redraws */
|
|
|
|
e->engine.func->output_redraws_clear(e->engine.data.output);
|
|
|
|
|
2013-01-11 11:55:40 -08:00
|
|
|
/* unref queues */
|
2013-01-17 14:14:05 -08:00
|
|
|
eina_array_foreach(&e->scie_unref_queue, _drop_scie_ref, NULL);
|
|
|
|
eina_array_clean(&e->scie_unref_queue);
|
|
|
|
evas_common_rgba_image_scalecache_prune();
|
|
|
|
|
2013-01-11 11:54:12 -08:00
|
|
|
eina_array_foreach(&e->image_unref_queue, _drop_image_cache_ref, NULL);
|
|
|
|
eina_array_clean(&e->image_unref_queue);
|
2013-01-16 14:32:39 -08:00
|
|
|
|
2013-01-11 11:55:40 -08:00
|
|
|
eina_array_foreach(&e->glyph_unref_queue, _drop_glyph_ref, NULL);
|
|
|
|
eina_array_clean(&e->glyph_unref_queue);
|
2013-01-16 14:32:39 -08:00
|
|
|
|
2013-01-15 09:35:11 -08:00
|
|
|
eina_array_foreach(&e->texts_unref_queue, _drop_texts_ref, NULL);
|
|
|
|
eina_array_clean(&e->texts_unref_queue);
|
2013-01-11 11:54:12 -08:00
|
|
|
|
2013-01-17 14:14:05 -08:00
|
|
|
/* post rendering */
|
2013-09-02 21:48:08 -07:00
|
|
|
_rendering_evases = eina_list_remove(_rendering_evases, e);
|
2013-01-14 12:02:43 -08:00
|
|
|
e->rendering = EINA_FALSE;
|
|
|
|
|
2013-03-20 02:53:26 -07:00
|
|
|
post.updated_area = ret_updates;
|
2013-11-30 20:26:04 -08:00
|
|
|
_cb_always_call(eo_e, EVAS_CALLBACK_RENDER_POST, &post);
|
2013-01-14 12:02:43 -08:00
|
|
|
|
2013-03-25 19:48:23 -07:00
|
|
|
evas_render_updates_free(ret_updates);
|
2012-12-18 08:26:44 -08:00
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_wakeup", eo_e, 0.0, NULL);
|
2016-08-15 06:44:41 -07:00
|
|
|
efl_unref(eo_e);
|
2015-04-03 07:34:15 -07:00
|
|
|
|
|
|
|
#ifdef EVAS_RENDER_DEBUG_TIMING
|
|
|
|
_accumulate_time(0, EINA_TRUE);
|
|
|
|
#endif
|
2012-12-18 08:26:44 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_render_async_wakeup(void *target, Evas_Callback_Type type EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Evas_Public_Data *e = target;
|
|
|
|
evas_render_wakeup(e->evas);
|
2015-07-07 05:29:31 -07:00
|
|
|
_evas_render_busy_end();
|
2012-12-18 08:26:44 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_render_pipe_wakeup(void *data)
|
|
|
|
{
|
2015-09-15 02:26:35 -07:00
|
|
|
Eina_List *l;
|
|
|
|
Render_Updates *ru;
|
|
|
|
Evas_Public_Data *e = data;
|
|
|
|
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+render_pipe_wakeup", e->evas, 0.0, NULL);
|
2015-09-27 10:56:28 -07:00
|
|
|
eina_spinlock_take(&(e->render.lock));
|
2015-09-15 02:26:35 -07:00
|
|
|
EINA_LIST_FOREACH(e->render.updates, l, ru)
|
|
|
|
{
|
|
|
|
eina_evlog("+render_push", e->evas, 0.0, NULL);
|
|
|
|
e->engine.func->output_redraws_next_update_push
|
|
|
|
(e->engine.data.output, ru->surface,
|
|
|
|
ru->area->x, ru->area->y, ru->area->w, ru->area->h,
|
|
|
|
EVAS_RENDER_MODE_ASYNC_END);
|
|
|
|
eina_evlog("-render_push", e->evas, 0.0, NULL);
|
2016-07-02 23:43:04 -07:00
|
|
|
//XXX: need a way to unref render output surfaces
|
2015-09-15 02:26:35 -07:00
|
|
|
ru->surface = NULL;
|
|
|
|
}
|
|
|
|
eina_evlog("+render_output_flush", e->evas, 0.0, NULL);
|
2015-09-27 10:56:28 -07:00
|
|
|
eina_spinlock_release(&(e->render.lock));
|
2015-09-15 02:26:35 -07:00
|
|
|
e->engine.func->output_flush(e->engine.data.output,
|
|
|
|
EVAS_RENDER_MODE_ASYNC_END);
|
2015-10-13 04:34:31 -07:00
|
|
|
eina_evlog("-render_output_flush", e->evas, 0.0, NULL);
|
2012-12-18 08:26:44 -08:00
|
|
|
evas_async_events_put(data, 0, NULL, evas_render_async_wakeup);
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-render_pipe_wakeup", e->evas, 0.0, NULL);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-01-06 15:05:17 -08:00
|
|
|
EAPI void
|
2008-10-21 09:31:05 -07:00
|
|
|
evas_render_updates_free(Eina_List *updates)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2009-06-23 06:57:27 -07:00
|
|
|
Eina_Rectangle *r;
|
2009-04-14 05:15:07 -07:00
|
|
|
|
|
|
|
EINA_LIST_FREE(updates, r)
|
2011-05-20 23:23:33 -07:00
|
|
|
eina_rectangle_free(r);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN Eina_Bool
|
2015-03-19 22:18:17 -07:00
|
|
|
_evas_canvas_render2(Eo *eo_e, Evas_Public_Data *e)
|
2012-12-18 08:26:44 -08:00
|
|
|
{
|
2015-05-14 01:35:22 -07:00
|
|
|
Eina_Bool ret;
|
|
|
|
|
|
|
|
eina_evlog("+render2", eo_e, 0.0, NULL);
|
|
|
|
ret = _evas_render2(eo_e, e);
|
|
|
|
eina_evlog("-render2", eo_e, 0.0, NULL);
|
|
|
|
return ret;
|
2015-03-19 22:18:17 -07:00
|
|
|
}
|
2012-12-18 08:26:44 -08:00
|
|
|
|
2015-06-02 04:39:57 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-03-19 22:18:17 -07:00
|
|
|
EOLIAN Eina_Bool
|
|
|
|
_evas_canvas_render_async(Eo *eo_e, Evas_Public_Data *e)
|
|
|
|
{
|
2015-05-14 01:35:22 -07:00
|
|
|
Eina_Bool ret;
|
|
|
|
eina_evlog("+render_block", eo_e, 0.0, NULL);
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_canvas_async_block(e);
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_block", eo_e, 0.0, NULL);
|
|
|
|
eina_evlog("+render", eo_e, 0.0, NULL);
|
|
|
|
ret = evas_render_updates_internal(eo_e, 1, 1, evas_render_pipe_wakeup,
|
|
|
|
e, EINA_TRUE);
|
|
|
|
eina_evlog("-render", eo_e, 0.0, NULL);
|
|
|
|
return ret;
|
2012-12-18 08:26:44 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_List *
|
|
|
|
evas_render_updates_internal_wait(Evas *eo_e,
|
|
|
|
unsigned char make_updates,
|
|
|
|
unsigned char do_draw)
|
|
|
|
{
|
|
|
|
Eina_List *ret = NULL;
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2015-03-19 22:18:17 -07:00
|
|
|
if (e->render2) return _evas_render2_updates_wait(eo_e, e);
|
2013-12-19 05:49:16 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!evas_render_updates_internal(eo_e, make_updates, do_draw, NULL,
|
|
|
|
NULL, EINA_FALSE))
|
|
|
|
return NULL;
|
|
|
|
}
|
2012-12-18 08:26:44 -08:00
|
|
|
|
2015-09-27 10:56:28 -07:00
|
|
|
eina_spinlock_take(&(e->render.lock));
|
2012-12-18 08:26:44 -08:00
|
|
|
ret = e->render.updates;
|
|
|
|
e->render.updates = NULL;
|
2015-09-27 10:56:28 -07:00
|
|
|
eina_spinlock_release(&(e->render.lock));
|
2012-12-18 08:26:44 -08:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2015-02-10 03:44:38 -08:00
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN Eina_List*
|
2014-06-26 14:29:46 -07:00
|
|
|
_evas_canvas_render_updates(Eo *eo_e, Evas_Public_Data *e)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-03-31 16:52:38 -07:00
|
|
|
Eina_List *ret, *updates = NULL;
|
|
|
|
Render_Updates *ru;
|
2014-03-11 23:53:00 -07:00
|
|
|
if (!e->changed) return NULL;
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_block", eo_e, 0.0, NULL);
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_canvas_async_block(e);
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_block", eo_e, 0.0, NULL);
|
|
|
|
eina_evlog("+render", eo_e, 0.0, NULL);
|
|
|
|
ret = evas_render_updates_internal_wait(eo_e, 1, 1);
|
|
|
|
eina_evlog("-render", eo_e, 0.0, NULL);
|
2016-03-31 16:52:38 -07:00
|
|
|
EINA_LIST_FREE(ret, ru)
|
|
|
|
{
|
|
|
|
updates = eina_list_append(updates, ru->area);
|
|
|
|
free(ru);
|
|
|
|
}
|
|
|
|
return updates;
|
2005-12-03 01:27:53 -08:00
|
|
|
}
|
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN void
|
2014-06-26 14:29:46 -07:00
|
|
|
_evas_canvas_render(Eo *eo_e, Evas_Public_Data *e)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-03-31 16:52:38 -07:00
|
|
|
Eina_List *ret;
|
|
|
|
Render_Updates *ru;
|
2006-09-18 02:40:29 -07:00
|
|
|
if (!e->changed) return;
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_block", eo_e, 0.0, NULL);
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_canvas_async_block(e);
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_block", eo_e, 0.0, NULL);
|
|
|
|
eina_evlog("+render", eo_e, 0.0, NULL);
|
2016-03-31 16:52:38 -07:00
|
|
|
ret = evas_render_updates_internal_wait(eo_e, 0, 1);
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render", eo_e, 0.0, NULL);
|
2016-03-31 16:52:38 -07:00
|
|
|
EINA_LIST_FREE(ret, ru)
|
|
|
|
{
|
|
|
|
eina_rectangle_free(ru->area);
|
|
|
|
free(ru);
|
|
|
|
}
|
2007-01-16 02:17:10 -08:00
|
|
|
}
|
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN void
|
2015-02-10 03:44:38 -08:00
|
|
|
_evas_canvas_norender(Eo *eo_e, Evas_Public_Data *e)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2015-03-19 22:18:17 -07:00
|
|
|
if (e->render2) _evas_norender2(eo_e, e);
|
|
|
|
else
|
|
|
|
{
|
2016-03-31 16:52:38 -07:00
|
|
|
Eina_List *ret;
|
|
|
|
Render_Updates *ru;
|
|
|
|
|
2015-03-19 22:18:17 -07:00
|
|
|
evas_canvas_async_block(e);
|
|
|
|
// if (!e->changed) return;
|
2016-03-31 16:52:38 -07:00
|
|
|
ret = evas_render_updates_internal_wait(eo_e, 0, 1);
|
|
|
|
EINA_LIST_FREE(ret, ru)
|
|
|
|
{
|
|
|
|
eina_rectangle_free(ru->area);
|
|
|
|
free(ru);
|
|
|
|
}
|
2015-03-19 22:18:17 -07:00
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2007-01-16 02:17:10 -08:00
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN void
|
2014-06-26 14:29:46 -07:00
|
|
|
_evas_canvas_render_idle_flush(Eo *eo_e, Evas_Public_Data *e)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("+idle_flush", eo_e, 0.0, NULL);
|
2015-03-19 22:18:17 -07:00
|
|
|
if (e->render2) _evas_render2_idle_flush(eo_e, e);
|
2013-12-19 05:49:16 -08:00
|
|
|
else
|
|
|
|
{
|
2015-03-19 22:18:17 -07:00
|
|
|
evas_canvas_async_block(e);
|
2013-12-19 05:49:16 -08:00
|
|
|
|
|
|
|
evas_render_rendering_wait(e);
|
2015-03-19 22:18:17 -07:00
|
|
|
|
2013-12-19 05:49:16 -08:00
|
|
|
evas_fonts_zero_pressure(eo_e);
|
2015-03-19 22:18:17 -07:00
|
|
|
|
2013-12-19 05:49:16 -08:00
|
|
|
if ((e->engine.func) && (e->engine.func->output_idle_flush) &&
|
|
|
|
(e->engine.data.output))
|
|
|
|
e->engine.func->output_idle_flush(e->engine.data.output);
|
2015-03-19 22:18:17 -07:00
|
|
|
|
2016-11-25 21:25:41 -08:00
|
|
|
eina_inarray_flush(&e->active_objects);
|
2013-12-19 05:49:16 -08:00
|
|
|
OBJS_ARRAY_FLUSH(&e->render_objects);
|
|
|
|
OBJS_ARRAY_FLUSH(&e->restack_objects);
|
|
|
|
OBJS_ARRAY_FLUSH(&e->delete_objects);
|
|
|
|
OBJS_ARRAY_FLUSH(&e->obscuring_objects);
|
|
|
|
OBJS_ARRAY_FLUSH(&e->temporary_objects);
|
|
|
|
eina_array_foreach(&e->clip_changes, _evas_clip_changes_free, NULL);
|
|
|
|
eina_array_clean(&e->clip_changes);
|
2015-03-19 22:18:17 -07:00
|
|
|
|
2013-12-19 05:49:16 -08:00
|
|
|
e->invalidate = EINA_TRUE;
|
|
|
|
}
|
2016-11-06 18:26:22 -08:00
|
|
|
eina_evlog("-idle_flush", eo_e, 0.0, NULL);
|
2007-06-16 19:56:59 -07:00
|
|
|
}
|
2008-05-26 06:24:24 -07:00
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN void
|
2014-06-26 14:29:46 -07:00
|
|
|
_evas_canvas_sync(Eo *eo_e, Evas_Public_Data *e)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("+render_sync", eo_e, 0.0, NULL);
|
2015-03-19 22:18:17 -07:00
|
|
|
if (e->render2) _evas_render2_sync(eo_e, e);
|
|
|
|
else
|
2013-12-19 05:49:16 -08:00
|
|
|
{
|
2015-03-19 22:18:17 -07:00
|
|
|
evas_canvas_async_block(e);
|
|
|
|
evas_render_rendering_wait(e);
|
2013-12-19 05:49:16 -08:00
|
|
|
}
|
2015-05-14 01:35:22 -07:00
|
|
|
eina_evlog("-render_sync", eo_e, 0.0, NULL);
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_evas_render_dump_map_surfaces(Evas_Object *eo_obj)
|
2010-04-12 01:23:53 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2013-01-21 19:56:00 -08:00
|
|
|
if ((obj->map->cur.map) && obj->map->surface)
|
2010-04-12 01:23:53 -07:00
|
|
|
{
|
2015-07-01 20:04:02 -07:00
|
|
|
obj->layer->evas->engine.func->image_free
|
2013-01-21 19:56:00 -08:00
|
|
|
(obj->layer->evas->engine.data.output, obj->map->surface);
|
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write)
|
|
|
|
map_write->surface = NULL;
|
|
|
|
EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write);
|
2010-04-12 01:23:53 -07:00
|
|
|
}
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
if (obj->is_smart)
|
2010-04-12 01:23:53 -07:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj2;
|
2010-04-27 06:43:10 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(eo_obj), obj2)
|
|
|
|
_evas_render_dump_map_surfaces(obj2->object);
|
2010-04-12 01:23:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN void
|
2015-03-19 22:18:17 -07:00
|
|
|
_evas_canvas_render_dump(Eo *eo_e, Evas_Public_Data *e)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2015-03-19 22:18:17 -07:00
|
|
|
if (e->render2) _evas_render2_dump(eo_e, e);
|
2013-12-19 05:49:16 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
Evas_Layer *lay;
|
2015-03-19 22:18:17 -07:00
|
|
|
|
|
|
|
evas_canvas_async_block(e);
|
|
|
|
|
2013-12-19 05:49:16 -08:00
|
|
|
evas_all_sync();
|
|
|
|
evas_cache_async_freeze();
|
2015-03-19 22:18:17 -07:00
|
|
|
|
2013-12-19 05:49:16 -08:00
|
|
|
EINA_INLIST_FOREACH(e->layers, lay)
|
2010-12-24 08:04:27 -08:00
|
|
|
{
|
2013-12-19 05:49:16 -08:00
|
|
|
Evas_Object_Protected_Data *obj;
|
2015-03-19 22:18:17 -07:00
|
|
|
|
2016-07-18 23:42:10 -07:00
|
|
|
lay->walking_objects++;
|
2013-12-19 05:49:16 -08:00
|
|
|
EINA_INLIST_FOREACH(lay->objects, obj)
|
2013-09-02 05:07:37 -07:00
|
|
|
{
|
2015-04-26 23:56:54 -07:00
|
|
|
if (obj->proxy->surface)
|
2013-09-02 05:07:37 -07:00
|
|
|
{
|
2013-12-19 05:49:16 -08:00
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy, Evas_Object_Proxy_Data, proxy_write)
|
2013-09-02 05:07:37 -07:00
|
|
|
{
|
2015-07-01 20:04:02 -07:00
|
|
|
e->engine.func->image_free(e->engine.data.output, proxy_write->surface);
|
2015-04-26 23:56:54 -07:00
|
|
|
proxy_write->surface = NULL;
|
2013-09-02 05:07:37 -07:00
|
|
|
}
|
2013-12-19 05:49:16 -08:00
|
|
|
EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, proxy_write);
|
2013-09-02 05:07:37 -07:00
|
|
|
}
|
2015-04-26 23:56:54 -07:00
|
|
|
if (obj->mask->surface)
|
|
|
|
{
|
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_mask_cow, obj->mask, Evas_Object_Mask_Data, mdata)
|
|
|
|
{
|
2015-07-01 20:04:02 -07:00
|
|
|
e->engine.func->image_free(e->engine.data.output, mdata->surface);
|
2015-04-26 23:56:54 -07:00
|
|
|
mdata->surface = NULL;
|
|
|
|
}
|
|
|
|
EINA_COW_WRITE_END(evas_object_mask_cow, obj->mask, mdata);
|
|
|
|
}
|
2013-12-19 05:49:16 -08:00
|
|
|
if ((obj->type) && (!strcmp(obj->type, "image")))
|
|
|
|
evas_object_inform_call_image_unloaded(obj->object);
|
|
|
|
_evas_render_dump_map_surfaces(obj->object);
|
2013-09-02 05:07:37 -07:00
|
|
|
}
|
2016-07-18 23:42:10 -07:00
|
|
|
lay->walking_objects--;
|
|
|
|
_evas_layer_flush_removes(lay);
|
2010-12-24 08:04:27 -08:00
|
|
|
}
|
2013-12-19 05:49:16 -08:00
|
|
|
if ((e->engine.func) && (e->engine.func->output_dump) &&
|
|
|
|
(e->engine.data.output))
|
|
|
|
e->engine.func->output_dump(e->engine.data.output);
|
2013-04-01 02:39:50 -07:00
|
|
|
|
2013-12-19 05:49:16 -08:00
|
|
|
#define GC_ALL(Cow) \
|
2014-05-19 06:42:36 -07:00
|
|
|
if (Cow) while (eina_cow_gc(Cow))
|
2013-12-19 05:49:16 -08:00
|
|
|
GC_ALL(evas_object_proxy_cow);
|
|
|
|
GC_ALL(evas_object_map_cow);
|
|
|
|
GC_ALL(evas_object_image_pixels_cow);
|
|
|
|
GC_ALL(evas_object_image_load_opts_cow);
|
|
|
|
GC_ALL(evas_object_image_state_cow);
|
2015-03-19 22:18:17 -07:00
|
|
|
|
2013-12-19 05:49:16 -08:00
|
|
|
evas_fonts_zero_pressure(eo_e);
|
2015-03-19 22:18:17 -07:00
|
|
|
|
2013-12-19 05:49:16 -08:00
|
|
|
if ((e->engine.func) && (e->engine.func->output_idle_flush) &&
|
|
|
|
(e->engine.data.output))
|
|
|
|
e->engine.func->output_idle_flush(e->engine.data.output);
|
2015-03-19 22:18:17 -07:00
|
|
|
|
2016-11-25 21:25:41 -08:00
|
|
|
eina_inarray_flush(&e->active_objects);
|
2013-12-19 05:49:16 -08:00
|
|
|
OBJS_ARRAY_FLUSH(&e->render_objects);
|
|
|
|
OBJS_ARRAY_FLUSH(&e->restack_objects);
|
|
|
|
OBJS_ARRAY_FLUSH(&e->delete_objects);
|
|
|
|
OBJS_ARRAY_FLUSH(&e->obscuring_objects);
|
|
|
|
OBJS_ARRAY_FLUSH(&e->temporary_objects);
|
|
|
|
eina_array_foreach(&e->clip_changes, _evas_clip_changes_free, NULL);
|
|
|
|
eina_array_clean(&e->clip_changes);
|
2015-03-19 22:18:17 -07:00
|
|
|
|
2013-12-19 05:49:16 -08:00
|
|
|
e->invalidate = EINA_TRUE;
|
2015-03-19 22:18:17 -07:00
|
|
|
|
2013-12-19 05:49:16 -08:00
|
|
|
evas_cache_async_thaw();
|
|
|
|
}
|
2010-04-12 01:23:53 -07:00
|
|
|
}
|
|
|
|
|
2008-05-26 06:24:24 -07:00
|
|
|
void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_render_invalidate(Evas *eo_e)
|
2008-05-26 06:24:24 -07:00
|
|
|
{
|
2012-10-10 00:23:00 -07:00
|
|
|
Evas_Public_Data *e;
|
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
MAGIC_CHECK(eo_e, Evas, MAGIC_EVAS);
|
2008-05-26 06:24:24 -07:00
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
2016-08-15 06:44:41 -07:00
|
|
|
e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2008-05-26 06:24:24 -07:00
|
|
|
|
2016-11-25 21:25:41 -08:00
|
|
|
eina_inarray_flush(&e->active_objects);
|
2013-05-02 00:47:16 -07:00
|
|
|
OBJS_ARRAY_CLEAN(&e->render_objects);
|
2008-06-04 09:42:39 -07:00
|
|
|
|
2013-05-02 00:47:16 -07:00
|
|
|
OBJS_ARRAY_FLUSH(&e->restack_objects);
|
|
|
|
OBJS_ARRAY_FLUSH(&e->delete_objects);
|
2015-05-09 11:02:13 -07:00
|
|
|
|
|
|
|
OBJS_ARRAY_FLUSH(&e->snapshot_objects);
|
2008-06-04 09:42:39 -07:00
|
|
|
|
2012-05-16 06:21:37 -07:00
|
|
|
e->invalidate = EINA_TRUE;
|
2008-05-26 06:24:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_render_object_recalc(Evas_Object *eo_obj)
|
2008-05-26 06:24:24 -07:00
|
|
|
{
|
2012-10-10 00:23:00 -07:00
|
|
|
Evas_Object_Protected_Data *obj;
|
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);
|
2008-05-26 06:24:24 -07:00
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
2012-10-10 00:23:00 -07:00
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2008-06-12 06:22:26 -07:00
|
|
|
if ((!obj->changed) && (obj->delete_me < 2))
|
2012-04-26 02:53:03 -07:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Public_Data *e;
|
2012-05-16 06:21:37 -07:00
|
|
|
|
2012-04-26 02:53:03 -07:00
|
|
|
e = obj->layer->evas;
|
|
|
|
if ((!e) || (e->cleanup)) return;
|
2013-05-02 00:47:16 -07:00
|
|
|
OBJ_ARRAY_PUSH(&e->pending_objects, obj);
|
2012-05-16 06:21:37 -07:00
|
|
|
obj->changed = EINA_TRUE;
|
2012-04-26 02:53:03 -07:00
|
|
|
}
|
2008-05-26 06:24:24 -07:00
|
|
|
}
|
2011-02-06 15:50:19 -08:00
|
|
|
|
2013-01-11 11:54:12 -08:00
|
|
|
void
|
|
|
|
evas_unref_queue_image_put(Evas_Public_Data *pd, void *image)
|
|
|
|
{
|
|
|
|
eina_array_push(&pd->image_unref_queue, image);
|
2013-01-17 14:14:05 -08:00
|
|
|
evas_common_rgba_image_scalecache_items_ref(image, &pd->scie_unref_queue);
|
2013-01-11 11:54:12 -08:00
|
|
|
}
|
|
|
|
|
2013-01-11 11:55:40 -08:00
|
|
|
void
|
|
|
|
evas_unref_queue_glyph_put(Evas_Public_Data *pd, void *glyph)
|
|
|
|
{
|
|
|
|
eina_array_push(&pd->glyph_unref_queue, glyph);
|
|
|
|
}
|
|
|
|
|
2013-01-15 09:35:11 -08:00
|
|
|
void
|
|
|
|
evas_unref_queue_texts_put(Evas_Public_Data *pd, void *texts)
|
|
|
|
{
|
|
|
|
eina_array_push(&pd->texts_unref_queue, texts);
|
|
|
|
}
|
|
|
|
|
2011-02-06 15:50:19 -08:00
|
|
|
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
|
2014-03-11 23:53:00 -07:00
|
|
|
|