drm-backend: cache drmModeObjectProperties for connectors

Instead of calling drmModeObjectGetProperties() each time that we need
the connector properties, it is better to keep a reference for it in
struct drm_connector. This reference is only updated when is necessary.
E.g. hotplug events.

Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
dev
Leandro Ribeiro 4 years ago committed by Pekka Paalanen
parent e636990de3
commit 702fbf7282
  1. 5
      libweston/backend-drm/drm-internal.h
  2. 57
      libweston/backend-drm/drm.c
  3. 4
      libweston/backend-drm/modes.c

@ -473,6 +473,8 @@ struct drm_connector {
drmModeConnector *conn; drmModeConnector *conn;
uint32_t connector_id; uint32_t connector_id;
drmModeObjectProperties *props_drm;
/* Holds the properties for the connector */ /* Holds the properties for the connector */
struct drm_property_info props[WDRM_CONNECTOR__COUNT]; struct drm_property_info props[WDRM_CONNECTOR__COUNT];
}; };
@ -622,8 +624,7 @@ struct drm_mode *
drm_output_choose_mode(struct drm_output *output, drm_output_choose_mode(struct drm_output *output,
struct weston_mode *target_mode); struct weston_mode *target_mode);
void void
update_head_from_connector(struct drm_head *head, update_head_from_connector(struct drm_head *head);
drmModeObjectProperties *props);
void void
drm_mode_list_destroy(struct drm_backend *backend, struct wl_list *mode_list); drm_mode_list_destroy(struct drm_backend *backend, struct wl_list *mode_list);

@ -1948,13 +1948,12 @@ get_weston_protection_from_drm(enum wdrm_content_protection_state protection,
* Get current content-protection status for a given head. * Get current content-protection status for a given head.
* *
* @param head drm_head, whose protection is to be retrieved * @param head drm_head, whose protection is to be retrieved
* @param props drm property object of the connector, related to the head
* @return protection status in case of success, -1 otherwise * @return protection status in case of success, -1 otherwise
*/ */
static enum weston_hdcp_protection static enum weston_hdcp_protection
drm_head_get_current_protection(struct drm_head *head, drm_head_get_current_protection(struct drm_head *head)
drmModeObjectProperties *props)
{ {
drmModeObjectProperties *props = head->connector.props_drm;
struct drm_property_info *info; struct drm_property_info *info;
enum wdrm_content_protection_state protection; enum wdrm_content_protection_state protection;
enum wdrm_hdcp_content_type type; enum wdrm_hdcp_content_type type;
@ -1991,6 +1990,26 @@ drm_head_get_current_protection(struct drm_head *head,
return weston_hdcp; return weston_hdcp;
} }
static int
drm_connector_update_properties(struct drm_connector *connector)
{
drmModeObjectProperties *props;
props = drmModeObjectGetProperties(connector->backend->drm.fd,
connector->connector_id,
DRM_MODE_OBJECT_CONNECTOR);
if (!props) {
weston_log("Error: failed to get connector properties\n");
return -1;
}
if (connector->props_drm)
drmModeFreeObjectProperties(connector->props_drm);
connector->props_drm = props;
return 0;
}
/** Replace connector data and monitor information /** Replace connector data and monitor information
* *
* @param connector The drm_connector object to be updated. * @param connector The drm_connector object to be updated.
@ -2006,17 +2025,10 @@ static int
drm_connector_assign_connector_info(struct drm_connector *connector, drm_connector_assign_connector_info(struct drm_connector *connector,
drmModeConnector *conn) drmModeConnector *conn)
{ {
drmModeObjectProperties *props;
assert(connector->connector_id == conn->connector_id); assert(connector->connector_id == conn->connector_id);
props = drmModeObjectGetProperties(connector->backend->drm.fd, if (drm_connector_update_properties(connector) < 0)
connector->connector_id,
DRM_MODE_OBJECT_CONNECTOR);
if (!props) {
weston_log("Error: failed to get connector properties\n");
return -1; return -1;
}
if (connector->conn && connector->conn != conn) if (connector->conn && connector->conn != conn)
drmModeFreeConnector(connector->conn); drmModeFreeConnector(connector->conn);
@ -2025,16 +2037,14 @@ drm_connector_assign_connector_info(struct drm_connector *connector,
drm_property_info_free(connector->props, WDRM_CONNECTOR__COUNT); drm_property_info_free(connector->props, WDRM_CONNECTOR__COUNT);
drm_property_info_populate(connector->backend, connector_props, drm_property_info_populate(connector->backend, connector_props,
connector->props, connector->props,
WDRM_CONNECTOR__COUNT, props); WDRM_CONNECTOR__COUNT, connector->props_drm);
if (connector->head != NULL) { if (connector->head != NULL) {
update_head_from_connector(connector->head, props); update_head_from_connector(connector->head);
weston_head_set_content_protection_status(&connector->head->base, weston_head_set_content_protection_status(&connector->head->base,
drm_head_get_current_protection(connector->head, props)); drm_head_get_current_protection(connector->head));
} }
drmModeFreeObjectProperties(props);
return 0; return 0;
} }
@ -2045,6 +2055,7 @@ drm_connector_init(struct drm_backend *b, struct drm_connector *connector,
connector->backend = b; connector->backend = b;
connector->connector_id = connector_id; connector->connector_id = connector_id;
connector->head = NULL; connector->head = NULL;
connector->props_drm = NULL;
connector->conn = drmModeGetConnector(b->drm.fd, connector_id); connector->conn = drmModeGetConnector(b->drm.fd, connector_id);
if (!connector->conn) { if (!connector->conn) {
@ -2059,6 +2070,7 @@ static void
drm_connector_fini(struct drm_connector *connector) drm_connector_fini(struct drm_connector *connector)
{ {
drmModeFreeConnector(connector->conn); drmModeFreeConnector(connector->conn);
drmModeFreeObjectProperties(connector->props_drm);
drm_property_info_free(connector->props, WDRM_CONNECTOR__COUNT); drm_property_info_free(connector->props, WDRM_CONNECTOR__COUNT);
} }
@ -2348,7 +2360,6 @@ drm_backend_update_conn_props(struct drm_backend *b,
{ {
struct drm_head *head; struct drm_head *head;
enum wdrm_connector_property conn_prop; enum wdrm_connector_property conn_prop;
drmModeObjectProperties *props;
head = drm_head_find_by_connector(b, connector_id); head = drm_head_find_by_connector(b, connector_id);
if (!head) { if (!head) {
@ -2361,19 +2372,13 @@ drm_backend_update_conn_props(struct drm_backend *b,
if (conn_prop >= WDRM_CONNECTOR__COUNT) if (conn_prop >= WDRM_CONNECTOR__COUNT)
return; return;
props = drmModeObjectGetProperties(b->drm.fd, if (drm_connector_update_properties(&head->connector) < 0)
connector_id,
DRM_MODE_OBJECT_CONNECTOR);
if (!props) {
weston_log("Error: failed to get connector '%s' properties\n",
head->base.name);
return; return;
}
if (conn_prop == WDRM_CONNECTOR_CONTENT_PROTECTION) { if (conn_prop == WDRM_CONNECTOR_CONTENT_PROTECTION) {
weston_head_set_content_protection_status(&head->base, weston_head_set_content_protection_status(&head->base,
drm_head_get_current_protection(head, props)); drm_head_get_current_protection(head));
} }
drmModeFreeObjectProperties(props);
} }
static int static int

@ -507,10 +507,10 @@ drm_output_choose_mode(struct drm_output *output,
} }
void void
update_head_from_connector(struct drm_head *head, update_head_from_connector(struct drm_head *head)
drmModeObjectProperties *props)
{ {
struct drm_connector *connector = &head->connector; struct drm_connector *connector = &head->connector;
drmModeObjectProperties *props = connector->props_drm;
drmModeConnector *conn = connector->conn; drmModeConnector *conn = connector->conn;
const char *make = "unknown"; const char *make = "unknown";
const char *model = "unknown"; const char *model = "unknown";

Loading…
Cancel
Save