This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch devs/devilhorns/apos
in repository efl.

View the commit online.

commit 7bddaacf0d84ba5da78f7de593a365b2a7887945
Author: Christopher Michael <[email protected]>
AuthorDate: Mon Aug 25 11:59:17 2025 -0500

    evas_drm: Add new reworked evas drm engine
    
    This patch set reworks the evas drm engine to use a swapper which can
    allocate up to 4 buffers.
    
    NB: The actual swapping code is not done yet, so attempts to use this
    right now will not actually draw anything
---
 src/modules/evas/engines/drm/Evas_Engine_Drm.h  |  15 +-
 src/modules/evas/engines/drm/evas_drm_swapper.c | 192 +++++++++++
 src/modules/evas/engines/drm/evas_engine.c      |  32 +-
 src/modules/evas/engines/drm/evas_engine.h      |  50 +++
 src/modules/evas/engines/drm/evas_outbuf.c      | 434 ++++++++++++++++++++++++
 src/modules/evas/engines/drm/meson.build        |   8 +-
 6 files changed, 705 insertions(+), 26 deletions(-)

diff --git a/src/modules/evas/engines/drm/Evas_Engine_Drm.h b/src/modules/evas/engines/drm/Evas_Engine_Drm.h
index d1f46630fd..188d5bdfc2 100644
--- a/src/modules/evas/engines/drm/Evas_Engine_Drm.h
+++ b/src/modules/evas/engines/drm/Evas_Engine_Drm.h
@@ -9,19 +9,16 @@ typedef struct _Evas_Engine_Info_Drm
    /* at you and make nasty noises */
    Evas_Engine_Info magic;
 
-   struct
-     {
-        int depth, bpp;
-        unsigned int format, rotation;
+   int bpp, rotation;
+   unsigned int depth, format;
 
-        Ecore_Drm2_Device *dev;
+   Ecore_Drm2_Device *dev;
 
-        Eina_Bool alpha : 1;
-        Eina_Bool vsync : 1;
-     } info;
+   Eina_Bool alpha : 1;
+   Eina_Bool vsync : 1;
 
    /* non-blocking or blocking mode */
    Evas_Engine_Render_Mode render_mode;
 } Evas_Engine_Info_Drm;
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/modules/evas/engines/drm/evas_drm_swapper.c b/src/modules/evas/engines/drm/evas_drm_swapper.c
new file mode 100644
index 0000000000..9c3f863a3b
--- /dev/null
+++ b/src/modules/evas/engines/drm/evas_drm_swapper.c
@@ -0,0 +1,192 @@
+#include "evas_engine.h"
+
+Drm_Swapper *
+_drm_swapper_new(Ecore_Drm2_Device *dev, int w, int h, int depth, int bpp, unsigned int format)
+{
+   Drm_Swapper *swp;
+
+   swp = calloc(1, sizeof(Drm_Swapper));
+   if (!swp) return NULL;
+
+   swp->w = w;
+   swp->h = h;
+   swp->dev = dev;
+   swp->bpp = bpp;
+   swp->depth = depth;
+   swp->format = format;
+   swp->last_count = -1;
+
+   return swp;
+}
+
+void
+_drm_swapper_free(Drm_Swapper *swp)
+{
+   Drm_Buffer *buf;
+
+   if (swp->mapped) _drm_swapper_buffer_unmap(swp);
+   EINA_LIST_FREE(swp->cache, buf)
+     {
+        ecore_drm2_fb_destroy(buf->fb);
+        free(buf);
+     }
+
+   free(swp);
+}
+
+void *
+_drm_swapper_buffer_map(Drm_Swapper *swp, int *bpl, int *w, int *h)
+{
+   Drm_Buffer *buf;
+   Eina_List *l;
+
+   if (swp->mapped)
+     {
+        if (bpl)
+          {
+             if (swp->buf)
+               *bpl = ecore_drm2_fb_stride_get(swp->buf->fb);
+             else
+               *bpl = swp->w * 4;
+          }
+        if (w) *w = swp->w;
+        if (h) *h = swp->h;
+
+        return ecore_drm2_fb_map_get(swp->buf_fb);
+     }
+
+   if ((swp->buf) && (!swp->buf->reused))
+     {
+        EINA_LIST_FREE(swp->cache, buf)
+          {
+             ecore_drm2_fb_destroy(buf->fb);
+             free(buf);
+          }
+     }
+   else
+     {
+        EINA_LIST_FOREACH(swp->cache, l, buf)
+          {
+             if (buf == swp->buf)
+               {
+                  buf->reused = EINA_TRUE;
+                  swp->buf = buf;
+                  swp->buf_fb = buf->fb;
+                  swp->cache = eina_list_promote_list(swp->cache, l);
+                  break;
+               }
+          }
+     }
+
+   if (!swp->buf_fb)
+     {
+        buf = calloc(1, sizeof(Drm_Buffer));
+        if (!buf) return NULL;
+
+        buf->fb =
+          ecore_drm2_fb_create(swp->dev, swp->w, swp->h, swp->depth,
+                               swp->bpp, swp->format, NULL);
+        if (!buf->fb)
+          {
+             ERR("\tCould Not Create Fb");
+             free(buf);
+             return NULL;
+          }
+
+        buf->index = eina_list_count(swp->cache);
+
+        swp->buf = buf;
+        swp->buf_fb = buf->fb;
+        swp->cache = eina_list_prepend(swp->cache, buf);
+
+        /* trim buffer cache */
+        while (eina_list_count(swp->cache) > 4)
+          {
+             l = eina_list_last(swp->cache);
+             if (l)
+               {
+                  buf = l->data;
+                  swp->cache = eina_list_remove_list(swp->cache, l);
+                  ecore_drm2_fb_destroy(buf->fb);
+                  free(buf);
+               }
+          }
+     }
+
+   if (!ecore_drm2_fb_map(swp->buf_fb))
+     {
+        ERR("Failed to map swap buffer: %m");
+        return NULL;
+     }
+
+   if (bpl) *bpl = ecore_drm2_fb_stride_get(swp->buf_fb);
+   if (w) *w = swp->w;
+   if (h) *h = swp->h;
+
+   swp->mapped = EINA_TRUE;
+   if (swp->buf) swp->buf->mapped = EINA_TRUE;
+
+   return ecore_drm2_fb_map_get(swp->buf_fb);
+}
+
+void
+_drm_swapper_buffer_unmap(Drm_Swapper *swp)
+{
+   if (!swp->mapped) return;
+
+   ecore_drm2_fb_unmap(swp->buf_fb);
+   free(swp->buf);
+
+   swp->buf = NULL;
+   swp->buf_fb = NULL;
+   swp->mapped = EINA_FALSE;
+}
+
+void
+_drm_swapper_swap(Drm_Swapper *swp EINA_UNUSED, Eina_Rectangle *rects EINA_UNUSED, int num EINA_UNUSED)
+{
+   /* int i = 0; */
+
+   /* for (; i < num; i++) */
+   /*   { */
+   /*   } */
+
+   /* TODO */
+   /* create region */
+   /* swap buffers with region */
+   /* destroy region */
+}
+
+Render_Output_Swap_Mode
+_drm_swapper_mode_get(Drm_Swapper *swp)
+{
+   if (!swp->mapped) _drm_swapper_buffer_map(swp, NULL, NULL, NULL);
+
+   if (!swp->mapped) return MODE_FULL;
+   if (!swp->buf) return MODE_FULL;
+
+   if (swp->buf->index != swp->last_count)
+     {
+        swp->last_count = swp->buf->index;
+        return MODE_FULL;
+     }
+
+   if (swp->buf->index == 0)
+     return MODE_FULL;
+   else if (swp->buf->index == 1)
+     return MODE_COPY;
+   else if (swp->buf->index == 2)
+     return MODE_DOUBLE;
+   else if (swp->buf->index == 3)
+     return MODE_TRIPLE;
+   else if (swp->buf->index == 4)
+     return MODE_QUADRUPLE;
+
+   return MODE_FULL;
+}
+
+void
+_drm_swapper_dirty(Drm_Swapper *swp, Eina_Rectangle *rects, int num)
+{
+   ecore_drm2_fb_dirty(swp->buf_fb, rects, num);
+}
diff --git a/src/modules/evas/engines/drm/evas_engine.c b/src/modules/evas/engines/drm/evas_engine.c
index 08bcd66c7a..4c2d71353f 100644
--- a/src/modules/evas/engines/drm/evas_engine.c
+++ b/src/modules/evas/engines/drm/evas_engine.c
@@ -33,20 +33,20 @@ eng_output_setup(void *engine, void *einfo, unsigned int w, unsigned int h)
    ob = _outbuf_setup(info, w, h);
    if (!ob) goto err;
 
-   re->dev = info->info.dev;
+   re->dev = info->dev;
 
    if (!evas_render_engine_software_generic_init(engine, &re->generic, ob,
-                                                 NULL, //_outbuf_state_get,
-                                                 NULL, //_outbuf_rotation_get,
-                                                 NULL, //_outbuf_reconfigure,
-                                                 NULL,
-                                                 NULL, //_outbuf_damage_region_set,
-                                                 NULL, //_outbuf_update_region_new,
-                                                 NULL, //_outbuf_update_region_push,
-                                                 NULL,
-                                                 NULL,
-                                                 NULL, //_outbuf_flush,
-                                                 NULL,
+                                                 _outbuf_swap_mode_get,
+                                                 _outbuf_rotation_get,
+                                                 _outbuf_reconfigure,
+                                                 NULL, // region first rect get
+                                                 _outbuf_damage_region_set,
+                                                 _outbuf_update_region_new,
+                                                 _outbuf_update_region_push,
+                                                 NULL, // free_region_for_update
+                                                 _outbuf_idle_flush,
+                                                 _outbuf_flush,
+                                                 NULL, // redraws_clear
                                                  _outbuf_free,
                                                  ob->w, ob->h))
      goto init_err;
@@ -68,11 +68,11 @@ static int
 eng_output_update(void *engine EINA_UNUSED, void *data, void *einfo, unsigned int w, unsigned int h)
 {
    Render_Engine *re = data;
-//   Evas_Engine_Info_Drm *info;
+   Evas_Engine_Info_Drm *info;
 
-//   info = (Evas_Engine_Info_Drm *)einfo;
-//   _outbuf_reconfigure(re->generic.ob, w, h,
-//                       info->info.rotation, info->info.depth);
+   info = (Evas_Engine_Info_Drm *)einfo;
+
+   _outbuf_reconfigure(re->generic.ob, w, h, info->rotation, info->depth);
 
    evas_render_engine_software_generic_update(&re->generic,
                                               re->generic.ob, w, h);
diff --git a/src/modules/evas/engines/drm/evas_engine.h b/src/modules/evas/engines/drm/evas_engine.h
index 041906fd34..be184b81fc 100644
--- a/src/modules/evas/engines/drm/evas_engine.h
+++ b/src/modules/evas/engines/drm/evas_engine.h
@@ -8,6 +8,7 @@
 # include "Evas_Engine_Drm.h"
 # include <Ecore.h>
 # include <Ecore_Drm2.h>
+# include <drm_fourcc.h>
 
 # include "../software_generic/Evas_Engine_Software_Generic.h"
 
@@ -38,14 +39,63 @@ extern int _evas_engine_drm_log_dom;
 # endif
 # define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_drm_log_dom, __VA_ARGS__)
 
+typedef struct
+{
+   Ecore_Drm2_Fb *fb;
+   unsigned int index : 3;
+   Eina_Bool mapped : 1;
+   Eina_Bool reused : 1;
+} Drm_Buffer;
+
+typedef struct _Drm_Swapper
+{
+   int w, h, depth, bpp;
+   unsigned int format;
+
+   int last_count;
+
+   Drm_Buffer *buf;
+   Ecore_Drm2_Fb *buf_fb;
+   Ecore_Drm2_Device *dev;
+
+   Eina_List *cache;
+
+   Eina_Bool mapped : 1;
+} Drm_Swapper;
+
 struct _Outbuf
 {
    Evas_Engine_Info_Drm *info;
 
    int w, h;
+
+   RGBA_Image *onebuf;
+   Eina_Array onebuf_regions;
+
+   Drm_Swapper *swapper;
+
+   Eina_List *update_regions;
+
+   Eina_Bool alpha : 1;
 };
 
 Outbuf *_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h);
 void _outbuf_free(Outbuf *ob);
+Render_Output_Swap_Mode _outbuf_swap_mode_get(Outbuf *ob);
+int _outbuf_rotation_get(Outbuf *ob);
+void _outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
+void _outbuf_damage_region_set(Outbuf *ob, Tilebuf_Rect *damage);
+void *_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
+void _outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
+void _outbuf_idle_flush(Outbuf *ob);
+void _outbuf_flush(Outbuf *ob, Tilebuf_Rect *surface_damage, Tilebuf_Rect *buffer_damage, Evas_Render_Mode render_mode);
+
+Drm_Swapper *_drm_swapper_new(Ecore_Drm2_Device *dev, int w, int h, int depth, int bpp, unsigned int format);
+void _drm_swapper_free(Drm_Swapper *swp);
+void *_drm_swapper_buffer_map(Drm_Swapper *swp, int *bpl, int *w, int *h);
+void _drm_swapper_buffer_unmap(Drm_Swapper *swp);
+void _drm_swapper_swap(Drm_Swapper *swp, Eina_Rectangle *rects, int num);
+Render_Output_Swap_Mode _drm_swapper_mode_get(Drm_Swapper *swp);
+void _drm_swapper_dirty(Drm_Swapper *swp, Eina_Rectangle *rects, int num);
 
 #endif
diff --git a/src/modules/evas/engines/drm/evas_outbuf.c b/src/modules/evas/engines/drm/evas_outbuf.c
index 5c495781ad..4992b73c26 100644
--- a/src/modules/evas/engines/drm/evas_outbuf.c
+++ b/src/modules/evas/engines/drm/evas_outbuf.c
@@ -1,5 +1,9 @@
 #include "evas_engine.h"
 
+#define RED_MASK 0xff0000
+#define GREEN_MASK 0x00ff00
+#define BLUE_MASK 0x0000ff
+
 Outbuf *
 _outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h)
 {
@@ -12,11 +16,441 @@ _outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h)
    ob->h = h;
    ob->info = info;
 
+   if ((ob->info->rotation == 0) || (ob->info->rotation == 180))
+     {
+        ob->swapper =
+          _drm_swapper_new(ob->info->dev, w, h, info->depth, info->bpp,
+                           info->format);
+     }
+   else if ((ob->info->rotation == 90) || (ob->info->rotation == 270))
+     {
+        ob->swapper =
+          _drm_swapper_new(ob->info->dev, h, w, info->depth, info->bpp,
+                           info->format);
+     }
+
+   if (!ob->swapper)
+     {
+        free(ob);
+        return NULL;
+     }
+
+   eina_array_step_set(&ob->onebuf_regions, sizeof(Eina_Array), 8);
+
    return ob;
 }
 
 void
 _outbuf_free(Outbuf *ob)
 {
+   _outbuf_flush(ob, NULL, NULL, EVAS_RENDER_MODE_UNDEF);
+   _outbuf_idle_flush(ob);
+
+   _drm_swapper_free(ob->swapper);
+
+   eina_array_flush(&ob->onebuf_regions);
+
    free(ob);
 }
+
+Render_Output_Swap_Mode
+_outbuf_swap_mode_get(Outbuf *ob)
+{
+   return _drm_swapper_mode_get(ob->swapper);
+}
+
+int
+_outbuf_rotation_get(Outbuf *ob)
+{
+   return ob->info->rotation;
+}
+
+void
+_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth)
+{
+   unsigned int format = DRM_FORMAT_ARGB8888;
+
+   switch (depth)
+     {
+      case OUTBUF_DEPTH_RGB_16BPP_565_565_DITHERED:
+        format = DRM_FORMAT_RGB565;
+        break;
+      case OUTBUF_DEPTH_RGB_16BPP_555_555_DITHERED:
+        format = DRM_FORMAT_RGBX5551;
+        break;
+      case OUTBUF_DEPTH_RGB_16BPP_444_444_DITHERED:
+        format = DRM_FORMAT_RGBX4444;
+        break;
+      case OUTBUF_DEPTH_RGB_16BPP_565_444_DITHERED:
+        format = DRM_FORMAT_RGB565;
+        break;
+      case OUTBUF_DEPTH_RGB_32BPP_888_8888:
+        format = DRM_FORMAT_RGBX8888; // Should this be DRM_FORMAT_XRGB8888 ??
+        break;
+      case OUTBUF_DEPTH_ARGB_32BPP_8888_8888:
+        format = DRM_FORMAT_ARGB8888;
+        break;
+      case OUTBUF_DEPTH_BGRA_32BPP_8888_8888:
+        format = DRM_FORMAT_BGRA8888;
+        break;
+      case OUTBUF_DEPTH_BGR_32BPP_888_8888:
+        format = DRM_FORMAT_BGRX8888;
+        break;
+      case OUTBUF_DEPTH_RGB_24BPP_888_888:
+        format = DRM_FORMAT_RGB888;
+        break;
+      case OUTBUF_DEPTH_BGR_24BPP_888_888:
+        format = DRM_FORMAT_BGR888;
+        break;
+      case OUTBUF_DEPTH_INHERIT:
+      default:
+        depth = ob->info->depth;
+        format = ob->info->format;
+        break;
+     }
+
+   if ((ob->w == w) && (ob->h == h) && (ob->info->rotation == rot) &&
+       (ob->info->depth == depth) && (ob->info->format == format))
+     return;
+
+   ob->w = w;
+   ob->h = h;
+   ob->info->depth = depth;
+   ob->info->format = format;
+   ob->info->rotation = rot;
+
+   _outbuf_idle_flush(ob);
+
+   _drm_swapper_free(ob->swapper);
+
+   if ((ob->info->rotation == 0) || (ob->info->rotation == 180))
+     {
+        ob->swapper =
+          _drm_swapper_new(ob->info->dev, w, h, ob->info->depth, ob->info->bpp,
+                           ob->info->format);
+     }
+   else if ((ob->info->rotation == 90) || (ob->info->rotation == 270))
+     {
+        ob->swapper =
+          _drm_swapper_new(ob->info->dev, h, w, ob->info->depth, ob->info->bpp,
+                           ob->info->format);
+     }
+}
+
+void
+_outbuf_damage_region_set(Outbuf *ob, Tilebuf_Rect *damage)
+{
+   Tilebuf_Rect *tr;
+   Eina_Rectangle *rects;
+   int count, i = 0;
+
+   count = eina_inlist_count(EINA_INLIST_GET(damage));
+   rects = alloca(count * sizeof(Eina_Rectangle));
+
+   EINA_INLIST_FOREACH(damage, tr)
+     {
+        rects[i].x = tr->x;
+        rects[i].y = tr->y;
+        rects[i].w = tr->w;
+        rects[i].h = tr->h;
+        i++;
+     }
+
+   _drm_swapper_dirty(ob->swapper, rects, count);
+}
+
+void *
+_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
+{
+   RGBA_Image *img = NULL;
+   Eina_Rectangle *rect;
+
+   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, ob->w, ob->h);
+   if ((w <= 0) || (h <= 0)) return NULL;
+
+   if ((ob->info->rotation == 0))
+     {
+        Eina_Rectangle *rect;
+        RGBA_Image *img;
+        void *data;
+        int bpl = 0;
+
+        img = ob->onebuf;
+        if (!img)
+          {
+             int ww = 0, hh = 0, bpp;
+
+             /* bpp = ob->info->depth / 8; */
+             bpp = ob->info->bpp;
+             data = "" &bpl, &ww, &hh);
+             img = (RGBA_Image *)
+               evas_cache_image_data(evas_common_image_cache_get(),
+                                     bpl / bpp, hh, data, ob->alpha,
+                                     EVAS_COLORSPACE_ARGB8888);
+             ob->_onebuf_ = img;
+             if (!img) return NULL;
+          }
+
+        rect = eina_rectangle_new(x, y, w, h);
+        if (!eina_array_push(&ob->onebuf_regions, rect))
+          {
+             evas_cache_image_drop(&img->cache_entry);
+             eina_rectangle_free(rect);
+             return NULL;
+          }
+
+        if (cx) *cx = x;
+        if (cy) *cy = y;
+        if (cw) *cw = w;
+        if (ch) *ch = h;
+
+        return img;
+     }
+   else
+     {
+        img = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
+        if (!img) return NULL;
+
+        RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, ob->w, ob->h);
+
+        if (!(rect = eina_rectangle_new(x, y, w, h)))
+          return NULL;
+
+        img->cache_entry.w = w;
+        img->cache_entry.h = h;
+        img->cache_entry.flags.alpha = ob->alpha;
+
+        evas_cache_image_surface_alloc(&img->cache_entry, w, h);
+
+        img->extended_info = rect;
+
+        if (cx) *cx = 0;
+        if (cy) *cy = 0;
+        if (cw) *cw = w;
+        if (ch) *ch = h;
+
+        /* add this cached image data to pending update regions */
+        ob->update_regions = eina_list_append(ob->update_regions, img);
+
+        return img;
+     }
+
+   return NULL;
+}
+
+void
+_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h)
+{
+   Gfx_Func_Convert conv_func = NULL;
+   Eina_Rectangle rect = {0, 0, 0, 0}, pr;
+   int bpp, bpl = 0, ww = 0, hh = 0;
+   int rx = 0, ry = 0, wid;
+   DATA32 *src;
+   DATA8 *dst;
+
+   if (!ob->update_regions) return;
+
+   /* bpp = ob->info->depth / 8; */
+   bpp = ob->info->bpp;
+   if (bpp <= 0) return;
+
+   if ((ob->info->rotation == 0) || (ob->info->rotation == 180))
+     {
+        conv_func =
+          evas_common_convert_func_get(0, w, h, ob->info->depth,
+                                       RED_MASK, GREEN_MASK, BLUE_MASK,
+                                       PAL_MODE_NONE, ob->info->rotation);
+     }
+   else if ((ob->info->rotation == 90) || (ob->info->rotation == 270))
+     {
+        conv_func =
+          evas_common_convert_func_get(0, h, w, ob->info->depth,
+                                       RED_MASK, GREEN_MASK, BLUE_MASK,
+                                       PAL_MODE_NONE, ob->info->rotation);
+     }
+
+   if (!conv_func) return;
+
+   if (ob->info->rotation == 0)
+     {
+        rect.x = x;
+        rect.y = y;
+     }
+   else if (ob->info->rotation == 90)
+     {
+        rect.x = y;
+        rect.y = (ob->w - x - w);
+     }
+   else if (ob->info->rotation == 180)
+     {
+        rect.x = (ob->w = x - w);
+        rect.y = (ob->h - y - h);
+     }
+   else if (ob->info->rotation == 270)
+     {
+        rect.x = (ob->h - y - h);
+        rect.y = x;
+     }
+
+   if ((ob->info->rotation == 0) || (ob->info->rotation == 180))
+     {
+        rect.w = w;
+        rect.h = h;
+     }
+   else if ((ob->info->rotation == 90) || (ob->info->rotation == 270))
+     {
+        rect.w = h;
+        rect.h = w;
+     }
+
+   src = ""
+   if (!src) return;
+
+   dst = _drm_swapper_buffer_map(ob->swapper, &bpl, &ww, &hh);
+   if (!dst) return;
+
+   if ((ob->info->rotation == 0) || (ob->info->rotation == 180))
+     {
+        RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh);
+        if (ob->info->rotation == 0)
+          dst += (bpl * rect.y) + (rect.x * bpp);
+        else if (ob->info->rotation == 180)
+          {
+             pr = rect;
+             rx = pr.w - rect.w;
+             ry = pr.h - rect.h;
+             src += (update->cache_entry.w * ry) + rx;
+          }
+        w -= rx;
+     }
+   else
+     {
+        pr = rect;
+        RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh);
+        rx = pr.w - rect.w;
+        ry = pr.h - rect.h;
+        if (ob->info->rotation == 90)
+          src += ry;
+        else if (ob->info->rotation == 270)
+          src += (update->cache_entry.w * rx);
+        w -= ry;
+     }
+
+   if ((rect.w <= 0) || (rect.h <= 0)) return;
+
+   wid = bpl / bpp;
+   dst += (bpl * rect.y) + (rect.x * bpp);
+   conv_func(src, dst, update->cache_entry.w - w, wid - rect.w,
+             rect.w, rect.h, x + rx, y + ry, NULL);
+}
+
+void
+_outbuf_idle_flush(Outbuf *ob EINA_UNUSED)
+{
+   /* _outbuf_update_regions_remove(ob); */
+   /* TODO: release FBs */
+}
+
+void
+_outbuf_flush(Outbuf *ob, Tilebuf_Rect *surface_damage EINA_UNUSED, Tilebuf_Rect *buffer_damage EINA_UNUSED, Evas_Render_Mode render_mode)
+{
+   Eina_Rectangle *rects;
+   RGBA_Image *img;
+   int update_count = 0;
+   unsigned int i = 0;
+
+   if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return;
+
+   if (!ob->update_regions)
+     {
+        Eina_Rectangle *rect;
+        Eina_Array_Iterator itr;
+
+        /* get count of updates */
+        update_count = eina_array_count_get(&ob->onebuf_regions);
+        if (update_count == 0) return;
+
+        /* allocate space for rectangles */
+        rects = alloca(update_count * sizeof(Eina_Rectangle));
+        if (!rects) return;
+
+        EINA_ARRAY_ITER_NEXT(&ob->onebuf_regions, i, rect, itr)
+          {
+             rects[i] = *rect;
+             eina_rectangle_free(rect);
+          }
+
+        _drm_swapper_buffer_unmap(ob->swapper);
+        _drm_swapper_swap(ob->swapper, rects, update_count);
+
+        eina_array_clean(&ob->onebuf_regions);
+
+        img = ob->onebuf;
+        ob->_onebuf_ = NULL;
+
+        if (img) evas_cache_image_drop(&img->cache_entry);
+     }
+   else
+     {
+        /* get count of updates */
+        update_count = eina_list_count(ob->update_regions);
+        if (update_count == 0) return;
+
+        /* allocate space for rectangles */
+        rects = alloca(update_count * sizeof(Eina_Rectangle));
+        if (!rects) return;
+
+        /* loop updates */
+        EINA_LIST_FREE(ob->update_regions, img)
+          {
+             Eina_Rectangle *rect;
+             int x = 0, y = 0, w = 0, h = 0;
+
+             rect = img->extended_info;
+             if (!rect) continue;
+
+             x = rect->x; y = rect->y; w = rect->w; h = rect->h;
+
+             /* based on rotation, set rectangle position */
+             if (ob->info->rotation == 0)
+               {
+                  rects[i].x = x;
+                  rects[i].y = y;
+               }
+             else if (ob->info->rotation == 90)
+               {
+                  rects[i].x = y;
+                  rects[i].y = (ob->w - x - w);
+               }
+             else if (ob->info->rotation == 180)
+               {
+                  rects[i].x = (ob->w - x - w);
+                  rects[i].y = (ob->h - y - h);
+               }
+             else if (ob->info->rotation == 270)
+               {
+                  rects[i].x = (ob->h - y - h);
+                  rects[i].y = x;
+               }
+
+             /* based on rotation, set rectangle size */
+             if ((ob->info->rotation == 0) || (ob->info->rotation == 180))
+               {
+                  rects[i].w = w;
+                  rects[i].h = h;
+               }
+             else if ((ob->info->rotation == 90) || (ob->info->rotation == 270))
+               {
+                  rects[i].w = h;
+                  rects[i].h = w;
+               }
+
+             eina_rectangle_free(rect);
+             evas_cache_image_drop(&img->cache_entry);
+             i++;
+          }
+
+        _drm_swapper_buffer_unmap(ob->swapper);
+        _drm_swapper_swap(ob->swapper, rects, update_count);
+     }
+}
diff --git a/src/modules/evas/engines/drm/meson.build b/src/modules/evas/engines/drm/meson.build
index a75732a1b1..1edf7b266e 100644
--- a/src/modules/evas/engines/drm/meson.build
+++ b/src/modules/evas/engines/drm/meson.build
@@ -2,9 +2,15 @@ engine_src = files([
   'Evas_Engine_Drm.h',
   'evas_engine.c',
   'evas_engine.h',
-  'evas_outbuf.c'
+  'evas_outbuf.c',
+  'evas_drm_swapper.c'
 ])
 
+evas_include_directories += include_directories('.')
+
+install_headers('Evas_Engine_Drm.h',
+  install_dir : join_paths(dir_include, 'evas-'+version_major),
+)
 engine_deps += [ecore_drm2, libdrm]
 
 shared_module(mod_full_name, engine_src,

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to