summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-01-18 11:47:25 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-04-14 11:26:43 +0900
commit2ef8d6f39af839c23551239216cea100254f80df (patch)
tree415581d3cb5245012225777926638827051bc3c2
parentfb52c15e8513cc1458341da13e570d231a886551 (diff)
evas filters: Refactor ector and gfx filters A LOT
Alright, so this is a massive patch that is the result of trying to get rid of unused or poorly implemented classes in ector. Originally ector was meant to support VG but extend to things like filters as well. At the moment, ector's design makes it quite hard to plug in the filters. For now I think it's easier to implement the GL support for the filters directly in the engine, where I hope to interfere as little as possible. This massive patch keeps only the required minimum to support a versatile gl buffer that can be mapped, drawn or rendered to (FBO). It's extremely inefficient as it relies on glReadPixels and lots of texture uploads, as well as conversions between ARGB and Alpha. Another type of GL buffer is a wrap around an existing GL image, but that one is read-only (map or draw: no write map, no FBO). No, all the filters run fine, and the high-level implementation (evas_filters.c) does not need to know whether the underlying engine is SW or GL. One problem though appears with the blending or blurring of some Alpha buffers, the colors are wrong. This patch removes more lines than it adds so it must be good ;)
Diffstat (limited to '')
-rw-r--r--src/Makefile_Ector.am6
-rw-r--r--src/Makefile_Evas.am2
-rw-r--r--src/bin/elementary/test_gfx_filters.c22
-rw-r--r--src/lib/ector/cairo/ector_cairo_software_surface.c7
-rw-r--r--src/lib/ector/ector_buffer.c9
-rw-r--r--src/lib/ector/ector_buffer.eo38
-rw-r--r--src/lib/ector/ector_buffer.h15
-rw-r--r--src/lib/ector/ector_renderer.h1
-rw-r--r--src/lib/ector/ector_renderer_buffer.c45
-rw-r--r--src/lib/ector/ector_renderer_buffer.eo17
-rw-r--r--src/lib/ector/gl/Ector_GL.h1
-rw-r--r--src/lib/ector/gl/ector_gl_buffer.eo2
-rw-r--r--src/lib/ector/gl/ector_gl_buffer_base.c65
-rw-r--r--src/lib/ector/gl/ector_gl_buffer_base.eo60
-rw-r--r--src/lib/ector/software/Ector_Software.h1
-rw-r--r--src/lib/ector/software/ector_renderer_software_buffer.c72
-rw-r--r--src/lib/ector/software/ector_renderer_software_buffer.eo20
-rw-r--r--src/lib/ector/software/ector_software_buffer.c138
-rw-r--r--src/lib/ector/software/ector_software_buffer_base.eo2
-rw-r--r--src/lib/ector/software/ector_software_private.h2
-rw-r--r--src/lib/ector/software/ector_software_rasterizer.c49
-rw-r--r--src/lib/ector/software/ector_software_surface.c13
-rw-r--r--src/lib/evas/filters/evas_filter.c490
-rw-r--r--src/lib/evas/filters/evas_filter_parser.c146
-rw-r--r--src/lib/evas/filters/evas_filter_private.h12
-rw-r--r--src/lib/evas/include/evas_ector_buffer.eo43
-rw-r--r--src/lib/evas/include/evas_filter.h19
-rw-r--r--src/lib/evas/include/evas_private.h4
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_common.h1
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_image.c61
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_texture.c1
-rw-r--r--src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c344
-rw-r--r--src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.eo36
-rw-r--r--src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c279
-rw-r--r--src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.eo11
-rw-r--r--src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c117
-rw-r--r--src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.eo10
-rw-r--r--src/modules/evas/engines/gl_generic/evas_engine.c90
-rw-r--r--src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c37
-rw-r--r--src/modules/evas/engines/software_generic/evas_ector_software_buffer.c60
-rw-r--r--src/modules/evas/engines/software_generic/evas_ector_software_buffer.eo5
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c73
-rw-r--r--src/modules/evas/engines/software_generic/filters/evas_filter_displace.c4
-rw-r--r--src/modules/evas/engines/software_generic/filters/evas_filter_fill.c10
-rw-r--r--src/modules/evas/engines/software_generic/filters/evas_filter_mask.c6
45 files changed, 1084 insertions, 1362 deletions
diff --git a/src/Makefile_Ector.am b/src/Makefile_Ector.am
index df6e6d2532..7baa0767d1 100644
--- a/src/Makefile_Ector.am
+++ b/src/Makefile_Ector.am
@@ -5,7 +5,6 @@ ector_eolian_files_generic = \
5 lib/ector/ector_buffer.eo \ 5 lib/ector/ector_buffer.eo \
6 lib/ector/ector_renderer.eo \ 6 lib/ector/ector_renderer.eo \
7 lib/ector/ector_renderer_shape.eo \ 7 lib/ector/ector_renderer_shape.eo \
8 lib/ector/ector_renderer_buffer.eo \
9 lib/ector/ector_renderer_gradient.eo \ 8 lib/ector/ector_renderer_gradient.eo \
10 lib/ector/ector_renderer_gradient_radial.eo \ 9 lib/ector/ector_renderer_gradient_radial.eo \
11 lib/ector/ector_renderer_gradient_linear.eo 10 lib/ector/ector_renderer_gradient_linear.eo
@@ -28,7 +27,6 @@ ector_eolian_files_software = \
28 lib/ector/software/ector_software_buffer_base.eo \ 27 lib/ector/software/ector_software_buffer_base.eo \
29 lib/ector/software/ector_renderer_software.eo \ 28 lib/ector/software/ector_renderer_software.eo \
30 lib/ector/software/ector_renderer_software_shape.eo \ 29 lib/ector/software/ector_renderer_software_shape.eo \
31 lib/ector/software/ector_renderer_software_buffer.eo \
32 lib/ector/software/ector_renderer_software_gradient_radial.eo \ 30 lib/ector/software/ector_renderer_software_gradient_radial.eo \
33 lib/ector/software/ector_renderer_software_gradient_linear.eo 31 lib/ector/software/ector_renderer_software_gradient_linear.eo
34ector_eolian_software_h = $(ector_eolian_files_software:%.eo=%.eo.h) 32ector_eolian_software_h = $(ector_eolian_files_software:%.eo=%.eo.h)
@@ -37,7 +35,6 @@ ector_eolian_software_h = $(ector_eolian_files_software:%.eo=%.eo.h)
37ector_eolian_files_gl = \ 35ector_eolian_files_gl = \
38 lib/ector/gl/ector_gl_surface.eo \ 36 lib/ector/gl/ector_gl_surface.eo \
39 lib/ector/gl/ector_gl_buffer.eo \ 37 lib/ector/gl/ector_gl_buffer.eo \
40 lib/ector/gl/ector_gl_buffer_base.eo \
41 lib/ector/gl/ector_renderer_gl.eo \ 38 lib/ector/gl/ector_renderer_gl.eo \
42 lib/ector/gl/ector_renderer_gl_shape.eo \ 39 lib/ector/gl/ector_renderer_gl_shape.eo \
43 lib/ector/gl/ector_renderer_gl_gradient_radial.eo \ 40 lib/ector/gl/ector_renderer_gl_gradient_radial.eo \
@@ -84,7 +81,6 @@ lib/ector/ector_gl_internal.h \
84lib/ector/ector_buffer.c \ 81lib/ector/ector_buffer.c \
85lib/ector/ector_renderer_shape.c \ 82lib/ector/ector_renderer_shape.c \
86lib/ector/ector_renderer.c \ 83lib/ector/ector_renderer.c \
87lib/ector/ector_renderer_buffer.c \
88lib/ector/ector_renderer_gradient.c \ 84lib/ector/ector_renderer_gradient.c \
89lib/ector/ector_renderer_gradient_radial.c \ 85lib/ector/ector_renderer_gradient_radial.c \
90lib/ector/ector_renderer_gradient_linear.c 86lib/ector/ector_renderer_gradient_linear.c
@@ -121,7 +117,6 @@ lib_ector_libector_la_SOURCES += \
121lib/ector/software/ector_renderer_software_gradient_linear.c \ 117lib/ector/software/ector_renderer_software_gradient_linear.c \
122lib/ector/software/ector_renderer_software_gradient_radial.c \ 118lib/ector/software/ector_renderer_software_gradient_radial.c \
123lib/ector/software/ector_renderer_software_shape.c \ 119lib/ector/software/ector_renderer_software_shape.c \
124lib/ector/software/ector_renderer_software_buffer.c \
125lib/ector/software/ector_software_gradient.c \ 120lib/ector/software/ector_software_gradient.c \
126lib/ector/software/ector_software_rasterizer.c \ 121lib/ector/software/ector_software_rasterizer.c \
127lib/ector/software/ector_software_surface.c \ 122lib/ector/software/ector_software_surface.c \
@@ -138,7 +133,6 @@ lib/ector/gl/ector_renderer_gl_gradient_radial.c \
138lib/ector/gl/ector_renderer_gl_shape.c \ 133lib/ector/gl/ector_renderer_gl_shape.c \
139lib/ector/gl/ector_renderer_gl.c \ 134lib/ector/gl/ector_renderer_gl.c \
140lib/ector/gl/ector_gl_buffer.c \ 135lib/ector/gl/ector_gl_buffer.c \
141lib/ector/gl/ector_gl_buffer_base.c \
142lib/ector/gl/ector_gl_surface.c \ 136lib/ector/gl/ector_gl_surface.c \
143lib/ector/gl/ector_gl_private.h \ 137lib/ector/gl/ector_gl_private.h \
144lib/ector/gl/shader/ector_gl_shaders.x \ 138lib/ector/gl/shader/ector_gl_shaders.x \
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index f925cdab65..83557dfb92 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -842,7 +842,6 @@ modules/evas/engines/gl_generic/Evas_Engine_GL_Generic.h \
842modules/evas/engines/gl_generic/Evas_Engine_GL_Shared.h \ 842modules/evas/engines/gl_generic/Evas_Engine_GL_Shared.h \
843modules/evas/engines/gl_generic/evas_ector_gl_buffer.c \ 843modules/evas/engines/gl_generic/evas_ector_gl_buffer.c \
844modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c \ 844modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c \
845modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c \
846modules/evas/engines/gl_generic/filters/gl_engine_filter.h \ 845modules/evas/engines/gl_generic/filters/gl_engine_filter.h \
847modules/evas/engines/gl_generic/filters/gl_filter_blend.c \ 846modules/evas/engines/gl_generic/filters/gl_filter_blend.c \
848$(NULL) 847$(NULL)
@@ -850,7 +849,6 @@ $(NULL)
850evas_gl_generic_eolian_files = \ 849evas_gl_generic_eolian_files = \
851modules/evas/engines/gl_generic/evas_ector_gl_buffer.eo \ 850modules/evas/engines/gl_generic/evas_ector_gl_buffer.eo \
852modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.eo \ 851modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.eo \
853modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.eo \
854$(NULL) 852$(NULL)
855 853
856evas_gl_generic_eolian_c = $(evas_gl_generic_eolian_files:%.eo=%.eo.c) 854evas_gl_generic_eolian_c = $(evas_gl_generic_eolian_files:%.eo=%.eo.c)
diff --git a/src/bin/elementary/test_gfx_filters.c b/src/bin/elementary/test_gfx_filters.c
index b9855292ca..d67f616ac8 100644
--- a/src/bin/elementary/test_gfx_filters.c
+++ b/src/bin/elementary/test_gfx_filters.c
@@ -47,6 +47,8 @@ static const Filter_Image images_anim[] = {
47/* builtin filter examples */ 47/* builtin filter examples */
48static const Filter templates[] = { 48static const Filter templates[] = {
49 { "Custom", NULL, NULL }, 49 { "Custom", NULL, NULL },
50 { "Simple blend",
51 "blend { color = 'darkblue' }", NULL },
50 { "Black shadow", 52 { "Black shadow",
51 "if not myColor then myColor = color('yellow') end\n" 53 "if not myColor then myColor = color('yellow') end\n"
52 "blur { 6, ox = 2, oy = 2, color = 'black' }\n" 54 "blur { 6, ox = 2, oy = 2, color = 'black' }\n"
@@ -521,13 +523,19 @@ test_gfx_filters(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
521 efl_ui_text_scrollable_set(efl_added, 1)); 523 efl_ui_text_scrollable_set(efl_added, 1));
522 efl_event_callback_add(o, EFL_UI_TEXT_EVENT_CHANGED_USER, _code_changed, win); 524 efl_event_callback_add(o, EFL_UI_TEXT_EVENT_CHANGED_USER, _code_changed, win);
523 525
524 // Insert filter code inside style string: DEFAULT='blah blah <here>' 526 // HACK: For now only set filter on code if engine is not GL (WIP)
525 buf = eina_strbuf_new(); 527 const char *engine = ecore_evas_engine_name_get
526 eina_strbuf_append(buf, efl_canvas_text_style_get(o, NULL)); 528 (ecore_evas_ecore_evas_get(evas_object_evas_get(win)));
527 eina_strbuf_insert(buf, " gfx_filter=code", eina_strbuf_length_get(buf) - 1); 529 if (engine && !strstr(engine, "gl"))
528 efl_gfx_filter_program_set(o, code_filter, "code"); 530 {
529 efl_canvas_text_style_set(o, NULL, eina_strbuf_string_get(buf)); 531 // Insert filter code inside style string: DEFAULT='blah blah <here>'
530 eina_strbuf_free(buf); 532 buf = eina_strbuf_new();
533 eina_strbuf_append(buf, efl_canvas_text_style_get(o, NULL));
534 eina_strbuf_insert(buf, " gfx_filter=code", eina_strbuf_length_get(buf) - 1);
535 efl_gfx_filter_program_set(o, code_filter, "code");
536 efl_canvas_text_style_set(o, NULL, eina_strbuf_string_get(buf));
537 eina_strbuf_free(buf);
538 }
531 539
532 // FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME 540 // FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
533 // Efl.Ui.Text doesn't seem to trigger the proper events during edit 541 // Efl.Ui.Text doesn't seem to trigger the proper events during edit
diff --git a/src/lib/ector/cairo/ector_cairo_software_surface.c b/src/lib/ector/cairo/ector_cairo_software_surface.c
index d96fdd517e..98dd8e0a4f 100644
--- a/src/lib/ector/cairo/ector_cairo_software_surface.c
+++ b/src/lib/ector/cairo/ector_cairo_software_surface.c
@@ -51,9 +51,8 @@ struct _Ector_Cairo_Software_Surface_Data
51 51
52EOLIAN static Eina_Bool 52EOLIAN static Eina_Bool
53_ector_cairo_software_surface_ector_buffer_pixels_set(Eo *obj, Ector_Cairo_Software_Surface_Data *pd, 53_ector_cairo_software_surface_ector_buffer_pixels_set(Eo *obj, Ector_Cairo_Software_Surface_Data *pd,
54 void *pixels, int width, int height, int stride, 54 void *pixels, int width, int height,
55 Efl_Gfx_Colorspace cspace, Eina_Bool writable, 55 Efl_Gfx_Colorspace cspace, Eina_Bool writable)
56 unsigned char l, unsigned char r, unsigned char t, unsigned char b)
57{ 56{
58 cairo_t *ctx = NULL; 57 cairo_t *ctx = NULL;
59 Eina_Bool ok = EINA_FALSE; 58 Eina_Bool ok = EINA_FALSE;
@@ -73,7 +72,7 @@ _ector_cairo_software_surface_ector_buffer_pixels_set(Eo *obj, Ector_Cairo_Softw
73 cairo_surface_destroy(pd->surface); 72 cairo_surface_destroy(pd->surface);
74 pd->surface = NULL; 73 pd->surface = NULL;
75 74
76 ok = ector_buffer_pixels_set(efl_super(obj, MY_CLASS), pixels, width, height, stride, cspace, writable, l, r, t, b); 75 ok = ector_buffer_pixels_set(efl_super(obj, MY_CLASS), pixels, width, height, cspace, writable);
77 76
78 if (ok && pixels) 77 if (ok && pixels)
79 { 78 {
diff --git a/src/lib/ector/ector_buffer.c b/src/lib/ector/ector_buffer.c
index 9fe9ed6930..51dbd1496a 100644
--- a/src/lib/ector/ector_buffer.c
+++ b/src/lib/ector/ector_buffer.c
@@ -15,15 +15,6 @@ _ector_buffer_cspace_get(Eo *obj EINA_UNUSED, Ector_Buffer_Data *pd)
15} 15}
16 16
17EOLIAN static void 17EOLIAN static void
18_ector_buffer_border_get(Eo *obj EINA_UNUSED, Ector_Buffer_Data *pd EINA_UNUSED, int *l, int *r, int *t, int *b)
19{
20 if (l) *l = pd->l;
21 if (r) *r = pd->r;
22 if (t) *t = pd->t;
23 if (b) *b = pd->b;
24}
25
26EOLIAN static void
27_ector_buffer_size_get(Eo *obj EINA_UNUSED, Ector_Buffer_Data *pd, int *w, int *h) 18_ector_buffer_size_get(Eo *obj EINA_UNUSED, Ector_Buffer_Data *pd, int *w, int *h)
28{ 19{
29 if (w) *w = pd->w; 20 if (w) *w = pd->w;
diff --git a/src/lib/ector/ector_buffer.eo b/src/lib/ector/ector_buffer.eo
index 0b8782ff68..f90bb1df1d 100644
--- a/src/lib/ector/ector_buffer.eo
+++ b/src/lib/ector/ector_buffer.eo
@@ -24,6 +24,7 @@ enum Ector.Buffer.Access_Flag {
24mixin Ector.Buffer 24mixin Ector.Buffer
25{ 25{
26 [[2D pixel buffer interface for Ector 26 [[2D pixel buffer interface for Ector
27
27 @since 1.17 28 @since 1.17
28 ]] 29 ]]
29 eo_prefix: ector_buffer; 30 eo_prefix: ector_buffer;
@@ -76,38 +77,11 @@ mixin Ector.Buffer
76 @in pixels: void_ptr; [[If $null, allocates an empty buffer]] 77 @in pixels: void_ptr; [[If $null, allocates an empty buffer]]
77 @in width: int; [[Buffer width]] 78 @in width: int; [[Buffer width]]
78 @in height: int; [[Buffer height]] 79 @in height: int; [[Buffer height]]
79 @in stride: int; [[Can be 0]]
80 @in cspace: Efl.Gfx.Colorspace; [[Buffer colorspace]] 80 @in cspace: Efl.Gfx.Colorspace; [[Buffer colorspace]]
81 @in writable: bool; [[Buffer is writable]] 81 @in writable: bool; [[Buffer is writable]]
82 @in l: ubyte; [[Left border pixels, usually 0 or 1]]
83 @in r: ubyte; [[Right border pixels, usually 0 or 1]]
84 @in t: ubyte; [[Top border pixels, usually 0 or 1]]
85 @in b: ubyte; [[Bottom border pixels, usually 0 or 1]]
86 } 82 }
87 return: bool; [[True if pixels_set was successful]] 83 return: bool; [[True if pixels_set was successful]]
88 } 84 }
89 span_get @pure_virtual {
90 [[Get a single horizontal span of length w starting from (x,y)
91
92 Call span_free() to release it. This function will try not to
93 allocate any new buffer, whenever possible. This means the data
94 might be mapped directly from the backing memory buffer.
95 ]]
96 params {
97 @in x: int; [[Ranges from -l to w+r-1]]
98 @in y: int; [[Ranges from -t to h+b-1]]
99 @in w: uint; [[Ranges from 1 to w+l+r]]
100 @in cspace: Efl.Gfx.Colorspace; [[Requested colorspace, may trigger conversion on the fly.]]
101 @out length: uint; [[Length in bytes of the returned buffer]]
102 }
103 return: ptr(uint8); [[A temporary memory buffer containing the pixels requested.]]
104 }
105 span_free @pure_virtual {
106 [[Must be called as soon as possible after span_get]]
107 params {
108 data: ptr(uint8); [[Data to be freed]]
109 }
110 }
111 @property flags { 85 @property flags {
112 [[The capabilities of this buffer]] 86 [[The capabilities of this buffer]]
113 get {} 87 get {}
@@ -115,16 +89,6 @@ mixin Ector.Buffer
115 flag: Ector.Buffer.Flag; [[A bitmask of capability flags]] 89 flag: Ector.Buffer.Flag; [[A bitmask of capability flags]]
116 } 90 }
117 } 91 }
118 @property border {
119 [[Duplicated pixel borders of this buffer, used for GL scaling]]
120 get {}
121 values {
122 l: int; [[Left border]]
123 r: int; [[Right border]]
124 t: int; [[Top border]]
125 b: int; [[Bottom border]]
126 }
127 }
128 } 92 }
129 events { 93 events {
130 detached; [[Emitted whenever the previously attached pixels are detached during pixels_set]] 94 detached; [[Emitted whenever the previously attached pixels are detached during pixels_set]]
diff --git a/src/lib/ector/ector_buffer.h b/src/lib/ector/ector_buffer.h
index e19c7fe4a6..9c91bfd4a4 100644
--- a/src/lib/ector/ector_buffer.h
+++ b/src/lib/ector/ector_buffer.h
@@ -18,13 +18,11 @@ typedef Eo Ector_Buffer;
18 18
19typedef struct _Ector_Buffer_Data Ector_Buffer_Data; 19typedef struct _Ector_Buffer_Data Ector_Buffer_Data;
20typedef struct _Ector_Software_Buffer_Base_Data Ector_Software_Buffer_Base_Data; 20typedef struct _Ector_Software_Buffer_Base_Data Ector_Software_Buffer_Base_Data;
21typedef struct _Ector_GL_Buffer_Base_Data Ector_GL_Buffer_Base_Data;
22 21
23struct _Ector_Buffer_Data 22struct _Ector_Buffer_Data
24{ 23{
25 Ector_Buffer *eo; 24 Ector_Buffer *eo;
26 unsigned int w, h; 25 unsigned int w, h;
27 unsigned char l, r, t, b;
28 Efl_Gfx_Colorspace cspace; 26 Efl_Gfx_Colorspace cspace;
29 Eina_Bool immutable : 1; // pixels_set is forbidden 27 Eina_Bool immutable : 1; // pixels_set is forbidden
30}; 28};
@@ -45,17 +43,4 @@ struct _Ector_Software_Buffer_Base_Data
45 Eina_Bool nofree : 1; // pixel data should not be free()'ed 43 Eina_Bool nofree : 1; // pixel data should not be free()'ed
46}; 44};
47 45
48struct _Ector_GL_Buffer_Base_Data
49{
50 Ector_Buffer_Data *generic;
51 int texid;
52 int fboid;
53 struct {
54 // x,y offset within the atlas
55 // w,h size of the atlas itself
56 int x, y, w, h;
57 } atlas;
58 Eina_Bool whole : 1;
59};
60
61#endif 46#endif
diff --git a/src/lib/ector/ector_renderer.h b/src/lib/ector/ector_renderer.h
index e2e2e65f58..c8d20d2fb3 100644
--- a/src/lib/ector/ector_renderer.h
+++ b/src/lib/ector/ector_renderer.h
@@ -3,7 +3,6 @@
3 3
4#include "ector_renderer.eo.h" 4#include "ector_renderer.eo.h"
5#include "ector_renderer_shape.eo.h" 5#include "ector_renderer_shape.eo.h"
6#include "ector_renderer_buffer.eo.h"
7#include "ector_renderer_gradient.eo.h" 6#include "ector_renderer_gradient.eo.h"
8#include "ector_renderer_gradient_linear.eo.h" 7#include "ector_renderer_gradient_linear.eo.h"
9#include "ector_renderer_gradient_radial.eo.h" 8#include "ector_renderer_gradient_radial.eo.h"
diff --git a/src/lib/ector/ector_renderer_buffer.c b/src/lib/ector/ector_renderer_buffer.c
deleted file mode 100644
index 56bb6f13e1..0000000000
--- a/src/lib/ector/ector_renderer_buffer.c
+++ /dev/null
@@ -1,45 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#else
4# define EFL_BETA_API_SUPPORT
5#endif
6
7#include <Eo.h>
8#include "ector_private.h"
9#include "ector_renderer_buffer.eo.h"
10
11#define MY_CLASS ECTOR_RENDERER_BUFFER_MIXIN
12
13EOLIAN static void
14_ector_renderer_buffer_efl_gfx_fill_fill_get(Eo *obj EINA_UNUSED, Ector_Renderer_Buffer_Data *pd, int *x, int *y, int *w, int *h)
15{
16 if (x) *x = pd->fill.x;
17 if (y) *y = pd->fill.y;
18 if (w) *w = pd->fill.w;
19 if (h) *h = pd->fill.h;
20}
21
22EOLIAN static void
23_ector_renderer_buffer_efl_gfx_fill_fill_set(Eo *obj EINA_UNUSED, Ector_Renderer_Buffer_Data *pd, int x, int y, int w, int h)
24{
25 if (w < 0) w = 0;
26 if (h < 0) h = 0;
27 pd->fill.x = x;
28 pd->fill.y = y;
29 pd->fill.w = w;
30 pd->fill.h = h;
31}
32
33EOLIAN static void
34_ector_renderer_buffer_buffer_set(Eo *obj EINA_UNUSED, Ector_Renderer_Buffer_Data *pd, Ector_Buffer *buf)
35{
36 _efl_xrefplace(&pd->eo_buffer, buf, obj);
37}
38
39EOLIAN static Ector_Buffer *
40_ector_renderer_buffer_buffer_get(Eo *obj EINA_UNUSED, Ector_Renderer_Buffer_Data *pd)
41{
42 return pd->eo_buffer;
43}
44
45#include "ector_renderer_buffer.eo.c"
diff --git a/src/lib/ector/ector_renderer_buffer.eo b/src/lib/ector/ector_renderer_buffer.eo
deleted file mode 100644
index b3e97d2053..0000000000
--- a/src/lib/ector/ector_renderer_buffer.eo
+++ /dev/null
@@ -1,17 +0,0 @@
1mixin Ector.Renderer.Buffer (Efl.Interface, Ector.Renderer, Efl.Gfx.Fill)
2{
3 [[Ector buffers have a default fill set to repeat]]
4 eo_prefix: ector_renderer_buffer;
5 methods {
6 @property buffer {
7 set { [[Sets the source buffer for this renderer, adds a ref]] }
8 get { [[Return the current source, no ref change]] }
9 values {
10 buf: Ector.Buffer; [[Buffer]]
11 }
12 }
13 }
14 implements {
15 Efl.Gfx.Fill.fill { get; set; }
16 }
17}
diff --git a/src/lib/ector/gl/Ector_GL.h b/src/lib/ector/gl/Ector_GL.h
index 04d76c0af1..df6ece47b7 100644
--- a/src/lib/ector/gl/Ector_GL.h
+++ b/src/lib/ector/gl/Ector_GL.h
@@ -15,7 +15,6 @@ typedef Eo Ector_Cairo_Surface;
15typedef unsigned int GLuint; 15typedef unsigned int GLuint;
16typedef short GLshort; 16typedef short GLshort;
17 17
18#include "gl/ector_gl_buffer_base.eo.h"
19#include "gl/ector_gl_buffer.eo.h" 18#include "gl/ector_gl_buffer.eo.h"
20#include "gl/ector_gl_surface.eo.h" 19#include "gl/ector_gl_surface.eo.h"
21#include "gl/ector_renderer_gl.eo.h" 20#include "gl/ector_renderer_gl.eo.h"
diff --git a/src/lib/ector/gl/ector_gl_buffer.eo b/src/lib/ector/gl/ector_gl_buffer.eo
index 67b96ae4e9..03171eac8c 100644
--- a/src/lib/ector/gl/ector_gl_buffer.eo
+++ b/src/lib/ector/gl/ector_gl_buffer.eo
@@ -1,4 +1,4 @@
1class Ector.GL.Buffer (Efl.Object, Ector.GL.Buffer.Base) 1class Ector.GL.Buffer (Efl.Object, Ector.Buffer)
2{ 2{
3 [[Ector GL buffer class]] 3 [[Ector GL buffer class]]
4 data: null; 4 data: null;
diff --git a/src/lib/ector/gl/ector_gl_buffer_base.c b/src/lib/ector/gl/ector_gl_buffer_base.c
deleted file mode 100644
index 954988a0fb..0000000000
--- a/src/lib/ector/gl/ector_gl_buffer_base.c
+++ /dev/null
@@ -1,65 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include "Ector_GL.h"
6#include "ector_gl_private.h"
7#include "ector_buffer.h"
8#include "ector_gl_buffer_base.eo.h"
9
10#define MY_CLASS ECTOR_GL_BUFFER_BASE_MIXIN
11
12EOLIAN static int
13_ector_gl_buffer_base_texture_get(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd)
14{
15 return pd->texid;
16}
17
18EOLIAN static int
19_ector_gl_buffer_base_fbo_get(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd)
20{
21 return pd->fboid;
22}
23
24EOLIAN static Eina_Bool
25_ector_gl_buffer_base_whole_get(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd)
26{
27 return pd->whole;
28}
29
30EOLIAN static void
31_ector_gl_buffer_base_vertices_get(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd, double *x, double *y, double *w, double *h)
32{
33 if (x) *x = (double) pd->atlas.x / pd->atlas.w;
34 if (y) *y = (double) pd->atlas.y / pd->atlas.h;
35 if (w) *w = (double) pd->generic->w / pd->atlas.w;
36 if (h) *h = (double) pd->generic->h / pd->atlas.h;
37}
38
39EOLIAN static void
40_ector_gl_buffer_base_attach(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd,
41 int texid, int fboid, Efl_Gfx_Colorspace cspace,
42 int imw, int imh, int tx, int ty, int tw, int th,
43 int l, int r, int t, int b)
44{
45 EINA_SAFETY_ON_NULL_RETURN(pd->generic);
46 EINA_SAFETY_ON_FALSE_RETURN(!pd->generic->immutable);
47
48 pd->generic->cspace = cspace;
49 pd->generic->w = imw;
50 pd->generic->h = imh;
51 pd->atlas.x = tx;
52 pd->atlas.y = ty;
53 pd->atlas.w = tw;
54 pd->atlas.h = th;
55 pd->generic->l = l;
56 pd->generic->r = r;
57 pd->generic->t = t;
58 pd->generic->b = b;
59 if (!(tx - l) && !(ty - t) && ((tw + l + r) == imw) && ((th + t + b) == imh))
60 pd->whole = EINA_TRUE;
61 pd->fboid = fboid;
62 pd->texid = texid;
63}
64
65#include "ector_gl_buffer_base.eo.c"
diff --git a/src/lib/ector/gl/ector_gl_buffer_base.eo b/src/lib/ector/gl/ector_gl_buffer_base.eo
deleted file mode 100644
index 2a1718246b..0000000000
--- a/src/lib/ector/gl/ector_gl_buffer_base.eo
+++ /dev/null
@@ -1,60 +0,0 @@
1mixin Ector.GL.Buffer.Base (Ector.Buffer)
2{
3 [[Ector GL buffer base class]]
4 methods {
5 @property texture {
6 [[GL texture ID]]
7 get {}
8 values {
9 texid: int; [[GL texture ID]]
10 }
11 }
12 @property fbo {
13 [[Framebuffer object ID]]
14 get {}
15 values {
16 fboid: int; [[GL framebuffer ID, 0 if there is no FBO]]
17 }
18 }
19 @property whole {
20 [[If $true, the image is covering the entire GL texture, ie. it's not
21 part of an atlas.
22 ]]
23 get {}
24 values {
25 is_whole: bool; [[$true if the image is covering the whole GL texture, $false otherwise]]
26 }
27 }
28 @property vertices {
29 [[Returns the texture vertices to draw this image with no rotation
30
31 The 4 points are then defined as (x,y), (x+w,y), (x,y+h), (x+w,y+h).
32 ]]
33 get {}
34 values {
35 x: double; [[X position of this image inside the texture atlas, from 0 to 1]]
36 y: double; [[Y position of this image inside the texture atlas, from 0 to 1]]
37 w: double; [[Width of this image inside the texture atlas, from 0 to 1]]
38 h: double; [[Height of this image inside the texture atlas, from 0 to 1]]
39 }
40 }
41 attach @protected {
42 [[Attach to an existing texture (or FBO). Used from child classes.]]
43 params {
44 texid: int; [[GL texture ID]]
45 fboid: int; [[Framebuffer object ID]]
46 cspace: Efl.Gfx.Colorspace; [[Colorspace]]
47 imw: int; [[Image width]]
48 imh: int; [[Image height]]
49 tx: int; [[Texture X coordinate]]
50 ty: int; [[Texture Y coordinate]]
51 tw: int; [[Texture width]]
52 th: int; [[Texture height]]
53 l: int; [[Left padding]]
54 r: int; [[Right padding]]
55 t: int; [[Top padding]]
56 b: int; [[Bottom padding]]
57 }
58 }
59 }
60}
diff --git a/src/lib/ector/software/Ector_Software.h b/src/lib/ector/software/Ector_Software.h
index f53526c5b2..7c94b895cf 100644
--- a/src/lib/ector/software/Ector_Software.h
+++ b/src/lib/ector/software/Ector_Software.h
@@ -10,7 +10,6 @@
10#include "software/ector_software_buffer_base.eo.h" 10#include "software/ector_software_buffer_base.eo.h"
11#include "software/ector_renderer_software.eo.h" 11#include "software/ector_renderer_software.eo.h"
12#include "software/ector_renderer_software_shape.eo.h" 12#include "software/ector_renderer_software_shape.eo.h"
13#include "software/ector_renderer_software_buffer.eo.h"
14#include "software/ector_renderer_software_gradient_linear.eo.h" 13#include "software/ector_renderer_software_gradient_linear.eo.h"
15#include "software/ector_renderer_software_gradient_radial.eo.h" 14#include "software/ector_renderer_software_gradient_radial.eo.h"
16 15
diff --git a/src/lib/ector/software/ector_renderer_software_buffer.c b/src/lib/ector/software/ector_renderer_software_buffer.c
deleted file mode 100644
index 9d524af72e..0000000000
--- a/src/lib/ector/software/ector_renderer_software_buffer.c
+++ /dev/null
@@ -1,72 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#else
4# define EFL_BETA_API_SUPPORT
5#endif
6
7#include <Eo.h>
8#include "Ector_Software.h"
9#include "ector_private.h"
10#include "ector_software_private.h"
11
12#define MY_CLASS ECTOR_RENDERER_SOFTWARE_BUFFER_CLASS
13
14typedef struct
15{
16 Ector_Renderer_Data *base;
17 Software_Rasterizer *surface;
18 Ector_Buffer *eo_buffer;
19} Ector_Renderer_Software_Buffer_Data;
20
21
22EOLIAN static void
23_ector_renderer_software_buffer_buffer_set(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd, Ector_Buffer *buf)
24{
25 _efl_xrefplace(&pd->eo_buffer, buf, obj);
26}
27
28EOLIAN static Ector_Buffer *
29_ector_renderer_software_buffer_buffer_get(Eo *obj EINA_UNUSED, Ector_Renderer_Software_Buffer_Data *pd)
30{
31 return pd->eo_buffer;
32}
33
34EOLIAN static Eina_Bool
35_ector_renderer_software_buffer_ector_renderer_software_fill(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd)
36{
37 Ector_Software_Buffer *buffer = efl_data_scope_get(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
38 ector_software_rasterizer_buffer_set(pd->surface, buffer);
39 return EINA_TRUE;
40}
41
42EOLIAN static Eina_Bool
43_ector_renderer_software_buffer_ector_renderer_prepare(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd)
44{
45 if (!pd->surface)
46 pd->surface = efl_data_xref(pd->base->surface, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
47
48 return EINA_TRUE;
49}
50
51EOLIAN static unsigned int
52_ector_renderer_software_buffer_ector_renderer_crc_get(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd)
53{
54 Ector_Software_Buffer_Base_Data *buffer = efl_data_scope_get(pd->eo_buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
55 unsigned int crc;
56
57 crc = ector_renderer_crc_get(efl_super(obj, MY_CLASS));
58 crc = eina_crc((const char *) buffer, sizeof(*buffer), crc, EINA_FALSE);
59 if (pd->surface)
60 crc = eina_crc((const char *) pd->surface, sizeof(*pd->surface), crc, EINA_FALSE);
61
62 return crc;
63}
64
65EOLIAN static void
66_ector_renderer_software_buffer_efl_object_destructor(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd)
67{
68 efl_data_xunref(pd->base->surface, pd->surface, obj);
69 efl_destructor(efl_super(obj, MY_CLASS));
70}
71
72#include "ector_renderer_software_buffer.eo.c"
diff --git a/src/lib/ector/software/ector_renderer_software_buffer.eo b/src/lib/ector/software/ector_renderer_software_buffer.eo
deleted file mode 100644
index 91878f2286..0000000000
--- a/src/lib/ector/software/ector_renderer_software_buffer.eo
+++ /dev/null
@@ -1,20 +0,0 @@
1class Ector.Renderer.Software.Buffer (Ector.Renderer.Software, Ector.Renderer.Buffer)
2{
3 [[Ecto software renderer buffer class]]
4 methods {
5 @property buffer {
6 [[Buffer property]]
7 set {}
8 get {}
9 values {
10 buf: Ector.Buffer; [[Buffer]]
11 }
12 }
13 }
14 implements {
15 Ector.Renderer.prepare;
16 Ector.Renderer.crc { get; }
17 Ector.Renderer.Software.fill;
18 Efl.Object.destructor;
19 }
20}
diff --git a/src/lib/ector/software/ector_software_buffer.c b/src/lib/ector/software/ector_software_buffer.c
index 499206309d..d44962bbec 100644
--- a/src/lib/ector/software/ector_software_buffer.c
+++ b/src/lib/ector/software/ector_software_buffer.c
@@ -16,24 +16,13 @@ typedef struct _Ector_Software_Buffer_Map
16{ 16{
17 EINA_INLIST; 17 EINA_INLIST;
18 uint8_t *ptr; 18 uint8_t *ptr;
19 unsigned int size; // in bytes 19 unsigned int size, stride; // in bytes
20 unsigned int x, y, w, h; 20 unsigned int x, y, w, h;
21 Efl_Gfx_Colorspace cspace; 21 Efl_Gfx_Colorspace cspace;
22 Eina_Bool allocated; 22 Eina_Bool allocated;
23 Ector_Buffer_Access_Flag mode; 23 Ector_Buffer_Access_Flag mode;
24} Ector_Software_Buffer_Map; 24} Ector_Software_Buffer_Map;
25 25
26static inline int
27_min_stride_calc(int width, Efl_Gfx_Colorspace cspace)
28{
29 switch (cspace)
30 {
31 case EFL_GFX_COLORSPACE_ARGB8888: return width * 4;
32 case EFL_GFX_COLORSPACE_GRY8: return width;
33 default: return 0;
34 }
35}
36
37/* FIXME: Conversion routines don't belong here */ 26/* FIXME: Conversion routines don't belong here */
38static inline void 27static inline void
39_pixels_argb_to_gry8_convert(uint8_t *dst, const uint32_t *src, int len) 28_pixels_argb_to_gry8_convert(uint8_t *dst, const uint32_t *src, int len)
@@ -64,10 +53,7 @@ _ector_software_buffer_base_pixels_clear(Eo *obj, Ector_Software_Buffer_Base_Dat
64 return; 53 return;
65 54
66 if (pd->internal.maps) 55 if (pd->internal.maps)
67 { 56 fail("Can not call pixels_clear when the buffer is mapped.");
68 CRI("Can not call pixels_clear when the buffer is mapped.");
69 return;
70 }
71 57
72 efl_event_callback_call(obj, ECTOR_BUFFER_EVENT_DETACHED, pd->pixels.u8); 58 efl_event_callback_call(obj, ECTOR_BUFFER_EVENT_DETACHED, pd->pixels.u8);
73 if (!pd->nofree) 59 if (!pd->nofree)
@@ -76,54 +62,37 @@ _ector_software_buffer_base_pixels_clear(Eo *obj, Ector_Software_Buffer_Base_Dat
76 } 62 }
77 pd->pixels.u8 = NULL; 63 pd->pixels.u8 = NULL;
78 pd->nofree = EINA_FALSE; 64 pd->nofree = EINA_FALSE;
65
66 return;
67
68on_fail:
69 return;
79} 70}
80 71
81EOLIAN static Eina_Bool 72EOLIAN static Eina_Bool
82_ector_software_buffer_base_ector_buffer_pixels_set(Eo *obj, Ector_Software_Buffer_Base_Data *pd, 73_ector_software_buffer_base_ector_buffer_pixels_set(Eo *obj, Ector_Software_Buffer_Base_Data *pd,
83 void *pixels, int width, int height, int stride, 74 void *pixels, int width, int height,
84 Efl_Gfx_Colorspace cspace, Eina_Bool writable, 75 Efl_Gfx_Colorspace cspace, Eina_Bool writable)
85 unsigned char l, unsigned char r,
86 unsigned char t, unsigned char b)
87{ 76{
88 unsigned px; 77 unsigned pxs, stride;
89 78
90 if (pd->generic->immutable) 79 if (pd->generic->immutable)
91 { 80 fail("This buffer is immutable.");
92 ERR("This buffer is immutable.");
93 return EINA_FALSE;
94 }
95 81
96 if (pd->internal.maps) 82 if (pd->internal.maps)
97 { 83 fail("Can not call pixels_set when the buffer is mapped.");
98 ERR("Can not call pixels_set when the buffer is mapped.");
99 return EINA_FALSE;
100 }
101
102 // safety check
103 px = _min_stride_calc(1, cspace);
104 if (px && ((unsigned long long)(uintptr_t)pixels) & (px - 1))
105 ERR("Pixel data is not aligned to %u bytes!", px);
106
107 if ((cspace != EFL_GFX_COLORSPACE_ARGB8888) &&
108 (cspace != EFL_GFX_COLORSPACE_GRY8))
109 {
110 ERR("Unsupported colorspace: %u", cspace);
111 return EINA_FALSE;
112 }
113 84
114 if (!stride) 85 if (cspace == EFL_GFX_COLORSPACE_ARGB8888)
115 stride = _min_stride_calc(width + l + r, cspace); 86 pxs = 4;
116 else if (stride < _min_stride_calc(width + l + r, cspace)) 87 else if (cspace == EFL_GFX_COLORSPACE_GRY8)
117 { 88 pxs = 1;
118 ERR("Invalid stride %u for width %u (+%u+%u) cspace %u. pixels_set failed.", 89 else
119 stride, width, l, r, cspace); 90 fail("Unsupported colorspace: %u", cspace);
120 _ector_software_buffer_base_pixels_clear(obj, pd);
121 return EINA_FALSE;
122 }
123 91
124 if ((px > 1) && (stride & (px - 1))) 92 if (((unsigned long long)(uintptr_t)pixels) & (pxs - 1))
125 ERR("Stride (%d) is not aligned to the pixel size (%d)", stride, px); 93 fail ("Pixel data is not aligned to %u bytes!", pxs);
126 94
95 stride = width * pxs;
127 if (pd->pixels.u8 && (pd->pixels.u8 != pixels)) 96 if (pd->pixels.u8 && (pd->pixels.u8 != pixels))
128 _ector_software_buffer_base_pixels_clear(obj, pd); 97 _ector_software_buffer_base_pixels_clear(obj, pd);
129 98
@@ -135,31 +104,30 @@ _ector_software_buffer_base_ector_buffer_pixels_set(Eo *obj, Ector_Software_Buff
135 } 104 }
136 else 105 else
137 { 106 {
138 pd->pixels.u8 = calloc(stride * (height + t + b), 1); 107 pd->pixels.u8 = calloc(stride * height, 1);
139 pd->nofree = EINA_FALSE; 108 pd->nofree = EINA_FALSE;
140 pd->writable = EINA_TRUE; 109 pd->writable = EINA_TRUE;
141 } 110 }
142 pd->generic->w = width; 111 pd->generic->w = width;
143 pd->generic->h = height; 112 pd->generic->h = height;
144 pd->generic->l = l;
145 pd->generic->r = r;
146 pd->generic->t = t;
147 pd->generic->b = b;
148 pd->generic->cspace = cspace; 113 pd->generic->cspace = cspace;
149 pd->stride = stride; 114 pd->stride = stride;
150 pd->pixel_size = px; 115 pd->pixel_size = pxs;
151 return EINA_TRUE; 116 return EINA_TRUE;
117
118on_fail:
119 return EINA_FALSE;
152} 120}
153 121
154EOLIAN static void * 122EOLIAN static void *
155_ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd, 123_ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd,
156 unsigned int *length, Ector_Buffer_Access_Flag mode, 124 unsigned int *length, Ector_Buffer_Access_Flag mode,
157 unsigned int x, unsigned int y, unsigned int w, unsigned int h, 125 unsigned int x, unsigned int y, unsigned int w, unsigned int h,
158 Efl_Gfx_Colorspace cspace EINA_UNUSED, unsigned int *stride) 126 Efl_Gfx_Colorspace cspace EINA_UNUSED, unsigned int *stride)
159{ 127{
160 Ector_Software_Buffer_Map *map = NULL; 128 Ector_Software_Buffer_Map *map = NULL;
161 Eina_Bool need_cow = EINA_FALSE; 129 Eina_Bool need_cow = EINA_FALSE;
162 unsigned int off, k, dst_stride; 130 unsigned int off, k, dst_stride, pxs, pxs_dest;
163 131
164 if (!w) w = pd->generic->w; 132 if (!w) w = pd->generic->w;
165 if (!h) h = pd->generic->h; 133 if (!h) h = pd->generic->h;
@@ -172,6 +140,14 @@ _ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software
172 if ((mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) && !pd->writable) 140 if ((mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) && !pd->writable)
173 fail("Can not map a read-only buffer for writing"); 141 fail("Can not map a read-only buffer for writing");
174 142
143 pxs = (pd->generic->cspace == EFL_GFX_COLORSPACE_ARGB8888) ? 4 : 1;
144 if (cspace == EFL_GFX_COLORSPACE_ARGB8888)
145 pxs_dest = 4;
146 else if (cspace == EFL_GFX_COLORSPACE_GRY8)
147 pxs_dest = 1;
148 else
149 fail("Unsupported colorspace: %u", cspace);
150
175 if ((mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) && 151 if ((mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) &&
176 (mode & ECTOR_BUFFER_ACCESS_FLAG_COW)) 152 (mode & ECTOR_BUFFER_ACCESS_FLAG_COW))
177 { 153 {
@@ -186,20 +162,21 @@ _ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software
186 map = calloc(1, sizeof(*map)); 162 map = calloc(1, sizeof(*map));
187 if (!map) fail("Out of memory"); 163 if (!map) fail("Out of memory");
188 164
165 off = (pxs * x) + (pd->stride * y);
166 dst_stride = w * pxs_dest;
167
189 map->mode = mode; 168 map->mode = mode;
190 map->cspace = cspace; 169 map->cspace = cspace;
170 map->stride = dst_stride;
191 map->x = x; 171 map->x = x;
192 map->y = y; 172 map->y = y;
193 map->w = w; 173 map->w = w;
194 map->h = h; 174 map->h = h;
195 175
196 off = _min_stride_calc(x + pd->generic->l, pd->generic->cspace) + (pd->stride * (y + pd->generic->t));
197 dst_stride = _min_stride_calc(w, cspace);
198
199 if (cspace != pd->generic->cspace) 176 if (cspace != pd->generic->cspace)
200 { 177 {
201 // convert on the fly 178 // convert on the fly
202 map->size = _min_stride_calc(w, cspace) * h; 179 map->size = w * h * pxs_dest;
203 map->allocated = EINA_TRUE; 180 map->allocated = EINA_TRUE;
204 map->ptr = malloc(map->size); 181 map->ptr = malloc(map->size);
205 if (!map->ptr) fail("Out of memory"); 182 if (!map->ptr) fail("Out of memory");
@@ -218,7 +195,7 @@ _ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software
218 else if (need_cow) 195 else if (need_cow)
219 { 196 {
220 // copy-on-write access 197 // copy-on-write access
221 map->size = _min_stride_calc(w, cspace) * h; 198 map->size = w * h * pxs_dest;
222 map->allocated = EINA_TRUE; 199 map->allocated = EINA_TRUE;
223 map->ptr = malloc(map->size); 200 map->ptr = malloc(map->size);
224 if (!map->ptr) fail("Out of memory"); 201 if (!map->ptr) fail("Out of memory");
@@ -261,7 +238,7 @@ _ector_software_buffer_base_ector_buffer_unmap(Eo *obj EINA_UNUSED, Ector_Softwa
261 { 238 {
262 if (map->mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) 239 if (map->mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE)
263 { 240 {
264 unsigned k, dst_stride; 241 unsigned k;
265 242
266 if (map->cspace != pd->generic->cspace) 243 if (map->cspace != pd->generic->cspace)
267 { 244 {
@@ -282,12 +259,10 @@ _ector_software_buffer_base_ector_buffer_unmap(Eo *obj EINA_UNUSED, Ector_Softwa
282 } 259 }
283 else 260 else
284 { 261 {
285 dst_stride = _min_stride_calc(map->w, map->cspace);
286 for (k = 0; k < map->h; k++) 262 for (k = 0; k < map->h; k++)
287 { 263 {
288 memcpy(pd->pixels.u8 + map->x + (k + map->y) * pd->stride, 264 memcpy(pd->pixels.u8 + map->x + (k + map->y) * pd->stride,
289 map->ptr + k * dst_stride, 265 map->ptr + k * map->stride, map->stride);
290 dst_stride);
291 } 266 }
292 } 267 }
293 } 268 }
@@ -301,33 +276,14 @@ _ector_software_buffer_base_ector_buffer_unmap(Eo *obj EINA_UNUSED, Ector_Softwa
301 CRI("Tried to unmap a non-mapped region!"); 276 CRI("Tried to unmap a non-mapped region!");
302} 277}
303 278
304EOLIAN static uint8_t *
305_ector_software_buffer_base_ector_buffer_span_get(Eo *obj, Ector_Software_Buffer_Base_Data *pd,
306 int x, int y, unsigned int w, Efl_Gfx_Colorspace cspace,
307 unsigned int *length)
308{
309 // ector_buffer_map
310 return _ector_software_buffer_base_ector_buffer_map
311 (obj, pd, length, ECTOR_BUFFER_ACCESS_FLAG_READ, x, y, w, 1, cspace, NULL);
312}
313
314EOLIAN static void
315_ector_software_buffer_base_ector_buffer_span_free(Eo *obj, Ector_Software_Buffer_Base_Data *pd,
316 uint8_t *data)
317{
318 // ector_buffer_unmap
319 return _ector_software_buffer_base_ector_buffer_unmap
320 (obj, pd, data, (unsigned int) -1);
321}
322
323EOLIAN static Ector_Buffer_Flag 279EOLIAN static Ector_Buffer_Flag
324_ector_software_buffer_base_ector_buffer_flags_get(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd) 280_ector_software_buffer_base_ector_buffer_flags_get(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd)
325{ 281{
326 return ECTOR_BUFFER_FLAG_CPU_READABLE | 282 return ECTOR_BUFFER_FLAG_CPU_READABLE |
327 ECTOR_BUFFER_FLAG_DRAWABLE | 283 ECTOR_BUFFER_FLAG_DRAWABLE |
328 ECTOR_BUFFER_FLAG_CPU_READABLE_FAST | 284 ECTOR_BUFFER_FLAG_CPU_READABLE_FAST |
329 ECTOR_BUFFER_FLAG_RENDERABLE |
330 (pd->writable ? (ECTOR_BUFFER_FLAG_CPU_WRITABLE | 285 (pd->writable ? (ECTOR_BUFFER_FLAG_CPU_WRITABLE |
286 ECTOR_BUFFER_FLAG_RENDERABLE |
331 ECTOR_BUFFER_FLAG_CPU_WRITABLE_FAST) 287 ECTOR_BUFFER_FLAG_CPU_WRITABLE_FAST)
332 : 0); 288 : 0);
333} 289}
diff --git a/src/lib/ector/software/ector_software_buffer_base.eo b/src/lib/ector/software/ector_software_buffer_base.eo
index f3145d87aa..2a3b63ee67 100644
--- a/src/lib/ector/software/ector_software_buffer_base.eo
+++ b/src/lib/ector/software/ector_software_buffer_base.eo
@@ -10,8 +10,6 @@ mixin Ector.Software.Buffer.Base (Ector.Buffer)
10 implements { 10 implements {
11 Ector.Buffer.flags { get; } 11 Ector.Buffer.flags { get; }
12 Ector.Buffer.pixels_set; 12 Ector.Buffer.pixels_set;
13 Ector.Buffer.span_get;
14 Ector.Buffer.span_free;
15 Ector.Buffer.map; 13 Ector.Buffer.map;
16 Ector.Buffer.unmap; 14 Ector.Buffer.unmap;
17 } 15 }
diff --git a/src/lib/ector/software/ector_software_private.h b/src/lib/ector/software/ector_software_private.h
index d11ba3adc0..459de0105d 100644
--- a/src/lib/ector/software/ector_software_private.h
+++ b/src/lib/ector/software/ector_software_private.h
@@ -61,7 +61,6 @@ typedef enum _Span_Data_Type {
61 Solid, 61 Solid,
62 LinearGradient, 62 LinearGradient,
63 RadialGradient, 63 RadialGradient,
64 Image
65} Span_Data_Type; 64} Span_Data_Type;
66 65
67typedef struct _Span_Data 66typedef struct _Span_Data
@@ -114,7 +113,6 @@ void ector_software_rasterizer_transform_set(Software_Rasterizer *rasterizer, Ei
114void ector_software_rasterizer_color_set(Software_Rasterizer *rasterizer, int r, int g, int b, int a); 113void ector_software_rasterizer_color_set(Software_Rasterizer *rasterizer, int r, int g, int b, int a);
115void ector_software_rasterizer_linear_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *linear); 114void ector_software_rasterizer_linear_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *linear);
116void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *radial); 115void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *radial);
117void ector_software_rasterizer_buffer_set(Software_Rasterizer *rasterizer, Ector_Software_Buffer *image);
118void ector_software_rasterizer_clip_rect_set(Software_Rasterizer *rasterizer, Eina_Array *clips); 116void ector_software_rasterizer_clip_rect_set(Software_Rasterizer *rasterizer, Eina_Array *clips);
119void ector_software_rasterizer_clip_shape_set(Software_Rasterizer *rasterizer, Shape_Rle_Data *clip); 117void ector_software_rasterizer_clip_shape_set(Software_Rasterizer *rasterizer, Shape_Rle_Data *clip);
120 118
diff --git a/src/lib/ector/software/ector_software_rasterizer.c b/src/lib/ector/software/ector_software_rasterizer.c
index b0ea4834af..9c91856ebb 100644
--- a/src/lib/ector/software/ector_software_rasterizer.c
+++ b/src/lib/ector/software/ector_software_rasterizer.c
@@ -76,45 +76,6 @@ _blend_gradient(int count, const SW_FT_Span *spans, void *user_data)
76 } 76 }
77} 77}
78 78
79static void
80_blend_image_argb(int count, const SW_FT_Span *spans, void *user_data)
81{
82 Span_Data *data = user_data;
83 RGBA_Comp_Func comp_func;
84 uint32_t *buffer, *target;
85 uint8_t *src8;
86 unsigned int l, length, sy = 0;
87 const int pix_stride = data->raster_buffer->stride / 4;
88
89 /* FIXME:
90 * optimize eo call
91 * implement image scaling
92 * tile and repeat image properly
93 */
94
95 comp_func = efl_draw_func_span_get(data->op, data->mul_col, EINA_TRUE);
96 buffer = data->raster_buffer->pixels.u32 + ((pix_stride * data->offy) + data->offx);
97
98 while (count--)
99 {
100 target = buffer + ((pix_stride * spans->y) + spans->x);
101 length = spans->len;
102 while (length)
103 {
104 l = MIN(length, data->buffer->generic->w);
105 src8 = ector_buffer_span_get(data->buffer->generic->eo, 0, sy, l, EFL_GFX_COLORSPACE_ARGB8888, NULL);
106 comp_func(target, (uint32_t *) src8, l, data->mul_col, spans->coverage);
107 ector_buffer_span_free(data->buffer->generic->eo, src8);
108 target += l;
109 length -= l;
110 }
111 ++spans;
112 ++sy;
113 if (sy >= data->buffer->generic->h)
114 sy = 0;
115 }
116}
117
118/*! 79/*!
119 \internal 80 \internal
120 spans must be sorted on y 81 spans must be sorted on y
@@ -318,9 +279,6 @@ _adjust_span_fill_methods(Span_Data *spdata)
318 case RadialGradient: 279 case RadialGradient:
319 spdata->unclipped_blend = &_blend_gradient; 280 spdata->unclipped_blend = &_blend_gradient;
320 break; 281 break;
321 case Image:
322 spdata->unclipped_blend = &_blend_image_argb;
323 break;
324 } 282 }
325 283
326 // setup clipping 284 // setup clipping
@@ -568,13 +526,6 @@ void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasteriz
568 rasterizer->fill_data.type = RadialGradient; 526 rasterizer->fill_data.type = RadialGradient;
569} 527}
570 528
571void ector_software_rasterizer_buffer_set(Software_Rasterizer *rasterizer,
572 Ector_Software_Buffer *buffer)
573{
574 rasterizer->fill_data.buffer = efl_data_scope_get(buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
575 rasterizer->fill_data.type = Image;
576}
577
578void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer, 529void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
579 int x, int y, uint32_t mul_col, 530 int x, int y, uint32_t mul_col,
580 Efl_Gfx_Render_Op op, Shape_Rle_Data* rle) 531 Efl_Gfx_Render_Op op, Shape_Rle_Data* rle)
diff --git a/src/lib/ector/software/ector_software_surface.c b/src/lib/ector/software/ector_software_surface.c
index f1492a2a28..1631449a73 100644
--- a/src/lib/ector/software/ector_software_surface.c
+++ b/src/lib/ector/software/ector_software_surface.c
@@ -12,8 +12,8 @@
12 12
13static Ector_Renderer * 13static Ector_Renderer *
14_ector_software_surface_ector_surface_renderer_factory_new(Eo *obj, 14_ector_software_surface_ector_surface_renderer_factory_new(Eo *obj,
15 Ector_Software_Surface_Data *pd EINA_UNUSED, 15 Ector_Software_Surface_Data *pd EINA_UNUSED,
16 const Efl_Class *type) 16 const Efl_Class *type)
17{ 17{
18 if (type == ECTOR_RENDERER_SHAPE_MIXIN) 18 if (type == ECTOR_RENDERER_SHAPE_MIXIN)
19 return efl_add(ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS, NULL, ector_renderer_surface_set(efl_added, obj)); 19 return efl_add(ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS, NULL, ector_renderer_surface_set(efl_added, obj));
@@ -21,9 +21,8 @@ _ector_software_surface_ector_surface_renderer_factory_new(Eo *obj,
21 return efl_add(ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS, NULL, ector_renderer_surface_set(efl_added, obj)); 21 return efl_add(ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS, NULL, ector_renderer_surface_set(efl_added, obj));
22 else if (type == ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN) 22 else if (type == ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN)
23 return efl_add(ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS, NULL, ector_renderer_surface_set(efl_added, obj)); 23 return efl_add(ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS, NULL, ector_renderer_surface_set(efl_added, obj));
24 else if (type == ECTOR_RENDERER_BUFFER_MIXIN) 24
25 return efl_add(ECTOR_RENDERER_SOFTWARE_BUFFER_CLASS, NULL, ector_renderer_surface_set(efl_added, obj)); 25 ERR("Couldn't find class for type: %s", efl_class_name_get(type));
26 ERR("Couldn't find class for type: %s\n", efl_class_name_get(type));
27 return NULL; 26 return NULL;
28} 27}
29 28
@@ -49,8 +48,8 @@ _ector_software_surface_efl_object_destructor(Eo *obj, Ector_Software_Surface_Da
49 48
50static void 49static void
51_ector_software_surface_ector_surface_reference_point_set(Eo *obj EINA_UNUSED, 50_ector_software_surface_ector_surface_reference_point_set(Eo *obj EINA_UNUSED,
52 Ector_Software_Surface_Data *pd, 51 Ector_Software_Surface_Data *pd,
53 int x, int y) 52 int x, int y)
54{ 53{
55 pd->x = x; 54 pd->x = x;
56 pd->y = y; 55 pd->y = y;
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index d00aa44a23..98a1cb8820 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -29,29 +29,19 @@
29 29
30static void _buffer_free(Evas_Filter_Buffer *fb); 30static void _buffer_free(Evas_Filter_Buffer *fb);
31static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd); 31static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd);
32static Ector_Buffer* _ector_buffer_create(Evas_Filter_Buffer const *fb, void *data); 32static Evas_Filter_Buffer *_buffer_alloc_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only, Eina_Bool render, Eina_Bool draw);
33 33
34#define DRAW_COLOR_SET(r, g, b, a) do { cmd->draw.R = r; cmd->draw.G = g; cmd->draw.B = b; cmd->draw.A = a; } while (0) 34#define DRAW_COLOR_SET(r, g, b, a) do { cmd->draw.R = r; cmd->draw.G = g; cmd->draw.B = b; cmd->draw.A = a; } while (0)
35#define DRAW_CLIP_SET(_x, _y, _w, _h) do { cmd->draw.clip.x = _x; cmd->draw.clip.y = _y; cmd->draw.clip.w = _w; cmd->draw.clip.h = _h; } while (0) 35#define DRAW_CLIP_SET(_x, _y, _w, _h) do { cmd->draw.clip.x = _x; cmd->draw.clip.y = _y; cmd->draw.clip.w = _w; cmd->draw.clip.h = _h; } while (0)
36#define DRAW_FILL_SET(fmode) do { cmd->draw.fillmode = fmode; } while (0) 36#define DRAW_FILL_SET(fmode) do { cmd->draw.fillmode = fmode; } while (0)
37 37
38static inline void *
39_evas_image_get(Ector_Buffer *buf)
40{
41 void *image = NULL;
42 if (!buf) return NULL;
43 /* FIXME: This MAY return RGBA_Image because engine_image_set MAY pass an
44 * RGBA_Image... Baaaaah */
45 evas_ector_buffer_engine_image_get(buf, NULL, &image);
46 return image;
47}
48
49/* Main functions */ 38/* Main functions */
50 39
51Evas_Filter_Context * 40Evas_Filter_Context *
52evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async, void *user_data) 41evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async, void *user_data)
53{ 42{
54 Evas_Filter_Context *ctx; 43 Evas_Filter_Context *ctx;
44 static int warned = 0;
55 45
56 EINA_SAFETY_ON_NULL_RETURN_VAL(evas, NULL); 46 EINA_SAFETY_ON_NULL_RETURN_VAL(evas, NULL);
57 EINA_SAFETY_ON_NULL_RETURN_VAL(evas->engine.func->gfx_filter_supports, NULL); 47 EINA_SAFETY_ON_NULL_RETURN_VAL(evas->engine.func->gfx_filter_supports, NULL);
@@ -65,6 +55,16 @@ evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async, void *user_data
65 ctx->user_data = user_data; 55 ctx->user_data = user_data;
66 ctx->buffer_scaled_get = &evas_filter_buffer_scaled_get; 56 ctx->buffer_scaled_get = &evas_filter_buffer_scaled_get;
67 57
58 if (ENFN->gl_surface_read_pixels)
59 {
60 ctx->gl = EINA_TRUE;
61 if (!warned)
62 {
63 WRN("OpenGL support through SW functions, expect low performance!");
64 warned = 1;
65 }
66 }
67
68 return ctx; 68 return ctx;
69} 69}
70 70
@@ -146,7 +146,7 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
146 } 146 }
147 _filter_buffer_backing_free(fb); 147 _filter_buffer_backing_free(fb);
148 XDBG("Source #%d '%s' has dimensions %dx%d", fb->id, fb->source_name, fb->w, fb->h); 148 XDBG("Source #%d '%s' has dimensions %dx%d", fb->id, fb->source_name, fb->w, fb->h);
149 fb->buffer = ENFN->ector_buffer_wrap(ENDT, obj->layer->evas->evas, source->proxy->surface, EINA_FALSE); 149 fb->buffer = ENFN->ector_buffer_wrap(ENDT, obj->layer->evas->evas, source->proxy->surface);
150 fb->alpha_only = EINA_FALSE; 150 fb->alpha_only = EINA_FALSE;
151 } 151 }
152} 152}
@@ -180,7 +180,8 @@ evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx,
180} 180}
181 181
182static Evas_Filter_Buffer * 182static Evas_Filter_Buffer *
183_buffer_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only) 183_buffer_empty_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only,
184 Eina_Bool transient)
184{ 185{
185 Evas_Filter_Buffer *fb; 186 Evas_Filter_Buffer *fb;
186 187
@@ -190,7 +191,7 @@ _buffer_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only)
190 fb->id = ++(ctx->last_buffer_id); 191 fb->id = ++(ctx->last_buffer_id);
191 fb->ctx = ctx; 192 fb->ctx = ctx;
192 fb->alpha_only = alpha_only; 193 fb->alpha_only = alpha_only;
193 fb->transient = EINA_TRUE; 194 fb->transient = transient;
194 fb->w = w; 195 fb->w = w;
195 fb->h = h; 196 fb->h = h;
196 197
@@ -199,26 +200,19 @@ _buffer_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only)
199} 200}
200 201
201static Ector_Buffer * 202static Ector_Buffer *
202_ector_buffer_create(Evas_Filter_Buffer const *fb, void *data) 203_ector_buffer_create(Evas_Filter_Buffer const *fb, Eina_Bool render, Eina_Bool draw)
203{ 204{
204 Evas_Colorspace cspace; 205 Efl_Gfx_Colorspace cspace = EFL_GFX_COLORSPACE_ARGB8888;
205 Ector_Buffer_Flag flags; 206 Ector_Buffer_Flag flags;
206 207
207 // FIXME: We still rely on evas image structs (scaling and target render) 208 // FIXME: Once all filters are GL buffers need not be CPU accessible
208 // This should be fixed by implementing full support in ector
209 // Note: dropped support for cserve2, that was not needed anyway
210
211 flags = ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_CPU_WRITABLE; 209 flags = ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_CPU_WRITABLE;
212 if (fb->id == EVAS_FILTER_BUFFER_INPUT_ID) 210 if (render) flags |= ECTOR_BUFFER_FLAG_RENDERABLE;
213 flags |= ECTOR_BUFFER_FLAG_RENDERABLE; 211 if (draw) flags |= ECTOR_BUFFER_FLAG_DRAWABLE;
214 else if (fb->id == EVAS_FILTER_BUFFER_OUTPUT_ID) 212 if (fb->alpha_only) cspace = EFL_GFX_COLORSPACE_GRY8;
215 flags |= ECTOR_BUFFER_FLAG_DRAWABLE;
216 213
217 cspace = fb->alpha_only ? EVAS_COLORSPACE_GRY8 : EVAS_COLORSPACE_ARGB8888;
218 return fb->ENFN->ector_buffer_new(fb->ENDT, fb->ctx->evas->evas, 214 return fb->ENFN->ector_buffer_new(fb->ENDT, fb->ctx->evas->evas,
219 data, fb->w, fb->h, 0, 215 fb->w, fb->h, cspace, flags);
220 (Efl_Gfx_Colorspace )cspace, EINA_TRUE,
221 0, 0, 0, 0, flags);
222} 216}
223 217
224Eina_Bool 218Eina_Bool
@@ -276,7 +270,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
276 if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) 270 if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
277 sh = h; 271 sh = h;
278 272
279 fb = evas_filter_buffer_alloc_new(ctx, sw, sh, in->alpha_only); 273 fb = _buffer_alloc_new(ctx, sw, sh, in->alpha_only, 1, 1);
280 XDBG("Allocated temporary buffer #%d of size %ux%u %s", 274 XDBG("Allocated temporary buffer #%d of size %ux%u %s",
281 fb ? fb->id : -1, sw, sh, in->alpha_only ? "alpha" : "rgba"); 275 fb ? fb->id : -1, sw, sh, in->alpha_only ? "alpha" : "rgba");
282 if (!fb) goto alloc_fail; 276 if (!fb) goto alloc_fail;
@@ -292,7 +286,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
292 if (in->w) sw = in->w; 286 if (in->w) sw = in->w;
293 if (in->h) sh = in->h; 287 if (in->h) sh = in->h;
294 288
295 fb = evas_filter_buffer_alloc_new(ctx, sw, sh, in->alpha_only); 289 fb = _buffer_alloc_new(ctx, sw, sh, in->alpha_only, 1, 1);
296 XDBG("Allocated temporary buffer #%d of size %ux%u %s", 290 XDBG("Allocated temporary buffer #%d of size %ux%u %s",
297 fb ? fb->id : -1, sw, sh, in->alpha_only ? "alpha" : "rgba"); 291 fb ? fb->id : -1, sw, sh, in->alpha_only ? "alpha" : "rgba");
298 if (!fb) goto alloc_fail; 292 if (!fb) goto alloc_fail;
@@ -309,6 +303,8 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
309 303
310 EINA_LIST_FOREACH(ctx->buffers, li, fb) 304 EINA_LIST_FOREACH(ctx->buffers, li, fb)
311 { 305 {
306 Eina_Bool render = EINA_FALSE, draw = EINA_FALSE;
307
312 if (fb->buffer || fb->source) 308 if (fb->buffer || fb->source)
313 continue; 309 continue;
314 310
@@ -318,7 +314,11 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
318 continue; 314 continue;
319 } 315 }
320 316
321 fb->buffer = _ector_buffer_create(fb, NULL); 317 render |= (fb->id == EVAS_FILTER_BUFFER_INPUT_ID);
318 render |= fb->is_render;
319 draw |= (fb->id == EVAS_FILTER_BUFFER_OUTPUT_ID);
320
321 fb->buffer = _ector_buffer_create(fb, render, draw);
322 XDBG("Allocated buffer #%d of size %ux%u %s: %p", 322 XDBG("Allocated buffer #%d of size %ux%u %s: %p",
323 fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba", fb->buffer); 323 fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba", fb->buffer);
324 if (!fb->buffer) goto alloc_fail; 324 if (!fb->buffer) goto alloc_fail;
@@ -338,64 +338,16 @@ evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only)
338 338
339 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); 339 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
340 340
341 fb = _buffer_new(ctx, 0, 0, alpha_only); 341 fb = _buffer_empty_new(ctx, 0, 0, alpha_only, EINA_FALSE);
342 if (!fb) return -1; 342 if (!fb) return -1;
343 343
344 fb->transient = EINA_FALSE;
345
346 XDBG("Created context buffer %d %s", fb->id, alpha_only ? "alpha" : "rgba"); 344 XDBG("Created context buffer %d %s", fb->id, alpha_only ? "alpha" : "rgba");
347 return fb->id; 345 return fb->id;
348} 346}
349 347
350Eina_Bool 348static Evas_Filter_Buffer *
351_filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data, 349_buffer_alloc_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only,
352 int w, int h, Eina_Bool alpha_only) 350 Eina_Bool render, Eina_Bool draw)
353{
354 Evas_Filter_Buffer *fb;
355
356 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
357
358 fb = _filter_buffer_get(ctx, bufid);
359 if (!fb) return EINA_FALSE;
360
361 _filter_buffer_backing_free(fb);
362 if (w <= 0 || h <= 0)
363 return EINA_FALSE;
364
365 EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->buffer == NULL, EINA_FALSE);
366 // TODO: Check input parameters?
367 fb->alpha_only = alpha_only;
368 fb->w = w;
369 fb->h = h;
370
371 fb->buffer = _ector_buffer_create(fb, data);
372 return (fb->buffer != NULL);
373}
374
375static int
376_filter_buffer_new_from_evas_surface(Evas_Filter_Context *ctx, void *image)
377{
378 Evas_Filter_Buffer *fb;
379
380 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
381
382 fb = calloc(1, sizeof(Evas_Filter_Buffer));
383 if (!fb) return -1;
384
385 fb->id = ++(ctx->last_buffer_id);
386 fb->ctx = ctx;
387 fb->buffer = ENFN->ector_buffer_wrap(ENDT, ctx->evas->evas, image, EINA_FALSE);
388 ENFN->image_size_get(ENDT, image, &fb->w, &fb->h);
389 fb->alpha_only = (ENFN->image_colorspace_get(ENDT, image)
390 == EVAS_COLORSPACE_GRY8);
391
392 ctx->buffers = eina_list_append(ctx->buffers, fb);
393 return fb->id;
394}
395
396Evas_Filter_Buffer *
397_filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h,
398 Eina_Bool alpha_only)
399{ 351{
400 Evas_Filter_Buffer *fb; 352 Evas_Filter_Buffer *fb;
401 353
@@ -407,15 +359,18 @@ _filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h,
407 359
408 fb->id = ++(ctx->last_buffer_id); 360 fb->id = ++(ctx->last_buffer_id);
409 fb->ctx = ctx; 361 fb->ctx = ctx;
410 ctx->buffers = eina_list_append(ctx->buffers, fb); 362 fb->w = w;
411 363 fb->h = h;
412 if (!_filter_buffer_data_set(ctx, fb->id, data, w, h, alpha_only)) 364 fb->alpha_only = alpha_only;
365 fb->buffer = _ector_buffer_create(fb, render, draw);
366 if (!fb->buffer)
413 { 367 {
414 ctx->buffers = eina_list_remove(ctx->buffers, fb); 368 ERR("Failed to create ector buffer!");
415 free(fb); 369 free(fb);
416 return NULL; 370 return NULL;
417 } 371 }
418 372
373 ctx->buffers = eina_list_append(ctx->buffers, fb);
419 return fb; 374 return fb;
420} 375}
421 376
@@ -441,17 +396,6 @@ _filter_buffer_get(Evas_Filter_Context *ctx, int bufid)
441} 396}
442 397
443void * 398void *
444evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid)
445{
446 Evas_Filter_Buffer *fb;
447
448 fb = _filter_buffer_get(ctx, bufid);
449 if (!fb) return NULL;
450
451 return _evas_image_get(fb->buffer);
452}
453
454void *
455evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid) 399evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid)
456{ 400{
457 Evas_Filter_Buffer *fb; 401 Evas_Filter_Buffer *fb;
@@ -459,7 +403,7 @@ evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid)
459 fb = _filter_buffer_get(ctx, bufid); 403 fb = _filter_buffer_get(ctx, bufid);
460 if (!fb) return NULL; 404 if (!fb) return NULL;
461 405
462 return fb->ENFN->image_ref(fb->ENDT, _evas_image_get(fb->buffer)); 406 return evas_ector_buffer_drawable_image_get(fb->buffer, EINA_TRUE);
463} 407}
464 408
465Eina_Bool 409Eina_Bool
@@ -468,10 +412,7 @@ evas_filter_buffer_backing_release(Evas_Filter_Context *ctx,
468{ 412{
469 if (!stolen_buffer) return EINA_FALSE; 413 if (!stolen_buffer) return EINA_FALSE;
470 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); 414 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
471
472#ifdef DEBUG
473 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_main_loop_is(), EINA_FALSE); 415 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_main_loop_is(), EINA_FALSE);
474#endif
475 416
476 ENFN->image_free(ENDT, stolen_buffer); 417 ENFN->image_free(ENDT, stolen_buffer);
477 return EINA_TRUE; 418 return EINA_TRUE;
@@ -511,19 +452,6 @@ _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd)
511 free(cmd); 452 free(cmd);
512} 453}
513 454
514Evas_Filter_Command *
515_evas_filter_command_get(Evas_Filter_Context *ctx, int cmdid)
516{
517 Evas_Filter_Command *cmd;
518
519 if (cmdid <= 0) return NULL;
520
521 EINA_INLIST_FOREACH(ctx->commands, cmd)
522 if (cmd->id == cmdid) return cmd;
523
524 return NULL;
525}
526
527Evas_Filter_Buffer * 455Evas_Filter_Buffer *
528evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, 456evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h,
529 Eina_Bool alpha_only) 457 Eina_Bool alpha_only)
@@ -535,8 +463,7 @@ evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h,
535 { 463 {
536 if (buf->transient && !buf->locked && (buf->alpha_only == alpha_only)) 464 if (buf->transient && !buf->locked && (buf->alpha_only == alpha_only))
537 { 465 {
538 if ((!w || (w == buf->w)) 466 if ((!w || (w == buf->w)) && (!h || (h == buf->h)))
539 && (!h || (h == buf->h)))
540 { 467 {
541 buf->locked = EINA_TRUE; 468 buf->locked = EINA_TRUE;
542 return buf; 469 return buf;
@@ -544,14 +471,15 @@ evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h,
544 } 471 }
545 } 472 }
546 473
547 if (ctx->running) // && ctx->async) 474 if (ctx->running)
548 { 475 {
549 ERR("Can not create a new buffer from this thread!"); 476 ERR("Can not create a new buffer while filter is running!");
550 return NULL; 477 return NULL;
551 } 478 }
552 479
553 buf = _buffer_new(ctx, w, h, alpha_only); 480 buf = _buffer_empty_new(ctx, w, h, alpha_only, EINA_TRUE);
554 buf->locked = EINA_TRUE; 481 buf->locked = EINA_TRUE;
482
555 return buf; 483 return buf;
556} 484}
557 485
@@ -565,7 +493,7 @@ _filter_buffer_unlock_all(Evas_Filter_Context *ctx)
565 buf->locked = EINA_FALSE; 493 buf->locked = EINA_FALSE;
566} 494}
567 495
568int 496Evas_Filter_Command *
569evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, 497evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context,
570 int bufid) 498 int bufid)
571{ 499{
@@ -573,18 +501,18 @@ evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context,
573 Evas_Filter_Buffer *buf = NULL; 501 Evas_Filter_Buffer *buf = NULL;
574 int R, G, B, A, cx, cy, cw, ch; 502 int R, G, B, A, cx, cy, cw, ch;
575 503
576 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); 504 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
577 EINA_SAFETY_ON_NULL_RETURN_VAL(draw_context, -1); 505 EINA_SAFETY_ON_NULL_RETURN_VAL(draw_context, NULL);
578 506
579 buf = _filter_buffer_get(ctx, bufid); 507 buf = _filter_buffer_get(ctx, bufid);
580 if (!buf) 508 if (!buf)
581 { 509 {
582 ERR("Buffer %d does not exist.", bufid); 510 ERR("Buffer %d does not exist.", bufid);
583 return -1; 511 return NULL;
584 } 512 }
585 513
586 cmd = _command_new(ctx, EVAS_FILTER_MODE_FILL, buf, NULL, buf); 514 cmd = _command_new(ctx, EVAS_FILTER_MODE_FILL, buf, NULL, buf);
587 if (!cmd) return -1; 515 if (!cmd) return NULL;
588 516
589 ENFN->context_color_get(ENDT, draw_context, &R, &G, &B, &A); 517 ENFN->context_color_get(ENDT, draw_context, &R, &G, &B, &A);
590 DRAW_COLOR_SET(R, G, B, A); 518 DRAW_COLOR_SET(R, G, B, A);
@@ -592,25 +520,26 @@ evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context,
592 ENFN->context_clip_get(ENDT, draw_context, &cx, &cy, &cw, &ch); 520 ENFN->context_clip_get(ENDT, draw_context, &cx, &cy, &cw, &ch);
593 DRAW_CLIP_SET(cx, cy, cw, ch); 521 DRAW_CLIP_SET(cx, cy, cw, ch);
594 522
523 XDBG("Add fill %d with color(%d,%d,%d,%d)", buf->id, R, G, B, A);
524
595 buf->dirty = EINA_TRUE; 525 buf->dirty = EINA_TRUE;
596 return cmd->id; 526 return cmd;
597} 527}
598 528
599int 529Evas_Filter_Command *
600evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx, 530evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
601 int inbuf, int outbuf, Evas_Filter_Blur_Type type, 531 int inbuf, int outbuf, Evas_Filter_Blur_Type type,
602 int dx, int dy, int ox, int oy, int count) 532 int dx, int dy, int ox, int oy, int count)
603{ 533{
604 Evas_Filter_Command *cmd = NULL;
605 Evas_Filter_Buffer *in = NULL, *out = NULL, *tmp = NULL, *in_dy = NULL; 534 Evas_Filter_Buffer *in = NULL, *out = NULL, *tmp = NULL, *in_dy = NULL;
606 Evas_Filter_Buffer *out_dy = NULL, *out_dx = NULL; 535 Evas_Filter_Buffer *out_dy = NULL, *out_dx = NULL;
607 Evas_Filter_Buffer *copybuf = NULL, *blur_out = NULL; 536 Evas_Filter_Buffer *copybuf = NULL, *blur_out = NULL;
608 Eina_Bool copy_back = EINA_FALSE, blend = EINA_FALSE; 537 Eina_Bool copy_back = EINA_FALSE, blend = EINA_FALSE;
538 Evas_Filter_Command *cmd = NULL;
609 int R, G, B, A; DATA32 color; 539 int R, G, B, A; DATA32 color;
610 int ret = 0, id;
611 540
612 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); 541 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
613 EINA_SAFETY_ON_NULL_RETURN_VAL(drawctx, -1); 542 EINA_SAFETY_ON_NULL_RETURN_VAL(drawctx, NULL);
614 543
615 if (dx < 0) dx = 0; 544 if (dx < 0) dx = 0;
616 if (dy < 0) dy = 0; 545 if (dy < 0) dy = 0;
@@ -621,18 +550,10 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
621 } 550 }
622 551
623 in = _filter_buffer_get(ctx, inbuf); 552 in = _filter_buffer_get(ctx, inbuf);
624 if (!in) 553 EINA_SAFETY_ON_FALSE_GOTO(in, fail);
625 {
626 ERR("Buffer %d does not exist [input].", inbuf);
627 goto fail;
628 }
629 554
630 out = _filter_buffer_get(ctx, outbuf); 555 out = _filter_buffer_get(ctx, outbuf);
631 if (!out) 556 EINA_SAFETY_ON_FALSE_GOTO(out, fail);
632 {
633 ERR("Buffer %d does not exist [output].", outbuf);
634 goto fail;
635 }
636 557
637 if (!in->alpha_only && out->alpha_only) 558 if (!in->alpha_only && out->alpha_only)
638 DBG("Different color formats, implicit conversion may be slow"); 559 DBG("Different color formats, implicit conversion may be slow");
@@ -676,7 +597,6 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
676 int tmp_ox = ox; 597 int tmp_ox = ox;
677 int tmp_oy = oy; 598 int tmp_oy = oy;
678 599
679 id = -1;
680 if (dx && dy) 600 if (dx && dy)
681 { 601 {
682 tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, alpha); 602 tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, alpha);
@@ -690,14 +610,13 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
690 if (dx <= 2) 610 if (dx <= 2)
691 type = EVAS_FILTER_BLUR_GAUSSIAN; 611 type = EVAS_FILTER_BLUR_GAUSSIAN;
692 else 612 else
693 type = EVAS_FILTER_BLUR_BOX; 613 type = EVAS_FILTER_BLUR_BOX;
694 614
695 if (dy && (color != 0xFFFFFFFF)) 615 if (dy && (color != 0xFFFFFFFF))
696 ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255); 616 ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
697 id = evas_filter_command_blur_add(ctx, drawctx, inbuf, tmp_out, 617 cmd = evas_filter_command_blur_add(ctx, drawctx, inbuf, tmp_out,
698 type, dx, 0, tmp_ox, tmp_oy, 0); 618 type, dx, 0, tmp_ox, tmp_oy, 0);
699 if (id < 0) goto fail; 619 if (!cmd) goto fail;
700 cmd = _evas_filter_command_get(ctx, id);
701 cmd->blur.auto_count = EINA_TRUE; 620 cmd->blur.auto_count = EINA_TRUE;
702 if (dy && (color != 0xFFFFFFFF)) 621 if (dy && (color != 0xFFFFFFFF))
703 ENFN->context_color_set(ENDT, drawctx, R, G, B, A); 622 ENFN->context_color_set(ENDT, drawctx, R, G, B, A);
@@ -710,14 +629,13 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
710 else 629 else
711 type = EVAS_FILTER_BLUR_BOX; 630 type = EVAS_FILTER_BLUR_BOX;
712 631
713 id = evas_filter_command_blur_add(ctx, drawctx, tmp_in, outbuf, 632 cmd = evas_filter_command_blur_add(ctx, drawctx, tmp_in, outbuf,
714 type, 0, dy, ox, oy, 0); 633 type, 0, dy, ox, oy, 0);
715 if (id < 0) goto fail; 634 if (!cmd) goto fail;
716 cmd = _evas_filter_command_get(ctx, id);
717 cmd->blur.auto_count = EINA_TRUE; 635 cmd->blur.auto_count = EINA_TRUE;
718 } 636 }
719 637
720 return id; 638 return cmd;
721 } 639 }
722 break; 640 break;
723 641
@@ -818,7 +736,6 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
818 cmd->blur.count = count; 736 cmd->blur.count = count;
819 if (!dy && !blend) 737 if (!dy && !blend)
820 DRAW_COLOR_SET(R, G, B, A); 738 DRAW_COLOR_SET(R, G, B, A);
821 ret = cmd->id;
822 } 739 }
823 740
824 if (dy) 741 if (dy)
@@ -832,45 +749,47 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
832 cmd->blur.count = count; 749 cmd->blur.count = count;
833 if (!blend) 750 if (!blend)
834 DRAW_COLOR_SET(R, G, B, A); 751 DRAW_COLOR_SET(R, G, B, A);
835 if (ret <= 0) ret = cmd->id;
836 } 752 }
837 753
838 if (copy_back) 754 if (copy_back)
839 { 755 {
756 Evas_Filter_Command *copycmd;
840 int render_op; 757 int render_op;
841 758
842 if (!cmd) goto fail; 759 if (!cmd) goto fail;
843 XDBG("Add copy %d -> %d", copybuf->id, blur_out->id); 760 XDBG("Add copy %d -> %d", copybuf->id, blur_out->id);
844 cmd->ENFN->context_color_set(cmd->ENDT, drawctx, 255, 255, 255, 255); 761 ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
845 render_op = cmd->ENFN->context_render_op_get(cmd->ENDT, drawctx); 762 render_op = ENFN->context_render_op_get(ENDT, drawctx);
846 cmd->ENFN->context_render_op_set(cmd->ENDT, drawctx, EVAS_RENDER_COPY); 763 ENFN->context_render_op_set(ENDT, drawctx, EVAS_RENDER_COPY);
847 id = evas_filter_command_blend_add(ctx, drawctx, copybuf->id, blur_out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE); 764 copycmd = evas_filter_command_blend_add(ctx, drawctx, copybuf->id, blur_out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE);
848 cmd->ENFN->context_color_set(cmd->ENDT, drawctx, R, G, B, A); 765 ENFN->context_color_set(ENDT, drawctx, R, G, B, A);
849 cmd->ENFN->context_render_op_set(cmd->ENDT, drawctx, render_op); 766 ENFN->context_render_op_set(ENDT, drawctx, render_op);
850 if (id < 0) goto fail; 767 if (!copycmd) goto fail;
851 ox = oy = 0; 768 ox = oy = 0;
852 } 769 }
853 770
854 if (blend) 771 if (blend)
855 { 772 {
773 Evas_Filter_Command *blendcmd;
774
856 XDBG("Add blend %d (%s) -> %d (%s)", 775 XDBG("Add blend %d (%s) -> %d (%s)",
857 blur_out->id, blur_out->alpha_only ? "Alpha" : "RGBA", 776 blur_out->id, blur_out->alpha_only ? "Alpha" : "RGBA",
858 out->id, out->alpha_only ? "Alpha" : "RGBA"); 777 out->id, out->alpha_only ? "Alpha" : "RGBA");
859 id = evas_filter_command_blend_add(ctx, drawctx, blur_out->id, out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE); 778 blendcmd = evas_filter_command_blend_add(ctx, drawctx, blur_out->id, out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE);
860 if (id < 0) goto fail; 779 if (!blendcmd) goto fail;
861 } 780 }
862 781
863 out->dirty = EINA_TRUE; 782 out->dirty = EINA_TRUE;
864 _filter_buffer_unlock_all(ctx); 783 _filter_buffer_unlock_all(ctx);
865 return ret; 784 return cmd;
866 785
867fail: 786fail:
868 ERR("Failed to add blur"); 787 ERR("Failed to add blur");
869 _filter_buffer_unlock_all(ctx); 788 _filter_buffer_unlock_all(ctx);
870 return -1; 789 return NULL;
871} 790}
872 791
873int 792Evas_Filter_Command *
874evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx, 793evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
875 int inbuf, int outbuf, int ox, int oy, 794 int inbuf, int outbuf, int ox, int oy,
876 Evas_Filter_Fill_Mode fillmode) 795 Evas_Filter_Fill_Mode fillmode)
@@ -879,30 +798,30 @@ evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
879 Evas_Filter_Buffer *in, *out; 798 Evas_Filter_Buffer *in, *out;
880 int R, G, B, A; 799 int R, G, B, A;
881 800
882 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); 801 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
883 802
884 if (inbuf == outbuf) 803 if (inbuf == outbuf)
885 { 804 {
886 XDBG("Skipping NOP blend operation %d --> %d", inbuf, outbuf); 805 XDBG("Skipping NOP blend operation %d --> %d", inbuf, outbuf);
887 return -1; 806 return NULL;
888 } 807 }
889 808
890 in = _filter_buffer_get(ctx, inbuf); 809 in = _filter_buffer_get(ctx, inbuf);
891 if (!in) 810 if (!in)
892 { 811 {
893 ERR("Buffer %d does not exist [input].", inbuf); 812 ERR("Buffer %d does not exist [input].", inbuf);
894 return -1; 813 return NULL;
895 } 814 }
896 815
897 out = _filter_buffer_get(ctx, outbuf); 816 out = _filter_buffer_get(ctx, outbuf);
898 if (!out) 817 if (!out)
899 { 818 {
900 ERR("Buffer %d does not exist [output].", outbuf); 819 ERR("Buffer %d does not exist [output].", outbuf);
901 return -1; 820 return NULL;
902 } 821 }
903 822
904 cmd = _command_new(ctx, EVAS_FILTER_MODE_BLEND, in, NULL, out); 823 cmd = _command_new(ctx, EVAS_FILTER_MODE_BLEND, in, NULL, out);
905 if (!cmd) return -1; 824 if (!cmd) return NULL;
906 825
907 ENFN->context_color_get(ENDT, drawctx, &R, &G, &B, &A); 826 ENFN->context_color_get(ENDT, drawctx, &R, &G, &B, &A);
908 DRAW_COLOR_SET(R, G, B, A); 827 DRAW_COLOR_SET(R, G, B, A);
@@ -915,24 +834,26 @@ evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
915 &cmd->draw.clip.x, &cmd->draw.clip.y, 834 &cmd->draw.clip.x, &cmd->draw.clip.y,
916 &cmd->draw.clip.w, &cmd->draw.clip.h); 835 &cmd->draw.clip.w, &cmd->draw.clip.h);
917 836
837 XDBG("Add blend %d -> %d", in->id, out->id);
918 if (cmd->draw.clip_use) 838 if (cmd->draw.clip_use)
919 XDBG("Draw clip: %d,%d,%d,%d", cmd->draw.clip.x, cmd->draw.clip.y, 839 XDBG("Draw clip: %d,%d,%d,%d", cmd->draw.clip.x, cmd->draw.clip.y,
920 cmd->draw.clip.w, cmd->draw.clip.h); 840 cmd->draw.clip.w, cmd->draw.clip.h);
921 841
922 out->dirty = EINA_TRUE; 842 out->dirty = EINA_TRUE;
923 return cmd->id; 843 return cmd;
924} 844}
925 845
926int 846Evas_Filter_Command *
927evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, 847evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
928 int inbuf, int outbuf, int radius, Eina_Bool smooth) 848 int inbuf, int outbuf, int radius, Eina_Bool smooth)
929{ 849{
930 int blurcmd, threshcmd, blendcmd, tmin = 0, growbuf; 850 Evas_Filter_Command *blurcmd, *threshcmd, *blendcmd;
851 Evas_Filter_Buffer *tmp = NULL, *in, *out;
931 int diam = abs(radius) * 2 + 1; 852 int diam = abs(radius) * 2 + 1;
932 DATA8 curve[256] = {0}; 853 DATA8 curve[256] = {0};
933 Evas_Filter_Buffer *tmp = NULL, *in, *out; 854 int tmin = 0, growbuf;
934 855
935 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); 856 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
936 857
937 if (!radius) 858 if (!radius)
938 { 859 {
@@ -941,12 +862,12 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
941 } 862 }
942 863
943 in = _filter_buffer_get(ctx, inbuf); 864 in = _filter_buffer_get(ctx, inbuf);
944 EINA_SAFETY_ON_NULL_RETURN_VAL(in, -1); 865 EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL);
945 866
946 if (inbuf != outbuf) 867 if (inbuf != outbuf)
947 { 868 {
948 tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only); 869 tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only);
949 EINA_SAFETY_ON_NULL_RETURN_VAL(tmp, -1); 870 EINA_SAFETY_ON_NULL_RETURN_VAL(tmp, NULL);
950 growbuf = tmp->id; 871 growbuf = tmp->id;
951 } 872 }
952 else 873 else
@@ -955,7 +876,7 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
955 blurcmd = evas_filter_command_blur_add(ctx, draw_context, inbuf, growbuf, 876 blurcmd = evas_filter_command_blur_add(ctx, draw_context, inbuf, growbuf,
956 EVAS_FILTER_BLUR_DEFAULT, 877 EVAS_FILTER_BLUR_DEFAULT,
957 abs(radius), abs(radius), 0, 0, 0); 878 abs(radius), abs(radius), 0, 0, 0);
958 if (blurcmd < 0) return -1; 879 if (!blurcmd) return NULL;
959 880
960 if (diam > 255) diam = 255; 881 if (diam > 255) diam = 255;
961 if (radius > 0) 882 if (radius > 0)
@@ -981,21 +902,21 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
981 } 902 }
982 903
983 out = _filter_buffer_get(ctx, growbuf); 904 out = _filter_buffer_get(ctx, growbuf);
984 if (!out) return -1; 905 if (!out) return NULL;
985 out->dirty = EINA_TRUE; 906 out->dirty = EINA_TRUE;
986 if (growbuf != outbuf) 907 if (growbuf != outbuf)
987 { 908 {
988 out = _filter_buffer_get(ctx, growbuf); 909 out = _filter_buffer_get(ctx, growbuf);
989 if (!out) return -1; 910 if (!out) return NULL;
990 out->dirty = EINA_TRUE; 911 out->dirty = EINA_TRUE;
991 } 912 }
992 913
993 threshcmd = evas_filter_command_curve_add(ctx, draw_context, growbuf, growbuf, 914 threshcmd = evas_filter_command_curve_add(ctx, draw_context, growbuf, growbuf,
994 curve, EVAS_FILTER_CHANNEL_ALPHA); 915 curve, EVAS_FILTER_CHANNEL_ALPHA);
995 if (threshcmd < 0) 916 if (!threshcmd)
996 { 917 {
997 _command_del(ctx, _evas_filter_command_get(ctx, blurcmd)); 918 _command_del(ctx, blurcmd);
998 return -1; 919 return NULL;
999 } 920 }
1000 921
1001 if (tmp) 922 if (tmp)
@@ -1003,18 +924,18 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
1003 blendcmd = evas_filter_command_blend_add(ctx, draw_context, tmp->id, 924 blendcmd = evas_filter_command_blend_add(ctx, draw_context, tmp->id,
1004 outbuf, 0, 0, 925 outbuf, 0, 0,
1005 EVAS_FILTER_FILL_MODE_NONE); 926 EVAS_FILTER_FILL_MODE_NONE);
1006 if (blendcmd < 0) 927 if (!blendcmd)
1007 { 928 {
1008 _command_del(ctx, _evas_filter_command_get(ctx, threshcmd)); 929 _command_del(ctx, threshcmd);
1009 _command_del(ctx, _evas_filter_command_get(ctx, blurcmd)); 930 _command_del(ctx, blurcmd);
1010 return -1; 931 return NULL;
1011 } 932 }
1012 } 933 }
1013 934
1014 return blurcmd; 935 return blurcmd;
1015} 936}
1016 937
1017int 938Evas_Filter_Command *
1018evas_filter_command_curve_add(Evas_Filter_Context *ctx, 939evas_filter_command_curve_add(Evas_Filter_Context *ctx,
1019 void *draw_context EINA_UNUSED, 940 void *draw_context EINA_UNUSED,
1020 int inbuf, int outbuf, DATA8 *curve, 941 int inbuf, int outbuf, DATA8 *curve,
@@ -1024,30 +945,28 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx,
1024 Evas_Filter_Buffer *in, *out; 945 Evas_Filter_Buffer *in, *out;
1025 DATA8 *copy; 946 DATA8 *copy;
1026 947
1027 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); 948 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
1028 EINA_SAFETY_ON_NULL_RETURN_VAL(curve, -1); 949 EINA_SAFETY_ON_NULL_RETURN_VAL(curve, NULL);
1029 950
1030 in = _filter_buffer_get(ctx, inbuf); 951 in = _filter_buffer_get(ctx, inbuf);
1031 out = _filter_buffer_get(ctx, outbuf); 952 out = _filter_buffer_get(ctx, outbuf);
1032 if (!in || !out) 953 EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL);
1033 { 954 EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
1034 ERR("Invalid buffer id: input %d [%p], output %d [%p]",
1035 inbuf, in, outbuf, out);
1036 return -1;
1037 }
1038 955
1039 if (in->alpha_only != out->alpha_only) 956 if (in->alpha_only != out->alpha_only)
1040 WRN("Incompatible formats for color curves, implicit conversion will be " 957 WRN("Incompatible formats for color curves, implicit conversion will be "
1041 "slow and may not produce the desired output."); 958 "slow and may not produce the desired output.");
1042 959
960 XDBG("Add curve %d -> %d", in->id, out->id);
961
1043 copy = malloc(256 * sizeof(DATA8)); 962 copy = malloc(256 * sizeof(DATA8));
1044 if (!copy) return -1; 963 if (!copy) return NULL;
1045 964
1046 cmd = _command_new(ctx, EVAS_FILTER_MODE_CURVE, in, NULL, out); 965 cmd = _command_new(ctx, EVAS_FILTER_MODE_CURVE, in, NULL, out);
1047 if (!cmd) 966 if (!cmd)
1048 { 967 {
1049 free(copy); 968 free(copy);
1050 return -1; 969 return NULL;
1051 } 970 }
1052 971
1053 memcpy(copy, curve, 256 * sizeof(DATA8)); 972 memcpy(copy, curve, 256 * sizeof(DATA8));
@@ -1055,10 +974,10 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx,
1055 cmd->curve.channel = channel; 974 cmd->curve.channel = channel;
1056 975
1057 out->dirty = EINA_TRUE; 976 out->dirty = EINA_TRUE;
1058 return cmd->id; 977 return cmd;
1059} 978}
1060 979
1061int 980Evas_Filter_Command *
1062evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx, 981evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx,
1063 void *draw_context EINA_UNUSED, 982 void *draw_context EINA_UNUSED,
1064 int inbuf, int outbuf, int dispbuf, 983 int inbuf, int outbuf, int dispbuf,
@@ -1066,22 +985,18 @@ evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx,
1066 int intensity, 985 int intensity,
1067 Evas_Filter_Fill_Mode fillmode) 986 Evas_Filter_Fill_Mode fillmode)
1068{ 987{
1069 Evas_Filter_Command *cmd;
1070 Evas_Filter_Buffer *in, *out, *map, *tmp = NULL, *disp_out; 988 Evas_Filter_Buffer *in, *out, *map, *tmp = NULL, *disp_out;
1071 int cmdid = -1; 989 Evas_Filter_Command *cmd = NULL;
1072 990
1073 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); 991 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
1074 EINA_SAFETY_ON_FALSE_RETURN_VAL(intensity >= 0, EINA_FALSE); 992 EINA_SAFETY_ON_FALSE_RETURN_VAL(intensity >= 0, NULL);
1075 993
1076 in = _filter_buffer_get(ctx, inbuf); 994 in = _filter_buffer_get(ctx, inbuf);
1077 out = _filter_buffer_get(ctx, outbuf); 995 out = _filter_buffer_get(ctx, outbuf);
1078 map = _filter_buffer_get(ctx, dispbuf); 996 map = _filter_buffer_get(ctx, dispbuf);
1079 if (!in || !out || !map) 997 EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL);
1080 { 998 EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
1081 ERR("Invalid buffer id: input %d [%p], output %d [%p], map %d [%p]", 999 EINA_SAFETY_ON_NULL_RETURN_VAL(map, NULL);
1082 inbuf, in, outbuf, out, dispbuf, map);
1083 return -1;
1084 }
1085 1000
1086 if (in->alpha_only != out->alpha_only) 1001 if (in->alpha_only != out->alpha_only)
1087 DBG("Different color formats, implicit conversion may be slow"); 1002 DBG("Different color formats, implicit conversion may be slow");
@@ -1095,39 +1010,41 @@ evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx,
1095 if (in == out) 1010 if (in == out)
1096 { 1011 {
1097 tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only); 1012 tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only);
1098 if (!tmp) return -1; 1013 if (!tmp) return NULL;
1099 disp_out = tmp; 1014 disp_out = tmp;
1100 } 1015 }
1101 else disp_out = out; 1016 else disp_out = out;
1102 1017
1103 cmd = _command_new(ctx, EVAS_FILTER_MODE_DISPLACE, in, map, disp_out); 1018 cmd = _command_new(ctx, EVAS_FILTER_MODE_DISPLACE, in, map, disp_out);
1104 if (!cmd) goto end; 1019 if (!cmd) goto fail;
1105 1020
1106 DRAW_FILL_SET(fillmode); 1021 DRAW_FILL_SET(fillmode);
1107 cmd->displacement.flags = flags & EVAS_FILTER_DISPLACE_BITMASK; 1022 cmd->displacement.flags = flags & EVAS_FILTER_DISPLACE_BITMASK;
1108 cmd->displacement.intensity = intensity; 1023 cmd->displacement.intensity = intensity;
1109 cmd->draw.rop = _evas_to_gfx_render_op(ENFN->context_render_op_get(ENDT, draw_context)); 1024 cmd->draw.rop = _evas_to_gfx_render_op(ENFN->context_render_op_get(ENDT, draw_context));
1110 cmdid = cmd->id;
1111 1025
1112 if (tmp) 1026 if (tmp)
1113 { 1027 {
1114 if (evas_filter_command_blend_add(ctx, draw_context, disp_out->id, 1028 Evas_Filter_Command *fillcmd;
1115 out->id, 0, 0, 1029
1116 EVAS_FILTER_FILL_MODE_NONE) < 0) 1030 fillcmd = evas_filter_command_blend_add(ctx, draw_context, disp_out->id,
1117 { 1031 out->id, 0, 0,
1118 _command_del(ctx, _evas_filter_command_get(ctx, cmdid)); 1032 EVAS_FILTER_FILL_MODE_NONE);
1119 cmdid = -1; 1033 if (!fillcmd) goto fail;
1120 }
1121 } 1034 }
1122 1035
1123 out->dirty = EINA_TRUE; 1036 out->dirty = EINA_TRUE;
1124 1037
1125end:
1126 _filter_buffer_unlock_all(ctx); 1038 _filter_buffer_unlock_all(ctx);
1127 return cmdid; 1039 return cmd;
1040
1041fail:
1042 _filter_buffer_unlock_all(ctx);
1043 _command_del(ctx, cmd);
1044 return NULL;
1128} 1045}
1129 1046
1130int 1047Evas_Filter_Command *
1131evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context, 1048evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context,
1132 int inbuf, int maskbuf, int outbuf, 1049 int inbuf, int maskbuf, int outbuf,
1133 Evas_Filter_Fill_Mode fillmode) 1050 Evas_Filter_Fill_Mode fillmode)
@@ -1135,10 +1052,9 @@ evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context,
1135 Evas_Filter_Command *cmd; 1052 Evas_Filter_Command *cmd;
1136 Evas_Filter_Buffer *in, *out, *mask; 1053 Evas_Filter_Buffer *in, *out, *mask;
1137 Efl_Gfx_Render_Op render_op; 1054 Efl_Gfx_Render_Op render_op;
1138 int cmdid = -1;
1139 int R, G, B, A; 1055 int R, G, B, A;
1140 1056
1141 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); 1057 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
1142 1058
1143 render_op = _evas_to_gfx_render_op(ENFN->context_render_op_get(ENDT, draw_context)); 1059 render_op = _evas_to_gfx_render_op(ENFN->context_render_op_get(ENDT, draw_context));
1144 ENFN->context_color_get(ENDT, draw_context, &R, &G, &B, &A); 1060 ENFN->context_color_get(ENDT, draw_context, &R, &G, &B, &A);
@@ -1146,29 +1062,22 @@ evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context,
1146 in = _filter_buffer_get(ctx, inbuf); 1062 in = _filter_buffer_get(ctx, inbuf);
1147 out = _filter_buffer_get(ctx, outbuf); 1063 out = _filter_buffer_get(ctx, outbuf);
1148 mask = _filter_buffer_get(ctx, maskbuf); 1064 mask = _filter_buffer_get(ctx, maskbuf);
1149 if (!in || !out || !mask) 1065 EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL);
1150 { 1066 EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
1151 ERR("Invalid buffer id: input %d [%p], output %d [%p], mask %d [%p]", 1067 EINA_SAFETY_ON_NULL_RETURN_VAL(mask, NULL);
1152 inbuf, in, outbuf, out, maskbuf, mask);
1153 return -1;
1154 }
1155 1068
1156 cmd = _command_new(ctx, EVAS_FILTER_MODE_MASK, in, mask, out); 1069 cmd = _command_new(ctx, EVAS_FILTER_MODE_MASK, in, mask, out);
1157 if (!cmd) goto end; 1070 if (!cmd) return NULL;
1158 1071
1159 cmd->draw.rop = render_op; 1072 cmd->draw.rop = render_op;
1160 DRAW_COLOR_SET(R, G, B, A); 1073 DRAW_COLOR_SET(R, G, B, A);
1161 DRAW_FILL_SET(fillmode); 1074 DRAW_FILL_SET(fillmode);
1162
1163 cmdid = cmd->id;
1164 out->dirty = EINA_TRUE; 1075 out->dirty = EINA_TRUE;
1165 1076
1166end: 1077 return cmd;
1167 _filter_buffer_unlock_all(ctx);
1168 return cmdid;
1169} 1078}
1170 1079
1171int 1080Evas_Filter_Command *
1172evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, 1081evas_filter_command_bump_map_add(Evas_Filter_Context *ctx,
1173 void *draw_context EINA_UNUSED, 1082 void *draw_context EINA_UNUSED,
1174 int inbuf, int bumpbuf, int outbuf, 1083 int inbuf, int bumpbuf, int outbuf,
@@ -1179,22 +1088,18 @@ evas_filter_command_bump_map_add(Evas_Filter_Context *ctx,
1179 Evas_Filter_Fill_Mode fillmode) 1088 Evas_Filter_Fill_Mode fillmode)
1180{ 1089{
1181 Evas_Filter_Command *cmd; 1090 Evas_Filter_Command *cmd;
1182 Evas_Filter_Buffer *in, *out, *bumpmap; 1091 Evas_Filter_Buffer *in, *out, *map;
1183 int cmdid = -1;
1184 1092
1185 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); 1093 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
1186 1094
1187 in = _filter_buffer_get(ctx, inbuf); 1095 in = _filter_buffer_get(ctx, inbuf);
1188 out = _filter_buffer_get(ctx, outbuf); 1096 out = _filter_buffer_get(ctx, outbuf);
1189 bumpmap = _filter_buffer_get(ctx, bumpbuf); 1097 map = _filter_buffer_get(ctx, bumpbuf);
1190 if (!in || !out || !bumpmap) 1098 EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL);
1191 { 1099 EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
1192 ERR("Invalid buffer id: input %d [%p], output %d [%p], bumpmap %d [%p]", 1100 EINA_SAFETY_ON_NULL_RETURN_VAL(map, NULL);
1193 inbuf, in, outbuf, out, bumpbuf, bumpmap);
1194 return -1;
1195 }
1196 1101
1197 if (!bumpmap->alpha_only) 1102 if (!map->alpha_only)
1198 DBG("Bump map is not an Alpha buffer, implicit conversion may be slow"); 1103 DBG("Bump map is not an Alpha buffer, implicit conversion may be slow");
1199 1104
1200 // FIXME: Boo! 1105 // FIXME: Boo!
@@ -1202,11 +1107,11 @@ evas_filter_command_bump_map_add(Evas_Filter_Context *ctx,
1202 WRN("RGBA bump map support is not implemented! This will trigger conversion."); 1107 WRN("RGBA bump map support is not implemented! This will trigger conversion.");
1203 1108
1204 // FIXME: Must ensure in != out 1109 // FIXME: Must ensure in != out
1205 if (in == out) CRI("Not acceptable"); 1110 EINA_SAFETY_ON_FALSE_RETURN_VAL(in != out, NULL);
1206 if (bumpmap == out) CRI("Not acceptable"); 1111 EINA_SAFETY_ON_FALSE_RETURN_VAL(map != out, NULL);
1207 1112
1208 cmd = _command_new(ctx, EVAS_FILTER_MODE_BUMP, in, bumpmap, out); 1113 cmd = _command_new(ctx, EVAS_FILTER_MODE_BUMP, in, map, out);
1209 if (!cmd) goto end; 1114 if (!cmd) return NULL;
1210 1115
1211 DRAW_FILL_SET(fillmode); 1116 DRAW_FILL_SET(fillmode);
1212 cmd->bump.xyangle = xyangle; 1117 cmd->bump.xyangle = xyangle;
@@ -1217,16 +1122,12 @@ evas_filter_command_bump_map_add(Evas_Filter_Context *ctx,
1217 cmd->bump.white = white; 1122 cmd->bump.white = white;
1218 cmd->bump.elevation = elevation; 1123 cmd->bump.elevation = elevation;
1219 cmd->bump.compensate = !!(flags & EVAS_FILTER_BUMP_COMPENSATE); 1124 cmd->bump.compensate = !!(flags & EVAS_FILTER_BUMP_COMPENSATE);
1220 cmdid = cmd->id;
1221
1222 out->dirty = EINA_TRUE; 1125 out->dirty = EINA_TRUE;
1223 1126
1224end: 1127 return cmd;
1225 _filter_buffer_unlock_all(ctx);
1226 return cmdid;
1227} 1128}
1228 1129
1229int 1130Evas_Filter_Command *
1230evas_filter_command_transform_add(Evas_Filter_Context *ctx, 1131evas_filter_command_transform_add(Evas_Filter_Context *ctx,
1231 void *draw_context EINA_UNUSED, 1132 void *draw_context EINA_UNUSED,
1232 int inbuf, int outbuf, 1133 int inbuf, int outbuf,
@@ -1236,19 +1137,15 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx,
1236 Evas_Filter_Command *cmd; 1137 Evas_Filter_Command *cmd;
1237 Evas_Filter_Buffer *in, *out; 1138 Evas_Filter_Buffer *in, *out;
1238 1139
1239 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); 1140 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
1240 1141
1241 in = _filter_buffer_get(ctx, inbuf); 1142 in = _filter_buffer_get(ctx, inbuf);
1242 out = _filter_buffer_get(ctx, outbuf); 1143 out = _filter_buffer_get(ctx, outbuf);
1243 if (!in || !out) 1144 EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL);
1244 { 1145 EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
1245 ERR("Invalid buffer id: input %d [%p], output %d [%p]",
1246 inbuf, in, outbuf, out);
1247 return -1;
1248 }
1249 1146
1250 cmd = _command_new(ctx, EVAS_FILTER_MODE_TRANSFORM, in, NULL, out); 1147 cmd = _command_new(ctx, EVAS_FILTER_MODE_TRANSFORM, in, NULL, out);
1251 if (!cmd) return -1; 1148 if (!cmd) return NULL;
1252 1149
1253 DRAW_COLOR_SET(255, 255, 255, 255); 1150 DRAW_COLOR_SET(255, 255, 255, 255);
1254 cmd->transform.flags = flags; 1151 cmd->transform.flags = flags;
@@ -1265,7 +1162,7 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx,
1265 1162
1266 out->dirty = EINA_TRUE; 1163 out->dirty = EINA_TRUE;
1267 1164
1268 return cmd->id; 1165 return cmd;
1269} 1166}
1270 1167
1271/* Final target */ 1168/* Final target */
@@ -1277,7 +1174,7 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
1277 1174
1278 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); 1175 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
1279 1176
1280 ctx->target.bufid = _filter_buffer_new_from_evas_surface(ctx, surface); 1177 ctx->target.surface = ENFN->image_ref(ENDT, surface);
1281 ctx->target.x = x; 1178 ctx->target.x = x;
1282 ctx->target.y = y; 1179 ctx->target.y = y;
1283 ctx->target.clip_use = ENFN->context_clip_get 1180 ctx->target.clip_use = ENFN->context_clip_get
@@ -1303,21 +1200,19 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
1303static Eina_Bool 1200static Eina_Bool
1304_filter_target_render(Evas_Filter_Context *ctx) 1201_filter_target_render(Evas_Filter_Context *ctx)
1305{ 1202{
1306 Evas_Filter_Buffer *src, *dst; 1203 Evas_Filter_Buffer *src;
1307 void *drawctx, *image = NULL, *surface = NULL; 1204 void *drawctx, *image = NULL, *surface;
1205
1206 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx->target.surface, EINA_FALSE);
1308 1207
1309 EINA_SAFETY_ON_FALSE_RETURN_VAL(ctx->target.bufid, EINA_FALSE); 1208 drawctx = ENFN->context_new(ENDT);
1209 surface = ctx->target.surface;
1310 1210
1311 src = _filter_buffer_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID); 1211 src = _filter_buffer_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID);
1312 dst = _filter_buffer_get(ctx, ctx->target.bufid);
1313 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); 1212 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
1314 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
1315 1213
1316 drawctx = ENFN->context_new(ENDT); 1214 image = evas_ector_buffer_drawable_image_get(src->buffer, EINA_FALSE);
1317 image = _evas_image_get(src->buffer); 1215 EINA_SAFETY_ON_NULL_GOTO(image, fail);
1318 surface = _evas_image_get(dst->buffer);
1319 EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
1320 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
1321 1216
1322 // FIXME: Use ector buffer RENDERER here 1217 // FIXME: Use ector buffer RENDERER here
1323 1218
@@ -1348,7 +1243,19 @@ _filter_target_render(Evas_Filter_Context *ctx)
1348 EINA_TRUE, EINA_FALSE); 1243 EINA_TRUE, EINA_FALSE);
1349 1244
1350 ENFN->context_free(ENDT, drawctx); 1245 ENFN->context_free(ENDT, drawctx);
1246 evas_ector_buffer_engine_image_release(src->buffer, image);
1247
1248 ENFN->image_free(ENDT, surface);
1249 ctx->target.surface = NULL;
1250
1351 return EINA_TRUE; 1251 return EINA_TRUE;
1252
1253fail:
1254 ENFN->image_free(ENDT, surface);
1255 ctx->target.surface = NULL;
1256
1257 ERR("Failed to render filter to target canvas!");
1258 return EINA_FALSE;
1352} 1259}
1353 1260
1354 1261
@@ -1365,8 +1272,8 @@ evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
1365 fb = _filter_buffer_get(ctx, bufid); 1272 fb = _filter_buffer_get(ctx, bufid);
1366 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); 1273 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
1367 1274
1368 surface = _evas_image_get(fb->buffer); 1275 surface = evas_ector_buffer_render_image_get(fb->buffer, EINA_FALSE);
1369 if (!surface) return EINA_FALSE; 1276 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
1370 1277
1371 // Copied from evas_font_draw_async_check 1278 // Copied from evas_font_draw_async_check
1372 async_unref = ENFN->font_draw(ENDT, draw_context, surface, 1279 async_unref = ENFN->font_draw(ENDT, draw_context, surface,
@@ -1378,6 +1285,7 @@ evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
1378 evas_unref_queue_glyph_put(ctx->evas, text_props->glyphs); 1285 evas_unref_queue_glyph_put(ctx->evas, text_props->glyphs);
1379 } 1286 }
1380 1287
1288 evas_ector_buffer_engine_image_release(fb->buffer, surface);
1381 return EINA_TRUE; 1289 return EINA_TRUE;
1382} 1290}
1383 1291
@@ -1389,13 +1297,17 @@ evas_filter_image_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
1389{ 1297{
1390 int dw = 0, dh = 0, w = 0, h = 0; 1298 int dw = 0, dh = 0, w = 0, h = 0;
1391 Eina_Bool async_unref; 1299 Eina_Bool async_unref;
1300 Evas_Filter_Buffer *fb;
1392 void *surface; 1301 void *surface;
1393 1302
1394 ENFN->image_size_get(ENDT, image, &w, &h); 1303 ENFN->image_size_get(ENDT, image, &w, &h);
1395 if (!w || !h) return EINA_FALSE; 1304 if (!w || !h) return EINA_FALSE;
1396 1305
1397 surface = evas_filter_buffer_backing_get(ctx, bufid); 1306 fb = _filter_buffer_get(ctx, bufid);
1398 if (!surface) return EINA_FALSE; 1307 if (!fb) return EINA_FALSE;
1308
1309 surface = evas_ector_buffer_render_image_get(fb->buffer, EINA_FALSE);
1310 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
1399 1311
1400 ENFN->image_size_get(ENDT, image, &dw, &dh); 1312 ENFN->image_size_get(ENDT, image, &dw, &dh);
1401 if (!dw || !dh) return EINA_FALSE; 1313 if (!dw || !dh) return EINA_FALSE;
@@ -1410,6 +1322,7 @@ evas_filter_image_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
1410 evas_unref_queue_image_put(ctx->evas, image); 1322 evas_unref_queue_image_put(ctx->evas, image);
1411 } 1323 }
1412 1324
1325 evas_ector_buffer_engine_image_release(fb->buffer, surface);
1413 return EINA_TRUE; 1326 return EINA_TRUE;
1414} 1327}
1415 1328
@@ -1571,7 +1484,6 @@ _filter_thread_run_cb(void *data)
1571Eina_Bool 1484Eina_Bool
1572evas_filter_run(Evas_Filter_Context *ctx) 1485evas_filter_run(Evas_Filter_Context *ctx)
1573{ 1486{
1574 static int warned = 0;
1575 Eina_Bool ret; 1487 Eina_Bool ret;
1576 1488
1577 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); 1489 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
@@ -1579,12 +1491,6 @@ evas_filter_run(Evas_Filter_Context *ctx)
1579 if (!ctx->commands) 1491 if (!ctx->commands)
1580 return EINA_TRUE; 1492 return EINA_TRUE;
1581 1493
1582 if (ENFN->gl_surface_read_pixels && !warned)
1583 {
1584 WRN("OpenGL support through SW functions, expect low performance!");
1585 warned = 1;
1586 }
1587
1588 if (ctx->async) 1494 if (ctx->async)
1589 { 1495 {
1590 evas_thread_queue_flush(_filter_thread_run_cb, ctx); 1496 evas_thread_queue_flush(_filter_thread_run_cb, ctx);
diff --git a/src/lib/evas/filters/evas_filter_parser.c b/src/lib/evas/filters/evas_filter_parser.c
index 8fce7c57a9..e3346e09bb 100644
--- a/src/lib/evas/filters/evas_filter_parser.c
+++ b/src/lib/evas/filters/evas_filter_parser.c
@@ -20,7 +20,7 @@
20#define EVAS_FILTER_MODE_BUFFER (EVAS_FILTER_MODE_LAST+2) 20#define EVAS_FILTER_MODE_BUFFER (EVAS_FILTER_MODE_LAST+2)
21 21
22#define INSTR_PARAM_CHECK(a) do { if (!(a)) { \ 22#define INSTR_PARAM_CHECK(a) do { if (!(a)) { \
23 ERR("Argument %s can not be nil in %s!", #a, instr->name); return -1; } \ 23 ERR("Argument %s can not be nil in %s!", #a, instr->name); return NULL; } \
24 } while (0) 24 } while (0)
25 25
26/* Note on the documentation: 26/* Note on the documentation:
@@ -913,8 +913,8 @@ _blend_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
913 913
914 src = _instruction_param_getbuf(instr, "src", NULL); 914 src = _instruction_param_getbuf(instr, "src", NULL);
915 dst = _instruction_param_getbuf(instr, "dst", NULL); 915 dst = _instruction_param_getbuf(instr, "dst", NULL);
916 INSTR_PARAM_CHECK(src); 916 EINA_SAFETY_ON_NULL_RETURN_VAL(src, 0);
917 INSTR_PARAM_CHECK(dst); 917 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0);
918 918
919 fillmode = _fill_mode_get(instr); 919 fillmode = _fill_mode_get(instr);
920 if (fillmode & (EVAS_FILTER_FILL_MODE_STRETCH_X | EVAS_FILTER_FILL_MODE_REPEAT_X)) ox = 0; 920 if (fillmode & (EVAS_FILTER_FILL_MODE_STRETCH_X | EVAS_FILTER_FILL_MODE_REPEAT_X)) ox = 0;
@@ -1022,8 +1022,8 @@ _blur_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
1022 1022
1023 src = _instruction_param_getbuf(instr, "src", NULL); 1023 src = _instruction_param_getbuf(instr, "src", NULL);
1024 dst = _instruction_param_getbuf(instr, "dst", NULL); 1024 dst = _instruction_param_getbuf(instr, "dst", NULL);
1025 INSTR_PARAM_CHECK(src); 1025 EINA_SAFETY_ON_NULL_RETURN_VAL(src, 0);
1026 INSTR_PARAM_CHECK(dst); 1026 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0);
1027 1027
1028 if (typestr && !strcasecmp(typestr, "box")) 1028 if (typestr && !strcasecmp(typestr, "box"))
1029 type = EVAS_FILTER_BLUR_BOX; 1029 type = EVAS_FILTER_BLUR_BOX;
@@ -1405,8 +1405,8 @@ _displace_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
1405 intensity = _instruction_param_geti(instr, "intensity", NULL); 1405 intensity = _instruction_param_geti(instr, "intensity", NULL);
1406 src = _instruction_param_getbuf(instr, "src", NULL); 1406 src = _instruction_param_getbuf(instr, "src", NULL);
1407 dst = _instruction_param_getbuf(instr, "dst", NULL); 1407 dst = _instruction_param_getbuf(instr, "dst", NULL);
1408 INSTR_PARAM_CHECK(src); 1408 EINA_SAFETY_ON_NULL_RETURN_VAL(src, 0);
1409 INSTR_PARAM_CHECK(dst); 1409 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0);
1410 1410
1411 l = intensity + src->pad.l; 1411 l = intensity + src->pad.l;
1412 r = intensity + src->pad.r; 1412 r = intensity + src->pad.r;
@@ -1552,8 +1552,8 @@ _grow_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
1552 radius = _instruction_param_geti(instr, "radius", NULL); 1552 radius = _instruction_param_geti(instr, "radius", NULL);
1553 src = _instruction_param_getbuf(instr, "src", NULL); 1553 src = _instruction_param_getbuf(instr, "src", NULL);
1554 dst = _instruction_param_getbuf(instr, "dst", NULL); 1554 dst = _instruction_param_getbuf(instr, "dst", NULL);
1555 INSTR_PARAM_CHECK(src); 1555 EINA_SAFETY_ON_NULL_RETURN_VAL(src, 0);
1556 INSTR_PARAM_CHECK(dst); 1556 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0);
1557 1557
1558 if (radius < 0) radius = 0; 1558 if (radius < 0) radius = 0;
1559 1559
@@ -1684,7 +1684,7 @@ _transform_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
1684 ox = 0; 1684 ox = 0;
1685 oy = _instruction_param_geti(instr, "oy", NULL); 1685 oy = _instruction_param_geti(instr, "oy", NULL);
1686 dst = _instruction_param_getbuf(instr, "dst", NULL); 1686 dst = _instruction_param_getbuf(instr, "dst", NULL);
1687 INSTR_PARAM_CHECK(dst); 1687 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0);
1688 1688
1689 if (ox < 0) l = (-ox) * 2; 1689 if (ox < 0) l = (-ox) * 2;
1690 else r = ox * 2; 1690 else r = ox * 2;
@@ -3018,15 +3018,16 @@ _fill_mode_get(Evas_Filter_Instruction *instr)
3018 return EVAS_FILTER_FILL_MODE_NONE; 3018 return EVAS_FILTER_FILL_MODE_NONE;
3019} 3019}
3020 3020
3021static int 3021static Evas_Filter_Command *
3022_instr2cmd_blend(Evas_Filter_Context *ctx, 3022_instr2cmd_blend(Evas_Filter_Context *ctx,
3023 Evas_Filter_Instruction *instr, void *dc) 3023 Evas_Filter_Instruction *instr, void *dc)
3024{ 3024{
3025 Eina_Bool isset = EINA_FALSE; 3025 Eina_Bool isset = EINA_FALSE;
3026 Evas_Filter_Command *cmd;
3026 DATA32 color; 3027 DATA32 color;
3027 Buffer *src, *dst; 3028 Buffer *src, *dst;
3028 Evas_Filter_Fill_Mode fillmode; 3029 Evas_Filter_Fill_Mode fillmode;
3029 int cmdid, ox, oy, A, R, G, B; 3030 int ox, oy, A, R, G, B;
3030 3031
3031 ox = _instruction_param_geti(instr, "ox", NULL); 3032 ox = _instruction_param_geti(instr, "ox", NULL);
3032 oy = _instruction_param_geti(instr, "oy", NULL); 3033 oy = _instruction_param_geti(instr, "oy", NULL);
@@ -3038,24 +3039,23 @@ _instr2cmd_blend(Evas_Filter_Context *ctx,
3038 INSTR_PARAM_CHECK(dst); 3039 INSTR_PARAM_CHECK(dst);
3039 3040
3040 if (isset) SETCOLOR(color); 3041 if (isset) SETCOLOR(color);
3041 cmdid = evas_filter_command_blend_add(ctx, dc, src->cid, dst->cid, ox, oy, 3042 cmd = evas_filter_command_blend_add(ctx, dc, src->cid, dst->cid, ox, oy, fillmode);
3042 fillmode);
3043 if (isset) RESETCOLOR(); 3043 if (isset) RESETCOLOR();
3044 if (cmdid < 0) return cmdid;
3045 3044
3046 return cmdid; 3045 return cmd;
3047} 3046}
3048 3047
3049static int 3048static Evas_Filter_Command *
3050_instr2cmd_blur(Evas_Filter_Context *ctx, 3049_instr2cmd_blur(Evas_Filter_Context *ctx,
3051 Evas_Filter_Instruction *instr, void *dc) 3050 Evas_Filter_Instruction *instr, void *dc)
3052{ 3051{
3053 Eina_Bool colorset = EINA_FALSE, yset = EINA_FALSE, cntset = EINA_FALSE; 3052 Eina_Bool colorset = EINA_FALSE, yset = EINA_FALSE, cntset = EINA_FALSE;
3054 Evas_Filter_Blur_Type type = EVAS_FILTER_BLUR_DEFAULT; 3053 Evas_Filter_Blur_Type type = EVAS_FILTER_BLUR_DEFAULT;
3054 Evas_Filter_Command *cmd;
3055 const char *typestr; 3055 const char *typestr;
3056 DATA32 color; 3056 DATA32 color;
3057 Buffer *src, *dst; 3057 Buffer *src, *dst;
3058 int cmdid, ox, oy, rx, ry, A, R, G, B, count; 3058 int ox, oy, rx, ry, A, R, G, B, count;
3059 3059
3060 ox = _instruction_param_geti(instr, "ox", NULL); 3060 ox = _instruction_param_geti(instr, "ox", NULL);
3061 oy = _instruction_param_geti(instr, "oy", NULL); 3061 oy = _instruction_param_geti(instr, "oy", NULL);
@@ -3098,14 +3098,14 @@ _instr2cmd_blur(Evas_Filter_Context *ctx,
3098 3098
3099 if (!yset) ry = rx; 3099 if (!yset) ry = rx;
3100 if (colorset) SETCOLOR(color); 3100 if (colorset) SETCOLOR(color);
3101 cmdid = evas_filter_command_blur_add(ctx, dc, src->cid, dst->cid, type, 3101 cmd = evas_filter_command_blur_add(ctx, dc, src->cid, dst->cid, type,
3102 rx, ry, ox, oy, count); 3102 rx, ry, ox, oy, count);
3103 if (colorset) RESETCOLOR(); 3103 if (colorset) RESETCOLOR();
3104 3104
3105 return cmdid; 3105 return cmd;
3106} 3106}
3107 3107
3108static int 3108static Evas_Filter_Command *
3109_instr2cmd_bump(Evas_Filter_Context *ctx, 3109_instr2cmd_bump(Evas_Filter_Context *ctx,
3110 Evas_Filter_Instruction *instr, void *dc) 3110 Evas_Filter_Instruction *instr, void *dc)
3111{ 3111{
@@ -3114,7 +3114,7 @@ _instr2cmd_bump(Evas_Filter_Context *ctx,
3114 DATA32 color, black, white; 3114 DATA32 color, black, white;
3115 Buffer *src, *dst, *map; 3115 Buffer *src, *dst, *map;
3116 double azimuth, elevation, depth, specular; 3116 double azimuth, elevation, depth, specular;
3117 int cmdid, compensate; 3117 int compensate;
3118 3118
3119 color = _instruction_param_getc(instr, "color", NULL); 3119 color = _instruction_param_getc(instr, "color", NULL);
3120 white = _instruction_param_getc(instr, "white", NULL); 3120 white = _instruction_param_getc(instr, "white", NULL);
@@ -3134,15 +3134,13 @@ _instr2cmd_bump(Evas_Filter_Context *ctx,
3134 INSTR_PARAM_CHECK(dst); 3134 INSTR_PARAM_CHECK(dst);
3135 INSTR_PARAM_CHECK(map); 3135 INSTR_PARAM_CHECK(map);
3136 3136
3137 cmdid = evas_filter_command_bump_map_add(ctx, dc, src->cid, map->cid, dst->cid, 3137 return evas_filter_command_bump_map_add(ctx, dc, src->cid, map->cid, dst->cid,
3138 azimuth, elevation, depth, specular, 3138 azimuth, elevation, depth, specular,
3139 black, color, white, flags, 3139 black, color, white, flags,
3140 fillmode); 3140 fillmode);
3141
3142 return cmdid;
3143} 3141}
3144 3142
3145static int 3143static Evas_Filter_Command *
3146_instr2cmd_displace(Evas_Filter_Context *ctx, 3144_instr2cmd_displace(Evas_Filter_Context *ctx,
3147 Evas_Filter_Instruction *instr, void *dc) 3145 Evas_Filter_Instruction *instr, void *dc)
3148{ 3146{
@@ -3151,7 +3149,7 @@ _instr2cmd_displace(Evas_Filter_Context *ctx,
3151 EVAS_FILTER_DISPLACE_STRETCH | EVAS_FILTER_DISPLACE_LINEAR; 3149 EVAS_FILTER_DISPLACE_STRETCH | EVAS_FILTER_DISPLACE_LINEAR;
3152 const char *flagsstr; 3150 const char *flagsstr;
3153 Buffer *src, *dst, *map; 3151 Buffer *src, *dst, *map;
3154 int cmdid, intensity; 3152 int intensity;
3155 Eina_Bool isset = EINA_FALSE; 3153 Eina_Bool isset = EINA_FALSE;
3156 3154
3157 src = _instruction_param_getbuf(instr, "src", NULL); 3155 src = _instruction_param_getbuf(instr, "src", NULL);
@@ -3176,23 +3174,19 @@ _instr2cmd_displace(Evas_Filter_Context *ctx,
3176 else if (isset) 3174 else if (isset)
3177 WRN("Invalid flags '%s' in displace operation. Using default instead", flagsstr); 3175 WRN("Invalid flags '%s' in displace operation. Using default instead", flagsstr);
3178 3176
3179 cmdid = evas_filter_command_displacement_map_add(ctx, dc, src->cid, dst->cid, 3177 return evas_filter_command_displacement_map_add(ctx, dc, src->cid, dst->cid,
3180 map->cid, flags, intensity, 3178 map->cid, flags, intensity,
3181 fillmode); 3179 fillmode);
3182
3183 return cmdid;
3184} 3180}
3185 3181
3186static int 3182static Evas_Filter_Command *
3187_instr2cmd_fill(Evas_Filter_Context *ctx, 3183_instr2cmd_fill(Evas_Filter_Context *ctx,
3188 Evas_Filter_Instruction *instr, void *dc) 3184 Evas_Filter_Instruction *instr, void *dc)
3189{ 3185{
3190 Buffer *dst; 3186 Buffer *dst;
3191 int R, G, B, A, l, r, t, b; 3187 int R, G, B, A, l, r, t, b;
3192 Evas_Filter_Command *cmd; 3188 Evas_Filter_Command *cmd;
3193 Eina_Inlist *il;
3194 DATA32 color; 3189 DATA32 color;
3195 int cmdid;
3196 3190
3197 dst = _instruction_param_getbuf(instr, "dst", NULL); 3191 dst = _instruction_param_getbuf(instr, "dst", NULL);
3198 color = _instruction_param_getc(instr, "color", NULL); 3192 color = _instruction_param_getc(instr, "color", NULL);
@@ -3203,31 +3197,27 @@ _instr2cmd_fill(Evas_Filter_Context *ctx,
3203 INSTR_PARAM_CHECK(dst); 3197 INSTR_PARAM_CHECK(dst);
3204 3198
3205 SETCOLOR(color); 3199 SETCOLOR(color);
3206 cmdid = evas_filter_command_fill_add(ctx, dc, dst->cid); 3200 cmd = evas_filter_command_fill_add(ctx, dc, dst->cid);
3207 RESETCOLOR(); 3201 RESETCOLOR();
3202 if (!cmd) return NULL;
3208 3203
3209 if (cmdid < 0) return -1;
3210 il = eina_inlist_last(ctx->commands);
3211 if (!il) return -1;
3212
3213 cmd = EINA_INLIST_CONTAINER_GET(il, Evas_Filter_Command);
3214 cmd->draw.clip.l = l; 3204 cmd->draw.clip.l = l;
3215 cmd->draw.clip.r = r; 3205 cmd->draw.clip.r = r;
3216 cmd->draw.clip.t = t; 3206 cmd->draw.clip.t = t;
3217 cmd->draw.clip.b = b; 3207 cmd->draw.clip.b = b;
3218 cmd->draw.clip_mode_lrtb = EINA_TRUE; 3208 cmd->draw.clip_mode_lrtb = EINA_TRUE;
3219 3209
3220 return cmdid; 3210 return cmd;
3221} 3211}
3222 3212
3223static int 3213static Evas_Filter_Command *
3224_instr2cmd_grow(Evas_Filter_Context *ctx, 3214_instr2cmd_grow(Evas_Filter_Context *ctx,
3225 Evas_Filter_Instruction *instr, void *dc) 3215 Evas_Filter_Instruction *instr, void *dc)
3226{ 3216{
3227 Evas_Filter_Command *cmd; 3217 Evas_Filter_Command *cmd;
3228 Buffer *src, *dst; 3218 Buffer *src, *dst;
3229 Eina_Bool smooth; 3219 Eina_Bool smooth;
3230 int cmdid, radius; 3220 int radius;
3231 3221
3232 src = _instruction_param_getbuf(instr, "src", NULL); 3222 src = _instruction_param_getbuf(instr, "src", NULL);
3233 dst = _instruction_param_getbuf(instr, "dst", NULL); 3223 dst = _instruction_param_getbuf(instr, "dst", NULL);
@@ -3236,23 +3226,21 @@ _instr2cmd_grow(Evas_Filter_Context *ctx,
3236 INSTR_PARAM_CHECK(src); 3226 INSTR_PARAM_CHECK(src);
3237 INSTR_PARAM_CHECK(dst); 3227 INSTR_PARAM_CHECK(dst);
3238 3228
3239 cmdid = evas_filter_command_grow_add(ctx, dc, src->cid, dst->cid, 3229 cmd = evas_filter_command_grow_add(ctx, dc, src->cid, dst->cid, radius, smooth);
3240 radius, smooth);
3241
3242 cmd = _evas_filter_command_get(ctx, cmdid);
3243 if (cmd) cmd->draw.need_temp_buffer = EINA_TRUE; 3230 if (cmd) cmd->draw.need_temp_buffer = EINA_TRUE;
3244 3231
3245 return cmdid; 3232 return cmd;
3246} 3233}
3247 3234
3248static int 3235static Evas_Filter_Command *
3249_instr2cmd_mask(Evas_Filter_Context *ctx, 3236_instr2cmd_mask(Evas_Filter_Context *ctx,
3250 Evas_Filter_Instruction *instr, void *dc) 3237 Evas_Filter_Instruction *instr, void *dc)
3251{ 3238{
3252 Evas_Filter_Fill_Mode fillmode; 3239 Evas_Filter_Fill_Mode fillmode;
3240 Evas_Filter_Command *cmd;
3253 Buffer *src, *dst, *mask; 3241 Buffer *src, *dst, *mask;
3254 DATA32 color; 3242 DATA32 color;
3255 int R, G, B, A, cmdid; 3243 int R, G, B, A;
3256 3244
3257 src = _instruction_param_getbuf(instr, "src", NULL); 3245 src = _instruction_param_getbuf(instr, "src", NULL);
3258 dst = _instruction_param_getbuf(instr, "dst", NULL); 3246 dst = _instruction_param_getbuf(instr, "dst", NULL);
@@ -3264,22 +3252,17 @@ _instr2cmd_mask(Evas_Filter_Context *ctx,
3264 INSTR_PARAM_CHECK(mask); 3252 INSTR_PARAM_CHECK(mask);
3265 3253
3266 SETCOLOR(color); 3254 SETCOLOR(color);
3267 cmdid = evas_filter_command_mask_add(ctx, dc, src->cid, mask->cid, dst->cid, fillmode); 3255 cmd = evas_filter_command_mask_add(ctx, dc, src->cid, mask->cid, dst->cid, fillmode);
3268 RESETCOLOR(); 3256 RESETCOLOR();
3269 if (cmdid < 0) return cmdid; 3257 if (!cmd) return NULL;
3270
3271 if (!src->alpha && !mask->alpha && !dst->alpha)
3272 {
3273 Evas_Filter_Command *cmd;
3274 3258
3275 cmd = _evas_filter_command_get(ctx, cmdid); 3259 if (!src->alpha && !mask->alpha && !dst->alpha && !ctx->gl)
3276 cmd->draw.need_temp_buffer = EINA_TRUE; 3260 cmd->draw.need_temp_buffer = EINA_TRUE;
3277 }
3278 3261
3279 return cmdid; 3262 return cmd;
3280} 3263}
3281 3264
3282static int 3265static Evas_Filter_Command *
3283_instr2cmd_curve(Evas_Filter_Context *ctx, 3266_instr2cmd_curve(Evas_Filter_Context *ctx,
3284 Evas_Filter_Instruction *instr, void *dc) 3267 Evas_Filter_Instruction *instr, void *dc)
3285{ 3268{
@@ -3289,7 +3272,6 @@ _instr2cmd_curve(Evas_Filter_Context *ctx,
3289 Buffer *src, *dst; 3272 Buffer *src, *dst;
3290 DATA8 values[256]; 3273 DATA8 values[256];
3291 int *points; 3274 int *points;
3292 int cmdid;
3293 3275
3294 src = _instruction_param_getbuf(instr, "src", NULL); 3276 src = _instruction_param_getbuf(instr, "src", NULL);
3295 dst = _instruction_param_getbuf(instr, "dst", NULL); 3277 dst = _instruction_param_getbuf(instr, "dst", NULL);
@@ -3328,12 +3310,10 @@ _instr2cmd_curve(Evas_Filter_Context *ctx,
3328 values[x] = x; 3310 values[x] = x;
3329 } 3311 }
3330 3312
3331 cmdid = evas_filter_command_curve_add(ctx, dc, src->cid, dst->cid, values, channel); 3313 return evas_filter_command_curve_add(ctx, dc, src->cid, dst->cid, values, channel);
3332
3333 return cmdid;
3334} 3314}
3335 3315
3336static int 3316static Evas_Filter_Command *
3337_instr2cmd_transform(Evas_Filter_Context *ctx, 3317_instr2cmd_transform(Evas_Filter_Context *ctx,
3338 Evas_Filter_Instruction *instr, void *dc) 3318 Evas_Filter_Instruction *instr, void *dc)
3339{ 3319{
@@ -3355,17 +3335,18 @@ _instr2cmd_transform(Evas_Filter_Context *ctx,
3355 else 3335 else
3356 { 3336 {
3357 ERR("Invalid transform '%s'", op); 3337 ERR("Invalid transform '%s'", op);
3358 return -1; 3338 return NULL;
3359 } 3339 }
3360 3340
3361 return evas_filter_command_transform_add(ctx, dc, src->cid, dst->cid, flags, ox, oy); 3341 return evas_filter_command_transform_add(ctx, dc, src->cid, dst->cid, flags, ox, oy);
3362} 3342}
3363 3343
3364static int 3344static Eina_Bool
3365_command_from_instruction(Evas_Filter_Context *ctx, 3345_command_from_instruction(Evas_Filter_Context *ctx,
3366 Evas_Filter_Instruction *instr, void *dc) 3346 Evas_Filter_Instruction *instr, void *dc)
3367{ 3347{
3368 int (* instr2cmd) (Evas_Filter_Context *, Evas_Filter_Instruction *, void *); 3348 Evas_Filter_Command * (* instr2cmd) (Evas_Filter_Context *, Evas_Filter_Instruction *, void *);
3349 Evas_Filter_Command *cmd;
3369 3350
3370 switch (instr->type) 3351 switch (instr->type)
3371 { 3352 {
@@ -3401,10 +3382,19 @@ _command_from_instruction(Evas_Filter_Context *ctx,
3401 return EINA_TRUE; 3382 return EINA_TRUE;
3402 default: 3383 default:
3403 CRI("Invalid instruction type: %d", instr->type); 3384 CRI("Invalid instruction type: %d", instr->type);
3404 return -1; 3385 return EINA_FALSE;
3405 } 3386 }
3406 3387
3407 return instr2cmd(ctx, instr, dc); 3388 cmd = instr2cmd(ctx, instr, dc);
3389 if (!cmd) return EINA_FALSE;
3390
3391 if (cmd->output && ctx->gl)
3392 {
3393 if (ENFN->gfx_filter_supports(ENDT, cmd) == EVAS_FILTER_SUPPORT_GL)
3394 cmd->output->is_render = EINA_TRUE;
3395 }
3396
3397 return EINA_TRUE;
3408} 3398}
3409 3399
3410#ifdef FILTERS_DEBUG 3400#ifdef FILTERS_DEBUG
@@ -3477,7 +3467,6 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx,
3477 Evas_Filter_Instruction *instr; 3467 Evas_Filter_Instruction *instr;
3478 Eina_Bool success = EINA_FALSE; 3468 Eina_Bool success = EINA_FALSE;
3479 void *dc = NULL; 3469 void *dc = NULL;
3480 int cmdid;
3481 3470
3482 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); 3471 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
3483 EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE); 3472 EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE);
@@ -3518,8 +3507,7 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx,
3518 EINA_INLIST_FOREACH(pgm->instructions, instr) 3507 EINA_INLIST_FOREACH(pgm->instructions, instr)
3519 { 3508 {
3520 _instruction_dump(instr); 3509 _instruction_dump(instr);
3521 cmdid = _command_from_instruction(ctx, instr, dc); 3510 if (!_command_from_instruction(ctx, instr, dc))
3522 if (cmdid <= 0)
3523 goto end; 3511 goto end;
3524 } 3512 }
3525 3513
diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h
index 6ba1a89e67..d982e6b389 100644
--- a/src/lib/evas/filters/evas_filter_private.h
+++ b/src/lib/evas/filters/evas_filter_private.h
@@ -8,9 +8,9 @@
8extern int _evas_filter_log_dom; 8extern int _evas_filter_log_dom;
9#define EVAS_FILTER_LOG_COLOR EINA_COLOR_LIGHTBLUE 9#define EVAS_FILTER_LOG_COLOR EINA_COLOR_LIGHTBLUE
10 10
11#ifdef DEBUG 11//#ifdef DEBUG
12# define FILTERS_DEBUG 12# define FILTERS_DEBUG
13#endif 13//#endif
14 14
15#ifdef ERR 15#ifdef ERR
16# undef ERR 16# undef ERR
@@ -136,7 +136,7 @@ struct _Evas_Filter_Context
136 136
137 struct 137 struct
138 { 138 {
139 int bufid; 139 void *surface;
140 int x, y; 140 int x, y;
141 int cx, cy, cw, ch; // clip 141 int cx, cy, cw, ch; // clip
142 int r, g, b, a; // clip color 142 int r, g, b, a; // clip color
@@ -150,6 +150,7 @@ struct _Evas_Filter_Context
150 Eina_Bool async : 1; 150 Eina_Bool async : 1;
151 Eina_Bool running : 1; 151 Eina_Bool running : 1;
152 Eina_Bool has_proxies : 1; 152 Eina_Bool has_proxies : 1;
153 Eina_Bool gl : 1;
153}; 154};
154 155
155struct _Evas_Filter_Command 156struct _Evas_Filter_Command
@@ -242,6 +243,7 @@ struct _Evas_Filter_Buffer
242 Eina_Bool locked : 1; // internal flag 243 Eina_Bool locked : 1; // internal flag
243 Eina_Bool delete_me : 1; // request delete asap (after released by client) 244 Eina_Bool delete_me : 1; // request delete asap (after released by client)
244 Eina_Bool dirty : 1; // Marked as dirty as soon as a command writes to it 245 Eina_Bool dirty : 1; // Marked as dirty as soon as a command writes to it
246 Eina_Bool is_render : 1; // Is render target of a filter using engine functions (ie. needs FBO in GL)
245}; 247};
246 248
247enum _Evas_Filter_Interpolation_Mode 249enum _Evas_Filter_Interpolation_Mode
@@ -264,13 +266,9 @@ void evas_filter_context_source_set(Evas_Filter_Context *ctx
264void _clip_to_target(int *sx, int *sy, int sw, int sh, int ox, int oy, int dw, int dh, int *dx, int *dy, int *rows, int *cols); 266void _clip_to_target(int *sx, int *sy, int sw, int sh, int ox, int oy, int dw, int dh, int *dx, int *dy, int *rows, int *cols);
265Eina_Bool evas_filter_buffer_alloc(Evas_Filter_Buffer *fb, int w, int h); 267Eina_Bool evas_filter_buffer_alloc(Evas_Filter_Buffer *fb, int w, int h);
266Evas_Filter_Buffer *_filter_buffer_get(Evas_Filter_Context *ctx, int bufid); 268Evas_Filter_Buffer *_filter_buffer_get(Evas_Filter_Context *ctx, int bufid);
267Eina_Bool _filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data, int w, int h, Eina_Bool alpha_only);
268Evas_Filter_Buffer *_filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h, Eina_Bool alpha_only);
269#define evas_filter_buffer_alloc_new(ctx, w, h, a) _filter_buffer_data_new(ctx, NULL, w, h, a)
270Evas_Filter_Buffer *evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only); 269Evas_Filter_Buffer *evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only);
271Evas_Filter_Buffer *evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx, Evas_Filter_Buffer *src, unsigned w, unsigned h); 270Evas_Filter_Buffer *evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx, Evas_Filter_Buffer *src, unsigned w, unsigned h);
272Eina_Bool evas_filter_interpolate(DATA8* output /* 256 values */, int *points /* 256 values */, Evas_Filter_Interpolation_Mode mode); 271Eina_Bool evas_filter_interpolate(DATA8* output /* 256 values */, int *points /* 256 values */, Evas_Filter_Interpolation_Mode mode);
273Evas_Filter_Command *_evas_filter_command_get(Evas_Filter_Context *ctx, int cmdid);
274int evas_filter_smallest_pow2_larger_than(int val); 272int evas_filter_smallest_pow2_larger_than(int val);
275 273
276void evas_filter_parser_shutdown(void); 274void evas_filter_parser_shutdown(void);
diff --git a/src/lib/evas/include/evas_ector_buffer.eo b/src/lib/evas/include/evas_ector_buffer.eo
index 9275e75c02..d70d9710bd 100644
--- a/src/lib/evas/include/evas_ector_buffer.eo
+++ b/src/lib/evas/include/evas_ector_buffer.eo
@@ -1,19 +1,42 @@
1/* Note: only for internal C API */
2
3import evas_canvas; 1import evas_canvas;
4 2
5interface Evas.Ector.Buffer 3interface Evas.Ector.Buffer
6{ 4{
7 [[Evas ector buffer interface]] 5 [[Binding layer between ector buffers and evas images.
6
7 Subclasses implement support for RGBA_Image for SW & GL,
8 and Evas_GL_Image for GL.
9
10 Note: Internal class, not API stable.
11 ]]
8 methods { 12 methods {
9 @property engine_image { 13 engine_image_set {
10 [[Engine image property]] 14 [[Attach this ector buffer to an existing engine image.]]
11 get {} 15 params {
12 set { [[This Buffer will hold a reference to the evas image struct.]] } 16 @in evas: Evas.Canvas; [[The current Evas.]]
13 values { 17 @in image: void_ptr; [[The RGBA_Image or Evas_GL_Image.]]
14 evas: Evas.Canvas; [[The current Evas.]] 18 }
15 image: void_ptr; [[The engine-specific image struct.]] 19 }
20 drawable_image_get {
21 [[Fetch an engine image from this ector buffer as a drawable.]]
22 params {
23 @in update: bool; [[$true to update the data to the remote image.]]
24 }
25 return: void_ptr; [[The engine image (RGBA_Image or Evas_GL_Image).]]
26 }
27 render_image_get {
28 [[Fetch an engine image from this ector buffer as a render target.]]
29 params {
30 @in update: bool; [[$true to update the data to the remote image.]]
31 }
32 return: void_ptr; [[The engine image (RGBA_Image or Evas_GL_Image).]]
33 }
34 engine_image_release {
35 [[Release an image from @.drawable_image_get or @.render_image_get.]]
36 params {
37 @in image: void_ptr; [[Return value of @.drawable_image_get or @.render_image_get.]]
16 } 38 }
39 return: bool; [[$false in case of error.]]
17 } 40 }
18 } 41 }
19} 42}
diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h
index cfea9bd197..0736b5b542 100644
--- a/src/lib/evas/include/evas_filter.h
+++ b/src/lib/evas/include/evas_filter.h
@@ -146,7 +146,6 @@ void evas_filter_context_post_run_callback_set(Evas_Filter_C
146Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx); 146Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx);
147 147
148int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only); 148int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only);
149void *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid);
150void *evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid); 149void *evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid);
151Eina_Bool evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer); 150Eina_Bool evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer);
152 151
@@ -171,7 +170,7 @@ void _evas_filter_source_hash_free_cb(void *data);
171 * @return Filter command ID or -1 in case of error 170 * @return Filter command ID or -1 in case of error
172 * @internal 171 * @internal
173 */ 172 */
174int evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int ox, int oy, Evas_Filter_Fill_Mode fillmode); 173Evas_Filter_Command *evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int ox, int oy, Evas_Filter_Fill_Mode fillmode);
175 174
176/** 175/**
177 * @brief Apply a blur effect on a buffer 176 * @brief Apply a blur effect on a buffer
@@ -188,7 +187,7 @@ int evas_filter_command_blend_add(Evas_Filter_Context *ctx,
188 * @return Filter command ID or -1 in case of error 187 * @return Filter command ID or -1 in case of error
189 * @internal 188 * @internal
190 */ 189 */
191int evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Blur_Type type, int dx, int dy, int ox, int oy, int count); 190Evas_Filter_Command *evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Blur_Type type, int dx, int dy, int ox, int oy, int count);
192 191
193/** 192/**
194 * @brief Fill a buffer with the current color 193 * @brief Fill a buffer with the current color
@@ -199,7 +198,7 @@ int evas_filter_command_blur_add(Evas_Filter_Context *ctx,
199 * @note The current draw context's render operation is ignored (always uses COPY mode). 198 * @note The current draw context's render operation is ignored (always uses COPY mode).
200 * @internal 199 * @internal
201 */ 200 */
202int evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, int buf); 201Evas_Filter_Command *evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, int buf);
203 202
204/** 203/**
205 * @brief evas_filter_command_curve_add 204 * @brief evas_filter_command_curve_add
@@ -212,7 +211,7 @@ int evas_filter_command_fill_add(Evas_Filter_Context *ctx,
212 * @return Filter command ID or -1 in case of error 211 * @return Filter command ID or -1 in case of error
213 * @internal 212 * @internal
214 */ 213 */
215int evas_filter_command_curve_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, DATA8 *curve /* 256 elements */, Evas_Filter_Channel channel); 214Evas_Filter_Command *evas_filter_command_curve_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, DATA8 *curve /* 256 elements */, Evas_Filter_Channel channel);
216 215
217/** 216/**
218 * @brief Grow/Shrink an image, as defined in image processing (this is not a scale algorithm!) 217 * @brief Grow/Shrink an image, as defined in image processing (this is not a scale algorithm!)
@@ -225,7 +224,7 @@ int evas_filter_command_curve_add(Evas_Filter_Context *ctx,
225 * @return Filter command ID or -1 in case of error 224 * @return Filter command ID or -1 in case of error
226 * @internal 225 * @internal
227 */ 226 */
228int evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int radius, Eina_Bool smooth); 227Evas_Filter_Command *evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int radius, Eina_Bool smooth);
229 228
230/** 229/**
231 * @brief Apply a displacement map to a buffer. This will move pixels from the source to the destination based on pixel per pixel offset, as defined in the displacement map 230 * @brief Apply a displacement map to a buffer. This will move pixels from the source to the destination based on pixel per pixel offset, as defined in the displacement map
@@ -240,7 +239,7 @@ int evas_filter_command_grow_add(Evas_Filter_Context *ctx,
240 * @return Filter command ID or -1 in case of error 239 * @return Filter command ID or -1 in case of error
241 * @internal 240 * @internal
242 */ 241 */
243int evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int dispbuf, Evas_Filter_Displacement_Flags flags, int intensity, Evas_Filter_Fill_Mode fillmode); 242Evas_Filter_Command *evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int dispbuf, Evas_Filter_Displacement_Flags flags, int intensity, Evas_Filter_Fill_Mode fillmode);
244 243
245/** 244/**
246 * @brief Apply a texture to a buffer 245 * @brief Apply a texture to a buffer
@@ -254,7 +253,7 @@ int evas_filter_command_displacement_map_add(Evas_Filter_Co
254 * @note For the moment, inbuf can only be ALPHA, and output must be RGBA if mask is RGBA as well 253 * @note For the moment, inbuf can only be ALPHA, and output must be RGBA if mask is RGBA as well
255 * @internal 254 * @internal
256 */ 255 */
257int evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int maskbuf, int outbuf, Evas_Filter_Fill_Mode fillmode); 256Evas_Filter_Command *evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int maskbuf, int outbuf, Evas_Filter_Fill_Mode fillmode);
258 257
259/** 258/**
260 * @brief Apply a relief effect based on a bump map (Z map) 259 * @brief Apply a relief effect based on a bump map (Z map)
@@ -275,7 +274,7 @@ int evas_filter_command_mask_add(Evas_Filter_Context *ctx,
275 * @return Filter command ID or -1 in case of error 274 * @return Filter command ID or -1 in case of error
276 * @internal 275 * @internal
277 */ 276 */
278int evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int bumpbuf, int outbuf, float azimuth, float elevation, float depth, float specular_factor, DATA32 black, DATA32 color, DATA32 white, Evas_Filter_Bump_Flags flags, Evas_Filter_Fill_Mode fillmode); 277Evas_Filter_Command *evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int bumpbuf, int outbuf, float azimuth, float elevation, float depth, float specular_factor, DATA32 black, DATA32 color, DATA32 white, Evas_Filter_Bump_Flags flags, Evas_Filter_Fill_Mode fillmode);
279 278
280/** 279/**
281 * @brief Apply a geometrical transformation to the buffer 280 * @brief Apply a geometrical transformation to the buffer
@@ -289,7 +288,7 @@ int evas_filter_command_bump_map_add(Evas_Filter_Context *c
289 * @return Filter command ID or -1 in case of error 288 * @return Filter command ID or -1 in case of error
290 * @internal 289 * @internal
291 */ 290 */
292int evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags, int ox, int oy); 291Evas_Filter_Command *evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags, int ox, int oy);
293 292
294/* Simple binding between a filter object and its sources */ 293/* Simple binding between a filter object and its sources */
295struct _Evas_Filter_Proxy_Binding 294struct _Evas_Filter_Proxy_Binding
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 4d6f608ac8..98c68a0b62 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1572,8 +1572,8 @@ struct _Evas_Func
1572 1572
1573 Ector_Surface *(*ector_create) (void *data); 1573 Ector_Surface *(*ector_create) (void *data);
1574 void (*ector_destroy) (void *data, Ector_Surface *surface); 1574 void (*ector_destroy) (void *data, Ector_Surface *surface);
1575 Ector_Buffer *(*ector_buffer_wrap) (void *data, Evas *e, void *engine_image, Eina_Bool is_rgba_image); 1575 Ector_Buffer *(*ector_buffer_wrap) (void *data, Evas *e, void *engine_image);
1576 Ector_Buffer *(*ector_buffer_new) (void *data, Evas *e, void *pixels, int width, int height, int stride, Efl_Gfx_Colorspace cspace, Eina_Bool writeable, int l, int r, int t, int b, Ector_Buffer_Flag flags); 1576 Ector_Buffer *(*ector_buffer_new) (void *data, Evas *e, int width, int height, Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags);
1577 void (*ector_begin) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, int x, int y, Eina_Bool do_async); 1577 void (*ector_begin) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, int x, int y, Eina_Bool do_async);
1578 void (*ector_renderer_draw) (void *data, void *context, void *surface, void *engine_data, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async); 1578 void (*ector_renderer_draw) (void *data, void *context, void *surface, void *engine_data, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
1579 void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async); 1579 void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h
index ef91f7b9d6..38474bbe35 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -688,6 +688,7 @@ void evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x,
688void evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im); 688void evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im);
689void evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int npoints, RGBA_Map_Point *p, int smooth, int level); 689void evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int npoints, RGBA_Map_Point *p, int smooth, int level);
690void evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth); 690void evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth);
691Evas_GL_Image *evas_gl_common_image_surface_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im);
691 692
692void *evas_gl_font_texture_new(void *gc, RGBA_Font_Glyph *fg); 693void *evas_gl_font_texture_new(void *gc, RGBA_Font_Glyph *fg);
693void evas_gl_font_texture_free(void *); 694void evas_gl_font_texture_free(void *);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c
index 3b02db1406..de907be540 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_image.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_image.c
@@ -248,6 +248,8 @@ evas_gl_common_image_new_from_rgbaimage(Evas_Engine_GL_Context *gc, RGBA_Image *
248 } 248 }
249 */ 249 */
250 250
251 if (error) *error = EVAS_LOAD_ERROR_NONE;
252
251 // FIXME: keep unreffed shared images around 253 // FIXME: keep unreffed shared images around
252 EINA_LIST_FOREACH(gc->shared->images, l, im) 254 EINA_LIST_FOREACH(gc->shared->images, l, im)
253 { 255 {
@@ -1039,6 +1041,65 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
1039 } 1041 }
1040} 1042}
1041 1043
1044Evas_GL_Image *
1045evas_gl_common_image_surface_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
1046{
1047 Evas_GL_Image *glim = NULL;
1048 Eina_Bool alpha;
1049 int w, h;
1050
1051 if (!gc || !im || !im->im || !im->im->image.data)
1052 goto fail;
1053
1054 if (im->im->cache_entry.space == EFL_GFX_COLORSPACE_ARGB8888)
1055 alpha = EINA_FALSE;
1056 else if (im->im->cache_entry.space == EFL_GFX_COLORSPACE_GRY8)
1057 alpha = EINA_TRUE;
1058 else goto fail;
1059
1060 w = im->im->cache_entry.w;
1061 h = im->im->cache_entry.h;
1062 glim = evas_gl_common_image_surface_new(gc, w, h, EINA_TRUE, EINA_FALSE);
1063 if (!glim) goto fail;
1064
1065 if (alpha)
1066 {
1067 RGBA_Image *image;
1068 uint32_t *rgba;
1069 uint8_t *gry8;
1070 int k;
1071
1072 image = evas_common_image_new(w, h, EINA_TRUE);
1073 if (!image) goto fail;
1074
1075 rgba = image->image.data;
1076 gry8 = im->im->image.data8;
1077 for (k = 0; k < (w * h); k++)
1078 {
1079 const int c = *gry8++;
1080 *rgba++ = ARGB_JOIN(c, c, c, c);
1081 }
1082
1083 glim->im = image;
1084 }
1085 else
1086 {
1087 evas_cache_image_ref(&im->im->cache_entry);
1088 glim->im = im->im;
1089 }
1090
1091 glim->dirty = EINA_TRUE;
1092 evas_gl_common_image_update(gc, glim);
1093 evas_gl_common_image_free(im);
1094
1095 return glim;
1096
1097fail:
1098 ERR("Failed to update surface pixels!");
1099 if (glim) evas_gl_common_image_free(glim);
1100 return NULL;
1101}
1102
1042void 1103void
1043evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, 1104evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
1044 int npoints, RGBA_Map_Point *p, int smooth, int level EINA_UNUSED) 1105 int npoints, RGBA_Map_Point *p, int smooth, int level EINA_UNUSED)
diff --git a/src/modules/evas/engines/gl_common/evas_gl_texture.c b/src/modules/evas/engines/gl_common/evas_gl_texture.c
index f4d747e331..77c55f593b 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_texture.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_texture.c
@@ -82,6 +82,7 @@ static const struct {
82 { MATCH_FALSE, MATCH_FALSE, EVAS_COLORSPACE_ARGB8888, &rgb_ifmt, &rgb_fmt }, 82 { MATCH_FALSE, MATCH_FALSE, EVAS_COLORSPACE_ARGB8888, &rgb_ifmt, &rgb_fmt },
83#endif 83#endif
84 { MATCH_FALSE, MATCH_ANY, EVAS_COLORSPACE_GRY8, &lum_fmt, &lum_ifmt }, 84 { MATCH_FALSE, MATCH_ANY, EVAS_COLORSPACE_GRY8, &lum_fmt, &lum_ifmt },
85 { MATCH_TRUE, MATCH_ANY, EVAS_COLORSPACE_GRY8, &alpha_fmt, &alpha_ifmt },
85 { MATCH_TRUE, MATCH_ANY, EVAS_COLORSPACE_AGRY88, &lum_alpha_fmt, &lum_alpha_ifmt }, 86 { MATCH_TRUE, MATCH_ANY, EVAS_COLORSPACE_AGRY88, &lum_alpha_fmt, &lum_alpha_ifmt },
86 // ETC1/2 support 87 // ETC1/2 support
87 { MATCH_FALSE, MATCH_ANY, EVAS_COLORSPACE_ETC1, &etc1_fmt, &etc1_fmt }, 88 { MATCH_FALSE, MATCH_ANY, EVAS_COLORSPACE_ETC1, &etc1_fmt, &etc1_fmt },
diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c b/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c
index 4736e6592c..ef8999e160 100644
--- a/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c
+++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c
@@ -2,13 +2,357 @@
2# include "config.h" 2# include "config.h"
3#endif 3#endif
4 4
5#define ECTOR_GL_BUFFER_BASE_PROTECTED
6
7#include "evas_common_private.h"
8#include "evas_gl_private.h"
9
5#include <gl/Ector_GL.h> 10#include <gl/Ector_GL.h>
6#include "gl/ector_gl_private.h" 11#include "gl/ector_gl_private.h"
7#include "evas_common_private.h" 12#include "evas_common_private.h"
13#include "../gl_common/evas_gl_common.h"
14#include "evas_private.h"
8#include "ector_buffer.h" 15#include "ector_buffer.h"
16#include "Evas_Engine_GL_Generic.h"
17
9#include "evas_ector_buffer.eo.h" 18#include "evas_ector_buffer.eo.h"
10#include "evas_ector_gl_buffer.eo.h" 19#include "evas_ector_gl_buffer.eo.h"
11 20
12#define MY_CLASS EVAS_ECTOR_GL_BUFFER_CLASS 21#define MY_CLASS EVAS_ECTOR_GL_BUFFER_CLASS
13 22
23typedef struct _Ector_GL_Buffer_Map Ector_GL_Buffer_Map;
24typedef struct _Evas_Ector_GL_Buffer_Data Evas_Ector_GL_Buffer_Data;
25
26struct _Ector_GL_Buffer_Map
27{
28 EINA_INLIST;
29 void *ptr;
30 unsigned int base_size; // in bytes
31 unsigned int x, y, w, h;
32 void *image_data, *base_data;
33 size_t length;
34 Efl_Gfx_Colorspace cspace;
35 Evas_GL_Image *im;
36 Eina_Bool allocated;
37 Ector_Buffer_Access_Flag mode;
38};
39
40struct _Evas_Ector_GL_Buffer_Data
41{
42 Evas_Public_Data *evas;
43 Evas_GL_Image *glim;
44 Eina_Bool alpha_only;
45 Ector_GL_Buffer_Map *maps;
46};
47
48#define ENFN pd->evas->engine.func
49#define ENDT pd->evas->engine.data.output
50
51// testing out some macros to maybe add to eina
52#define EINA_INLIST_REMOVE(l,i) do { l = (__typeof__(l)) eina_inlist_remove(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
53#define EINA_INLIST_APPEND(l,i) do { l = (__typeof__(l)) eina_inlist_append(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
54#define EINA_INLIST_PREPEND(l,i) do { l = (__typeof__(l)) eina_inlist_prepend(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
55
56#define fail(fmt, ...) do { ERR(fmt, ##__VA_ARGS__); goto on_fail; } while (0)
57
58/* FIXME: Conversion routines don't belong here */
59static inline void
60_pixels_argb_to_gry8_convert(uint8_t *dst, const uint32_t *src, int len)
61{
62 int k;
63 for (k = 0; k < len; k++)
64 {
65 const uint32_t *s = src++;
66 *dst++ = A_VAL(s);
67 }
68}
69
70static inline void
71_pixels_gry8_to_argb_convert(uint32_t *dst, const uint8_t *src, int len)
72{
73 int k;
74 for (k = 0; k < len; k++)
75 {
76 const uint8_t s = *src++;
77 *dst++ = ARGB_JOIN(s, s, s, s);
78 }
79}
80
81static inline Eina_Bool
82_evas_gl_image_is_fbo(Evas_GL_Image *glim)
83{
84 return glim && glim->tex && glim->tex->pt && glim->tex->pt->fb;
85}
86
87EOLIAN static void
88_evas_ector_gl_buffer_gl_buffer_prepare(Eo *obj, Evas_Ector_GL_Buffer_Data *pd,
89 Evas_Canvas *eo_evas,
90 int w, int h, Efl_Gfx_Colorspace cspace,
91 Ector_Buffer_Flag flags EINA_UNUSED)
92{
93 Render_Engine_GL_Generic *re;
94 Evas_Engine_GL_Context *gc;
95 Evas_GL_Image *im;
96
97 // this is meant to be called only once
98 EINA_SAFETY_ON_FALSE_GOTO(!pd->evas, on_fail);
99 EINA_SAFETY_ON_FALSE_GOTO(!efl_finalized_get(obj), on_fail);
100
101 if (cspace == EFL_GFX_COLORSPACE_ARGB8888)
102 pd->alpha_only = EINA_FALSE;
103 else if (cspace == EFL_GFX_COLORSPACE_GRY8)
104 pd->alpha_only = EINA_TRUE;
105 else
106 fail("Unsupported colorspace: %u", cspace);
107
108 pd->evas = efl_data_xref(eo_evas, EVAS_CANVAS_CLASS, obj);
109 re = pd->evas->engine.data.output;
110 gc = re->window_gl_context_get(re->software.ob);
111
112 im = evas_gl_common_image_surface_new(gc, w, h, EINA_TRUE, EINA_FALSE);
113 if (!im) fail("Failed to create GL surface!");
114
115 pd->glim = im;
116 return;
117
118on_fail:
119 if (pd->glim) evas_gl_common_image_free(pd->glim);
120 pd->glim = NULL;
121}
122
123EOLIAN static void *
124_evas_ector_gl_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
125 Evas_Ector_GL_Buffer_Data *pd,
126 Eina_Bool update)
127{
128 Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
129 Evas_Engine_GL_Context *gc;
130
131 if (pd->maps != NULL)
132 fail("Image is currently mapped!");
133
134 evas_gl_common_image_ref(pd->glim);
135 if (!update) return pd->glim;
136
137 gc = re->window_gl_context_get(re->software.ob);
138 evas_gl_common_image_update(gc, pd->glim);
139
140 return pd->glim;
141
142on_fail:
143 return NULL;
144}
145
146EOLIAN static void *
147_evas_ector_gl_buffer_evas_ector_buffer_render_image_get(Eo *obj EINA_UNUSED,
148 Evas_Ector_GL_Buffer_Data *pd,
149 Eina_Bool update)
150{
151 Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
152 Evas_Engine_GL_Context *gc;
153
154 if (pd->maps != NULL)
155 fail("Image is currently mapped!");
156
157 evas_gl_common_image_ref(pd->glim);
158 if (!update) return pd->glim;
159
160 gc = re->window_gl_context_get(re->software.ob);
161 evas_gl_common_image_update(gc, pd->glim);
162
163 return pd->glim;
164
165on_fail:
166 return NULL;
167}
168
169EOLIAN static Eina_Bool
170_evas_ector_gl_buffer_evas_ector_buffer_engine_image_release(Eo *obj EINA_UNUSED,
171 Evas_Ector_GL_Buffer_Data *pd,
172 void *image)
173{
174 EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
175 EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->glim == image, EINA_FALSE);
176
177 evas_gl_common_image_free(pd->glim);
178
179 return EINA_TRUE;
180}
181
182EOLIAN static void
183_evas_ector_gl_buffer_ector_buffer_size_get(Eo *obj EINA_UNUSED,
184 Evas_Ector_GL_Buffer_Data *pd,
185 int *w, int *h)
186{
187 if (w) *w = pd->glim->w;
188 if (h) *h = pd->glim->h;
189}
190
191EOLIAN static Efl_Gfx_Colorspace
192_evas_ector_gl_buffer_ector_buffer_cspace_get(Eo *obj EINA_UNUSED,
193 Evas_Ector_GL_Buffer_Data *pd)
194{
195 if (pd->alpha_only)
196 return EFL_GFX_COLORSPACE_GRY8;
197 else
198 return EFL_GFX_COLORSPACE_ARGB8888;
199}
200
201EOLIAN static Ector_Buffer_Flag
202_evas_ector_gl_buffer_ector_buffer_flags_get(Eo *obj EINA_UNUSED,
203 Evas_Ector_GL_Buffer_Data *pd EINA_UNUSED)
204{
205 return ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_DRAWABLE |
206 ECTOR_BUFFER_FLAG_CPU_WRITABLE | ECTOR_BUFFER_FLAG_RENDERABLE;
207}
208
209EOLIAN static void *
210_evas_ector_gl_buffer_ector_buffer_map(Eo *obj EINA_UNUSED, Evas_Ector_GL_Buffer_Data *pd,
211 unsigned int *length,
212 Ector_Buffer_Access_Flag mode,
213 unsigned int x, unsigned int y, unsigned int w, unsigned int h,
214 Efl_Gfx_Colorspace cspace, unsigned int *stride)
215{
216 Eina_Bool write = !!(mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE);
217 Ector_GL_Buffer_Map *map = NULL;
218 Eina_Bool tofree = EINA_FALSE;
219 Evas_GL_Image *im = NULL;
220 unsigned int W, H;
221 int len, err;
222 uint32_t *data;
223 int pxs;
224
225 W = pd->glim->w;
226 H = pd->glim->h;
227 if (!w) w = W - x;
228 if (!h) h = H - y;
229 if ((x + w > W) || (y + h > H)) return NULL;
230
231