Evas filters: Move font draw inside the filters functions
authorJean-Philippe Andre <jp.andre@samsung.com>
Fri, 17 Jan 2014 04:32:25 +0000 (13:32 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Fri, 7 Feb 2014 08:33:17 +0000 (17:33 +0900)
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.

src/lib/evas/canvas/evas_object_text.c
src/lib/evas/filters/evas_filter.c
src/lib/evas/include/evas_filter.h

index 4c48b90..af3c488 100644 (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,
index 05f9db2..61563c0 100644 (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))
index 6c39e0e..1b68d8a 100644 (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