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>main
parent
6f90b77ea9
commit
5ed5fa1060
|
@ -43,6 +43,7 @@
|
||||||
|
|
||||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||||
|
|
||||||
|
int current;
|
||||||
int connectors;
|
int connectors;
|
||||||
int full_props;
|
int full_props;
|
||||||
int edid;
|
int edid;
|
||||||
|
@ -272,7 +273,7 @@ static int printRes(int fd, drmModeResPtr res)
|
||||||
|
|
||||||
if (connectors) {
|
if (connectors) {
|
||||||
for (i = 0; i < res->count_connectors; i++) {
|
for (i = 0; i < res->count_connectors; i++) {
|
||||||
connector = drmModeGetConnector(fd, res->connectors[i]);
|
connector = (current ? drmModeGetConnectorCurrent : drmModeGetConnector) (fd, res->connectors[i]);
|
||||||
|
|
||||||
if (!connector)
|
if (!connector)
|
||||||
printf("Could not get connector %i\n", res->connectors[i]);
|
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)
|
static void args(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
int defaults = 1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fbs = 0;
|
fbs = 0;
|
||||||
|
@ -341,32 +343,41 @@ static void args(int argc, char **argv)
|
||||||
full_modes = 0;
|
full_modes = 0;
|
||||||
full_props = 0;
|
full_props = 0;
|
||||||
connectors = 0;
|
connectors = 0;
|
||||||
|
current = 0;
|
||||||
|
|
||||||
module_name = argv[1];
|
module_name = argv[1];
|
||||||
|
|
||||||
for (i = 2; i < argc; i++) {
|
for (i = 2; i < argc; i++) {
|
||||||
if (strcmp(argv[i], "-fb") == 0) {
|
if (strcmp(argv[i], "-fb") == 0) {
|
||||||
fbs = 1;
|
fbs = 1;
|
||||||
|
defaults = 0;
|
||||||
} else if (strcmp(argv[i], "-crtcs") == 0) {
|
} else if (strcmp(argv[i], "-crtcs") == 0) {
|
||||||
crtcs = 1;
|
crtcs = 1;
|
||||||
|
defaults = 0;
|
||||||
} else if (strcmp(argv[i], "-cons") == 0) {
|
} else if (strcmp(argv[i], "-cons") == 0) {
|
||||||
connectors = 1;
|
connectors = 1;
|
||||||
modes = 1;
|
modes = 1;
|
||||||
|
defaults = 0;
|
||||||
} else if (strcmp(argv[i], "-modes") == 0) {
|
} else if (strcmp(argv[i], "-modes") == 0) {
|
||||||
connectors = 1;
|
connectors = 1;
|
||||||
modes = 1;
|
modes = 1;
|
||||||
|
defaults = 0;
|
||||||
} else if (strcmp(argv[i], "-full") == 0) {
|
} else if (strcmp(argv[i], "-full") == 0) {
|
||||||
connectors = 1;
|
connectors = 1;
|
||||||
modes = 1;
|
modes = 1;
|
||||||
full_modes = 1;
|
full_modes = 1;
|
||||||
|
defaults = 0;
|
||||||
} else if (strcmp(argv[i], "-props") == 0) {
|
} else if (strcmp(argv[i], "-props") == 0) {
|
||||||
connectors = 1;
|
connectors = 1;
|
||||||
full_props = 1;
|
full_props = 1;
|
||||||
|
defaults = 0;
|
||||||
} else if (strcmp(argv[i], "-edids") == 0) {
|
} else if (strcmp(argv[i], "-edids") == 0) {
|
||||||
connectors = 1;
|
connectors = 1;
|
||||||
edid = 1;
|
edid = 1;
|
||||||
|
defaults = 0;
|
||||||
} else if (strcmp(argv[i], "-encoders") == 0) {
|
} else if (strcmp(argv[i], "-encoders") == 0) {
|
||||||
encoders = 1;
|
encoders = 1;
|
||||||
|
defaults = 0;
|
||||||
} else if (strcmp(argv[i], "-v") == 0) {
|
} else if (strcmp(argv[i], "-v") == 0) {
|
||||||
fbs = 1;
|
fbs = 1;
|
||||||
edid = 1;
|
edid = 1;
|
||||||
|
@ -376,10 +387,13 @@ static void args(int argc, char **argv)
|
||||||
full_modes = 1;
|
full_modes = 1;
|
||||||
full_props = 1;
|
full_props = 1;
|
||||||
connectors = 1;
|
connectors = 1;
|
||||||
|
defaults = 0;
|
||||||
|
} else if (strcmp(argv[i], "-current") == 0) {
|
||||||
|
current = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 2) {
|
if (defaults) {
|
||||||
fbs = 1;
|
fbs = 1;
|
||||||
edid = 1;
|
edid = 1;
|
||||||
crtcs = 1;
|
crtcs = 1;
|
||||||
|
|
|
@ -476,19 +476,23 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
|
||||||
/*
|
/*
|
||||||
* Connector manipulation
|
* Connector manipulation
|
||||||
*/
|
*/
|
||||||
|
static drmModeConnectorPtr
|
||||||
drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
|
_drmModeGetConnector(int fd, uint32_t connector_id, int probe)
|
||||||
{
|
{
|
||||||
struct drm_mode_get_connector conn, counts;
|
struct drm_mode_get_connector conn, counts;
|
||||||
drmModeConnectorPtr r = NULL;
|
drmModeConnectorPtr r = NULL;
|
||||||
|
|
||||||
retry:
|
|
||||||
memclear(conn);
|
memclear(conn);
|
||||||
conn.connector_id = connector_id;
|
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))
|
if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
retry:
|
||||||
counts = conn;
|
counts = conn;
|
||||||
|
|
||||||
if (conn.count_props) {
|
if (conn.count_props) {
|
||||||
|
@ -504,6 +508,9 @@ retry:
|
||||||
conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo)));
|
conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo)));
|
||||||
if (!conn.modes_ptr)
|
if (!conn.modes_ptr)
|
||||||
goto err_allocs;
|
goto err_allocs;
|
||||||
|
} else {
|
||||||
|
conn.count_modes = 1;
|
||||||
|
conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct drm_mode_modeinfo)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn.count_encoders) {
|
if (conn.count_encoders) {
|
||||||
|
@ -572,6 +579,16 @@ err_allocs:
|
||||||
return r;
|
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)
|
int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
|
||||||
{
|
{
|
||||||
struct drm_mode_mode_cmd res;
|
struct drm_mode_mode_cmd res;
|
||||||
|
|
|
@ -422,11 +422,24 @@ 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,
|
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.
|
* Attaches the given mode to an connector.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue