jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=4e110a34bffe09abe4dd793f9ecf1cf3884ccf22

commit 4e110a34bffe09abe4dd793f9ecf1cf3884ccf22
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Tue Dec 13 17:41:49 2016 +0900

    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
---
 src/lib/evas/canvas/efl_canvas_proxy.c   | 51 +++++++++++++++++++++++++++-----
 src/lib/evas/canvas/efl_canvas_proxy.eo  | 25 +++++++++++++++-
 src/lib/evas/canvas/evas_image_private.h |  6 ++++
 src/lib/evas/canvas/evas_object_image.c  | 19 ++++++++++--
 src/lib/evas/canvas/evas_render.c        | 30 ++++++++++++++-----
 src/lib/evas/filters/evas_filter.c       |  3 +-
 src/lib/evas/include/evas_private.h      |  4 +--
 7 files changed, 115 insertions(+), 23 deletions(-)

diff --git a/src/lib/evas/canvas/efl_canvas_proxy.c 
b/src/lib/evas/canvas/efl_canvas_proxy.c
index 2e5af8d..2b18482 100644
--- a/src/lib/evas/canvas/efl_canvas_proxy.c
+++ b/src/lib/evas/canvas/efl_canvas_proxy.c
@@ -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
  */
diff --git a/src/lib/evas/canvas/efl_canvas_proxy.eo 
b/src/lib/evas/canvas/efl_canvas_proxy.eo
index b8048fb..d455520 100644
--- a/src/lib/evas/canvas/efl_canvas_proxy.eo
+++ b/src/lib/evas/canvas/efl_canvas_proxy.eo
@@ -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;
    }
diff --git a/src/lib/evas/canvas/evas_image_private.h 
b/src/lib/evas/canvas/evas_image_private.h
index e22a862..fa2e63f 100644
--- a/src/lib/evas/canvas/evas_image_private.h
+++ b/src/lib/evas/canvas/evas_image_private.h
@@ -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);
diff --git a/src/lib/evas/canvas/evas_object_image.c 
b/src/lib/evas/canvas/evas_object_image.c
index 110b9da..9fd263b 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -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;
diff --git a/src/lib/evas/canvas/evas_render.c 
b/src/lib/evas/canvas/evas_render.c
index bded79b..66d82f4 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -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;
-
-   RD(level, "  proxy_subrender(source: %p, proxy: %p, %dx%d)\n", source, 
proxy_obj, w, 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, 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);
diff --git a/src/lib/evas/filters/evas_filter.c 
b/src/lib/evas/filters/evas_filter.c
index 63ab6a3..0f799a5 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -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);
diff --git a/src/lib/evas/include/evas_private.h 
b/src/lib/evas/include/evas_private.h
index c038e75..8f8f63b 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.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);

-- 


Reply via email to