diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-03-30 14:35:30 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-03-30 14:37:04 -0700 |
commit | cd5c66c659168cbe2e3229ebf8be79f764ed0ee1 (patch) | |
tree | aad537d3d0fcba6ab5ee0806587db84dea2081b3 | |
parent | 93e65271601e6a1c7c90453f2f13157ae24b35c2 (diff) |
libdrm: speed up connector & mode fetching
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 <wallbraker@gmail.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r-- | libdrm/xf86drmMode.c | 39 |
1 files changed, 32 insertions, 7 deletions
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; } |