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.

Any comments or problems with the patch?

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c
index 872604f..e2aba81 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;
        }

------------------------------------------------------------------------------
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to