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 = \ lib/ector/ector_buffer.eo \ lib/ector/ector_renderer.eo \ lib/ector/ector_renderer_shape.eo \ - lib/ector/ector_renderer_buffer.eo \ lib/ector/ector_renderer_gradient.eo \ lib/ector/ector_renderer_gradient_radial.eo \ lib/ector/ector_renderer_gradient_linear.eo @@ -28,7 +27,6 @@ ector_eolian_files_software = \ lib/ector/software/ector_software_buffer_base.eo \ lib/ector/software/ector_renderer_software.eo \ lib/ector/software/ector_renderer_software_shape.eo \ - lib/ector/software/ector_renderer_software_buffer.eo \ lib/ector/software/ector_renderer_software_gradient_radial.eo \ lib/ector/software/ector_renderer_software_gradient_linear.eo ector_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) ector_eolian_files_gl = \ lib/ector/gl/ector_gl_surface.eo \ lib/ector/gl/ector_gl_buffer.eo \ - lib/ector/gl/ector_gl_buffer_base.eo \ lib/ector/gl/ector_renderer_gl.eo \ lib/ector/gl/ector_renderer_gl_shape.eo \ lib/ector/gl/ector_renderer_gl_gradient_radial.eo \ @@ -84,7 +81,6 @@ lib/ector/ector_gl_internal.h \ lib/ector/ector_buffer.c \ lib/ector/ector_renderer_shape.c \ lib/ector/ector_renderer.c \ -lib/ector/ector_renderer_buffer.c \ lib/ector/ector_renderer_gradient.c \ lib/ector/ector_renderer_gradient_radial.c \ lib/ector/ector_renderer_gradient_linear.c @@ -121,7 +117,6 @@ lib_ector_libector_la_SOURCES += \ lib/ector/software/ector_renderer_software_gradient_linear.c \ lib/ector/software/ector_renderer_software_gradient_radial.c \ lib/ector/software/ector_renderer_software_shape.c \ -lib/ector/software/ector_renderer_software_buffer.c \ lib/ector/software/ector_software_gradient.c \ lib/ector/software/ector_software_rasterizer.c \ lib/ector/software/ector_software_surface.c \ @@ -138,7 +133,6 @@ lib/ector/gl/ector_renderer_gl_gradient_radial.c \ lib/ector/gl/ector_renderer_gl_shape.c \ lib/ector/gl/ector_renderer_gl.c \ lib/ector/gl/ector_gl_buffer.c \ -lib/ector/gl/ector_gl_buffer_base.c \ lib/ector/gl/ector_gl_surface.c \ lib/ector/gl/ector_gl_private.h \ lib/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 \ modules/evas/engines/gl_generic/Evas_Engine_GL_Shared.h \ modules/evas/engines/gl_generic/evas_ector_gl_buffer.c \ modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c \ -modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c \ modules/evas/engines/gl_generic/filters/gl_engine_filter.h \ modules/evas/engines/gl_generic/filters/gl_filter_blend.c \ $(NULL) @@ -850,7 +849,6 @@ $(NULL) evas_gl_generic_eolian_files = \ modules/evas/engines/gl_generic/evas_ector_gl_buffer.eo \ modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.eo \ -modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.eo \ $(NULL) evas_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[] = { /* builtin filter examples */ static const Filter templates[] = { { "Custom", NULL, NULL }, + { "Simple blend", + "blend { color = 'darkblue' }", NULL }, { "Black shadow", "if not myColor then myColor = color('yellow') end\n" "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 efl_ui_text_scrollable_set(efl_added, 1)); efl_event_callback_add(o, EFL_UI_TEXT_EVENT_CHANGED_USER, _code_changed, win); - // Insert filter code inside style string: DEFAULT='blah blah ' - buf = eina_strbuf_new(); - eina_strbuf_append(buf, efl_canvas_text_style_get(o, NULL)); - eina_strbuf_insert(buf, " gfx_filter=code", eina_strbuf_length_get(buf) - 1); - efl_gfx_filter_program_set(o, code_filter, "code"); - efl_canvas_text_style_set(o, NULL, eina_strbuf_string_get(buf)); - eina_strbuf_free(buf); + // HACK: For now only set filter on code if engine is not GL (WIP) + const char *engine = ecore_evas_engine_name_get + (ecore_evas_ecore_evas_get(evas_object_evas_get(win))); + if (engine && !strstr(engine, "gl")) + { + // Insert filter code inside style string: DEFAULT='blah blah ' + buf = eina_strbuf_new(); + eina_strbuf_append(buf, efl_canvas_text_style_get(o, NULL)); + eina_strbuf_insert(buf, " gfx_filter=code", eina_strbuf_length_get(buf) - 1); + efl_gfx_filter_program_set(o, code_filter, "code"); + efl_canvas_text_style_set(o, NULL, eina_strbuf_string_get(buf)); + eina_strbuf_free(buf); + } // FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME // 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 EOLIAN static Eina_Bool _ector_cairo_software_surface_ector_buffer_pixels_set(Eo *obj, Ector_Cairo_Software_Surface_Data *pd, - void *pixels, int width, int height, int stride, - Efl_Gfx_Colorspace cspace, Eina_Bool writable, - unsigned char l, unsigned char r, unsigned char t, unsigned char b) + void *pixels, int width, int height, + Efl_Gfx_Colorspace cspace, Eina_Bool writable) { cairo_t *ctx = NULL; Eina_Bool ok = EINA_FALSE; @@ -73,7 +72,7 @@ _ector_cairo_software_surface_ector_buffer_pixels_set(Eo *obj, Ector_Cairo_Softw cairo_surface_destroy(pd->surface); pd->surface = NULL; - ok = ector_buffer_pixels_set(efl_super(obj, MY_CLASS), pixels, width, height, stride, cspace, writable, l, r, t, b); + ok = ector_buffer_pixels_set(efl_super(obj, MY_CLASS), pixels, width, height, cspace, writable); if (ok && pixels) { 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 @@ -14,15 +14,6 @@ _ector_buffer_cspace_get(Eo *obj EINA_UNUSED, Ector_Buffer_Data *pd) return pd->cspace; } -EOLIAN static void -_ector_buffer_border_get(Eo *obj EINA_UNUSED, Ector_Buffer_Data *pd EINA_UNUSED, int *l, int *r, int *t, int *b) -{ - if (l) *l = pd->l; - if (r) *r = pd->r; - if (t) *t = pd->t; - if (b) *b = pd->b; -} - EOLIAN static void _ector_buffer_size_get(Eo *obj EINA_UNUSED, Ector_Buffer_Data *pd, int *w, int *h) { 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 { mixin Ector.Buffer { [[2D pixel buffer interface for Ector + @since 1.17 ]] eo_prefix: ector_buffer; @@ -76,38 +77,11 @@ mixin Ector.Buffer @in pixels: void_ptr; [[If $null, allocates an empty buffer]] @in width: int; [[Buffer width]] @in height: int; [[Buffer height]] - @in stride: int; [[Can be 0]] @in cspace: Efl.Gfx.Colorspace; [[Buffer colorspace]] @in writable: bool; [[Buffer is writable]] - @in l: ubyte; [[Left border pixels, usually 0 or 1]] - @in r: ubyte; [[Right border pixels, usually 0 or 1]] - @in t: ubyte; [[Top border pixels, usually 0 or 1]] - @in b: ubyte; [[Bottom border pixels, usually 0 or 1]] } return: bool; [[True if pixels_set was successful]] } - span_get @pure_virtual { - [[Get a single horizontal span of length w starting from (x,y) - - Call span_free() to release it. This function will try not to - allocate any new buffer, whenever possible. This means the data - might be mapped directly from the backing memory buffer. - ]] - params { - @in x: int; [[Ranges from -l to w+r-1]] - @in y: int; [[Ranges from -t to h+b-1]] - @in w: uint; [[Ranges from 1 to w+l+r]] - @in cspace: Efl.Gfx.Colorspace; [[Requested colorspace, may trigger conversion on the fly.]] - @out length: uint; [[Length in bytes of the returned buffer]] - } - return: ptr(uint8); [[A temporary memory buffer containing the pixels requested.]] - } - span_free @pure_virtual { - [[Must be called as soon as possible after span_get]] - params { - data: ptr(uint8); [[Data to be freed]] - } - } @property flags { [[The capabilities of this buffer]] get {} @@ -115,16 +89,6 @@ mixin Ector.Buffer flag: Ector.Buffer.Flag; [[A bitmask of capability flags]] } } - @property border { - [[Duplicated pixel borders of this buffer, used for GL scaling]] - get {} - values { - l: int; [[Left border]] - r: int; [[Right border]] - t: int; [[Top border]] - b: int; [[Bottom border]] - } - } } events { 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; typedef struct _Ector_Buffer_Data Ector_Buffer_Data; typedef struct _Ector_Software_Buffer_Base_Data Ector_Software_Buffer_Base_Data; -typedef struct _Ector_GL_Buffer_Base_Data Ector_GL_Buffer_Base_Data; struct _Ector_Buffer_Data { Ector_Buffer *eo; unsigned int w, h; - unsigned char l, r, t, b; Efl_Gfx_Colorspace cspace; Eina_Bool immutable : 1; // pixels_set is forbidden }; @@ -45,17 +43,4 @@ struct _Ector_Software_Buffer_Base_Data Eina_Bool nofree : 1; // pixel data should not be free()'ed }; -struct _Ector_GL_Buffer_Base_Data -{ - Ector_Buffer_Data *generic; - int texid; - int fboid; - struct { - // x,y offset within the atlas - // w,h size of the atlas itself - int x, y, w, h; - } atlas; - Eina_Bool whole : 1; -}; - #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 @@ #include "ector_renderer.eo.h" #include "ector_renderer_shape.eo.h" -#include "ector_renderer_buffer.eo.h" #include "ector_renderer_gradient.eo.h" #include "ector_renderer_gradient_linear.eo.h" #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 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#else -# define EFL_BETA_API_SUPPORT -#endif - -#include -#include "ector_private.h" -#include "ector_renderer_buffer.eo.h" - -#define MY_CLASS ECTOR_RENDERER_BUFFER_MIXIN - -EOLIAN static void -_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) -{ - if (x) *x = pd->fill.x; - if (y) *y = pd->fill.y; - if (w) *w = pd->fill.w; - if (h) *h = pd->fill.h; -} - -EOLIAN static void -_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) -{ - if (w < 0) w = 0; - if (h < 0) h = 0; - pd->fill.x = x; - pd->fill.y = y; - pd->fill.w = w; - pd->fill.h = h; -} - -EOLIAN static void -_ector_renderer_buffer_buffer_set(Eo *obj EINA_UNUSED, Ector_Renderer_Buffer_Data *pd, Ector_Buffer *buf) -{ - _efl_xrefplace(&pd->eo_buffer, buf, obj); -} - -EOLIAN static Ector_Buffer * -_ector_renderer_buffer_buffer_get(Eo *obj EINA_UNUSED, Ector_Renderer_Buffer_Data *pd) -{ - return pd->eo_buffer; -} - -#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 @@ -mixin Ector.Renderer.Buffer (Efl.Interface, Ector.Renderer, Efl.Gfx.Fill) -{ - [[Ector buffers have a default fill set to repeat]] - eo_prefix: ector_renderer_buffer; - methods { - @property buffer { - set { [[Sets the source buffer for this renderer, adds a ref]] } - get { [[Return the current source, no ref change]] } - values { - buf: Ector.Buffer; [[Buffer]] - } - } - } - implements { - Efl.Gfx.Fill.fill { get; set; } - } -} 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; typedef unsigned int GLuint; typedef short GLshort; -#include "gl/ector_gl_buffer_base.eo.h" #include "gl/ector_gl_buffer.eo.h" #include "gl/ector_gl_surface.eo.h" #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 @@ -class Ector.GL.Buffer (Efl.Object, Ector.GL.Buffer.Base) +class Ector.GL.Buffer (Efl.Object, Ector.Buffer) { [[Ector GL buffer class]] 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 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "Ector_GL.h" -#include "ector_gl_private.h" -#include "ector_buffer.h" -#include "ector_gl_buffer_base.eo.h" - -#define MY_CLASS ECTOR_GL_BUFFER_BASE_MIXIN - -EOLIAN static int -_ector_gl_buffer_base_texture_get(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd) -{ - return pd->texid; -} - -EOLIAN static int -_ector_gl_buffer_base_fbo_get(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd) -{ - return pd->fboid; -} - -EOLIAN static Eina_Bool -_ector_gl_buffer_base_whole_get(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd) -{ - return pd->whole; -} - -EOLIAN static void -_ector_gl_buffer_base_vertices_get(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd, double *x, double *y, double *w, double *h) -{ - if (x) *x = (double) pd->atlas.x / pd->atlas.w; - if (y) *y = (double) pd->atlas.y / pd->atlas.h; - if (w) *w = (double) pd->generic->w / pd->atlas.w; - if (h) *h = (double) pd->generic->h / pd->atlas.h; -} - -EOLIAN static void -_ector_gl_buffer_base_attach(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd, - int texid, int fboid, Efl_Gfx_Colorspace cspace, - int imw, int imh, int tx, int ty, int tw, int th, - int l, int r, int t, int b) -{ - EINA_SAFETY_ON_NULL_RETURN(pd->generic); - EINA_SAFETY_ON_FALSE_RETURN(!pd->generic->immutable); - - pd->generic->cspace = cspace; - pd->generic->w = imw; - pd->generic->h = imh; - pd->atlas.x = tx; - pd->atlas.y = ty; - pd->atlas.w = tw; - pd->atlas.h = th; - pd->generic->l = l; - pd->generic->r = r; - pd->generic->t = t; - pd->generic->b = b; - if (!(tx - l) && !(ty - t) && ((tw + l + r) == imw) && ((th + t + b) == imh)) - pd->whole = EINA_TRUE; - pd->fboid = fboid; - pd->texid = texid; -} - -#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 @@ -mixin Ector.GL.Buffer.Base (Ector.Buffer) -{ - [[Ector GL buffer base class]] - methods { - @property texture { - [[GL texture ID]] - get {} - values { - texid: int; [[GL texture ID]] - } - } - @property fbo { - [[Framebuffer object ID]] - get {} - values { - fboid: int; [[GL framebuffer ID, 0 if there is no FBO]] - } - } - @property whole { - [[If $true, the image is covering the entire GL texture, ie. it's not - part of an atlas. - ]] - get {} - values { - is_whole: bool; [[$true if the image is covering the whole GL texture, $false otherwise]] - } - } - @property vertices { - [[Returns the texture vertices to draw this image with no rotation - - The 4 points are then defined as (x,y), (x+w,y), (x,y+h), (x+w,y+h). - ]] - get {} - values { - x: double; [[X position of this image inside the texture atlas, from 0 to 1]] - y: double; [[Y position of this image inside the texture atlas, from 0 to 1]] - w: double; [[Width of this image inside the texture atlas, from 0 to 1]] - h: double; [[Height of this image inside the texture atlas, from 0 to 1]] - } - } - attach @protected { - [[Attach to an existing texture (or FBO). Used from child classes.]] - params { - texid: int; [[GL texture ID]] - fboid: int; [[Framebuffer object ID]] - cspace: Efl.Gfx.Colorspace; [[Colorspace]] - imw: int; [[Image width]] - imh: int; [[Image height]] - tx: int; [[Texture X coordinate]] - ty: int; [[Texture Y coordinate]] - tw: int; [[Texture width]] - th: int; [[Texture height]] - l: int; [[Left padding]] - r: int; [[Right padding]] - t: int; [[Top padding]] - b: int; [[Bottom padding]] - } - } - } -} 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 @@ #include "software/ector_software_buffer_base.eo.h" #include "software/ector_renderer_software.eo.h" #include "software/ector_renderer_software_shape.eo.h" -#include "software/ector_renderer_software_buffer.eo.h" #include "software/ector_renderer_software_gradient_linear.eo.h" #include "software/ector_renderer_software_gradient_radial.eo.h" 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 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#else -# define EFL_BETA_API_SUPPORT -#endif - -#include -#include "Ector_Software.h" -#include "ector_private.h" -#include "ector_software_private.h" - -#define MY_CLASS ECTOR_RENDERER_SOFTWARE_BUFFER_CLASS - -typedef struct -{ - Ector_Renderer_Data *base; - Software_Rasterizer *surface; - Ector_Buffer *eo_buffer; -} Ector_Renderer_Software_Buffer_Data; - - -EOLIAN static void -_ector_renderer_software_buffer_buffer_set(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd, Ector_Buffer *buf) -{ - _efl_xrefplace(&pd->eo_buffer, buf, obj); -} - -EOLIAN static Ector_Buffer * -_ector_renderer_software_buffer_buffer_get(Eo *obj EINA_UNUSED, Ector_Renderer_Software_Buffer_Data *pd) -{ - return pd->eo_buffer; -} - -EOLIAN static Eina_Bool -_ector_renderer_software_buffer_ector_renderer_software_fill(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd) -{ - Ector_Software_Buffer *buffer = efl_data_scope_get(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN); - ector_software_rasterizer_buffer_set(pd->surface, buffer); - return EINA_TRUE; -} - -EOLIAN static Eina_Bool -_ector_renderer_software_buffer_ector_renderer_prepare(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd) -{ - if (!pd->surface) - pd->surface = efl_data_xref(pd->base->surface, ECTOR_SOFTWARE_SURFACE_CLASS, obj); - - return EINA_TRUE; -} - -EOLIAN static unsigned int -_ector_renderer_software_buffer_ector_renderer_crc_get(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd) -{ - Ector_Software_Buffer_Base_Data *buffer = efl_data_scope_get(pd->eo_buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN); - unsigned int crc; - - crc = ector_renderer_crc_get(efl_super(obj, MY_CLASS)); - crc = eina_crc((const char *) buffer, sizeof(*buffer), crc, EINA_FALSE); - if (pd->surface) - crc = eina_crc((const char *) pd->surface, sizeof(*pd->surface), crc, EINA_FALSE); - - return crc; -} - -EOLIAN static void -_ector_renderer_software_buffer_efl_object_destructor(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd) -{ - efl_data_xunref(pd->base->surface, pd->surface, obj); - efl_destructor(efl_super(obj, MY_CLASS)); -} - -#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 @@ -class Ector.Renderer.Software.Buffer (Ector.Renderer.Software, Ector.Renderer.Buffer) -{ - [[Ecto software renderer buffer class]] - methods { - @property buffer { - [[Buffer property]] - set {} - get {} - values { - buf: Ector.Buffer; [[Buffer]] - } - } - } - implements { - Ector.Renderer.prepare; - Ector.Renderer.crc { get; } - Ector.Renderer.Software.fill; - Efl.Object.destructor; - } -} 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 { EINA_INLIST; uint8_t *ptr; - unsigned int size; // in bytes + unsigned int size, stride; // in bytes unsigned int x, y, w, h; Efl_Gfx_Colorspace cspace; Eina_Bool allocated; Ector_Buffer_Access_Flag mode; } Ector_Software_Buffer_Map; -static inline int -_min_stride_calc(int width, Efl_Gfx_Colorspace cspace) -{ - switch (cspace) - { - case EFL_GFX_COLORSPACE_ARGB8888: return width * 4; - case EFL_GFX_COLORSPACE_GRY8: return width; - default: return 0; - } -} - /* FIXME: Conversion routines don't belong here */ static inline void _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 return; if (pd->internal.maps) - { - CRI("Can not call pixels_clear when the buffer is mapped."); - return; - } + fail("Can not call pixels_clear when the buffer is mapped."); efl_event_callback_call(obj, ECTOR_BUFFER_EVENT_DETACHED, pd->pixels.u8); if (!pd->nofree) @@ -76,54 +62,37 @@ _ector_software_buffer_base_pixels_clear(Eo *obj, Ector_Software_Buffer_Base_Dat } pd->pixels.u8 = NULL; pd->nofree = EINA_FALSE; + + return; + +on_fail: + return; } EOLIAN static Eina_Bool _ector_software_buffer_base_ector_buffer_pixels_set(Eo *obj, Ector_Software_Buffer_Base_Data *pd, - void *pixels, int width, int height, int stride, - Efl_Gfx_Colorspace cspace, Eina_Bool writable, - unsigned char l, unsigned char r, - unsigned char t, unsigned char b) + void *pixels, int width, int height, + Efl_Gfx_Colorspace cspace, Eina_Bool writable) { - unsigned px; + unsigned pxs, stride; if (pd->generic->immutable) - { - ERR("This buffer is immutable."); - return EINA_FALSE; - } + fail("This buffer is immutable."); if (pd->internal.maps) - { - ERR("Can not call pixels_set when the buffer is mapped."); - return EINA_FALSE; - } + fail("Can not call pixels_set when the buffer is mapped."); - // safety check - px = _min_stride_calc(1, cspace); - if (px && ((unsigned long long)(uintptr_t)pixels) & (px - 1)) - ERR("Pixel data is not aligned to %u bytes!", px); + if (cspace == EFL_GFX_COLORSPACE_ARGB8888) + pxs = 4; + else if (cspace == EFL_GFX_COLORSPACE_GRY8) + pxs = 1; + else + fail("Unsupported colorspace: %u", cspace); - if ((cspace != EFL_GFX_COLORSPACE_ARGB8888) && - (cspace != EFL_GFX_COLORSPACE_GRY8)) - { - ERR("Unsupported colorspace: %u", cspace); - return EINA_FALSE; - } - - if (!stride) - stride = _min_stride_calc(width + l + r, cspace); - else if (stride < _min_stride_calc(width + l + r, cspace)) - { - ERR("Invalid stride %u for width %u (+%u+%u) cspace %u. pixels_set failed.", - stride, width, l, r, cspace); - _ector_software_buffer_base_pixels_clear(obj, pd); - return EINA_FALSE; - } - - if ((px > 1) && (stride & (px - 1))) - ERR("Stride (%d) is not aligned to the pixel size (%d)", stride, px); + if (((unsigned long long)(uintptr_t)pixels) & (pxs - 1)) + fail ("Pixel data is not aligned to %u bytes!", pxs); + stride = width * pxs; if (pd->pixels.u8 && (pd->pixels.u8 != pixels)) _ector_software_buffer_base_pixels_clear(obj, pd); @@ -135,31 +104,30 @@ _ector_software_buffer_base_ector_buffer_pixels_set(Eo *obj, Ector_Software_Buff } else { - pd->pixels.u8 = calloc(stride * (height + t + b), 1); + pd->pixels.u8 = calloc(stride * height, 1); pd->nofree = EINA_FALSE; pd->writable = EINA_TRUE; } pd->generic->w = width; pd->generic->h = height; - pd->generic->l = l; - pd->generic->r = r; - pd->generic->t = t; - pd->generic->b = b; pd->generic->cspace = cspace; pd->stride = stride; - pd->pixel_size = px; + pd->pixel_size = pxs; return EINA_TRUE; + +on_fail: + return EINA_FALSE; } EOLIAN static void * _ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd, - unsigned int *length, Ector_Buffer_Access_Flag mode, - unsigned int x, unsigned int y, unsigned int w, unsigned int h, - Efl_Gfx_Colorspace cspace EINA_UNUSED, unsigned int *stride) + unsigned int *length, Ector_Buffer_Access_Flag mode, + unsigned int x, unsigned int y, unsigned int w, unsigned int h, + Efl_Gfx_Colorspace cspace EINA_UNUSED, unsigned int *stride) { Ector_Software_Buffer_Map *map = NULL; Eina_Bool need_cow = EINA_FALSE; - unsigned int off, k, dst_stride; + unsigned int off, k, dst_stride, pxs, pxs_dest; if (!w) w = pd->generic->w; if (!h) h = pd->generic->h; @@ -172,6 +140,14 @@ _ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software if ((mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) && !pd->writable) fail("Can not map a read-only buffer for writing"); + pxs = (pd->generic->cspace == EFL_GFX_COLORSPACE_ARGB8888) ? 4 : 1; + if (cspace == EFL_GFX_COLORSPACE_ARGB8888) + pxs_dest = 4; + else if (cspace == EFL_GFX_COLORSPACE_GRY8) + pxs_dest = 1; + else + fail("Unsupported colorspace: %u", cspace); + if ((mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) && (mode & ECTOR_BUFFER_ACCESS_FLAG_COW)) { @@ -186,20 +162,21 @@ _ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software map = calloc(1, sizeof(*map)); if (!map) fail("Out of memory"); + off = (pxs * x) + (pd->stride * y); + dst_stride = w * pxs_dest; + map->mode = mode; map->cspace = cspace; + map->stride = dst_stride; map->x = x; map->y = y; map->w = w; map->h = h; - off = _min_stride_calc(x + pd->generic->l, pd->generic->cspace) + (pd->stride * (y + pd->generic->t)); - dst_stride = _min_stride_calc(w, cspace); - if (cspace != pd->generic->cspace) { // convert on the fly - map->size = _min_stride_calc(w, cspace) * h; + map->size = w * h * pxs_dest; map->allocated = EINA_TRUE; map->ptr = malloc(map->size); if (!map->ptr) fail("Out of memory"); @@ -218,7 +195,7 @@ _ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software else if (need_cow) { // copy-on-write access - map->size = _min_stride_calc(w, cspace) * h; + map->size = w * h * pxs_dest; map->allocated = EINA_TRUE; map->ptr = malloc(map->size); if (!map->ptr) fail("Out of memory"); @@ -261,7 +238,7 @@ _ector_software_buffer_base_ector_buffer_unmap(Eo *obj EINA_UNUSED, Ector_Softwa { if (map->mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) { - unsigned k, dst_stride; + unsigned k; if (map->cspace != pd->generic->cspace) { @@ -282,12 +259,10 @@ _ector_software_buffer_base_ector_buffer_unmap(Eo *obj EINA_UNUSED, Ector_Softwa } else { - dst_stride = _min_stride_calc(map->w, map->cspace); for (k = 0; k < map->h; k++) { memcpy(pd->pixels.u8 + map->x + (k + map->y) * pd->stride, - map->ptr + k * dst_stride, - dst_stride); + map->ptr + k * map->stride, map->stride); } } } @@ -301,33 +276,14 @@ _ector_software_buffer_base_ector_buffer_unmap(Eo *obj EINA_UNUSED, Ector_Softwa CRI("Tried to unmap a non-mapped region!"); } -EOLIAN static uint8_t * -_ector_software_buffer_base_ector_buffer_span_get(Eo *obj, Ector_Software_Buffer_Base_Data *pd, - int x, int y, unsigned int w, Efl_Gfx_Colorspace cspace, - unsigned int *length) -{ - // ector_buffer_map - return _ector_software_buffer_base_ector_buffer_map - (obj, pd, length, ECTOR_BUFFER_ACCESS_FLAG_READ, x, y, w, 1, cspace, NULL); -} - -EOLIAN static void -_ector_software_buffer_base_ector_buffer_span_free(Eo *obj, Ector_Software_Buffer_Base_Data *pd, - uint8_t *data) -{ - // ector_buffer_unmap - return _ector_software_buffer_base_ector_buffer_unmap - (obj, pd, data, (unsigned int) -1); -} - EOLIAN static Ector_Buffer_Flag _ector_software_buffer_base_ector_buffer_flags_get(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd) { return ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_DRAWABLE | ECTOR_BUFFER_FLAG_CPU_READABLE_FAST | - ECTOR_BUFFER_FLAG_RENDERABLE | (pd->writable ? (ECTOR_BUFFER_FLAG_CPU_WRITABLE | + ECTOR_BUFFER_FLAG_RENDERABLE | ECTOR_BUFFER_FLAG_CPU_WRITABLE_FAST) : 0); } 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) implements { Ector.Buffer.flags { get; } Ector.Buffer.pixels_set; - Ector.Buffer.span_get; - Ector.Buffer.span_free; Ector.Buffer.map; Ector.Buffer.unmap; } 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 { Solid, LinearGradient, RadialGradient, - Image } Span_Data_Type; typedef struct _Span_Data @@ -114,7 +113,6 @@ void ector_software_rasterizer_transform_set(Software_Rasterizer *rasterizer, Ei void ector_software_rasterizer_color_set(Software_Rasterizer *rasterizer, int r, int g, int b, int a); void ector_software_rasterizer_linear_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *linear); void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *radial); -void ector_software_rasterizer_buffer_set(Software_Rasterizer *rasterizer, Ector_Software_Buffer *image); void ector_software_rasterizer_clip_rect_set(Software_Rasterizer *rasterizer, Eina_Array *clips); void ector_software_rasterizer_clip_shape_set(Software_Rasterizer *rasterizer, Shape_Rle_Data *clip); 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) } } -static void -_blend_image_argb(int count, const SW_FT_Span *spans, void *user_data) -{ - Span_Data *data = user_data; - RGBA_Comp_Func comp_func; - uint32_t *buffer, *target; - uint8_t *src8; - unsigned int l, length, sy = 0; - const int pix_stride = data->raster_buffer->stride / 4; - - /* FIXME: - * optimize eo call - * implement image scaling - * tile and repeat image properly - */ - - comp_func = efl_draw_func_span_get(data->op, data->mul_col, EINA_TRUE); - buffer = data->raster_buffer->pixels.u32 + ((pix_stride * data->offy) + data->offx); - - while (count--) - { - target = buffer + ((pix_stride * spans->y) + spans->x); - length = spans->len; - while (length) - { - l = MIN(length, data->buffer->generic->w); - src8 = ector_buffer_span_get(data->buffer->generic->eo, 0, sy, l, EFL_GFX_COLORSPACE_ARGB8888, NULL); - comp_func(target, (uint32_t *) src8, l, data->mul_col, spans->coverage); - ector_buffer_span_free(data->buffer->generic->eo, src8); - target += l; - length -= l; - } - ++spans; - ++sy; - if (sy >= data->buffer->generic->h) - sy = 0; - } -} - /*! \internal spans must be sorted on y @@ -318,9 +279,6 @@ _adjust_span_fill_methods(Span_Data *spdata) case RadialGradient: spdata->unclipped_blend = &_blend_gradient; break; - case Image: - spdata->unclipped_blend = &_blend_image_argb; - break; } // setup clipping @@ -568,13 +526,6 @@ void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasteriz rasterizer->fill_data.type = RadialGradient; } -void ector_software_rasterizer_buffer_set(Software_Rasterizer *rasterizer, - Ector_Software_Buffer *buffer) -{ - rasterizer->fill_data.buffer = efl_data_scope_get(buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN); - rasterizer->fill_data.type = Image; -} - void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer, int x, int y, uint32_t mul_col, 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 @@ static Ector_Renderer * _ector_software_surface_ector_surface_renderer_factory_new(Eo *obj, - Ector_Software_Surface_Data *pd EINA_UNUSED, - const Efl_Class *type) + Ector_Software_Surface_Data *pd EINA_UNUSED, + const Efl_Class *type) { if (type == ECTOR_RENDERER_SHAPE_MIXIN) 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, return efl_add(ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS, NULL, ector_renderer_surface_set(efl_added, obj)); else if (type == ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN) return efl_add(ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS, NULL, ector_renderer_surface_set(efl_added, obj)); - else if (type == ECTOR_RENDERER_BUFFER_MIXIN) - return efl_add(ECTOR_RENDERER_SOFTWARE_BUFFER_CLASS, NULL, ector_renderer_surface_set(efl_added, obj)); - ERR("Couldn't find class for type: %s\n", efl_class_name_get(type)); + + ERR("Couldn't find class for type: %s", efl_class_name_get(type)); return NULL; } @@ -49,8 +48,8 @@ _ector_software_surface_efl_object_destructor(Eo *obj, Ector_Software_Surface_Da static void _ector_software_surface_ector_surface_reference_point_set(Eo *obj EINA_UNUSED, - Ector_Software_Surface_Data *pd, - int x, int y) + Ector_Software_Surface_Data *pd, + int x, int y) { pd->x = x; 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 @@ static void _buffer_free(Evas_Filter_Buffer *fb); static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd); -static Ector_Buffer* _ector_buffer_create(Evas_Filter_Buffer const *fb, void *data); +static Evas_Filter_Buffer *_buffer_alloc_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only, Eina_Bool render, Eina_Bool draw); #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) #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) #define DRAW_FILL_SET(fmode) do { cmd->draw.fillmode = fmode; } while (0) -static inline void * -_evas_image_get(Ector_Buffer *buf) -{ - void *image = NULL; - if (!buf) return NULL; - /* FIXME: This MAY return RGBA_Image because engine_image_set MAY pass an - * RGBA_Image... Baaaaah */ - evas_ector_buffer_engine_image_get(buf, NULL, &image); - return image; -} - /* Main functions */ Evas_Filter_Context * evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async, void *user_data) { Evas_Filter_Context *ctx; + static int warned = 0; EINA_SAFETY_ON_NULL_RETURN_VAL(evas, NULL); 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 ctx->user_data = user_data; ctx->buffer_scaled_get = &evas_filter_buffer_scaled_get; + if (ENFN->gl_surface_read_pixels) + { + ctx->gl = EINA_TRUE; + if (!warned) + { + WRN("OpenGL support through SW functions, expect low performance!"); + warned = 1; + } + } + return ctx; } @@ -146,7 +146,7 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, } _filter_buffer_backing_free(fb); XDBG("Source #%d '%s' has dimensions %dx%d", fb->id, fb->source_name, fb->w, fb->h); - fb->buffer = ENFN->ector_buffer_wrap(ENDT, obj->layer->evas->evas, source->proxy->surface, EINA_FALSE); + fb->buffer = ENFN->ector_buffer_wrap(ENDT, obj->layer->evas->evas, source->proxy->surface); fb->alpha_only = EINA_FALSE; } } @@ -180,7 +180,8 @@ evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, } static Evas_Filter_Buffer * -_buffer_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only) +_buffer_empty_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only, + Eina_Bool transient) { Evas_Filter_Buffer *fb; @@ -190,7 +191,7 @@ _buffer_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only) fb->id = ++(ctx->last_buffer_id); fb->ctx = ctx; fb->alpha_only = alpha_only; - fb->transient = EINA_TRUE; + fb->transient = transient; fb->w = w; fb->h = h; @@ -199,26 +200,19 @@ _buffer_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only) } static Ector_Buffer * -_ector_buffer_create(Evas_Filter_Buffer const *fb, void *data) +_ector_buffer_create(Evas_Filter_Buffer const *fb, Eina_Bool render, Eina_Bool draw) { - Evas_Colorspace cspace; + Efl_Gfx_Colorspace cspace = EFL_GFX_COLORSPACE_ARGB8888; Ector_Buffer_Flag flags; - // FIXME: We still rely on evas image structs (scaling and target render) - // This should be fixed by implementing full support in ector - // Note: dropped support for cserve2, that was not needed anyway - + // FIXME: Once all filters are GL buffers need not be CPU accessible flags = ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_CPU_WRITABLE; - if (fb->id == EVAS_FILTER_BUFFER_INPUT_ID) - flags |= ECTOR_BUFFER_FLAG_RENDERABLE; - else if (fb->id == EVAS_FILTER_BUFFER_OUTPUT_ID) - flags |= ECTOR_BUFFER_FLAG_DRAWABLE; + if (render) flags |= ECTOR_BUFFER_FLAG_RENDERABLE; + if (draw) flags |= ECTOR_BUFFER_FLAG_DRAWABLE; + if (fb->alpha_only) cspace = EFL_GFX_COLORSPACE_GRY8; - cspace = fb->alpha_only ? EVAS_COLORSPACE_GRY8 : EVAS_COLORSPACE_ARGB8888; return fb->ENFN->ector_buffer_new(fb->ENDT, fb->ctx->evas->evas, - data, fb->w, fb->h, 0, - (Efl_Gfx_Colorspace )cspace, EINA_TRUE, - 0, 0, 0, 0, flags); + fb->w, fb->h, cspace, flags); } Eina_Bool @@ -276,7 +270,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx) if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) sh = h; - fb = evas_filter_buffer_alloc_new(ctx, sw, sh, in->alpha_only); + fb = _buffer_alloc_new(ctx, sw, sh, in->alpha_only, 1, 1); XDBG("Allocated temporary buffer #%d of size %ux%u %s", fb ? fb->id : -1, sw, sh, in->alpha_only ? "alpha" : "rgba"); if (!fb) goto alloc_fail; @@ -292,7 +286,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx) if (in->w) sw = in->w; if (in->h) sh = in->h; - fb = evas_filter_buffer_alloc_new(ctx, sw, sh, in->alpha_only); + fb = _buffer_alloc_new(ctx, sw, sh, in->alpha_only, 1, 1); XDBG("Allocated temporary buffer #%d of size %ux%u %s", fb ? fb->id : -1, sw, sh, in->alpha_only ? "alpha" : "rgba"); if (!fb) goto alloc_fail; @@ -309,6 +303,8 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx) EINA_LIST_FOREACH(ctx->buffers, li, fb) { + Eina_Bool render = EINA_FALSE, draw = EINA_FALSE; + if (fb->buffer || fb->source) continue; @@ -318,7 +314,11 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx) continue; } - fb->buffer = _ector_buffer_create(fb, NULL); + render |= (fb->id == EVAS_FILTER_BUFFER_INPUT_ID); + render |= fb->is_render; + draw |= (fb->id == EVAS_FILTER_BUFFER_OUTPUT_ID); + + fb->buffer = _ector_buffer_create(fb, render, draw); XDBG("Allocated buffer #%d of size %ux%u %s: %p", fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba", fb->buffer); if (!fb->buffer) goto alloc_fail; @@ -338,64 +338,16 @@ evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only) EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); - fb = _buffer_new(ctx, 0, 0, alpha_only); + fb = _buffer_empty_new(ctx, 0, 0, alpha_only, EINA_FALSE); if (!fb) return -1; - fb->transient = EINA_FALSE; - XDBG("Created context buffer %d %s", fb->id, alpha_only ? "alpha" : "rgba"); return fb->id; } -Eina_Bool -_filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data, - int w, int h, Eina_Bool alpha_only) -{ - Evas_Filter_Buffer *fb; - - EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); - - fb = _filter_buffer_get(ctx, bufid); - if (!fb) return EINA_FALSE; - - _filter_buffer_backing_free(fb); - if (w <= 0 || h <= 0) - return EINA_FALSE; - - EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->buffer == NULL, EINA_FALSE); - // TODO: Check input parameters? - fb->alpha_only = alpha_only; - fb->w = w; - fb->h = h; - - fb->buffer = _ector_buffer_create(fb, data); - return (fb->buffer != NULL); -} - -static int -_filter_buffer_new_from_evas_surface(Evas_Filter_Context *ctx, void *image) -{ - Evas_Filter_Buffer *fb; - - EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); - - fb = calloc(1, sizeof(Evas_Filter_Buffer)); - if (!fb) return -1; - - fb->id = ++(ctx->last_buffer_id); - fb->ctx = ctx; - fb->buffer = ENFN->ector_buffer_wrap(ENDT, ctx->evas->evas, image, EINA_FALSE); - ENFN->image_size_get(ENDT, image, &fb->w, &fb->h); - fb->alpha_only = (ENFN->image_colorspace_get(ENDT, image) - == EVAS_COLORSPACE_GRY8); - - ctx->buffers = eina_list_append(ctx->buffers, fb); - return fb->id; -} - -Evas_Filter_Buffer * -_filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h, - Eina_Bool alpha_only) +static Evas_Filter_Buffer * +_buffer_alloc_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only, + Eina_Bool render, Eina_Bool draw) { Evas_Filter_Buffer *fb; @@ -407,15 +359,18 @@ _filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h, fb->id = ++(ctx->last_buffer_id); fb->ctx = ctx; - ctx->buffers = eina_list_append(ctx->buffers, fb); - - if (!_filter_buffer_data_set(ctx, fb->id, data, w, h, alpha_only)) + fb->w = w; + fb->h = h; + fb->alpha_only = alpha_only; + fb->buffer = _ector_buffer_create(fb, render, draw); + if (!fb->buffer) { - ctx->buffers = eina_list_remove(ctx->buffers, fb); + ERR("Failed to create ector buffer!"); free(fb); return NULL; } + ctx->buffers = eina_list_append(ctx->buffers, fb); return fb; } @@ -440,17 +395,6 @@ _filter_buffer_get(Evas_Filter_Context *ctx, int bufid) return NULL; } -void * -evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid) -{ - Evas_Filter_Buffer *fb; - - fb = _filter_buffer_get(ctx, bufid); - if (!fb) return NULL; - - return _evas_image_get(fb->buffer); -} - void * evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid) { @@ -459,7 +403,7 @@ evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid) fb = _filter_buffer_get(ctx, bufid); if (!fb) return NULL; - return fb->ENFN->image_ref(fb->ENDT, _evas_image_get(fb->buffer)); + return evas_ector_buffer_drawable_image_get(fb->buffer, EINA_TRUE); } Eina_Bool @@ -468,10 +412,7 @@ evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, { if (!stolen_buffer) return EINA_FALSE; EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); - -#ifdef DEBUG EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_main_loop_is(), EINA_FALSE); -#endif ENFN->image_free(ENDT, stolen_buffer); return EINA_TRUE; @@ -511,19 +452,6 @@ _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd) free(cmd); } -Evas_Filter_Command * -_evas_filter_command_get(Evas_Filter_Context *ctx, int cmdid) -{ - Evas_Filter_Command *cmd; - - if (cmdid <= 0) return NULL; - - EINA_INLIST_FOREACH(ctx->commands, cmd) - if (cmd->id == cmdid) return cmd; - - return NULL; -} - Evas_Filter_Buffer * evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only) @@ -535,8 +463,7 @@ evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, { if (buf->transient && !buf->locked && (buf->alpha_only == alpha_only)) { - if ((!w || (w == buf->w)) - && (!h || (h == buf->h))) + if ((!w || (w == buf->w)) && (!h || (h == buf->h))) { buf->locked = EINA_TRUE; return buf; @@ -544,14 +471,15 @@ evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, } } - if (ctx->running) // && ctx->async) + if (ctx->running) { - ERR("Can not create a new buffer from this thread!"); + ERR("Can not create a new buffer while filter is running!"); return NULL; } - buf = _buffer_new(ctx, w, h, alpha_only); + buf = _buffer_empty_new(ctx, w, h, alpha_only, EINA_TRUE); buf->locked = EINA_TRUE; + return buf; } @@ -565,7 +493,7 @@ _filter_buffer_unlock_all(Evas_Filter_Context *ctx) buf->locked = EINA_FALSE; } -int +Evas_Filter_Command * evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, int bufid) { @@ -573,18 +501,18 @@ evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, Evas_Filter_Buffer *buf = NULL; int R, G, B, A, cx, cy, cw, ch; - EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); - EINA_SAFETY_ON_NULL_RETURN_VAL(draw_context, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(draw_context, NULL); buf = _filter_buffer_get(ctx, bufid); if (!buf) { ERR("Buffer %d does not exist.", bufid); - return -1; + return NULL; } cmd = _command_new(ctx, EVAS_FILTER_MODE_FILL, buf, NULL, buf); - if (!cmd) return -1; + if (!cmd) return NULL; ENFN->context_color_get(ENDT, draw_context, &R, &G, &B, &A); DRAW_COLOR_SET(R, G, B, A); @@ -592,25 +520,26 @@ evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, ENFN->context_clip_get(ENDT, draw_context, &cx, &cy, &cw, &ch); DRAW_CLIP_SET(cx, cy, cw, ch); + XDBG("Add fill %d with color(%d,%d,%d,%d)", buf->id, R, G, B, A); + buf->dirty = EINA_TRUE; - return cmd->id; + return cmd; } -int +Evas_Filter_Command * evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx, int inbuf, int outbuf, Evas_Filter_Blur_Type type, int dx, int dy, int ox, int oy, int count) { - Evas_Filter_Command *cmd = NULL; Evas_Filter_Buffer *in = NULL, *out = NULL, *tmp = NULL, *in_dy = NULL; Evas_Filter_Buffer *out_dy = NULL, *out_dx = NULL; Evas_Filter_Buffer *copybuf = NULL, *blur_out = NULL; Eina_Bool copy_back = EINA_FALSE, blend = EINA_FALSE; + Evas_Filter_Command *cmd = NULL; int R, G, B, A; DATA32 color; - int ret = 0, id; - EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); - EINA_SAFETY_ON_NULL_RETURN_VAL(drawctx, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(drawctx, NULL); if (dx < 0) dx = 0; if (dy < 0) dy = 0; @@ -621,18 +550,10 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx, } in = _filter_buffer_get(ctx, inbuf); - if (!in) - { - ERR("Buffer %d does not exist [input].", inbuf); - goto fail; - } + EINA_SAFETY_ON_FALSE_GOTO(in, fail); out = _filter_buffer_get(ctx, outbuf); - if (!out) - { - ERR("Buffer %d does not exist [output].", outbuf); - goto fail; - } + EINA_SAFETY_ON_FALSE_GOTO(out, fail); if (!in->alpha_only && out->alpha_only) DBG("Different color formats, implicit conversion may be slow"); @@ -676,7 +597,6 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx, int tmp_ox = ox; int tmp_oy = oy; - id = -1; if (dx && dy) { 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, if (dx <= 2) type = EVAS_FILTER_BLUR_GAUSSIAN; else - type = EVAS_FILTER_BLUR_BOX; + type = EVAS_FILTER_BLUR_BOX; if (dy && (color != 0xFFFFFFFF)) ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255); - id = evas_filter_command_blur_add(ctx, drawctx, inbuf, tmp_out, - type, dx, 0, tmp_ox, tmp_oy, 0); - if (id < 0) goto fail; - cmd = _evas_filter_command_get(ctx, id); + cmd = evas_filter_command_blur_add(ctx, drawctx, inbuf, tmp_out, + type, dx, 0, tmp_ox, tmp_oy, 0); + if (!cmd) goto fail; cmd->blur.auto_count = EINA_TRUE; if (dy && (color != 0xFFFFFFFF)) 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, else type = EVAS_FILTER_BLUR_BOX; - id = evas_filter_command_blur_add(ctx, drawctx, tmp_in, outbuf, - type, 0, dy, ox, oy, 0); - if (id < 0) goto fail; - cmd = _evas_filter_command_get(ctx, id); + cmd = evas_filter_command_blur_add(ctx, drawctx, tmp_in, outbuf, + type, 0, dy, ox, oy, 0); + if (!cmd) goto fail; cmd->blur.auto_count = EINA_TRUE; } - return id; + return cmd; } break; @@ -818,7 +736,6 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx, cmd->blur.count = count; if (!dy && !blend) DRAW_COLOR_SET(R, G, B, A); - ret = cmd->id; } if (dy) @@ -832,45 +749,47 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx, cmd->blur.count = count; if (!blend) DRAW_COLOR_SET(R, G, B, A); - if (ret <= 0) ret = cmd->id; } if (copy_back) { + Evas_Filter_Command *copycmd; int render_op; if (!cmd) goto fail; XDBG("Add copy %d -> %d", copybuf->id, blur_out->id); - cmd->ENFN->context_color_set(cmd->ENDT, drawctx, 255, 255, 255, 255); - render_op = cmd->ENFN->context_render_op_get(cmd->ENDT, drawctx); - cmd->ENFN->context_render_op_set(cmd->ENDT, drawctx, EVAS_RENDER_COPY); - id = evas_filter_command_blend_add(ctx, drawctx, copybuf->id, blur_out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE); - cmd->ENFN->context_color_set(cmd->ENDT, drawctx, R, G, B, A); - cmd->ENFN->context_render_op_set(cmd->ENDT, drawctx, render_op); - if (id < 0) goto fail; + ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255); + render_op = ENFN->context_render_op_get(ENDT, drawctx); + ENFN->context_render_op_set(ENDT, drawctx, EVAS_RENDER_COPY); + copycmd = evas_filter_command_blend_add(ctx, drawctx, copybuf->id, blur_out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE); + ENFN->context_color_set(ENDT, drawctx, R, G, B, A); + ENFN->context_render_op_set(ENDT, drawctx, render_op); + if (!copycmd) goto fail; ox = oy = 0; } if (blend) { + Evas_Filter_Command *blendcmd; + XDBG("Add blend %d (%s) -> %d (%s)", blur_out->id, blur_out->alpha_only ? "Alpha" : "RGBA", out->id, out->alpha_only ? "Alpha" : "RGBA"); - id = evas_filter_command_blend_add(ctx, drawctx, blur_out->id, out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE); - if (id < 0) goto fail; + blendcmd = evas_filter_command_blend_add(ctx, drawctx, blur_out->id, out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE); + if (!blendcmd) goto fail; } out->dirty = EINA_TRUE; _filter_buffer_unlock_all(ctx); - return ret; + return cmd; fail: ERR("Failed to add blur"); _filter_buffer_unlock_all(ctx); - return -1; + return NULL; } -int +Evas_Filter_Command * evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx, int inbuf, int outbuf, int ox, int oy, Evas_Filter_Fill_Mode fillmode) @@ -879,30 +798,30 @@ evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx, Evas_Filter_Buffer *in, *out; int R, G, B, A; - EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); if (inbuf == outbuf) { XDBG("Skipping NOP blend operation %d --> %d", inbuf, outbuf); - return -1; + return NULL; } in = _filter_buffer_get(ctx, inbuf); if (!in) { ERR("Buffer %d does not exist [input].", inbuf); - return -1; + return NULL; } out = _filter_buffer_get(ctx, outbuf); if (!out) { ERR("Buffer %d does not exist [output].", outbuf); - return -1; + return NULL; } cmd = _command_new(ctx, EVAS_FILTER_MODE_BLEND, in, NULL, out); - if (!cmd) return -1; + if (!cmd) return NULL; ENFN->context_color_get(ENDT, drawctx, &R, &G, &B, &A); DRAW_COLOR_SET(R, G, B, A); @@ -915,24 +834,26 @@ evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx, &cmd->draw.clip.x, &cmd->draw.clip.y, &cmd->draw.clip.w, &cmd->draw.clip.h); + XDBG("Add blend %d -> %d", in->id, out->id); if (cmd->draw.clip_use) XDBG("Draw clip: %d,%d,%d,%d", cmd->draw.clip.x, cmd->draw.clip.y, cmd->draw.clip.w, cmd->draw.clip.h); out->dirty = EINA_TRUE; - return cmd->id; + return cmd; } -int +Evas_Filter_Command * evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int radius, Eina_Bool smooth) { - int blurcmd, threshcmd, blendcmd, tmin = 0, growbuf; + Evas_Filter_Command *blurcmd, *threshcmd, *blendcmd; + Evas_Filter_Buffer *tmp = NULL, *in, *out; int diam = abs(radius) * 2 + 1; DATA8 curve[256] = {0}; - Evas_Filter_Buffer *tmp = NULL, *in, *out; + int tmin = 0, growbuf; - EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); if (!radius) { @@ -941,12 +862,12 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, } in = _filter_buffer_get(ctx, inbuf); - EINA_SAFETY_ON_NULL_RETURN_VAL(in, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL); if (inbuf != outbuf) { tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only); - EINA_SAFETY_ON_NULL_RETURN_VAL(tmp, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(tmp, NULL); growbuf = tmp->id; } else @@ -955,7 +876,7 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, blurcmd = evas_filter_command_blur_add(ctx, draw_context, inbuf, growbuf, EVAS_FILTER_BLUR_DEFAULT, abs(radius), abs(radius), 0, 0, 0); - if (blurcmd < 0) return -1; + if (!blurcmd) return NULL; if (diam > 255) diam = 255; if (radius > 0) @@ -981,21 +902,21 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, } out = _filter_buffer_get(ctx, growbuf); - if (!out) return -1; + if (!out) return NULL; out->dirty = EINA_TRUE; if (growbuf != outbuf) { out = _filter_buffer_get(ctx, growbuf); - if (!out) return -1; + if (!out) return NULL; out->dirty = EINA_TRUE; } threshcmd = evas_filter_command_curve_add(ctx, draw_context, growbuf, growbuf, curve, EVAS_FILTER_CHANNEL_ALPHA); - if (threshcmd < 0) + if (!threshcmd) { - _command_del(ctx, _evas_filter_command_get(ctx, blurcmd)); - return -1; + _command_del(ctx, blurcmd); + return NULL; } if (tmp) @@ -1003,18 +924,18 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, blendcmd = evas_filter_command_blend_add(ctx, draw_context, tmp->id, outbuf, 0, 0, EVAS_FILTER_FILL_MODE_NONE); - if (blendcmd < 0) + if (!blendcmd) { - _command_del(ctx, _evas_filter_command_get(ctx, threshcmd)); - _command_del(ctx, _evas_filter_command_get(ctx, blurcmd)); - return -1; + _command_del(ctx, threshcmd); + _command_del(ctx, blurcmd); + return NULL; } } return blurcmd; } -int +Evas_Filter_Command * evas_filter_command_curve_add(Evas_Filter_Context *ctx, void *draw_context EINA_UNUSED, int inbuf, int outbuf, DATA8 *curve, @@ -1024,30 +945,28 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx, Evas_Filter_Buffer *in, *out; DATA8 *copy; - EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); - EINA_SAFETY_ON_NULL_RETURN_VAL(curve, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(curve, NULL); in = _filter_buffer_get(ctx, inbuf); out = _filter_buffer_get(ctx, outbuf); - if (!in || !out) - { - ERR("Invalid buffer id: input %d [%p], output %d [%p]", - inbuf, in, outbuf, out); - return -1; - } + EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL); if (in->alpha_only != out->alpha_only) WRN("Incompatible formats for color curves, implicit conversion will be " "slow and may not produce the desired output."); + XDBG("Add curve %d -> %d", in->id, out->id); + copy = malloc(256 * sizeof(DATA8)); - if (!copy) return -1; + if (!copy) return NULL; cmd = _command_new(ctx, EVAS_FILTER_MODE_CURVE, in, NULL, out); if (!cmd) { free(copy); - return -1; + return NULL; } memcpy(copy, curve, 256 * sizeof(DATA8)); @@ -1055,10 +974,10 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx, cmd->curve.channel = channel; out->dirty = EINA_TRUE; - return cmd->id; + return cmd; } -int +Evas_Filter_Command * evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx, void *draw_context EINA_UNUSED, int inbuf, int outbuf, int dispbuf, @@ -1066,22 +985,18 @@ evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx, int intensity, Evas_Filter_Fill_Mode fillmode) { - Evas_Filter_Command *cmd; Evas_Filter_Buffer *in, *out, *map, *tmp = NULL, *disp_out; - int cmdid = -1; + Evas_Filter_Command *cmd = NULL; - EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); - EINA_SAFETY_ON_FALSE_RETURN_VAL(intensity >= 0, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(intensity >= 0, NULL); in = _filter_buffer_get(ctx, inbuf); out = _filter_buffer_get(ctx, outbuf); map = _filter_buffer_get(ctx, dispbuf); - if (!in || !out || !map) - { - ERR("Invalid buffer id: input %d [%p], output %d [%p], map %d [%p]", - inbuf, in, outbuf, out, dispbuf, map); - return -1; - } + EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(map, NULL); if (in->alpha_only != out->alpha_only) DBG("Different color formats, implicit conversion may be slow"); @@ -1095,39 +1010,41 @@ evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx, if (in == out) { tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only); - if (!tmp) return -1; + if (!tmp) return NULL; disp_out = tmp; } else disp_out = out; cmd = _command_new(ctx, EVAS_FILTER_MODE_DISPLACE, in, map, disp_out); - if (!cmd) goto end; + if (!cmd) goto fail; DRAW_FILL_SET(fillmode); cmd->displacement.flags = flags & EVAS_FILTER_DISPLACE_BITMASK; cmd->displacement.intensity = intensity; cmd->draw.rop = _evas_to_gfx_render_op(ENFN->context_render_op_get(ENDT, draw_context)); - cmdid = cmd->id; if (tmp) { - if (evas_filter_command_blend_add(ctx, draw_context, disp_out->id, - out->id, 0, 0, - EVAS_FILTER_FILL_MODE_NONE) < 0) - { - _command_del(ctx, _evas_filter_command_get(ctx, cmdid)); - cmdid = -1; - } + Evas_Filter_Command *fillcmd; + + fillcmd = evas_filter_command_blend_add(ctx, draw_context, disp_out->id, + out->id, 0, 0, + EVAS_FILTER_FILL_MODE_NONE); + if (!fillcmd) goto fail; } out->dirty = EINA_TRUE; -end: _filter_buffer_unlock_all(ctx); - return cmdid; + return cmd; + +fail: + _filter_buffer_unlock_all(ctx); + _command_del(ctx, cmd); + return NULL; } -int +Evas_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) @@ -1135,10 +1052,9 @@ evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context, Evas_Filter_Command *cmd; Evas_Filter_Buffer *in, *out, *mask; Efl_Gfx_Render_Op render_op; - int cmdid = -1; int R, G, B, A; - EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); render_op = _evas_to_gfx_render_op(ENFN->context_render_op_get(ENDT, draw_context)); 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, in = _filter_buffer_get(ctx, inbuf); out = _filter_buffer_get(ctx, outbuf); mask = _filter_buffer_get(ctx, maskbuf); - if (!in || !out || !mask) - { - ERR("Invalid buffer id: input %d [%p], output %d [%p], mask %d [%p]", - inbuf, in, outbuf, out, maskbuf, mask); - return -1; - } + EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(mask, NULL); cmd = _command_new(ctx, EVAS_FILTER_MODE_MASK, in, mask, out); - if (!cmd) goto end; + if (!cmd) return NULL; cmd->draw.rop = render_op; DRAW_COLOR_SET(R, G, B, A); DRAW_FILL_SET(fillmode); - - cmdid = cmd->id; out->dirty = EINA_TRUE; -end: - _filter_buffer_unlock_all(ctx); - return cmdid; + return cmd; } -int +Evas_Filter_Command * evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, void *draw_context EINA_UNUSED, int inbuf, int bumpbuf, int outbuf, @@ -1179,22 +1088,18 @@ evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, Evas_Filter_Fill_Mode fillmode) { Evas_Filter_Command *cmd; - Evas_Filter_Buffer *in, *out, *bumpmap; - int cmdid = -1; + Evas_Filter_Buffer *in, *out, *map; - EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); in = _filter_buffer_get(ctx, inbuf); out = _filter_buffer_get(ctx, outbuf); - bumpmap = _filter_buffer_get(ctx, bumpbuf); - if (!in || !out || !bumpmap) - { - ERR("Invalid buffer id: input %d [%p], output %d [%p], bumpmap %d [%p]", - inbuf, in, outbuf, out, bumpbuf, bumpmap); - return -1; - } + map = _filter_buffer_get(ctx, bumpbuf); + EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(map, NULL); - if (!bumpmap->alpha_only) + if (!map->alpha_only) DBG("Bump map is not an Alpha buffer, implicit conversion may be slow"); // FIXME: Boo! @@ -1202,11 +1107,11 @@ evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, WRN("RGBA bump map support is not implemented! This will trigger conversion."); // FIXME: Must ensure in != out - if (in == out) CRI("Not acceptable"); - if (bumpmap == out) CRI("Not acceptable"); + EINA_SAFETY_ON_FALSE_RETURN_VAL(in != out, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(map != out, NULL); - cmd = _command_new(ctx, EVAS_FILTER_MODE_BUMP, in, bumpmap, out); - if (!cmd) goto end; + cmd = _command_new(ctx, EVAS_FILTER_MODE_BUMP, in, map, out); + if (!cmd) return NULL; DRAW_FILL_SET(fillmode); cmd->bump.xyangle = xyangle; @@ -1217,16 +1122,12 @@ evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, cmd->bump.white = white; cmd->bump.elevation = elevation; cmd->bump.compensate = !!(flags & EVAS_FILTER_BUMP_COMPENSATE); - cmdid = cmd->id; - out->dirty = EINA_TRUE; -end: - _filter_buffer_unlock_all(ctx); - return cmdid; + return cmd; } -int +Evas_Filter_Command * evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context EINA_UNUSED, int inbuf, int outbuf, @@ -1236,19 +1137,15 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd; Evas_Filter_Buffer *in, *out; - EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); in = _filter_buffer_get(ctx, inbuf); out = _filter_buffer_get(ctx, outbuf); - if (!in || !out) - { - ERR("Invalid buffer id: input %d [%p], output %d [%p]", - inbuf, in, outbuf, out); - return -1; - } + EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL); cmd = _command_new(ctx, EVAS_FILTER_MODE_TRANSFORM, in, NULL, out); - if (!cmd) return -1; + if (!cmd) return NULL; DRAW_COLOR_SET(255, 255, 255, 255); cmd->transform.flags = flags; @@ -1265,7 +1162,7 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx, out->dirty = EINA_TRUE; - return cmd->id; + return cmd; } /* Final target */ @@ -1277,7 +1174,7 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); - ctx->target.bufid = _filter_buffer_new_from_evas_surface(ctx, surface); + ctx->target.surface = ENFN->image_ref(ENDT, surface); ctx->target.x = x; ctx->target.y = y; ctx->target.clip_use = ENFN->context_clip_get @@ -1303,21 +1200,19 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, static Eina_Bool _filter_target_render(Evas_Filter_Context *ctx) { - Evas_Filter_Buffer *src, *dst; - void *drawctx, *image = NULL, *surface = NULL; + Evas_Filter_Buffer *src; + void *drawctx, *image = NULL, *surface; - EINA_SAFETY_ON_FALSE_RETURN_VAL(ctx->target.bufid, EINA_FALSE); - - src = _filter_buffer_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID); - dst = _filter_buffer_get(ctx, ctx->target.bufid); - EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx->target.surface, EINA_FALSE); drawctx = ENFN->context_new(ENDT); - image = _evas_image_get(src->buffer); - surface = _evas_image_get(dst->buffer); - EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE); + surface = ctx->target.surface; + + src = _filter_buffer_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID); + EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); + + image = evas_ector_buffer_drawable_image_get(src->buffer, EINA_FALSE); + EINA_SAFETY_ON_NULL_GOTO(image, fail); // FIXME: Use ector buffer RENDERER here @@ -1348,7 +1243,19 @@ _filter_target_render(Evas_Filter_Context *ctx) EINA_TRUE, EINA_FALSE); ENFN->context_free(ENDT, drawctx); + evas_ector_buffer_engine_image_release(src->buffer, image); + + ENFN->image_free(ENDT, surface); + ctx->target.surface = NULL; + return EINA_TRUE; + +fail: + ENFN->image_free(ENDT, surface); + ctx->target.surface = NULL; + + ERR("Failed to render filter to target canvas!"); + return EINA_FALSE; } @@ -1365,8 +1272,8 @@ evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, fb = _filter_buffer_get(ctx, bufid); EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); - surface = _evas_image_get(fb->buffer); - if (!surface) return EINA_FALSE; + surface = evas_ector_buffer_render_image_get(fb->buffer, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE); // Copied from evas_font_draw_async_check 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, evas_unref_queue_glyph_put(ctx->evas, text_props->glyphs); } + evas_ector_buffer_engine_image_release(fb->buffer, surface); return EINA_TRUE; } @@ -1389,13 +1297,17 @@ evas_filter_image_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, { int dw = 0, dh = 0, w = 0, h = 0; Eina_Bool async_unref; + Evas_Filter_Buffer *fb; void *surface; ENFN->image_size_get(ENDT, image, &w, &h); if (!w || !h) return EINA_FALSE; - surface = evas_filter_buffer_backing_get(ctx, bufid); - if (!surface) return EINA_FALSE; + fb = _filter_buffer_get(ctx, bufid); + if (!fb) return EINA_FALSE; + + surface = evas_ector_buffer_render_image_get(fb->buffer, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE); ENFN->image_size_get(ENDT, image, &dw, &dh); if (!dw || !dh) return EINA_FALSE; @@ -1410,6 +1322,7 @@ evas_filter_image_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, evas_unref_queue_image_put(ctx->evas, image); } + evas_ector_buffer_engine_image_release(fb->buffer, surface); return EINA_TRUE; } @@ -1571,7 +1484,6 @@ _filter_thread_run_cb(void *data) Eina_Bool evas_filter_run(Evas_Filter_Context *ctx) { - static int warned = 0; Eina_Bool ret; EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); @@ -1579,12 +1491,6 @@ evas_filter_run(Evas_Filter_Context *ctx) if (!ctx->commands) return EINA_TRUE; - if (ENFN->gl_surface_read_pixels && !warned) - { - WRN("OpenGL support through SW functions, expect low performance!"); - warned = 1; - } - if (ctx->async) { 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 @@ #define EVAS_FILTER_MODE_BUFFER (EVAS_FILTER_MODE_LAST+2) #define INSTR_PARAM_CHECK(a) do { if (!(a)) { \ - ERR("Argument %s can not be nil in %s!", #a, instr->name); return -1; } \ + ERR("Argument %s can not be nil in %s!", #a, instr->name); return NULL; } \ } while (0) /* Note on the documentation: @@ -913,8 +913,8 @@ _blend_padding_update(Evas_Filter_Program *pgm EINA_UNUSED, src = _instruction_param_getbuf(instr, "src", NULL); dst = _instruction_param_getbuf(instr, "dst", NULL); - INSTR_PARAM_CHECK(src); - INSTR_PARAM_CHECK(dst); + EINA_SAFETY_ON_NULL_RETURN_VAL(src, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0); fillmode = _fill_mode_get(instr); 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, src = _instruction_param_getbuf(instr, "src", NULL); dst = _instruction_param_getbuf(instr, "dst", NULL); - INSTR_PARAM_CHECK(src); - INSTR_PARAM_CHECK(dst); + EINA_SAFETY_ON_NULL_RETURN_VAL(src, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0); if (typestr && !strcasecmp(typestr, "box")) type = EVAS_FILTER_BLUR_BOX; @@ -1405,8 +1405,8 @@ _displace_padding_update(Evas_Filter_Program *pgm EINA_UNUSED, intensity = _instruction_param_geti(instr, "intensity", NULL); src = _instruction_param_getbuf(instr, "src", NULL); dst = _instruction_param_getbuf(instr, "dst", NULL); - INSTR_PARAM_CHECK(src); - INSTR_PARAM_CHECK(dst); + EINA_SAFETY_ON_NULL_RETURN_VAL(src, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0); l = intensity + src->pad.l; r = intensity + src->pad.r; @@ -1552,8 +1552,8 @@ _grow_padding_update(Evas_Filter_Program *pgm EINA_UNUSED, radius = _instruction_param_geti(instr, "radius", NULL); src = _instruction_param_getbuf(instr, "src", NULL); dst = _instruction_param_getbuf(instr, "dst", NULL); - INSTR_PARAM_CHECK(src); - INSTR_PARAM_CHECK(dst); + EINA_SAFETY_ON_NULL_RETURN_VAL(src, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0); if (radius < 0) radius = 0; @@ -1684,7 +1684,7 @@ _transform_padding_update(Evas_Filter_Program *pgm EINA_UNUSED, ox = 0; oy = _instruction_param_geti(instr, "oy", NULL); dst = _instruction_param_getbuf(instr, "dst", NULL); - INSTR_PARAM_CHECK(dst); + EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0); if (ox < 0) l = (-ox) * 2; else r = ox * 2; @@ -3018,15 +3018,16 @@ _fill_mode_get(Evas_Filter_Instruction *instr) return EVAS_FILTER_FILL_MODE_NONE; } -static int +static Evas_Filter_Command * _instr2cmd_blend(Evas_Filter_Context *ctx, Evas_Filter_Instruction *instr, void *dc) { Eina_Bool isset = EINA_FALSE; + Evas_Filter_Command *cmd; DATA32 color; Buffer *src, *dst; Evas_Filter_Fill_Mode fillmode; - int cmdid, ox, oy, A, R, G, B; + int ox, oy, A, R, G, B; ox = _instruction_param_geti(instr, "ox", NULL); oy = _instruction_param_geti(instr, "oy", NULL); @@ -3038,24 +3039,23 @@ _instr2cmd_blend(Evas_Filter_Context *ctx, INSTR_PARAM_CHECK(dst); if (isset) SETCOLOR(color); - cmdid = evas_filter_command_blend_add(ctx, dc, src->cid, dst->cid, ox, oy, - fillmode); + cmd = evas_filter_command_blend_add(ctx, dc, src->cid, dst->cid, ox, oy, fillmode); if (isset) RESETCOLOR(); - if (cmdid < 0) return cmdid; - return cmdid; + return cmd; } -static int +static Evas_Filter_Command * _instr2cmd_blur(Evas_Filter_Context *ctx, Evas_Filter_Instruction *instr, void *dc) { Eina_Bool colorset = EINA_FALSE, yset = EINA_FALSE, cntset = EINA_FALSE; Evas_Filter_Blur_Type type = EVAS_FILTER_BLUR_DEFAULT; + Evas_Filter_Command *cmd; const char *typestr; DATA32 color; Buffer *src, *dst; - int cmdid, ox, oy, rx, ry, A, R, G, B, count; + int ox, oy, rx, ry, A, R, G, B, count; ox = _instruction_param_geti(instr, "ox", NULL); oy = _instruction_param_geti(instr, "oy", NULL); @@ -3098,14 +3098,14 @@ _instr2cmd_blur(Evas_Filter_Context *ctx, if (!yset) ry = rx; if (colorset) SETCOLOR(color); - cmdid = evas_filter_command_blur_add(ctx, dc, src->cid, dst->cid, type, - rx, ry, ox, oy, count); + cmd = evas_filter_command_blur_add(ctx, dc, src->cid, dst->cid, type, + rx, ry, ox, oy, count); if (colorset) RESETCOLOR(); - return cmdid; + return cmd; } -static int +static Evas_Filter_Command * _instr2cmd_bump(Evas_Filter_Context *ctx, Evas_Filter_Instruction *instr, void *dc) { @@ -3114,7 +3114,7 @@ _instr2cmd_bump(Evas_Filter_Context *ctx, DATA32 color, black, white; Buffer *src, *dst, *map; double azimuth, elevation, depth, specular; - int cmdid, compensate; + int compensate; color = _instruction_param_getc(instr, "color", NULL); white = _instruction_param_getc(instr, "white", NULL); @@ -3134,15 +3134,13 @@ _instr2cmd_bump(Evas_Filter_Context *ctx, INSTR_PARAM_CHECK(dst); INSTR_PARAM_CHECK(map); - cmdid = evas_filter_command_bump_map_add(ctx, dc, src->cid, map->cid, dst->cid, - azimuth, elevation, depth, specular, - black, color, white, flags, - fillmode); - - return cmdid; + return evas_filter_command_bump_map_add(ctx, dc, src->cid, map->cid, dst->cid, + azimuth, elevation, depth, specular, + black, color, white, flags, + fillmode); } -static int +static Evas_Filter_Command * _instr2cmd_displace(Evas_Filter_Context *ctx, Evas_Filter_Instruction *instr, void *dc) { @@ -3151,7 +3149,7 @@ _instr2cmd_displace(Evas_Filter_Context *ctx, EVAS_FILTER_DISPLACE_STRETCH | EVAS_FILTER_DISPLACE_LINEAR; const char *flagsstr; Buffer *src, *dst, *map; - int cmdid, intensity; + int intensity; Eina_Bool isset = EINA_FALSE; src = _instruction_param_getbuf(instr, "src", NULL); @@ -3176,23 +3174,19 @@ _instr2cmd_displace(Evas_Filter_Context *ctx, else if (isset) WRN("Invalid flags '%s' in displace operation. Using default instead", flagsstr); - cmdid = evas_filter_command_displacement_map_add(ctx, dc, src->cid, dst->cid, - map->cid, flags, intensity, - fillmode); - - return cmdid; + return evas_filter_command_displacement_map_add(ctx, dc, src->cid, dst->cid, + map->cid, flags, intensity, + fillmode); } -static int +static Evas_Filter_Command * _instr2cmd_fill(Evas_Filter_Context *ctx, Evas_Filter_Instruction *instr, void *dc) { Buffer *dst; int R, G, B, A, l, r, t, b; Evas_Filter_Command *cmd; - Eina_Inlist *il; DATA32 color; - int cmdid; dst = _instruction_param_getbuf(instr, "dst", NULL); color = _instruction_param_getc(instr, "color", NULL); @@ -3203,31 +3197,27 @@ _instr2cmd_fill(Evas_Filter_Context *ctx, INSTR_PARAM_CHECK(dst); SETCOLOR(color); - cmdid = evas_filter_command_fill_add(ctx, dc, dst->cid); + cmd = evas_filter_command_fill_add(ctx, dc, dst->cid); RESETCOLOR(); + if (!cmd) return NULL; - if (cmdid < 0) return -1; - il = eina_inlist_last(ctx->commands); - if (!il) return -1; - - cmd = EINA_INLIST_CONTAINER_GET(il, Evas_Filter_Command); cmd->draw.clip.l = l; cmd->draw.clip.r = r; cmd->draw.clip.t = t; cmd->draw.clip.b = b; cmd->draw.clip_mode_lrtb = EINA_TRUE; - return cmdid; + return cmd; } -static int +static Evas_Filter_Command * _instr2cmd_grow(Evas_Filter_Context *ctx, Evas_Filter_Instruction *instr, void *dc) { Evas_Filter_Command *cmd; Buffer *src, *dst; Eina_Bool smooth; - int cmdid, radius; + int radius; src = _instruction_param_getbuf(instr, "src", NULL); dst = _instruction_param_getbuf(instr, "dst", NULL); @@ -3236,23 +3226,21 @@ _instr2cmd_grow(Evas_Filter_Context *ctx, INSTR_PARAM_CHECK(src); INSTR_PARAM_CHECK(dst); - cmdid = evas_filter_command_grow_add(ctx, dc, src->cid, dst->cid, - radius, smooth); - - cmd = _evas_filter_command_get(ctx, cmdid); + cmd = evas_filter_command_grow_add(ctx, dc, src->cid, dst->cid, radius, smooth); if (cmd) cmd->draw.need_temp_buffer = EINA_TRUE; - return cmdid; + return cmd; } -static int +static Evas_Filter_Command * _instr2cmd_mask(Evas_Filter_Context *ctx, Evas_Filter_Instruction *instr, void *dc) { Evas_Filter_Fill_Mode fillmode; + Evas_Filter_Command *cmd; Buffer *src, *dst, *mask; DATA32 color; - int R, G, B, A, cmdid; + int R, G, B, A; src = _instruction_param_getbuf(instr, "src", NULL); dst = _instruction_param_getbuf(instr, "dst", NULL); @@ -3264,22 +3252,17 @@ _instr2cmd_mask(Evas_Filter_Context *ctx, INSTR_PARAM_CHECK(mask); SETCOLOR(color); - cmdid = evas_filter_command_mask_add(ctx, dc, src->cid, mask->cid, dst->cid, fillmode); + cmd = evas_filter_command_mask_add(ctx, dc, src->cid, mask->cid, dst->cid, fillmode); RESETCOLOR(); - if (cmdid < 0) return cmdid; + if (!cmd) return NULL; - if (!src->alpha && !mask->alpha && !dst->alpha) - { - Evas_Filter_Command *cmd; + if (!src->alpha && !mask->alpha && !dst->alpha && !ctx->gl) + cmd->draw.need_temp_buffer = EINA_TRUE; - cmd = _evas_filter_command_get(ctx, cmdid); - cmd->draw.need_temp_buffer = EINA_TRUE; - } - - return cmdid; + return cmd; } -static int +static Evas_Filter_Command * _instr2cmd_curve(Evas_Filter_Context *ctx, Evas_Filter_Instruction *instr, void *dc) { @@ -3289,7 +3272,6 @@ _instr2cmd_curve(Evas_Filter_Context *ctx, Buffer *src, *dst; DATA8 values[256]; int *points; - int cmdid; src = _instruction_param_getbuf(instr, "src", NULL); dst = _instruction_param_getbuf(instr, "dst", NULL); @@ -3328,12 +3310,10 @@ _instr2cmd_curve(Evas_Filter_Context *ctx, values[x] = x; } - cmdid = evas_filter_command_curve_add(ctx, dc, src->cid, dst->cid, values, channel); - - return cmdid; + return evas_filter_command_curve_add(ctx, dc, src->cid, dst->cid, values, channel); } -static int +static Evas_Filter_Command * _instr2cmd_transform(Evas_Filter_Context *ctx, Evas_Filter_Instruction *instr, void *dc) { @@ -3355,17 +3335,18 @@ _instr2cmd_transform(Evas_Filter_Context *ctx, else { ERR("Invalid transform '%s'", op); - return -1; + return NULL; } return evas_filter_command_transform_add(ctx, dc, src->cid, dst->cid, flags, ox, oy); } -static int +static Eina_Bool _command_from_instruction(Evas_Filter_Context *ctx, Evas_Filter_Instruction *instr, void *dc) { - int (* instr2cmd) (Evas_Filter_Context *, Evas_Filter_Instruction *, void *); + Evas_Filter_Command * (* instr2cmd) (Evas_Filter_Context *, Evas_Filter_Instruction *, void *); + Evas_Filter_Command *cmd; switch (instr->type) { @@ -3401,10 +3382,19 @@ _command_from_instruction(Evas_Filter_Context *ctx, return EINA_TRUE; default: CRI("Invalid instruction type: %d", instr->type); - return -1; + return EINA_FALSE; } - return instr2cmd(ctx, instr, dc); + cmd = instr2cmd(ctx, instr, dc); + if (!cmd) return EINA_FALSE; + + if (cmd->output && ctx->gl) + { + if (ENFN->gfx_filter_supports(ENDT, cmd) == EVAS_FILTER_SUPPORT_GL) + cmd->output->is_render = EINA_TRUE; + } + + return EINA_TRUE; } #ifdef FILTERS_DEBUG @@ -3477,7 +3467,6 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Instruction *instr; Eina_Bool success = EINA_FALSE; void *dc = NULL; - int cmdid; EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE); @@ -3518,8 +3507,7 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx, EINA_INLIST_FOREACH(pgm->instructions, instr) { _instruction_dump(instr); - cmdid = _command_from_instruction(ctx, instr, dc); - if (cmdid <= 0) + if (!_command_from_instruction(ctx, instr, dc)) goto end; } 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 @@ extern int _evas_filter_log_dom; #define EVAS_FILTER_LOG_COLOR EINA_COLOR_LIGHTBLUE -#ifdef DEBUG +//#ifdef DEBUG # define FILTERS_DEBUG -#endif +//#endif #ifdef ERR # undef ERR @@ -136,7 +136,7 @@ struct _Evas_Filter_Context struct { - int bufid; + void *surface; int x, y; int cx, cy, cw, ch; // clip int r, g, b, a; // clip color @@ -150,6 +150,7 @@ struct _Evas_Filter_Context Eina_Bool async : 1; Eina_Bool running : 1; Eina_Bool has_proxies : 1; + Eina_Bool gl : 1; }; struct _Evas_Filter_Command @@ -242,6 +243,7 @@ struct _Evas_Filter_Buffer Eina_Bool locked : 1; // internal flag Eina_Bool delete_me : 1; // request delete asap (after released by client) Eina_Bool dirty : 1; // Marked as dirty as soon as a command writes to it + Eina_Bool is_render : 1; // Is render target of a filter using engine functions (ie. needs FBO in GL) }; enum _Evas_Filter_Interpolation_Mode @@ -264,13 +266,9 @@ void evas_filter_context_source_set(Evas_Filter_Context *ctx void _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); Eina_Bool evas_filter_buffer_alloc(Evas_Filter_Buffer *fb, int w, int h); Evas_Filter_Buffer *_filter_buffer_get(Evas_Filter_Context *ctx, int bufid); -Eina_Bool _filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data, int w, int h, Eina_Bool alpha_only); -Evas_Filter_Buffer *_filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h, Eina_Bool alpha_only); -#define evas_filter_buffer_alloc_new(ctx, w, h, a) _filter_buffer_data_new(ctx, NULL, w, h, a) Evas_Filter_Buffer *evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only); Evas_Filter_Buffer *evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx, Evas_Filter_Buffer *src, unsigned w, unsigned h); Eina_Bool evas_filter_interpolate(DATA8* output /* 256 values */, int *points /* 256 values */, Evas_Filter_Interpolation_Mode mode); -Evas_Filter_Command *_evas_filter_command_get(Evas_Filter_Context *ctx, int cmdid); int evas_filter_smallest_pow2_larger_than(int val); void 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 @@ -/* Note: only for internal C API */ - import evas_canvas; interface Evas.Ector.Buffer { - [[Evas ector buffer interface]] + [[Binding layer between ector buffers and evas images. + + Subclasses implement support for RGBA_Image for SW & GL, + and Evas_GL_Image for GL. + + Note: Internal class, not API stable. + ]] methods { - @property engine_image { - [[Engine image property]] - get {} - set { [[This Buffer will hold a reference to the evas image struct.]] } - values { - evas: Evas.Canvas; [[The current Evas.]] - image: void_ptr; [[The engine-specific image struct.]] + engine_image_set { + [[Attach this ector buffer to an existing engine image.]] + params { + @in evas: Evas.Canvas; [[The current Evas.]] + @in image: void_ptr; [[The RGBA_Image or Evas_GL_Image.]] } } + drawable_image_get { + [[Fetch an engine image from this ector buffer as a drawable.]] + params { + @in update: bool; [[$true to update the data to the remote image.]] + } + return: void_ptr; [[The engine image (RGBA_Image or Evas_GL_Image).]] + } + render_image_get { + [[Fetch an engine image from this ector buffer as a render target.]] + params { + @in update: bool; [[$true to update the data to the remote image.]] + } + return: void_ptr; [[The engine image (RGBA_Image or Evas_GL_Image).]] + } + engine_image_release { + [[Release an image from @.drawable_image_get or @.render_image_get.]] + params { + @in image: void_ptr; [[Return value of @.drawable_image_get or @.render_image_get.]] + } + return: bool; [[$false in case of error.]] + } } } 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 Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx); int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only); -void *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid); void *evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid); Eina_Bool evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer); @@ -171,7 +170,7 @@ void _evas_filter_source_hash_free_cb(void *data); * @return Filter command ID or -1 in case of error * @internal */ -int 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); +Evas_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); /** * @brief Apply a blur effect on a buffer @@ -188,7 +187,7 @@ int evas_filter_command_blend_add(Evas_Filter_Context *ctx, * @return Filter command ID or -1 in case of error * @internal */ -int 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); +Evas_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); /** * @brief Fill a buffer with the current color @@ -199,7 +198,7 @@ int evas_filter_command_blur_add(Evas_Filter_Context *ctx, * @note The current draw context's render operation is ignored (always uses COPY mode). * @internal */ -int evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, int buf); +Evas_Filter_Command *evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, int buf); /** * @brief evas_filter_command_curve_add @@ -212,7 +211,7 @@ int evas_filter_command_fill_add(Evas_Filter_Context *ctx, * @return Filter command ID or -1 in case of error * @internal */ -int evas_filter_command_curve_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, DATA8 *curve /* 256 elements */, Evas_Filter_Channel channel); +Evas_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); /** * @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, * @return Filter command ID or -1 in case of error * @internal */ -int evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int radius, Eina_Bool smooth); +Evas_Filter_Command *evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int radius, Eina_Bool smooth); /** * @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, * @return Filter command ID or -1 in case of error * @internal */ -int 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); +Evas_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); /** * @brief Apply a texture to a buffer @@ -254,7 +253,7 @@ int evas_filter_command_displacement_map_add(Evas_Filter_Co * @note For the moment, inbuf can only be ALPHA, and output must be RGBA if mask is RGBA as well * @internal */ -int evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int maskbuf, int outbuf, Evas_Filter_Fill_Mode fillmode); +Evas_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); /** * @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, * @return Filter command ID or -1 in case of error * @internal */ -int 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); +Evas_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); /** * @brief Apply a geometrical transformation to the buffer @@ -289,7 +288,7 @@ int evas_filter_command_bump_map_add(Evas_Filter_Context *c * @return Filter command ID or -1 in case of error * @internal */ -int 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); +Evas_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); /* Simple binding between a filter object and its sources */ struct _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 Ector_Surface *(*ector_create) (void *data); void (*ector_destroy) (void *data, Ector_Surface *surface); - Ector_Buffer *(*ector_buffer_wrap) (void *data, Evas *e, void *engine_image, Eina_Bool is_rgba_image); - 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); + Ector_Buffer *(*ector_buffer_wrap) (void *data, Evas *e, void *engine_image); + Ector_Buffer *(*ector_buffer_new) (void *data, Evas *e, int width, int height, Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags); void (*ector_begin) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, int x, int y, Eina_Bool do_async); void (*ector_renderer_draw) (void *data, void *context, void *surface, void *engine_data, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async); 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, void evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im); void 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); void 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); +Evas_GL_Image *evas_gl_common_image_surface_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im); void *evas_gl_font_texture_new(void *gc, RGBA_Font_Glyph *fg); void 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 * } */ + if (error) *error = EVAS_LOAD_ERROR_NONE; + // FIXME: keep unreffed shared images around EINA_LIST_FOREACH(gc->shared->images, l, im) { @@ -1039,6 +1041,65 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im) } } +Evas_GL_Image * +evas_gl_common_image_surface_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im) +{ + Evas_GL_Image *glim = NULL; + Eina_Bool alpha; + int w, h; + + if (!gc || !im || !im->im || !im->im->image.data) + goto fail; + + if (im->im->cache_entry.space == EFL_GFX_COLORSPACE_ARGB8888) + alpha = EINA_FALSE; + else if (im->im->cache_entry.space == EFL_GFX_COLORSPACE_GRY8) + alpha = EINA_TRUE; + else goto fail; + + w = im->im->cache_entry.w; + h = im->im->cache_entry.h; + glim = evas_gl_common_image_surface_new(gc, w, h, EINA_TRUE, EINA_FALSE); + if (!glim) goto fail; + + if (alpha) + { + RGBA_Image *image; + uint32_t *rgba; + uint8_t *gry8; + int k; + + image = evas_common_image_new(w, h, EINA_TRUE); + if (!image) goto fail; + + rgba = image->image.data; + gry8 = im->im->image.data8; + for (k = 0; k < (w * h); k++) + { + const int c = *gry8++; + *rgba++ = ARGB_JOIN(c, c, c, c); + } + + glim->im = image; + } + else + { + evas_cache_image_ref(&im->im->cache_entry); + glim->im = im->im; + } + + glim->dirty = EINA_TRUE; + evas_gl_common_image_update(gc, glim); + evas_gl_common_image_free(im); + + return glim; + +fail: + ERR("Failed to update surface pixels!"); + if (glim) evas_gl_common_image_free(glim); + return NULL; +} + void 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 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 { { MATCH_FALSE, MATCH_FALSE, EVAS_COLORSPACE_ARGB8888, &rgb_ifmt, &rgb_fmt }, #endif { MATCH_FALSE, MATCH_ANY, EVAS_COLORSPACE_GRY8, &lum_fmt, &lum_ifmt }, + { MATCH_TRUE, MATCH_ANY, EVAS_COLORSPACE_GRY8, &alpha_fmt, &alpha_ifmt }, { MATCH_TRUE, MATCH_ANY, EVAS_COLORSPACE_AGRY88, &lum_alpha_fmt, &lum_alpha_ifmt }, // ETC1/2 support { 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 @@ # include "config.h" #endif +#define ECTOR_GL_BUFFER_BASE_PROTECTED + +#include "evas_common_private.h" +#include "evas_gl_private.h" + #include #include "gl/ector_gl_private.h" #include "evas_common_private.h" +#include "../gl_common/evas_gl_common.h" +#include "evas_private.h" #include "ector_buffer.h" +#include "Evas_Engine_GL_Generic.h" + #include "evas_ector_buffer.eo.h" #include "evas_ector_gl_buffer.eo.h" #define MY_CLASS EVAS_ECTOR_GL_BUFFER_CLASS +typedef struct _Ector_GL_Buffer_Map Ector_GL_Buffer_Map; +typedef struct _Evas_Ector_GL_Buffer_Data Evas_Ector_GL_Buffer_Data; + +struct _Ector_GL_Buffer_Map +{ + EINA_INLIST; + void *ptr; + unsigned int base_size; // in bytes + unsigned int x, y, w, h; + void *image_data, *base_data; + size_t length; + Efl_Gfx_Colorspace cspace; + Evas_GL_Image *im; + Eina_Bool allocated; + Ector_Buffer_Access_Flag mode; +}; + +struct _Evas_Ector_GL_Buffer_Data +{ + Evas_Public_Data *evas; + Evas_GL_Image *glim; + Eina_Bool alpha_only; + Ector_GL_Buffer_Map *maps; +}; + +#define ENFN pd->evas->engine.func +#define ENDT pd->evas->engine.data.output + +// testing out some macros to maybe add to eina +#define EINA_INLIST_REMOVE(l,i) do { l = (__typeof__(l)) eina_inlist_remove(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0) +#define EINA_INLIST_APPEND(l,i) do { l = (__typeof__(l)) eina_inlist_append(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0) +#define EINA_INLIST_PREPEND(l,i) do { l = (__typeof__(l)) eina_inlist_prepend(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0) + +#define fail(fmt, ...) do { ERR(fmt, ##__VA_ARGS__); goto on_fail; } while (0) + +/* FIXME: Conversion routines don't belong here */ +static inline void +_pixels_argb_to_gry8_convert(uint8_t *dst, const uint32_t *src, int len) +{ + int k; + for (k = 0; k < len; k++) + { + const uint32_t *s = src++; + *dst++ = A_VAL(s); + } +} + +static inline void +_pixels_gry8_to_argb_convert(uint32_t *dst, const uint8_t *src, int len) +{ + int k; + for (k = 0; k < len; k++) + { + const uint8_t s = *src++; + *dst++ = ARGB_JOIN(s, s, s, s); + } +} + +static inline Eina_Bool +_evas_gl_image_is_fbo(Evas_GL_Image *glim) +{ + return glim && glim->tex && glim->tex->pt && glim->tex->pt->fb; +} + +EOLIAN static void +_evas_ector_gl_buffer_gl_buffer_prepare(Eo *obj, Evas_Ector_GL_Buffer_Data *pd, + Evas_Canvas *eo_evas, + int w, int h, Efl_Gfx_Colorspace cspace, + Ector_Buffer_Flag flags EINA_UNUSED) +{ + Render_Engine_GL_Generic *re; + Evas_Engine_GL_Context *gc; + Evas_GL_Image *im; + + // this is meant to be called only once + EINA_SAFETY_ON_FALSE_GOTO(!pd->evas, on_fail); + EINA_SAFETY_ON_FALSE_GOTO(!efl_finalized_get(obj), on_fail); + + if (cspace == EFL_GFX_COLORSPACE_ARGB8888) + pd->alpha_only = EINA_FALSE; + else if (cspace == EFL_GFX_COLORSPACE_GRY8) + pd->alpha_only = EINA_TRUE; + else + fail("Unsupported colorspace: %u", cspace); + + pd->evas = efl_data_xref(eo_evas, EVAS_CANVAS_CLASS, obj); + re = pd->evas->engine.data.output; + gc = re->window_gl_context_get(re->software.ob); + + im = evas_gl_common_image_surface_new(gc, w, h, EINA_TRUE, EINA_FALSE); + if (!im) fail("Failed to create GL surface!"); + + pd->glim = im; + return; + +on_fail: + if (pd->glim) evas_gl_common_image_free(pd->glim); + pd->glim = NULL; +} + +EOLIAN static void * +_evas_ector_gl_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED, + Evas_Ector_GL_Buffer_Data *pd, + Eina_Bool update) +{ + Render_Engine_GL_Generic *re = pd->evas->engine.data.output; + Evas_Engine_GL_Context *gc; + + if (pd->maps != NULL) + fail("Image is currently mapped!"); + + evas_gl_common_image_ref(pd->glim); + if (!update) return pd->glim; + + gc = re->window_gl_context_get(re->software.ob); + evas_gl_common_image_update(gc, pd->glim); + + return pd->glim; + +on_fail: + return NULL; +} + +EOLIAN static void * +_evas_ector_gl_buffer_evas_ector_buffer_render_image_get(Eo *obj EINA_UNUSED, + Evas_Ector_GL_Buffer_Data *pd, + Eina_Bool update) +{ + Render_Engine_GL_Generic *re = pd->evas->engine.data.output; + Evas_Engine_GL_Context *gc; + + if (pd->maps != NULL) + fail("Image is currently mapped!"); + + evas_gl_common_image_ref(pd->glim); + if (!update) return pd->glim; + + gc = re->window_gl_context_get(re->software.ob); + evas_gl_common_image_update(gc, pd->glim); + + return pd->glim; + +on_fail: + return NULL; +} + +EOLIAN static Eina_Bool +_evas_ector_gl_buffer_evas_ector_buffer_engine_image_release(Eo *obj EINA_UNUSED, + Evas_Ector_GL_Buffer_Data *pd, + void *image) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->glim == image, EINA_FALSE); + + evas_gl_common_image_free(pd->glim); + + return EINA_TRUE; +} + +EOLIAN static void +_evas_ector_gl_buffer_ector_buffer_size_get(Eo *obj EINA_UNUSED, + Evas_Ector_GL_Buffer_Data *pd, + int *w, int *h) +{ + if (w) *w = pd->glim->w; + if (h) *h = pd->glim->h; +} + +EOLIAN static Efl_Gfx_Colorspace +_evas_ector_gl_buffer_ector_buffer_cspace_get(Eo *obj EINA_UNUSED, + Evas_Ector_GL_Buffer_Data *pd) +{ + if (pd->alpha_only) + return EFL_GFX_COLORSPACE_GRY8; + else + return EFL_GFX_COLORSPACE_ARGB8888; +} + +EOLIAN static Ector_Buffer_Flag +_evas_ector_gl_buffer_ector_buffer_flags_get(Eo *obj EINA_UNUSED, + Evas_Ector_GL_Buffer_Data *pd EINA_UNUSED) +{ + return ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_DRAWABLE | + ECTOR_BUFFER_FLAG_CPU_WRITABLE | ECTOR_BUFFER_FLAG_RENDERABLE; +} + +EOLIAN static void * +_evas_ector_gl_buffer_ector_buffer_map(Eo *obj EINA_UNUSED, Evas_Ector_GL_Buffer_Data *pd, + unsigned int *length, + Ector_Buffer_Access_Flag mode, + unsigned int x, unsigned int y, unsigned int w, unsigned int h, + Efl_Gfx_Colorspace cspace, unsigned int *stride) +{ + Eina_Bool write = !!(mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE); + Ector_GL_Buffer_Map *map = NULL; + Eina_Bool tofree = EINA_FALSE; + Evas_GL_Image *im = NULL; + unsigned int W, H; + int len, err; + uint32_t *data; + int pxs; + + W = pd->glim->w; + H = pd->glim->h; + if (!w) w = W - x; + if (!h) h = H - y; + if ((x + w > W) || (y + h > H)) return NULL; + + if (write && _evas_gl_image_is_fbo(pd->glim)) + { + // Can not open FBO data to write! + im = ENFN->image_data_get(ENDT, pd->glim, EINA_FALSE, &data, &err, &tofree); + if (!im) return NULL; + } + else + { + im = ENFN->image_data_get(ENDT, pd->glim, write, &data, &err, &tofree); + if (!im) return NULL; + } + + map = calloc(1, sizeof(*map)); + map->mode = mode; + map->cspace = cspace; + map->x = x; + map->y = y; + map->w = w; + map->h = h; + map->image_data = data; + map->im = tofree ? im : NULL; + + len = W * H; + if (cspace == EFL_GFX_COLORSPACE_GRY8) + { + uint8_t *data8 = malloc(len); + + if (!data8) goto on_fail; + _pixels_argb_to_gry8_convert(data8, data, len); + map->allocated = EINA_TRUE; + map->base_data = data8; + map->ptr = data8 + x + (y * W); + pxs = 1; + } + else + { + map->allocated = EINA_FALSE; + map->base_data = data; + map->ptr = data + x + (y * W); + pxs = 4; + } + + map->base_size = len * pxs; + map->length = (W * h + w - W) * pxs; + if (stride) *stride = W * pxs; + if (length) *length = map->length; + + EINA_INLIST_PREPEND(pd->maps, map);; + return map->ptr; + +on_fail: + free(map); + return NULL; +} + +EOLIAN static void +_evas_ector_gl_buffer_ector_buffer_unmap(Eo *obj EINA_UNUSED, Evas_Ector_GL_Buffer_Data *pd, + void *data, unsigned int length) +{ + Ector_GL_Buffer_Map *map; + if (!data) return; + + EINA_INLIST_FOREACH(pd->maps, map) + { + if ((map->ptr == data) && (map->length == length)) + { + EINA_INLIST_REMOVE(pd->maps, map); + if (map->mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) + { + Render_Engine_GL_Generic *re = pd->evas->engine.data.output; + Evas_GL_Image *old_glim = pd->glim; + Evas_Engine_GL_Context *gc; + int W, H; + + W = pd->glim->w; + H = pd->glim->h; + gc = re->window_gl_context_get(re->software.ob); + + if (map->cspace == EFL_GFX_COLORSPACE_GRY8) + _pixels_gry8_to_argb_convert(map->image_data, map->base_data, W * H); + + if (map->im) + { + pd->glim = evas_gl_common_image_surface_update(gc, map->im); + evas_gl_common_image_free(old_glim); + } + else + { + pd->glim = evas_gl_common_image_surface_update(gc, old_glim); + } + } + else + { + if (map->im) + ENFN->image_free(ENDT, map->im); + else + ENFN->image_data_put(ENDT, pd->glim, map->image_data); + } + if (map->allocated) + free(map->base_data); + free(map); + return; + } + } + + ERR("Tried to unmap a non-mapped region!"); +} + +EOLIAN static Efl_Object * +_evas_ector_gl_buffer_efl_object_finalize(Eo *obj, Evas_Ector_GL_Buffer_Data *pd) +{ + if (!pd->glim) + { + ERR("Buffer was not initialized properly!"); + return NULL; + } + return efl_finalize(efl_super(obj, MY_CLASS)); +} + +EOLIAN static void +_evas_ector_gl_buffer_efl_object_destructor(Eo *obj, Evas_Ector_GL_Buffer_Data *pd) +{ + evas_gl_common_image_free(pd->glim); + efl_data_xunref(pd->evas->evas, pd->evas, obj); + efl_destructor(efl_super(obj, MY_CLASS)); +} + #include "evas_ector_gl_buffer.eo.c" diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.eo b/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.eo index 417ee53136..6c6bdc03b9 100644 --- a/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.eo +++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.eo @@ -1,5 +1,35 @@ -class Evas.Ector.GL.Buffer (Efl.Object, Evas.Ector.Buffer, Ector.GL.Buffer.Base) +class Evas.Ector.GL.Buffer (Efl.Object, Evas.Ector.Buffer, Ector.GL.Buffer) { - [[Evas ector GL buffer class]] - data: null; + [[An Ector GL buffer capable of being mapped, drawn and rendered to. + + Potentially very inefficient (may rely on glReadPixels). + ]] + methods { + gl_buffer_prepare { + [[Set the main properties to create a gl buffer.]] + params { + evas: Evas.Canvas; [[The current canvas]] + w: int; [[Width]] + h: int; [[Height]] + cspace: Efl.Gfx.Colorspace; [[Alpha or RGBA]] + flags: Ector.Buffer.Flag; [[Required buffer capabilities + (map/draw/render, etc...)]] + } + } + } + constructors { + .gl_buffer_prepare; + } + implements { + Efl.Object.finalize; + Efl.Object.destructor; + Evas.Ector.Buffer.drawable_image_get; + Evas.Ector.Buffer.render_image_get; + Evas.Ector.Buffer.engine_image_release; + Ector.Buffer.size { get; } + Ector.Buffer.cspace { get; } + Ector.Buffer.flags { get; } + Ector.Buffer.map; + Ector.Buffer.unmap; + } } diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c b/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c index 4625071d8c..647f7cc7df 100644 --- a/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c +++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c @@ -2,14 +2,20 @@ # include "config.h" #endif +/* this one is read-only buffer wrapping an existing evas_gl_image */ + #define ECTOR_GL_BUFFER_BASE_PROTECTED +#include "evas_common_private.h" +#include "evas_gl_private.h" + #include #include "gl/ector_gl_private.h" #include "evas_common_private.h" #include "../gl_common/evas_gl_common.h" #include "evas_private.h" #include "ector_buffer.h" +#include "Evas_Engine_GL_Generic.h" #include "evas_ector_buffer.eo.h" #include "evas_ector_gl_buffer.eo.h" @@ -17,30 +23,36 @@ #define MY_CLASS EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS -typedef struct _Ector_GL_Buffer_Map +typedef struct _Ector_GL_Buffer_Map Ector_GL_Buffer_Map; +typedef struct _Evas_Ector_GL_Image_Buffer_Data Evas_Ector_GL_Image_Buffer_Data; + +struct _Ector_GL_Buffer_Map { EINA_INLIST; void *ptr; - unsigned int size; // in bytes + unsigned int base_size; // in bytes unsigned int x, y, w, h; + void *image_data, *base_data; + size_t length; Efl_Gfx_Colorspace cspace; Evas_GL_Image *im; - Eina_Bool allocated; + Eina_Bool allocated, free_image; Ector_Buffer_Access_Flag mode; -} Ector_GL_Buffer_Map; +}; -typedef struct +struct _Evas_Ector_GL_Image_Buffer_Data { - Ector_GL_Buffer_Base_Data *base; - Evas *evas; - Evas_GL_Image *image; - struct { - Eina_Inlist *maps; // Ector_GL_Buffer_Map - } internal; -} Evas_Ector_GL_Image_Buffer_Data; + Evas_Public_Data *evas; + Evas_GL_Image *glim; + Ector_GL_Buffer_Map *maps; +}; -#define ENFN e->engine.func -#define ENDT e->engine.data.output +#define ENFN pd->evas->engine.func +#define ENDT pd->evas->engine.data.output + +// testing out some macros to maybe add to eina +#define EINA_INLIST_REMOVE(l,i) do { l = (__typeof__(l)) eina_inlist_remove(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0) +#define EINA_INLIST_APPEND(l,i) do { l = (__typeof__(l)) eina_inlist_append(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0) /* FIXME: Conversion routines don't belong here */ static inline void @@ -58,92 +70,99 @@ EOLIAN static void _evas_ector_gl_image_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd, Evas *evas, void *image) { - Evas_Public_Data *e = efl_data_scope_get(evas, EVAS_CANVAS_CLASS); Evas_GL_Image *im = image; - int l = 0, r = 0, t = 0, b = 0; - if (pd->base->generic->immutable) - { - CRI("Can't set image after finalize"); - return; - } - - pd->evas = efl_xref(evas, obj); + EINA_SAFETY_ON_FALSE_RETURN(!pd->glim); EINA_SAFETY_ON_NULL_RETURN(im); - if (im->tex && im->tex->pt) - { - if (im->im) - { - l = im->im->cache_entry.borders.l; - r = im->im->cache_entry.borders.r; - t = im->im->cache_entry.borders.t; - b = im->im->cache_entry.borders.b; - } - else - { - // always 1 pixel border, except FBO - if (!im->tex->pt->fb) - l = r = t = b = 1; - } - - pd->image = ENFN->image_ref(ENDT, im); - ector_gl_buffer_base_attach(obj, im->tex->pt->texture, im->tex->pt->fb, (Efl_Gfx_Colorspace) evas_gl_common_gl_format_to_colorspace(im->tex->pt->format), im->tex->w, im->tex->h, im->tex->x, im->tex->y, im->tex->pt->w, im->tex->pt->h, l, r, t, b); - } - else - { - // FIXME: This might be required to support texture upload here - ERR("Image has no attached texture! Unsupported!"); - pd->image = NULL; - } + pd->evas = efl_data_xref(evas, EVAS_CANVAS_CLASS, obj); + evas_gl_common_image_ref(im); + pd->glim = im; } -EOLIAN static void -_evas_ector_gl_image_buffer_evas_ector_buffer_engine_image_get(Eo *obj EINA_UNUSED, - Evas_Ector_GL_Image_Buffer_Data *pd, - Evas **evas, void **image) +EOLIAN static void * +_evas_ector_gl_image_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED, + Evas_Ector_GL_Image_Buffer_Data *pd, + Eina_Bool update EINA_UNUSED) { - if (evas) *evas = pd->evas; - if (image) *image = pd->image; + evas_gl_common_image_ref(pd->glim); + return pd->glim; +} + +EOLIAN static Eina_Bool +_evas_ector_gl_image_buffer_evas_ector_buffer_engine_image_release(Eo *obj EINA_UNUSED, + Evas_Ector_GL_Image_Buffer_Data *pd, + void *image) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->glim == image, EINA_FALSE); + + evas_gl_common_image_free(pd->glim); + return EINA_TRUE; } EOLIAN static Ector_Buffer_Flag _evas_ector_gl_image_buffer_ector_buffer_flags_get(Eo *obj EINA_UNUSED, - Evas_Ector_GL_Image_Buffer_Data *pd) + Evas_Ector_GL_Image_Buffer_Data *pd EINA_UNUSED) { - Ector_Buffer_Flag flags; + return ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_DRAWABLE; +} - if (!pd->image) return 0; +EOLIAN static void +_evas_ector_gl_image_buffer_ector_buffer_size_get(Eo *obj EINA_UNUSED, + Evas_Ector_GL_Image_Buffer_Data *pd, + int *w, int *h) +{ + if (w) *w = pd->glim->w; + if (h) *h = pd->glim->h; +} - flags = ECTOR_BUFFER_FLAG_CPU_READABLE; - if (pd->image->tex) - { - flags |= ECTOR_BUFFER_FLAG_DRAWABLE; - if (pd->image->tex->pt->fb) - flags |= ECTOR_BUFFER_FLAG_RENDERABLE; - } - if (pd->image->im) - flags |= ECTOR_BUFFER_FLAG_CPU_WRITABLE; - - return flags; +EOLIAN static Efl_Gfx_Colorspace +_evas_ector_gl_image_buffer_ector_buffer_cspace_get(Eo *obj EINA_UNUSED, + Evas_Ector_GL_Image_Buffer_Data *pd EINA_UNUSED) +{ + return EFL_GFX_COLORSPACE_ARGB8888; } EOLIAN static void * _evas_ector_gl_image_buffer_ector_buffer_map(Eo *obj EINA_UNUSED, Evas_Ector_GL_Image_Buffer_Data *pd, unsigned int *length, - Ector_Buffer_Access_Flag mode, - unsigned int x, unsigned int y, unsigned int w, unsigned int h, - Efl_Gfx_Colorspace cspace, unsigned int *stride) + Ector_Buffer_Access_Flag mode, + unsigned int x, unsigned int y, unsigned int w, unsigned int h, + Efl_Gfx_Colorspace cspace, unsigned int *stride) { - Evas_Public_Data *e = efl_data_scope_get(pd->evas, EVAS_CANVAS_CLASS); Ector_GL_Buffer_Map *map = NULL; Eina_Bool tofree = EINA_FALSE; - Evas_GL_Image *im; - uint32_t *data; + Evas_GL_Image *im = NULL; + unsigned int W, H; int len, err; + uint32_t *data; + int pxs; - im = ENFN->image_data_get(ENDT, pd->image, - mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE, - &data, &err, &tofree); + if ((cspace != EFL_GFX_COLORSPACE_GRY8) && (cspace != EFL_GFX_COLORSPACE_ARGB8888)) + { + ERR("Unsupported colorspace for map: %d", (int) cspace); + return NULL; + } + + if (mode == EFL_GFX_BUFFER_ACCESS_MODE_NONE) + { + ERR("Invalid access mode for map (none)"); + return NULL; + } + + if (mode & EFL_GFX_BUFFER_ACCESS_MODE_WRITE) + { + ERR("%s does not support write access for map", efl_class_name_get(MY_CLASS)); + return NULL; + } + + W = pd->glim->w; + H = pd->glim->h; + if (!w) w = W - x; + if (!h) h = H - y; + if ((x + w > W) || (y + h > H)) return NULL; + + im = ENFN->image_data_get(ENDT, pd->glim, EINA_FALSE, &data, &err, &tofree); if (!im) return NULL; map = calloc(1, sizeof(*map)); @@ -153,111 +172,89 @@ _evas_ector_gl_image_buffer_ector_buffer_map(Eo *obj EINA_UNUSED, Evas_Ector_GL_ map->y = y; map->w = w; map->h = h; - map->ptr = data; + map->image_data = data; + map->im = im; + map->free_image = tofree; - if (tofree) - map->im = im; - else - map->im = NULL; - - len = w * h; + len = W * H; if (cspace == EFL_GFX_COLORSPACE_GRY8) { uint8_t *data8 = malloc(len); + + if (!data8) goto fail; _pixels_argb_to_gry8_convert(data8, data, len); map->allocated = EINA_TRUE; - map->ptr = data8; - map->size = len; - if (stride) *stride = w; + map->base_data = data8; + map->ptr = data8 + x + (y * W); + pxs = 1; } else { map->allocated = EINA_FALSE; - map->ptr = data; - map->size = len * 4; - if (stride) *stride = w * 4; + map->base_data = data; + map->ptr = data + x + (y * W); + pxs = 4; } - if (length) *length = map->size; + map->base_size = len * pxs; + map->length = (W * h + w - W) * pxs; + if (stride) *stride = W * pxs; + if (length) *length = map->length; - pd->internal.maps = eina_inlist_prepend(pd->internal.maps, EINA_INLIST_GET(map)); + if (!tofree) + pd->glim = im; + + EINA_INLIST_APPEND(pd->maps, map); return map->ptr; + +fail: + free(map); + return NULL; } EOLIAN static void -_evas_ector_gl_image_buffer_ector_buffer_unmap(Eo *obj EINA_UNUSED, Evas_Ector_GL_Image_Buffer_Data *pd, - void *data, unsigned int length) +_evas_ector_gl_image_buffer_ector_buffer_unmap(Eo *obj EINA_UNUSED, + Evas_Ector_GL_Image_Buffer_Data *pd, + void *data, unsigned int length) { - Evas_Public_Data *e = efl_data_scope_get(pd->evas, EVAS_CANVAS_CLASS); Ector_GL_Buffer_Map *map; if (!data) return; - EINA_INLIST_FOREACH(pd->internal.maps, map) + EINA_INLIST_FOREACH(pd->maps, map) { - if ((map->ptr == data) && ((map->size == length) || (length == (unsigned int) -1))) + if ((map->base_data == data) && (map->length == length)) { - pd->internal.maps = eina_inlist_remove(pd->internal.maps, EINA_INLIST_GET(map)); - if (map->mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) - { - CRI("Not implemented yet. Dropping pixel changes."); - } - if (map->im) + EINA_INLIST_REMOVE(pd->maps, map); + if (map->free_image) ENFN->image_free(ENDT, map->im); + else + ENFN->image_data_put(ENDT, map->im, map->image_data); if (map->allocated) - free(map->ptr); + free(map->base_data); + free(map); return; } } - CRI("Tried to unmap a non-mapped region!"); -} - -EOLIAN static uint8_t * -_evas_ector_gl_image_buffer_ector_buffer_span_get(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd, int x, int y, unsigned int w, - Efl_Gfx_Colorspace cspace, unsigned int *length) -{ - // ector_buffer_map - return _evas_ector_gl_image_buffer_ector_buffer_map - (obj, pd, length, ECTOR_BUFFER_ACCESS_FLAG_READ, x, y, w, 1, cspace, NULL); -} - -EOLIAN static void -_evas_ector_gl_image_buffer_ector_buffer_span_free(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd, uint8_t *data) -{ - // ector_buffer_unmap - return _evas_ector_gl_image_buffer_ector_buffer_unmap - (obj, pd, data, (unsigned int) -1); -} - - -EOLIAN static Efl_Object * -_evas_ector_gl_image_buffer_efl_object_constructor(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd) -{ - obj = efl_constructor(efl_super(obj, MY_CLASS)); - pd->base = efl_data_ref(obj, ECTOR_GL_BUFFER_BASE_MIXIN); - pd->base->generic = efl_data_ref(obj, ECTOR_BUFFER_MIXIN); - pd->base->generic->eo = obj; - return obj; + ERR("Tried to unmap a non-mapped region: %p +%u", data, length); } EOLIAN static Efl_Object * _evas_ector_gl_image_buffer_efl_object_finalize(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd) { - EINA_SAFETY_ON_NULL_RETURN_VAL(pd->base, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(pd->image, NULL); - pd->base->generic->immutable = EINA_TRUE; + if (!pd->glim) + { + ERR("Buffer was not initialized properly!"); + return NULL; + } return efl_finalize(efl_super(obj, MY_CLASS)); } EOLIAN static void _evas_ector_gl_image_buffer_efl_object_destructor(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd) { - Evas_Public_Data *e = efl_data_scope_get(pd->evas, EVAS_CANVAS_CLASS); - - efl_data_unref(obj, pd->base->generic); - efl_data_unref(obj, pd->base); - ENFN->image_free(ENDT, pd->image); - efl_xunref(pd->evas, obj); + evas_gl_common_image_free(pd->glim); + efl_data_xunref(pd->evas->evas, pd->evas, obj); efl_destructor(efl_super(obj, MY_CLASS)); } diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.eo b/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.eo index eff9d82984..ccf1534549 100644 --- a/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.eo +++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.eo @@ -1,14 +1,15 @@ -class Evas.Ector.GL.Image.Buffer (Evas.Ector.GL.Buffer, Evas.Ector.Buffer) +class Evas.Ector.GL.Image.Buffer (Efl.Object, Evas.Ector.Buffer, Ector.GL.Buffer) { [[An Ector GL buffer wrapping an existing Evas_GL_Image.]] implements { - Efl.Object.constructor; Efl.Object.finalize; Efl.Object.destructor; - Evas.Ector.Buffer.engine_image { get; set; } + Evas.Ector.Buffer.engine_image_set; + Evas.Ector.Buffer.drawable_image_get; + Evas.Ector.Buffer.engine_image_release; + Ector.Buffer.size { get; } + Ector.Buffer.cspace { get; } Ector.Buffer.flags { get; } - Ector.Buffer.span_get; - Ector.Buffer.span_free; Ector.Buffer.map; Ector.Buffer.unmap; } diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c b/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c deleted file mode 100644 index 91bb22220d..0000000000 --- a/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c +++ /dev/null @@ -1,117 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "evas_common_private.h" -#include "evas_gl_private.h" - -#include -#include -#include "Evas_Engine_GL_Generic.h" - -#include "evas_ector_buffer.eo.h" -#include "evas_ector_gl_rgbaimage_buffer.eo.h" -#include "../software_generic/evas_ector_software_buffer.eo.h" - -#define MY_CLASS EVAS_ECTOR_GL_RGBAIMAGE_BUFFER_CLASS - -typedef struct { - Ector_Software_Buffer_Base_Data *base; - Evas *evas; - RGBA_Image *image; - Evas_GL_Image *glim; -} Evas_Ector_GL_RGBAImage_Buffer_Data; - -// GL engine stuff, do not use with RGBA_Image / Image_Entry -#define ENFN e->engine.func -#define ENDT e->engine.data.output - -EOLIAN static void -_evas_ector_gl_rgbaimage_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ector_GL_RGBAImage_Buffer_Data *pd, - Evas *evas, void *image) -{ - RGBA_Image *im = image; - - EINA_SAFETY_ON_NULL_RETURN(image); - if (efl_finalized_get(obj)) - { - CRI("engine_image must be set at construction time only"); - return; - } - - if (!im->image.data) - { - CRI("image has no pixels yet"); - return; - } - - pd->evas = efl_xref(evas, obj); - evas_cache_image_ref(&im->cache_entry); - pd->image = im; - - ector_buffer_pixels_set(obj, im->image.data, im->cache_entry.w, im->cache_entry.h, 0, (Efl_Gfx_Colorspace) im->cache_entry.space, EINA_TRUE, 0, 0, 0, 0); -} - -EOLIAN static void -_evas_ector_gl_rgbaimage_buffer_evas_ector_buffer_engine_image_get(Eo *obj EINA_UNUSED, - Evas_Ector_GL_RGBAImage_Buffer_Data *pd, - Evas **evas, void **image) -{ - Evas_Public_Data *e = efl_data_scope_get(pd->evas, EVAS_CANVAS_CLASS); - Render_Engine_GL_Generic *re = e->engine.data.output; - int err = EVAS_LOAD_ERROR_NONE; - Evas_Engine_GL_Context *gc; - - if (evas) *evas = pd->evas; - if (image) *image = NULL; - if (pd->glim) - goto end; - - gc = re->window_gl_context_get(re->software.ob); -#ifdef EVAS_CSERVE2 - if (evas_cache2_image_cached(&pd->image->cache_entry)) - evas_cache2_image_ref(&pd->image->cache_entry); - else -#endif - evas_cache_image_ref(&pd->image->cache_entry); - pd->glim = evas_gl_common_image_new_from_rgbaimage(gc, pd->image, NULL, &err); - if ((err != EVAS_LOAD_ERROR_NONE) || !pd->glim) - { - ERR("Failed to create GL image! error %d", err); - return; - } - -end: - if (image) *image = pd->glim; -} - -EOLIAN static Eo * -_evas_ector_gl_rgbaimage_buffer_efl_object_constructor(Eo *obj, Evas_Ector_GL_RGBAImage_Buffer_Data *pd) -{ - obj = efl_constructor(efl_super(obj, MY_CLASS)); - pd->base = efl_data_xref(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN, obj); - return obj; -} - -EOLIAN static Eo * -_evas_ector_gl_rgbaimage_buffer_efl_object_finalize(Eo *obj, Evas_Ector_GL_RGBAImage_Buffer_Data *pd) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(pd->base, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(pd->image, NULL); - pd->base->generic->immutable = EINA_TRUE; - return efl_finalize(efl_super(obj, MY_CLASS)); -} - -EOLIAN static void -_evas_ector_gl_rgbaimage_buffer_efl_object_destructor(Eo *obj, Evas_Ector_GL_RGBAImage_Buffer_Data *pd) -{ - Evas_Public_Data *e = efl_data_scope_get(pd->evas, EVAS_CANVAS_CLASS); - - efl_data_xunref(obj, pd->base, obj); - ENFN->image_free(ENDT, pd->glim); - evas_cache_image_drop(&pd->image->cache_entry); - efl_xunref(pd->evas, obj); - efl_destructor(efl_super(obj, MY_CLASS)); -} - -#include "evas_ector_gl_rgbaimage_buffer.eo.c" diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.eo b/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.eo deleted file mode 100644 index 1bb15e8a5b..0000000000 --- a/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.eo +++ /dev/null @@ -1,10 +0,0 @@ -class Evas.Ector.GL.RGBAImage.Buffer (Ector.Software.Buffer, Evas.Ector.Buffer) -{ - [[A buffer object wrapping an existing Evas RGBA_Image for the GL Engine.]] - implements { - Efl.Object.constructor; - Efl.Object.finalize; - Efl.Object.destructor; - Evas.Ector.Buffer.engine_image { get; set; } - } -} diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 00fcc1d555..fe127d4936 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -7,7 +7,6 @@ #include "evas_ector_buffer.eo.h" #include "evas_ector_gl_buffer.eo.h" #include "evas_ector_gl_image_buffer.eo.h" -#include "evas_ector_gl_rgbaimage_buffer.eo.h" #include "filters/gl_engine_filter.h" #if defined HAVE_DLSYM && ! defined _WIN32 @@ -844,11 +843,11 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i if (!ok) { if (err) *err = EVAS_LOAD_ERROR_GENERIC; - ERR("Unlock failed."); + ERR("ReadPixels failed."); return NULL; } *image_data = im_new->im->image.data; - if (tofree) *tofree = EINA_TRUE; + *tofree = EINA_TRUE; return im_new; } @@ -2539,85 +2538,22 @@ eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector) } static Ector_Buffer * -eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *evas, void *engine_image, Eina_Bool is_rgba_image) +eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *evas, void *engine_image) { - Ector_Buffer *buf = NULL; + Evas_GL_Image *im = engine_image; + EINA_SAFETY_ON_NULL_RETURN_VAL(engine_image, NULL); - if (is_rgba_image) - { - RGBA_Image *im = engine_image; - buf = efl_add(EVAS_ECTOR_GL_RGBAIMAGE_BUFFER_CLASS, evas, evas_ector_buffer_engine_image_set(efl_added, evas, im)); - } - else - { - Evas_GL_Image *im = engine_image; - - buf = efl_add(EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS, evas, evas_ector_buffer_engine_image_set(efl_added, evas, im)); - } - return buf; + return efl_add(EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS, evas, + evas_ector_buffer_engine_image_set(efl_added, evas, im)); } static Ector_Buffer * -eng_ector_buffer_new(void *data, Evas *evas, void *pixels, - int width, int height, int stride, - Efl_Gfx_Colorspace cspace, Eina_Bool writeable EINA_UNUSED, - int l, int r, int t, int b, Ector_Buffer_Flag flags) +eng_ector_buffer_new(void *data EINA_UNUSED, Evas *evas, int w, int h, + Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags) { - Evas_Public_Data *e = efl_data_scope_get(evas, EVAS_CANVAS_CLASS); - Render_Engine_GL_Generic *re = e->engine.data.output; - Evas_Engine_GL_Context *gc = NULL; - Ector_Buffer *buf = NULL; - int iw = width + l + r; - int ih = height + t + b; - int pxs = (cspace == EFL_GFX_COLORSPACE_ARGB8888) ? 4 : 1; - - if (stride && (stride != iw * pxs)) - WRN("stride support is not implemented for ector gl buffers at this point!"); - - if ((flags & ECTOR_BUFFER_FLAG_RENDERABLE) == 0) - { - // Create an RGBA Image as backing - Image_Entry *ie; - - if (pixels) - { - // no copy - ie = evas_cache_image_data(evas_common_image_cache_get(), iw, ih, - pixels, EINA_TRUE, (Evas_Colorspace) cspace); - if (!ie) return NULL; - } - else - { - // alloc buffer - ie = evas_cache_image_copied_data(evas_common_image_cache_get(), iw, ih, - NULL, EINA_TRUE, (Evas_Colorspace) cspace); - if (!ie) return NULL; - pixels = ((RGBA_Image *) ie)->image.data; - memset(pixels, 0, iw * ih * pxs); - } - ie->borders.l = l; - ie->borders.r = r; - ie->borders.t = t; - ie->borders.b = b; - - buf = eng_ector_buffer_wrap(data, evas, ie, EINA_TRUE); - evas_cache_image_drop(ie); - } - else - { - // Create only an Evas_GL_Image as backing - Evas_GL_Image *im; - - if (l || r || t || b) - WRN("Borders are not supported by Evas surfaces!"); - - gc = re->window_gl_context_get(re->software.ob); - im = evas_gl_common_image_surface_new(gc, iw, ih, EINA_TRUE, EINA_FALSE); - buf = efl_add(EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS, evas, evas_ector_buffer_engine_image_set(efl_added, evas, im)); - im->references--; - } - return buf; + return efl_add(EVAS_ECTOR_GL_BUFFER_CLASS, evas, + evas_ector_gl_buffer_prepare(efl_added, evas, w, h, cspace, flags)); } static Efl_Gfx_Render_Op @@ -2768,7 +2704,7 @@ eng_ector_begin(void *data, void *context EINA_UNUSED, Ector_Surface *ector, } } memset(buffer->software, 0, sizeof (unsigned int) * w * h); - ector_buffer_pixels_set(ector, buffer->software, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE, 0, 0, 0, 0); + ector_buffer_pixels_set(ector, buffer->software, w, h, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE); ector_surface_reference_point_set(ector, x, y); } else @@ -2796,7 +2732,7 @@ eng_ector_end(void *data, void *context EINA_UNUSED, Ector_Surface *ector, w = gl_context->w; h = gl_context->h; mul_use = gl_context->dc->mul.use; - ector_buffer_pixels_set(ector, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0); + ector_buffer_pixels_set(ector, NULL, 0, 0, 0, 0); buffer->gl = eng_image_data_put(data, buffer->gl, buffer->software); if (!mul_use) diff --git a/src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c b/src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c index 9ed93897cf..5e48883ba3 100644 --- a/src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c +++ b/src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c @@ -4,17 +4,40 @@ static Eina_Bool _gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd) { Evas_Engine_GL_Context *gc; - Evas_GL_Image *image; - Evas_Canvas *eo_evas; - void *im = NULL; + Evas_GL_Image *image, *surface; + RGBA_Draw_Context *dc_save; re->window_use(re->software.ob); gc = re->window_gl_context_get(re->software.ob); - evas_ector_buffer_engine_image_get(cmd->input->buffer, &eo_evas, &im); - image = im; + image = evas_ector_buffer_drawable_image_get(cmd->input->buffer, EINA_TRUE); - evas_gl_common_image_draw(gc, image, 0, 0, image->w, image->h, 0, 0, image->w, image->h, EINA_TRUE); + EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(image->tex, EINA_FALSE); + + surface = evas_ector_buffer_render_image_get(cmd->output->buffer, EINA_FALSE); + + EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(surface->tex, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(surface->tex->pt, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(surface->tex->pt->fb != 0, EINA_FALSE); + evas_gl_common_context_target_surface_set(gc, surface); + + // TODO: mapped render iteration + + dc_save = gc->dc; + gc->dc = evas_common_draw_context_new(); + evas_common_draw_context_set_multiplier(gc->dc, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A); + + evas_gl_common_image_draw(gc, image, 0, 0, image->w, image->h, + cmd->draw.ox, cmd->draw.oy, image->w, image->h, + EINA_TRUE); + + evas_common_draw_context_free(gc->dc); + gc->dc = dc_save; + + evas_ector_buffer_engine_image_release(cmd->input->buffer, image); + evas_ector_buffer_engine_image_release(cmd->output->buffer, surface); return EINA_TRUE; } @@ -26,5 +49,5 @@ gl_filter_blend_func_get(Evas_Filter_Command *cmd) EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL); - return NULL; // _gl_filter_blend; + return _gl_filter_blend; } diff --git a/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c b/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c index 061d5fbd89..d3129744cd 100644 --- a/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c +++ b/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c @@ -27,46 +27,44 @@ _evas_ector_software_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ect RGBA_Image *im = image; EINA_SAFETY_ON_NULL_RETURN(image); - if (efl_finalized_get(obj)) - { - CRI("engine_image must be set at construction time only"); - return; - } - - if (!im->image.data) - { - CRI("image has no pixels yet"); - return; - } + EINA_SAFETY_ON_FALSE_RETURN(!efl_finalized_get(obj)); + EINA_SAFETY_ON_NULL_RETURN(im->image.data); pd->evas = efl_data_xref(evas, EVAS_CANVAS_CLASS, obj); evas_cache_image_ref(&im->cache_entry); pd->image = im; - ector_buffer_pixels_set(obj, im->image.data, im->cache_entry.w, im->cache_entry.h, 0, (Efl_Gfx_Colorspace) im->cache_entry.space, EINA_TRUE, 0, 0, 0, 0); + ector_buffer_pixels_set(obj, im->image.data, im->cache_entry.w, im->cache_entry.h, im->cache_entry.space, EINA_TRUE); } -EOLIAN static void -_evas_ector_software_buffer_evas_ector_buffer_engine_image_get(Eo *obj EINA_UNUSED, - Evas_Ector_Software_Buffer_Data *pd, - Evas **evas, void **image) +EOLIAN static void * +_evas_ector_software_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED, + Evas_Ector_Software_Buffer_Data *pd, + Eina_Bool update EINA_UNUSED) { - if (!pd->evas) - { - INF("evas_ector_buffer_engine_image_set was not called on this image"); - if (evas) *evas = NULL; - if (image) *image = NULL; - return; - } - if (evas) *evas = pd->evas->evas; - if (pd->evas->engine.func->gl_surface_read_pixels) - { - ERR("Invalid: requesting engine_image from a GL image from a simple SW buffer!"); - if (image) *image = NULL; - return; - } + evas_cache_image_ref(&pd->image->cache_entry); + return pd->image; +} - if (image) *image = pd->image; +EOLIAN static void * +_evas_ector_software_buffer_evas_ector_buffer_render_image_get(Eo *obj EINA_UNUSED, + Evas_Ector_Software_Buffer_Data *pd, + Eina_Bool update EINA_UNUSED) +{ + evas_cache_image_ref(&pd->image->cache_entry); + return pd->image; +} + +EOLIAN static Eina_Bool +_evas_ector_software_buffer_evas_ector_buffer_engine_image_release(Eo *obj EINA_UNUSED, + Evas_Ector_Software_Buffer_Data *pd, + void *image) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->image == image, EINA_FALSE); + + evas_cache_image_drop(&pd->image->cache_entry); + return EINA_TRUE; } EOLIAN static Eo * diff --git a/src/modules/evas/engines/software_generic/evas_ector_software_buffer.eo b/src/modules/evas/engines/software_generic/evas_ector_software_buffer.eo index f2c98bb17a..938cd3a4e8 100644 --- a/src/modules/evas/engines/software_generic/evas_ector_software_buffer.eo +++ b/src/modules/evas/engines/software_generic/evas_ector_software_buffer.eo @@ -5,6 +5,9 @@ class Evas.Ector.Software.Buffer (Ector.Software.Buffer, Evas.Ector.Buffer) Efl.Object.constructor; Efl.Object.finalize; Efl.Object.destructor; - Evas.Ector.Buffer.engine_image { get; set; } + Evas.Ector.Buffer.engine_image_set; + Evas.Ector.Buffer.drawable_image_get; + Evas.Ector.Buffer.render_image_get; + Evas.Ector.Buffer.engine_image_release; } } diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 4ccec9bc8f..3947af63ad 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -4333,7 +4333,7 @@ eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector) } static Ector_Buffer * -eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image, Eina_Bool is_rgba_image EINA_UNUSED) +eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image) { Image_Entry *ie = engine_image; Ector_Buffer *buf = NULL; @@ -4342,61 +4342,42 @@ eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image, Eina_ if (!efl_domain_current_push(EFL_ID_DOMAIN_SHARED)) return NULL; - buf = efl_add(EVAS_ECTOR_SOFTWARE_BUFFER_CLASS, NULL, evas_ector_buffer_engine_image_set(efl_added, e, ie)); + buf = efl_add(EVAS_ECTOR_SOFTWARE_BUFFER_CLASS, NULL, + evas_ector_buffer_engine_image_set(efl_added, e, ie)); efl_domain_current_pop(); return buf; } static Ector_Buffer * -eng_ector_buffer_new(void *data EINA_UNUSED, Evas *evas, 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 EINA_UNUSED) +eng_ector_buffer_new(void *data EINA_UNUSED, Evas *evas, int width, int height, + Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags EINA_UNUSED) { - Ector_Buffer *buf = NULL; - int pxs = (cspace == EFL_GFX_COLORSPACE_ARGB8888) ? 4 : 1; - int iw = width + l + r; - int ih = height + t + b; + Ector_Buffer *buf; + Image_Entry *ie; + void *pixels; + int pxs; - if ((flags & (ECTOR_BUFFER_FLAG_RENDERABLE | ECTOR_BUFFER_FLAG_DRAWABLE)) == 0) - { - if (!efl_domain_current_push(EFL_ID_DOMAIN_SHARED)) - return NULL; - buf = efl_add(ECTOR_SOFTWARE_BUFFER_CLASS, NULL, ector_buffer_pixels_set(efl_added, pixels, width, height, stride, cspace, writeable, l, r, t, b)); - efl_domain_current_pop(); - } + if (cspace == EFL_GFX_COLORSPACE_ARGB8888) + pxs = 4; + else if (cspace == EFL_GFX_COLORSPACE_GRY8) + pxs = 1; else { - // Create an RGBA Image as backing - Image_Entry *ie; - - if (pixels) - { - // no copy - ie = evas_cache_image_data(evas_common_image_cache_get(), iw, ih, - pixels, EINA_TRUE, (Evas_Colorspace) cspace); - if (!ie) return NULL; - } - else - { - // alloc buffer - ie = evas_cache_image_copied_data(evas_common_image_cache_get(), iw, ih, - NULL, EINA_TRUE, (Evas_Colorspace) cspace); - if (!ie) return NULL; - pixels = ((RGBA_Image *) ie)->image.data; - memset(pixels, 0, iw * ih * pxs); - } - ie->borders.l = l; - ie->borders.r = r; - ie->borders.t = t; - ie->borders.b = b; - - buf = eng_ector_buffer_wrap(data, evas, ie, EINA_TRUE); - evas_cache_image_drop(ie); + ERR("Unsupported colorspace: %d", (int) cspace); + return NULL; } + // alloc buffer + ie = evas_cache_image_copied_data(evas_common_image_cache_get(), width, height, + NULL, EINA_TRUE, cspace); + if (!ie) return NULL; + pixels = ((RGBA_Image *) ie)->image.data; + memset(pixels, 0, width * height * pxs); + + buf = eng_ector_buffer_wrap(data, evas, ie); + evas_cache_image_drop(ie); + return buf; } @@ -4546,7 +4527,7 @@ _draw_thread_ector_surface_set(void *data) y = ector_surface->y; } - ector_buffer_pixels_set(ector_surface->ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE, 0, 0, 0, 0); + ector_buffer_pixels_set(ector_surface->ector, pixels, w, h, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE); ector_surface_reference_point_set(ector_surface->ector, x, y); eina_mempool_free(_mp_command_ector_surface, ector_surface); @@ -4591,7 +4572,7 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface w = sf->cache_entry.w; h = sf->cache_entry.h; - ector_buffer_pixels_set(ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE, 0, 0, 0, 0); + ector_buffer_pixels_set(ector, pixels, w, h, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE); ector_surface_reference_point_set(ector, x, y); } } @@ -4613,7 +4594,7 @@ eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface * } else { - ector_buffer_pixels_set(ector, NULL, 0, 0, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE, 0, 0, 0, 0); + ector_buffer_pixels_set(ector, NULL, 0, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE); evas_common_cpu_end_opt(); } } diff --git a/src/modules/evas/engines/software_generic/filters/evas_filter_displace.c b/src/modules/evas/engines/software_generic/filters/evas_filter_displace.c index aeea412c79..cc459a0592 100644 --- a/src/modules/evas/engines/software_generic/filters/evas_filter_displace.c +++ b/src/modules/evas/engines/software_generic/filters/evas_filter_displace.c @@ -269,7 +269,7 @@ _filter_displace_cpu_rgba(Evas_Filter_Command *cmd) EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE); src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ARGB, &src_stride); - dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ, E_ARGB, &dst_stride); + dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ | E_WRITE, E_ARGB, &dst_stride); stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH; smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR; map_w = cmd->mask->w; @@ -294,7 +294,7 @@ _filter_displace_cpu_rgba(Evas_Filter_Command *cmd) } else map_fb = cmd->mask; - map_start = (uint32_t *) _buffer_map_all(map_fb->buffer, &map_len, E_READ, E_ARGB, &map_stride); + map_start = _buffer_map_all(map_fb->buffer, &map_len, E_READ, E_ARGB, &map_stride); EINA_SAFETY_ON_FALSE_GOTO(src && dst && map_start, end); _filter_displace_cpu_rgba_do(w, h, map_w, map_h, intensity, diff --git a/src/modules/evas/engines/software_generic/filters/evas_filter_fill.c b/src/modules/evas/engines/software_generic/filters/evas_filter_fill.c index 87a0075c35..6460b861e1 100644 --- a/src/modules/evas/engines/software_generic/filters/evas_filter_fill.c +++ b/src/modules/evas/engines/software_generic/filters/evas_filter_fill.c @@ -10,7 +10,7 @@ _fill_cpu(Evas_Filter_Command *cmd) uint32_t color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B); unsigned int stride, len; int w, h, k; - uint8_t *ptr; + uint8_t *map, *ptr; if (!cmd->draw.clip_mode_lrtb) { @@ -31,10 +31,10 @@ _fill_cpu(Evas_Filter_Command *cmd) h = CLAMP(0, fb->h - y - cmd->draw.clip.b, fb->h - y); } - ptr = _buffer_map_all(fb->buffer, &len, E_WRITE, fb->alpha_only ? E_ALPHA : E_ARGB, &stride); - if (!ptr) return EINA_FALSE; + map = _buffer_map_all(fb->buffer, &len, E_WRITE, fb->alpha_only ? E_ALPHA : E_ARGB, &stride); + if (!map) return EINA_FALSE; - ptr += y * stride; + ptr = map + y * stride; if (fb->alpha_only) { for (k = 0; k < h; k++) @@ -52,7 +52,7 @@ _fill_cpu(Evas_Filter_Command *cmd) } } - ector_buffer_unmap(fb->buffer, ptr, len); + ector_buffer_unmap(fb->buffer, map, len); return EINA_TRUE; } diff --git a/src/modules/evas/engines/software_generic/filters/evas_filter_mask.c b/src/modules/evas/engines/software_generic/filters/evas_filter_mask.c index 9243811a52..a138b43af1 100644 --- a/src/modules/evas/engines/software_generic/filters/evas_filter_mask.c +++ b/src/modules/evas/engines/software_generic/filters/evas_filter_mask.c @@ -16,9 +16,9 @@ eng_filter_mask_func_get(Evas_Filter_Command *cmd) EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->buffer, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->buffer, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->buffer, NULL); + //EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->buffer, NULL); + //EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->buffer, NULL); + //EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->buffer, NULL); EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->input->w > 0) && (cmd->input->h > 0), NULL); EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->mask->w > 0) && (cmd->mask->h > 0), NULL); EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->w == cmd->output->w, NULL);