forked from enlightenment/efl
Evas filters: Fix image with filters using fill mode
Depending on the "filled" flag, adjust how the image is filtered. Filled: take padding into account and zoom out original image if needed Non filled: we're tiling anyways, so padding doesn't have any meaning
This commit is contained in:
parent
223e1258c1
commit
fe0f7566d5
|
@ -503,6 +503,7 @@ _image_done_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Image_Data *o)
|
||||||
obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output, o->engine_data, &stride);
|
obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output, o->engine_data, &stride);
|
||||||
else
|
else
|
||||||
stride = w * 4;
|
stride = w * 4;
|
||||||
|
|
||||||
EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
|
EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
|
||||||
{
|
{
|
||||||
state_write->has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output, o->engine_data);
|
state_write->has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output, o->engine_data);
|
||||||
|
@ -3107,6 +3108,7 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
|
||||||
if (pixels)
|
if (pixels)
|
||||||
{
|
{
|
||||||
Evas_Coord idw, idh, idx, idy;
|
Evas_Coord idw, idh, idx, idy;
|
||||||
|
int l = 0, r = 0, t = 0, b = 0;
|
||||||
int ix, iy, iw, ih;
|
int ix, iy, iw, ih;
|
||||||
|
|
||||||
if ((obj->map->cur.map) && (obj->map->cur.map->count > 3) && (obj->map->cur.usemap))
|
if ((obj->map->cur.map) && (obj->map->cur.map->count > 3) && (obj->map->cur.usemap))
|
||||||
|
@ -3122,8 +3124,7 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
|
||||||
Evas_Filter_Context *filter = NULL;
|
Evas_Filter_Context *filter = NULL;
|
||||||
void * const surface_save = surface;
|
void * const surface_save = surface;
|
||||||
void * const context_save = context;
|
void * const context_save = context;
|
||||||
const Eina_Bool do_async_save = do_async;
|
Eina_Bool input_stolen = EINA_FALSE;
|
||||||
int l = 0, r = 0, t = 0, b = 0;
|
|
||||||
Eina_Bool clear = EINA_FALSE;
|
Eina_Bool clear = EINA_FALSE;
|
||||||
int W, H, offx, offy;
|
int W, H, offx, offy;
|
||||||
|
|
||||||
|
@ -3148,6 +3149,20 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
|
||||||
|
|
||||||
/* Evas Filters on Image Object. Yet another experimental piece of code.
|
/* Evas Filters on Image Object. Yet another experimental piece of code.
|
||||||
* Replace current context, offset and surface by filter-made targets.
|
* Replace current context, offset and surface by filter-made targets.
|
||||||
|
*
|
||||||
|
* Mechanism:
|
||||||
|
* 1. Create a new surface & context, matching the object geometry
|
||||||
|
* 2. Render all borders & tiles into that surface
|
||||||
|
* 3. Apply effect and draw this surface into the original target
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
* This becomes VERY SLOW when the image OBJECT size grows... even if
|
||||||
|
* the image itself is very small. But we can't really apply a proper blur
|
||||||
|
* over one tile and repeat since blurs should overlap.
|
||||||
|
*
|
||||||
|
* Behaviour depends on the 'filled' flag:
|
||||||
|
* - If filled, then scale down the image to accomodate the whole filter's padding.
|
||||||
|
* - Otherwise, draw image in place and clip the filter's effects (eg. blur will be clipped out).
|
||||||
*/
|
*/
|
||||||
if (!o->cur->filter.invalid && o->cur->filter.code)
|
if (!o->cur->filter.invalid && o->cur->filter.code)
|
||||||
{
|
{
|
||||||
|
@ -3156,8 +3171,8 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
|
||||||
Eina_Bool ok;
|
Eina_Bool ok;
|
||||||
|
|
||||||
evas_filter_program_padding_get(pgm, &l, &r, &t, &b);
|
evas_filter_program_padding_get(pgm, &l, &r, &t, &b);
|
||||||
W = obj->cur->geometry.w + l + r;
|
W = obj->cur->geometry.w;
|
||||||
H = obj->cur->geometry.h + t + b;
|
H = obj->cur->geometry.h;
|
||||||
|
|
||||||
if (!redraw && o->cur->filter.output)
|
if (!redraw && o->cur->filter.output)
|
||||||
{
|
{
|
||||||
|
@ -3211,8 +3226,21 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
|
||||||
|
|
||||||
if (obj->layer->evas->engine.func->gl_surface_read_pixels)
|
if (obj->layer->evas->engine.func->gl_surface_read_pixels)
|
||||||
{
|
{
|
||||||
evas_filter_context_proxy_render_all(filter, eo_obj, EINA_FALSE);
|
// GL case: Create new surface, draw to it (OpenGL) and call glReadPixels
|
||||||
surface = obj->layer->evas->engine.func->image_map_surface_new(output, W, H, EINA_TRUE);
|
surface = obj->layer->evas->engine.func->image_map_surface_new(output, W, H, EINA_TRUE);
|
||||||
|
input_stolen = EINA_FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Software case: Directly draw into the filter's input buffer
|
||||||
|
surface = evas_filter_buffer_backing_steal(filter, EVAS_FILTER_BUFFER_INPUT_ID);
|
||||||
|
input_stolen = EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!surface)
|
||||||
|
{
|
||||||
|
surface = surface_save;
|
||||||
|
ok = EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
state_write:
|
state_write:
|
||||||
|
@ -3220,12 +3248,19 @@ state_write:
|
||||||
{
|
{
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
offx = l;
|
|
||||||
offy = t;
|
|
||||||
context = obj->layer->evas->engine.func->context_new(output);
|
context = obj->layer->evas->engine.func->context_new(output);
|
||||||
clear = EINA_TRUE;
|
clear = EINA_TRUE;
|
||||||
do_async = EINA_FALSE;
|
|
||||||
state_write->filter.chain = pgm;
|
state_write->filter.chain = pgm;
|
||||||
|
if (!o->filled)
|
||||||
|
{
|
||||||
|
offx = 0;
|
||||||
|
offy = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offx = l;
|
||||||
|
offy = t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3238,6 +3273,15 @@ state_write:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write)
|
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write)
|
||||||
|
|
||||||
|
if (clear)
|
||||||
|
{
|
||||||
|
obj->layer->evas->engine.func->context_color_set(output, context, 0, 0, 0, 0);
|
||||||
|
obj->layer->evas->engine.func->context_render_op_set(output, context, EVAS_RENDER_COPY);
|
||||||
|
obj->layer->evas->engine.func->rectangle_draw(output, context, surface, 0, 0, W, H, EINA_FALSE);
|
||||||
|
obj->layer->evas->engine.func->context_color_set(output, context, 255, 255, 255, 255);
|
||||||
|
obj->layer->evas->engine.func->context_render_op_set(output, context, EVAS_RENDER_BLEND);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((int)idx < obj->cur->geometry.w)
|
while ((int)idx < obj->cur->geometry.w)
|
||||||
|
@ -3256,14 +3300,9 @@ state_write:
|
||||||
else
|
else
|
||||||
iw = ((int)(idx + idw)) - ix;
|
iw = ((int)(idx + idw)) - ix;
|
||||||
|
|
||||||
if (clear)
|
// Filter stuff
|
||||||
{
|
if (o->filled)
|
||||||
obj->layer->evas->engine.func->context_color_set(output, context, 0, 0, 0, 0);
|
iw -= l + r;
|
||||||
obj->layer->evas->engine.func->context_render_op_set(output, context, EVAS_RENDER_COPY);
|
|
||||||
obj->layer->evas->engine.func->rectangle_draw(output, context, surface, 0, 0, W, H, EINA_FALSE);
|
|
||||||
obj->layer->evas->engine.func->context_color_set(output, context, 255, 255, 255, 255);
|
|
||||||
obj->layer->evas->engine.func->context_render_op_set(output, context, EVAS_RENDER_BLEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((int)idy < obj->cur->geometry.h)
|
while ((int)idy < obj->cur->geometry.h)
|
||||||
{
|
{
|
||||||
|
@ -3278,6 +3317,11 @@ state_write:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ih = ((int)(idy + idh)) - iy;
|
ih = ((int)(idy + idh)) - iy;
|
||||||
|
|
||||||
|
// Filter stuff
|
||||||
|
if (o->filled)
|
||||||
|
ih -= t + b;
|
||||||
|
|
||||||
if ((o->cur->border.l == 0) &&
|
if ((o->cur->border.l == 0) &&
|
||||||
(o->cur->border.r == 0) &&
|
(o->cur->border.r == 0) &&
|
||||||
(o->cur->border.t == 0) &&
|
(o->cur->border.t == 0) &&
|
||||||
|
@ -3472,14 +3516,18 @@ state_write:
|
||||||
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write)
|
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write)
|
||||||
}
|
}
|
||||||
|
|
||||||
evas_filter_image_draw(filter, context, EVAS_FILTER_BUFFER_INPUT_ID, surface, do_async_save);
|
if (!input_stolen)
|
||||||
obj->layer->evas->engine.func->context_free(output, context);
|
evas_filter_image_draw(filter, context, EVAS_FILTER_BUFFER_INPUT_ID, surface, do_async);
|
||||||
|
else
|
||||||
|
evas_filter_buffer_backing_release(filter, surface);
|
||||||
|
|
||||||
evas_filter_target_set(filter, context_save, surface_save, obj->cur->geometry.x + x, obj->cur->geometry.y + y);
|
evas_filter_target_set(filter, context_save, surface_save, obj->cur->geometry.x + x, obj->cur->geometry.y + y);
|
||||||
evas_filter_context_autodestroy(filter);
|
evas_filter_context_autodestroy(filter);
|
||||||
evas_filter_run(filter);
|
evas_filter_run(filter);
|
||||||
|
|
||||||
|
if (!input_stolen)
|
||||||
obj->layer->evas->engine.func->image_map_surface_free(output, surface);
|
obj->layer->evas->engine.func->image_map_surface_free(output, surface);
|
||||||
|
obj->layer->evas->engine.func->context_free(output, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue