From 0c0dd22b5f22d683e92aa3ddc454a882805ea636 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 11 May 2016 09:39:46 -0400 Subject: [PATCH] ecore-drm2: Add API function to get possible crtc of a given output Signed-off-by: Chris Michael --- src/lib/ecore_drm2/Ecore_Drm2.h | 16 ++++++ src/lib/ecore_drm2/ecore_drm2_outputs.c | 66 ++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/lib/ecore_drm2/Ecore_Drm2.h b/src/lib/ecore_drm2/Ecore_Drm2.h index 925a9466b9..f06fa409eb 100644 --- a/src/lib/ecore_drm2/Ecore_Drm2.h +++ b/src/lib/ecore_drm2/Ecore_Drm2.h @@ -579,6 +579,22 @@ EAPI unsigned int ecore_drm2_output_connector_type_get(Ecore_Drm2_Output *output */ EAPI void ecore_drm2_output_resolution_get(Ecore_Drm2_Output *output, int *w, int *h, unsigned int *refresh); +/** + * Get if an output can be used on a given crtc + * + * This function will loop the possible crtcs of an encoder to determine if + * a given output can be assigned to a given crtc + * + * @param output + * @param crtc + * + * @return EINA_TRUE if the output can be assigned to given crtc, EINA_FALSE otherwise + * + * @ingroup Ecore_Drm2_Output_Group + * @since 1.18 + */ +EAPI Eina_Bool ecore_drm2_output_possible_crtc_get(Ecore_Drm2_Output *output, unsigned int crtc); + /** * @defgroup Ecore_Drm2_Fb_Group Drm framebuffer functions * diff --git a/src/lib/ecore_drm2/ecore_drm2_outputs.c b/src/lib/ecore_drm2/ecore_drm2_outputs.c index b55c0d8417..1b9313f000 100644 --- a/src/lib/ecore_drm2/ecore_drm2_outputs.c +++ b/src/lib/ecore_drm2/ecore_drm2_outputs.c @@ -219,7 +219,7 @@ static int _output_crtc_find(const drmModeRes *res, const drmModeConnector *conn, Ecore_Drm2_Device *dev) { drmModeEncoder *enc; - uint32_t pcrtcs; + uint32_t crtc; int i = 0, j = 0; for (j = 0; j < conn->count_encoders; j++) @@ -227,15 +227,12 @@ _output_crtc_find(const drmModeRes *res, const drmModeConnector *conn, Ecore_Drm enc = drmModeGetEncoder(dev->fd, conn->encoders[j]); if (!enc) continue; - pcrtcs = enc->possible_crtcs; + crtc = enc->crtc_id; drmModeFreeEncoder(enc); for (i = 0; i < res->count_crtcs; i++) - { - if ((pcrtcs & (1 << i)) && - (!(dev->alloc.crtc & (1 << res->crtcs[i])))) - return i; - } + if (crtc == res->crtcs[i]) + return i; } return -1; @@ -1091,3 +1088,58 @@ ecore_drm2_output_resolution_get(Ecore_Drm2_Output *output, int *w, int *h, unsi if (h) *h = output->current_mode->height; if (refresh) *refresh = output->current_mode->refresh; } + +EAPI Eina_Bool +ecore_drm2_output_possible_crtc_get(Ecore_Drm2_Output *output, unsigned int crtc) +{ + drmModeRes *res; + drmModeConnector *conn; + drmModeEncoder *enc; + int i = 0, j = 0, k = 0; + unsigned int p = 0; + Eina_Bool ret = EINA_FALSE; + + EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE); + EINA_SAFETY_ON_TRUE_RETURN_VAL((output->fd < 0), EINA_FALSE); + + res = drmModeGetResources(output->fd); + if (!res) return EINA_FALSE; + + for (; i < res->count_connectors; i++) + { + conn = drmModeGetConnector(output->fd, res->connectors[i]); + if (!conn) continue; + + for (j = 0; j < conn->count_encoders; j++) + { + enc = drmModeGetEncoder(output->fd, conn->encoders[j]); + if (!enc) continue; + + if (enc->crtc_id != crtc) goto next; + + p = enc->possible_crtcs; + + for (k = 0; k < res->count_crtcs; k++) + { + if (res->crtcs[k] != output->crtc_id) continue; + + if (p & (1 << k)) + { + ret = EINA_TRUE; + break; + } + } + +next: + drmModeFreeEncoder(enc); + if (ret) break; + } + + drmModeFreeConnector(conn); + if (ret) break; + } + + drmModeFreeResources(res); + + return ret; +}