summaryrefslogtreecommitdiff
path: root/libdrm
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2009-03-30 14:35:30 -0700
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-03-30 14:37:04 -0700
commitcd5c66c659168cbe2e3229ebf8be79f764ed0ee1 (patch)
treeaad537d3d0fcba6ab5ee0806587db84dea2081b3 /libdrm
parent93e65271601e6a1c7c90453f2f13157ae24b35c2 (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>
Diffstat (limited to 'libdrm')
-rw-r--r--libdrm/xf86drmMode.c39
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;
}