summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <c.bail@partner.samsung.com>2014-06-25 10:47:08 +0200
committerCedric BAIL <c.bail@partner.samsung.com>2014-07-04 15:11:22 +0200
commite4a4304dc4158159ad62fc318f29248d9b2945f9 (patch)
tree3e77faa3a237a22dc338a72c706abd5cf7821103
parent325d760c554d9bc1e2b531382c0182ad439024c7 (diff)
downloadefl-e4a4304dc4158159ad62fc318f29248d9b2945f9.tar.gz
evas: simplify DRM backend to use Software generic infrastructure more.
-rw-r--r--src/modules/evas/engines/drm/evas_engine.c401
-rw-r--r--src/modules/evas/engines/drm/evas_engine.h64
-rw-r--r--src/modules/evas/engines/drm/evas_outbuf.c40
3 files changed, 102 insertions, 403 deletions
diff --git a/src/modules/evas/engines/drm/evas_engine.c b/src/modules/evas/engines/drm/evas_engine.c
index 4bed29a623..68f586ae33 100644
--- a/src/modules/evas/engines/drm/evas_engine.c
+++ b/src/modules/evas/engines/drm/evas_engine.c
@@ -5,24 +5,13 @@ typedef struct _Render_Engine Render_Engine;
struct _Render_Engine
{
- Evas_Engine_Info_Drm *info;
-
- Tilebuf *tb;
- Tilebuf_Rect *rects;
- Tilebuf_Rect *prev_rects[3];
-
- Outbuf *ob;
+ Render_Engine_Software_Generic generic;
- short mode;
-
- Eina_Inlist *cur_rect;
-
- Eina_Bool end : 1;
- Eina_Bool lost_back : 1;
+ Evas_Engine_Info_Drm *info;
};
/* local function prototypes */
-static void *_output_setup(Evas_Engine_Info_Drm *info, int w, int h, int swap);
+static void *_output_setup(Evas_Engine_Info_Drm *info, int w, int h);
/* function tables - filled in later (func and parent func) */
static Evas_Func func, pfunc;
@@ -32,56 +21,51 @@ int _evas_engine_drm_log_dom;
/* local functions */
static void *
-_output_setup(Evas_Engine_Info_Drm *info, int w, int h, int swap)
+_output_setup(Evas_Engine_Info_Drm *info, int w, int h)
{
Render_Engine *re;
+ Outbuf *ob;
/* try to allocate space for our render engine structure */
if (!(re = calloc(1, sizeof(Render_Engine))))
return NULL;
- /* try to create a new tilebuffer */
- if (!(re->tb = evas_common_tilebuf_new(w, h)))
- {
- free(re);
- return NULL;
- }
-
- /* set tilesize */
- evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
+ /* try to create new outbuf */
+ if (!(ob = evas_outbuf_setup(info, w, h)))
+ goto on_error;
+
+ if(!evas_render_engine_software_generic_init(&re->generic, ob,
+ evas_outbuf_buffer_state_get,
+ evas_outbuf_get_rot,
+ evas_outbuf_reconfigure,
+ evas_outbuf_update_region_new,
+ evas_outbuf_update_region_push,
+ evas_outbuf_update_region_free,
+ NULL,
+ evas_outbuf_flush,
+ evas_outbuf_free,
+ w, h))
+ goto on_error;
/* if we have no drm device, get one */
if (info->info.fd < 0)
{
/* try to init drm (this includes openening the card & tty) */
if (!evas_drm_init(info))
- {
- if (re->tb) evas_common_tilebuf_free(re->tb);
- free(re);
- return NULL;
- }
+ goto on_error;
}
- if (swap)
- {
- /* free any existing outbuf */
- if (re->ob) evas_outbuf_free(re->ob);
-
- /* try to create new outbuf */
- if (!(re->ob = evas_outbuf_setup(info, w, h)))
- {
- if (re->tb) evas_common_tilebuf_free(re->tb);
+ /* return the allocated render_engine structure */
+ return re;
- /* shutdown drm card & tty */
- evas_drm_shutdown(info);
+ on_error:
+ evas_render_engine_software_generic_clean(&re->generic);
- free(re);
- return NULL;
- }
- }
+ /* shutdown drm card & tty */
+ evas_drm_shutdown(info);
- /* return the allocated render_engine structure */
- return re;
+ free(re);
+ return NULL;
}
/* engine api functions */
@@ -101,7 +85,7 @@ eng_info(Evas *evas EINA_UNUSED)
return info;
}
-static void
+static void
eng_info_free(Evas *evas EINA_UNUSED, void *einfo)
{
Evas_Engine_Info_Drm *info;
@@ -111,7 +95,7 @@ eng_info_free(Evas *evas EINA_UNUSED, void *einfo)
free(info);
}
-static int
+static int
eng_setup(Evas *evas, void *einfo)
{
Evas_Engine_Info_Drm *info;
@@ -125,17 +109,15 @@ eng_setup(Evas *evas, void *einfo)
if (!(epd = eo_data_scope_get(evas, EVAS_CANVAS_CLASS))) return 0;
/* set canvas reference
- *
- * NB: We do this here so that on a vt switch, we can disable
+ *
+ * NB: We do this here so that on a vt switch, we can disable
* rendering (or re-enable) for this canvas */
info->info.evas = evas;
/* check for valid engine output */
if (!(re = epd->engine.data.output))
{
- static int swap = -1;
-
- /* NB: If we have no valid output then assume we have not been
+ /* NB: If we have no valid output then assume we have not been
* initialized yet and call any needed common init routines */
evas_common_cpu_init();
evas_common_blend_init();
@@ -149,25 +131,20 @@ eng_setup(Evas *evas, void *einfo)
evas_common_draw_init();
evas_common_tilebuf_init();
- /* check if swapping is disabled */
- if (swap == -1)
- {
- if (getenv("EVAS_DRM_NO_SWAP")) swap = 0;
- else swap = 1;
- }
-
/* try to create a new render_engine */
- if (!(re = _output_setup(info, epd->output.w, epd->output.h, swap)))
+ if (!(re = _output_setup(info, epd->output.w, epd->output.h)))
return 0;
}
else
{
- /* if we have an existing outbuf, free it */
- if (re->ob) evas_outbuf_free(re->ob);
+ Outbuf *ob;
/* try to create a new outbuf */
- if (!(re->ob = evas_outbuf_setup(info, epd->output.w, epd->output.h)))
- return 0;
+ ob = evas_outbuf_setup(info, epd->output.w, epd->output.h);
+ if (ob) return 0;
+
+ /* if we have an existing outbuf, free it */
+ evas_render_engine_software_generic_update(&re->generic, ob);
}
/* update the info structure pointer */
@@ -181,299 +158,26 @@ eng_setup(Evas *evas, void *einfo)
if (!epd->engine.data.context)
{
/* create a context if needed */
- epd->engine.data.context =
+ epd->engine.data.context =
epd->engine.func->context_new(epd->engine.data.output);
}
return 1;
}
-static void
+static void
eng_output_free(void *data)
{
- Render_Engine *re;
+ Render_Engine *re = data;
- if ((re = data))
- {
- if (re->ob) evas_outbuf_free(re->ob);
- if (re->tb) evas_common_tilebuf_free(re->tb);
- if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
- if (re->prev_rects[0])
- evas_common_tilebuf_free_render_rects(re->prev_rects[0]);
- if (re->prev_rects[1])
- evas_common_tilebuf_free_render_rects(re->prev_rects[1]);
- if (re->prev_rects[2])
- evas_common_tilebuf_free_render_rects(re->prev_rects[2]);
-
- evas_drm_shutdown(re->info);
-
- free(re);
- }
+ evas_drm_shutdown(re->info);
+ evas_render_engine_software_generic_clean(&re->generic);
+ free(re);
evas_common_font_shutdown();
evas_common_image_shutdown();
}
-static void
-eng_output_resize(void *data, int w, int h)
-{
- Render_Engine *re;
-
- /* try to get the render_engine */
- if (!(re = (Render_Engine *)data)) return;
-
- evas_outbuf_reconfigure(re->info, re->ob, w, h);
-
- if (re->tb) evas_common_tilebuf_free(re->tb);
- if ((re->tb = evas_common_tilebuf_new(w, h)))
- evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
-}
-
-static void
-eng_output_tile_size_set(void *data, int w, int h)
-{
- Render_Engine *re;
-
- /* try to get the render_engine */
- if (!(re = (Render_Engine *)data)) return;
- if (re->tb) evas_common_tilebuf_set_tile_size(re->tb, w, h);
-}
-
-static void
-eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
-{
- Render_Engine *re;
-
- /* try to get the render_engine */
- if (!(re = (Render_Engine *)data)) return;
- if (re->tb) evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
-}
-
-static void
-eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
-{
- Render_Engine *re;
-
- /* try to get the render_engine */
- if (!(re = (Render_Engine *)data)) return;
- if (re->tb) evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
-}
-
-static void
-eng_output_redraws_clear(void *data)
-{
- Render_Engine *re;
-
- /* try to get the render_engine */
- if (!(re = (Render_Engine *)data)) return;
- if (re->tb) evas_common_tilebuf_clear(re->tb);
-}
-
-static Tilebuf_Rect *
-_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3)
-{
- Tilebuf_Rect *r, *rects;
-
- if (r1)
- {
- EINA_INLIST_FOREACH(EINA_INLIST_GET(r1), r)
- evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
- }
- if (r2)
- {
- EINA_INLIST_FOREACH(EINA_INLIST_GET(r2), r)
- evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
- }
- if (r3)
- {
- EINA_INLIST_FOREACH(EINA_INLIST_GET(r3), r)
- evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
- }
- rects = evas_common_tilebuf_get_render_rects(tb);
-
-/*
- // bounding box -> make a bounding box single region update of all regions.
- // yes we could try and be smart and figure out size of regions, how far
- // apart etc. etc. to try and figure out an optimal "set". this is a tradeoff
- // between multiple update regions to render and total pixels to render.
- if (rects)
- {
- px1 = rects->x; py1 = rects->y;
- px2 = rects->x + rects->w; py2 = rects->y + rects->h;
- EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
- {
- if (r->x < x1) px1 = r->x;
- if (r->y < y1) py1 = r->y;
- if ((r->x + r->w) > x2) px2 = r->x + r->w;
- if ((r->y + r->h) > y2) py2 = r->y + r->h;
- }
- evas_common_tilebuf_free_render_rects(rects);
- rects = calloc(1, sizeof(Tilebuf_Rect));
- if (rects)
- {
- rects->x = px1;
- rects->y = py1;
- rects->w = px2 - px1;
- rects->h = py2 - py1;
- }
- }
- */
- evas_common_tilebuf_clear(tb);
- return rects;
-}
-
-static void *
-eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
-{
- Render_Engine *re;
- RGBA_Image *img;
- Tilebuf_Rect *rect;
-
- /* try to get the render_engine */
- if (!(re = (Render_Engine *)data)) return NULL;
-
-#define CLEAR_PREV_RECTS(x) \
- do { \
- if (re->prev_rects[x]) \
- evas_common_tilebuf_free_render_rects(re->prev_rects[x]); \
- re->prev_rects[x] = NULL; \
- } while (0)
-
- if (re->end)
- {
- re->end = EINA_FALSE;
- return NULL;
- }
-
- if (!re->rects)
- {
- re->mode = evas_outbuf_buffer_state_get(re->ob);
- if ((re->rects = evas_common_tilebuf_get_render_rects(re->tb)))
- {
- if ((re->lost_back) || (re->mode == MODE_FULL))
- {
- re->lost_back = EINA_FALSE;
- evas_common_tilebuf_add_redraw(re->tb,
- 0, 0, re->ob->w, re->ob->h);
- evas_common_tilebuf_free_render_rects(re->rects);
- re->rects = evas_common_tilebuf_get_render_rects(re->tb);
- }
-
- evas_common_tilebuf_clear(re->tb);
- CLEAR_PREV_RECTS(2);
- re->prev_rects[2] = re->prev_rects[1];
- re->prev_rects[1] = re->prev_rects[0];
- re->prev_rects[0] = re->rects;
- re->rects = NULL;
-
- switch (re->mode)
- {
- case MODE_FULL:
- case MODE_COPY:
- re->rects =
- _merge_rects(re->tb, re->prev_rects[0], NULL, NULL);
- break;
- case MODE_DOUBLE:
- re->rects =
- _merge_rects(re->tb, re->prev_rects[0], re->prev_rects[1], NULL);
- break;
- case MODE_TRIPLE:
- re->rects =
- _merge_rects(re->tb, re->prev_rects[0], re->prev_rects[1], re->prev_rects[2]);
- break;
- default:
- break;
- }
- }
-
- /* NB: Not sure this is entirely needed here as it's already done
- * inside _merge_rects */
- evas_common_tilebuf_clear(re->tb);
- re->cur_rect = EINA_INLIST_GET(re->rects);
- }
-
- if (!re->cur_rect) return NULL;
- rect = (Tilebuf_Rect *)re->cur_rect;
- if (re->rects)
- {
- switch (re->mode)
- {
- case MODE_COPY:
- case MODE_DOUBLE:
- case MODE_TRIPLE:
- rect = (Tilebuf_Rect *)re->cur_rect;
- *x = rect->x;
- *y = rect->y;
- *w = rect->w;
- *h = rect->h;
- *cx = rect->x;
- *cy = rect->y;
- *cw = rect->w;
- *ch = rect->h;
- re->cur_rect = re->cur_rect->next;
- break;
- case MODE_FULL:
- re->cur_rect = NULL;
- if (x) *x = 0;
- if (y) *y = 0;
- if (w) *w = re->ob->w;
- if (h) *h = re->ob->h;
- if (cx) *cx = 0;
- if (cy) *cy = 0;
- if (cw) *cw = re->ob->w;
- if (ch) *ch = re->ob->h;
- break;
- default:
- break;
- }
- img =
- evas_outbuf_update_region_new(re->ob, *x, *y, *w, *h,
- cx, cy, cw, ch);
- if (!re->cur_rect)
- {
- /* evas_common_tilebuf_free_render_rects(re->rects); */
- /* re->rects = NULL; */
- re->end = EINA_TRUE;
- }
-
- return img;
- }
-
- return NULL;
-}
-
-static void
-eng_output_redraws_next_update_push(void *data, void *img, int x, int y, int w, int h, Evas_Render_Mode render_mode)
-{
- Render_Engine *re;
-
- if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return;
-
- if (!(re = (Render_Engine *)data)) return;
-#if defined(BUILD_PIPE_RENDER)
- evas_common_pipe_map_begin(img);
-#endif
- evas_outbuf_update_region_push(re->ob, img, x, y, w, h);
-
- /* NB: No reason to free region here. That is done on flush anyway */
- /* evas_outbuf_update_region_free(re->ob, img); */
-
- evas_common_cpu_end_opt();
-}
-
-static void
-eng_output_flush(void *data, Evas_Render_Mode render_mode)
-{
- Render_Engine *re;
-
- if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return;
-
- if (!(re = (Render_Engine *)data)) return;
- evas_outbuf_flush(re->ob);
- if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
- re->rects = NULL;
-}
-
/* module api functions */
static int
module_open(Evas_Module *em)
@@ -503,15 +207,6 @@ module_open(Evas_Module *em)
EVAS_API_OVERRIDE(info_free, &func, eng_);
EVAS_API_OVERRIDE(setup, &func, eng_);
EVAS_API_OVERRIDE(output_free, &func, eng_);
- EVAS_API_OVERRIDE(output_resize, &func, eng_);
- EVAS_API_OVERRIDE(output_tile_size_set, &func, eng_);
- EVAS_API_OVERRIDE(output_redraws_rect_add, &func, eng_);
- EVAS_API_OVERRIDE(output_redraws_rect_del, &func, eng_);
- EVAS_API_OVERRIDE(output_redraws_clear, &func, eng_);
- EVAS_API_OVERRIDE(output_redraws_next_update_get, &func, eng_);
- EVAS_API_OVERRIDE(output_redraws_next_update_push, &func, eng_);
- EVAS_API_OVERRIDE(output_flush, &func, eng_);
- /* EVAS_API_OVERRIDE(output_idle_flush, &func, eng_); */
/* advertise our engine functions */
em->functions = (void *)(&func);
diff --git a/src/modules/evas/engines/drm/evas_engine.h b/src/modules/evas/engines/drm/evas_engine.h
index 675c9e50ac..cf4e22206a 100644
--- a/src/modules/evas/engines/drm/evas_engine.h
+++ b/src/modules/evas/engines/drm/evas_engine.h
@@ -17,6 +17,8 @@
#include <unistd.h>
#include <fcntl.h>
+#include "../software_generic/Evas_Engine_Software_Generic.h"
+
extern int _evas_engine_drm_log_dom;
# ifdef ERR
@@ -51,22 +53,6 @@ typedef struct _Buffer Buffer;
typedef struct _Plane Plane;
typedef struct _Outbuf Outbuf;
-enum
-{
- MODE_FULL,
- MODE_COPY,
- MODE_DOUBLE,
- MODE_TRIPLE
-};
-
-enum
-{
- OUTBUF_DEPTH_NONE,
- OUTBUF_DEPTH_ARGB_32BPP_8888_8888,
- OUTBUF_DEPTH_RGB_32BPP_8888_8888,
- OUTBUF_DEPTH_LAST
-};
-
struct _Buffer
{
int w, h;
@@ -100,37 +86,43 @@ struct _Plane
struct _Outbuf
{
+ Evas_Engine_Info_Drm *info;
+
int w, h;
- unsigned int rotation, depth;
- Eina_Bool destination_alpha : 1;
- Eina_Bool vsync : 1;
+ int rotation;
+ unsigned int depth;
- struct
- {
- int fd;
- unsigned int conn, crtc, fb;
+ struct
+ {
+ Buffer buffer[NUM_BUFFERS];
- Buffer buffer[NUM_BUFFERS];
- int curr, num;
+ Eina_List *pending_writes;
+ Eina_List *planes;
- drmModeModeInfo mode;
- drmEventContext ctx;
- Eina_Bool pending_flip : 1;
+# ifdef HAVE_DRM_HW_ACCEL
+ void *surface;
+# endif
- Eina_List *pending_writes;
+ int fd;
+ unsigned int conn, crtc, fb;
- Eina_List *planes;
+ int curr, num;
-# ifdef HAVE_DRM_HW_ACCEL
- void *surface;
-# endif
- } priv;
+ drmModeModeInfo mode;
+ drmEventContext ctx;
+
+ Eina_Bool pending_flip : 1;
+ } priv;
+
+ Eina_Bool destination_alpha : 1;
+ Eina_Bool vsync : 1;
};
Outbuf *evas_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h);
void evas_outbuf_free(Outbuf *ob);
-void evas_outbuf_reconfigure(Evas_Engine_Info_Drm *info, Outbuf *ob, int w, int h);
-int evas_outbuf_buffer_state_get(Outbuf *ob);
+void evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
+Render_Engine_Swap_Mode evas_outbuf_buffer_state_get(Outbuf *ob);
+int evas_outbuf_get_rot(Outbuf *ob);
RGBA_Image *evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update);
diff --git a/src/modules/evas/engines/drm/evas_outbuf.c b/src/modules/evas/engines/drm/evas_outbuf.c
index 80f031dbf7..1e33315626 100644
--- a/src/modules/evas/engines/drm/evas_outbuf.c
+++ b/src/modules/evas/engines/drm/evas_outbuf.c
@@ -133,10 +133,12 @@ evas_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h)
/* set back buffer as first one to draw into */
/* ob->priv.curr = (ob->priv.num - 1); */
+ ob->info = info;
+
return ob;
}
-void
+void
evas_outbuf_free(Outbuf *ob)
{
int i = 0;
@@ -149,22 +151,25 @@ evas_outbuf_free(Outbuf *ob)
free(ob);
}
-void
-evas_outbuf_reconfigure(Evas_Engine_Info_Drm *info, Outbuf *ob, int w, int h)
+void
+evas_outbuf_reconfigure(Outbuf *ob,
+ int w, int h,
+ int rot,
+ Outbuf_Depth depth)
{
int i = 0;
/* check for changes */
- if ((ob->w == w) && (ob->h == h) &&
- (ob->destination_alpha == info->info.destination_alpha) &&
- (ob->rotation == info->info.rotation) &&
- (ob->depth == info->info.depth))
+ if ((ob->w == w) && (ob->h == h) &&
+ (ob->destination_alpha == ob->info->info.destination_alpha) &&
+ (ob->rotation == rot) &&
+ (ob->depth == depth))
return;
/* set new outbuf properties */
- ob->rotation =info->info. rotation;
- ob->depth = info->info.depth;
- ob->destination_alpha = info->info.destination_alpha;
+ ob->rotation = rot;
+ ob->depth = depth;
+ ob->destination_alpha = ob->info->info.destination_alpha;
/* handle rotation */
if ((ob->rotation == 0) || (ob->rotation == 180))
@@ -196,7 +201,7 @@ evas_outbuf_reconfigure(Evas_Engine_Info_Drm *info, Outbuf *ob, int w, int h)
}
}
-int
+Render_Engine_Swap_Mode
evas_outbuf_buffer_state_get(Outbuf *ob)
{
int i = 0, n = 0, count = 0;
@@ -399,10 +404,11 @@ evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int
rect.w, rect.h, x + rx, y + ry, NULL);
}
-void
-evas_outbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update)
+void
+evas_outbuf_update_region_free(Outbuf *ob EINA_UNUSED,
+ RGBA_Image *update EINA_UNUSED)
{
- evas_cache_image_drop(&update->cache_entry);
+ /* evas_cache_image_drop(&update->cache_entry); */
}
void
@@ -478,3 +484,9 @@ evas_outbuf_flush(Outbuf *ob)
/* force a buffer swap */
_evas_outbuf_buffer_swap(ob, rects, n);
}
+
+int
+evas_outbuf_get_rot(Outbuf *ob)
+{
+ return ob->info->info.rotation;
+}