From f18723d489a68ae6b217deb99ab872022e375388 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 1 Sep 2021 13:23:12 +0200 Subject: [PATCH] drm: compute per-connector CRTC mask --- src/drm.cpp | 41 ++++++++++++++++++++--------------------- src/drm.hpp | 1 + 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/drm.cpp b/src/drm.cpp index e510e47..30d2cda 100644 --- a/src/drm.cpp +++ b/src/drm.cpp @@ -67,35 +67,33 @@ static std::map< uint32_t, const char * > connector_types = { #endif }; -static struct crtc *find_crtc_for_encoder(struct drm_t *drm, const drmModeEncoder *encoder) { - for (size_t i = 0; i < drm->crtcs.size(); i++) { - /* possible_crtcs is a bitmask as described here: - * https://dvdhrm.wordpress.com/2012/09/13/linux-drm-mode-setting-api - */ - uint32_t crtc_mask = 1 << i; - if (encoder->possible_crtcs & crtc_mask) - return &drm->crtcs[i]; - } +static uint32_t get_connector_possible_crtcs(struct drm_t *drm, const drmModeConnector *connector) { + uint32_t possible_crtcs = 0; - /* no match found */ - return nullptr; -} - -static struct crtc *find_crtc_for_connector(struct drm_t *drm, const drmModeConnector *connector) { for (int i = 0; i < connector->count_encoders; i++) { uint32_t encoder_id = connector->encoders[i]; drmModeEncoder *encoder = drmModeGetEncoder(drm->fd, encoder_id); - if (encoder == nullptr) + if (encoder == nullptr) { + drm_log.errorf_errno("drmModeGetEncoder failed"); continue; + } + + possible_crtcs |= encoder->possible_crtcs; - struct crtc *crtc = find_crtc_for_encoder(drm, encoder); drmModeFreeEncoder(encoder); - if (crtc != nullptr) - return crtc; } - /* no match found */ + return possible_crtcs; +} + +static struct crtc *find_crtc_for_connector(struct drm_t *drm, const struct connector *connector) { + for (size_t i = 0; i < drm->crtcs.size(); i++) { + uint32_t crtc_mask = 1 << i; + if (connector->possible_crtcs & crtc_mask) + return &drm->crtcs[i]; + } + return nullptr; } @@ -307,7 +305,6 @@ static bool refresh_state( drm_t *drm ) for (size_t i = 0; i < drm->connectors.size(); i++) { struct connector *conn = &drm->connectors[i]; - // TODO: refresh connector status and mode list if (!get_object_properties(drm, conn->id, DRM_MODE_OBJECT_CONNECTOR, conn->props, conn->initial_prop_values)) { return false; } @@ -406,6 +403,8 @@ static bool get_resources(struct drm_t *drm) snprintf(name, sizeof(name), "%s-%d", type_str, conn->connector->connector_type_id); conn->name = strdup(name); + + conn->possible_crtcs = get_connector_possible_crtcs(drm, conn->connector); } for (size_t i = 0; i < drm->crtcs.size(); i++) { @@ -1118,7 +1117,7 @@ bool drm_set_connector( struct drm_t *drm, struct connector *conn ) { drm_log.infof("selecting connector %s", conn->name); - struct crtc *crtc = find_crtc_for_connector(drm, conn->connector); + struct crtc *crtc = find_crtc_for_connector(drm, conn); if (crtc == nullptr) { drm_log.errorf("no CRTC found!"); return false; diff --git a/src/drm.hpp b/src/drm.hpp index 8a4fed6..4d4698b 100644 --- a/src/drm.hpp +++ b/src/drm.hpp @@ -45,6 +45,7 @@ struct connector { uint32_t id; char *name; drmModeConnector *connector; + uint32_t possible_crtcs; std::map props; std::map initial_prop_values; };