summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2015-03-04 10:07:19 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2015-04-14 15:58:26 +0100
commit5ed5fa10600f0140b317ec07be6f24739c11bd18 (patch)
treed535444f960512bf8eb809f0359b8abcaa7a4080
parent6f90b77ea903756c87ae614c093e3d816ebb26fc (diff)
mode: Retrieve only the current information for a Connector
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. v4: Avoid probing on the second calls to GETCONNECTOR for unconnected outputs. 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> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--tests/modeprint/modeprint.c18
-rw-r--r--xf86drmMode.c23
-rw-r--r--xf86drmMode.h17
3 files changed, 51 insertions, 7 deletions
diff --git a/tests/modeprint/modeprint.c b/tests/modeprint/modeprint.c
index de59cbd1..e6c6553b 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 @@ static 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 @@ static int printRes(int fd, drmModeResPtr res)
static void args(int argc, char **argv)
{
+ int defaults = 1;
int i;
fbs = 0;
@@ -341,32 +343,41 @@ static 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 @@ static 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 61d5e012..1333da48 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) {
@@ -504,6 +508,9 @@ retry:
conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo)));
if (!conn.modes_ptr)
goto err_allocs;
+ } else {
+ conn.count_modes = 1;
+ conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct drm_mode_modeinfo)));
}
if (conn.count_encoders) {
@@ -572,6 +579,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 2d30184e..20c3f153 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.