forked from enlightenment/efl
evas: Add source_region property to proxy objects
This will allow partially rendering a proxy in a smaller image, limited to the specified region. At the moment, this will allow apps to create proxies of very large objects and let them deal with the geometry & clipping. This is not directly solving the issues with adding a filter to textblock or the infinite page scrollers. @feature
This commit is contained in:
parent
0ca1d0eef2
commit
4e110a34bf
|
@ -3,6 +3,18 @@
|
|||
|
||||
#define MY_CLASS EFL_CANVAS_PROXY_CLASS
|
||||
|
||||
EOLIAN static Efl_Object *
|
||||
_efl_canvas_proxy_efl_object_constructor(Eo *eo_obj, Efl_Canvas_Proxy_Data *pd EINA_UNUSED)
|
||||
{
|
||||
Evas_Image_Data *o;
|
||||
|
||||
eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS));
|
||||
o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
|
||||
if (o) o->efl_canvas_proxy = EINA_TRUE;
|
||||
|
||||
return eo_obj;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_evas_image_proxy_source_set(Eo *eo_obj, Evas_Object *eo_src)
|
||||
{
|
||||
|
@ -57,7 +69,7 @@ _evas_image_proxy_source_set(Eo *eo_obj, Evas_Object *eo_src)
|
|||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_proxy_source_set(Eo *eo_obj, void *_pd EINA_UNUSED, Evas_Object *eo_src)
|
||||
_efl_canvas_proxy_source_set(Eo *eo_obj, Efl_Canvas_Proxy_Data *pd EINA_UNUSED, Evas_Object *eo_src)
|
||||
{
|
||||
return _evas_image_proxy_source_set(eo_obj, eo_src);
|
||||
}
|
||||
|
@ -70,7 +82,7 @@ _evas_image_proxy_source_get(const Eo *eo_obj)
|
|||
}
|
||||
|
||||
EOLIAN static Evas_Object *
|
||||
_efl_canvas_proxy_source_get(Eo *eo_obj, void *_pd EINA_UNUSED)
|
||||
_efl_canvas_proxy_source_get(Eo *eo_obj, Efl_Canvas_Proxy_Data *pd EINA_UNUSED)
|
||||
{
|
||||
return _evas_image_proxy_source_get(eo_obj);
|
||||
}
|
||||
|
@ -94,7 +106,7 @@ _evas_image_proxy_source_clip_set(Eo *eo_obj, Eina_Bool source_clip)
|
|||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_canvas_proxy_source_clip_set(Eo *eo_obj, void *_pd EINA_UNUSED, Eina_Bool source_clip)
|
||||
_efl_canvas_proxy_source_clip_set(Eo *eo_obj, Efl_Canvas_Proxy_Data *pd EINA_UNUSED, Eina_Bool source_clip)
|
||||
{
|
||||
return _evas_image_proxy_source_clip_set(eo_obj, source_clip);
|
||||
}
|
||||
|
@ -107,7 +119,7 @@ _evas_image_proxy_source_clip_get(const Eo *eo_obj)
|
|||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_proxy_source_clip_get(Eo *eo_obj, void *_pd EINA_UNUSED)
|
||||
_efl_canvas_proxy_source_clip_get(Eo *eo_obj, Efl_Canvas_Proxy_Data *pd EINA_UNUSED)
|
||||
{
|
||||
return _evas_image_proxy_source_clip_get(eo_obj);
|
||||
}
|
||||
|
@ -131,7 +143,7 @@ _evas_image_proxy_source_events_set(Eo *eo_obj, Eina_Bool source_events)
|
|||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_canvas_proxy_source_events_set(Eo *eo_obj, void *_pd EINA_UNUSED, Eina_Bool repeat)
|
||||
_efl_canvas_proxy_source_events_set(Eo *eo_obj, Efl_Canvas_Proxy_Data *pd EINA_UNUSED, Eina_Bool repeat)
|
||||
{
|
||||
return _evas_image_proxy_source_events_set(eo_obj, repeat);
|
||||
}
|
||||
|
@ -144,7 +156,7 @@ _evas_image_proxy_source_events_get(const Eo *eo_obj)
|
|||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_proxy_source_events_get(Eo *eo_obj, void *_pd EINA_UNUSED)
|
||||
_efl_canvas_proxy_source_events_get(Eo *eo_obj, Efl_Canvas_Proxy_Data *pd EINA_UNUSED)
|
||||
{
|
||||
return _evas_image_proxy_source_events_get(eo_obj);
|
||||
}
|
||||
|
@ -260,7 +272,7 @@ _proxy_image_get(Evas_Image_Data *o)
|
|||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_proxy_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
|
||||
_efl_canvas_proxy_efl_gfx_buffer_buffer_map(Eo *eo_obj, Efl_Canvas_Proxy_Data *pd EINA_UNUSED,
|
||||
Eina_Rw_Slice *slice,
|
||||
Efl_Gfx_Buffer_Access_Mode mode,
|
||||
int x, int y, int w, int h,
|
||||
|
@ -329,7 +341,7 @@ end:
|
|||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_proxy_efl_gfx_buffer_buffer_unmap(Eo *eo_obj, void *_pd EINA_UNUSED,
|
||||
_efl_canvas_proxy_efl_gfx_buffer_buffer_unmap(Eo *eo_obj, Efl_Canvas_Proxy_Data *pd EINA_UNUSED,
|
||||
const Eina_Rw_Slice *slice)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
||||
|
@ -344,6 +356,29 @@ _efl_canvas_proxy_efl_gfx_buffer_buffer_unmap(Eo *eo_obj, void *_pd EINA_UNUSED,
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_canvas_proxy_source_region_set(Eo *eo_obj, Efl_Canvas_Proxy_Data *pd,
|
||||
int x, int y, int w, int h)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
||||
|
||||
pd->region.x = x;
|
||||
pd->region.y = y;
|
||||
pd->region.w = w;
|
||||
pd->region.h = h;
|
||||
evas_object_change(eo_obj, obj);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_canvas_proxy_source_region_get(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Proxy_Data *pd,
|
||||
int *x, int *y, int *w, int *h)
|
||||
{
|
||||
if (x) *x = pd->region.x;
|
||||
if (y) *y = pd->region.y;
|
||||
if (w) *w = pd->region.w;
|
||||
if (h) *h = pd->region.h;
|
||||
}
|
||||
|
||||
/* Some moron just set a proxy on a proxy.
|
||||
* Give them some pixels. A random color
|
||||
*/
|
||||
|
|
|
@ -6,7 +6,6 @@ class Efl.Canvas.Proxy (Efl.Canvas.Image.Internal, Efl.Gfx.Buffer)
|
|||
object attached to it. It can be used to apply some sort of image
|
||||
transformation to any object (eg. filters, map or zoom).
|
||||
]]
|
||||
data: null;
|
||||
methods {
|
||||
@property source {
|
||||
[[The source object for this proxy.
|
||||
|
@ -70,8 +69,32 @@ class Efl.Canvas.Proxy (Efl.Canvas.Image.Internal, Efl.Gfx.Buffer)
|
|||
($false) to its source.]]
|
||||
}
|
||||
}
|
||||
@property source_region {
|
||||
[[Region in the source object that should be used as source of pixels.
|
||||
|
||||
If this property is enabled (ie. the region is not empty), then the
|
||||
proxy will be an image object of the size of this region, and only
|
||||
include the pixels from the source object starting at the relative
|
||||
position $x,$y.
|
||||
|
||||
The region ($x,$y,$w,$h) should fit inside the source object
|
||||
relative geometry. Invalid values lead to undefined behaviour.
|
||||
(0,0,0,0) can be used to reset the region to the entire object.
|
||||
|
||||
@since 1.19
|
||||
]]
|
||||
values {
|
||||
x: int; [[Relative X position inside the source object.]]
|
||||
y: int; [[Relative Y position inside the source object.]]
|
||||
w: int; [[Width of the region inside the source object, or 0
|
||||
for the entire object width.]]
|
||||
h: int; [[Height of the region inside the source object, or 0
|
||||
for the entire object height.]]
|
||||
}
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Efl.Object.constructor;
|
||||
Efl.Gfx.Buffer.buffer_map;
|
||||
Efl.Gfx.Buffer.buffer_unmap;
|
||||
}
|
||||
|
|
|
@ -133,6 +133,7 @@ struct _Evas_Image_Data
|
|||
Eina_Bool direct_render : 1;
|
||||
Eina_Bool has_filter : 1;
|
||||
Eina_Bool buffer_data_set : 1;
|
||||
Eina_Bool efl_canvas_proxy : 1;
|
||||
struct
|
||||
{
|
||||
Eina_Bool video_move : 1;
|
||||
|
@ -143,6 +144,11 @@ struct _Evas_Image_Data
|
|||
Eina_Bool legacy_type : 1;
|
||||
};
|
||||
|
||||
typedef struct _Efl_Canvas_Proxy_Data
|
||||
{
|
||||
Eina_Rectangle region;
|
||||
} Efl_Canvas_Proxy_Data;
|
||||
|
||||
/* shared functions between legacy and new eo classes */
|
||||
void _evas_image_init_set(const Eina_File *f, const char *file, const char *key, Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Image_Data *o, Evas_Image_Load_Opts *lo);
|
||||
void _evas_image_done_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Image_Data *o);
|
||||
|
|
|
@ -917,9 +917,10 @@ _efl_canvas_image_internal_efl_file_save(const Eo *eo_obj, Evas_Image_Data *o, c
|
|||
}
|
||||
else
|
||||
{
|
||||
Eina_Rectangle region = { 0, 0, 0, 0 };
|
||||
o->proxyrendering = EINA_TRUE;
|
||||
evas_render_proxy_subrender(obj->layer->evas->evas, o->cur->source,
|
||||
(Eo *) eo_obj, obj, EINA_FALSE);
|
||||
(Eo *) eo_obj, obj, region, EINA_FALSE);
|
||||
pixels = source->proxy->surface;
|
||||
imagew = source->proxy->w;
|
||||
imageh = source->proxy->h;
|
||||
|
@ -1926,9 +1927,15 @@ _evas_image_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
|
|||
}
|
||||
else
|
||||
{
|
||||
Eina_Rectangle region = { 0, 0, 0, 0 };
|
||||
if (o->efl_canvas_proxy)
|
||||
{
|
||||
Efl_Canvas_Proxy_Data *ppd = efl_data_scope_get(eo_obj, EFL_CANVAS_PROXY_CLASS);
|
||||
region = ppd->region;
|
||||
}
|
||||
o->proxyrendering = EINA_TRUE;
|
||||
evas_render_proxy_subrender(obj->layer->evas->evas, o->cur->source,
|
||||
eo_obj, obj, EINA_FALSE);
|
||||
eo_obj, obj, region, EINA_FALSE);
|
||||
pixels = source->proxy->surface;
|
||||
imagew = source->proxy->w;
|
||||
imageh = source->proxy->h;
|
||||
|
@ -2955,9 +2962,15 @@ evas_object_image_is_inside(Evas_Object *eo_obj,
|
|||
}
|
||||
else
|
||||
{
|
||||
Eina_Rectangle region = { 0, 0, 0, 0 };
|
||||
if (o->efl_canvas_proxy)
|
||||
{
|
||||
Efl_Canvas_Proxy_Data *ppd = efl_data_scope_get(eo_obj, EFL_CANVAS_PROXY_CLASS);
|
||||
region = ppd->region;
|
||||
}
|
||||
o->proxyrendering = EINA_TRUE;
|
||||
evas_render_proxy_subrender(obj->layer->evas->evas, o->cur->source,
|
||||
eo_obj, obj, EINA_FALSE);
|
||||
eo_obj, obj, region, EINA_FALSE);
|
||||
pixels = source->proxy->surface;
|
||||
imagew = source->proxy->w;
|
||||
imageh = source->proxy->h;
|
||||
|
|
|
@ -2254,14 +2254,15 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
|
|||
*/
|
||||
void
|
||||
evas_render_proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Evas_Object *eo_proxy,
|
||||
Evas_Object_Protected_Data *proxy_obj, Eina_Bool do_async)
|
||||
Evas_Object_Protected_Data *proxy_obj, Eina_Rectangle region,
|
||||
Eina_Bool do_async)
|
||||
{
|
||||
Evas_Public_Data *evas = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
||||
Evas_Object_Protected_Data *source;
|
||||
Eina_Bool source_clip = EINA_FALSE;
|
||||
int level = 1;
|
||||
void *ctx;
|
||||
int w, h;
|
||||
int x, y, w, h, W, H;
|
||||
|
||||
#ifdef REND_DBG
|
||||
level = __RD_level;
|
||||
|
@ -2271,10 +2272,22 @@ evas_render_proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Evas_Object *eo_
|
|||
eina_evlog("+proxy_subrender", eo_proxy, 0.0, NULL);
|
||||
source = efl_data_scope_get(eo_source, EFL_CANVAS_OBJECT_CLASS);
|
||||
|
||||
w = source->cur->geometry.w;
|
||||
h = source->cur->geometry.h;
|
||||
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, %dx%d)\n", source, proxy_obj, w, h);
|
||||
RD(level, " proxy_subrender(source: %p, proxy: %p, region: %d,%d %dx%d)\n", eo_source, eo_proxy, x, y, w, h);
|
||||
|
||||
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy,
|
||||
Evas_Object_Proxy_Data, proxy_write)
|
||||
|
@ -2318,6 +2331,7 @@ evas_render_proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Evas_Object *eo_
|
|||
.proxy_obj = proxy_obj,
|
||||
.eo_src = eo_source,
|
||||
.src_obj = source,
|
||||
.region = (Eina_Rectangle) { x, y, w, h },
|
||||
.source_clip = source_clip
|
||||
};
|
||||
|
||||
|
@ -2326,8 +2340,8 @@ evas_render_proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Evas_Object *eo_
|
|||
|
||||
ctx = ENFN->context_new(ENDT);
|
||||
evas_render_mapped(evas, eo_source, source, ctx, proxy_write->surface,
|
||||
-source->cur->geometry.x,
|
||||
-source->cur->geometry.y,
|
||||
x - source->cur->geometry.x,
|
||||
y - source->cur->geometry.y,
|
||||
level + 1, 0, 0, evas->output.w, evas->output.h,
|
||||
&proxy_render_data, level + 1, EINA_TRUE, do_async);
|
||||
ENFN->context_free(ENDT, ctx);
|
||||
|
|
|
@ -121,10 +121,11 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
|
|||
}
|
||||
else
|
||||
{
|
||||
Eina_Rectangle region = { 0, 0, 0, 0 };
|
||||
XDBG("Source needs to be rendered: '%s' of type '%s' (%s)",
|
||||
fb->source_name, efl_class_name_get(efl_class_get(fb->source)),
|
||||
source->proxy->redraw ? "redraw" : "no surface");
|
||||
evas_render_proxy_subrender(ctx->evas->evas, fb->source, eo_obj, obj, do_async);
|
||||
evas_render_proxy_subrender(ctx->evas->evas, fb->source, eo_obj, obj, region, do_async);
|
||||
}
|
||||
_filter_buffer_backing_free(fb);
|
||||
XDBG("Source #%d '%s' has dimensions %dx%d", fb->id, fb->source_name, fb->w, fb->h);
|
||||
|
|
|
@ -1924,6 +1924,7 @@ struct _Evas_Proxy_Render_Data
|
|||
Evas_Object_Protected_Data *src_obj;
|
||||
Evas_Object *eo_proxy;
|
||||
Evas_Object *eo_src;
|
||||
Eina_Rectangle region;
|
||||
Eina_Bool source_clip : 1;
|
||||
};
|
||||
|
||||
|
@ -1983,8 +1984,7 @@ Eina_Bool evas_render_mapped(Evas_Public_Data *e, Evas_Object *obj,
|
|||
int level, Eina_Bool use_mapped_ctx, Eina_Bool do_async);
|
||||
void evas_render_invalidate(Evas *e);
|
||||
void evas_render_object_recalc(Evas_Object *obj);
|
||||
void evas_render_proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Evas_Object *eo_proxy,
|
||||
Evas_Object_Protected_Data *proxy_obj, Eina_Bool do_async);
|
||||
void evas_render_proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Evas_Object *eo_proxy, Evas_Object_Protected_Data *proxy_obj, Eina_Rectangle region, Eina_Bool do_async);
|
||||
void evas_render_mask_subrender(Evas_Public_Data *e, Evas_Object_Protected_Data *mask, Evas_Object_Protected_Data *prev_mask, int level);
|
||||
|
||||
Eina_Bool evas_map_inside_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y);
|
||||
|
|
Loading…
Reference in New Issue