summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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 if (write && _evas_gl_image_is_fbo(pd->glim))
232 {
233 // Can not open FBO data to write!
234 im = ENFN->image_data_get(ENDT, pd->glim, EINA_FALSE, &data, &err, &tofree);
235 if (!im) return NULL;
236 }
237 else
238 {
239 im = ENFN->image_data_get(ENDT, pd->glim, write, &data, &err, &tofree);