Efl.Gfx.Filter: Rework APIs and mark as stable

- Remove @beta flags,
- Update @since to match stabilization,
- Change methods to properties with keys,
- Use eo_prefix and add filter_ prefix to all properties since
  they use very generic names,

The filter API stays under Efl.Gfx since there are other kinds of
filters, and this one is the particular "graphical filter" or
"effect" API.

The EO API mostly not change from an application point of view,
except for "source_get" which now returns a string directly. Also,
state and data can now be queried.
This commit is contained in:
Jean-Philippe Andre 2016-02-29 15:23:18 +09:00
parent 7920e66f29
commit 24f19dc770
8 changed files with 178 additions and 105 deletions

View File

@ -1,45 +1,69 @@
interface Efl.Gfx.Filter
{
[[Graphical filters can be applied to any object implementing this interface.
Filters are programmable effects that run whenever the object is rendered
on its canvas. The program language is Lua and a complete reference can
be found under "EFL Graphics Filters".
This was a beta feature since 1.15.
@since 1.18
]]
eo_prefix: efl_gfx;
legacy_prefix: null;
/* @since 1.15 */
methods {
@property program @beta {
@property filter_program {
set {
[[Set an evas filter program on this object.
[[Set a graphical filter program on this object.
Valid for Text and Image objects at the moment.
The argument passed to this function is a string
containing a valid Lua program based on the filters
API as described in the "Evas filters reference"
page.
The argument passed to this function is a string containing
a valid Lua program based on the filters API as described in
the "EFL Graphics Filters" reference page.
Set to null to disable filtering.
Set to $null to disable filtering.
]]
}
get {
[[Gets the code of the filter program set on this object.
May be null.
May be $null.
]]
}
values {
code: const(char)*; [[filter program source code]]
name: const(char)*(0); [[filter name (optional)]]
code: const(char)*; [[The Lua program source code.]]
name: const(char)* @optional; [[An optional name for this filter.]]
}
}
@property state @beta {
set {
[[Set the current state of the filter (for use from Edje).]]
}
@property filter_state {
[[Set the current state of the filter.
This should be used by Edje (EFL's internal layout engine), but
could also be used when implementing animations programmatically.
A full state is defined by two states (name + value): origin state
and target state of an ongoing animation, as well as the $pos
progress (from 0 to 1) of that animation timeline. The second state
can be omitted if there is no ongoing animation.
]]
get {}
set {}
values {
cur_state: const(char)*;
cur_val: double(0.0);
next_state: const(char)*;
next_val: double(0.0);
pos: double(0.0);
cur_val: double;
next_state: const(char)* @optional;
next_val: double @optional;
pos: double @optional;
}
}
@property padding @beta {
@property filter_padding {
[[Required padding to apply this filter without cropping.
Read-only property that can be used to calculate the object's final
geometry. This can be overriden (set) from inside the filter program
by using the function 'padding_set' in the Lua program.
]]
get {
[[Gets the padding required to apply this filter.]]
}
@ -50,34 +74,37 @@ interface Efl.Gfx.Filter
b: int;
}
}
source_set @beta {
[[Bind an object to use as a mask or texture with Evas Filters.
@property filter_source {
[[Bind an object to use as a mask or texture in a filter program.
This will create automatically a new RGBA buffer containing
the source object's pixels (as it is rendered).
]]
params {
@in name: const(char)*; [[buffer name as used in the program]]
@in source: Efl.Gfx.Base*; [[object to use as a proxy source]]
set {}
get {}
keys {
name: const(char)*; [[Buffer name as used in the program.]]
}
values {
source: Efl.Gfx.Base*; [[Object to use as a source of pixels.]]
}
}
source_get @const @beta {
[[Retrieve which object is attached to this filter given its
buffer name.
]]
params {
@in name: const(char)*; [[buffer name as used in the program]]
@out source: Efl.Gfx.Base*; [[object used as a proxy source]]
}
}
data_set @beta {
[[Pass extra data to the filter program.
@property filter_data {
[[Extra data used by the filter program.
This sets a global value as a string.]]
params {
@in name: const(char)*; [[Name of the global variable]]
@in value: const(char)*; [[String value to use as data]]
@in execute: bool; [[If true, execute 'name = value']]
Each data element is a string ($value) stored as a global variable
$name. The program is then responsible for conversion to numbers,
tables, etc...
If the $execute flag is set, then the $value can be complex and
run, as if the original Lua program contained a line 'name = value'.
]]
keys {
name: const(char)*; [[Name of the global variable]]
}
values {
value: const(char)*; [[String value to use as data]]
execute: bool(false); [[If $true, execute 'name = value']]
}
}
}

View File

@ -1,9 +1,12 @@
mixin Evas.Filter (Efl.Gfx.Filter, Eo.Base)
{
// Evas internal implementation
[[Evas internal implementation of filters.]]
eo_prefix: evas;
legacy_prefix: null;
methods {
@property changed @protected {
@property filter_changed @protected {
set {
[[Marks this filter as changed.]]
}
@ -11,7 +14,7 @@ mixin Evas.Filter (Efl.Gfx.Filter, Eo.Base)
val: bool;
}
}
@property invalid @protected {
@property filter_invalid @protected {
set {
[[Marks this filter as invalid.]]
}
@ -19,11 +22,11 @@ mixin Evas.Filter (Efl.Gfx.Filter, Eo.Base)
val: bool;
}
}
input_alpha @protected {
filter_input_alpha @protected {
[[Called by Evas.Filter to determine whether the input is alpha or rgba.]]
return: bool;
}
input_render @protected {
filter_input_render @protected {
[[Called by Evas.Filter when the parent class must render the input.
;
]]
@ -38,13 +41,13 @@ mixin Evas.Filter (Efl.Gfx.Filter, Eo.Base)
do_async: bool;
}
}
dirty @protected {
filter_dirty @protected {
[[Called when the filter changes must trigger a redraw of the object.
Virtual, to be implemented in the parent class.
]]
}
@property output_buffer @protected {
@property filter_output_buffer @protected {
get {
[[Retrieve cached output buffer, if any.
@ -59,15 +62,17 @@ mixin Evas.Filter (Efl.Gfx.Filter, Eo.Base)
implements {
Eo.Base.constructor;
Eo.Base.destructor;
Efl.Gfx.Filter.program.set;
Efl.Gfx.Filter.program.get;
Efl.Gfx.Filter.state.set;
Efl.Gfx.Filter.padding.get;
Efl.Gfx.Filter.source_set;
Efl.Gfx.Filter.source_get;
Efl.Gfx.Filter.data_set;
@virtual .input_alpha;
@virtual .input_render;
@virtual .dirty;
Efl.Gfx.Filter.filter_program.set;
Efl.Gfx.Filter.filter_program.get;
Efl.Gfx.Filter.filter_state.get;
Efl.Gfx.Filter.filter_state.set;
Efl.Gfx.Filter.filter_padding.get;
Efl.Gfx.Filter.filter_source.set;
Efl.Gfx.Filter.filter_source.get;
Efl.Gfx.Filter.filter_data.get;
Efl.Gfx.Filter.filter_data.set;
@virtual .filter_input_alpha;
@virtual .filter_input_render;
@virtual .filter_dirty;
}
}

View File

@ -352,8 +352,8 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
}
EOLIAN static void
_evas_filter_efl_gfx_filter_program_set(Eo *eo_obj, Evas_Filter_Data *pd,
const char *code, const char *name)
_evas_filter_efl_gfx_filter_filter_program_set(Eo *eo_obj, Evas_Filter_Data *pd,
const char *code, const char *name)
{
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
Evas_Filter_Program *pgm = NULL;
@ -404,15 +404,15 @@ _evas_filter_efl_gfx_filter_program_set(Eo *eo_obj, Evas_Filter_Data *pd,
}
EOLIAN static void
_evas_filter_efl_gfx_filter_program_get(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, const char **code, const char **name)
_evas_filter_efl_gfx_filter_filter_program_get(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, const char **code, const char **name)
{
if (code) *code = pd->data->code;
if (name) *name = pd->data->name;
}
EOLIAN static void
_evas_filter_efl_gfx_filter_source_set(Eo *eo_obj, Evas_Filter_Data *pd,
const char *name, Efl_Gfx_Base *eo_source)
_evas_filter_efl_gfx_filter_filter_source_set(Eo *eo_obj, Evas_Filter_Data *pd,
const char *name, Efl_Gfx_Base *eo_source)
{
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
Evas_Filter_Proxy_Binding *pb, *pb_old = NULL;
@ -497,19 +497,20 @@ update:
evas_object_inform_call_resize(eo_obj);
}
EOLIAN static void
_evas_filter_efl_gfx_filter_source_get(const Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd,
const char *name, Efl_Gfx_Base **source)
EOLIAN static Efl_Gfx_Base *
_evas_filter_efl_gfx_filter_filter_source_get(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
const char * name)
{
if (!source) return;
*source = eina_hash_find(pd->data->sources, name);
Evas_Filter_Proxy_Binding *pb = eina_hash_find(pd->data->sources, name);
if (!pb) return NULL;
return pb->eo_source;
}
EOLIAN static void
_evas_filter_efl_gfx_filter_state_set(Eo *eo_obj, Evas_Filter_Data *pd,
const char *cur_state, double cur_val,
const char *next_state, double next_val,
double pos)
_evas_filter_efl_gfx_filter_filter_state_set(Eo *eo_obj, Evas_Filter_Data *pd,
const char *cur_state, double cur_val,
const char *next_state, double next_val,
double pos)
{
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
@ -520,9 +521,9 @@ _evas_filter_efl_gfx_filter_state_set(Eo *eo_obj, Evas_Filter_Data *pd,
{
Evas_Object_Filter_Data *fcow = FCOW_BEGIN(pd);
fcow->changed = 1;
fcow->state.cur.name = cur_state;
eina_stringshare_replace(&fcow->state.cur.name, cur_state);
fcow->state.cur.value = cur_val;
fcow->state.next.name = next_state;
eina_stringshare_replace(&fcow->state.next.name, next_state);
fcow->state.next.value = next_val;
fcow->state.pos = pos;
FCOW_END(fcow, pd);
@ -545,8 +546,21 @@ _evas_filter_efl_gfx_filter_state_set(Eo *eo_obj, Evas_Filter_Data *pd,
}
EOLIAN static void
_evas_filter_efl_gfx_filter_padding_get(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd,
int *l, int *r, int *t, int *b)
_evas_filter_efl_gfx_filter_filter_state_get(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
const char **cur_state, double *cur_val,
const char **next_state, double *next_val,
double *pos)
{
if (cur_state) *cur_state = pd->data->state.cur.name;
if (cur_val) *cur_val = pd->data->state.cur.value;
if (next_state) *next_state = pd->data->state.next.name;
if (next_val) *next_val = pd->data->state.next.value;
if (pos) *pos = pd->data->state.pos;
}
EOLIAN static void
_evas_filter_efl_gfx_filter_filter_padding_get(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd,
int *l, int *r, int *t, int *b)
{
if (!pd->data->chain)
{
@ -560,7 +574,7 @@ _evas_filter_efl_gfx_filter_padding_get(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data
}
EOLIAN static void
_evas_filter_changed_set(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, Eina_Bool val)
_evas_filter_filter_changed_set(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, Eina_Bool val)
{
if ((evas_object_filter_cow_default != pd->data) && (pd->data->changed != val))
{
@ -571,7 +585,7 @@ _evas_filter_changed_set(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, Eina_Bool
}
EOLIAN static void
_evas_filter_invalid_set(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, Eina_Bool val)
_evas_filter_filter_invalid_set(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, Eina_Bool val)
{
if (pd->data->invalid != val)
{
@ -619,6 +633,8 @@ _evas_filter_eo_base_destructor(Eo *eo_obj, Evas_Filter_Data *pd)
}
evas_filter_program_del(pd->data->chain);
eina_stringshare_del(pd->data->code);
eina_stringshare_del(pd->data->state.cur.name);
eina_stringshare_del(pd->data->state.next.name);
finish:
eina_cow_free(evas_object_filter_cow, (const Eina_Cow_Data **) &pd->data);
@ -634,9 +650,9 @@ finish:
}
EOLIAN static void
_evas_filter_efl_gfx_filter_data_set(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
const char *name, const char *value,
Eina_Bool execute)
_evas_filter_efl_gfx_filter_filter_data_set(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
const char *name, const char *value,
Eina_Bool execute)
{
Evas_Filter_Data_Binding *db, *found = NULL;
Evas_Object_Filter_Data *fcow;
@ -680,8 +696,32 @@ _evas_filter_efl_gfx_filter_data_set(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
FCOW_END(fcow, pd);
}
EOLIAN static void
_evas_filter_efl_gfx_filter_filter_data_get(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
const char *name, const char **value,
Eina_Bool *execute)
{
Evas_Filter_Data_Binding *db;
if (!value && !execute) return;
EINA_SAFETY_ON_NULL_RETURN(pd->data);
EINA_INLIST_FOREACH(pd->data->data, db)
{
if (!strcmp(name, db->name))
{
if (value) *value = db->value;
if (execute) *execute = db->execute;
return;
}
}
if (value) *value = NULL;
if (execute) *execute = EINA_FALSE;
}
EOLIAN static void *
_evas_filter_output_buffer_get(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd)
_evas_filter_filter_output_buffer_get(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd)
{
return pd->data->output;
}

View File

@ -784,9 +784,9 @@ class Evas.Image (Evas.Object, Efl.File, Efl.Image, Efl.Gfx.Fill, Efl.Gfx.View,
Efl.Gfx.Fill.fill.get;
Efl.Gfx.View.size.set;
Efl.Gfx.View.size.get;
Efl.Gfx.Filter.program.set;
Evas.Filter.input_alpha;
Evas.Filter.input_render;
Evas.Filter.dirty;
Efl.Gfx.Filter.filter_program.set;
Evas.Filter.filter_input_alpha;
Evas.Filter.filter_input_render;
Evas.Filter.filter_dirty;
}
}

View File

@ -3208,22 +3208,22 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
}
EOLIAN static void
_evas_image_evas_filter_dirty(Eo *eo_obj EINA_UNUSED, Evas_Image_Data *o)
_evas_image_evas_filter_filter_dirty(Eo *eo_obj EINA_UNUSED, Evas_Image_Data *o)
{
o->changed = 1;
}
EOLIAN static Eina_Bool
_evas_image_evas_filter_input_alpha(Eo *eo_obj EINA_UNUSED, Evas_Image_Data *o EINA_UNUSED)
_evas_image_evas_filter_filter_input_alpha(Eo *eo_obj EINA_UNUSED, Evas_Image_Data *o EINA_UNUSED)
{
return EINA_FALSE;
}
EOLIAN static Eina_Bool
_evas_image_evas_filter_input_render(Eo *eo_obj, Evas_Image_Data *o,
void *_filter, void *context,
int l, int r EINA_UNUSED, int t, int b EINA_UNUSED,
Eina_Bool do_async)
_evas_image_evas_filter_filter_input_render(Eo *eo_obj, Evas_Image_Data *o,
void *_filter, void *context,
int l, int r EINA_UNUSED, int t, int b EINA_UNUSED,
Eina_Bool do_async)
{
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
Evas_Filter_Context *filter = _filter;
@ -4974,7 +4974,8 @@ evas_object_image_smooth_scale_get(const Eo *obj)
}
EOLIAN static void
_evas_image_efl_gfx_filter_program_set(Eo *obj, Evas_Image_Data *pd EINA_UNUSED, const char *code, const char *name)
_evas_image_efl_gfx_filter_filter_program_set(Eo *obj, Evas_Image_Data *pd EINA_UNUSED,
const char *code, const char *name)
{
pd->has_filter = (code != NULL);
eo_do_super(obj, MY_CLASS, efl_gfx_filter_program_set(code, name));

View File

@ -1664,7 +1664,7 @@ evas_font_draw_async_check(Evas_Object_Protected_Data *obj,
/* ugly binding between evas_fitler_mixin.c and this object */
EOLIAN static void
_evas_text_evas_filter_dirty(Eo *eo_obj, Evas_Text_Data *o)
_evas_text_evas_filter_filter_dirty(Eo *eo_obj, Evas_Text_Data *o)
{
_evas_object_text_items_clear(o);
o->changed = 1;
@ -1672,16 +1672,16 @@ _evas_text_evas_filter_dirty(Eo *eo_obj, Evas_Text_Data *o)
}
EOLIAN static Eina_Bool
_evas_text_evas_filter_input_alpha(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o EINA_UNUSED)
_evas_text_evas_filter_filter_input_alpha(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o EINA_UNUSED)
{
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_evas_text_evas_filter_input_render(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o,
void *_filter, void *drawctx,
int l, int r EINA_UNUSED, int t, int b EINA_UNUSED,
Eina_Bool do_async)
_evas_text_evas_filter_filter_input_render(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o,
void *_filter, void *drawctx,
int l, int r EINA_UNUSED, int t, int b EINA_UNUSED,
Eina_Bool do_async)
{
Evas_Filter_Context *filter = _filter;
Evas_Object_Text_Item *it;
@ -2336,7 +2336,7 @@ evas_object_text_text_get(const Eo *obj)
}
EOLIAN static void
_evas_text_efl_gfx_filter_program_set(Eo *obj, Evas_Text_Data *pd EINA_UNUSED, const char *code, const char *name)
_evas_text_efl_gfx_filter_filter_program_set(Eo *obj, Evas_Text_Data *pd EINA_UNUSED, const char *code, const char *name)
{
pd->has_filter = (code != NULL);
eo_do_super(obj, MY_CLASS, efl_gfx_filter_program_set(code, name));

View File

@ -260,10 +260,10 @@ class Evas.Text (Evas.Object, Efl.Text, Efl.Text_Properties, Evas.Filter)
Efl.Text_Properties.font.set;
Efl.Text_Properties.font_source.get;
Efl.Text_Properties.font_source.set;
Efl.Gfx.Filter.program.set;
Evas.Filter.input_alpha;
Evas.Filter.input_render;
Evas.Filter.dirty;
Efl.Gfx.Filter.filter_program.set;
Evas.Filter.filter_input_alpha;
Evas.Filter.filter_input_render;
Evas.Filter.filter_dirty;
Evas.Object.paragraph_direction.set;
Evas.Object.paragraph_direction.get;
}

View File

@ -240,7 +240,7 @@ START_TEST(edje_test_filters)
fail_if(!prg);
fail_if(!name || strcmp(name, "filterfile"));
eo_do(text, efl_gfx_filter_source_get("mask", &src));
eo_do(text, src = efl_gfx_filter_source_get("mask"));
fail_if(!src);
// TODO: Verify properly that the filter runs well