forked from enlightenment/efl
evas filters: Avoid unnecessary draw
This avoids creating one more FBO and doing one more draw, by rendering the image input data directly into the input buffer. This also makes the code common between SW and GL.
This commit is contained in:
parent
ebeead4681
commit
b77cb960ca
|
@ -54,7 +54,7 @@ _filter_end_sync(Evas_Filter_Context *ctx, Evas_Object_Protected_Data *obj,
|
|||
else
|
||||
{
|
||||
Evas_Object_Filter_Data *fcow;
|
||||
void *output = evas_filter_buffer_backing_steal(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID);
|
||||
void *output = evas_filter_buffer_backing_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID, EINA_FALSE);
|
||||
|
||||
fcow = FCOW_BEGIN(pd);
|
||||
fcow->output = output;
|
||||
|
|
|
@ -1754,30 +1754,22 @@ _efl_canvas_image_internal_efl_canvas_filter_internal_filter_state_prepare(
|
|||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_canvas_image_internal_efl_canvas_filter_internal_filter_input_render(
|
||||
Eo *eo_obj, Evas_Image_Data *o, void *_filter, void *context,
|
||||
Eo *eo_obj, Evas_Image_Data *o, void *_filter, void *context EINA_UNUSED,
|
||||
void *data EINA_UNUSED, int l, int r EINA_UNUSED, int t, int b EINA_UNUSED,
|
||||
int x, int y, Eina_Bool do_async)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
||||
Evas_Filter_Context *filter = _filter;
|
||||
void *surface, *output;
|
||||
Eina_Bool input_stolen;
|
||||
void *surface, *output, *ctx;
|
||||
int W, H;
|
||||
|
||||
W = obj->cur->geometry.w;
|
||||
H = obj->cur->geometry.h;
|
||||
output = ENDT;
|
||||
|
||||
if (ENFN->gl_surface_read_pixels)
|
||||
{
|
||||
surface = ENFN->image_map_surface_new(output, W, H, EINA_TRUE);
|
||||
input_stolen = EINA_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
surface = evas_filter_buffer_backing_steal(filter, EVAS_FILTER_BUFFER_INPUT_ID);
|
||||
input_stolen = EINA_TRUE;
|
||||
}
|
||||
surface = evas_filter_buffer_backing_get(filter, EVAS_FILTER_BUFFER_INPUT_ID, EINA_TRUE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
|
||||
|
||||
if (!o->filled)
|
||||
{
|
||||
l = 0;
|
||||
|
@ -1786,30 +1778,25 @@ _efl_canvas_image_internal_efl_canvas_filter_internal_filter_input_render(
|
|||
b = 0;
|
||||
}
|
||||
|
||||
if (!surface)
|
||||
ctx = ENFN->context_new(output);
|
||||
|
||||
if (o->cur->has_alpha && !obj->cur->snapshot)
|
||||
{
|
||||
ERR("Failed to allocate surface for filter input!");
|
||||
return EINA_FALSE;
|
||||
ENFN->context_color_set(output, ctx, 0, 0, 0, 0);
|
||||
ENFN->context_render_op_set(output, ctx, EVAS_RENDER_COPY);
|
||||
ENFN->rectangle_draw(output, ctx, surface, 0, 0, W, H, do_async);
|
||||
ENFN->context_color_set(output, ctx, 255, 255, 255, 255);
|
||||
ENFN->context_render_op_set(output, ctx, EVAS_RENDER_BLEND);
|
||||
}
|
||||
|
||||
ENFN->context_color_set(output, context, 0, 0, 0, 0);
|
||||
ENFN->context_render_op_set(output, context, EVAS_RENDER_COPY);
|
||||
ENFN->rectangle_draw(output, context, surface, 0, 0, W, H, EINA_FALSE);
|
||||
ENFN->context_color_set(output, context, 255, 255, 255, 255);
|
||||
ENFN->context_render_op_set(output, context, EVAS_RENDER_BLEND);
|
||||
|
||||
_evas_image_render(eo_obj, obj, output, context, surface,
|
||||
_evas_image_render(eo_obj, obj, output, ctx, surface,
|
||||
x + l - obj->cur->geometry.x,
|
||||
y + t - obj->cur->geometry.y,
|
||||
l, t, r, b, do_async);
|
||||
|
||||
if (!input_stolen)
|
||||
{
|
||||
evas_filter_image_draw(filter, context, EVAS_FILTER_BUFFER_INPUT_ID, surface, do_async);
|
||||
ENFN->image_free(output, surface);
|
||||
}
|
||||
else
|
||||
evas_filter_buffer_backing_release(filter, surface);
|
||||
ENFN->context_free(output, ctx);
|
||||
|
||||
evas_filter_buffer_backing_release(filter, surface);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
|
|
@ -13002,7 +13002,7 @@ _filter_sync_end(Evas_Filter_Context *ctx, Eina_Bool success)
|
|||
|
||||
if (filter->ti)
|
||||
{
|
||||
filter->output = evas_filter_buffer_backing_steal(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID);
|
||||
filter->output = evas_filter_buffer_backing_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID, EINA_FALSE);
|
||||
if (filter->ti->parent.format->gfx_filter)
|
||||
filter->ti->parent.format->gfx_filter->invalid = !success;
|
||||
// else just avoid sigsegv
|
||||
|
|
|
@ -395,14 +395,17 @@ _filter_buffer_get(Evas_Filter_Context *ctx, int bufid)
|
|||
}
|
||||
|
||||
void *
|
||||
evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid)
|
||||
evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid, Eina_Bool render)
|
||||
{
|
||||
Evas_Filter_Buffer *fb;
|
||||
|
||||
fb = _filter_buffer_get(ctx, bufid);
|
||||
if (!fb) return NULL;
|
||||
|
||||
return evas_ector_buffer_drawable_image_get(fb->buffer);
|
||||
if (render)
|
||||
return evas_ector_buffer_render_image_get(fb->buffer); // ref++
|
||||
else
|
||||
return evas_ector_buffer_drawable_image_get(fb->buffer); // ref++
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
|
@ -413,7 +416,7 @@ evas_filter_buffer_backing_release(Evas_Filter_Context *ctx,
|
|||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_main_loop_is(), EINA_FALSE);
|
||||
|
||||
ENFN->image_free(ENDT, stolen_buffer);
|
||||
ENFN->image_free(ENDT, stolen_buffer); // ref--
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1445,44 +1448,6 @@ evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Image draw: scale and draw an original image into a RW surface */
|
||||
Eina_Bool
|
||||
evas_filter_image_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
|
||||
void *image, Eina_Bool do_async)
|
||||
{
|
||||
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;
|
||||
|
||||
fb = _filter_buffer_get(ctx, bufid);
|
||||
if (!fb) return EINA_FALSE;
|
||||
|
||||
surface = evas_ector_buffer_render_image_get(fb->buffer);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
|
||||
|
||||
ENFN->image_size_get(ENDT, image, &dw, &dh);
|
||||
if (!dw || !dh) return EINA_FALSE;
|
||||
|
||||
async_unref = ENFN->image_draw(ENDT, draw_context, surface, image,
|
||||
0, 0, w, h,
|
||||
0, 0, dw, dh,
|
||||
EINA_TRUE, do_async);
|
||||
if (do_async && async_unref)
|
||||
{
|
||||
ENFN->image_ref(ENDT, image);
|
||||
evas_unref_queue_image_put(ctx->evas, image);
|
||||
}
|
||||
|
||||
evas_ector_buffer_engine_image_release(fb->buffer, surface);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Clip full input rect (0, 0, sw, sh) to target (dx, dy, dw, dh)
|
||||
* and get source's clipped sx, sy as well as destination x, y, cols and rows */
|
||||
void
|
||||
|
|
|
@ -252,7 +252,6 @@ struct _Evas_Filter_Buffer
|
|||
Eina_Bool alpha_only : 1; // 1 channel (A) instead of 4 (RGBA)
|
||||
Eina_Bool transient : 1; // temporary buffer (automatic allocation)
|
||||
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)
|
||||
};
|
||||
|
|
|
@ -155,13 +155,12 @@ Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Co
|
|||
void evas_filter_context_obscured_region_set(Evas_Filter_Context *ctx, Eina_Rectangle rect);
|
||||
|
||||
int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only);
|
||||
void *evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid);
|
||||
void *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid, Eina_Bool render);
|
||||
Eina_Bool evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer);
|
||||
|
||||
Eina_Bool evas_filter_run(Evas_Filter_Context *ctx);
|
||||
|
||||
Eina_Bool evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, Evas_Font_Set *font, int x, int y, Evas_Text_Props *text_props, Eina_Bool do_async);
|
||||
Eina_Bool evas_filter_image_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, void *image, Eina_Bool do_async);
|
||||
Eina_Bool evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, void *surface, int x, int y);
|
||||
|
||||
// utility function
|
||||
|
|
Loading…
Reference in New Issue