diff mbox

[v3] mode: Retrieve only the current information for a Connector

Message ID 1425474095-5847-1-git-send-email-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Chris Wilson March 4, 2015, 1:01 p.m. UTC
Add a new API that allows the caller to skip any forced probing, which
may require slow i2c to a remote display, and only report the currently
active mode and encoder for a Connector. This is often the information
of interest and is much, much faster than re-retrieving the link status
and EDIDs, e.g. if the caller only wishes to count the number of active
outputs.

v2: Fix error path to avoid double free after a failed GETCONNECTOR
ioctl.

v3: Daniel strongly disapproved of my disjoint in behaviour between
GetConnector and GetConnectorCurrent, and considering how best to make a
drop in replacement for drmmode_output_init() convinced me keeping the
API as consistent as possible was the right approach.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.com>
Cc: Damien Lespiau <damien.lespiau@intel.com>
Cc: David Herrmann <dh.herrmann@googlemail.com>
---
 tests/modeprint/modeprint.c | 18 ++++++++++++++++--
 xf86drmMode.c               | 20 +++++++++++++++++---
 xf86drmMode.h               | 17 +++++++++++++++--
 3 files changed, 48 insertions(+), 7 deletions(-)
diff mbox

Patch

diff --git a/tests/modeprint/modeprint.c b/tests/modeprint/modeprint.c
index 6f0d039..514d3ba 100644
--- a/tests/modeprint/modeprint.c
+++ b/tests/modeprint/modeprint.c
@@ -43,6 +43,7 @@ 
 
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 
+int current;
 int connectors;
 int full_props;
 int edid;
@@ -272,7 +273,7 @@  int printRes(int fd, drmModeResPtr res)
 
 	if (connectors) {
 		for (i = 0; i < res->count_connectors; i++) {
-			connector = drmModeGetConnector(fd, res->connectors[i]);
+			connector = (current ? drmModeGetConnectorCurrent : drmModeGetConnector) (fd, res->connectors[i]);
 
 			if (!connector)
 				printf("Could not get connector %i\n", res->connectors[i]);
@@ -331,6 +332,7 @@  int printRes(int fd, drmModeResPtr res)
 
 void args(int argc, char **argv)
 {
+	int defaults = 1;
 	int i;
 
 	fbs = 0;
@@ -341,32 +343,41 @@  void args(int argc, char **argv)
 	full_modes = 0;
 	full_props = 0;
 	connectors = 0;
+	current = 0;
 
 	module_name = argv[1];
 
 	for (i = 2; i < argc; i++) {
 		if (strcmp(argv[i], "-fb") == 0) {
 			fbs = 1;
+			defaults = 0;
 		} else if (strcmp(argv[i], "-crtcs") == 0) {
 			crtcs = 1;
+			defaults = 0;
 		} else if (strcmp(argv[i], "-cons") == 0) {
 			connectors = 1;
 			modes = 1;
+			defaults = 0;
 		} else if (strcmp(argv[i], "-modes") == 0) {
 			connectors = 1;
 			modes = 1;
+			defaults = 0;
 		} else if (strcmp(argv[i], "-full") == 0) {
 			connectors = 1;
 			modes = 1;
 			full_modes = 1;
+			defaults = 0;
 		} else if (strcmp(argv[i], "-props") == 0) {
 			connectors = 1;
 			full_props = 1;
+			defaults = 0;
 		} else if (strcmp(argv[i], "-edids") == 0) {
 			connectors = 1;
 			edid = 1;
+			defaults = 0;
 		} else if (strcmp(argv[i], "-encoders") == 0) {
 			encoders = 1;
+			defaults = 0;
 		} else if (strcmp(argv[i], "-v") == 0) {
 			fbs = 1;
 			edid = 1;
@@ -376,10 +387,13 @@  void args(int argc, char **argv)
 			full_modes = 1;
 			full_props = 1;
 			connectors = 1;
+			defaults = 0;
+		} else if (strcmp(argv[i], "-current") == 0) {
+			current = 1;
 		}
 	}
 
-	if (argc == 2) {
+	if (defaults) {
 		fbs = 1;
 		edid = 1;
 		crtcs = 1;
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 9ea8fe7..138f1bf 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -476,19 +476,23 @@  drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
 /*
  * Connector manipulation
  */
-
-drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
+static drmModeConnectorPtr
+_drmModeGetConnector(int fd, uint32_t connector_id, int probe)
 {
 	struct drm_mode_get_connector conn, counts;
 	drmModeConnectorPtr r = NULL;
 
-retry:
 	memclear(conn);
 	conn.connector_id = connector_id;
+	if (!probe) {
+		conn.count_modes = 1;
+		conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct drm_mode_modeinfo)));
+	}
 
 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
 		return 0;
 
+retry:
 	counts = conn;
 
 	if (conn.count_props) {
@@ -572,6 +576,16 @@  err_allocs:
 	return r;
 }
 
+drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
+{
+	return _drmModeGetConnector(fd, connector_id, 1);
+}
+
+drmModeConnectorPtr drmModeGetConnectorCurrent(int fd, uint32_t connector_id)
+{
+	return _drmModeGetConnector(fd, connector_id, 0);
+}
+
 int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
 {
 	struct drm_mode_mode_cmd res;
diff --git a/xf86drmMode.h b/xf86drmMode.h
index 856a6bb..278da48 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -422,10 +422,23 @@  drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id);
  */
 
 /**
- * Retrive information about the connector connectorId.
+ * Retrieve all information about the connector connectorId. This will do a
+ * forced probe on the connector to retrieve remote information such as EDIDs
+ * from the display device.
  */
 extern drmModeConnectorPtr drmModeGetConnector(int fd,
-		uint32_t connectorId);
+					       uint32_t connectorId);
+
+/**
+ * Retrieve current information, i.e the currently active mode and encoder,
+ * about the connector connectorId. This will not do any probing on the
+ * connector or remote device, and only reports what is currently known.
+ * For the complete set of modes and encoders associated with the connector
+ * use drmModeGetConnector() which will do a probe to determine any display
+ * link changes first.
+ */
+extern drmModeConnectorPtr drmModeGetConnectorCurrent(int fd,
+						      uint32_t connector_id);
 
 /**
  * Attaches the given mode to an connector.