Evas filters: Move font draw inside the filters functions

Since the filters will have to decide on which engine (SW, GL) to
choose from to render the font and the effects, move the font
draw call inside the filters module.
This commit is contained in:
Jean-Philippe Andre 2014-01-17 13:32:25 +09:00
parent 0135b45c12
commit f007cd5665
3 changed files with 85 additions and 27 deletions

View File

@ -2131,9 +2131,11 @@ evas_object_text_render(Evas_Object *eo_obj EINA_UNUSED,
int inbuf = 1;
int outbuf = 2;
int targetbuf;
RGBA_Image *input, *outputimg; // FIXME: This is engine dependent
RGBA_Image *input, *outputimg = NULL; // FIXME: This is engine dependent
void *filter_ctx;
static int gl_engine = -1;
Eina_Bool ok;
int ox = 0, oy = 0;
/* NOTE: Font effect rendering is now done ENTIRELY on CPU.
* So we rely on cache/cache2 to allocate a real image buffer,
@ -2142,6 +2144,10 @@ evas_object_text_render(Evas_Object *eo_obj EINA_UNUSED,
* image to GL.
*/
// FIXME. Disabled redraw for OpenGL.
if (gl_engine == -1)
gl_engine = !!strstr(obj->layer->evas->engine.module->definition->name, "gl");
W = obj->cur->geometry.w;
H = obj->cur->geometry.h;
X = obj->cur->geometry.x;
@ -2205,39 +2211,29 @@ evas_object_text_render(Evas_Object *eo_obj EINA_UNUSED,
// Output
targetbuf = evas_filter_buffer_image_new(filter, surface);
// Context: FIXME it should be a sw context only
filter_ctx = ENFN->context_new(ENDT);
ENFN->context_color_set(ENDT, filter_ctx, 255, 255, 255, 255);
// Alloc input now so we can draw text asap
evas_filter_buffer_data_set(filter, inbuf, NULL, W, H, EINA_TRUE);
input = evas_filter_buffer_backing_get(filter, inbuf);
// Allocate output so we can keep it around
// Allocate and steal output so we can keep it around
evas_filter_buffer_data_set(filter, outbuf, NULL, W, H, EINA_FALSE);
outputimg = evas_filter_buffer_backing_get(filter, outbuf);
if (!gl_engine)
outputimg = evas_filter_buffer_backing_steal(filter, outbuf);
o->cur.filter.output = outputimg;
// Render text to input buffer
{
int ox, oy;
ox = 0;
oy = 0;
EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
if ((o->font) && (it->text_props.len > 0))
{
evas_font_draw_async_check(obj, output,
filter_ctx,
input,
o->font,
sl + ox + it->x,
st + oy + (int) o->max_ascent,
W, H,
W, H,
&it->text_props,
do_async);
}
}
EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
if ((o->font) && (it->text_props.len > 0))
{
evas_filter_font_draw(filter, filter_ctx, inbuf, o->font,
sl + ox + it->x,
st + oy + (int) o->max_ascent,
&it->text_props,
do_async);
}
// FIXME: This final blend is not necessary. Needs to be removed.
evas_filter_command_blend_add(filter, context, outbuf, targetbuf,

View File

@ -518,6 +518,18 @@ evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid)
return buffer->backing;
}
void *
evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid)
{
Evas_Filter_Buffer *buffer;
buffer = _filter_buffer_get(ctx, bufid);
if (!buffer) return NULL;
buffer->allocated = EINA_FALSE;
return buffer->backing;
}
static Evas_Filter_Command *
_command_new(Evas_Filter_Context *ctx, Evas_Filter_Mode mode,
Evas_Filter_Buffer *input, Evas_Filter_Buffer *mask,
@ -1199,6 +1211,49 @@ evas_filter_fill_cpu_func_get(Evas_Filter_Command *cmd)
}
/* Font drawing stuff */
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 async_unref;
Evas_Filter_Buffer *fb;
void *surface;
fb = _filter_buffer_get(ctx, bufid);
if (!fb) return EINA_FALSE;
surface = fb->backing;
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
{
// 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();
}
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
@ -1286,10 +1341,13 @@ _filter_command_run(Evas_Filter_Command *cmd)
return EINA_TRUE;
}
if (!cmd->output->backing && !cmd->output->w && !cmd->output->h)
if (!cmd->output->w && !cmd->output->h)
{
cmd->output->w = cmd->ctx->w;
cmd->output->h = cmd->ctx->h;
if (!cmd->output->backing)
{
cmd->output->w = cmd->ctx->w;
cmd->output->h = cmd->ctx->h;
}
}
if ((cmd->output->w <= 0) || (cmd->output->h <= 0))

View File

@ -2,6 +2,7 @@
#define _EVAS_FILTER_H
#include "evas_common_private.h"
#include "evas_private.h"
typedef struct _Evas_Filter_Context Evas_Filter_Context;
typedef struct _Evas_Filter_Command Evas_Filter_Command;
@ -106,10 +107,13 @@ int evas_filter_buffer_image_new(Evas_Filter_Context *ctx,
int evas_filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h, Eina_Bool alpha_only);
#define evas_filter_buffer_alloc_new(ctx, w, h, a) evas_filter_buffer_data_new(ctx, NULL, w, h, a)
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_data_set(Evas_Filter_Context *ctx, int bufid, void *data, int w, int h, Eina_Bool alpha_only);
Eina_Bool evas_filter_run(Evas_Filter_Context *ctx, Eina_Bool do_async);
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);
/**
* @brief Blend a source buffer into a destination buffer, allowing X,Y offsets, Alpha to RGBA conversion with color
* @param ctx Current filter chain