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 3d2294b277b1a21d5731efa5945bf8071063f3ab
Author: Christopher Michael <devilho...@comcast.net>
AuthorDate: Sun Aug 21 11:13:59 2022 -0400

    ecore-drm2: Add support to fill Atomic Modesetting state
---
 src/lib/ecore_drm2/ecore_drm2_atomic.c | 442 +++++++++++++++++++++++++++++++++
 src/lib/ecore_drm2/ecore_drm2_device.c |  25 +-
 src/lib/ecore_drm2/meson.build         |   1 +
 3 files changed, 463 insertions(+), 5 deletions(-)

diff --git a/src/lib/ecore_drm2/ecore_drm2_atomic.c b/src/lib/ecore_drm2/ecore_drm2_atomic.c
new file mode 100644
index 0000000000..d931ab869c
--- /dev/null
+++ b/src/lib/ecore_drm2/ecore_drm2_atomic.c
@@ -0,0 +1,442 @@
+#include "ecore_drm2_private.h"
+
+static Eina_Bool
+_ecore_drm2_atomic_state_crtc_fill(Ecore_Drm2_Crtc_State *cstate, int fd)
+{
+   drmModeObjectPropertiesPtr oprops;
+   unsigned int i = 0;
+
+   DBG("Atomic State Crtc Fill");
+
+   /* try to get crtc object properties */
+   oprops =
+     sym_drmModeObjectGetProperties(fd, cstate->obj_id, DRM_MODE_OBJECT_CRTC);
+   if (!oprops) return EINA_FALSE;
+
+   DBG("\tCrtc %d", cstate->obj_id);
+
+   for (; i < oprops->count_props; i++)
+     {
+        drmModePropertyPtr prop;
+
+        /* try to get this property */
+        prop = sym_drmModeGetProperty(fd, oprops->props[i]);
+        if (!prop) continue;
+
+        DBG("\t\tProperty: %s %d", prop->name, i);
+
+        /* find the properties we are interested in and fill in crtc state */
+        if (!strcmp(prop->name, "MODE_ID"))
+          {
+             drmModePropertyBlobPtr bp;
+
+             cstate->mode.id = prop->prop_id;
+             cstate->mode.value = oprops->prop_values[i];
+
+             DBG("\t\t\tValue: %d", cstate->mode.value);
+
+             if (!cstate->mode.value)
+               {
+                  cstate->mode.len = 0;
+                  goto cont;
+               }
+
+             bp = sym_drmModeGetPropertyBlob(fd, cstate->mode.value);
+             if (!bp) goto cont;
+
+             if ((!cstate->mode.data) ||
+                 memcmp(cstate->mode.data, bp->data, bp->length) != 0)
+               cstate->mode.data = "" bp->length, 1);
+
+             cstate->mode.len = bp->length;
+
+             if (cstate->mode.value != 0)
+               sym_drmModeCreatePropertyBlob(fd, bp->data, bp->length,
+                                             &cstate->mode.value);
+
+             sym_drmModeFreePropertyBlob(bp);
+          }
+        else if (!strcmp(prop->name, "ACTIVE"))
+          {
+             cstate->active.id = prop->prop_id;
+             cstate->active.value = oprops->prop_values[i];
+             DBG("\t\t\tValue: %lu", (long)cstate->active.value);
+          }
+        /* else if (!strcmp(prop->name, "BACKGROUND_COLOR")) */
+        /*   { */
+        /*      cstate->background.id = prop->prop_id; */
+        /*      cstate->background.value = oprops->prop_values[i]; */
+        /*   } */
+
+cont:
+        sym_drmModeFreeProperty(prop);
+     }
+
+   /* free crtc object properties */
+   sym_drmModeFreeObjectProperties(oprops);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_ecore_drm2_atomic_state_connector_fill(Ecore_Drm2_Connector_State *cstate, int fd)
+{
+   drmModeObjectPropertiesPtr oprops;
+   unsigned int i = 0;
+
+   DBG("Atomic State Connector Fill");
+
+   /* try to get connector object properties */
+   oprops =
+     sym_drmModeObjectGetProperties(fd, cstate->obj_id,
+                                    DRM_MODE_OBJECT_CONNECTOR);
+   if (!oprops) return EINA_FALSE;
+
+   DBG("\tConnector %d", cstate->obj_id);
+
+   for (; i < oprops->count_props; i++)
+     {
+        drmModePropertyPtr prop;
+
+        /* try to get this property */
+        prop = sym_drmModeGetProperty(fd, oprops->props[i]);
+        if (!prop) continue;
+
+        DBG("\t\tProperty: %s %d", prop->name, i);
+
+        /* find the properties we are interested in and fill in conn state */
+
+        if (!strcmp(prop->name, "CRTC_ID"))
+          {
+             cstate->crtc.id = prop->prop_id;
+             cstate->crtc.value = oprops->prop_values[i];
+             DBG("\t\t\tValue: %lu", (long)cstate->crtc.value);
+          }
+        else if (!strcmp(prop->name, "DPMS"))
+          {
+             cstate->dpms.id = prop->prop_id;
+             cstate->dpms.value = oprops->prop_values[i];
+             DBG("\t\t\tValue: %lu", (long)cstate->dpms.value);
+          }
+        else if (!strcmp(prop->name, "aspect ratio"))
+          {
+             cstate->aspect.id = prop->prop_id;
+             cstate->aspect.value = oprops->prop_values[i];
+             DBG("\t\t\tValue: %lu", (long)cstate->aspect.value);
+          }
+        else if (!strcmp(prop->name, "scaling mode"))
+          {
+             cstate->scaling.id = prop->prop_id;
+             cstate->scaling.value = oprops->prop_values[i];
+             DBG("\t\t\tValue: %lu", (long)cstate->scaling.value);
+          }
+        else if (!strcmp(prop->name, "EDID"))
+          {
+             drmModePropertyBlobPtr bp;
+
+             cstate->edid.id = oprops->prop_values[i];
+             if (!cstate->edid.id)
+               {
+                  cstate->edid.len = 0;
+                  goto cont;
+               }
+
+             bp = sym_drmModeGetPropertyBlob(fd, cstate->edid.id);
+             if (!bp) goto cont;
+
+             if ((!cstate->edid.data) ||
+                 memcmp(cstate->edid.data, bp->data, bp->length) != 0)
+               {
+                  cstate->edid.data =
"">+                    eina_memdup(bp->data, bp->length, 1);
+               }
+
+             cstate->edid.len = bp->length;
+
+             if (cstate->edid.id != 0)
+               sym_drmModeCreatePropertyBlob(fd, bp->data, bp->length,
+                                         &cstate->edid.id);
+
+             sym_drmModeFreePropertyBlob(bp);
+          }
+cont:
+        sym_drmModeFreeProperty(prop);
+     }
+
+   /* free crtc object properties */
+   sym_drmModeFreeObjectProperties(oprops);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_ecore_drm2_atomic_state_plane_fill(Ecore_Drm2_Plane_State *pstate, int fd)
+{
+   drmModeObjectPropertiesPtr oprops;
+   unsigned int i = 0;
+
+   DBG("Atomic State Plane Fill");
+
+   /* try to get plane object properties */
+   oprops =
+     sym_drmModeObjectGetProperties(fd, pstate->obj_id, DRM_MODE_OBJECT_PLANE);
+   if (!oprops) return EINA_FALSE;
+
+   DBG("\tPlane %d", pstate->obj_id);
+
+   for (; i < oprops->count_props; i++)
+     {
+        drmModePropertyPtr prop;
+
+        /* try to get this property */
+        prop = sym_drmModeGetProperty(fd, oprops->props[i]);
+        if (!prop) continue;
+
+        DBG("\t\tProperty: %s %d", prop->name, i);
+
+        /* find the properties we are interested in and fill in plane state */
+        if (!strcmp(prop->name, "CRTC_ID"))
+          {
+             pstate->cid.id = prop->prop_id;
+             pstate->cid.value = oprops->prop_values[i];
+             DBG("\t\t\tValue: %lu", (long)pstate->cid.value);
+          }
+        else if (!strcmp(prop->name, "FB_ID"))
+          {
+             pstate->fid.id = prop->prop_id;
+             pstate->fid.value = oprops->prop_values[i];
+             DBG("\t\t\tValue: %lu", (long)pstate->fid.value);
+          }
+        else if (!strcmp(prop->name, "CRTC_X"))
+          {
+             pstate->cx.id = prop->prop_id;
+             pstate->cx.value = oprops->prop_values[i];
+          }
+        else if (!strcmp(prop->name, "CRTC_Y"))
+          {
+             pstate->cy.id = prop->prop_id;
+             pstate->cy.value = oprops->prop_values[i];
+          }
+        else if (!strcmp(prop->name, "CRTC_W"))
+          {
+             pstate->cw.id = prop->prop_id;
+             pstate->cw.value = oprops->prop_values[i];
+          }
+        else if (!strcmp(prop->name, "CRTC_H"))
+          {
+             pstate->ch.id = prop->prop_id;
+             pstate->ch.value = oprops->prop_values[i];
+          }
+        else if (!strcmp(prop->name, "SRC_X"))
+          {
+             pstate->sx.id = prop->prop_id;
+             pstate->sx.value = oprops->prop_values[i];
+          }
+        else if (!strcmp(prop->name, "SRC_Y"))
+          {
+             pstate->sy.id = prop->prop_id;
+             pstate->sy.value = oprops->prop_values[i];
+          }
+        else if (!strcmp(prop->name, "SRC_W"))
+          {
+             pstate->sw.id = prop->prop_id;
+             pstate->sw.value = oprops->prop_values[i];
+          }
+        else if (!strcmp(prop->name, "SRC_H"))
+          {
+             pstate->sh.id = prop->prop_id;
+             pstate->sh.value = oprops->prop_values[i];
+          }
+        else if (!strcmp(prop->name, "type"))
+          {
+             pstate->type.id = prop->prop_id;
+             pstate->type.value = oprops->prop_values[i];
+             switch (pstate->type.value)
+               {
+                case DRM_PLANE_TYPE_OVERLAY:
+                  DBG("\t\t\tOverlay Plane");
+                  break;
+                case DRM_PLANE_TYPE_PRIMARY:
+                  DBG("\t\t\tPrimary Plane");
+                  break;
+                case DRM_PLANE_TYPE_CURSOR:
+                  DBG("\t\t\tCursor Plane");
+                  break;
+                default:
+                  DBG("\t\t\tValue: %lu", (long)pstate->type.value);
+                  break;
+               }
+          }
+        else if (!strcmp(prop->name, "rotation"))
+          {
+             int k = 0;
+
+             pstate->rotation.id = prop->prop_id;
+             pstate->rotation.value = oprops->prop_values[i];
+
+             for (k = 0; k < prop->count_enums; k++)
+               {
+                  int r = -1;
+
+                  DBG("\t\t\tRotation: %s", prop->enums[k].name);
+                  if (!strcmp(prop->enums[k].name, "rotate-0"))
+                    r = ECORE_DRM2_ROTATION_NORMAL;
+                  else if (!strcmp(prop->enums[k].name, "rotate-90"))
+                    r = ECORE_DRM2_ROTATION_90;
+                  else if (!strcmp(prop->enums[k].name, "rotate-180"))
+                    r = ECORE_DRM2_ROTATION_180;
+                  else if (!strcmp(prop->enums[k].name, "rotate-270"))
+                    r = ECORE_DRM2_ROTATION_270;
+                  else if (!strcmp(prop->enums[k].name, "reflect-x"))
+                    r = ECORE_DRM2_ROTATION_REFLECT_X;
+                  else if (!strcmp(prop->enums[k].name, "reflect-y"))
+                    r = ECORE_DRM2_ROTATION_REFLECT_Y;
+
+                  if (r != -1)
+                    {
+                       pstate->supported_rotations |= r;
+                       pstate->rotation_map[ffs(r)] =
+                         1ULL << prop->enums[k].value;
+                    }
+               }
+          }
+
+        sym_drmModeFreeProperty(prop);
+     }
+
+   /* free plane object properties */
+   sym_drmModeFreeObjectProperties(oprops);
+
+   return EINA_TRUE;
+}
+
+Eina_Bool
+_ecore_drm2_atomic_state_fill(Ecore_Drm2_Atomic_State *state, int fd)
+{
+   int i = 0;
+   drmModeResPtr res;
+   drmModePlaneResPtr pres;
+
+   /* try to get drm resources */
+   res = sym_drmModeGetResources(fd);
+   if (!res) return EINA_FALSE;
+
+   state->crtcs = res->count_crtcs;
+
+   /* try to allocate space for crtc states */
+   state->crtc_states = calloc(state->crtcs, sizeof(Ecore_Drm2_Crtc_State));
+   if (!state->crtc_states)
+     {
+        ERR("Could not allocate space for CRTC states");
+        goto crtc_err;
+     }
+
+   /* try to fill atomic state for each crtc */
+   for (i = 0; i < state->crtcs; i++)
+     {
+        Ecore_Drm2_Crtc_State *cstate;
+
+        cstate = &state->crtc_states[i];
+        cstate->obj_id = res->crtcs[i];
+        cstate->index = i;
+
+        /* try fill atomic state for this crtc */
+        if (!_ecore_drm2_atomic_state_crtc_fill(cstate, fd))
+          {
+             WRN("Failed to fill atomic crtc state for CRTC %d",
+                 cstate->obj_id);
+             continue;
+          }
+     }
+
+   /* try to allocate space for connector states */
+   state->conns = res->count_connectors;
+   state->conn_states = calloc(state->conns, sizeof(Ecore_Drm2_Connector_State));
+   if (!state->conn_states)
+     {
+        ERR("Could not allocate space for CONN states");
+        goto conn_err;
+     }
+
+   /* try to fill atomic state for each connector */
+   for (i = 0; i < state->conns; i++)
+     {
+        Ecore_Drm2_Connector_State *cstate;
+
+        cstate = &state->conn_states[i];
+        cstate->obj_id = res->connectors[i];
+
+        /* try to fill atomic state for this connector */
+        if (!_ecore_drm2_atomic_state_connector_fill(cstate, fd))
+          {
+             WRN("Failed to fill atomic connector state for CONN %d",
+                 cstate->obj_id);
+             continue;
+          }
+     }
+
+   /* try to get plane resources */
+   pres = sym_drmModeGetPlaneResources(fd);
+   if (!pres) goto plane_res_err;
+
+   /* try to allocate space for plane states */
+   state->planes = pres->count_planes;
+   state->plane_states = calloc(state->planes, sizeof(Ecore_Drm2_Plane_State));
+   if (!state->plane_states)
+     {
+        ERR("Could not allocate space for PLANE states");
+        goto plane_err;
+     }
+
+   /* try to fill atomic state for each plane */
+   for (i = 0; i < state->planes; i++)
+     {
+        unsigned int f = 0;
+        drmModePlanePtr plane;
+        Ecore_Drm2_Plane_State *pstate;
+
+        /* try to get this plane */
+        plane = sym_drmModeGetPlane(fd, pres->planes[i]);
+        if (!plane) continue;
+
+        pstate = &state->plane_states[i];
+
+        pstate->obj_id = pres->planes[i];
+        pstate->mask = plane->possible_crtcs;
+
+        /* try to get the formats supported on this plane */
+        pstate->num_formats = plane->count_formats;
+        pstate->formats = calloc(plane->count_formats, sizeof(uint32_t));
+        for (; f < plane->count_formats; f++)
+          pstate->formats[f] = plane->formats[f];
+
+        /* free drm plane */
+        sym_drmModeFreePlane(plane);
+
+        /* try to fill atomic state for this plane */
+        if (!_ecore_drm2_atomic_state_plane_fill(pstate, fd))
+          {
+             WRN("Failed to fill atomic plane state for PLANE %d",
+                 pstate->obj_id);
+             continue;
+          }
+     }
+
+   /* free drm plane resources */
+   sym_drmModeFreePlaneResources(pres);
+
+   /* free drm resources */
+   sym_drmModeFreeResources(res);
+
+   return EINA_TRUE;
+
+plane_err:
+   sym_drmModeFreePlaneResources(pres);
+plane_res_err:
+   free(state->conn_states);
+conn_err:
+   free(state->crtc_states);
+crtc_err:
+   sym_drmModeFreeResources(res);
+   return EINA_FALSE;
+}
diff --git a/src/lib/ecore_drm2/ecore_drm2_device.c b/src/lib/ecore_drm2/ecore_drm2_device.c
index b4e6edbfcd..279bb68b23 100644
--- a/src/lib/ecore_drm2/ecore_drm2_device.c
+++ b/src/lib/ecore_drm2/ecore_drm2_device.c
@@ -115,7 +115,7 @@ ecore_drm2_device_open(const char *seat, unsigned int tty)
    const char *path;
    Ecore_Drm2_Device *dev;
 
-   /* try to allocate space for return structure */
+   /* try to allocate space for device structure */
    dev = calloc(1, sizeof(Ecore_Drm2_Device));
    if (!dev) return NULL;
 
@@ -143,6 +143,8 @@ ecore_drm2_device_open(const char *seat, unsigned int tty)
         goto open_err;
      }
 
+   DBG("Opened DRM Device: %s", path);
+
    /* try to enable elput input */
    if (!elput_input_init(dev->em))
      {
@@ -150,7 +152,7 @@ ecore_drm2_device_open(const char *seat, unsigned int tty)
         goto input_err;
      }
 
-   /* NB: For now, we will ONLY support Atomic */
+   /* test if this device can do Atomic Modesetting */
    _ecore_drm2_atomic_use = _ecore_drm2_device_atomic_capable_get(dev->fd);
    if (!_ecore_drm2_atomic_use)
      {
@@ -158,17 +160,30 @@ ecore_drm2_device_open(const char *seat, unsigned int tty)
         goto atomic_err;
      }
 
-   /* TODO: Fill atomic state */
+   /* try to allocate space for Atomic State */
+   dev->atomic_state = calloc(1, sizeof(Ecore_Drm2_Atomic_State));
+   if (!dev->atomic_state)
+     {
+        ERR("Failed to allocate device atomic state");
+        goto atomic_err;
+     }
+
+   /* try to fill atomic state */
+   if (!_ecore_drm2_atomic_state_fill(dev->atomic_state, dev->fd))
+     {
+        ERR("Failed to fill Atomic State");
+        goto atomic_fill_err;
+     }
 
    /* TODO: event handlers for session_active & device_change */
 
-   DBG("Opened DRM Device: %s", path);
-
    /* cleanup path variable */
    eina_stringshare_del(path);
 
    return dev;
 
+atomic_fill_err:
+   free(dev->atomic_state);
 atomic_err:
    elput_input_shutdown(dev->em);
 input_err:
diff --git a/src/lib/ecore_drm2/meson.build b/src/lib/ecore_drm2/meson.build
index 7ebe1cda76..dc672dc4ba 100644
--- a/src/lib/ecore_drm2/meson.build
+++ b/src/lib/ecore_drm2/meson.build
@@ -7,6 +7,7 @@ ecore_drm2_header_src = [
 ]
 
 ecore_drm2_src = files([
+  'ecore_drm2_atomic.c',
   'ecore_drm2_device.c',
   'ecore_drm2.c',
   'ecore_drm2_private.h'

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

Reply via email to