diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index 8cb499140f..9fa99a32ec 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c @@ -24,6 +24,7 @@ static void _buffer_free(Evas_Filter_Buffer *fb); static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd); +static RGBA_Image *_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data); #ifdef CLAMP # undef CLAMP @@ -85,55 +86,102 @@ evas_filter_context_clear(Evas_Filter_Context *ctx) } static void -_backing_free(Evas_Filter_Context *ctx, Image_Entry *ie) +_backing_free(Evas_Filter_Context *ctx, RGBA_Image *im) { - if (!ie) return; + if (!im) return; if (!ctx->gl_engine) { if (!ctx->async) - ENFN->image_free(ENDT, ie); + ENFN->image_free(ENDT, im); } else { #ifdef EVAS_CSERVE2 if (evas_cserve2_use_get()) - evas_cache2_image_close(ie); + evas_cache2_image_close(&im->cache_entry); else #endif - evas_cache_image_drop(ie); + evas_cache_image_drop(&im->cache_entry); } } static void _filter_buffer_backing_free(Evas_Filter_Buffer *fb) { - void *backing; if (!fb) return; - if (fb->stolen) + if (!fb->stolen) { - if (eina_list_data_find(fb->ctx->buffers, fb)) + if (fb->allocated) + _backing_free(fb->ctx, fb->backing); + if (fb->glimage && fb->allocated_gl) + fb->ENFN->image_free(fb->ENDT, fb->glimage); + fb->backing = NULL; + fb->glimage = NULL; + } + else + { + if (!fb->ctx->gl_engine) { - fb->delete_me = EINA_TRUE; - return; + fb->delete_me = fb->allocated; + } + else if (fb->glimage && fb->allocated) + { + _backing_free(fb->ctx, fb->backing); + fb->backing = NULL; } } +} - INF("Free backing of buffer %d fb @ %p backing @ %p alloc %d", fb->id, fb, fb->backing, fb->allocated); - backing = fb->backing; - fb->backing = NULL; +/* GL engine stuff: read-back from texture */ +static Eina_Bool +_filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb) +{ + Eina_Bool ok; - if (!fb->allocated) return; - _backing_free(fb->ctx, backing); + EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->ctx->gl_engine, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(fb->glimage, EINA_FALSE); + + if (fb->backing) + return EINA_TRUE; + + EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_lock, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_read_pixels, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_unlock, EINA_FALSE); + + fb->backing = _rgba_image_alloc(fb, NULL); + fb->allocated = EINA_TRUE; + EINA_SAFETY_ON_NULL_RETURN_VAL(fb->backing, EINA_FALSE); + + ok = fb->ENFN->gl_surface_lock(fb->ENDT, fb->glimage); + if (!ok) + { + ERR("Failed to lock the image pixels"); + return EINA_FALSE; + } + + ok = fb->ENFN->gl_surface_read_pixels(fb->ENDT, fb->glimage, + 0, 0, fb->w, fb->h, fb->alpha_only + ? EVAS_COLORSPACE_GRY8 + : EVAS_COLORSPACE_ARGB8888, + fb->backing->image.data); + if (!ok) + ERR("Could not read the image pixels!"); + + ok &= fb->ENFN->gl_surface_unlock(fb->ENDT, fb->glimage); + return ok; } /** + * @internal * Render the source object when a proxy is set. * * Used to force a draw if necessary, else just makes sure it's available. - * @note This comes direcly from evas_object_image.c. A common function is desirable here :) + * @note This comes direcly from evas_object_image.c. + * A common function is desirable here :) */ static void _proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Evas_Object *eo_proxy, @@ -151,7 +199,8 @@ _proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Evas_Object *eo_proxy, w = source->cur->geometry.w; h = source->cur->geometry.h; - EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy, Evas_Object_Proxy_Data, proxy_write) + EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy, + Evas_Object_Proxy_Data, proxy_write) { proxy_write->redraw = EINA_FALSE; @@ -227,13 +276,6 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, obj = eo_data_scope_get(eo_obj, EVAS_OBJ_CLASS); if (!ctx->has_proxies) return; - if (ctx->gl_engine) - { - // FIXME: We need to call glReadPixels (yeah, no other way around...) - ERR("Proxy subrender is not supported in the GL engine (yet)"); - return; - } - EINA_LIST_FOREACH(ctx->buffers, li, fb) if (fb->source) { @@ -243,10 +285,19 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, { INF("Source already rendered"); _filter_buffer_backing_free(fb); - fb->backing = source->proxy->surface; fb->w = source->cur->geometry.w; fb->h = source->cur->geometry.h; - fb->allocated = EINA_FALSE; + if (!ctx->gl_engine) + { + fb->backing = source->proxy->surface; + fb->allocated = EINA_FALSE; + } + else + { + fb->glimage = source->proxy->surface; + fb->allocated_gl = EINA_FALSE; + _filter_buffer_glimage_pixels_read(fb); + } fb->alpha_only = EINA_FALSE; } else @@ -254,10 +305,19 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, INF("Source needs to be rendered"); _proxy_subrender(ctx->evas->evas, fb->source, eo_obj, obj, do_async); _filter_buffer_backing_free(fb); - fb->backing = source->proxy->surface; fb->w = source->cur->geometry.w; fb->h = source->cur->geometry.h; - fb->allocated = EINA_FALSE; + if (!ctx->gl_engine) + { + fb->backing = source->proxy->surface; + fb->allocated = EINA_FALSE; + } + else + { + fb->glimage = source->proxy->surface; + fb->allocated_gl = EINA_FALSE; + _filter_buffer_glimage_pixels_read(fb); + } fb->alpha_only = EINA_FALSE; } DBG("Source has dimensions %dx%d (buffer %d)", fb->w, fb->h, fb->id); @@ -373,7 +433,6 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx, { Evas_Filter_Command *cmd; Evas_Filter_Buffer *fb; - Image_Entry *ie; Eina_List *li; EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); @@ -452,13 +511,14 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx, EINA_LIST_FOREACH(ctx->buffers, li, fb) { - ie = fb->backing; - if (ie) + RGBA_Image *im; + im = fb->backing; + if (im) { if (ctx->async) { - ie->references++; - evas_unref_queue_image_put(ctx->evas, ie); + im->cache_entry.references++; + evas_unref_queue_image_put(ctx->evas, &im->cache_entry); } continue; } @@ -471,22 +531,22 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx, if (!fb->w && !fb->h) { - ERR("Size should be known at this point. Is this a dangling buffer?"); + ERR("Size of buffer %d should be known at this point. Is this a dangling buffer?", fb->id); continue; } //DBG("Allocating buffer of size %ux%u alpha %d", fb->w, fb->h, fb->alpha_only); - ie = (Image_Entry *) _rgba_image_alloc(fb, NULL); - if (!ie) + im = _rgba_image_alloc(fb, NULL); + if (!im) { ERR("Buffer %d allocation failed!", fb->id); return EINA_FALSE; } - fb->backing = ie; - fb->allocated = (ie != NULL); + fb->backing = im; + fb->allocated = (im != NULL); if (ctx->async && fb->allocated) - evas_unref_queue_image_put(ctx->evas, ie); + evas_unref_queue_image_put(ctx->evas, &im->cache_entry); } return EINA_TRUE; @@ -536,7 +596,7 @@ _filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data, } int -evas_filter_buffer_image_new(Evas_Filter_Context *ctx, RGBA_Image *image) +evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image) { Evas_Filter_Buffer *fb; @@ -548,10 +608,19 @@ evas_filter_buffer_image_new(Evas_Filter_Context *ctx, RGBA_Image *image) fb->id = ++(ctx->last_buffer_id); fb->ctx = ctx; - fb->backing = image; - fb->w = image->cache_entry.w; - fb->h = image->cache_entry.h; - fb->alpha_only = (image->cache_entry.space == EVAS_COLORSPACE_GRY8); + if (!fb->ctx->gl_engine) + { + fb->backing = image; + fb->allocated = EINA_FALSE; + } + else + { + fb->glimage = image; + fb->allocated_gl = 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; @@ -626,23 +695,20 @@ evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid) if (!buffer) return NULL; buffer->stolen = EINA_TRUE; - if (buffer->glimage) + + if (ctx->gl_engine) return buffer->glimage; - else - { - if (ctx->async) - { - Image_Entry *ie = buffer->backing; - if (ie) ie->references++; - } - return buffer->backing; - } + + if (ctx->async && buffer->backing) + buffer->backing->cache_entry.references++; + + return buffer->backing; } Eina_Bool -evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer) +evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, + void *stolen_buffer) { - Image_Entry *ie = stolen_buffer; Evas_Filter_Buffer *fb; Eina_List *li; @@ -651,7 +717,7 @@ evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer EINA_LIST_FOREACH(ctx->buffers, li, fb) { - if (fb->backing == ie) + if (fb->backing == stolen_buffer) { fb->stolen = EINA_FALSE; if (fb->delete_me) @@ -660,7 +726,7 @@ evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer if (ctx->async) { if (fb->allocated) - evas_unref_queue_image_put(ctx->evas, ie); + evas_unref_queue_image_put(ctx->evas, stolen_buffer); free(fb); } else @@ -675,20 +741,19 @@ evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer if (fb->delete_me) { ctx->buffers = eina_list_remove_list(ctx->buffers, li); - ENFN->image_free(ENDT, stolen_buffer); - free(fb); + _buffer_free(fb); } return EINA_TRUE; } } if (ctx->async) - evas_unref_queue_image_put(ctx->evas, ie); + evas_unref_queue_image_put(ctx->evas, stolen_buffer); else if (ctx->gl_engine) ctx->post_run.buffers_to_free = eina_list_append(ctx->post_run.buffers_to_free, stolen_buffer); else - _backing_free(ctx, ie); + _backing_free(ctx, stolen_buffer); return EINA_TRUE; } @@ -1435,18 +1500,19 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, if (ctx->gl_engine) { // Since GL has sync rendering, draw_context is safe to keep around - Evas_Filter_Buffer *target, *image; - RGBA_Image *im; + Evas_Filter_Buffer *fb; ctx->target.context = draw_context; - target = _filter_buffer_get(ctx, ctx->target.bufid); - target->glimage = target->backing; - target->backing = NULL; - image = _filter_buffer_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID); - im = image->backing; - image->glimage = ENFN->image_new_from_data - (ENDT, image->w, image->h, im->image.data, EINA_TRUE, im->cache_entry.space); + fb = _filter_buffer_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID); + EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); + + fb->glimage = ENFN->image_new_from_data + (ENDT, fb->w, fb->h, fb->backing->image.data, EINA_TRUE, + fb->backing->cache_entry.space); + + DBG("Set target as #%d (%p) and output #%d (%p, gl %p)", + ctx->target.bufid, surface, fb->id, fb->backing, fb->glimage); } return EINA_TRUE; @@ -1477,6 +1543,21 @@ _filter_target_render(Evas_Filter_Context *ctx) { drawctx = ctx->target.context; surface = dst->glimage; + if (src->glimage) + { + DBG("Using glimage from output buffer."); + if (src->backing) + ENFN->image_data_put(ENDT, src->glimage, src->backing->image.data); + } + else + { + RGBA_Image *im = src->backing; + + DBG("Creating glimage from output buffer."); + src->glimage = ENFN->image_new_from_data(ENDT, src->w, src->h, + im->image.data, EINA_TRUE, + EVAS_COLORSPACE_ARGB8888); + } image = src->glimage; } EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE); diff --git a/src/lib/evas/filters/evas_filter_blend.c b/src/lib/evas/filters/evas_filter_blend.c index 61b4ef3f27..b201b282e4 100644 --- a/src/lib/evas/filters/evas_filter_blend.c +++ b/src/lib/evas/filters/evas_filter_blend.c @@ -25,9 +25,9 @@ _smallest_pow2_larger_than(int val) #endif typedef Eina_Bool (*image_draw_func) (void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async); -static void _mapped_blend_cpu(void *data, void *drawctx, RGBA_Image *in, RGBA_Image *out, Evas_Filter_Fill_Mode fillmode, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, image_draw_func image_draw); +static Eina_Bool _mapped_blend(void *data, void *drawctx, void *in, void *out, Evas_Filter_Fill_Mode fillmode, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, image_draw_func image_draw); -struct Alpha_Blend_Draw_Context +struct Filter_Blend_Draw_Context { int render_op; DATA32 color; @@ -41,7 +41,7 @@ _image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context, int smooth EINA_UNUSED, Eina_Bool do_async EINA_UNUSED) { - struct Alpha_Blend_Draw_Context *dc = context; + struct Filter_Blend_Draw_Context *dc = context; RGBA_Image *src = image; RGBA_Image *dst = surface; DATA8* srcdata = src->image.data8; @@ -77,7 +77,7 @@ _image_draw_cpu_alpha2rgba(void *data EINA_UNUSED, void *context, int smooth EINA_UNUSED, Eina_Bool do_async EINA_UNUSED) { - struct Alpha_Blend_Draw_Context *dc = context; + struct Filter_Blend_Draw_Context *dc = context; RGBA_Image *src = image; RGBA_Image *dst = surface; DATA8* srcdata = src->image.data8; @@ -112,7 +112,7 @@ _filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, { RGBA_Image *in, *out; int sw, sh, dx, dy, dw, dh, sx, sy; - struct Alpha_Blend_Draw_Context dc; + struct Filter_Blend_Draw_Context dc; in = cmd->input->backing; out = cmd->output->backing; @@ -161,10 +161,8 @@ _filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, dc.render_op = cmd->draw.render_op; dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B); - _mapped_blend_cpu(cmd->ENDT, &dc, in, out, cmd->draw.fillmode, - sx, sy, sw, sh, dx, dy, dw, dh, image_draw); - - return EINA_TRUE; + return _mapped_blend(cmd->ENDT, &dc, in, out, cmd->draw.fillmode, + sx, sy, sw, sh, dx, dy, dw, dh, image_draw); } static Eina_Bool @@ -211,6 +209,42 @@ _image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED, return EINA_TRUE; } +static Eina_Bool +_image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context, + void *surface, void *image, + int src_x, int src_y, int src_w, int src_h, + int dst_x, int dst_y, int dst_w, int dst_h, + int smooth EINA_UNUSED, + Eina_Bool do_async EINA_UNUSED) +{ + struct Filter_Blend_Draw_Context *dc = context; + RGBA_Image *src = image; + RGBA_Image *dst = surface; + DATA32* srcdata = src->image.data; + DATA32* dstdata = dst->image.data; + RGBA_Gfx_Func func; + int y, sw, dw; + + EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE); + + func = evas_common_gfx_func_composite_pixel_span_get(image, surface, 1, dc->render_op); + EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE); + + sw = src->cache_entry.w; + dw = dst->cache_entry.w; + + srcdata += src_y * sw; + dstdata += dst_y * dw; + for (y = src_h; y; y--) + { + func(srcdata + src_x, NULL, dc->color, dstdata + dst_x, src_w); + srcdata += sw; + dstdata += dw; + } + + return EINA_TRUE; +} + static Eina_Bool _filter_blend_cpu_alpha(Evas_Filter_Command *cmd) { @@ -235,6 +269,7 @@ _filter_blend_cpu_rgba(Evas_Filter_Command *cmd) RGBA_Image *in, *out; RGBA_Draw_Context *drawctx; int sw, sh, dx, dy, dw, dh, sx, sy; + Eina_Bool ret; in = cmd->input->backing; out = cmd->output->backing; @@ -243,6 +278,9 @@ _filter_blend_cpu_rgba(Evas_Filter_Command *cmd) EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE); EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE); + if (cmd->ctx->gl_engine) + return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba2rgba); + sx = 0; sy = 0; sw = in->cache_entry.w; @@ -275,43 +313,42 @@ _filter_blend_cpu_rgba(Evas_Filter_Command *cmd) out->cache_entry.w, out->cache_entry.h); } - _mapped_blend_cpu(cmd->ENDT, drawctx, in, out, cmd->draw.fillmode, - sx, sy, sw, sh, dx, dy, dw, dh, - cmd->ENFN->image_draw); + ret = _mapped_blend(cmd->ENDT, drawctx, in, out, cmd->draw.fillmode, + sx, sy, sw, sh, dx, dy, dw, dh, + cmd->ENFN->image_draw); cmd->ENFN->context_free(cmd->ENDT, drawctx); - return EINA_TRUE; + return ret; } -static void -_mapped_blend_cpu(void *data, void *drawctx, - RGBA_Image *in, RGBA_Image *out, - Evas_Filter_Fill_Mode fillmode, - int sx, int sy, - int sw, int sh, - int dx, int dy, - int dw, int dh, - image_draw_func image_draw) +static Eina_Bool +_mapped_blend(void *data, void *drawctx, + void *in, void *out, + Evas_Filter_Fill_Mode fillmode, + int sx, int sy, + int sw, int sh, + int dx, int dy, + int dw, int dh, + image_draw_func image_draw) { int right = 0, bottom = 0, left = 0, top = 0; int row, col, rows, cols; + Eina_Bool ret = EINA_TRUE; + + EINA_SAFETY_ON_FALSE_RETURN_VAL((sx == 0) && (sy == 0), EINA_FALSE); if (fillmode == EVAS_FILTER_FILL_MODE_NONE) { - _clip_to_target(&sx, &sy, sw, sh, dx, dy, out->cache_entry.w, - out->cache_entry.h, &dx, &dy, &rows, &cols); - + _clip_to_target(&sx, &sy, sw, sh, dx, dy, dw, dh, &dx, &dy, &rows, &cols); DBG("blend: %d,%d,%d,%d --> %d,%d,%d,%d (from %dx%d to %dx%d +%d,%d)", - 0, 0, sw, sh, dx, dy, cols, rows, - in->cache_entry.w, in->cache_entry.h, - out->cache_entry.w, out->cache_entry.h, - dx, dy); - image_draw(data, drawctx, out, in, - sx, sy, cols, rows, // src - dx, dy, cols, rows, // dst - EINA_TRUE, // smooth - EINA_FALSE); // Not async - return; + 0, 0, sw, sh, dx, dy, cols, rows, sw, sh, dw, dh, dx, dy); + + ret = image_draw(data, drawctx, out, in, + sx, sy, cols, rows, // src + dx, dy, cols, rows, // dst + EINA_TRUE, // smooth + EINA_FALSE); // Not async + return ret; } if (fillmode & EVAS_FILTER_FILL_MODE_REPEAT_X) @@ -328,13 +365,13 @@ _mapped_blend_cpu(void *data, void *drawctx, else if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) { cols = 0; - dw = out->cache_entry.w; dx = 0; } else { + // FIXME: Probably wrong if dx != 0 cols = 0; - dw = out->cache_entry.w - dx; + dw -= dx; } if (fillmode & EVAS_FILTER_FILL_MODE_REPEAT_Y) @@ -351,13 +388,13 @@ _mapped_blend_cpu(void *data, void *drawctx, else if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) { rows = 0; - dh = out->cache_entry.h; dy = 0; } else { + // FIXME: Probably wrong if dy != 0 rows = 0; - dh = out->cache_entry.h - dy; + dh -= dy; } if (top > 0) row = -1; @@ -444,12 +481,14 @@ _mapped_blend_cpu(void *data, void *drawctx, col, row, src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h, sw, sh, dw, dh); - image_draw(data, drawctx, out, in, - src_x, src_y, src_w, src_h, - dst_x, dst_y, dst_w, dst_h, - EINA_TRUE, EINA_FALSE); + ret = image_draw(data, drawctx, out, in, + src_x, src_y, src_w, src_h, + dst_x, dst_y, dst_w, dst_h, + EINA_TRUE, EINA_FALSE); + if (!ret) return EINA_FALSE; } } + return ret; } Evas_Filter_Apply_Func @@ -459,18 +498,27 @@ evas_filter_blend_cpu_func_get(Evas_Filter_Command *cmd) EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL); - if (cmd->input->alpha_only) + if (!cmd->ctx->gl_engine || !cmd->output->glimage || cmd->output->backing) { - if (cmd->output->alpha_only) - return _filter_blend_cpu_alpha; + if (cmd->input->alpha_only) + { + if (cmd->output->alpha_only) + return _filter_blend_cpu_alpha; + else + return _filter_blend_cpu_mask_rgba; + } else - return _filter_blend_cpu_mask_rgba; + { + if (cmd->output->alpha_only) + return _filter_blend_cpu_rgba2alpha; + else + return _filter_blend_cpu_rgba; + } } else { - if (cmd->output->alpha_only) - return _filter_blend_cpu_rgba2alpha; - else - return _filter_blend_cpu_rgba; + CRI("Can't render to GL image for the moment!"); + //return _filter_blend_opengl_generic; + return NULL; } } diff --git a/src/lib/evas/filters/evas_filter_mask.c b/src/lib/evas/filters/evas_filter_mask.c index 96e8c543a9..58500713be 100644 --- a/src/lib/evas/filters/evas_filter_mask.c +++ b/src/lib/evas/filters/evas_filter_mask.c @@ -352,6 +352,7 @@ _mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd) Evas_Filter_Command fake_cmd; Evas_Filter_Apply_Func blend; Evas_Filter_Buffer *fb; + Eina_Bool ret; int w, h; fake_cmd = *cmd; @@ -379,7 +380,8 @@ _mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd) fake_cmd.draw.render_op = EVAS_RENDER_MUL; blend = evas_filter_blend_cpu_func_get(&fake_cmd); EINA_SAFETY_ON_NULL_RETURN_VAL(blend, EINA_FALSE); - blend(&fake_cmd); + ret = blend(&fake_cmd); + if (!ret) goto finish; // Temp --> Output fake_cmd.draw.render_op = EVAS_RENDER_BLEND; @@ -387,8 +389,9 @@ _mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd) fake_cmd.output = cmd->output; blend = evas_filter_blend_cpu_func_get(&fake_cmd); EINA_SAFETY_ON_NULL_RETURN_VAL(blend, EINA_FALSE); - blend(&fake_cmd); + ret = blend(&fake_cmd); +finish: fb->locked = EINA_FALSE; - return EINA_TRUE; + return ret; } diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h index bf610a8db8..6be8b63f02 100644 --- a/src/lib/evas/filters/evas_filter_private.h +++ b/src/lib/evas/filters/evas_filter_private.h @@ -153,7 +153,7 @@ struct _Evas_Filter_Buffer Evas_Object *source; Eina_Stringshare *source_name; - void *backing; + RGBA_Image *backing; void *glimage; int w, h; @@ -161,6 +161,7 @@ struct _Evas_Filter_Buffer Eina_Bool alpha_only : 1; // 1 channel (A) instead of 4 (RGBA) Eina_Bool allocated : 1; // allocated on demand, belongs to this context + Eina_Bool allocated_gl : 1; // allocated on demand the glimage Eina_Bool transient : 1; // temporary buffer (automatic allocation) Eina_Bool locked : 1; // internal flag Eina_Bool stolen : 1; // stolen by the client diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h index e79fc9e396..5445058545 100644 --- a/src/lib/evas/include/evas_filter.h +++ b/src/lib/evas/include/evas_filter.h @@ -107,7 +107,7 @@ void evas_filter_context_post_run_callback_set(Evas_Filter_C Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx, unsigned w, unsigned h); int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only); -int evas_filter_buffer_image_new(Evas_Filter_Context *ctx, RGBA_Image *image); +int evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image); 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);