From 0d5b42e6bbff30ead404460a0538d80282a9d6c9 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Mon, 4 Jan 2016 18:00:30 +0900 Subject: [PATCH] Evas filters: Move evas image creation to the engine Evas filters is now more and more unaware of evas images (RGBA_Image) and the engine + ector take care of everything. Still left to do: - map / unmap an FBO buffer into RO or RW memory --- src/lib/evas/filters/evas_filter.c | 61 +++++-------------- src/lib/evas/filters/evas_filter_blend.c | 9 +-- src/lib/evas/filters/evas_filter_private.h | 1 - .../gl_generic/evas_ector_gl_rgbaimage_buffer.c | 3 +- src/modules/evas/engines/gl_generic/evas_engine.c | 71 +++++++++++++++++++--- 5 files changed, 83 insertions(+), 62 deletions(-) diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index 801c5a6..d632d9b 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c @@ -200,39 +200,21 @@ static Ector_Buffer * _ector_buffer_create(Evas_Filter_Buffer const *fb, void *data) { Evas_Colorspace cspace; - Image_Entry *ie; + 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 + flags = ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_CPU_WRITABLE; + if (fb->id == EVAS_FILTER_BUFFER_INPUT_ID) + flags |= ECTOR_BUFFER_FLAG_RENDERABLE; + cspace = fb->alpha_only ? EVAS_COLORSPACE_GRY8 : EVAS_COLORSPACE_ARGB8888; -#if 0 - // ideal code return fb->ENFN->ector_buffer_new(fb->ENDT, fb->ctx->evas->evas, data, fb->w, fb->h, 0, - cspace, EINA_TRUE, 0, 0, 0, 0, - ECTOR_BUFFER_FLAG_CPU_READABLE | - ECTOR_BUFFER_FLAG_CPU_WRITABLE); -#endif - - if (data) - { - // no copy - ie = evas_cache_image_data(evas_common_image_cache_get(), fb->w, fb->h, - data, EINA_TRUE, cspace); - if (!ie) return NULL; - } - else - { - // alloc buffer - ie = evas_cache_image_copied_data(evas_common_image_cache_get(), fb->w, fb->h, - NULL, EINA_TRUE, cspace); - if (!ie) return NULL; - data = ((RGBA_Image *) ie)->image.data; - memset(data, 0, fb->w * fb->h * (fb->alpha_only ? 1 : 4)); - } - return fb->ENFN->ector_buffer_wrap(fb->ENDT, fb->ctx->evas->evas, ie, EINA_TRUE); + (Efl_Gfx_Colorspace )cspace, EINA_TRUE, + 0, 0, 0, 0, flags); } Eina_Bool @@ -323,7 +305,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx) EINA_LIST_FOREACH(ctx->buffers, li, fb) { - if (fb->buffer || fb->source || fb->glimage) + if (fb->buffer || fb->source) continue; if (!fb->w && !fb->h) @@ -1439,27 +1421,14 @@ evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, surface = _evas_image_get(fb->buffer); if (!surface) return EINA_FALSE; - if (!ctx->gl_engine) - { - // Copied from evas_font_draw_async_check - async_unref = ENFN->font_draw(ENDT, draw_context, surface, - font, x, y, fb->w, fb->h, fb->w, fb->h, - text_props, do_async); - if (do_async && async_unref) - { - evas_common_font_glyphs_ref(text_props->glyphs); - evas_unref_queue_glyph_put(ctx->evas, text_props->glyphs); - } - } - else + // Copied from evas_font_draw_async_check + async_unref = ENFN->font_draw(ENDT, draw_context, surface, + font, x, y, fb->w, fb->h, fb->w, fb->h, + text_props, do_async); + if (do_async && async_unref) { - // FIXME/GL: Render in software only. - // Copied from eng_font_draw in the software engine. - - if (do_async) WRN("Async flag is ignored here!"); - evas_common_font_draw_prepare(text_props); - evas_common_font_draw(surface, draw_context, x, y, text_props->glyphs); - evas_common_cpu_end_opt(); + evas_common_font_glyphs_ref(text_props->glyphs); + evas_unref_queue_glyph_put(ctx->evas, text_props->glyphs); } return EINA_TRUE; diff --git a/src/lib/evas/filters/evas_filter_blend.c b/src/lib/evas/filters/evas_filter_blend.c index 344a7c0..9030e80 100644 --- a/src/lib/evas/filters/evas_filter_blend.c +++ b/src/lib/evas/filters/evas_filter_blend.c @@ -47,7 +47,7 @@ _image_draw_cpu_alpha_alpha(void *data EINA_UNUSED, void *context, dstdata += dst_y * dw; for (y = src_h; y; y--) { - func(srcdata + src_x, dstdata + dst_x, src_w); + func((uint8_t *) srcdata + src_x, dstdata + dst_x, src_w); srcdata += sw; dstdata += dw; } @@ -181,7 +181,7 @@ _filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, draw_func image_draw) struct Filter_Blend_Draw_Context dc; Eina_Bool ret = EINA_FALSE; Evas_Filter_Buffer *src_fb; - void *src, *dst; + void *src = NULL, *dst = NULL; sx = 0; sy = 0; @@ -220,6 +220,7 @@ _filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, draw_func image_draw) src = _buffer_map_all(src_fb->buffer, &src_len, E_READ, src_fb->alpha_only ? E_ALPHA : E_ARGB, &src_stride); dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &dst_stride); + EINA_SAFETY_ON_FALSE_GOTO(src && dst, end); dc.rop = cmd->draw.rop; dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B); @@ -228,8 +229,8 @@ _filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, draw_func image_draw) sx, sy, sw, sh, dx, dy, dw, dh, image_draw); end: - eo_do(src_fb->buffer, ector_buffer_unmap(src, src_len)); - eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len)); + if (src) eo_do(src_fb->buffer, ector_buffer_unmap(src, src_len)); + if (dst) eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len)); return ret; } diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h index e5fbc3b..bc13de9 100644 --- a/src/lib/evas/filters/evas_filter_private.h +++ b/src/lib/evas/filters/evas_filter_private.h @@ -231,7 +231,6 @@ struct _Evas_Filter_Buffer Evas_Object *source; Eina_Stringshare *source_name; Ector_Generic_Buffer *buffer; - void *glimage; int w, h; Eina_Bool alpha_only : 1; // 1 channel (A) instead of 4 (RGBA) 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 index 03d957a..6b2e127 100644 --- 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 @@ -64,15 +64,14 @@ _evas_ector_gl_rgbaimage_buffer_evas_ector_buffer_engine_image_get(Eo *obj EINA_ { Evas_Public_Data *e = eo_data_scope_get(pd->evas, EVAS_CANVAS_CLASS); Render_Engine_GL_Generic *re = e->engine.data.output; - Evas_Engine_GL_Context *gc = NULL; 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; - EINA_SAFETY_ON_NULL_RETURN(re); gc = re->window_gl_context_get(re->software.ob); pd->glim = evas_gl_common_image_new_from_rgbaimage(gc, pd->image, NULL, &err); if ((err != EVAS_LOAD_ERROR_NONE) || !pd->glim) diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index fc9caf0..6cc4b90 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -2469,7 +2469,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) +eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *evas, void *engine_image, Eina_Bool is_rgba_image) { Ector_Buffer *buf = NULL; EINA_SAFETY_ON_NULL_RETURN_VAL(engine_image, NULL); @@ -2477,27 +2477,80 @@ eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image, Eina_ { RGBA_Image *im = engine_image; - buf = eo_add(EVAS_ECTOR_GL_RGBAIMAGE_BUFFER_CLASS, e, - evas_ector_buffer_engine_image_set(e, im)); + buf = eo_add(EVAS_ECTOR_GL_RGBAIMAGE_BUFFER_CLASS, evas, + evas_ector_buffer_engine_image_set(evas, im)); } else { Evas_GL_Image *im = engine_image; - buf = eo_add(EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS, e, - evas_ector_buffer_engine_image_set(e, im)); + buf = eo_add(EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS, evas, + evas_ector_buffer_engine_image_set(evas, im)); } return buf; } static Ector_Buffer * -eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *pixels, +eng_ector_buffer_new(void *data, Evas *evas, void *pixels, int width, int height, int stride, - Efl_Gfx_Colorspace cspace, Eina_Bool writeable, + Efl_Gfx_Colorspace cspace, Eina_Bool writeable EINA_UNUSED, int l, int r, int t, int b, Ector_Buffer_Flag flags) { - CRI("Not implemented."); - return NULL; + Evas_Public_Data *e = eo_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); + buf = eo_add(EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS, evas, + evas_ector_buffer_engine_image_set(evas, im)); + im->references--; + } + return buf; } static Efl_Gfx_Render_Op -- 2.7.4