From cd5c66c659168cbe2e3229ebf8be79f764ed0ee1 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 30 Mar 2009 14:35:30 -0700 Subject: libdrm: speed up connector & mode fetching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch speeds up drmModeGetConnector by pre-allocating mode & property info space before calling into the kernel.  In many cases this pre-allocation will be sufficient to hold the returned values (it's easy enough to tweak if the common case becomes larger), which means we don't have to make the second call, which saves a lot of time. Acked-by: Jakob Bornecrantz Signed-off-by: Jesse Barnes --- libdrm/xf86drmMode.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'libdrm') diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index 872604ff..e2aba810 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -357,21 +357,45 @@ drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) { struct drm_mode_get_connector conn; drmModeConnectorPtr r = NULL; + int pre_props = 8, pre_modes = 16, pre_encoders = 4; conn.connector_id = connector_id; conn.connector_type_id = 0; conn.connector_type = 0; - conn.count_modes = 0; - conn.modes_ptr = 0; - conn.count_props = 0; - conn.props_ptr = 0; - conn.prop_values_ptr = 0; - conn.count_encoders = 0; - conn.encoders_ptr = 0; + conn.count_modes = pre_modes; + conn.count_props = pre_props; + conn.count_encoders = pre_encoders; + + /* + * Pre-allocate space for some modes, properties, and encoders. If + * we're lucky we won't need to call into the kernel twice. + */ + conn.props_ptr = VOID2U64(drmMalloc(pre_props * sizeof(uint32_t))); + conn.prop_values_ptr = VOID2U64(drmMalloc(pre_props * + sizeof(uint64_t))); + conn.modes_ptr = VOID2U64(drmMalloc(pre_modes * + sizeof(struct drm_mode_modeinfo))); + conn.encoders_ptr = VOID2U64(drmMalloc(pre_encoders * + sizeof(uint32_t))); if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn)) return 0; + if (conn.count_props <= pre_props && + conn.count_modes <= pre_modes && + conn.count_encoders <= pre_encoders) + goto done; + + /* Oh well, free & reallocate everything and ask again... */ + drmFree(U642VOID(conn.prop_values_ptr)); + drmFree(U642VOID(conn.props_ptr)); + drmFree(U642VOID(conn.modes_ptr)); + drmFree(U642VOID(conn.encoders_ptr)); + conn.prop_values_ptr = 0; + conn.props_ptr = 0; + conn.modes_ptr = 0; + conn.encoders_ptr = 0; + if (conn.count_props) { conn.props_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint32_t))); conn.prop_values_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint64_t))); @@ -386,6 +410,7 @@ drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn)) goto err_allocs; +done: if(!(r = drmMalloc(sizeof(*r)))) { goto err_allocs; } -- cgit v1.2.3